Repository: cambridgehackers/connectal Branch: master Commit: f182656bfe21 Files: 1351 Total size: 7.9 MB Directory structure: gitextract_q6vy71mg/ ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── Makefile ├── Makefile.connectal ├── Makefile.version ├── README.md ├── boardinfo/ │ ├── ac701.json │ ├── ac701_untethered.json │ ├── ac701g2.json │ ├── asic.json │ ├── awsf1.json │ ├── bluesim.json │ ├── cvc.json │ ├── de5.json │ ├── htg4.json │ ├── kc160g2.json │ ├── kc705.json │ ├── kc705_untethered.json │ ├── kc705g1.json │ ├── kc705g2.json │ ├── kcu105.json │ ├── miniitx100.json │ ├── ncverilog.json │ ├── nfsume.json │ ├── parallella.json │ ├── ultra96.json │ ├── v2000t.json │ ├── vc707.json │ ├── vc707g2.json │ ├── vc709.json │ ├── vcs.json │ ├── vcu108.json │ ├── vcu118.json │ ├── verilator.json │ ├── vsim.json │ ├── xsim.json │ ├── zc702.json │ ├── zc706.json │ ├── zc706_ubuntu.json │ ├── zcu102.json │ ├── zcu111.json │ ├── zedboard.json │ ├── zedboard_ubuntu.json │ ├── zybo.json │ └── zynq100.json ├── bsv/ │ ├── Adapter.bsv │ ├── AddressGenerator.bsv │ ├── AsicTop.bsv │ ├── AvalonBits.bsv │ ├── AvalonDdr3Controller.bsv │ ├── AvalonDma.bsv │ ├── AvalonGather.bsv │ ├── AvalonMasterSlave.bsv │ ├── AvalonSplitter.bsv │ ├── AwsF1Top.bsv │ ├── Axi4MasterSlave.bsv │ ├── AxiBits.bsv │ ├── AxiDdr3Controller.bsv │ ├── AxiDma.bsv │ ├── AxiGather.bsv │ ├── AxiMasterSlave.bsv │ ├── AxiStream.bsv │ ├── BpiFlash.bsv │ ├── BramMux.bsv │ ├── CnocPortal.bsv │ ├── ConnectableWithTrace.bsv │ ├── ConnectalAlteraCells.bsv │ ├── ConnectalBram.bsv │ ├── ConnectalBramFifo.bsv │ ├── ConnectalClocks.bsv │ ├── ConnectalCompletionBuffer.bsv │ ├── ConnectalConfig.bsv │ ├── ConnectalEHR.bsv │ ├── ConnectalFIFO.bsv │ ├── ConnectalMMU.bsv │ ├── ConnectalMemTypes.bsv │ ├── ConnectalMemUtils.bsv │ ├── ConnectalMemory.bsv │ ├── ConnectalMimo.bsv │ ├── ConnectalPrelude.bsv │ ├── ConnectalXilinxCells.bsv │ ├── CtrlMux.bsv │ ├── DisplayInd.bsv │ ├── Dsp48E1.bsv │ ├── GearboxGetPut.bsv │ ├── GetPutM.bsv │ ├── GetPutWithClocks.bsv │ ├── HostInterface.bsv │ ├── LinkerLib.bsv │ ├── MIFO.bsv │ ├── MemPipe.bsv │ ├── MemReadEngine.bsv │ ├── MemServer.bsv │ ├── MemServerInternal.bsv │ ├── MemServerPortal.bsv │ ├── MemToPcie.bsv │ ├── MemWriteEngine.bsv │ ├── OldEHR.bsv │ ├── PS4LIB.bsv │ ├── PS5LIB.bsv │ ├── PS7LIB.bsv │ ├── PS7Trace.bsv │ ├── PS8LIB.bsv │ ├── ParallellaTop.bsv │ ├── Pcie1EndpointX7.bsv │ ├── Pcie2EndpointX7.bsv │ ├── Pcie3EndpointX7.bsv │ ├── Pcie3RootPortX7.bsv │ ├── PcieCsr.bsv │ ├── PcieEndpointS5.bsv │ ├── PcieEndpointS5Test.bsv │ ├── PcieGearbox.bsv │ ├── PcieHost.bsv │ ├── PcieRootDevice.bsv │ ├── PcieRootPortX7.bsv │ ├── PcieSplitter.bsv │ ├── PcieStateChanges.bsv │ ├── PcieToMem.bsv │ ├── PcieTop.bsv │ ├── PcieTracer.bsv │ ├── PhysMemSlaveFromBram.bsv │ ├── Pipe.bsv │ ├── Platform.bsv │ ├── Portal.bsv │ ├── SimDma.bsv │ ├── SimLink.bsv │ ├── SyncAxisFifo32x8.bsv │ ├── SyncBits.bsv │ ├── Trace.bsv │ ├── TraceMemClient.bsv │ ├── UntetheredTop.bsv │ ├── XsimIF.bsv │ ├── XsimTop.bsv │ ├── ZynqTop.bsv │ └── ZynqUltraTop.bsv ├── constraints/ │ ├── altera/ │ │ ├── de5.qsf │ │ ├── de5.sdc │ │ ├── htg4.qsf │ │ └── htg4.sdc │ └── xilinx/ │ ├── Readme.md │ ├── ac701.xdc │ ├── awsf1.xdc │ ├── bluesim.xdc │ ├── bluesim_pcie.xdc │ ├── cdc.tcl │ ├── kc160g2.xdc │ ├── kc705-3.0.xdc │ ├── kc705-ddr3.prj │ ├── kc705.xdc │ ├── kc705g2.xdc │ ├── kcu105.xdc │ ├── miniitx100-axiddr3.prj │ ├── miniitx100.xdc │ ├── nfsume-axiddr3.prj │ ├── nfsume.xdc │ ├── ok/ │ │ ├── zc7z010clg400.xdc │ │ ├── zc7z020clg400.xdc │ │ ├── zc7z020clg484.xdc │ │ ├── zc7z045ffg900.xdc │ │ └── zc7z100ffg900.xdc │ ├── parallella.xdc │ ├── pcie-clocks.xdc │ ├── v2000t.xdc │ ├── vc707-axiddr3.prj │ ├── vc707-portal-pblock.xdc │ ├── vc707.xdc │ ├── vc707_aurora.xdc │ ├── vc707_ddr3.xdc │ ├── vc707_ddr3_pins.xdc │ ├── vc707g2-axiddr3.prj │ ├── vc707g2.xdc │ ├── vc709.xdc │ ├── vcu108.xdc │ ├── vcu118.xdc │ ├── verilator.xdc │ ├── xc7z010clg400.xdc │ ├── xc7z045ffg900.xdc │ ├── xc7z100ffg900.xdc │ ├── zc706-axiddr3.prj │ ├── zc706.xdc │ ├── zc706_pl_ddr3_pins.xdc │ ├── zc7z020clg400.xdc │ ├── zc7z020clg484.xdc │ ├── zcu102.xdc │ ├── zcu111.xdc │ ├── zybo.xdc │ └── zynq100.xdc ├── contrib/ │ ├── bluescope/ │ │ ├── Makefile │ │ ├── Memcpy.bsv │ │ ├── Top.bsv │ │ └── testbluescope.cpp │ ├── bluescopeevent/ │ │ ├── Makefile │ │ ├── SignalGen.bsv │ │ ├── Top.bsv │ │ └── testbluescopeevent.cpp │ ├── bluescopeeventpio/ │ │ ├── Makefile │ │ ├── SignalGen.bsv │ │ ├── Top.bsv │ │ └── testbluescopeeventpio.cpp │ ├── channelselect/ │ │ ├── ChannelSelect.bsv │ │ ├── ChannelSelectTest.bsv │ │ ├── ChannelSelectTestInterfaces.bsv │ │ ├── DDS.bsv │ │ ├── DDSTest.bsv │ │ ├── DDSTestInterfaces.bsv │ │ ├── FPCMult.bsv │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── SDRTypes.bsv │ │ ├── Top.bsv │ │ ├── sinetable.c │ │ └── testchannelselecttest.cpp │ ├── fib/ │ │ ├── Fib.bsv │ │ ├── FibNarrow.bsv │ │ ├── Makefile │ │ ├── Readme.md │ │ └── testfib.cpp │ ├── flowcontrol/ │ │ ├── Makefile │ │ ├── Sink.bsv │ │ ├── Top.bsv │ │ └── test.cpp │ ├── importverilog/ │ │ ├── .gitignore │ │ ├── Main.bsv │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── regfile.v │ │ ├── regfile_tb.v │ │ └── testmain.cpp │ ├── maxcommonsubseq/ │ │ ├── HirschA.bsv │ │ ├── HirschB.bsv │ │ ├── HirschC.bsv │ │ ├── MCSAlgorithm.bsv │ │ ├── Makefile │ │ ├── Maxcommonsubseq.bsv │ │ ├── Top.bsv │ │ ├── hirschberg.py │ │ └── testmaxcommonsubseq.cpp │ ├── noc/ │ │ ├── Makefile │ │ ├── Noc.bsv │ │ ├── NocNode.bsv │ │ ├── Readme.md │ │ ├── Top.bsv │ │ └── testnoc.cpp │ ├── noc2d/ │ │ ├── Makefile │ │ ├── Noc2d.bsv │ │ ├── NocNode.bsv │ │ ├── Readme.md │ │ ├── Top.bsv │ │ └── testnoc2d.cpp │ ├── parallella/ │ │ ├── ELink.bsv │ │ ├── Makefile │ │ ├── PParallellaLIB.bsv │ │ ├── ParallellaLib.bsv │ │ ├── ParallellaLibDefs.bsv │ │ ├── Top.bsv │ │ ├── notes.txt │ │ ├── parallella.v │ │ └── testmain.cpp │ ├── perf/ │ │ ├── Makefile │ │ ├── Perf.bsv │ │ ├── Top.bsv │ │ └── testperf.cpp │ ├── pipe_mul/ │ │ ├── Makefile │ │ ├── PipeMulTB.bsv │ │ ├── Top.bsv │ │ └── testpipe_mul.cpp │ ├── pipe_mul2/ │ │ ├── Makefile │ │ ├── PipeMulTB.bsv │ │ ├── Top.bsv │ │ └── testpipe_mul.cpp │ ├── portalperf/ │ │ ├── Makefile │ │ ├── PortalPerf.bsv │ │ ├── Repeat.bsv │ │ ├── Top.bsv │ │ └── testportalperf.cpp │ ├── ptest/ │ │ ├── Makefile │ │ ├── PTest.bsv │ │ ├── PTest.bsv.bad │ │ └── PTest.bsv.good │ ├── serialconfig/ │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── Serialconfig.bsv │ │ └── testserialconfig.cpp │ ├── smithwaterman/ │ │ ├── GotohB.bsv │ │ ├── GotohC.bsv │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── Smithwaterman.bsv │ │ ├── Top.bsv │ │ ├── sw.py │ │ └── testsmithwaterman.cpp │ └── splice/ │ ├── Makefile │ ├── Splice.bsv │ ├── Top.bsv │ └── testsplice.cpp ├── cpp/ │ ├── BsimDma.cpp │ ├── DmaBuffer.cpp │ ├── DmaBuffer.h │ ├── MMUServer.h │ ├── TlpReplay.cpp │ ├── XsimTop.cpp │ ├── XsimTop.h │ ├── bluesim_main.cxx │ ├── bsim_relay.c │ ├── dmaManager.c │ ├── dmaManager.h │ ├── dmaSendFd.h │ ├── kernel_module.c │ ├── manualMMUIndication.h │ ├── monkit.h │ ├── platformMemory.cpp │ ├── poller.cpp │ ├── portal.c │ ├── portal.h │ ├── portalJson.c │ ├── portalKernel.h │ ├── portalPrintf.c │ ├── portalPython.cpp │ ├── runpython.cpp │ ├── sock_utils.c │ ├── sock_utils.h │ ├── timer.c │ ├── transportHardware.c │ ├── transportPortal.c │ ├── transportSerial.c │ ├── transportShared.c │ ├── transportSocket.c │ ├── transportWebSocket.c │ ├── transportXsim.c │ └── verilatortop.cpp ├── debian/ │ ├── changelog │ ├── compat │ ├── connectal-doc.docs │ ├── connectal-doc.install │ ├── connectal-zynqdrivers.install │ ├── connectal.dkms │ ├── connectal.install │ ├── connectal.udev │ ├── control │ ├── copyright │ ├── docs │ └── rules ├── doc/ │ ├── Makefile │ ├── ReadmePartialReconfiguration.md │ ├── SmithWaterman.md │ ├── axi_tracing.md │ ├── centos.md │ ├── generated/ │ │ └── html/ │ │ └── portal.html │ ├── ifdef.md │ ├── library/ │ │ ├── Makefile │ │ └── source/ │ │ ├── bsv/ │ │ │ ├── addressgenerator.rst │ │ │ ├── arith.rst │ │ │ ├── axistream.rst │ │ │ ├── bsv.rst │ │ │ ├── ctrlmux.rst │ │ │ ├── hostinterface.rst │ │ │ ├── leds.rst │ │ │ ├── memportal.rst │ │ │ ├── memreadengine.rst │ │ │ ├── memtypes.rst │ │ │ ├── mmu.rst │ │ │ ├── pipe.rst │ │ │ └── portal.rst │ │ ├── bsvsphinx.py │ │ ├── c/ │ │ │ ├── c.rst │ │ │ └── portal.rst │ │ ├── conf.py │ │ ├── design/ │ │ │ ├── Makefile │ │ │ ├── abstract.rst │ │ │ ├── bs-related-papers.bib │ │ │ ├── conclusion.rst │ │ │ ├── connectal-framework.rst │ │ │ ├── design.rst │ │ │ ├── flowcontrol.rst │ │ │ ├── host_interface.rst │ │ │ ├── images/ │ │ │ │ ├── Makefile │ │ │ │ ├── MemreadEngine.pptx │ │ │ │ ├── PortalImpl0.pptx │ │ │ │ ├── data_accel_logical0.pptx │ │ │ │ ├── data_accel_logical1.pptx │ │ │ │ ├── data_accel_logical2.pptx │ │ │ │ ├── data_accel_logical3.pptx │ │ │ │ ├── data_accel_logical4.pptx │ │ │ │ ├── msc0.pptx │ │ │ │ ├── msc1.pptx │ │ │ │ ├── msc2.pptx │ │ │ │ ├── platform.pptx │ │ │ │ └── platforms.pptx │ │ │ ├── implementing-string-search.rst │ │ │ ├── interface_definitions.rst │ │ │ ├── introduction.rst │ │ │ ├── performance.rst │ │ │ ├── portal.rst │ │ │ ├── portalstructure.rst │ │ │ ├── references.bib │ │ │ ├── related-work.rst │ │ │ ├── string-search.rst │ │ │ └── toolchain.rst │ │ ├── devguide/ │ │ │ ├── clocks.rst │ │ │ ├── compilingproject.rst │ │ │ ├── design.rst │ │ │ ├── devguide.rst │ │ │ └── projectstructure.rst │ │ ├── examples/ │ │ │ ├── index.rst │ │ │ └── simple.rst │ │ ├── index.rst │ │ ├── installation.rst │ │ ├── intro.rst │ │ ├── make.rst │ │ ├── makefile.connectal.build.rst │ │ ├── makefile.connectal.rst │ │ ├── themes/ │ │ │ └── connectal/ │ │ │ ├── layout.html │ │ │ ├── static/ │ │ │ │ └── tracking.js_t │ │ │ └── theme.conf │ │ └── tools/ │ │ ├── generate-constraints.rst │ │ ├── makefilegen.rst │ │ ├── pcieflat.rst │ │ ├── tools.rst │ │ └── topgen.rst │ ├── makefilegen.md │ ├── maxcommonsubseq.md │ ├── previous/ │ │ └── portal.asciidoc │ ├── server.md │ └── syntax.md ├── docker/ │ └── Dockerfile ├── drivers/ │ ├── awsf1portal/ │ │ ├── Makefile │ │ ├── Makefile.dkms │ │ ├── cdev_bypass.c │ │ ├── cdev_ctrl.c │ │ ├── cdev_ctrl.h │ │ ├── cdev_events.c │ │ ├── cdev_sgdma.c │ │ ├── cdev_sgdma.h │ │ ├── cdev_xvc.c │ │ ├── cdev_xvc.h │ │ ├── dkms.conf │ │ ├── driverversion.h │ │ ├── libxdma.c │ │ ├── libxdma.h │ │ ├── libxdma_api.h │ │ ├── linux/ │ │ │ └── dma-buf.h │ │ ├── pcieportal.h │ │ ├── portal.c │ │ ├── portal_internal.h │ │ ├── version.h │ │ ├── xdma_cdev.c │ │ ├── xdma_cdev.h │ │ ├── xdma_ioctl.h │ │ ├── xdma_mod.c │ │ └── xdma_mod.h │ ├── connectalsdhci/ │ │ ├── Makefile │ │ └── connectalsdhci.c │ ├── connectalspi/ │ │ ├── Makefile │ │ └── connectalspi.c │ ├── pcieportal/ │ │ ├── Makefile │ │ ├── Makefile.dkms │ │ ├── dkms.conf │ │ ├── driverversion.h │ │ ├── linux/ │ │ │ └── dma-buf.h │ │ ├── pcieportal.c │ │ └── pcieportal.h │ ├── portalmem/ │ │ ├── Makefile │ │ ├── portalmem.c │ │ └── portalmem.h │ └── zynqportal/ │ ├── Makefile │ ├── zynqportal.c │ └── zynqportal.h ├── etc/ │ ├── modules-load.d/ │ │ └── connectal.conf │ └── udev/ │ └── rules.d/ │ ├── 51-connectaltty.rules │ ├── 52-altera-usb.rules │ ├── 52-connectaltest.rules │ ├── 52-digilent-usb.rules │ └── 99-pcieportal.rules ├── examples/ │ ├── algo1_nandsim/ │ │ ├── Algo1NandSim.bsv │ │ ├── Makefile │ │ ├── nandsim.cpp │ │ └── test.cpp │ ├── algo2_nandsim/ │ │ ├── Makefile │ │ ├── Top.bsv │ │ ├── jregexp.charMap │ │ ├── jregexp.stateMap │ │ ├── jregexp.stateTransitions │ │ └── test.cpp │ ├── aurora/ │ │ ├── Aurora.bsv │ │ ├── BviAurora.bsv │ │ ├── Gtx.bsv │ │ ├── Makefile │ │ ├── Top.bsv │ │ ├── aurora-clocks.xdc │ │ ├── aurora.json │ │ ├── clock.tcl │ │ ├── synth-ip.tcl │ │ └── testaurora.cpp │ ├── bscan/ │ │ ├── BscanIF.bsv │ │ ├── Makefile │ │ └── testbscan.cpp │ ├── caffe/ │ │ ├── Conv.bsv │ │ ├── INSTALL │ │ ├── Makefile │ │ └── README.md │ ├── echo/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ └── testecho.cpp │ ├── echo2ind/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ └── testecho.cpp │ ├── echofast/ │ │ └── Makefile │ ├── echohost/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── testecho.cpp │ │ └── vc707_floorplan.xdc │ ├── echoinvert/ │ │ ├── Echo.bsv │ │ ├── EchoInterface.bsv │ │ ├── Makefile │ │ └── testecho.cpp │ ├── echojson/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── Swallow.bsv │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── echojsonpy/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── Swallow.bsv │ │ ├── daemon.cpp │ │ ├── old_testecho.py │ │ └── testecho.py │ ├── echomux/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── Services.bsv │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── echoproto/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── echo.proto │ │ └── testecho.cpp │ ├── echopy/ │ │ ├── Echo.bsv │ │ ├── EchoInterface.bsv │ │ ├── Makefile │ │ ├── testecho.py │ │ └── ubuntu-python-dev.sh │ ├── echoshared/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── echoslow/ │ │ ├── Echo.bsv │ │ └── Makefile │ ├── echosoft/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── Swallow.bsv │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── echotrace/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── testecho.cpp │ │ └── vc707_floorplan.xdc │ ├── echowebsocket/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── Swallow.bsv │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── fmcomms1/ │ │ ├── ExtraXilinxCells.bsv │ │ ├── ExtraXilinxCells.bsv.pp │ │ ├── FMComms1.bsv │ │ ├── FMComms1ADC.bsv │ │ ├── FMComms1DAC.bsv │ │ ├── FMComms1Pins.bsv │ │ ├── Makefile │ │ ├── Top.bsv │ │ ├── clock.tcl │ │ ├── fmci2c.c │ │ ├── fmci2c.h │ │ ├── fmcomms1-fmc.json │ │ ├── i2c_zedboardandroid.c │ │ ├── i2c_zedboardandroid.h │ │ ├── readtrace.py │ │ ├── testfmcomms1.cpp │ │ └── testi2c.c │ ├── gyro_simple/ │ │ ├── Makefile │ │ ├── clock.tcl │ │ ├── gyro.h │ │ ├── gyroVisualize.py │ │ ├── gyro_simple.h │ │ ├── pinout.json │ │ ├── test_gyro.cpp │ │ └── test_gyro.py │ ├── gyrospi/ │ │ ├── Makefile │ │ ├── STest.bsv │ │ ├── gyro.h │ │ ├── pinout.json │ │ └── testspi.cpp │ ├── hbridge_simple/ │ │ ├── Makefile │ │ ├── hbridge_simple.h │ │ ├── pinout.json │ │ └── test_hbridge.cpp │ ├── hdmidisplay/ │ │ ├── BsimHdmi.cpp │ │ ├── HDMI16.bsv │ │ ├── Makefile │ │ ├── TestHdmi.pro │ │ ├── hdmi.json │ │ ├── hdmidisplay-bluesim.xdc │ │ ├── hdmidisplay-vc707.xdc │ │ ├── hdmidisplay-zc702.xdc │ │ ├── hdmidisplay-zedboard.xdc │ │ ├── i2c.json │ │ ├── qtmain.cpp │ │ ├── testhdmidisplay.cpp │ │ └── worker.h │ ├── imageon/ │ │ ├── ImageonCapture.bsv │ │ ├── ImageonCapturePins.bsv │ │ ├── Makefile │ │ ├── Makefile.dump │ │ ├── clock.tcl │ │ ├── dump_image.cpp │ │ ├── i2ccamera.h │ │ ├── imageon-clocks.xdc │ │ ├── imageon-fmc.json │ │ ├── imageon-zedboard.json │ │ └── testimagecapture.cpp │ ├── leds/ │ │ ├── LedController.bsv │ │ ├── Makefile │ │ ├── pinout.json │ │ └── testleds.cpp │ ├── linking/ │ │ ├── GetInverse.v │ │ ├── LinkerLib.bsv │ │ ├── Makefile │ │ ├── Processor.bsv │ │ ├── ProcessorTop.bsv │ │ └── Processor_Generated.bsv │ ├── matmul/ │ │ ├── Makefile │ │ ├── Makefile.mm │ │ ├── Makefile.mmif │ │ ├── clocks.tcl │ │ ├── design-vc707.tcl │ │ ├── design.tcl │ │ ├── mkZynqTop_flpn.xdc │ │ ├── perf.txt │ │ ├── synth-ip.tcl │ │ └── testmm.cpp │ ├── maxsonar_simple/ │ │ ├── Makefile │ │ ├── maxsonar_simple.h │ │ ├── pinout.json │ │ └── test_maxsonar.cpp │ ├── memcpy/ │ │ ├── Makefile │ │ ├── Memcpy.bsv │ │ └── testmemcpy.cpp │ ├── memcpyslow/ │ │ └── Makefile │ ├── memlatency/ │ │ ├── Makefile │ │ ├── Memlatency.bsv │ │ └── testmemlatency.cpp │ ├── memread/ │ │ ├── Makefile │ │ ├── ReadTest.bsv │ │ ├── design_vc707.tcl │ │ ├── testmemread.cpp │ │ └── vc707_floorplan.xdc │ ├── memread128/ │ │ └── Makefile │ ├── memread2/ │ │ ├── Makefile │ │ ├── Memread2.bsv │ │ └── testmemread2.cpp │ ├── memread256/ │ │ └── Makefile │ ├── memread_4m/ │ │ ├── Makefile │ │ └── ReadTest.bsv │ ├── memread_simple/ │ │ ├── Makefile │ │ ├── ReadTest.bsv │ │ ├── design_vc707.tcl │ │ ├── testmemread.cpp │ │ └── vc707_floorplan.xdc │ ├── memwrite/ │ │ ├── Makefile │ │ ├── Memwrite.bsv │ │ └── testmemwrite.cpp │ ├── memwrite128/ │ │ └── Makefile │ ├── memwrite256/ │ │ └── Makefile │ ├── memwrite_4m/ │ │ ├── Makefile │ │ └── Memwrite.bsv │ ├── nandsim/ │ │ ├── Makefile │ │ └── testnandsim.cpp │ ├── portal-synth-boundary/ │ │ ├── Makefile │ │ ├── Simple.bsv │ │ ├── Top.bsv │ │ └── testsimple.cpp │ ├── printf/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── SwallowIF.bsv │ │ ├── Top.bsv │ │ └── testecho.cpp │ ├── rbm/ │ │ ├── LICENSE.txt │ │ ├── Makefile │ │ ├── Makefile.rbm │ │ ├── Readme.md │ │ └── testrbm.cpp │ ├── readbw/ │ │ ├── ReadBW.bsv │ │ └── testreadbw.cpp │ ├── regexp/ │ │ ├── Makefile │ │ ├── jregexp.charMap │ │ ├── jregexp.stateMap │ │ ├── jregexp.stateTransitions │ │ └── testregexp.cpp │ ├── sdcard_spi/ │ │ ├── Makefile │ │ ├── SPI.bsv │ │ ├── SPITest.bsv │ │ ├── pin_translation.json │ │ ├── readme.txt │ │ └── sdcard_spi.cpp │ ├── simple/ │ │ ├── Makefile │ │ ├── Simple.bsv │ │ ├── boards/ │ │ │ ├── de5.json │ │ │ └── htg4.json │ │ ├── simple.h │ │ └── testsimple.cpp │ ├── simplemultibluesim/ │ │ ├── Link.bsv │ │ ├── LinkIF.bsv │ │ ├── Makefile │ │ ├── run.sh │ │ ├── testsimple.cpp │ │ └── xsimrun.sh │ ├── simplesharedhw/ │ │ ├── Makefile │ │ ├── Simple.bsv │ │ └── testsimple.cpp │ ├── strstr/ │ │ ├── Makefile │ │ ├── StrstrExample.bsv │ │ └── teststrstr.cpp │ ├── swmemcpy/ │ │ ├── Makefile │ │ ├── SWmemcpy.bsv │ │ └── testswmemcpy.cpp │ ├── vectoradd_hls/ │ │ ├── Makefile │ │ ├── README.md │ │ ├── bsv/ │ │ │ ├── Vadd.bsv │ │ │ └── VaddBvi.bsv │ │ ├── solution1/ │ │ │ └── impl/ │ │ │ └── verilog/ │ │ │ └── vectoradd.v │ │ ├── src/ │ │ │ └── vectoradd.cpp │ │ └── testvadd.cpp │ ├── zedboard_robot/ │ │ ├── Controller.bsv │ │ ├── Makefile │ │ ├── pinout.json │ │ ├── sonarVisualize.py │ │ ├── test_zedboard_robot.cpp │ │ └── test_zedboard_robot.py │ └── zynqpcie/ │ ├── Makefile │ ├── SimpleIF.bsv │ ├── Top.bsv │ ├── ZynqPcieTestIF.bsv │ ├── synth-ip.tcl │ ├── testsimple.cpp │ ├── testzynqpcie.cpp │ └── zynqpcie.json ├── generated/ │ ├── altera/ │ │ ├── ALTERA_DDR3_WRAPPER.bsv │ │ ├── ALTERA_ETH_PMA_RECONFIG_WRAPPER.bsv │ │ ├── ALTERA_ETH_PMA_RESET_CONTROL_WRAPPER.bsv │ │ ├── ALTERA_ETH_PMA_WRAPPER.bsv │ │ ├── ALTERA_PCIE_ED_WRAPPER.bsv │ │ ├── ALTERA_PCIE_RECONFIG_DRIVER_WRAPPER.bsv │ │ ├── ALTERA_PCIE_SIV_WRAPPER.bsv │ │ ├── ALTERA_PCIE_SV_WRAPPER.bsv │ │ ├── ALTERA_PLL_WRAPPER.bsv │ │ └── ALTERA_XCVR_RECONFIG_WRAPPER.bsv │ ├── cpp/ │ │ ├── GeneratedTypes.h │ │ ├── MMURequest.c │ │ └── README │ └── scripts/ │ ├── generate_altera_ddrbvi.sh │ ├── generate_altera_ethbvi.sh │ ├── generate_altera_macbvi.sh │ ├── generate_altera_pciebvi.sh │ ├── generate_bscane2.sh │ ├── generate_bufgcrtl.sh │ ├── generate_pcie2wrapper.sh │ ├── generate_pcie3.sh │ ├── generate_pcie3u.sh │ ├── generate_pcie3uplus.sh │ ├── generate_pcie_2_1.sh │ ├── generate_pciewrapper.sh │ ├── generate_pipeclock.sh │ ├── generate_pps7.sh │ ├── generate_pps7lib.sh │ ├── generate_zynq_mpsoc.sh │ └── importbvi.py ├── gralloc/ │ ├── Android.mk │ ├── Makefile │ ├── README │ ├── bitset │ ├── gr.h │ ├── gralloc.cpp │ ├── gralloc_priv.h │ └── mapper.cpp ├── jtag/ │ ├── README │ ├── bsd/ │ │ ├── xc7k325t_ffg900.bsd │ │ ├── xc7vx485t_ffg1761.bsd │ │ ├── xc7vx690t_ffg1761.bsd │ │ └── xc7z020_clg484.bsd │ ├── digilent-hs1.cfg │ ├── digilent-hs2.cfg │ ├── dumptrace.py │ ├── kc705.cfg │ ├── kc705program.cfg │ ├── pcietrace.cfg │ ├── readll.py │ ├── run_jtag.sh │ ├── run_trace.sh │ ├── zedboard.cfg │ └── zedtrace.cfg ├── lib/ │ ├── bsv/ │ │ ├── Arith.bsv │ │ ├── BRAMFIFOFLevel.bsv │ │ ├── BlueScope.bsv │ │ ├── BlueScopeEvent.bsv │ │ ├── BlueScopeEventPIO.bsv │ │ ├── Bscan.bsv │ │ ├── ConfigCounter.bsv │ │ ├── ConnectalSpi.bsv │ │ ├── Dma2BRAM.bsv │ │ ├── FrequencyCounter.bsv │ │ ├── HDMI.bsv │ │ ├── HdmiDisplay.bsv │ │ ├── ImageonVita.bsv │ │ ├── IserdesDatadeser.bsv │ │ ├── IserdesDatadeserIF.bsv │ │ ├── Leds.bsv │ │ ├── PipeMul.bsv │ │ ├── SharedMemoryFifo.bsv │ │ ├── SharedMemoryPortal.bsv │ │ ├── SpiRoot.bsv │ │ ├── SpiTap.bsv │ │ ├── Stack.bsv │ │ ├── StackReg.bsv │ │ ├── XADC.bsv │ │ ├── XilinxVirtex7PCIE.bsv │ │ └── YUV.bsv │ ├── cpp/ │ │ ├── connectal_conv.cpp │ │ ├── connectal_conv.h │ │ ├── connectal_convmm.cpp │ │ ├── edid.h │ │ ├── i2chdmi.h │ │ ├── printfInd.h │ │ └── userReference.h │ ├── deprecated/ │ │ ├── BurstFunnel.bsv │ │ ├── DirectoryRF.bsv │ │ ├── DmaUtils.bsv │ │ ├── OldMemServer.bsv │ │ ├── RegFileA.bsv │ │ ├── SGListComb.bsv │ │ ├── bsv_Makefile │ │ ├── pcietestbench/ │ │ │ ├── Makefile │ │ │ ├── PcieTestBench.bsv │ │ │ ├── Top.bsv │ │ │ └── testpcie.cpp │ │ ├── pcietestbench_dma_io/ │ │ │ ├── Makefile │ │ │ ├── Memread.bsv │ │ │ ├── PcieTestBench.bsv │ │ │ ├── Top.bsv │ │ │ ├── memread_nobuff_io.tstlp │ │ │ └── testpcie.cpp │ │ └── pcietestbench_dma_oo/ │ │ ├── Makefile │ │ ├── Memread.bsv │ │ ├── PcieTestBench.bsv │ │ ├── Top.bsv │ │ ├── memread_nobuff_oo.tstlp │ │ └── testpcie.cpp │ ├── matmul/ │ │ ├── bar.m │ │ ├── bsv/ │ │ │ ├── DotProdServer.bsv │ │ │ ├── FloatOps.bsv │ │ │ ├── FpAdd.bsv │ │ │ ├── FpMac.bsv │ │ │ ├── FpMacTb.bsv │ │ │ ├── FpMul.bsv │ │ │ ├── MatrixNT.bsv │ │ │ └── MatrixTN.bsv │ │ └── cpp/ │ │ ├── cuda.cpp │ │ ├── portalmat.cpp │ │ └── portalmat.h │ ├── nandsim/ │ │ ├── bsv/ │ │ │ ├── NandSim.bsv │ │ │ └── NandSimNames.bsv │ │ └── cpp/ │ │ └── nandsim.h │ ├── nvme/ │ │ ├── bsv/ │ │ │ ├── AxiPcie3RootPort.bsv │ │ │ ├── AxiPcieRootPort.bsv │ │ │ ├── Nvme.bsv │ │ │ ├── NvmeIfc.bsv │ │ │ └── NvmePins.bsv │ │ ├── cpp/ │ │ │ ├── nvme.cpp │ │ │ └── nvme.h │ │ └── tcl/ │ │ └── package.tcl │ ├── qemu/ │ │ ├── fpgadev.cpp │ │ └── fpgadev.h │ ├── rbm/ │ │ ├── bsv/ │ │ │ ├── DmaVector.bsv │ │ │ ├── Rbm.bsv │ │ │ ├── RbmTypes.bsv │ │ │ ├── Sigmoid.bsv │ │ │ └── Timer.bsv │ │ └── cpp/ │ │ ├── mnist.h │ │ ├── rbm.cpp │ │ └── rbm.h │ ├── regexp/ │ │ ├── bsv/ │ │ │ ├── Regexp.bsv │ │ │ └── RegexpEngine.bsv │ │ └── cpp/ │ │ └── regexp_utils.h │ ├── strstr/ │ │ ├── bsv/ │ │ │ ├── MPEngine.bsv │ │ │ └── Strstr.bsv │ │ └── cpp/ │ │ ├── mp.h │ │ └── strstr.h │ └── zedboard_robot/ │ ├── bsv/ │ │ ├── GyroController.bsv │ │ ├── HBridgeController.bsv │ │ └── MaxSonarController.bsv │ └── cpp/ │ ├── read_buffer.cpp │ └── read_buffer.h ├── pcie/ │ ├── Makefile │ ├── pcieflat │ └── tlp.py ├── scripts/ │ ├── AST.py │ ├── Doxyfile │ ├── Makefile.connectal.application │ ├── Makefile.connectal.build │ ├── adb/ │ │ ├── LICENSE │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── adb_commands.py │ │ ├── adb_debug.py │ │ ├── adb_protocol.py │ │ ├── adb_test.py │ │ ├── common.py │ │ ├── common_cli.py │ │ ├── common_stub.py │ │ ├── fastboot.py │ │ ├── fastboot_debug.py │ │ ├── fastboot_protocol.txt │ │ ├── fastboot_test.py │ │ ├── filesync_protocol.py │ │ ├── filesync_protocol.txt │ │ └── usb_exceptions.py │ ├── aws/ │ │ ├── build.sh │ │ ├── create-fpga-image.sh │ │ ├── create_dcp_from_cl.tcl │ │ ├── describe-latest-fpga-image.sh │ │ ├── encrypt.tcl │ │ ├── notify_via_sns.py │ │ ├── run.awsf1 │ │ ├── synth_awsf1.tcl │ │ ├── upload.sh │ │ └── wait_for_afi.py │ ├── boardinfo.py │ ├── bsv.filter │ ├── bsvdepend.py │ ├── bsvdependencies.py │ ├── bsvgen.py │ ├── bsvpreprocess.py │ ├── cadb │ ├── check-timing.py │ ├── connectal-make │ ├── connectal-synth-avalonddr3.tcl │ ├── connectal-synth-axichecker.tcl │ ├── connectal-synth-axiddr3.tcl │ ├── connectal-synth-axidma.tcl │ ├── connectal-synth-axieth.tcl │ ├── connectal-synth-axiintc.tcl │ ├── connectal-synth-eth.tcl │ ├── connectal-synth-ila.tcl │ ├── connectal-synth-ip.tcl │ ├── connectal-synth-pcie-rp.tcl │ ├── connectal-synth-pcie.tcl │ ├── connectal-synth-pll.tcl │ ├── connectal-synth-zynq-mpsoc.tcl │ ├── cppgen.py │ ├── deprecated/ │ │ ├── mkpcietop-partial-reconfiguration.tcl │ │ ├── mkpcietop-synth.tcl │ │ ├── portaltop-impl.tcl │ │ └── portaltop-synth.tcl │ ├── discover_icmp.py │ ├── discover_tcp.py │ ├── driver_signature.sed │ ├── extract-bvi-schedule.py │ ├── generate-constraints.py │ ├── globalv.py │ ├── makefilegen.py │ ├── packagesource.py │ ├── parse_qsf.py │ ├── parse_xdc.py │ ├── portal.py │ ├── portalJson.py │ ├── power.py │ ├── preprocess_trace.py │ ├── reorderbytes.py │ ├── run.android │ ├── run.android.sh │ ├── run.parallella.sh │ ├── run.pcietest │ ├── run.pcietest.altera │ ├── run_on_daffodil │ ├── syntax.py │ ├── topgen.py │ └── util.py ├── tests/ │ ├── adapter/ │ │ ├── Makefile │ │ ├── Test.bsv │ │ └── test.cpp │ ├── aecho/ │ │ ├── Echo.orig.bsv │ │ ├── EchoReq.bsv │ │ ├── Makefile │ │ ├── generated/ │ │ │ ├── Echo.bsv │ │ │ ├── EchoVerilog.v │ │ │ ├── L_class_OC_Echo.bsv │ │ │ ├── L_class_OC_Fifo.bsv │ │ │ ├── L_class_OC_Fifo1.bsv │ │ │ ├── l_class_OC_Echo.cpp │ │ │ ├── l_class_OC_Echo.h │ │ │ ├── l_class_OC_Echo.v │ │ │ ├── l_class_OC_EchoIndication.cpp │ │ │ ├── l_class_OC_EchoIndication.h │ │ │ ├── l_class_OC_EchoRequest.cpp │ │ │ ├── l_class_OC_EchoRequest.h │ │ │ ├── l_class_OC_EchoTest.cpp │ │ │ ├── l_class_OC_EchoTest.h │ │ │ ├── l_class_OC_Fifo.cpp │ │ │ ├── l_class_OC_Fifo.h │ │ │ ├── l_class_OC_Fifo.v │ │ │ ├── l_class_OC_Fifo1.cpp │ │ │ ├── l_class_OC_Fifo1.h │ │ │ ├── l_class_OC_Fifo1.v │ │ │ ├── output.cpp │ │ │ └── output.h │ │ └── testecho.cpp │ ├── algo1_flashmodel/ │ │ ├── AuroraCommon.bsv │ │ ├── AuroraGearbox.bsv │ │ ├── AuroraImportFmc1.bsv │ │ ├── ChipscopeWrapper.bsv │ │ ├── ControllerTypes.bsv │ │ ├── FlashBusModel.bsv │ │ ├── FlashCtrlModel.bsv │ │ ├── FlashTop.bsv │ │ ├── Makefile │ │ ├── NandSimMod.bsv │ │ ├── NullResetN.bsv │ │ ├── PageBuffers.bsv │ │ ├── Top.bsv │ │ ├── TopPins.bsv │ │ ├── flashaccess.cpp │ │ └── test.cpp │ ├── algo1_nandsim_manual/ │ │ ├── Makefile │ │ ├── algo1.cpp │ │ ├── haystack.txt │ │ ├── kernel/ │ │ │ └── Makefile │ │ └── nandsim_manual.c │ ├── avalon_mm/ │ │ ├── AvalonBfmWrapper.bsv │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── TestProgram.bsv │ │ ├── avlm_avls_1x1.qsys │ │ ├── testecho.cpp │ │ └── verilog/ │ │ ├── tb.sv │ │ └── test_program.v │ ├── axieth/ │ │ ├── AxiEth.bsv │ │ ├── EthPins.bsv │ │ ├── Makefile │ │ ├── axieth.h │ │ ├── axieth.json │ │ ├── axieth.xdc │ │ ├── testaxieth.cpp │ │ └── xsim_export.tcl │ ├── bluecheck-bram/ │ │ ├── Bram2Example.bsv │ │ ├── BramExample.bsv │ │ └── make.sh │ ├── bluecheck-sharedmemfifo/ │ │ ├── ConnectalProjectConfig.bsv │ │ ├── SharedMemoryFifoCheck.bsv │ │ └── make.sh │ ├── bluecheck_harness/ │ │ ├── Harness.bsv │ │ ├── Makefile │ │ └── harness.py │ ├── bpiflash/ │ │ ├── BpiFlashTest.bsv │ │ ├── I28F512P33.bsv │ │ ├── Makefile │ │ ├── bpiflash.h │ │ ├── bpiflash.json │ │ ├── i28f512p33.v │ │ └── testbpiflash.cpp │ ├── ddr3/ │ │ ├── Ddr3Test.bsv │ │ ├── Makefile │ │ ├── synth-ip.tcl │ │ └── testddr3.cpp │ ├── ddr3_altera/ │ │ ├── Ddr3Test.bsv │ │ ├── Makefile │ │ ├── de5.json │ │ ├── synth-ip.tcl │ │ └── testddr3.cpp │ ├── ddr_minimal/ │ │ ├── Ddr3Test.bsv │ │ ├── Makefile │ │ ├── synth-ip.tcl │ │ └── testddr3.cpp │ ├── dma2bram/ │ │ ├── Makefile │ │ ├── Test.bsv │ │ └── test.cpp │ ├── dram_awsf1/ │ │ ├── Axi4.bsv │ │ ├── DdrAws.bsv │ │ ├── Makefile │ │ └── testddr3.cpp │ ├── echosoft2/ │ │ ├── EchoId.bsv │ │ ├── Makefile │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── fastecho/ │ │ ├── FastEcho.bsv │ │ ├── Makefile │ │ ├── about_this_test.txt │ │ ├── synth-ip.tcl │ │ └── testfastecho.cpp │ ├── float/ │ │ ├── FloatTest.bsv │ │ ├── Makefile │ │ └── ftest.c │ ├── fp/ │ │ ├── BviFpAdd.bsv │ │ ├── FpOps.bsv │ │ ├── FpTest.bsv │ │ ├── Makefile │ │ ├── synth-ip.tcl │ │ └── testfp.cpp │ ├── guard/ │ │ ├── GuardTest.bsv │ │ ├── Makefile │ │ └── gtest.c │ ├── ipcperf/ │ │ ├── IpcTest.bsv │ │ ├── Makefile │ │ ├── testipctest.cpp │ │ └── vc707_floorplan.xdc │ ├── memcpy_manysglists/ │ │ ├── Makefile │ │ ├── Top.bsv │ │ └── testmemcpy.cpp │ ├── memread_err/ │ │ ├── Makefile │ │ ├── Memread.bsv │ │ └── testmemread.cpp │ ├── memread_manual/ │ │ ├── Makefile │ │ ├── ReadTest.bsv │ │ ├── design_vc707.tcl │ │ ├── kernel/ │ │ │ └── Makefile │ │ ├── memread_manual_manager.c │ │ └── vc707_floorplan.xdc │ ├── memread_manyclients/ │ │ ├── Makefile │ │ └── performance.txt │ ├── memread_manyclients128/ │ │ └── Makefile │ ├── memread_manyengines/ │ │ ├── Makefile │ │ └── ReadTest.bsv │ ├── memserver_copy/ │ │ ├── Makefile │ │ ├── Memcopy.bsv │ │ └── testmemcopy.cpp │ ├── memserver_copy128/ │ │ └── Makefile │ ├── memserver_copy_slow/ │ │ └── Makefile │ ├── memserver_write/ │ │ ├── Makefile │ │ ├── Memwrite.bsv │ │ └── testmemwrite.cpp │ ├── memserver_write128/ │ │ └── Makefile │ ├── memtopcie_bluesim/ │ │ ├── Makefile │ │ └── Top.bsv │ ├── memwrite_acp/ │ │ ├── Makefile │ │ ├── Memwrite.bsv │ │ └── testmemwrite.cpp │ ├── memwrite_manyclients/ │ │ └── Makefile │ ├── memwrite_manyclients128/ │ │ └── Makefile │ ├── memwrite_trivial/ │ │ ├── Makefile │ │ ├── Memwrite.bsv │ │ └── testmemwrite.cpp │ ├── memwriteengine_test/ │ │ ├── Makefile │ │ ├── MemWriteEngineTest.bsv │ │ ├── Memwrite.bsv │ │ └── testmemwrite.cpp │ ├── method/ │ │ ├── Makefile │ │ ├── Method.bsv │ │ └── mtest.cpp │ ├── mifo/ │ │ ├── Makefile │ │ ├── MifoTest.bsv │ │ └── testmifo.cpp │ ├── nandsim_manual/ │ │ ├── Makefile │ │ ├── kernel/ │ │ │ └── Makefile │ │ ├── nandsim_manual.c │ │ ├── testnandsim.cpp │ │ └── testnandsim_test.cpp │ ├── nvme_core/ │ │ └── string_search.cpp │ ├── nvme_strstr/ │ │ ├── Makefile │ │ ├── NvmeSearch.bsv │ │ ├── StringSearchIfc.bsv │ │ ├── fmc.json │ │ ├── main.cpp │ │ ├── nfsume.json │ │ ├── nvme.json │ │ ├── nvme.xdc │ │ ├── package100.tcl │ │ └── synth-ip.tcl │ ├── nvme_test/ │ │ ├── Makefile │ │ ├── NvmeTest.bsv │ │ ├── fmc.json │ │ ├── impl.tcl │ │ ├── main.cpp │ │ ├── miniitx100.json │ │ ├── nfsume.json │ │ ├── nfsume.xdc │ │ ├── nvme.xdc │ │ └── synth-ip.tcl │ ├── ov7670/ │ │ ├── Makefile │ │ ├── Ov7670Controller.bsv │ │ ├── Ov7670Interface.bsv │ │ ├── SCCB.bsv │ │ ├── pinout.json │ │ └── testcam.cpp │ ├── partial/ │ │ ├── Bounce.bsv │ │ ├── Bounce1.bsv │ │ ├── Bounce2.bsv │ │ ├── Bounce3.bsv │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── README │ │ ├── floorplan-zc702.xdc │ │ └── testecho.cpp │ ├── pcie-debug/ │ │ ├── Makefile │ │ ├── TestPins.bsv │ │ ├── TracePcie.bsv │ │ ├── pin_translation.json │ │ └── tracepcie.cpp │ ├── pciememcheck/ │ │ ├── CheckMPM.bsv │ │ ├── Makefile │ │ ├── PcieMemCheck.bsv │ │ └── pciememcheck.cpp │ ├── physmaster/ │ │ ├── Echo.bsv │ │ ├── Makefile │ │ ├── PhysReq.bsv │ │ ├── daemon.cpp │ │ └── testecho.cpp │ ├── qemuaccel/ │ │ ├── AccelIfcNames.bsv │ │ ├── AccelTop.bsv │ │ ├── BlockDev.bsv │ │ ├── Devices.bsv │ │ ├── Makefile │ │ ├── QemuAccel.bsv │ │ ├── QemuAccelIfc.bsv │ │ ├── Serial.bsv │ │ └── qemuaccel.cpp │ ├── rootport/ │ │ ├── AxiPcieRootPort.bsv │ │ ├── Makefile │ │ ├── RootPort.bsv │ │ ├── RootPortIfc.bsv │ │ ├── RootPortPins.bsv │ │ ├── gencores.tcl │ │ ├── rootport.cpp │ │ ├── rootport.json │ │ └── rootport.xdc │ ├── serialportal/ │ │ ├── Makefile │ │ ├── SerialPortalIfc.bsv │ │ ├── SerialPortalTest.bsv │ │ ├── rs232.json │ │ └── serialportal.cpp │ ├── simmethodtime/ │ │ ├── Makefile │ │ ├── Simm.bsv │ │ └── test.cpp │ ├── simple_manual/ │ │ ├── Makefile │ │ ├── Simple.bsv │ │ ├── kernel/ │ │ │ └── Makefile │ │ ├── simple_manual.c │ │ └── testsimple.cpp │ ├── spi/ │ │ ├── ConnectalProjectConfig.bsv │ │ ├── Makefile │ │ └── spitest.gtkw │ ├── spikehw/ │ │ ├── AxiEthBufferBvi.bsv │ │ ├── AxiEthSubsystem.bsv │ │ ├── AxiIic.bsv │ │ ├── AxiSpiBvi.bsv │ │ ├── AxiUart.bsv │ │ ├── GigEthPcsPmaBvi.bsv │ │ ├── Makefile │ │ ├── README.md │ │ ├── SpikeHw.bsv │ │ ├── SpikeHwIfc.bsv │ │ ├── SpikeHwPins.bsv │ │ ├── SyncAxisFifo32x1024.bsv │ │ ├── TriModeMacBvi.bsv │ │ ├── boot/ │ │ │ ├── Makefile │ │ │ ├── copybbl.c │ │ │ └── entry.S │ │ ├── bootromx4.hex │ │ ├── eth.json │ │ ├── flash.json │ │ ├── gencores.tcl │ │ ├── geneth.tcl │ │ ├── i2c-standard.json │ │ ├── nfsume.json │ │ ├── program.tcl │ │ ├── rtscts.json │ │ ├── spikehw-miniitx100.json │ │ ├── spikehw-vc707g2.json │ │ ├── spikehw-vc709.json │ │ ├── spikehw.cpp │ │ ├── spikehw.h │ │ ├── spikehw.json │ │ ├── spikehw.xdc │ │ ├── test-spikehw.cpp │ │ └── trace.tcl │ ├── test_pmod/ │ │ ├── Controller.bsv │ │ ├── Makefile │ │ ├── Top.bsv │ │ ├── pinout.json │ │ └── testpmod.cpp │ ├── test_sdio1/ │ │ ├── Makefile │ │ ├── SDIO.bsv │ │ ├── Top.bsv │ │ ├── pinout.json │ │ └── test_sdio1.cpp │ ├── test_spi0/ │ │ ├── Makefile │ │ ├── SPI.bsv │ │ ├── Top.bsv │ │ ├── foo.cpp │ │ └── test_spi0.cpp │ ├── testfpmul/ │ │ ├── Makefile │ │ ├── Top.bsv │ │ └── testfpmul.cpp │ ├── testldstrex/ │ │ ├── Makefile │ │ └── testldstrex.cpp │ ├── testmm16.16.2/ │ │ └── Makefile │ ├── testmm16.16.4/ │ │ └── Makefile │ ├── testmm2.4.2/ │ │ ├── Makefile │ │ └── zc706_floorplan.xdc │ ├── testmm32.16.2/ │ │ └── Makefile │ ├── testmm32.32.2/ │ │ └── Makefile │ ├── testmm4.2.2/ │ │ └── Makefile │ ├── testmm4.4.2/ │ │ └── Makefile │ ├── testmm4.4.4/ │ │ └── Makefile │ ├── testmm8.8.2/ │ │ ├── Makefile │ │ └── zc706_floorplan.xdc │ ├── testmm8.8.4/ │ │ └── Makefile │ ├── testmm_cuda_perf/ │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── cuda_opencv_example/ │ │ │ ├── Makefile │ │ │ ├── main.cpp │ │ │ └── main.cu │ │ ├── run_exe │ │ ├── synth-ip.tcl │ │ └── zc706_floorplan.xdc │ ├── testrbm16.16.2/ │ │ ├── Makefile │ │ └── synth-ip.tcl │ ├── testrbm8.8.2/ │ │ ├── Makefile │ │ └── synth-ip.tcl │ └── yuv/ │ ├── Makefile │ ├── YuvIF.bsv │ └── testyuv.cpp └── verilog/ ├── CONNECTNET.v ├── CONNECTNET2.v ├── FpgaReset.v ├── GenBIBUF.v ├── LinkInverter.v ├── PositiveReset.v ├── PutInverter.v ├── SyncFIFO.v ├── SyncFIFO1.v ├── SyncReset.v ├── XsimDmaReadWrite.sv ├── XsimFinish.sv ├── XsimLink.sv ├── XsimSink.sv ├── XsimSource.sv ├── altera/ │ ├── BRAM1.v │ ├── BRAM1BE.v │ ├── BRAM2.v │ └── siv_gen2x8/ │ └── siv_gen2x8.v ├── awsf1.sv ├── cl_id_defines.vh └── xsimtop.sv ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *~ *.pyc *.o lextab.py parselog.txt parser.out parsetab.py *.bo *.so *.ba *.cmd *.mod.c *.ko Module.symvers *.jou *.log .build mk*.cxx mk*.h *.bspec model_*.cxx model_*.h mk*.sched mk*.v modules.order xilinx/pcie_7x_v2_1 examples/*/ac701 examples/*/kc705 examples/*/vc707 examples/*/zc702 examples/*/zc706 examples/*/de5 examples/*/htg4 examples/*/zedboard examples/*/zybo generated/xilinx/* dkms.conf.out *.vcd bluesim xsim vc709 vc707 vc707g2 usage_statistics_webtalk.* vivado_pid* nfsume .cache ubuntu.exe *signature_file.h .tmp_versions .Xil *.mcs verilator zc706 *.png *.bit *.prm zedboard miniitx100 *.pb kc705g2 ac701g2 *.ltx zedboard_ubuntu ================================================ FILE: .travis.yml ================================================ language: cpp cache: directories: before_script: - if [ -d Bluespec-2018.10.beta1 ] ; then echo bluespec cached; else curl http://buildbot.connectal.org/downloads/Bluespec-2018.10.beta1.tar.gz | tar -zxf - ; fi - mkdir -p lib - ln -s /usr/lib/x86_64-linux-gnu/libgmp.so.10 lib/libgmp.so.3 - if [ "$CONNECTAL_ARCH" == "cvc" ]; then if [ -d open-src-cvc-700c-1 ] ; then echo cvc cached; else curl -L https://github.com/cambridgehackers/open-src-cvc/archive/700c-1.tar.gz | tar -zxf - ; (cd open-src-cvc-700c-1/src; make -j4 -f makefile.cvc64); fi; fi - (if [ "$CONNECTAL_ARCH" == "verilator" ]; then curl -L http://www.veripool.org/ftp/verilator-3.888.tgz | tar -zxf -; cd verilator-3.888/; ./configure --prefix=`dirname $PWD`/verilator; make -j4; make install; fi) - curl http://www.dabeaz.com/ply/ply-3.9.tar.gz | tar -zxf - - ln -s ../ply-3.9/ply scripts - ls -l scripts/ply env: global: - BLUESPECDIR=$PWD/Bluespec-2018.10.beta1/lib - PATH=$PATH:$PWD/Bluespec-2018.10.beta1/bin:$PWD/open-src-cvc-700c-1/src:$PWD/verilator/bin - LD_LIBRARY_PATH=$PWD/lib matrix: - CONNECTAL_TEST=examples/echo CONNECTAL_ARCH=verilator - CONNECTAL_TEST=examples/echopy CONNECTAL_ARCH=verilator - CONNECTAL_TEST=examples/echo CONNECTAL_ARCH=cvc - CONNECTAL_TEST=examples/echopy CONNECTAL_ARCH=cvc - CONNECTAL_TEST=examples/echoslow CONNECTAL_ARCH=verilator - CONNECTAL_TEST=examples/echoslow CONNECTAL_ARCH=cvc - CONNECTAL_TEST=examples/simple CONNECTAL_ARCH=bluesim - CONNECTAL_TEST=examples/simple CONNECTAL_ARCH=verilator - CONNECTAL_TEST=examples/simple CONNECTAL_ARCH=cvc - CONNECTAL_TEST=examples/memcpy CONNECTAL_ARCH=bluesim - CONNECTAL_TEST=examples/memcpy CONNECTAL_ARCH=verilator - CONNECTAL_TEST=examples/memcpy CONNECTAL_ARCH=cvc - CONNECTAL_TEST=examples/strstr CONNECTAL_ARCH=bluesim - CONNECTAL_TEST=tests/memserver_write128 CONNECTAL_ARCH=verilator - CONNECTAL_TEST=tests/memserver_copy128 CONNECTAL_ARCH=verilator script: - export PYTHONPATH=$PWD/scripts; make scripts/syntax/parsetab.py; cd $CONNECTAL_TEST; make build.$CONNECTAL_ARCH run.$CONNECTAL_ARCH sudo: no dist: trusty os: - linux addons: apt: sources: - sourceline: 'ppa:jamey-hicks/connectal' packages: - python-dev - libgmp10 - libjsoncpp-dev - flex - bison notifications: email: false irc: channels: - chat.freenode.net#connectal slack: secure: mQApKri2F2TZEyLEs530x+snMA8aDdL6o0e/HCVqk3t4pfSfj2OfPQ5edVrvIh+dsFjhX1GNDk94LSmZTS6AVCQ4+VPXORN1VjvB+xIeyP/PsIjSUoWqvS2V0t8CYV5K+5HRJq2H7tNmY4wxZYQnPAAGplsrKgJBxjccMhSqO30= ================================================ FILE: LICENSE.txt ================================================ Copyright (c) 2012 Nokia, Inc. Copyright (c) 2013-2015 Quanta Research Cambridge, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # include Makefile.version export UDEV_RULES_DIR=/etc/udev/rules.d UDEV_RULES=$(shell ls etc/udev/rules.d) MODULES_LOAD_D_DIR=/etc/modules-load.d all: pciedrivers scripts/syntax/parsetab.py echo version "$(VERSION)" pciedrivers: (cd drivers/pcieportal; make) make -C pcie pciedrivers-clean: (cd drivers/pcieportal; make clean) make -C pcie clean ifneq ("$(DESTDIR)", "") INSTALL_SHARED = install-shared endif install: $(INSTALL_SHARED) install -d -m755 $(DESTDIR)/$(UDEV_RULES_DIR) $(DESTDIR)/etc/modules-load.d if [ -d $(DESTDIR)/$(MODULES_LOAD_D_DIR) ]; then \ for fname in ./$(MODULES_LOAD_D_DIR)/* ; do \ install -m644 $$fname $(DESTDIR)$(MODULES_LOAD_D_DIR) ; \ done; \ fi echo 'Installing from' $(CURDIR) (cd drivers/pcieportal; CONNECTALDIR=$(CURDIR) make install) install -m644 etc/modules-load.d/connectal.conf $(DESTDIR)/etc/modules-load.d make -C pcie install install -d -m755 $(DESTDIR)$(UDEV_RULES_DIR) for fname in $(UDEV_RULES) ; do \ install -m644 etc/udev/rules.d/$$fname $(DESTDIR)$(UDEV_RULES_DIR) ; \ done ifeq ( _$(DESTDIR), _) service udev restart; rmmod portalmem; rmmod pcieportal; modprobe portalmem; modprobe pcieportal; endif INSTALL_DIRS = $(shell ls | grep -v debian) install-shared: find $(INSTALL_DIRS) -type d -exec install -d -m755 $(DESTDIR)/usr/share/connectal/{} \; -print find $(INSTALL_DIRS) -type f -exec install -m644 {} $(DESTDIR)/usr/share/connectal/{} \; -print chmod agu+rx $(DESTDIR)/usr/share/connectal/scripts/* uninstall: for fname in ./$(MODULES_LOAD_D_DIR)/* ; do \ rm -vf $(MODULES_LOAD_D_DIR)/`basename $$fname` ; \ done; (cd drivers/pcieportal; make uninstall) make -C pcie/connectalutil uninstall for fname in $(UDEV_RULES) ; do \ rm -f $(UDEV_RULES_DIR)/$$fname ; \ done service udev restart docs: doxygen scripts/Doxyfile spkg: git clean -fdx git checkout debian sed -i s/precise/precise/g debian/changelog gbp buildpackage --git-upstream-branch=master --git-debian-branch=ubuntu --git-ignore-new -S -tc '--git-upstream-tag=v%(version)s' git checkout debian sed -i s/precise/trusty/g debian/changelog gbp buildpackage --git-upstream-branch=master --git-debian-branch=ubuntu --git-ignore-new -S -tc '--git-upstream-tag=v%(version)s' git checkout debian sed -i s/precise/xenial/g debian/changelog gbp buildpackage --git-upstream-branch=master --git-debian-branch=ubuntu --git-ignore-new -S -tc '--git-upstream-tag=v%(version)s' git checkout debian sed -i s/precise/artful/g debian/changelog gbp buildpackage --git-upstream-branch=master --git-debian-branch=ubuntu --git-ignore-new -S -tc '--git-upstream-tag=v%(version)s' git checkout debian upload: git push origin v$(VERSION) (cd ../obs/home:jameyhicks:connectaldeb/connectal/; osc rm * || true) cp -v ../connectal_$(VERSION)*stable*.diff.gz ../connectal_$(VERSION)*stable*.dsc ../connectal_$(VERSION)*.orig.tar.gz ../obs/home:jameyhicks:connectaldeb/connectal/ rm -fv ../connectal_$(VERSION)*stable* dput ppa:jamey-hicks/connectal ../connectal_$(VERSION)-*_source.changes (cd ../obs/home:jameyhicks:connectaldeb/connectal/; osc add *; osc commit -m $(VERSION) ) (cd ../obs/home:jameyhicks:connectal/connectal; sed -i "s/>v.....v$(VERSION) make run. where target is Command suffix | Function --------------|---------- bluesim | compile for simulation zedboard| compile for zedboard zybo| compile for zybo zc702| compile for zc702 board zc706| compile for zc706 board kc705| compile for kc705 board vc707| compile for vc707 board vc709| compile for vc709 board nfsume| compile for NetFPGA-SUME board To turn on more verbosity for debugging when running make, add V=1 to command line, as make examples/examplename. V=1 or V=1 make examples/examplename. To run the example on a machine different than the build machine, use RUNPARAM=hostname-or-addr: make RUNPARAM=zedtest run.zedboard make RUNPARAM=192.168.1.123 run.vc707 ### Bitstream Packaging The FPGA bitstream is included in the application executable, and the FPGA is automatically programmed when the application is run: cd examples/echo make build.vc707 ./vc707/bin/ubuntu.exe We are running Android on the Zynq devices and so the application executable is called android.exe. ### Echo Example ## this has only been tested with the Vivado 2013.2 release . Xilinx/Vivado/2013.2/settings64.sh make -C examples/echo build..zedboard or make -C examples/echo build.zc702 or make -C examples/echo build.kc705 or make -C examples/echo build.vc707 To run on a zedboard with IP address aa.bb.cc.dd: RUNPARAM=aa.bb.cc.dd make -C examples/echo run.zedboard ### Memcpy Example make -C examples/memcpy build.vc707 [![Analytics](https://ga-beacon.appspot.com/UA-15845210-3/connectal/README.md)](https://github.com/igrigorik/ga-beacon) ================================================ FILE: boardinfo/ac701.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Artix7", "PCIE", "PCIE1", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=4", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7a200tfbg676-2", "need_pcie" : "x7_gen1x8", "TOP" : "PcieTop", "constraints": [], "implconstraints": ["constraints/xilinx/ac701.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "uart": { "d_in": { "PACKAGE_PIN": "T19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "d_out": { "PACKAGE_PIN": "U19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "rts": { "PACKAGE_PIN": "V19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "cts": { "PACKAGE_PIN": "W19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "P19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "N19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "P23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "P21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "N24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "N23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "P24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "R20", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" } }, "fmc": { } } ================================================ FILE: boardinfo/ac701_untethered.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Artix7", "PhysAddrWidth=40", "PcieLanes=4", "UNTETHERED=1", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7a200tfbg676-2", "TOP" : "UntetheredTop", "constraints": [], "implconstraints": ["constraints/xilinx/ac701.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "uart": { "d_in": { "PACKAGE_PIN": "T19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "d_out": { "PACKAGE_PIN": "U19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "rts": { "PACKAGE_PIN": "V19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "cts": { "PACKAGE_PIN": "W19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "P19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "N19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "P23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "P21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "N24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "N23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "P24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "R20", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" } }, "fmc": { }, "pins": { "cpu_reset": { "PACKAGE_PIN": "U4", "IOSTANDARD": "LVCMOS15", "PIO_DIRECTION": "INPUT" } } } ================================================ FILE: boardinfo/ac701g2.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Artix7", "PCIE", "PCIE2", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=4", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7a200tfbg676-2", "need_pcie" : "x7_gen2x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/ac701.xdc", "constraints/xilinx/pcie-clocks.xdc"], "implconstraints": ["constraints/xilinx/ac701.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "fmc": { } } ================================================ FILE: boardinfo/asic.json ================================================ { "options": { "os" : "ubuntu", "partname" : "asic", "rewireclockstring" : "", "TOP" : "AsicTop", "bsvdefines": ["ASIC", "CnocTop", "XsimHostInterface", "PhysAddrWidth=32"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/awsf1.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "VirtexUltrascale", "PhysAddrWidth=40", "DataBusWidth=512", "XsimHostInterface", "AWSF1=1", "MemTagSize=16", "MemServerTags=8", "DEFAULT_NOPROGRAM=1", "CONNECTAL_BITS_DEPENDENCES=build/checkpoints/to_aws/mkTop.SH_CL_routed.dcp", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.aws"], "os" : "ubuntu", "partname" : "xcvu9p-flgb2104-2-i", "TOP" : "AwsF1Top", "constraints": ["constraints/xilinx/awsf1.xdc"], "implconstraints": ["constraints/xilinx/awsf1.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=8", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "pins": { } } ================================================ FILE: boardinfo/bluesim.json ================================================ { "options": { "os" : "ubuntu", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "TOP" : "XsimTop", "bsvdefines": ["CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "SIMULATION", "CONNECTAL_BITS_DEPENDENCES=bsim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" }, "fmc": { "CLK0_M2C_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "CLK0_M2C_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA00_n_CC": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA00_p_CC": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA01_n_CC": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA05_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA05_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA07_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA07_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA08_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA08_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA09_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA09_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA10_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA10_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA11_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA11_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA12_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA12_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA13_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA13_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA14_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA14_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA15_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA15_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA16_n": { "LOC": "ZZZ", "IOSTANDARD": "YY" }, "LA16_p": { "LOC": "ZZZ", "IOSTANDARD": "YY" } }, "pins": { "GPIO_sw_left": {"PACKAGE_PIN": "XXXX","IOSTANDARD": "YYYY","slew": "ZZZZ","PIO_DIRECTION": "INPUT"}, "GPIO_sw_center": {"PACKAGE_PIN": "XXXX","IOSTANDARD": "YYYY","slew": "ZZZZ","PIO_DIRECTION": "INPUT"}, "GPIO_sw_right": {"PACKAGE_PIN": "XXXX","IOSTANDARD": "YYYY","slew": "ZZZZ","PIO_DIRECTION": "INPUT"}, "GPIO_sw_down": {"PACKAGE_PIN": "XXXX","IOSTANDARD": "YYYY","slew": "ZZZZ","PIO_DIRECTION": "INPUT"}, "GPIO_sw_up": {"PACKAGE_PIN": "XXXX","IOSTANDARD": "YYYY","slew": "ZZZZ","PIO_DIRECTION": "INPUT"} }, "pmoda" : { "J1" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J2" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J3" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J4" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J7" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J8" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J9" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J10" : { "LOC" : "XX", "IOSTANDARD" : "YY"} }, "pmodb" : { "J1" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J2" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J3" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J4" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J7" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J8" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J9" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J10" : { "LOC" : "XX", "IOSTANDARD" : "YY"} }, "pmodc" : { "J1" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J2" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J3" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J4" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J7" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J8" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J9" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J10" : { "LOC" : "XX", "IOSTANDARD" : "YY"} }, "pmodd" : { "J1" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J2" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J3" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J4" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J7" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J8" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J9" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J10" : { "LOC" : "XX", "IOSTANDARD" : "YY"} }, "pmode" : { "J1" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J2" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J3" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J4" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J7" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J8" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J9" : { "LOC" : "XX", "IOSTANDARD" : "YY"}, "J10" : { "LOC" : "XX", "IOSTANDARD" : "YY"} }, "leds" : { "L0" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "LOC" : "XX", "IOSTANDARD" : "YY", "PIO_DIRECTION" : "OUTPUT" } } } ================================================ FILE: boardinfo/cvc.json ================================================ { "options": { "os" : "ubuntu", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "TOP" : "XsimTop", "bsvdefines": ["CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "SIMULATION", "SVDPI", "CONNECTAL_BITS_DEPENDENCES=cvcsim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/de5.json ================================================ { "options": { "bsvdefines" : ["ALTERA=1", "StratixV", "PCIE", "PCIE_NO_BSCAN", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=4", "NUMBER_OF_10G_PORTS=4", "SYNTHESIS", "PcieLanes=8", "DEFAULT_NOPROGRAM=1", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest.altera"], "os" : "ubuntu", "partname" : "5SGXEA7N2F45C2", "need_pcie" : "s5_gen2x8", "TOP" : "PcieTop", "constraints": ["constraints/altera/de5.sdc"], "runscript" : "run.pcietest.altera", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "BUTTON": { "BUTTON[0]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AK15" }, "BUTTON[1]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AK14" }, "BUTTON[2]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AL14" }, "BUTTON[3]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AL15" } }, "I2C": { "CLOCK_SCL": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AE15" }, "CLOCK_SDA": { "PIO_DIRECTION": "BIDIR", "IO_STANDARD": "2.5 V", "LOC": "PIN_AE16" } }, "CPU": { "CPU_RESET_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BC37" } }, "DDR3A": { "DDR3A_A[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M39" }, "DDR3A_A[10]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M38" }, "DDR3A_A[11]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C37" }, "DDR3A_A[12]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K36" }, "DDR3A_A[13]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M33" }, "DDR3A_A[14]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K34" }, "DDR3A_A[15]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B38" }, "DDR3A_A[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L35" }, "DDR3A_A[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N38" }, "DDR3A_A[3]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L36" }, "DDR3A_A[4]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H36" }, "DDR3A_A[5]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K29" }, "DDR3A_A[6]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D37" }, "DDR3A_A[7]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K35" }, "DDR3A_A[8]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K32" }, "DDR3A_A[9]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K37" }, "DDR3A_BA[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M37" }, "DDR3A_BA[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P39" }, "DDR3A_BA[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J36" }, "DDR3A_CAS_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M36" }, "DDR3A_CKE[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E36" }, "DDR3A_CKE[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B35" }, "DDR3A_CK[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_G37" }, "DDR3A_CK[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_J37" }, "DDR3A_CK_n[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_F36" }, "DDR3A_CK_n[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_H37" }, "DDR3A_CS_n[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P36" }, "DDR3A_CS_n[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R28" }, "DDR3A_DM[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C36" }, "DDR3A_DM[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E32" }, "DDR3A_DM[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H34" }, "DDR3A_DM[3]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L32" }, "DDR3A_DM[4]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N32" }, "DDR3A_DM[5]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W32" }, "DDR3A_DM[6]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K30" }, "DDR3A_DM[7]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T28" }, "DDR3A_DQS[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_C34" }, "DDR3A_DQS[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_C31" }, "DDR3A_DQS[2]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_H35" }, "DDR3A_DQS[3]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_U35" }, "DDR3A_DQS[4]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_T33" }, "DDR3A_DQS[5]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_T30" }, "DDR3A_DQS[6]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_J30" }, "DDR3A_DQS[7]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_Y30" }, "DDR3A_DQS_n[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_B34" }, "DDR3A_DQS_n[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_B31" }, "DDR3A_DQS_n[2]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_G35" }, "DDR3A_DQS_n[3]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_T35" }, "DDR3A_DQS_n[4]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_T32" }, "DDR3A_DQS_n[5]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_R30" }, "DDR3A_DQS_n[6]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_H30" }, "DDR3A_DQS_n[7]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_Y29" }, "DDR3A_DQ[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A35" }, "DDR3A_DQ[10]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C30" }, "DDR3A_DQ[11]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D30" }, "DDR3A_DQ[12]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B29" }, "DDR3A_DQ[13]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E30" }, "DDR3A_DQ[14]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F31" }, "DDR3A_DQ[15]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G31" }, "DDR3A_DQ[16]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F35" }, "DDR3A_DQ[17]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G34" }, "DDR3A_DQ[18]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J33" }, "DDR3A_DQ[19]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J34" }, "DDR3A_DQ[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A34" }, "DDR3A_DQ[20]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F34" }, "DDR3A_DQ[21]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E35" }, "DDR3A_DQ[22]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J31" }, "DDR3A_DQ[23]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K31" }, "DDR3A_DQ[24]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P34" }, "DDR3A_DQ[25]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R33" }, "DDR3A_DQ[26]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M34" }, "DDR3A_DQ[27]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L33" }, "DDR3A_DQ[28]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R34" }, "DDR3A_DQ[29]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T34" }, "DDR3A_DQ[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D36" }, "DDR3A_DQ[30]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W34" }, "DDR3A_DQ[31]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V35" }, "DDR3A_DQ[32]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P33" }, "DDR3A_DQ[33]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P32" }, "DDR3A_DQ[34]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V33" }, "DDR3A_DQ[35]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V34" }, "DDR3A_DQ[36]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N31" }, "DDR3A_DQ[37]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M31" }, "DDR3A_DQ[38]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U32" }, "DDR3A_DQ[39]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U33" }, "DDR3A_DQ[3]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C33" }, "DDR3A_DQ[40]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R31" }, "DDR3A_DQ[41]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W31" }, "DDR3A_DQ[42]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U30" }, "DDR3A_DQ[43]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P31" }, "DDR3A_DQ[44]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T31" }, "DDR3A_DQ[45]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_Y32" }, "DDR3A_DQ[46]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T29" }, "DDR3A_DQ[47]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P30" }, "DDR3A_DQ[48]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H32" }, "DDR3A_DQ[49]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H31" }, "DDR3A_DQ[4]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B32" }, "DDR3A_DQ[50]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L30" }, "DDR3A_DQ[51]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L29" }, "DDR3A_DQ[52]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F32" }, "DDR3A_DQ[53]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G32" }, "DDR3A_DQ[54]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M30" }, "DDR3A_DQ[55]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N29" }, "DDR3A_DQ[56]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U29" }, "DDR3A_DQ[57]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V28" }, "DDR3A_DQ[58]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_Y28" }, "DDR3A_DQ[59]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W29" }, "DDR3A_DQ[5]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D35" }, "DDR3A_DQ[60]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V30" }, "DDR3A_DQ[61]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V29" }, "DDR3A_DQ[62]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W28" }, "DDR3A_DQ[63]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_Y27" }, "DDR3A_DQ[6]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D33" }, "DDR3A_DQ[7]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E33" }, "DDR3A_DQ[8]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A32" }, "DDR3A_DQ[9]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A31" }, "DDR3A_EVENT_n": { "IO_STANDARD": "1.5 V", "LOC": "PIN_K19" }, "DDR3A_ODT[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V36" }, "DDR3A_ODT[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W35" }, "DDR3A_RAS_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P38" }, "DDR3A_RESET_n": { "IO_STANDARD": "1.5 V", "LOC": "PIN_H33" }, "DDR3A_SCL": { "IO_STANDARD": "1.5 V", "LOC": "PIN_C15" }, "DDR3A_SDA": { "IO_STANDARD": "1.5 V", "LOC": "PIN_P15" }, "DDR3A_WE_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N37" } }, "DDR3B": { "DDR3B_A[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G17" }, "DDR3B_A[10]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C19" }, "DDR3B_A[11]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R18" }, "DDR3B_A[12]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K18" }, "DDR3B_A[13]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E18" }, "DDR3B_A[14]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T19" }, "DDR3B_A[15]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R19" }, "DDR3B_A[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F17" }, "DDR3B_A[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N17" }, "DDR3B_A[3]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F19" }, "DDR3B_A[4]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N19" }, "DDR3B_A[5]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H16" }, "DDR3B_A[6]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M17" }, "DDR3B_A[7]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T18" }, "DDR3B_A[8]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H17" }, "DDR3B_A[9]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J19" }, "DDR3B_BA[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C18" }, "DDR3B_BA[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G19" }, "DDR3B_BA[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M20" }, "DDR3B_CAS_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A17" }, "DDR3B_CKE[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P17" }, "DDR3B_CKE[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V18" }, "DDR3B_CK[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_B16" }, "DDR3B_CK[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_E17" }, "DDR3B_CK_n[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_A16" }, "DDR3B_CK_n[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_D17" }, "DDR3B_CS_n[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B19" }, "DDR3B_CS_n[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B17" }, "DDR3B_DM[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R15" }, "DDR3B_DM[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K15" }, "DDR3B_DM[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V12" }, "DDR3B_DM[3]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G10" }, "DDR3B_DM[4]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T12" }, "DDR3B_DM[5]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C16" }, "DDR3B_DM[6]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H15" }, "DDR3B_DM[7]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B11" }, "DDR3B_DQS[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_Y16" }, "DDR3B_DQS[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_V17" }, "DDR3B_DQS[2]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_P14" }, "DDR3B_DQS[3]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_K11" }, "DDR3B_DQS[4]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_U9" }, "DDR3B_DQS[5]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_E15" }, "DDR3B_DQS[6]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_L15" }, "DDR3B_DQS[7]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_D12" }, "DDR3B_DQS_n[0]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_W16" }, "DDR3B_DQS_n[1]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_U17" }, "DDR3B_DQS_n[2]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_N14" }, "DDR3B_DQS_n[3]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_L11" }, "DDR3B_DQS_n[4]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_T9" }, "DDR3B_DQS_n[5]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_D15" }, "DDR3B_DQS_n[6]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_K14" }, "DDR3B_DQS_n[7]": { "IO_STANDARD": "DIFFERENTIAL 1.5-V SSTL CLASS I", "LOC": "PIN_C12" }, "DDR3B_DQ[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_Y17" }, "DDR3B_DQ[10]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R16" }, "DDR3B_DQ[11]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P16" }, "DDR3B_DQ[12]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N16" }, "DDR3B_DQ[13]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M15" }, "DDR3B_DQ[14]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M14" }, "DDR3B_DQ[15]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L14" }, "DDR3B_DQ[16]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T14" }, "DDR3B_DQ[17]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U14" }, "DDR3B_DQ[18]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U11" }, "DDR3B_DQ[19]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T13" }, "DDR3B_DQ[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W17" }, "DDR3B_DQ[20]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U12" }, "DDR3B_DQ[21]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R13" }, "DDR3B_DQ[22]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P13" }, "DDR3B_DQ[23]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N13" }, "DDR3B_DQ[24]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K12" }, "DDR3B_DQ[25]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J12" }, "DDR3B_DQ[26]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J10" }, "DDR3B_DQ[27]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H12" }, "DDR3B_DQ[28]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_N11" }, "DDR3B_DQ[29]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M11" }, "DDR3B_DQ[2]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V15" }, "DDR3B_DQ[30]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H10" }, "DDR3B_DQ[31]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H11" }, "DDR3B_DQ[32]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T10" }, "DDR3B_DQ[33]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R10" }, "DDR3B_DQ[34]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M12" }, "DDR3B_DQ[35]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_L12" }, "DDR3B_DQ[36]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V10" }, "DDR3B_DQ[37]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V9" }, "DDR3B_DQ[38]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_R12" }, "DDR3B_DQ[39]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_P12" }, "DDR3B_DQ[3]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T15" }, "DDR3B_DQ[40]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D14" }, "DDR3B_DQ[41]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C13" }, "DDR3B_DQ[42]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B14" }, "DDR3B_DQ[43]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B13" }, "DDR3B_DQ[44]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E14" }, "DDR3B_DQ[45]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F14" }, "DDR3B_DQ[46]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A14" }, "DDR3B_DQ[47]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A13" }, "DDR3B_DQ[48]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K13" }, "DDR3B_DQ[49]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_K16" }, "DDR3B_DQ[4]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V13" }, "DDR3B_DQ[50]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H13" }, "DDR3B_DQ[51]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H14" }, "DDR3B_DQ[52]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J13" }, "DDR3B_DQ[53]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_J16" }, "DDR3B_DQ[54]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G13" }, "DDR3B_DQ[55]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F13" }, "DDR3B_DQ[56]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D11" }, "DDR3B_DQ[57]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_C10" }, "DDR3B_DQ[58]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A10" }, "DDR3B_DQ[59]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_B10" }, "DDR3B_DQ[5]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_V16" }, "DDR3B_DQ[60]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_G11" }, "DDR3B_DQ[61]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_F11" }, "DDR3B_DQ[62]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E11" }, "DDR3B_DQ[63]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_E12" }, "DDR3B_DQ[6]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_W14" }, "DDR3B_DQ[7]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_U15" }, "DDR3B_DQ[8]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T17" }, "DDR3B_DQ[9]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T16" }, "DDR3B_EVENT_n": { "IO_STANDARD": "1.5 V", "LOC": "PIN_K17" }, "DDR3B_ODT[0]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_M18" }, "DDR3B_ODT[1]": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_A19" }, "DDR3B_RAS_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_H19" }, "DDR3B_RESET_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_T20" }, "DDR3B_SCL": { "IO_STANDARD": "1.5 V", "LOC": "PIN_P18" }, "DDR3B_SDA": { "IO_STANDARD": "1.5 V", "LOC": "PIN_P19" }, "DDR3B_WE_n": { "IO_STANDARD": "SSTL-15 CLASS I", "LOC": "PIN_D18" } }, "FAN": { "FAN_CTRL": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AR32" } }, "FLASH": { "FLASH_ADV_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AK29" }, "FLASH_CE_n[0]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE27" }, "FLASH_CE_n[1]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BA31" }, "FLASH_CLK": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AL29" }, "FLASH_OE_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AY30" }, "FLASH_RDY_BSY_n[0]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BA29" }, "FLASH_RDY_BSY_n[1]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BB32" }, "FLASH_RESET_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE28" }, "FLASH_WE_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AR31" } }, "FSM": { "FSM_A[0]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AU32" }, "FSM_A[10]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AN30" }, "FSM_A[11]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AH33" }, "FSM_A[12]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AK32" }, "FSM_A[13]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AM32" }, "FSM_A[14]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AM31" }, "FSM_A[15]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AL31" }, "FSM_A[16]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AN33" }, "FSM_A[17]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AP33" }, "FSM_A[18]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AT32" }, "FSM_A[19]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AT29" }, "FSM_A[1]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AH30" }, "FSM_A[20]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AP31" }, "FSM_A[21]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AR30" }, "FSM_A[22]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AU30" }, "FSM_A[23]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AJ31" }, "FSM_A[24]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AP30" }, "FSM_A[25]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AN31" }, "FSM_A[26]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AT30" }, "FSM_A[2]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AJ30" }, "FSM_A[3]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AH31" }, "FSM_A[4]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AK30" }, "FSM_A[5]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AJ32" }, "FSM_A[6]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG33" }, "FSM_A[7]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AL30" }, "FSM_A[8]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AK33" }, "FSM_A[9]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AJ33" }, "FSM_D[0]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG26" }, "FSM_D[10]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE33" }, "FSM_D[11]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE31" }, "FSM_D[12]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF28" }, "FSM_D[13]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE30" }, "FSM_D[14]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG29" }, "FSM_D[15]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG27" }, "FSM_D[16]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AP28" }, "FSM_D[17]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AN28" }, "FSM_D[18]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AU31" }, "FSM_D[19]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AW32" }, "FSM_D[1]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AD33" }, "FSM_D[20]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BD32" }, "FSM_D[21]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AY31" }, "FSM_D[22]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BA30" }, "FSM_D[23]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BB30" }, "FSM_D[24]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AM29" }, "FSM_D[25]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AR29" }, "FSM_D[26]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AV31" }, "FSM_D[27]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AV32" }, "FSM_D[28]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BC31" }, "FSM_D[29]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AW30" }, "FSM_D[2]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE34" }, "FSM_D[30]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BC32" }, "FSM_D[31]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BD31" }, "FSM_D[3]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF31" }, "FSM_D[4]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG28" }, "FSM_D[5]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG30" }, "FSM_D[6]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF29" }, "FSM_D[7]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE29" }, "FSM_D[8]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG25" }, "FSM_D[9]": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF34" } }, "HEX0": { "HEX0_DP": { "IO_STANDARD": "1.5 V", "LOC": "PIN_P8" }, "HEX0_D[0]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_G8" }, "HEX0_D[1]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_H8" }, "HEX0_D[2]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_J9" }, "HEX0_D[3]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_K10" }, "HEX0_D[4]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_K8" }, "HEX0_D[5]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_K9" }, "HEX0_D[6]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_N8" } }, "HEX1": { "HEX1_DP": { "IO_STANDARD": "1.5 V", "LOC": "PIN_E9" }, "HEX1_D[0]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_H18" }, "HEX1_D[1]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_G16" }, "HEX1_D[2]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_F16" }, "HEX1_D[3]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_A7" }, "HEX1_D[4]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_B7" }, "HEX1_D[5]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_C9" }, "HEX1_D[6]": { "IO_STANDARD": "1.5 V", "LOC": "PIN_D10" } }, "LED": { "LED[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AW37" }, "LED[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AV37" }, "LED[2]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_BB36" }, "LED[3]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_BB39" }, "LED_BRACKET[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AH15" }, "LED_BRACKET[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AH13" }, "LED_BRACKET[2]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AJ13" }, "LED_BRACKET[3]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AJ14" }, "LED_RJ45_L": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG15" }, "LED_RJ45_R": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG16" } }, "OSC": { "OSC_50_B3B": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AW35" }, "OSC_50_B3D": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_BC28" }, "OSC_50_B4A": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_AP10" }, "OSC_50_B4D": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_AY18" }, "OSC_50_B7A": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.5 V", "LOC": "PIN_M8" }, "OSC_50_B7D": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.5 V", "LOC": "PIN_J18" }, "OSC_50_B8A": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.5 V", "LOC": "PIN_R36" }, "OSC_50_B8D": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_R25" } }, "PCIE": { "PCIE_PERST_n": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_AU33" }, "PCIE_REFCLK_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "HCSL", "LOC": "PIN_AK38" }, "PCIE_RX_p[0]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_BB43" }, "PCIE_RX_p[1]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_BA41" }, "PCIE_RX_p[2]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AW41" }, "PCIE_RX_p[3]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AY43" }, "PCIE_RX_p[4]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AT43" }, "PCIE_RX_p[5]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AP43" }, "PCIE_RX_p[6]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AM43" }, "PCIE_RX_p[7]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AK43" }, "PCIE_SMBCLK": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BD34" }, "PCIE_SMBDAT": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AT33" }, "PCIE_TX_p[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AY39" }, "PCIE_TX_p[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AV39" }, "PCIE_TX_p[2]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AT39" }, "PCIE_TX_p[3]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AU41" }, "PCIE_TX_p[4]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AN41" }, "PCIE_TX_p[5]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AL41" }, "PCIE_TX_p[6]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AJ41" }, "PCIE_TX_p[7]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AG41" }, "PCIE_WAKE_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BD35" }, "PCIE_REFCLK_p(n)": { "IO_STANDARD": "HCSL", "LOC": "PIN_AK39" }, "PCIE_RX_p[0](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_BB44" }, "PCIE_RX_p[1](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_BA42" }, "PCIE_RX_p[2](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AW42" }, "PCIE_RX_p[3](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AY44" }, "PCIE_RX_p[4](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AT44" }, "PCIE_RX_p[5](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AP44" }, "PCIE_RX_p[6](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AM44" }, "PCIE_RX_p[7](n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AK44" }, "PCIE_TX_p[0](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AY40" }, "PCIE_TX_p[1](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AV40" }, "PCIE_TX_p[2](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AT40" }, "PCIE_TX_p[3](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AU42" }, "PCIE_TX_p[4](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AN42" }, "PCIE_TX_p[5](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AL42" }, "PCIE_TX_p[6](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AJ42" }, "PCIE_TX_p[7](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AG42" } }, "SATA": { "SATA_DEVICE_REFCLK_p(n)": { "IO_STANDARD": "HCSL", "LOC": "PIN_V40" }, "SATA_DEVICE_RX_p[0](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K44" }, "SATA_DEVICE_RX_p[1](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H44" }, "SATA_DEVICE_TX_p[0](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K40" }, "SATA_DEVICE_TX_p[1](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H40" }, "SATA_HOST_REFCLK_p(n)": { "IO_STANDARD": "HCSL", "LOC": "PIN_V5" }, "SATA_HOST_RX_p[0](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K1" }, "SATA_HOST_RX_p[1](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H1" }, "SATA_HOST_TX_p[0](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K5" }, "SATA_HOST_TX_p[1](n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H5" } }, "SFP": { "SFP1G_REFCLK_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "HCSL", "LOC": "PIN_AH6" }, "SFP1G_REFCLK_p(n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "HCSL", "LOC": "PIN_AH5" }, "SFP_REFCLK_p(n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "HCSL", "LOC": "PIN_AK6" }, "SFP_REFCLK_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "HCSL", "LOC": "PIN_AK7" } }, "PLL": { "PLL_SCL": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF32" }, "PLL_SDA": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG32" } }, "QDRIIA": { "QDRIIA_A[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU29" }, "QDRIIA_A[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW27" }, "QDRIIA_A[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY28" }, "QDRIIA_A[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD28" }, "QDRIIA_A[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV29" }, "QDRIIA_A[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW29" }, "QDRIIA_A[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB29" }, "QDRIIA_A[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD29" }, "QDRIIA_A[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL27" }, "QDRIIA_A[18]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR27" }, "QDRIIA_A[19]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL28" }, "QDRIIA_A[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA28" }, "QDRIIA_A[20]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR28" }, "QDRIIA_A[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AP27" }, "QDRIIA_A[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK27" }, "QDRIIA_A[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN27" }, "QDRIIA_A[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM28" }, "QDRIIA_A[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV28" }, "QDRIIA_A[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY27" }, "QDRIIA_A[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC29" }, "QDRIIA_A[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU28" }, "QDRIIA_BWS_n[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ24" }, "QDRIIA_BWS_n[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT27" }, "QDRIIA_CQ_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA25" }, "QDRIIA_CQ_p": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH22" }, "QDRIIA_DOFF_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR23" }, "QDRIIA_D[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH28" }, "QDRIIA_D[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM26" }, "QDRIIA_D[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM25" }, "QDRIIA_D[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL26" }, "QDRIIA_D[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK26" }, "QDRIIA_D[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU27" }, "QDRIIA_D[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU26" }, "QDRIIA_D[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV26" }, "QDRIIA_D[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW26" }, "QDRIIA_D[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH27" }, "QDRIIA_D[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH25" }, "QDRIIA_D[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ28" }, "QDRIIA_D[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ27" }, "QDRIIA_D[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ26" }, "QDRIIA_D[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ25" }, "QDRIIA_D[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL25" }, "QDRIIA_D[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH24" }, "QDRIIA_D[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN25" }, "QDRIIA_K_n": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_AR26" }, "QDRIIA_K_p": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_AP25" }, "QDRIIA_ODT": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN23" }, "QDRIIA_QVLD": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM23" }, "QDRIIA_Q[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK23" }, "QDRIIA_Q[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC26" }, "QDRIIA_Q[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY25" }, "QDRIIA_Q[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU24" }, "QDRIIA_Q[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV25" }, "QDRIIA_Q[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU25" }, "QDRIIA_Q[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR25" }, "QDRIIA_Q[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AP24" }, "QDRIIA_Q[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL24" }, "QDRIIA_Q[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB26" }, "QDRIIA_Q[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD26" }, "QDRIIA_Q[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA24" }, "QDRIIA_Q[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL23" }, "QDRIIA_Q[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ23" }, "QDRIIA_Q[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL21" }, "QDRIIA_Q[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK21" }, "QDRIIA_Q[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ22" }, "QDRIIA_Q[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW24" }, "QDRIIA_RPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT26" }, "QDRIIA_WPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK24" } }, "QDRIIB": { "QDRIIB_A[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR24" }, "QDRIIB_A[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ20" }, "QDRIIB_A[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG20" }, "QDRIIB_A[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW23" }, "QDRIIB_A[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB24" }, "QDRIIB_A[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY24" }, "QDRIIB_A[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD23" }, "QDRIIB_A[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC23" }, "QDRIIB_A[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG21" }, "QDRIIB_A[18]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM20" }, "QDRIIB_A[19]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK18" }, "QDRIIB_A[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB23" }, "QDRIIB_A[20]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN22" }, "QDRIIB_A[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK20" }, "QDRIIB_A[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ19" }, "QDRIIB_A[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL20" }, "QDRIIB_A[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG19" }, "QDRIIB_A[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT23" }, "QDRIIB_A[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU23" }, "QDRIIB_A[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV23" }, "QDRIIB_A[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM22" }, "QDRIIB_BWS_n[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV20" }, "QDRIIB_BWS_n[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU21" }, "QDRIIB_CQ_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AP18" }, "QDRIIB_CQ_p": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ15" }, "QDRIIB_DOFF_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH19" }, "QDRIIB_D[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB21" }, "QDRIIB_D[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR21" }, "QDRIIB_D[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AP21" }, "QDRIIB_D[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD22" }, "QDRIIB_D[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC22" }, "QDRIIB_D[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA22" }, "QDRIIB_D[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV22" }, "QDRIIB_D[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY22" }, "QDRIIB_D[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW22" }, "QDRIIB_D[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD20" }, "QDRIIB_D[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC20" }, "QDRIIB_D[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR22" }, "QDRIIB_D[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB20" }, "QDRIIB_D[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU22" }, "QDRIIB_D[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA21" }, "QDRIIB_D[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY21" }, "QDRIIB_D[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW21" }, "QDRIIB_D[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT21" }, "QDRIIB_K_n": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_AT20" }, "QDRIIB_K_p": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_AR20" }, "QDRIIB_ODT": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH18" }, "QDRIIB_QVLD": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ16" }, "QDRIIB_Q[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR19" }, "QDRIIB_Q[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ18" }, "QDRIIB_Q[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ17" }, "QDRIIB_Q[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG18" }, "QDRIIB_Q[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU19" }, "QDRIIB_Q[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW19" }, "QDRIIB_Q[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV19" }, "QDRIIB_Q[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AP19" }, "QDRIIB_Q[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN20" }, "QDRIIB_Q[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM19" }, "QDRIIB_Q[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL19" }, "QDRIIB_Q[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM17" }, "QDRIIB_Q[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL18" }, "QDRIIB_Q[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN19" }, "QDRIIB_Q[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU18" }, "QDRIIB_Q[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK17" }, "QDRIIB_Q[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL17" }, "QDRIIB_Q[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG17" }, "QDRIIB_RPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW20" }, "QDRIIB_WPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU20" } }, "QDRIIC": { "QDRIIC_A[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV16" }, "QDRIIC_A[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH21" }, "QDRIIC_A[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU17" }, "QDRIIC_A[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU16" }, "QDRIIC_A[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB8" }, "QDRIIC_A[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT18" }, "QDRIIC_A[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW17" }, "QDRIIC_A[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV17" }, "QDRIIC_A[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU8" }, "QDRIIC_A[18]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT9" }, "QDRIIC_A[19]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV8" }, "QDRIIC_A[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW16" }, "QDRIIC_A[20]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN17" }, "QDRIIC_A[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AP16" }, "QDRIIC_A[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW9" }, "QDRIIC_A[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD7" }, "QDRIIC_A[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC7" }, "QDRIIC_A[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR17" }, "QDRIIC_A[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR18" }, "QDRIIC_A[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT17" }, "QDRIIC_A[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB9" }, "QDRIIC_BWS_n[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ11" }, "QDRIIC_BWS_n[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ10" }, "QDRIIC_CQ_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AF13" }, "QDRIIC_CQ_p": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC11" }, "QDRIIC_DOFF_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AE14" }, "QDRIIC_D[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG9" }, "QDRIIC_D[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AM13" }, "QDRIIC_D[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR12" }, "QDRIIC_D[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AR13" }, "QDRIIC_D[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU9" }, "QDRIIC_D[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU10" }, "QDRIIC_D[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AU11" }, "QDRIIC_D[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV11" }, "QDRIIC_D[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AT12" }, "QDRIIC_D[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG10" }, "QDRIIC_D[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG12" }, "QDRIIC_D[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AG11" }, "QDRIIC_D[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AV10" }, "QDRIIC_D[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH12" }, "QDRIIC_D[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AK12" }, "QDRIIC_D[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL12" }, "QDRIIC_D[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AJ12" }, "QDRIIC_D[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AN12" }, "QDRIIC_K_n": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_AP13" }, "QDRIIC_K_p": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_AP12" }, "QDRIIC_ODT": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD10" }, "QDRIIC_QVLD": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BD11" }, "QDRIIC_Q[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA12" }, "QDRIIC_Q[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW11" }, "QDRIIC_Q[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AF10" }, "QDRIIC_Q[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY12" }, "QDRIIC_Q[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AW10" }, "QDRIIC_Q[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AY10" }, "QDRIIC_Q[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB12" }, "QDRIIC_Q[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BC10" }, "QDRIIC_Q[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BA10" }, "QDRIIC_Q[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AF14" }, "QDRIIC_Q[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AE13" }, "QDRIIC_Q[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AD14" }, "QDRIIC_Q[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AE12" }, "QDRIIC_Q[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AF11" }, "QDRIIC_Q[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AE11" }, "QDRIIC_Q[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AE10" }, "QDRIIC_Q[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AE9" }, "QDRIIC_Q[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_BB11" }, "QDRIIC_RPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AH10" }, "QDRIIC_WPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_AL11" } }, "QDRIID": { "QDRIID_A[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_N26" }, "QDRIID_A[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_U27" }, "QDRIID_A[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_R27" }, "QDRIID_A[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_P27" }, "QDRIID_A[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_V25" }, "QDRIID_A[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_V26" }, "QDRIID_A[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_T25" }, "QDRIID_A[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_P26" }, "QDRIID_A[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_M27" }, "QDRIID_A[18]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_M28" }, "QDRIID_A[19]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_P29" }, "QDRIID_A[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_P28" }, "QDRIID_A[20]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_D29" }, "QDRIID_A[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_N28" }, "QDRIID_A[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_L26" }, "QDRIID_A[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_K27" }, "QDRIID_A[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_L27" }, "QDRIID_A[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_U26" }, "QDRIID_A[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_T26" }, "QDRIID_A[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_T27" }, "QDRIID_A[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_V27" }, "QDRIID_BWS_n[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_E26" }, "QDRIID_BWS_n[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_K26" }, "QDRIID_CQ_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H27" }, "QDRIID_CQ_p": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_E29" }, "QDRIID_DOFF_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_E27" }, "QDRIID_D[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H25" }, "QDRIID_D[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_P24" }, "QDRIID_D[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_P23" }, "QDRIID_D[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_L24" }, "QDRIID_D[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_R24" }, "QDRIID_D[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_U23" }, "QDRIID_D[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_U24" }, "QDRIID_D[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_T24" }, "QDRIID_D[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_T23" }, "QDRIID_D[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H24" }, "QDRIID_D[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H23" }, "QDRIID_D[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_J25" }, "QDRIID_D[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_J24" }, "QDRIID_D[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_K25" }, "QDRIID_D[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_D26" }, "QDRIID_D[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_F25" }, "QDRIID_D[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_G25" }, "QDRIID_D[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_N23" }, "QDRIID_K_n": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_K24" }, "QDRIID_K_p": { "IO_STANDARD": "DIFFERENTIAL 1.8-V HSTL CLASS I", "LOC": "PIN_L23" }, "QDRIID_ODT": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H26" }, "QDRIID_QVLD": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_J27" }, "QDRIID_Q[0]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_C27" }, "QDRIID_Q[10]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_F28" }, "QDRIID_Q[11]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_D27" }, "QDRIID_Q[12]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_G29" }, "QDRIID_Q[13]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_F29" }, "QDRIID_Q[14]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H28" }, "QDRIID_Q[15]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_K28" }, "QDRIID_Q[16]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_J28" }, "QDRIID_Q[17]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_H29" }, "QDRIID_Q[1]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_A26" }, "QDRIID_Q[2]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_B26" }, "QDRIID_Q[3]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_F26" }, "QDRIID_Q[4]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_G26" }, "QDRIID_Q[5]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_C28" }, "QDRIID_Q[6]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_A29" }, "QDRIID_Q[7]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_A28" }, "QDRIID_Q[8]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_B28" }, "QDRIID_Q[9]": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_G28" }, "QDRIID_RPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_F24" }, "QDRIID_WPS_n": { "IO_STANDARD": "1.8-V HSTL CLASS I", "LOC": "PIN_M23" } }, "RS422": { "RS422_DE": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AG14" }, "RS422_DIN": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE18" }, "RS422_DOUT": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AE17" }, "RS422_RE_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF17" }, "RS422_TE": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AF16" } }, "RZQ": { "RZQ_0": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_BA36" }, "RZQ_1": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_AR8" }, "RZQ_4": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.5 V", "LOC": "PIN_H9" }, "RZQ_5": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.5 V", "LOC": "PIN_P35" } }, "SATA": { "SATA_DEVICE_REFCLK_p": { "IO_STANDARD": "HCSL", "LOC": "PIN_V39" }, "SATA_DEVICE_RX_p[0]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K43" }, "SATA_DEVICE_RX_p[1]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H43" }, "SATA_DEVICE_TX_p[0]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K39" }, "SATA_DEVICE_TX_p[1]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H39" }, "SATA_HOST_REFCLK_p": { "IO_STANDARD": "HCSL", "LOC": "PIN_V6" }, "SATA_HOST_RX_p[0]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K2" }, "SATA_HOST_RX_p[1]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H2" }, "SATA_HOST_TX_p[0]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_K6" }, "SATA_HOST_TX_p[1]": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_H6" } }, "SFPA": { "SFPA_LOS": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_F22" }, "SFPA_MOD0_PRSNT_n": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_E21" }, "SFPA_MOD1_SCL": { "IO_STANDARD": "2.5 V", "LOC": "PIN_B20" }, "SFPA_MOD2_SDA": { "IO_STANDARD": "2.5 V", "LOC": "PIN_A20" }, "SFPA_RATESEL[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_E20" }, "SFPA_RATESEL[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_G22" }, "SFPA_RX_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AK2" }, "SFPA_TXDISABLE": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_B22" }, "SFPA_TXFAULT": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_A22" }, "SFPA_TX_p": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AG4" }, "SFPA_RX_p(n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AK1" }, "SFPA_TX_p(n)": { "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AG3" } }, "SFPB": { "SFPB_LOS": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_R22" }, "SFPB_MOD0_PRSNT_n": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_K22" }, "SFPB_MOD1_SCL": { "IO_STANDARD": "2.5 V", "LOC": "PIN_K21" }, "SFPB_MOD2_SDA": { "IO_STANDARD": "2.5 V", "LOC": "PIN_K20" }, "SFPB_RATESEL[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_R21" }, "SFPB_RATESEL[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_T22" }, "SFPB_RX_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AP2" }, "SFPB_TXDISABLE": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_H22" }, "SFPB_TXFAULT": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_H20" }, "SFPB_TX_p": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AL4" }, "SFPB_RX_p(n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AP1" }, "SFPB_TX_p(n)": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AL3" } }, "SFPC": { "SFPC_LOS": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_L21" }, "SFPC_MOD0_PRSNT_n": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_J21" }, "SFPC_MOD1_SCL": { "IO_STANDARD": "2.5 V", "LOC": "PIN_H21" }, "SFPC_MOD2_SDA": { "IO_STANDARD": "2.5 V", "LOC": "PIN_G20" }, "SFPC_RATESEL[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_J22" }, "SFPC_RATESEL[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_P21" }, "SFPC_RX_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AW4" }, "SFPC_TXDISABLE": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_F21" }, "SFPC_TXFAULT": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_F20" }, "SFPC_TX_p": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AT6" }, "SFPC_RX_p(n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AW3" }, "SFPC_TX_p(n)": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AT5" } }, "SFPD": { "SFPD_LOS": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_N22" }, "SFPD_MOD0_PRSNT_n": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_V20" }, "SFPD_MOD1_SCL": { "IO_STANDARD": "2.5 V", "LOC": "PIN_U21" }, "SFPD_MOD2_SDA": { "IO_STANDARD": "2.5 V", "LOC": "PIN_V19" }, "SFPD_RATESEL[0]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_V21" }, "SFPD_RATESEL[1]": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_M22" }, "SFPD_RX_p": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_BB2" }, "SFPD_TXDISABLE": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_U20" }, "SFPD_TXFAULT": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "2.5 V", "LOC": "PIN_T21" }, "SFPD_TX_p": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AY6" }, "SFPD_RX_p(n)": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_BB1" }, "SFPD_TX_p(n)": { "PIO_DIRECTION": "OUTPUT", "IO_STANDARD": "1.4-V PCML", "LOC": "PIN_AY5" } }, "SMA": { "SMA_CLKIN": { "IO_STANDARD": "2.5 V", "LOC": "PIN_BB33" }, "SMA_CLKOUT": { "IO_STANDARD": "2.5 V", "LOC": "PIN_AV34" } }, "SW": { "SW[0]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_B25" }, "SW[1]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_A25" }, "SW[2]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_B23" }, "SW[3]": { "PIO_DIRECTION": "INPUT", "IO_STANDARD": "1.8 V", "LOC": "PIN_A23" } }, "TEMP": { "TEMP_CLK": { "IO_STANDARD": "2.5 V", "LOC": "PIN_D21" }, "TEMP_DATA": { "IO_STANDARD": "2.5 V", "LOC": "PIN_D20" }, "TEMP_INT_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_C21" }, "TEMP_OVERT_n": { "IO_STANDARD": "2.5 V", "LOC": "PIN_C22" } } } ================================================ FILE: boardinfo/htg4.json ================================================ { "options": { "bsvdefines" : ["ALTERA=1", "StratixIV", "PCIE", "PCIE_NO_BSCAN", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=4", "NUMBER_OF_10G_PORTS=2", "PcieLanes=8", "DEFAULT_NOPROGRAM=1", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest.altera"], "os" : "ubuntu", "partname" : "EP4S100G2F40I2", "need_pcie" : "s4_gen2x8", "TOP" : "PcieTop", "constraints": ["constraints/altera/htg4.xdc"], "runscript" : "run.pcietest.altera", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "PCIE": { "PCIE_PERST_n": { "IOSTANDARD": "2.5 V", "LOC": "PIN_AG24" }, "PCIE_REFCLK_p": { "IOSTANDARD": "DIFFERENTIAL LVPECL", "LOC": "PIN_AA38" }, "PCIE_RX_p[0]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AU38" }, "PCIE_RX_p[1]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AR38" }, "PCIE_RX_p[2]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AJ38" }, "PCIE_RX_p[3]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AG38" }, "PCIE_RX_p[4]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AE38" }, "PCIE_RX_p[5]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AC38" }, "PCIE_RX_p[6]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_U38" }, "PCIE_RX_p[7]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_R38" }, "PCIE_SMBCLK": { "IOSTANDARD": "2.5 V", "LOC": "PIN_W35" }, "PCIE_SMBDAT": { "IOSTANDARD": "2.5 V", "LOC": "PIN_W34" }, "PCIE_TX_p[0]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AT36" }, "PCIE_TX_p[1]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AP36" }, "PCIE_TX_p[2]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AH36" }, "PCIE_TX_p[3]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AF36" }, "PCIE_TX_p[4]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AD36" }, "PCIE_TX_p[5]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AB36" }, "PCIE_TX_p[6]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_T36" }, "PCIE_TX_p[7]": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_P36" }, "PCIE_WAKE_n": { "IOSTANDARD": "2.5 V", "LOC": "PIN_R33" }, "PCIE_REFCLK_p(n)": { "IOSTANDARD": "HCSL", "LOC": "PIN_AA39" }, "PCIE_RX_p[0](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AU39" }, "PCIE_RX_p[1](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AR39" }, "PCIE_RX_p[2](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AJ39" }, "PCIE_RX_p[3](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AG39" }, "PCIE_RX_p[4](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AE39" }, "PCIE_RX_p[5](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AC39" }, "PCIE_RX_p[6](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_U39" }, "PCIE_RX_p[7](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_R39" }, "PCIE_TX_p[0](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AT37" }, "PCIE_TX_p[1](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AP37" }, "PCIE_TX_p[2](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AH37" }, "PCIE_TX_p[3](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AF37" }, "PCIE_TX_p[4](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AO37" }, "PCIE_TX_p[5](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_AB37" }, "PCIE_TX_p[6](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_T37" }, "PCIE_TX_p[7](n)": { "IOSTANDARD": "1.4-V PCML", "LOC": "PIN_P37" } }, "LED": { "LED[0]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_D33" }, "LED[1]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_C34" }, "LED[2]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_M28" }, "LED[3]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_D34" }, "LED[4]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_E34" }, "LED[5]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_R27" }, "LED[6]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_F34" }, "LED[7]": { "IOSTANDARD": "2.5 V", "LOC": "PIN_N28" } }, "OSC": { "CLK200": { "IOSTANDARD": "LVDS", "LOC": "PIN_K34" }, "CLK644": { "IOSTANDARD": "DIFFERENTIAL LVPECL", "LOC": "PIN_J2" }, "CLK100": { "IOSTANDARD": "DIFFERENTIAL LVPECL", "LOC": "PIN_J2" } } } ================================================ FILE: boardinfo/kc160g2.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Kintex7", "PCIE", "PCIE2", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7k160tffg676-2", "need_pcie" : "x7_gen2x8", "TOP" : "PcieTop", "constraints": [], "implconstraints": ["constraints/xilinx/kc160g2.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" } } ================================================ FILE: boardinfo/kc705.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Kintex7", "PCIE", "PCIE1", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7k325tffg900-2", "need_pcie" : "x7_gen1x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/kc705.xdc"], "implconstraints": ["constraints/xilinx/kc705.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "fmc1": { "LA00_p_CC": { "LOC": "C25", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "LOC": "B25", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "LOC": "D26", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "LOC": "C26", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "LOC": "H24", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "LOC": "H25", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "LOC": "H26", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "LOC": "H27", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "LOC": "G28", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "LOC": "F28", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "LOC": "G29", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "LOC": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "LOC": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "LOC": "G30", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "LOC": "E28", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "LOC": "D28", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "LOC": "E29", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "LOC": "E30", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "LOC": "B30", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "LOC": "A30", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "LOC": "D29", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "LOC": "C30", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "LOC": "G27", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "LOC": "F27", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "LOC": "C29", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "LOC": "C29", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "LOC": "A25", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "LOC": "A26", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "LOC": "B28", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "LOC": "A28", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "LOC": "C24", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "LOC": "B24", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "LOC": "B27", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "LOC": "A27", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "LOC": "AB27", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "LOC": "AC27", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "LOC": "AD27", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "LOC": "AD28", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "LOC": "AJ26", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "LOC": "AK26", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "LOC": "bogus", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "LOC": "bogus", "IOSTANDARD": "LVCMOS25" } }, "uart": { "d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "rts": { "PACKAGE_PIN": "K23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "cts": { "PACKAGE_PIN": "L27", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "AC20", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "AA23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "AA22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "AC21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "AB23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "AB22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "AA21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "Y21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" } }, "pins": { "userClk_p": { "PACKAGE_PIN": "K29", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "K28", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "L25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "K25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "J8", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "J7", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "K6", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "K5", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "K2", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "K1", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/kc705_untethered.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Kintex7", "PhysAddrWidth=40", "PcieLanes=8", "UNTETHERED=1", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7k325tffg900-2", "TOP" : "UntetheredTop", "constraints": ["constraints/xilinx/kc705g2.xdc", "constraints/xilinx/pcie-clocks.xdc"], "implconstraints": ["constraints/xilinx/kc705g2.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "fmc1": { "LA00_p_CC": { "PACKAGE_PIN": "C25", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "B25", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "D26", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "C26", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "H24", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "H25", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "H26", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "H27", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "G28", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "F28", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "G29", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "G30", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "E28", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "D28", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "E29", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "E30", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "B30", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "A30", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "D29", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "C30", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "G27", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "F27", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "C29", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "C29", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "A25", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "A26", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "B28", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "A28", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "C24", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "B24", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "B27", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "A27", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "AB27", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "AC27", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "AD27", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "AD28", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "AJ26", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "AK26", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVCMOS25" } }, "uart": { "d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "rts": { "PACKAGE_PIN": "K23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "cts": { "PACKAGE_PIN": "L27", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "AC20", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "AA23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "AA22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "AC21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "AB23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "AB22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "AA21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "Y21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" } }, "pins": { "cpu_reset": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS15", "PIO_DIRECTION": "INPUT" }, "userClk_p": { "PACKAGE_PIN": "K29", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "K28", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "L25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "K25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "J8", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "J7", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "K6", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "K5", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "K2", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "K1", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/kc705g1.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Kintex7", "PCIE", "PCIE1", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7k325tffg900-2", "need_pcie" : "x7_gen1x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/kc705.xdc"], "implconstraints": ["constraints/xilinx/kc705.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "fmc1": { "LA00_p_CC": { "LOC": "C25", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "LOC": "B25", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "LOC": "D26", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "LOC": "C26", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "LOC": "H24", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "LOC": "H25", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "LOC": "H26", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "LOC": "H27", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "LOC": "G28", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "LOC": "F28", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "LOC": "G29", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "LOC": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "LOC": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "LOC": "G30", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "LOC": "E28", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "LOC": "D28", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "LOC": "E29", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "LOC": "E30", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "LOC": "B30", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "LOC": "A30", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "LOC": "D29", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "LOC": "C30", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "LOC": "G27", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "LOC": "F27", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "LOC": "C29", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "LOC": "C29", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "LOC": "A25", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "LOC": "A26", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "LOC": "B28", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "LOC": "A28", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "LOC": "C24", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "LOC": "B24", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "LOC": "B27", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "LOC": "A27", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "LOC": "AB27", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "LOC": "AC27", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "LOC": "AD27", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "LOC": "AD28", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "LOC": "AJ26", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "LOC": "AK26", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "LOC": "bogus", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "LOC": "bogus", "IOSTANDARD": "LVCMOS25" } }, "uart": { "d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "rts": { "PACKAGE_PIN": "K23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "cts": { "PACKAGE_PIN": "L27", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "AC20", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "AA23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "AA22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "AC21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "AB23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "AB22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "AA21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "Y21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" } }, "pins": { "userClk_p": { "PACKAGE_PIN": "K29", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "K28", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "L25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "K25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "J8", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "J7", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "K6", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "K5", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "K2", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "K1", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/kc705g2.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Kintex7", "PCIE", "PCIE2", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7k325tffg900-2", "need_pcie" : "x7_gen2x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/kc705g2.xdc", "constraints/xilinx/pcie-clocks.xdc"], "implconstraints": ["constraints/xilinx/kc705g2.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "fmc1": { "LA00_p_CC": { "PACKAGE_PIN": "C25", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "B25", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "D26", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "C26", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "H24", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "H25", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "H26", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "H27", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "G28", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "F28", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "G29", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "H30", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "G30", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "E28", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "D28", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "E29", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "E30", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "B30", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "A30", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "D29", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "C30", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "G27", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "F27", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "C29", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "C29", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "A25", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "A26", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "B28", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "A28", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "C24", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "B24", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "B27", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "A27", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "AB27", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "AC27", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "AD27", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "AD28", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "AJ26", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "AK26", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVCMOS25" } }, "uart": { "d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "rts": { "PACKAGE_PIN": "K23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "cts": { "PACKAGE_PIN": "L27", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "AC20", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "AA23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "AA22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "AC21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "AB23", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "AB22", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "AA21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "Y21", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" } }, "pins": { "userClk_p": { "PACKAGE_PIN": "K29", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "K28", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "L25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "K25", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "J8", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "J7", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "K6", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "K5", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "K2", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "K1", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "K24", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/kcu105.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Virtex7", "PCIE", "PCIE3", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=8", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "XCKU040-2FFVA1156E", "need_pcie" : "x7_gen3x8", "TOP" : "PcieTop", "constraints": [], "implconstraints": ["constraints/xilinx/kcu105.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "leds" : { "L0" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "LOC" : "bogus", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" } }, "sfp1": { "rxp" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" } }, "sfp2": { "rxp" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" } }, "sfp3": { "rxp" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" } }, "sfp4": { "rxp" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "bogus", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "bogus", "PIO_DIRECTION" : "OUTPUT" } }, "uart": { "d_in": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "d_out": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "rts": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "cts": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } }, "iic_main": { "sda": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "scl": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" } }, "pins": { "userClk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "sys_clk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "sys_clk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_clk_p": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_clk_n": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "si5324_rst_n": { "LOC": "bogus", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/miniitx100.json ================================================ { "options": { "os" : "android", "partname" : "xc7z100ffg900-2", "rewireclockstring" : "tclzynqrewireclock", "constraints": ["constraints/xilinx/xc7z100ffg900.xdc", "constraints/xilinx/miniitx100.xdc"], "implconstraints": ["constraints/xilinx/xc7z100ffg900.xdc", "constraints/xilinx/miniitx100.xdc"], "TOP" : "ZynqTop", "runscript" : "run.android", "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "NUMBER_OF_LEDS=8", "PcieLanes=4", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2"], "CONNECTALFLAGS": ["--mainclockperiod=5", "--derivedclockperiod=2.5"], "need_pcie" : "unused" }, "uart": { "d_out": { "IOSTANDARD": "LVCMOS15", "PIO_DIRECTION": "OUTPUT", "LOC": "C19" }, "d_in": { "IOSTANDARD": "LVCMOS15", "PIO_DIRECTION": "INPUT", "LOC": "D18" } }, "i2c_main": { "scl": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "LOC": "A19" }, "sda": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "LOC": "F19" }, "mux_reset": { "IOSTANDARD": "LVCMOS15", "PIO_DIRECTION": "OUTPUT", "LOC": "F20" } }, "pcie": { "sys_clk_p": { "IOSTANDARD": "DIFF_SSTL15", "PIO_DIRECTION": "OUTPUT", "LOC": "N8" }, "sys_clk_n": { "IOSTANDARD": "DIFF_SSTL15", "PIO_DIRECTION": "OUTPUT", "LOC": "N7" }, "sys_reset_n": { "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT", "LOC": "AC18" } }, "sfp1": { "mod_def0": { "IOSTANDARD": "LVCMOS25", "LOC": "AB20" }, "mod_def1": { "IOSTANDARD": "LVCMOS25", "LOC": "AB19" }, "mod_def2": { "IOSTANDARD": "LVCMOS25", "LOC": "AA19" }, "rx_los": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AE20" }, "tx_disable": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AA18" }, "tx_fault": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AD19" }, "rxp": { "PIO_DIRECTION": "INPUT", "LOC": "AC4" }, "rxn": { "PIO_DIRECTION": "INPUT", "LOC": "AC3" }, "txp": { "PIO_DIRECTION": "OUTPUT", "LOC": "AB2" }, "txn": { "PIO_DIRECTION": "OUTPUT", "LOC": "AB1" } } } ================================================ FILE: boardinfo/ncverilog.json ================================================ { "options": { "os" : "ubuntu", "partname" : "xc7z020clg484-1", "TOP" : "XsimTop", "bsvdefines": ["CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "SIMULATION", "SVDPI", "CONNECTAL_BITS_DEPENDENCES=ncverilogsim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/nfsume.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Virtex7", "PCIE", "PCIE3", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=2", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7vx690tffg1761-3", "need_pcie" : "x7_gen3x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/nfsume.xdc"], "implconstraints": ["constraints/xilinx/nfsume.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "BTN": { "BTN[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AR13" }, "BTN[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BB12" } }, "CLK": { "FPGA_SYSCLK_N": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "G18" }, "FPGA_SYSCLK_P": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "H19" } }, "CPLD": { "CPLD_IMGSEL[0]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AP31" }, "CPLD_IMGSEL[1]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AP33" }, "CPLD_IMGSEL[2]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AR33" }, "CPLD_RECONFIG": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AK32" } }, "DDR": { "DDR3_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "E35" }, "DDR3_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "E34" } }, "FMC": { "FMC_GBTCLK_P[00]": { "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AT8" }, "FMC_GBTCLK_N[00]": { "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AT7" }, "FMC_CLK0_M2C_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AT27" }, "FMC_CLK0_M2C_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AR27" }, "FMC_CLK1_M2C_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AV35" }, "FMC_CLK1_M2C_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AV34" }, "FMC_LA_N[00]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV28" }, "FMC_LA_N[01]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AR28" }, "FMC_LA_N[02]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT29" }, "FMC_LA_N[03]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB27" }, "FMC_LA_N[04]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB29" }, "FMC_LA_N[05]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV26" }, "FMC_LA_N[06]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA27" }, "FMC_LA_N[07]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AY28" }, "FMC_LA_N[08]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AP28" }, "FMC_LA_N[09]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AR25" }, "FMC_LA_N[10]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW26" }, "FMC_LA_N[11]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT26" }, "FMC_LA_N[12]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV29" }, "FMC_LA_N[13]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW28" }, "FMC_LA_N[14]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AN26" }, "FMC_LA_N[15]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AM27" }, "FMC_LA_N[16]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AL27" }, "FMC_LA_N[17]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AY33" }, "FMC_LA_N[18]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV33" }, "FMC_LA_N[19]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW31" }, "FMC_LA_N[20]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AY30" }, "FMC_LA_N[21]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB31" }, "FMC_LA_N[22]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA32" }, "FMC_LA_N[23]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB34" }, "FMC_LA_N[24]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU34" }, "FMC_LA_N[25]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU33" }, "FMC_LA_N[26]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB33" }, "FMC_LA_N[27]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV31" }, "FMC_LA_N[28]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT35" }, "FMC_LA_N[29]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB36" }, "FMC_LA_N[30]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA35" }, "FMC_LA_N[31]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AP30" }, "FMC_LA_N[32]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW36" }, "FMC_LA_N[33]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU36" }, "FMC_LA_P[00]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU28" }, "FMC_LA_P[01]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AP27" }, "FMC_LA_P[02]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AR29" }, "FMC_LA_P[03]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB26" }, "FMC_LA_P[04]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB28" }, "FMC_LA_P[05]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV25" }, "FMC_LA_P[06]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA26" }, "FMC_LA_P[07]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AY27" }, "FMC_LA_P[08]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AN28" }, "FMC_LA_P[09]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AP25" }, "FMC_LA_P[10]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW25" }, "FMC_LA_P[11]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT25" }, "FMC_LA_P[12]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU29" }, "FMC_LA_P[13]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW27" }, "FMC_LA_P[14]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AN25" }, "FMC_LA_P[15]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AM26" }, "FMC_LA_P[16]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AK27" }, "FMC_LA_P[17]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AY32" }, "FMC_LA_P[18]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU32" }, "FMC_LA_P[19]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV30" }, "FMC_LA_P[20]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AW30" }, "FMC_LA_P[21]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA30" }, "FMC_LA_P[22]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA31" }, "FMC_LA_P[23]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA34" }, "FMC_LA_P[24]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT34" }, "FMC_LA_P[25]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT32" }, "FMC_LA_P[26]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BB32" }, "FMC_LA_P[27]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AU31" }, "FMC_LA_P[28]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AR34" }, "FMC_LA_P[29]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "BA36" }, "FMC_LA_P[30]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AY34" }, "FMC_LA_P[31]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AN30" }, "FMC_LA_P[32]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AV36" }, "FMC_LA_P[33]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AT36" }, "FMC_PRSNT_LS": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AR30" } }, "Fan": { "FAN_PWM": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AN34" }, "FAN_TACH": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AP32" } }, "I2C": { "I2C_FPGA_SCL": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AK24" }, "I2C_FPGA_SDA": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AK25" }, "I2C_MUX_RESET": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AM39" } }, "sdio": { "cmd": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AJ26" }, "clk": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AJ25" }, "cd": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AW35" }, "d0": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AY29" }, "d1": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AM28" }, "d2": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AL25" }, "d3": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AL26" } }, "LED": { "LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AR22" }, "LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AR23" } }, "PCIE": { "PCIE_SYS_RESETN": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AY35" }, "PCIE_PRSNT_B_LS": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AR35" }, "PCIE_WAKE": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AT31" }, "PCIE_SYSCLK_N": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AB8" }, "PCIE_SYSCLK_P": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AB7" } }, "PMODCTRL": { "DIR_JA[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AT16" }, "DIR_JA[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AU16" }, "DIR_JA[2]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BB19" }, "DIR_JA[3]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AV20" }, "DIR_JA[4]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AW20" }, "DIR_JA[5]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BA17" }, "DIR_JA[6]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BB17" }, "DIR_JA[7]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AY20" }, "PMOD_OE_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "C40" } }, "PMODData": { "JA_FPGA[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AW18" }, "JA_FPGA[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AW17" }, "JA_FPGA[2]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AU19" }, "JA_FPGA[3]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AV19" }, "JA_FPGA[4]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AT20" }, "JA_FPGA[5]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AT19" }, "JA_FPGA[6]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AV16" }, "JA_FPGA[7]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AW16" } }, "POWER": { "PCON_ALERT_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "J41" }, "PCON_AUXFAULT_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "M41" }, "PCON_FAULT": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "N40" }, "PWR_SNS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AW42" } }, "QDRIIA": { "QDRII_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AD33" }, "QDRII_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AD32" } }, "QDRIIC": { "QDRIIC_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AU13" }, "QDRIIC_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AU14" } }, "MICRO_SD": { "SD_CCLK": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AJ25" }, "SD_CD": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AW35" }, "SD_CMD": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AJ26" }, "SD_D[0]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AY29" }, "SD_D[1]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AM28" }, "SD_D[2]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AL25" }, "SD_D[3]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AL26" } }, "SFPCLK": { "SFP_CLK_ALARM_B": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AM29" }, "SFP_CLK_RST": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "BA29" } }, "SFP": { "SFP_REFCLK_N": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "E9" }, "SFP_REFCLK_P": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "E10" } }, "SFPA": { "ETH1_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "G13" }, "ETH1_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "L15" }, "ETH1_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "N18" }, "ETH1_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "N19" }, "ETH1_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "P18" }, "ETH1_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "L17" }, "ETH1_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "M18" }, "ETH1_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "M19" }, "ETH1_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "A6" }, "ETH1_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "A5" }, "ETH1_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "B4" }, "ETH1_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "B3" } }, "SFPB": { "ETH2_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AL22" }, "ETH2_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BA20" }, "ETH2_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "L19" }, "ETH2_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "P20" }, "ETH2_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "N20" }, "ETH2_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "L20" }, "ETH2_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "B31" }, "ETH2_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "C26" }, "ETH2_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "B8" }, "ETH2_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "B7" }, "ETH2_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "C2" }, "ETH2_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "C1" } }, "SFPC": { "ETH3_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AY18" }, "ETH3_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AY17" }, "ETH3_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "J37" }, "ETH3_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "F39" }, "ETH3_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "G36" }, "ETH3_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "G37" }, "ETH3_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "J38" }, "ETH3_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "E39" }, "ETH3_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "C6" }, "ETH3_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "C5" }, "ETH3_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "D4" }, "ETH3_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "D3" } }, "SFPD": { "ETH4_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "P31" }, "ETH4_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "K32" }, "ETH4_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "H36" }, "ETH4_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "H38" }, "ETH4_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "G38" }, "ETH4_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "J36" }, "ETH4_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "L21" }, "ETH4_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "J26" }, "ETH4_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "D8" }, "ETH4_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "D7" }, "ETH4_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "E2" }, "ETH4_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "E1" } }, "SI570": { "USERCLK_N": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AU27" }, "USERCLK_P": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "AU26" } }, "uart": { "UART_CTS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BA16" }, "UART_RTS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BB16" }, "d_out": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "BA19", "PIO_DIRECTION": "OUTPUT" }, "d_in": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "AY19", "PIO_DIRECTION": "INPUT" } }, "pins": { "userClk_p": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "bogus", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/parallella.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2"], "os" : "ubuntu", "partname" : "xc7z020clg400-1", "constraints": [], "implconstraints": ["constraints/xilinx/zc7z020clg400.xdc", "constraints/xilinx/parallella.xdc"], "rewireclockstring" : "tclzynqrewireclock", "TOP" : "ZynqTop", "runscript" : "run.android", "CONNECTALFLAGS" : [], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/ultra96.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqUltrascale", "ZynqHostInterface", "PhysAddrWidth=40", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest", "CONNECTAL_EXENAME=ubuntu.exe", "CONNECTAL_EXENAME2=ubuntu.exe2"], "os" : "ubuntu", "arch" : "arm64", "toolchain" : "aarch64-linux-gnu-", "partname" : "xczu3eg-sbva484-1-i", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/zcu102.xdc"], "TOP" : "ZynqUltraTop", "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=5", "--derivedclockperiod=2.5"], "ZYNQ_MPSOC": "zynq_ultra_ps_e" }, "fmc1": { "LA00_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" } }, "fmc2": { "LA00_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" } }, "leds" : { "L0" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "xadc" : { "L0" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "hdmi" : { "clock" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "hsync" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "vsync" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "de" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[0]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[1]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[2]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[3]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[4]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[5]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[6]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[7]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[8]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[9]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[10]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[11]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[12]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[13]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[14]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[15]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/v2000t.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Virtex7", "PCIE", "PcieHostInterface", "PhysAddrWidth=40", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7v2000tflg1925-2", "need_pcie" : "x7_gen1x8", "TOP" : "PcieTop", "constraints": [], "implconstraints": ["constraints/xilinx/v2000t.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : [], "rewireclockstring" : "" }, "fmc": { } } ================================================ FILE: boardinfo/vc707.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Virtex7", "PCIE", "PCIE1", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7vx485tffg1761-2", "need_pcie" : "x7_gen1x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/vc707.xdc"], "implconstraints": ["constraints/xilinx/vc707.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=8", "--derivedclockperiod=4", "--pcieclockperiod=8"], "rewireclockstring" : "" }, "fmc": { }, "bpi_flash": { "data[0]" : { "LOC" : "AM36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[1]" : { "LOC" : "AN36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[2]" : { "LOC" : "AJ36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[3]" : { "LOC" : "AJ37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[4]" : { "LOC" : "AK37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[5]" : { "LOC" : "AL37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[6]" : { "LOC" : "AN35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[7]" : { "LOC" : "AP35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[8]" : { "LOC" : "AM37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[9]" : { "LOC" : "AG33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[10]" : { "LOC" : "AH33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[11]" : { "LOC" : "AK35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[12]" : { "LOC" : "AL35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[13]" : { "LOC" : "AJ31", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[14]" : { "LOC" : "AH34", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[15]" : { "LOC" : "AJ35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "addr[0]" : { "LOC" : "AJ28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[1]" : { "LOC" : "AH28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[2]" : { "LOC" : "AG31", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[3]" : { "LOC" : "AF30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[4]" : { "LOC" : "AK29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[5]" : { "LOC" : "AK28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[6]" : { "LOC" : "AG29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[7]" : { "LOC" : "AK30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[8]" : { "LOC" : "AJ30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[9]" : { "LOC" : "AH30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[10]" : { "LOC" : "AH29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[11]" : { "LOC" : "AL30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[12]" : { "LOC" : "AL29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[13]" : { "LOC" : "AN33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[14]" : { "LOC" : "AM33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[15]" : { "LOC" : "AM32", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[16]" : { "LOC" : "AV41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[17]" : { "LOC" : "AU41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[18]" : { "LOC" : "BA42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[19]" : { "LOC" : "AU42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[20]" : { "LOC" : "AT41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[21]" : { "LOC" : "BA40", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[22]" : { "LOC" : "BA39", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[23]" : { "LOC" : "BB39", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[24]" : { "LOC" : "AW42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[25]" : { "LOC" : "AW41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "wait_in_b" : { "LOC" : "AM34", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "INPUT", "PULLUP" : "TRUE" }, "rst" : { "LOC" : "_not_usable", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "oe_b" : { "LOC" : "BA41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "ce_b" : { "LOC" : "AL36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "we_b" : { "LOC" : "BB41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "adv_b" : { "LOC" : "AY37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" } }, "uart": { "d_in": { "LOC": "AU33", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "d_out": { "LOC": "AU36", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "rts": { "LOC": "AR34", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "cts": { "LOC": "AT32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "AR30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "AU31", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "AV31", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "AT30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "AN30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "AP30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "AP32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "AR32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" } }, "iic_main": { "sda": { "LOC": "AU32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "scl": { "LOC": "AT35", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" } }, "pins": { "si5324_clk_p": { "LOC": "AD8", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_clk_n": { "LOC": "AD7", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_rst_n": { "LOC": "AT36", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "sgmii_clk_p": { "LOC": "AH8", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "sgmii_clk_n": { "LOC": "AH7", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" } } } ================================================ FILE: boardinfo/vc707g2.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Virtex7", "PCIE", "PCIE2", "PcieHostInterface", "PhysAddrWidth=40", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7vx485tffg1761-2", "need_pcie" : "x7_gen2x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/vc707g2.xdc", "constraints/xilinx/pcie-clocks.xdc"], "implconstraints": ["constraints/xilinx/vc707g2.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "sfp1" : { "rxp" : { "LOC" : "AL6", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "AL5", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "AM4", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "AM3", "PIO_DIRECTION" : "OUTPUT" } }, "fmc": { }, "bpi_flash": { "data[0]" : { "LOC" : "AM36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[1]" : { "LOC" : "AN36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[2]" : { "LOC" : "AJ36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[3]" : { "LOC" : "AJ37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[4]" : { "LOC" : "AK37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[5]" : { "LOC" : "AL37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[6]" : { "LOC" : "AN35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[7]" : { "LOC" : "AP35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[8]" : { "LOC" : "AM37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[9]" : { "LOC" : "AG33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[10]" : { "LOC" : "AH33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[11]" : { "LOC" : "AK35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[12]" : { "LOC" : "AL35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[13]" : { "LOC" : "AJ31", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[14]" : { "LOC" : "AH34", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[15]" : { "LOC" : "AJ35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "addr[0]" : { "LOC" : "AJ28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[1]" : { "LOC" : "AH28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[2]" : { "LOC" : "AG31", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[3]" : { "LOC" : "AF30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[4]" : { "LOC" : "AK29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[5]" : { "LOC" : "AK28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[6]" : { "LOC" : "AG29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[7]" : { "LOC" : "AK30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[8]" : { "LOC" : "AJ30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[9]" : { "LOC" : "AH30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[10]" : { "LOC" : "AH29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[11]" : { "LOC" : "AL30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[12]" : { "LOC" : "AL29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[13]" : { "LOC" : "AN33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[14]" : { "LOC" : "AM33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[15]" : { "LOC" : "AM32", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[16]" : { "LOC" : "AV41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[17]" : { "LOC" : "AU41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[18]" : { "LOC" : "BA42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[19]" : { "LOC" : "AU42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[20]" : { "LOC" : "AT41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[21]" : { "LOC" : "BA40", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[22]" : { "LOC" : "BA39", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[23]" : { "LOC" : "BB39", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[24]" : { "LOC" : "AW42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[25]" : { "LOC" : "AW41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "wait_in_b" : { "LOC" : "AM34", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "INPUT", "PULLUP" : "TRUE" }, "rst" : { "LOC" : "_not_usable", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "oe_b" : { "LOC" : "BA41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "ce_b" : { "LOC" : "AL36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "we_b" : { "LOC" : "BB41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "adv_b" : { "LOC" : "AY37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" } }, "uart": { "d_in": { "LOC": "AU33", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "d_out": { "LOC": "AU36", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "rts": { "LOC": "AR34", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "cts": { "LOC": "AT32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } }, "sdio": { "dat0": { "PACKAGE_PIN": "AR30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "dat1": { "PACKAGE_PIN": "AU31", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "dat2": { "PACKAGE_PIN": "AV31", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "cd_dat3": { "PACKAGE_PIN": "AT30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "clk": { "PACKAGE_PIN": "AN30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "cmd": { "PACKAGE_PIN": "AP30", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "sddet": { "PACKAGE_PIN": "AP32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "sdwp": { "PACKAGE_PIN": "AR32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" } }, "iic_main": { "sda": { "LOC": "AU32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "scl": { "LOC": "AT35", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" } }, "pins": { "si5324_clk_p": { "LOC": "AD8", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_clk_n": { "LOC": "AD7", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_rst_n": { "LOC": "AT36", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "sgmii_clk_p": { "LOC": "AH8", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "sgmii_clk_n": { "LOC": "AH7", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" } } } ================================================ FILE: boardinfo/vc709.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "Virtex7", "PCIE", "PCIE3", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=8", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xc7vx690tffg1761-2", "need_pcie" : "x7_gen3x8", "TOP" : "PcieTop", "constraints": [], "implconstraints": ["constraints/xilinx/vc709.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "leds" : { "L0" : { "LOC" : "AM39", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "LOC" : "AN39", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "LOC" : "AR37", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "LOC" : "AT37", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "LOC" : "AR35", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "LOC" : "AP41", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "LOC" : "AP42", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "LOC" : "AU39", "IOSTANDARD" : "LVCMOS15", "PIO_DIRECTION" : "OUTPUT" } }, "sfp1": { "rxp" : { "LOC" : "AN6", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "AN5", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "AP4", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "AP3", "PIO_DIRECTION" : "OUTPUT" } }, "sfp2": { "rxp" : { "LOC" : "AM8", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "AM7", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "AN2", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "AN1", "PIO_DIRECTION" : "OUTPUT" } }, "sfp3": { "rxp" : { "LOC" : "AL6", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "AL5", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "AM4", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "AM3", "PIO_DIRECTION" : "OUTPUT" } }, "sfp4": { "rxp" : { "LOC" : "AJ6", "PIO_DIRECTION" : "INPUT" }, "rxn" : { "LOC" : "AJ5", "PIO_DIRECTION" : "INPUT" }, "txp" : { "LOC" : "AL2", "PIO_DIRECTION" : "OUTPUT" }, "txn" : { "LOC" : "AL1", "PIO_DIRECTION" : "OUTPUT" } }, "bpi_flash": { "data[0]" : { "LOC" : "AM36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[1]" : { "LOC" : "AN36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[2]" : { "LOC" : "AJ36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[3]" : { "LOC" : "AJ37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[4]" : { "LOC" : "AK37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[5]" : { "LOC" : "AL37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[6]" : { "LOC" : "AN35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[7]" : { "LOC" : "AP35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[8]" : { "LOC" : "AM37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[9]" : { "LOC" : "AG33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[10]" : { "LOC" : "AH33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[11]" : { "LOC" : "AK35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[12]" : { "LOC" : "AL35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[13]" : { "LOC" : "AJ31", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[14]" : { "LOC" : "AH34", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "data[15]" : { "LOC" : "AJ35", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "BIDIR" }, "addr[0]" : { "LOC" : "AJ28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[1]" : { "LOC" : "AH28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[2]" : { "LOC" : "AG31", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[3]" : { "LOC" : "AF30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[4]" : { "LOC" : "AK29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[5]" : { "LOC" : "AK28", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[6]" : { "LOC" : "AG29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[7]" : { "LOC" : "AK30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[8]" : { "LOC" : "AJ30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[9]" : { "LOC" : "AH30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[10]" : { "LOC" : "AH29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[11]" : { "LOC" : "AL30", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[12]" : { "LOC" : "AL29", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[13]" : { "LOC" : "AN33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[14]" : { "LOC" : "AM33", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[15]" : { "LOC" : "AM32", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[16]" : { "LOC" : "AV41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[17]" : { "LOC" : "AU41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[18]" : { "LOC" : "BA42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[19]" : { "LOC" : "AU42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[20]" : { "LOC" : "AT41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[21]" : { "LOC" : "BA40", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[22]" : { "LOC" : "BA39", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[23]" : { "LOC" : "BB39", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[24]" : { "LOC" : "AW42", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "addr[25]" : { "LOC" : "AW41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "wait_in_b" : { "LOC" : "AM34", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "INPUT", "PULLUP" : "TRUE" }, "rst" : { "LOC" : "AG11_not_usable", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "oe_b" : { "LOC" : "BA41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "ce_b" : { "LOC" : "AL36", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "we_b" : { "LOC" : "BB41", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" }, "adv_b" : { "LOC" : "AY37", "IOSTANDARD" : "LVCMOS18", "PIO_DIRECTION" : "OUTPUT" } }, "uart": { "d_in": { "LOC": "AU33", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "d_out": { "LOC": "AU36", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" }, "rts": { "LOC": "AR34", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "cts": { "LOC": "AT32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } }, "iic_main": { "sda": { "LOC": "AU32", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" }, "scl": { "LOC": "AT35", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "BIDIR" } }, "pins": { "userClk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "sys_clk_p": { "LOC": "H19", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "sys_clk_n": { "LOC": "G18", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_clk_p": { "LOC": "AH8", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "si5324_clk_n": { "LOC": "AH7", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_p": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "LOC": "bogus", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "LOC": "bogus", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "si5324_rst_n": { "LOC": "AT36", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/vcs.json ================================================ { "options": { "os" : "ubuntu", "partname" : "xc7z020clg484-1", "TOP" : "XsimTop", "bsvdefines": ["CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "SIMULATION", "SVDPI", "CONNECTAL_BITS_DEPENDENCES=vcssim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/vcu108.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "VirtexUltrascale", "XilinxUltrascale", "PCIE", "PCIE3", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=2", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xcvu095-ffva2104-2-e", "need_pcie" : "xu_gen3x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/vcu108.xdc"], "implconstraints": ["constraints/xilinx/vcu108.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "BTN": { "BTN[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "BTN[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "CLK": { "FPGA_SYSCLK_N": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FPGA_SYSCLK_P": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "CPLD": { "CPLD_IMGSEL[0]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "CPLD_IMGSEL[1]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "CPLD_IMGSEL[2]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "CPLD_RECONFIG": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "DDR": { "DDR3_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "DDR3_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "FMC": { "FMC_GBTCLK_P[00]": { "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_GBTCLK_N[00]": { "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK0_M2C_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK0_M2C_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK1_M2C_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK1_M2C_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[00]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[01]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[02]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[03]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[04]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[05]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[06]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[07]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[08]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[09]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[10]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[11]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[12]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[13]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[14]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[15]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[16]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[17]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[18]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[19]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[20]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[21]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[22]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[23]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[24]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[25]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[26]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[27]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[28]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[29]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[30]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[31]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[32]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[33]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[00]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[01]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[02]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[03]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[04]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[05]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[06]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[07]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[08]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[09]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[10]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[11]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[12]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[13]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[14]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[15]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[16]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[17]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[18]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[19]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[20]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[21]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[22]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[23]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[24]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[25]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[26]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[27]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[28]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[29]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[30]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[31]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[32]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[33]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_PRSNT_LS": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "Fan": { "FAN_PWM": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "FAN_TACH": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "I2C": { "I2C_FPGA_SCL": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "I2C_FPGA_SDA": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "I2C_MUX_RESET": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "sdio": { "cmd": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "clk": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "cd": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d0": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d1": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d2": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d3": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "LED": { "LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "PCIE": { "RST_N_pci_sys_reset_n": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AM17" }, "PCIE_PRSNT_B_LS": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "NOTCONNECTED" }, "PCIE_WAKE": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AY17" }, "CLK_pci_sys_clk_n": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AL8" }, "CLK_pci_sys_clk_p": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AL9" } }, "PMODCTRL": { "DIR_JA[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[2]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[3]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[4]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[5]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[6]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[7]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PMOD_OE_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "PMODData": { "JA_FPGA[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[2]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[3]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[4]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[5]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[6]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[7]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "POWER": { "PCON_ALERT_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PCON_AUXFAULT_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PCON_FAULT": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PWR_SNS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "QDRIIA": { "QDRII_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "QDRII_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "QDRIIC": { "QDRIIC_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "QDRIIC_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "MICRO_SD": { "SD_CCLK": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_CD": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_CMD": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[0]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[1]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[2]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[3]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "SFPCLK": { "SFP_CLK_ALARM_B": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SFP_CLK_RST": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "SFP": { "SFP_REFCLK_N": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "SFP_REFCLK_P": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" } }, "SFPA": { "ETH1_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH1_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH1_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH1_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SFPB": { "ETH2_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH2_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH2_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH2_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SFPC": { "ETH3_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH3_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH3_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH3_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SFPD": { "ETH4_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH4_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH4_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH4_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SI570": { "USERCLK_N": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "USERCLK_P": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "UART": { "UART_CTS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "UART_RTS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "UART_RXD_OUT": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "UART_TXD_IN": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "pins": { "userClk_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/vcu118.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "VirtexUltrascalePlus", "VirtexUltrascale", "XilinxUltrascalePlus", "XilinxUltrascale", "PCIE", "PCIE3", "PcieHostInterface", "PhysAddrWidth=40", "NUMBER_OF_LEDS=2", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest"], "os" : "ubuntu", "partname" : "xcvu9p-flga2104-2L-e", "need_pcie" : "xuplus_gen3x8", "TOP" : "PcieTop", "constraints": ["constraints/xilinx/vcu118.xdc"], "implconstraints": ["constraints/xilinx/vcu118.xdc", "constraints/xilinx/pcie-clocks.xdc"], "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=4", "--derivedclockperiod=4", "--pcieclockperiod=4"], "rewireclockstring" : "" }, "BTN": { "BTN[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "BTN[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "CLK": { "FPGA_SYSCLK_N": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FPGA_SYSCLK_P": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "CPLD": { "CPLD_IMGSEL[0]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "CPLD_IMGSEL[1]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "CPLD_IMGSEL[2]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "CPLD_RECONFIG": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "DDR": { "DDR3_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "DDR3_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "FMC": { "FMC_GBTCLK_P[00]": { "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_GBTCLK_N[00]": { "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK0_M2C_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK0_M2C_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK1_M2C_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_CLK1_M2C_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[00]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[01]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[02]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[03]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[04]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[05]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[06]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[07]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[08]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[09]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[10]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[11]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[12]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[13]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[14]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[15]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[16]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[17]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[18]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[19]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[20]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[21]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[22]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[23]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[24]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[25]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[26]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[27]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[28]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[29]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[30]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[31]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[32]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_N[33]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[00]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[01]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[02]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[03]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[04]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[05]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[06]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[07]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[08]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[09]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[10]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[11]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[12]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[13]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[14]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[15]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[16]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[17]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[18]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[19]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[20]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[21]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[22]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[23]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[24]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[25]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[26]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[27]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[28]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[29]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[30]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[31]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[32]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_LA_P[33]": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "TBD" }, "FMC_PRSNT_LS": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "Fan": { "FAN_PWM": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "FAN_TACH": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "I2C": { "I2C_FPGA_SCL": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "I2C_FPGA_SDA": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "I2C_MUX_RESET": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "sdio": { "cmd": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "clk": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "cd": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d0": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d1": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d2": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "d3": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "LED": { "LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "PCIE": { "RST_N_pci_sys_reset_n": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AM17" }, "PCIE_PRSNT_B_LS": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "NOTCONNECTED" }, "PCIE_WAKE": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "AY17" }, "CLK_pci_sys_clk_n": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AL8" }, "CLK_pci_sys_clk_p": { "IOSTANDARD": "LVDS", "PACKAGE_PIN": "AL9" } }, "PMODCTRL": { "DIR_JA[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[2]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[3]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[4]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[5]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[6]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "DIR_JA[7]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PMOD_OE_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "PMODData": { "JA_FPGA[0]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[1]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[2]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[3]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[4]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[5]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[6]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "JA_FPGA[7]": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "POWER": { "PCON_ALERT_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PCON_AUXFAULT_B": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PCON_FAULT": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "PWR_SNS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "QDRIIA": { "QDRII_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "QDRII_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "QDRIIC": { "QDRIIC_SYSCLK_N": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "QDRIIC_SYSCLK_P": { "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "MICRO_SD": { "SD_CCLK": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_CD": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_CMD": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[0]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[1]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[2]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SD_D[3]": { "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "SFPCLK": { "SFP_CLK_ALARM_B": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" }, "SFP_CLK_RST": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS18", "PACKAGE_PIN": "TBD" } }, "SFP": { "SFP_REFCLK_N": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "SFP_REFCLK_P": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" } }, "SFPA": { "ETH1_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH1_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH1_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH1_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH1_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SFPB": { "ETH2_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH2_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH2_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH2_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH2_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SFPC": { "ETH3_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH3_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH3_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH3_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH3_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SFPD": { "ETH4_LED[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_LED[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_MOD_DETECT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RS[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RS[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RX_LOS": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_TX_DISABLE": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_TX_FAULT": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "ETH4_RX_p": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH4_RX_n": { "PIO_DIRECTION": "INPUT", "PACKAGE_PIN": "TBD" }, "ETH4_TX_p": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" }, "ETH4_TX_n": { "PIO_DIRECTION": "OUTPUT", "PACKAGE_PIN": "TBD" } }, "SI570": { "USERCLK_N": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" }, "USERCLK_P": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS", "DIFF_TERM": "TRUE", "PACKAGE_PIN": "TBD" } }, "UART": { "UART_CTS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "UART_RTS": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "UART_RXD_OUT": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" }, "UART_TXD_IN": { "IOSTANDARD": "LVCMOS15", "PACKAGE_PIN": "TBD" } }, "pins": { "userClk_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "TBD", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "uart_d_in": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "INPUT" }, "uart_d_out": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/verilator.json ================================================ { "options": { "os" : "ubuntu", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "TOP" : "XsimTop", "bsvdefines": ["CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "SIMULATION", "SVDPI", "CONNECTAL_BITS_DEPENDENCES=vlsim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/vsim.json ================================================ { "options": { "os" : "ubuntu", "partname" : "5SGXEA7N2F45C2", "rewireclockstring" : "tclzynqrewireclock", "TOP" : "XsimTop", "bsvdefines": ["MODELSIM=1", "CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "XSIM", "SIMULATION", "SVDPI", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=vsim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/xsim.json ================================================ { "options": { "os" : "ubuntu", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "TOP" : "XsimTop", "bsvdefines": ["XILINX=1", "CnocTop", "XsimHostInterface", "PhysAddrWidth=40", "XSIM", "SIMULATION", "SVDPI", "PcieLanes=8", "CONNECTAL_BITS_DEPENDENCES=xsim"], "CONNECTALFLAGS" : ["--mainclockperiod=20", "--derivedclockperiod=10"], "need_pcie" : "unused" } } ================================================ FILE: boardinfo/zc702.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2"], "os" : "android", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/zc7z020clg484.xdc"], "TOP" : "ZynqTop", "runscript" : "run.android", "CONNECTALFLAGS" : ["--mainclockperiod=10", "--derivedclockperiod=5"], "need_pcie" : "unused" }, "fmc1": { "LA00_p_CC": { "LOC": "K19", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "LOC": "K20", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "LOC": "N19", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "LOC": "N20", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "LOC": "L21", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "LOC": "L22", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "LOC": "J20", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "LOC": "K21", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "LOC": "M21", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "LOC": "M22", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "LOC": "N17", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "LOC": "N18", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "LOC": "J18", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "LOC": "K18", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "LOC": "J15", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "LOC": "K15", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "LOC": "J21", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "LOC": "J22", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "LOC": "M15", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "LOC": "M16", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "LOC": "L17", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "LOC": "M17", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "LOC": "R20", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "LOC": "R21", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "LOC": "N22", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "LOC": "P22", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "LOC": "P16", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "LOC": "R16", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "LOC": "J16", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "LOC": "J17", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "LOC": "P20", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "LOC": "P21", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "LOC": "N15", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "LOC": "P15", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "LOC": "B19", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "LOC": "B20", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "LOC": "D20", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "LOC": "C20", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "LOC": "E19", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "LOC": "E20", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "LOC": "L18", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "LOC": "L19", "IOSTANDARD": "LVCMOS25" } }, "fmc2": { "LA00_p_CC": { "LOC": "Y19", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "LOC": "AA19", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "LOC": "W16", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "LOC": "Y16", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "LOC": "V14", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "LOC": "V15", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "LOC": "AA16", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "LOC": "AB16", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "LOC": "V13", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "LOC": "W13", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "LOC": "AB19", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "LOC": "AB20", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "LOC": "U17", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "LOC": "V17", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "LOC": "T21", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "LOC": "U21", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "LOC": "AA17", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "LOC": "AB17", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "LOC": "U15", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "LOC": "U16", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "LOC": "Y20", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "LOC": "Y21", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "LOC": "Y14", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "LOC": "AA14", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "LOC": "W15", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "LOC": "Y15", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "LOC": "V22", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "LOC": "W22", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "LOC": "T22", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "LOC": "U22", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "LOC": "Y13", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "LOC": "AA13", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "LOC": "AB14", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "LOC": "AB15", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "LOC": "AA7", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "LOC": "AA6", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "LOC": "AA9", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "LOC": "AA8", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "LOC": "R6", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "LOC": "T6", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "LOC": "Y18", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "LOC": "AA18", "IOSTANDARD": "LVCMOS25" } }, "leds" : { "L0" : { "LOC" : "E15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "LOC" : "D15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "LOC" : "W17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "LOC" : "W5", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "LOC" : "V7", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "LOC" : "W10", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "LOC" : "P18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "LOC" : "P17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "xadc" : { "L0" : { "LOC" : "H17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "LOC" : "H22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "LOC" : "G22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "LOC" : "H18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "hdmi" : { "clock" : { "LOC" : "L16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "hsync" : { "LOC" : "R18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "vsync" : { "LOC" : "H15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "de" : { "LOC" : "T18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[0]" : { "LOC" : "AB21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[1]" : { "LOC" : "AA21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[2]" : { "LOC" : "AB22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[3]" : { "LOC" : "AA22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[4]" : { "LOC" : "V19", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[5]" : { "LOC" : "V18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[6]" : { "LOC" : "V20", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[7]" : { "LOC" : "U20", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[8]" : { "LOC" : "W21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[9]" : { "LOC" : "W20", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[10]" : { "LOC" : "W18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[11]" : { "LOC" : "T19", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[12]" : { "LOC" : "U19", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[13]" : { "LOC" : "R19", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[14]" : { "LOC" : "T17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[15]" : { "LOC" : "T16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/zc706.json ================================================ { "options": { "os" : "android", "partname" : "xc7z045ffg900-2", "rewireclockstring" : "tclzynqrewireclock", "constraints": ["constraints/xilinx/xc7z045ffg900.xdc", "constraints/xilinx/zc706.xdc"], "implconstraints": ["constraints/xilinx/xc7z045ffg900.xdc", "constraints/xilinx/zc706.xdc"], "TOP" : "ZynqTop", "runscript" : "run.android", "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "NUMBER_OF_LEDS=4", "PcieLanes=4", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2"], "CONNECTALFLAGS": ["--mainclockperiod=5", "--derivedclockperiod=2.5"], "need_pcie" : "unused" }, "sfp1": { "mod_def0": { "IOSTANDARD": "LVCMOS15", "LOC": "AB20" }, "mod_def1": { "IOSTANDARD": "LVCMOS15", "LOC": "AB19" }, "mod_def2": { "IOSTANDARD": "LVCMOS15", "LOC": "AA19" }, "rx_los": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AE20" }, "tx_disable": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AA18" }, "tx_fault": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AD19" }, "rxp": { "PIO_DIRECTION": "INPUT", "LOC": "AC4" }, "rxn": { "PIO_DIRECTION": "INPUT", "LOC": "AC3" }, "txp": { "PIO_DIRECTION": "OUTPUT", "LOC": "AB2" }, "txn": { "PIO_DIRECTION": "OUTPUT", "LOC": "AB1" } }, "lpcfmc": { "CLK0_M2C_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG16" }, "CLK0_M2C_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG17" }, "CLK1_M2C_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD28" }, "CLK1_M2C_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC28" }, "LA00_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF13" }, "LA00_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE13" }, "LA01_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG15" }, "LA01_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF15" }, "LA02_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF12" }, "LA02_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE12" }, "LA03_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH12" }, "LA03_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG12" }, "LA04_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK15" }, "LA04_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ15" }, "LA05_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE15" }, "LA05_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE16" }, "LA06_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC12" }, "LA06_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB12" }, "LA07_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AA14" }, "LA07_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AA15" }, "LA08_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD13" }, "LA08_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD14" }, "LA09_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH13" }, "LA09_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH14" }, "LA10_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC13" }, "LA10_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC14" }, "LA11_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK16" }, "LA11_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ16" }, "LA12_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD15" }, "LA12_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD16" }, "LA13_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH16" }, "LA13_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH17" }, "LA14_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF17" }, "LA14_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF18" }, "LA15_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB14" }, "LA15_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB15" }, "LA16_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE17" }, "LA16_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE18" }, "LA17_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC27" }, "LA17_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB27" }, "LA18_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF27" }, "LA18_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE27" }, "LA19_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH27" }, "LA19_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH26" }, "LA20_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG27" }, "LA20_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG26" }, "LA21_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH29" }, "LA21_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH28" }, "LA22_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK28" }, "LA22_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK27" }, "LA23_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK26" }, "LA23_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ26" }, "LA24_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG30" }, "LA24_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF30" }, "LA25_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG29" }, "LA25_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF29" }, "LA26_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK30" }, "LA26_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ30" }, "LA27_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ29" }, "LA27_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ28" }, "LA28_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE26" }, "LA28_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD25" }, "LA29_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF25" }, "LA29_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE25" }, "LA30_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB30" }, "LA30_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB29" }, "LA31_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD29" }, "LA31_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC29" }, "LA32_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "Y27" }, "LA32_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "Y26" }, "LA33_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AA30" }, "LA33_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "Y30" }, "DP0_C2M_N": { "PACKAGE_PIN": "AB1" }, "DP0_C2M_P": { "PACKAGE_PIN": "AB2" }, "DP0_M2C_N": { "PACKAGE_PIN": "AC3" }, "DP0_M2C_P": { "PACKAGE_PIN": "AC4" }, "GBTCLK0_M2C_C_N": { "PACKAGE_PIN": "U7" }, "GBTCLK0_M2C_C_P": { "PACKAGE_PIN": "U8" } }, "hpcfmc": { "CLK0_M2C_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF22" }, "CLK0_M2C_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE22" }, "CLK1_M2C_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "U27" }, "CLK1_M2C_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "U26" }, "LA00_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG20" }, "LA00_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF20" }, "LA01_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH21" }, "LA01_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG21" }, "LA02_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK18" }, "LA02_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK17" }, "LA03_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ19" }, "LA03_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH19" }, "LA04_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AK20" }, "LA04_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ20" }, "LA05_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH24" }, "LA05_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH23" }, "LA06_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AH22" }, "LA06_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG22" }, "LA07_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ24" }, "LA07_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AJ23" }, "LA08_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG19" }, "LA08_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF19" }, "LA09_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE21" }, "LA09_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD21" }, "LA10_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG25" }, "LA10_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AG24" }, "LA11_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AE23" }, "LA11_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD23" }, "LA12_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF24" }, "LA12_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AF23" }, "LA13_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AA23" }, "LA13_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AA22" }, "LA14_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AD24" }, "LA14_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AC24" }, "LA15_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "Y23" }, "LA15_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "Y22" }, "LA16_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AB24" }, "LA16_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "AA24" }, "LA17_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "W24" }, "LA17_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "V23" }, "LA18_CC_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "W26" }, "LA18_CC_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "W25" }, "LA19_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "T25" }, "LA19_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "T24" }, "LA20_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "V26" }, "LA20_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "U25" }, "LA21_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "W30" }, "LA21_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "W29" }, "LA22_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "W28" }, "LA22_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "V27" }, "LA23_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P26" }, "LA23_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P25" }, "LA24_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "U30" }, "LA24_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "T30" }, "LA25_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "U29" }, "LA25_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "T29" }, "LA26_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "T28" }, "LA26_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "R28" }, "LA27_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "V29" }, "LA27_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "V28" }, "LA28_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "R30" }, "LA28_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P30" }, "LA29_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "R26" }, "LA29_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "R25" }, "LA30_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P24" }, "LA30_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P23" }, "LA31_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P29" }, "LA31_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "N29" }, "LA32_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "R21" }, "LA32_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "P21" }, "LA33_N": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "N27" }, "LA33_P": { "IOSTANDARD": "LVCMOS25", "PACKAGE_PIN": "N26" }, "DP0_C2M_N": { "PACKAGE_PIN": "AK9" }, "DP0_C2M_P": { "PACKAGE_PIN": "AK10" }, "DP0_M2C_N": { "PACKAGE_PIN": "AH9" }, "DP0_M2C_P": { "PACKAGE_PIN": "AH10" }, "DP1_C2M_N": { "PACKAGE_PIN": "AK5" }, "DP1_C2M_P": { "PACKAGE_PIN": "AK6" }, "DP1_M2C_N": { "PACKAGE_PIN": "AJ7" }, "DP1_M2C_P": { "PACKAGE_PIN": "AJ8" }, "DP2_C2M_N": { "PACKAGE_PIN": "AJ3" }, "DP2_C2M_P": { "PACKAGE_PIN": "AJ4" }, "DP2_M2C_N": { "PACKAGE_PIN": "AG7" }, "DP2_M2C_P": { "PACKAGE_PIN": "AG8" }, "DP3_C2M_N": { "PACKAGE_PIN": "AK1" }, "DP3_C2M_P": { "PACKAGE_PIN": "AK2" }, "DP3_M2C_N": { "PACKAGE_PIN": "AE7" }, "DP3_M2C_P": { "PACKAGE_PIN": "AE8" }, "DP4_C2M_N": { "PACKAGE_PIN": "AH1" }, "DP4_C2M_P": { "PACKAGE_PIN": "AH2" }, "DP4_M2C_N": { "PACKAGE_PIN": "AH5" }, "DP4_M2C_P": { "PACKAGE_PIN": "AH6" }, "DP5_C2M_N": { "PACKAGE_PIN": "AF1" }, "DP5_C2M_P": { "PACKAGE_PIN": "AF2" }, "DP5_M2C_N": { "PACKAGE_PIN": "AG3" }, "DP5_M2C_P": { "PACKAGE_PIN": "AG4" }, "DP6_C2M_N": { "PACKAGE_PIN": "AE3" }, "DP6_C2M_P": { "PACKAGE_PIN": "AE4" }, "DP6_M2C_N": { "PACKAGE_PIN": "AF5" }, "DP6_M2C_P": { "PACKAGE_PIN": "AF6" }, "DP7_C2M_N": { "PACKAGE_PIN": "AD1" }, "DP7_C2M_P": { "PACKAGE_PIN": "AD2" }, "DP7_M2C_N": { "PACKAGE_PIN": "AD5" }, "DP7_M2C_P": { "PACKAGE_PIN": "AD6" }, "GBTCLK0_M2C_C_N": { "PACKAGE_PIN": "AD9" }, "GBTCLK0_M2C_C_P": { "PACKAGE_PIN": "AD10" }, "GBTCLK1_M2C_C_N": { "PACKAGE_PIN": "AA7" }, "GBTCLK1_M2C_C_P": { "PACKAGE_PIN": "AA8" } }, "pins": { "GPIO_LEDS[0]": { "PACKAGE_PIN": "A17", "IOSTANDARD": "LVCMOS15", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_LEDS[1]": { "PACKAGE_PIN": "W21", "IOSTANDARD": "LVCMOS25", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_LEDS[2]": { "PACKAGE_PIN": "G2", "IOSTANDARD": "LVCMOS15", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_LEDS[3]": { "PACKAGE_PIN": "Y21", "IOSTANDARD": "LVCMOS25", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_sw_left": { "PACKAGE_PIN": "AK25", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_center": { "PACKAGE_PIN": "K15", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_right": { "PACKAGE_PIN": "R27", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "pl_cpu_reset": { "PACKAGE_PIN": "A8", "IOSTANDARD": "LVCMOS15", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "userClk_p": { "PACKAGE_PIN": "AF14", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "AG14", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "AD18", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "AD19", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "W8", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "W7", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "AB6", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "AB5", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "Y2", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "Y1", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" } }, "pcie": { "PCIE_clk_q0_p": { "PACKAGE_PIN": "N8", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_clk_q0_n": { "PACKAGE_PIN": "N7", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_tx0_p": { "PACKAGE_PIN": "N4", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx0_n": { "PACKAGE_PIN": "N3", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx1_p": { "PACKAGE_PIN": "P2", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx1_n": { "PACKAGE_PIN": "P1", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx2_p": { "PACKAGE_PIN": "R4", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx2_n": { "PACKAGE_PIN": "R3", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx3_p": { "PACKAGE_PIN": "T2", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx3_n": { "PACKAGE_PIN": "T1", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_rx0_p": { "PACKAGE_PIN": "P6", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx0_n": { "PACKAGE_PIN": "P5", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx1_p": { "PACKAGE_PIN": "T6", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx1_n": { "PACKAGE_PIN": "T5", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx2_p": { "PACKAGE_PIN": "U4", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx2_n": { "PACKAGE_PIN": "U3", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx3_p": { "PACKAGE_PIN": "V6", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx3_n": { "PACKAGE_PIN": "V5", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_perst": { "PACKAGE_PIN": "AK23", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "PCIE_wake_b": { "PACKAGE_PIN": "AK22", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" } } } ================================================ FILE: boardinfo/zc706_ubuntu.json ================================================ { "options": { "os" : "ubuntu", "arch" : "arm", "toolchain" : "arm-linux-gnueabihf-", "partname" : "xc7z045ffg900-2", "rewireclockstring" : "tclzynqrewireclock", "constraints": ["constraints/xilinx/xc7z045ffg900.xdc", "constraints/xilinx/zc706.xdc"], "implconstraints": ["constraints/xilinx/xc7z045ffg900.xdc", "constraints/xilinx/zc706.xdc"], "TOP" : "ZynqTop", "runscript" : "run.ubuntu", "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "NUMBER_OF_LEDS=4", "PcieLanes=4", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.ubuntu", "CONNECTAL_EXENAME=ubuntu.exe", "CONNECTAL_EXENAME2=ubuntu.exe2"], "CONNECTALFLAGS": ["--mainclockperiod=5", "--derivedclockperiod=2.5"], "need_pcie" : "unused" }, "sfp1": { "mod_def0": { "IOSTANDARD": "LVCMOS15", "LOC": "AB20" }, "mod_def1": { "IOSTANDARD": "LVCMOS15", "LOC": "AB19" }, "mod_def2": { "IOSTANDARD": "LVCMOS15", "LOC": "AA19" }, "rx_los": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AE20" }, "tx_disable": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AA18" }, "tx_fault": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVCMOS25", "LOC": "AD19" }, "rxp": { "PIO_DIRECTION": "INPUT", "LOC": "AC4" }, "rxn": { "PIO_DIRECTION": "INPUT", "LOC": "AC3" }, "txp": { "PIO_DIRECTION": "OUTPUT", "LOC": "AB2" }, "txn": { "PIO_DIRECTION": "OUTPUT", "LOC": "AB1" } }, "fmc1": { "LA00_p_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "", "IOSTANDARD": "LVCMOS25" } }, "pins": { "GPIO_leds[0]": { "PACKAGE_PIN": "A17", "IOSTANDARD": "LVCMOS15", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_leds[1]": { "PACKAGE_PIN": "W21", "IOSTANDARD": "LVCMOS25", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_leds[2]": { "PACKAGE_PIN": "G2", "IOSTANDARD": "LVCMOS15", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_leds[3]": { "PACKAGE_PIN": "Y21", "IOSTANDARD": "LVCMOS25", "slew": "SLOW", "PIO_DIRECTION": "OUTPUT" }, "GPIO_sw_left": { "PACKAGE_PIN": "AK25", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_center": { "PACKAGE_PIN": "K15", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_right": { "PACKAGE_PIN": "R27", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "pl_cpu_reset": { "PACKAGE_PIN": "A8", "IOSTANDARD": "LVCMOS15", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "userClk_p": { "PACKAGE_PIN": "AF14", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "userClk_n": { "PACKAGE_PIN": "AG14", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "smaUserClk_p": { "PACKAGE_PIN": "AD18", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "smaUserClk_n": { "PACKAGE_PIN": "AD19", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtRefClk_p": { "PACKAGE_PIN": "W8", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRefClk_n": { "PACKAGE_PIN": "W7", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_p": { "PACKAGE_PIN": "AB6", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtRx_n": { "PACKAGE_PIN": "AB5", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "mgtTx_p": { "PACKAGE_PIN": "Y2", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "mgtTx_n": { "PACKAGE_PIN": "Y1", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" } }, "pcie": { "PCIE_clk_q0_p": { "PACKAGE_PIN": "N8", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_clk_q0_n": { "PACKAGE_PIN": "N7", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_tx0_p": { "PACKAGE_PIN": "N4", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx0_n": { "PACKAGE_PIN": "N3", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx1_p": { "PACKAGE_PIN": "P2", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx1_n": { "PACKAGE_PIN": "P1", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx2_p": { "PACKAGE_PIN": "R4", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx2_n": { "PACKAGE_PIN": "R3", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx3_p": { "PACKAGE_PIN": "T2", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_tx3_n": { "PACKAGE_PIN": "T1", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "OUTPUT" }, "PCIE_rx0_p": { "PACKAGE_PIN": "P6", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx0_n": { "PACKAGE_PIN": "P5", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx1_p": { "PACKAGE_PIN": "T6", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx1_n": { "PACKAGE_PIN": "T5", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx2_p": { "PACKAGE_PIN": "U4", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx2_n": { "PACKAGE_PIN": "U3", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx3_p": { "PACKAGE_PIN": "V6", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_rx3_n": { "PACKAGE_PIN": "V5", "DIFF_TERM": "TRUE", "IOSTANDARD": "LVDS_25", "PIO_DIRECTION": "INPUT" }, "PCIE_perst": { "PACKAGE_PIN": "AK23", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" }, "PCIE_wake_b": { "PACKAGE_PIN": "AK22", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "INPUT" } } } ================================================ FILE: boardinfo/zcu102.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqUltrascale", "ZynqHostInterface", "PhysAddrWidth=40", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest", "CONNECTAL_EXENAME=ubuntu.exe", "CONNECTAL_EXENAME2=ubuntu.exe2"], "os" : "ubuntu", "arch" : "arm64", "toolchain" : "aarch64-linux-gnu-", "partname" : "xczu9eg-ffvb1156-2-i-es2", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/zcu102.xdc"], "TOP" : "ZynqUltraTop", "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=5", "--derivedclockperiod=2.5"], "ZYNQ_MPSOC": "zynq_ultra_ps_e" }, "fmc1": { "LA00_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" } }, "fmc2": { "LA00_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" } }, "leds" : { "L0" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "xadc" : { "L0" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "hdmi" : { "clock" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "hsync" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "vsync" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "de" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[0]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[1]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[2]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[3]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[4]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[5]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[6]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[7]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[8]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[9]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[10]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[11]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[12]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[13]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[14]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[15]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/zcu111.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqUltrascale", "ZynqHostInterface", "PhysAddrWidth=40", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest", "CONNECTAL_EXENAME=ubuntu.exe", "CONNECTAL_EXENAME2=ubuntu.exe2"], "os" : "ubuntu", "arch" : "arm64", "toolchain" : "aarch64-linux-gnu-", "partname" : "xczu28dr-ffvg1517-2-e", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/zcu111.xdc"], "TOP" : "ZynqUltraTop", "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=5", "--derivedclockperiod=2.5"], "ZYNQ_MPSOC" : "zynq_ultra_ps_e" }, "fmc1": { "LA00_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" } }, "fmc2": { "LA00_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA00_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA01_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA02_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA03_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA04_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA05_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA06_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA07_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA08_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA09_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA10_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA11_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA12_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA13_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA14_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA15_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA16_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA17_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_p_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA18_n_CC": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "LA19_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_p": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_n": { "PACKAGE_PIN": "TBD", "IOSTANDARD": "LVCMOS25" } }, "leds" : { "L0" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "xadc" : { "L0" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "hdmi" : { "clock" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "hsync" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "vsync" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "de" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[0]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[1]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[2]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[3]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[4]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[5]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[6]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[7]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[8]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[9]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[10]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[11]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[12]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[13]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[14]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[15]" : { "PACKAGE_PIN" : "TBD", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/zedboard.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "CFGBVS=VCCO", "CONFIG_VOLTAGE=3.3", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2" ], "os" : "android", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/zc7z020clg484.xdc"], "TOP" : "ZynqTop", "runscript" : "run.android", "CONNECTALFLAGS" : ["--mainclockperiod=10", "--derivedclockperiod=5"], "need_pcie" : "unused" }, "fmc1": { "LA00_CC_P": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25" }, "LA00_CC_N": { "PACKAGE_PIN": "M20", "IOSTANDARD": "LVCMOS25" }, "LA01_CC_P": { "PACKAGE_PIN": "N19", "IOSTANDARD": "LVCMOS25" }, "LA01_CC_N": { "PACKAGE_PIN": "N20", "IOSTANDARD": "LVCMOS25" }, "LA02_P": { "PACKAGE_PIN": "P17", "IOSTANDARD": "LVCMOS25" }, "LA02_N": { "PACKAGE_PIN": "P18", "IOSTANDARD": "LVCMOS25" }, "LA03_P": { "PACKAGE_PIN": "N22", "IOSTANDARD": "LVCMOS25" }, "LA03_N": { "PACKAGE_PIN": "P22", "IOSTANDARD": "LVCMOS25" }, "LA04_P": { "PACKAGE_PIN": "M21", "IOSTANDARD": "LVCMOS25" }, "LA04_N": { "PACKAGE_PIN": "M22", "IOSTANDARD": "LVCMOS25" }, "LA05_P": { "PACKAGE_PIN": "J18", "IOSTANDARD": "LVCMOS25" }, "LA05_N": { "PACKAGE_PIN": "K18", "IOSTANDARD": "LVCMOS25" }, "LA06_P": { "PACKAGE_PIN": "L21", "IOSTANDARD": "LVCMOS25" }, "LA06_N": { "PACKAGE_PIN": "L22", "IOSTANDARD": "LVCMOS25" }, "LA07_P": { "PACKAGE_PIN": "T16", "IOSTANDARD": "LVCMOS25" }, "LA07_N": { "PACKAGE_PIN": "T17", "IOSTANDARD": "LVCMOS25" }, "LA08_P": { "PACKAGE_PIN": "J21", "IOSTANDARD": "LVCMOS25" }, "LA08_N": { "PACKAGE_PIN": "J22", "IOSTANDARD": "LVCMOS25" }, "LA09_P": { "PACKAGE_PIN": "R20", "IOSTANDARD": "LVCMOS25" }, "LA09_N": { "PACKAGE_PIN": "R21", "IOSTANDARD": "LVCMOS25" }, "LA10_P": { "PACKAGE_PIN": "R19", "IOSTANDARD": "LVCMOS25" }, "LA10_N": { "PACKAGE_PIN": "T19", "IOSTANDARD": "LVCMOS25" }, "LA11_P": { "PACKAGE_PIN": "N17", "IOSTANDARD": "LVCMOS25" }, "LA11_N": { "PACKAGE_PIN": "N18", "IOSTANDARD": "LVCMOS25" }, "LA12_P": { "PACKAGE_PIN": "P20", "IOSTANDARD": "LVCMOS25" }, "LA12_N": { "PACKAGE_PIN": "P21", "IOSTANDARD": "LVCMOS25" }, "LA13_P": { "PACKAGE_PIN": "L17", "IOSTANDARD": "LVCMOS25" }, "LA13_N": { "PACKAGE_PIN": "M17", "IOSTANDARD": "LVCMOS25" }, "LA14_P": { "PACKAGE_PIN": "K19", "IOSTANDARD": "LVCMOS25" }, "LA14_N": { "PACKAGE_PIN": "K20", "IOSTANDARD": "LVCMOS25" }, "LA15_P": { "PACKAGE_PIN": "J16", "IOSTANDARD": "LVCMOS25" }, "LA15_N": { "PACKAGE_PIN": "J17", "IOSTANDARD": "LVCMOS25" }, "LA16_P": { "PACKAGE_PIN": "J20", "IOSTANDARD": "LVCMOS25" }, "LA16_N": { "PACKAGE_PIN": "K21", "IOSTANDARD": "LVCMOS25" }, "LA17_CC_P": { "PACKAGE_PIN": "B19", "IOSTANDARD": "LVCMOS25" }, "LA17_CC_N": { "PACKAGE_PIN": "B20", "IOSTANDARD": "LVCMOS25" }, "LA18_CC_P": { "PACKAGE_PIN": "D20", "IOSTANDARD": "LVCMOS25" }, "LA18_CC_N": { "PACKAGE_PIN": "C20", "IOSTANDARD": "LVCMOS25" }, "LA19_P": { "PACKAGE_PIN": "G15", "IOSTANDARD": "LVCMOS25" }, "LA19_N": { "PACKAGE_PIN": "G16", "IOSTANDARD": "LVCMOS25" }, "LA20_P": { "PACKAGE_PIN": "G20", "IOSTANDARD": "LVCMOS25" }, "LA20_N": { "PACKAGE_PIN": "G21", "IOSTANDARD": "LVCMOS25" }, "LA21_P": { "PACKAGE_PIN": "E19", "IOSTANDARD": "LVCMOS25" }, "LA21_N": { "PACKAGE_PIN": "E20", "IOSTANDARD": "LVCMOS25" }, "LA22_P": { "PACKAGE_PIN": "G19", "IOSTANDARD": "LVCMOS25" }, "LA22_N": { "PACKAGE_PIN": "F19", "IOSTANDARD": "LVCMOS25" }, "LA23_P": { "PACKAGE_PIN": "E15", "IOSTANDARD": "LVCMOS25" }, "LA23_N": { "PACKAGE_PIN": "D15", "IOSTANDARD": "LVCMOS25" }, "LA24_P": { "PACKAGE_PIN": "A18", "IOSTANDARD": "LVCMOS25" }, "LA24_N": { "PACKAGE_PIN": "A19", "IOSTANDARD": "LVCMOS25" }, "LA25_P": { "PACKAGE_PIN": "D22", "IOSTANDARD": "LVCMOS25" }, "LA25_N": { "PACKAGE_PIN": "C22", "IOSTANDARD": "LVCMOS25" }, "LA26_P": { "PACKAGE_PIN": "F18", "IOSTANDARD": "LVCMOS25" }, "LA26_N": { "PACKAGE_PIN": "E18", "IOSTANDARD": "LVCMOS25" }, "LA27_P": { "PACKAGE_PIN": "E21", "IOSTANDARD": "LVCMOS25" }, "LA27_N": { "PACKAGE_PIN": "D21", "IOSTANDARD": "LVCMOS25" }, "LA28_P": { "PACKAGE_PIN": "A16", "IOSTANDARD": "LVCMOS25" }, "LA28_N": { "PACKAGE_PIN": "A17", "IOSTANDARD": "LVCMOS25" }, "LA29_P": { "PACKAGE_PIN": "C17", "IOSTANDARD": "LVCMOS25" }, "LA29_N": { "PACKAGE_PIN": "C18", "IOSTANDARD": "LVCMOS25" }, "LA30_P": { "PACKAGE_PIN": "C15", "IOSTANDARD": "LVCMOS25" }, "LA30_N": { "PACKAGE_PIN": "B15", "IOSTANDARD": "LVCMOS25" }, "LA31_P": { "PACKAGE_PIN": "B16", "IOSTANDARD": "LVCMOS25" }, "LA31_N": { "PACKAGE_PIN": "B17", "IOSTANDARD": "LVCMOS25" }, "LA32_P": { "PACKAGE_PIN": "A21", "IOSTANDARD": "LVCMOS25" }, "LA32_N": { "PACKAGE_PIN": "A22", "IOSTANDARD": "LVCMOS25" }, "LA33_P": { "PACKAGE_PIN": "B21", "IOSTANDARD": "LVCMOS25" }, "LA33_N": { "PACKAGE_PIN": "B22", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_P": { "PACKAGE_PIN": "L18", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_N": { "PACKAGE_PIN": "L19", "IOSTANDARD": "LVCMOS25" }, "CLK1_M2C_P": { "PACKAGE_PIN": "D18", "IOSTANDARD": "LVCMOS25" }, "CLK1_M2C_N": { "PACKAGE_PIN": "C19", "IOSTANDARD": "LVCMOS25" }, "SDA": { "PACKAGE_PIN": "U7", "IOSTANDARD": "LVCMOS25" }, "SCL": { "PACKAGE_PIN": "R7", "IOSTANDARD": "LVCMOS25" } }, "pins": { "GPIO_sw_left": { "PACKAGE_PIN": "N15", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_center": { "PACKAGE_PIN": "P16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_right": { "PACKAGE_PIN": "R18", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_down": { "PACKAGE_PIN": "R16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_up": { "PACKAGE_PIN": "T18", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" } }, "pmoda" : { "J1" : { "PACKAGE_PIN" : "Y11", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "AA11", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "Y10", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "AA9", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "AB11", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "AB10", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "AB9", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "AA8", "IOSTANDARD" : "LVCMOS33" } }, "pmodb" : { "J1" : { "PACKAGE_PIN" : "W12", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "W11", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "V10", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "W8", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "V12", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "W10", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "V9", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "V8", "IOSTANDARD" : "LVCMOS33" } }, "pmodc" : { "J1" : { "PACKAGE_PIN" : "AB7", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "AB6", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "Y4", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "AA4", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "R6", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "T6", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "T4", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "U4", "IOSTANDARD" : "LVCMOS33" } }, "pmodd" : { "J1" : { "PACKAGE_PIN" : "V7", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "W7", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "V5", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "V4", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "W6", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "W5", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "U6", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "U5", "IOSTANDARD" : "LVCMOS33" } }, "pmode_documentation_only;cannot use from PL" : { "MIO13" : { "PACKAGE_PIN" : "A6", "CONNECTORPIN" : "JE1" }, "MIO10" : { "PACKAGE_PIN" : "G7", "CONNECTORPIN" : "JE2" }, "MIO11" : { "PACKAGE_PIN" : "B4", "CONNECTORPIN" : "JE3" }, "MIO12" : { "PACKAGE_PIN" : "C5", "CONNECTORPIN" : "JE4" }, "MIO0" : { "PACKAGE_PIN" : "G6", "CONNECTORPIN" : "JE7" }, "MIO9" : { "PACKAGE_PIN" : "C4", "CONNECTORPIN" : "JE8" }, "MIO14" : { "PACKAGE_PIN" : "B6", "CONNECTORPIN" : "JE9" }, "MIO15" : { "PACKAGE_PIN" : "E6", "CONNECTORPIN" : "JE10" } }, "pins": { "GPIO_LEDS[0]" : { "PACKAGE_PIN" : "T22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[1]" : { "PACKAGE_PIN" : "T21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[2]" : { "PACKAGE_PIN" : "U22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[3]" : { "PACKAGE_PIN" : "U21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[4]" : { "PACKAGE_PIN" : "V22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[5]" : { "PACKAGE_PIN" : "W22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[6]" : { "PACKAGE_PIN" : "U19", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "GPIO_LEDS[7]" : { "PACKAGE_PIN" : "U14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "i2c0" : { "scl" : { "PACKAGE_PIN" : "AA18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sda" : { "PACKAGE_PIN" : "Y16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "BIDIR" } }, "hdmi" : { "clock" : { "PACKAGE_PIN" : "W18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "hsync" : { "PACKAGE_PIN" : "V17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "vsync" : { "PACKAGE_PIN" : "W17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "de" : { "PACKAGE_PIN" : "U16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[0]" : { "PACKAGE_PIN" : "Y13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[1]" : { "PACKAGE_PIN" : "AA13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[2]" : { "PACKAGE_PIN" : "AA14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[3]" : { "PACKAGE_PIN" : "Y14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[4]" : { "PACKAGE_PIN" : "AB15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[5]" : { "PACKAGE_PIN" : "AB16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[6]" : { "PACKAGE_PIN" : "AA16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[7]" : { "PACKAGE_PIN" : "AB17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[8]" : { "PACKAGE_PIN" : "AA17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[9]" : { "PACKAGE_PIN" : "Y15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[10]" : { "PACKAGE_PIN" : "W13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[11]" : { "PACKAGE_PIN" : "W15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[12]" : { "PACKAGE_PIN" : "V15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[13]" : { "PACKAGE_PIN" : "U17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[14]" : { "PACKAGE_PIN" : "V14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[15]" : { "PACKAGE_PIN" : "V13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/zedboard_ubuntu.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "CFGBVS=VCCO", "CONFIG_VOLTAGE=3.3", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.pcietest", "CONNECTAL_EXENAME=ubuntu.exe", "CONNECTAL_EXENAME2=ubuntu.exe2" ], "os" : "ubuntu", "arch" : "arm", "toolchain" : "arm-linux-gnueabihf-", "partname" : "xc7z020clg484-1", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/zc7z020clg484.xdc"], "TOP" : "ZynqTop", "runscript" : "run.pcietest", "CONNECTALFLAGS" : ["--mainclockperiod=10", "--derivedclockperiod=5"], "need_pcie" : "unused" }, "fmc1": { "LA00_CC_P": { "PACKAGE_PIN": "M19", "IOSTANDARD": "LVCMOS25" }, "LA00_CC_N": { "PACKAGE_PIN": "M20", "IOSTANDARD": "LVCMOS25" }, "LA01_CC_P": { "PACKAGE_PIN": "N19", "IOSTANDARD": "LVCMOS25" }, "LA01_CC_N": { "PACKAGE_PIN": "N20", "IOSTANDARD": "LVCMOS25" }, "LA02_P": { "PACKAGE_PIN": "P17", "IOSTANDARD": "LVCMOS25" }, "LA02_N": { "PACKAGE_PIN": "P18", "IOSTANDARD": "LVCMOS25" }, "LA03_P": { "PACKAGE_PIN": "N22", "IOSTANDARD": "LVCMOS25" }, "LA03_N": { "PACKAGE_PIN": "P22", "IOSTANDARD": "LVCMOS25" }, "LA04_P": { "PACKAGE_PIN": "M21", "IOSTANDARD": "LVCMOS25" }, "LA04_N": { "PACKAGE_PIN": "M22", "IOSTANDARD": "LVCMOS25" }, "LA05_P": { "PACKAGE_PIN": "J18", "IOSTANDARD": "LVCMOS25" }, "LA05_N": { "PACKAGE_PIN": "K18", "IOSTANDARD": "LVCMOS25" }, "LA06_P": { "PACKAGE_PIN": "L21", "IOSTANDARD": "LVCMOS25" }, "LA06_N": { "PACKAGE_PIN": "L22", "IOSTANDARD": "LVCMOS25" }, "LA07_P": { "PACKAGE_PIN": "T16", "IOSTANDARD": "LVCMOS25" }, "LA07_N": { "PACKAGE_PIN": "T17", "IOSTANDARD": "LVCMOS25" }, "LA08_P": { "PACKAGE_PIN": "J21", "IOSTANDARD": "LVCMOS25" }, "LA08_N": { "PACKAGE_PIN": "J22", "IOSTANDARD": "LVCMOS25" }, "LA09_P": { "PACKAGE_PIN": "R20", "IOSTANDARD": "LVCMOS25" }, "LA09_N": { "PACKAGE_PIN": "R21", "IOSTANDARD": "LVCMOS25" }, "LA10_P": { "PACKAGE_PIN": "R19", "IOSTANDARD": "LVCMOS25" }, "LA10_N": { "PACKAGE_PIN": "T19", "IOSTANDARD": "LVCMOS25" }, "LA11_P": { "PACKAGE_PIN": "N17", "IOSTANDARD": "LVCMOS25" }, "LA11_N": { "PACKAGE_PIN": "N18", "IOSTANDARD": "LVCMOS25" }, "LA12_P": { "PACKAGE_PIN": "P20", "IOSTANDARD": "LVCMOS25" }, "LA12_N": { "PACKAGE_PIN": "P21", "IOSTANDARD": "LVCMOS25" }, "LA13_P": { "PACKAGE_PIN": "L17", "IOSTANDARD": "LVCMOS25" }, "LA13_N": { "PACKAGE_PIN": "M17", "IOSTANDARD": "LVCMOS25" }, "LA14_P": { "PACKAGE_PIN": "K19", "IOSTANDARD": "LVCMOS25" }, "LA14_N": { "PACKAGE_PIN": "K20", "IOSTANDARD": "LVCMOS25" }, "LA15_P": { "PACKAGE_PIN": "J16", "IOSTANDARD": "LVCMOS25" }, "LA15_N": { "PACKAGE_PIN": "J17", "IOSTANDARD": "LVCMOS25" }, "LA16_P": { "PACKAGE_PIN": "J20", "IOSTANDARD": "LVCMOS25" }, "LA16_N": { "PACKAGE_PIN": "K21", "IOSTANDARD": "LVCMOS25" }, "LA17_CC_P": { "PACKAGE_PIN": "B19", "IOSTANDARD": "LVCMOS25" }, "LA17_CC_N": { "PACKAGE_PIN": "B20", "IOSTANDARD": "LVCMOS25" }, "LA18_CC_P": { "PACKAGE_PIN": "D20", "IOSTANDARD": "LVCMOS25" }, "LA18_CC_N": { "PACKAGE_PIN": "C20", "IOSTANDARD": "LVCMOS25" }, "LA19_P": { "PACKAGE_PIN": "G15", "IOSTANDARD": "LVCMOS25" }, "LA19_N": { "PACKAGE_PIN": "G16", "IOSTANDARD": "LVCMOS25" }, "LA20_P": { "PACKAGE_PIN": "G20", "IOSTANDARD": "LVCMOS25" }, "LA20_N": { "PACKAGE_PIN": "G21", "IOSTANDARD": "LVCMOS25" }, "LA21_P": { "PACKAGE_PIN": "E19", "IOSTANDARD": "LVCMOS25" }, "LA21_N": { "PACKAGE_PIN": "E20", "IOSTANDARD": "LVCMOS25" }, "LA22_P": { "PACKAGE_PIN": "G19", "IOSTANDARD": "LVCMOS25" }, "LA22_N": { "PACKAGE_PIN": "F19", "IOSTANDARD": "LVCMOS25" }, "LA23_P": { "PACKAGE_PIN": "E15", "IOSTANDARD": "LVCMOS25" }, "LA23_N": { "PACKAGE_PIN": "D15", "IOSTANDARD": "LVCMOS25" }, "LA24_P": { "PACKAGE_PIN": "A18", "IOSTANDARD": "LVCMOS25" }, "LA24_N": { "PACKAGE_PIN": "A19", "IOSTANDARD": "LVCMOS25" }, "LA25_P": { "PACKAGE_PIN": "D22", "IOSTANDARD": "LVCMOS25" }, "LA25_N": { "PACKAGE_PIN": "C22", "IOSTANDARD": "LVCMOS25" }, "LA26_P": { "PACKAGE_PIN": "F18", "IOSTANDARD": "LVCMOS25" }, "LA26_N": { "PACKAGE_PIN": "E18", "IOSTANDARD": "LVCMOS25" }, "LA27_P": { "PACKAGE_PIN": "E21", "IOSTANDARD": "LVCMOS25" }, "LA27_N": { "PACKAGE_PIN": "D21", "IOSTANDARD": "LVCMOS25" }, "LA28_P": { "PACKAGE_PIN": "A16", "IOSTANDARD": "LVCMOS25" }, "LA28_N": { "PACKAGE_PIN": "A17", "IOSTANDARD": "LVCMOS25" }, "LA29_P": { "PACKAGE_PIN": "C17", "IOSTANDARD": "LVCMOS25" }, "LA29_N": { "PACKAGE_PIN": "C18", "IOSTANDARD": "LVCMOS25" }, "LA30_P": { "PACKAGE_PIN": "C15", "IOSTANDARD": "LVCMOS25" }, "LA30_N": { "PACKAGE_PIN": "B15", "IOSTANDARD": "LVCMOS25" }, "LA31_P": { "PACKAGE_PIN": "B16", "IOSTANDARD": "LVCMOS25" }, "LA31_N": { "PACKAGE_PIN": "B17", "IOSTANDARD": "LVCMOS25" }, "LA32_P": { "PACKAGE_PIN": "A21", "IOSTANDARD": "LVCMOS25" }, "LA32_N": { "PACKAGE_PIN": "A22", "IOSTANDARD": "LVCMOS25" }, "LA33_P": { "PACKAGE_PIN": "B21", "IOSTANDARD": "LVCMOS25" }, "LA33_N": { "PACKAGE_PIN": "B22", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_P": { "PACKAGE_PIN": "L18", "IOSTANDARD": "LVCMOS25" }, "CLK0_M2C_N": { "PACKAGE_PIN": "L19", "IOSTANDARD": "LVCMOS25" }, "CLK1_M2C_P": { "PACKAGE_PIN": "D18", "IOSTANDARD": "LVCMOS25" }, "CLK1_M2C_N": { "PACKAGE_PIN": "C19", "IOSTANDARD": "LVCMOS25" }, "SDA": { "PACKAGE_PIN": "U7", "IOSTANDARD": "LVCMOS25" }, "SCL": { "PACKAGE_PIN": "R7", "IOSTANDARD": "LVCMOS25" } }, "pins": { "GPIO_sw_left": { "PACKAGE_PIN": "N15", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_center": { "PACKAGE_PIN": "P16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_right": { "PACKAGE_PIN": "R18", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_down": { "PACKAGE_PIN": "R16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_up": { "PACKAGE_PIN": "T18", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" } }, "pmoda" : { "J1" : { "PACKAGE_PIN" : "Y11", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "AA11", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "Y10", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "AA9", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "AB11", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "AB10", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "AB9", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "AA8", "IOSTANDARD" : "LVCMOS33" } }, "pmodb" : { "J1" : { "PACKAGE_PIN" : "W12", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "W11", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "V10", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "W8", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "V12", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "W10", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "V9", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "V8", "IOSTANDARD" : "LVCMOS33" } }, "pmodc" : { "J1" : { "PACKAGE_PIN" : "AB7", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "AB6", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "Y4", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "AA4", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "R6", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "T6", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "T4", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "U4", "IOSTANDARD" : "LVCMOS33" } }, "pmodd" : { "J1" : { "PACKAGE_PIN" : "V7", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "PACKAGE_PIN" : "W7", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "PACKAGE_PIN" : "V5", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "PACKAGE_PIN" : "V4", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "PACKAGE_PIN" : "W6", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "PACKAGE_PIN" : "W5", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "PACKAGE_PIN" : "U6", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "PACKAGE_PIN" : "U5", "IOSTANDARD" : "LVCMOS33" } }, "pmode_documentation_only;cannot use from PL" : { "MIO13" : { "PACKAGE_PIN" : "A6", "CONNECTORPIN" : "JE1" }, "MIO10" : { "PACKAGE_PIN" : "G7", "CONNECTORPIN" : "JE2" }, "MIO11" : { "PACKAGE_PIN" : "B4", "CONNECTORPIN" : "JE3" }, "MIO12" : { "PACKAGE_PIN" : "C5", "CONNECTORPIN" : "JE4" }, "MIO0" : { "PACKAGE_PIN" : "G6", "CONNECTORPIN" : "JE7" }, "MIO9" : { "PACKAGE_PIN" : "C4", "CONNECTORPIN" : "JE8" }, "MIO14" : { "PACKAGE_PIN" : "B6", "CONNECTORPIN" : "JE9" }, "MIO15" : { "PACKAGE_PIN" : "E6", "CONNECTORPIN" : "JE10" } }, "leds" : { "L0" : { "PACKAGE_PIN" : "T22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L1" : { "PACKAGE_PIN" : "T21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L2" : { "PACKAGE_PIN" : "U22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L3" : { "PACKAGE_PIN" : "U21", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L4" : { "PACKAGE_PIN" : "V22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L5" : { "PACKAGE_PIN" : "W22", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L6" : { "PACKAGE_PIN" : "U19", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" }, "L7" : { "PACKAGE_PIN" : "U14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION" : "OUTPUT" } }, "i2c0" : { "scl" : { "PACKAGE_PIN" : "AA18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "BIDIR" }, "sda" : { "PACKAGE_PIN" : "Y16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "BIDIR" } }, "hdmi" : { "clock" : { "PACKAGE_PIN" : "W18", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "hsync" : { "PACKAGE_PIN" : "V17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "vsync" : { "PACKAGE_PIN" : "W17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "de" : { "PACKAGE_PIN" : "U16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[0]" : { "PACKAGE_PIN" : "Y13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[1]" : { "PACKAGE_PIN" : "AA13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[2]" : { "PACKAGE_PIN" : "AA14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[3]" : { "PACKAGE_PIN" : "Y14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[4]" : { "PACKAGE_PIN" : "AB15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[5]" : { "PACKAGE_PIN" : "AB16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[6]" : { "PACKAGE_PIN" : "AA16", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[7]" : { "PACKAGE_PIN" : "AB17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[8]" : { "PACKAGE_PIN" : "AA17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[9]" : { "PACKAGE_PIN" : "Y15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[10]" : { "PACKAGE_PIN" : "W13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[11]" : { "PACKAGE_PIN" : "W15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[12]" : { "PACKAGE_PIN" : "V15", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[13]" : { "PACKAGE_PIN" : "U17", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[14]" : { "PACKAGE_PIN" : "V14", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" }, "data[15]" : { "PACKAGE_PIN" : "V13", "IOSTANDARD" : "LVCMOS25", "PIO_DIRECTION": "OUTPUT" } } } ================================================ FILE: boardinfo/zybo.json ================================================ { "options": { "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=32", "NUMBER_OF_LEDS=4", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2"], "os" : "android", "partname" : "xc7z010clg400-1", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/xc7z010clg400.xdc", "constraints/xilinx/zybo.xdc"], "TOP" : "ZynqTop", "runscript" : "run.android", "CONNECTALFLAGS" : ["--mainclockperiod=10", "--derivedclockperiod=5"], "need_pcie" : "unused" }, "pins": { "GPIO_sw_left": { "PACKAGE_PIN": "R18", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_center": { "PACKAGE_PIN": "P16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_right": { "PACKAGE_PIN": "V16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_down": { "PACKAGE_PIN": "Y16", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" }, "GPIO_sw_up": { "PACKAGE_PIN": "T18", "IOSTANDARD": "LVCMOS18", "slew": "SLOW", "PIO_DIRECTION": "INPUT" } }, "pmoda" : { "J1" : { "LOC" : "N15", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "LOC" : "L14", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "LOC" : "K16", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "LOC" : "K14", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "LOC" : "N16", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "LOC" : "L15", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "LOC" : "J16", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "LOC" : "J14", "IOSTANDARD" : "LVCMOS33" } }, "pmodb" : { "J1" : { "LOC" : "T20", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "LOC" : "U20", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "LOC" : "V20", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "LOC" : "W20", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "LOC" : "Y18", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "LOC" : "Y19", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "LOC" : "W18", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "LOC" : "W19", "IOSTANDARD" : "LVCMOS33" } }, "pmodc" : { "J1" : { "LOC" : "V15", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "LOC" : "W15", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "LOC" : "T11", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "LOC" : "T10", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "LOC" : "W14", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "LOC" : "Y14", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "LOC" : "T12", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "LOC" : "U12", "IOSTANDARD" : "LVCMOS33" } }, "pmodd" : { "J1" : { "LOC" : "T14", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "LOC" : "T15", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "LOC" : "P14", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "LOC" : "R14", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "LOC" : "U14", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "LOC" : "U15", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "LOC" : "V17", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "LOC" : "V18", "IOSTANDARD" : "LVCMOS33" } }, "pmode" : { "J1" : { "LOC" : "V12", "IOSTANDARD" : "LVCMOS33" }, "J2" : { "LOC" : "W16", "IOSTANDARD" : "LVCMOS33" }, "J3" : { "LOC" : "J15", "IOSTANDARD" : "LVCMOS33" }, "J4" : { "LOC" : "H15", "IOSTANDARD" : "LVCMOS33" }, "J7" : { "LOC" : "V13", "IOSTANDARD" : "LVCMOS33" }, "J8" : { "LOC" : "U17", "IOSTANDARD" : "LVCMOS33" }, "J9" : { "LOC" : "T17", "IOSTANDARD" : "LVCMOS33" }, "J10" : { "LOC" : "Y17", "IOSTANDARD" : "LVCMOS33" } }, "pmodf_mio_documentation" : { "J1" : { "LOC" : "E8", "MIO" : "MIO13" }, "J2" : { "LOC" : "E9", "MIO" : "MIO10" }, "J3" : { "LOC" : "C6", "MIO" : "MIO11" }, "J4" : { "LOC" : "D9", "MIO" : "MIO12" }, "J7" : { "LOC" : "E6", "MIO" : "MIO0" }, "J8" : { "LOC" : "B5", "MIO" : "MIO9" }, "J9" : { "LOC" : "C5", "MIO" : "MIO14" }, "J10" : { "LOC" : "C8", "MIO" : "MIO15" } } } ================================================ FILE: boardinfo/zynq100.json ================================================ { "options": { "os" : "android", "partname" : "xc7z100ffg900-2", "rewireclockstring" : "tclzynqrewireclock", "constraints": [], "implconstraints": ["constraints/xilinx/xc7z045ffg900.xdc", "constraints/xilinx/zynq100.xdc", "CONNECTAL_BITS_DEPENDENCES=hw/mkTop.bit", "CONNECTAL_RUN_SCRIPT=$(CONNECTALDIR)/scripts/run.android", "CONNECTAL_EXENAME=android.exe", "CONNECTAL_EXENAME2=android.exe2"], "TOP" : "ZynqTop", "runscript" : "run.android", "bsvdefines" : ["XILINX=1", "ZYNQ", "ZynqHostInterface", "PhysAddrWidth=40"], "CONNECTALFLAGS" : [], "need_pcie" : "unused" }, "fmc": { } } ================================================ FILE: bsv/Adapter.bsv ================================================ // Copyright (c) 2012 MIT // Copyright (c) 2012 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut ::*; import FIFOF ::*; import SpecialFIFOs ::*; import StmtFSM ::*; import Assert ::*; import Pipe ::*; function Bit#(a) rtruncate(Bit#(b) x) provisos(Add#(k,a,b)); match {.v,.*} = split(x); return v; endfunction interface AdapterToBus#(numeric type n, type a); interface PipeIn#(a) in; interface PipeOut#(Bit#(n)) out; endinterface interface AdapterFromBus#(numeric type n, type a); interface PipeIn#(Bit#(n)) in; interface PipeOut#(a) out; endinterface module mkAdapterToBus(AdapterToBus#(n,a)) provisos(Bits#(a,asz), Add#(1, z, asz), Div#(asz,n,nwords), Mul#(n,nwords,aszn), Add#(n,a__,aszn), Add#(asz,paddingsz,aszn)); Bit#(TLog#(nwords)) max = fromInteger(valueOf(nwords) - 1); Bit#(paddingsz) padding = 0; Reg#(Bool) notEmptyReg <- mkReg(False); Reg#(Bit#(aszn)) bits <- mkReg(0); Reg#(Bit#(TLog#(nwords))) count <- mkReg(0); Reg#(Bit#(TAdd#(TLog#(asz),1))) shift <- mkReg(0); interface PipeIn in; method Action enq(a val) if (!notEmptyReg); bits <= {padding,pack(val)}; notEmptyReg <= True; endmethod method notFull = !notEmptyReg; endinterface interface PipeOut out; method Bit#(n) first() if (notEmptyReg); return rtruncate(bits); endmethod method Action deq() if (notEmptyReg); if (count == max) begin count <= 0; notEmptyReg <= False; end else begin count <= count + 1; shift <= shift + fromInteger(valueOf(n)); bits <= (bits << valueOf(n)); end endmethod method notEmpty = notEmptyReg; endinterface endmodule module mkAdapterFromBus(AdapterFromBus#(n,a)) provisos(Bits#(a,asz), Add#(1,z,asz), Div#(asz,n,nwords), Mul#(n,nwords,aszn), Add#(n,a__,aszn), Add#(asz,paddingsz,aszn)); Bit#(TLog#(nwords)) max = fromInteger(valueOf(nwords)-1); Reg#(Bit#(aszn)) fbnbuff <- mkReg(0); Reg#(Bit#(TLog#(nwords))) count <- mkReg(0); FIFOF#(Bit#(asz)) fifo <- mkFIFOF1; interface PipeIn in; method Action enq(Bit#(n) x) if (count < max || fifo.notFull); Bit#(aszn) newbuff = truncate({fbnbuff,x}); fbnbuff <= newbuff; if (count == max) begin count <= 0; fifo.enq(truncate(newbuff)); end else begin count <= count+1; end endmethod method notFull = fifo.notFull; endinterface interface PipeOut out; method first = unpack(fifo.first); method deq = fifo.deq; method notEmpty = fifo.notEmpty; endinterface endmodule interface AdapterIndication; method Action done(); endinterface interface AdapterTb; method Action start(); endinterface module mkAdapterTb#(AdapterIndication indication)(AdapterTb); AdapterToBus#(32,Bit#(72)) tb32_72 <- mkAdapterToBus(); AdapterToBus#(32,Bit#(17)) tb32_17 <- mkAdapterToBus(); AdapterFromBus#(32,Bit#(72)) fb32_72 <- mkAdapterFromBus(); AdapterFromBus#(32,Bit#(17)) fb32_17 <- mkAdapterFromBus(); Reg#(Bit#(10)) timer <- mkReg(0); rule timeout; timer <= timer+1; dynamicAssert(timer < 128, "Timeout"); endrule let fsm <- mkFSM( seq // test to bit-32 tb32_72.in.enq(72'h090807060504030201); dynamicAssert(tb32_72.out.notEmpty, "Adapter not empty"); dynamicAssert(!tb32_72.in.notFull, "Adapter full"); $display("tb32_72 notEmpty %d notFull %d", tb32_72.out.notEmpty, tb32_72.in.notFull); $display("tb32_72 word 0 %h", tb32_72.out.first()); dynamicAssert(tb32_72.out.first == 32'h00000009, "expecting 00000009"); tb32_72.out.deq; $display("tb32_72 word 1 %h", tb32_72.out.first()); dynamicAssert(tb32_72.out.first == 32'h08070605, "expecting 08070605"); tb32_72.out.deq; $display("tb32_72 word 2 %h", tb32_72.out.first()); dynamicAssert(tb32_72.out.first == 32'h04030201, "expecting 04030201"); tb32_72.out.deq; dynamicAssert(!tb32_72.out.notEmpty && tb32_72.in.notFull, "Adapter empty and not full"); $display("tb32_72 notEmpty %d notFull %d", tb32_72.out.notEmpty, tb32_72.in.notFull); dynamicAssert(!tb32_17.out.notEmpty, "tb32_17 empty"); dynamicAssert(tb32_17.in.notFull, "tb32_17 !full"); tb32_17.in.enq(17'h10203); dynamicAssert(tb32_17.out.notEmpty, "tb32_17 not empty"); dynamicAssert(!tb32_17.in.notFull, "tb32_17 full"); $display("tb32_17.out.first %h", tb32_17.out.first); dynamicAssert(tb32_17.out.first == (32'h00010203), "Expected 00010203"); tb32_17.out.deq; dynamicAssert(!tb32_17.out.notEmpty, "tb32_17 empty"); dynamicAssert(tb32_17.in.notFull, "tb32_17 !full"); //test from bit-32 dynamicAssert(!fb32_72.out.notEmpty, "Adapter empty"); dynamicAssert(fb32_72.in.notFull, "Adapter not full"); $display("fb32_72 notEmpty %d notFull %d", fb32_72.out.notEmpty, fb32_72.in.notFull); fb32_72.in.enq(32'h00000009); fb32_72.in.enq(32'h08070605); fb32_72.in.enq(32'h04030201); $display("fb32_72.out.first %h", fb32_72.out.first); dynamicAssert(fb32_72.out.first == 72'h090807060504030201, "Expected 090807060504030201"); fb32_72.out.deq; fb32_72.in.enq(32'h09080706); dynamicAssert(!fb32_72.out.notEmpty, "Adapter not empty"); dynamicAssert(fb32_72.in.notFull, "Adapter not full"); fb32_72.in.enq(32'h05040302); fb32_72.in.enq(32'h01000000); dynamicAssert(fb32_72.out.notEmpty, "Adapter not empty"); dynamicAssert(!fb32_72.in.notFull, "Adapter full"); $display("fb32_72.out.first %h", fb32_72.out.first); dynamicAssert(fb32_72.out.first == 72'h060504030201000000, "Expected 060504030201000000"); fb32_72.out.deq; $display("fb32_72 notEmpty %d notFull %d", fb32_72.out.notEmpty, fb32_72.in.notFull); dynamicAssert(!fb32_72.out.notEmpty, "Adapter empty"); dynamicAssert(fb32_72.in.notFull, "Adapter not full"); fb32_17.in.enq(32'h10203); dynamicAssert(fb32_17.out.notEmpty, "Adapter not empty"); dynamicAssert(!fb32_17.in.notFull, "Adapter full"); $display("fb32_17.out.first %h", fb32_17.out.first); dynamicAssert(fb32_17.out.first == 17'h10203, "Expected 10203"); fb32_17.out.deq; dynamicAssert(!fb32_17.out.notEmpty, "Adapter empty"); dynamicAssert(fb32_17.in.notFull, "Adapter not full"); // they should be duals tb32_72.in.enq(72'h090807060504030201); fb32_72.in.enq(tb32_72.out.first); tb32_72.out.deq; fb32_72.in.enq(tb32_72.out.first); tb32_72.out.deq; fb32_72.in.enq(tb32_72.out.first); tb32_72.out.deq; dynamicAssert(fb32_72.out.first == 72'h090807060504030201, "Expected 090807060504030201"); fb32_72.out.deq; tb32_17.in.enq(17'h10203); fb32_17.in.enq(tb32_17.out.first); tb32_17.out.deq; dynamicAssert(fb32_17.out.first == 17'h10203, "Expected 10203"); fb32_17.out.deq; indication.done(); endseq ); method Action start(); fsm.start(); endmethod endmodule ================================================ FILE: bsv/AddressGenerator.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import FIFO::*; import GetPut::*; import Connectable::*; import RegFile::*; import ConnectalMemTypes::*; import ConnectalConfig::*; typedef struct { Bit#(addrWidth) addr; Bit#(BurstLenSize) bc; Bit#(MemTagSize) tag; Bool last; } AddrBeat#(numeric type addrWidth) deriving (Bits); interface AddressGenerator#(numeric type addrWidth, numeric type dataWidth); interface Put#(PhysMemRequest#(addrWidth,dataWidth)) request; interface Get#(AddrBeat#(addrWidth)) addrBeat; endinterface module mkAddressGenerator(AddressGenerator#(addrWidth, dataWidth)) provisos (Div#(dataWidth,8,dataWidthBytes), Log#(dataWidthBytes,beatShift)); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) requestFifo <- mkFIFOF1(); FIFOF#(AddrBeat#(addrWidth)) addrBeatFifo <- mkFIFOF(); Reg#(Bit#(addrWidth)) addrReg <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstCountReg <- mkReg(0); Reg#(Bool) isFirstReg <- mkReg(True); Reg#(Bool) isLastReg <- mkReg(False); rule addrBeatRule; let req = requestFifo.first(); let addr = addrReg; let burstCount = burstCountReg; let isLast = isLastReg; if (isFirstReg) begin addr = req.addr; burstCount = req.burstLen >> valueOf(beatShift); isLast = (req.burstLen == fromInteger(valueOf(dataWidthBytes))); //$display("addr=%h, burstCount=%h, isLast=%h", addr, burstCount, isLast); end let nextIsLast = burstCount == 2; let nextBurstCount = burstCount - 1; addrReg <= addr + fromInteger(valueOf(dataWidthBytes)); burstCountReg <= nextBurstCount; isLastReg <= nextIsLast; Bool nextIsFirst = False; if (isLast) begin requestFifo.deq(); nextIsFirst = True; end isFirstReg <= nextIsFirst; //$display("addr=%h, burstCount=%h, isLast=%h", addr, burstCount, isLast); addrBeatFifo.enq(AddrBeat { addr: addr, bc: burstCount, last: isLast, tag: req.tag}); endrule interface Put request; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); requestFifo.enq(req); endmethod endinterface interface Get addrBeat; method ActionValue#(AddrBeat#(addrWidth)) get(); addrBeatFifo.deq(); return addrBeatFifo.first(); endmethod endinterface endmodule ================================================ FILE: bsv/AsicTop.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import Vector :: *; import GetPut::*; import Connectable::*; import Portal :: *; import Top :: *; import HostInterface :: *; import Pipe::*; import CnocPortal::*; import ConnectalMemTypes:: *; import ConnectalMMU:: *; import MemServer:: *; import MMURequest::*; import MMUIndication::*; import MemServerIndication::*; import MemServerRequest::*; import SimDma::*; import IfcNames::*; import BuildVector::*; import Top::*; `include "ConnectalProjectConfig.bsv" interface AsicTop; interface Vector#(TAdd#(2,NumberOfRequests), PortalMsgRequest) requests; interface Vector#(TAdd#(2,NumberOfIndications), PortalMsgIndication) indications; endinterface module mkAsicTop#(Clock derivedClock, Reset derivedReset)(AsicTop); Reg#(Bool) dumpstarted <- mkReg(False); rule startdump if (!dumpstarted); //$dumpfile("dump.vcd"); //$dumpvars; $display("AsicTop starting"); dumpstarted <= True; endrule XsimHost host <- mkXsimHost(derivedClock, derivedReset); let top <- mkCnocTop( `ifdef IMPORT_HOSTIF host `else `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary derivedClock, derivedReset `else // otherwise no params `endif `endif ); MMUIndicationOutput lMMUIndicationOutput <- mkMMUIndicationOutput; MMURequestInput lMMURequestInput <- mkMMURequestInput; MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationOutput.ifc); mkConnection(lMMURequestInput.pipes, lMMU.request); MemServerIndicationOutput lMemServerIndicationOutput <- mkMemServerIndicationOutput; MemServerRequestInput lMemServerRequestInput <- mkMemServerRequestInput; MemServer#(PhysAddrWidth,DataBusWidth,NumberOfMasters) lMemServer <- mkMemServer(top.readers, top.writers, cons(lMMU,nil), lMemServerIndicationOutput.ifc); mkConnection(lMemServerRequestInput.pipes, lMemServer.request); let lMMUIndicationOutputNoc <- mkPortalMsgIndication(extend(pack(PlatformIfcNames_MMUIndicationH2S)), lMMUIndicationOutput.portalIfc.indications, lMMUIndicationOutput.portalIfc.messageSize); let lMMURequestInputNoc <- mkPortalMsgRequest(extend(pack(PlatformIfcNames_MMURequestS2H)), lMMURequestInput.portalIfc.requests); let lMemServerIndicationOutputNoc <- mkPortalMsgIndication(extend(pack(PlatformIfcNames_MemServerIndicationH2S)), lMemServerIndicationOutput.portalIfc.indications, lMemServerIndicationOutput.portalIfc.messageSize); let lMemServerRequestInputNoc <- mkPortalMsgRequest(extend(pack(PlatformIfcNames_MemServerRequestS2H)), lMemServerRequestInput.portalIfc.requests); interface requests = append(top.requests, vec(lMMURequestInputNoc, lMemServerRequestInputNoc)); interface indications = append(top.indications, vec(lMMUIndicationOutputNoc, lMemServerIndicationOutputNoc)); // mapM_(mkAsicMemoryConnection, lMemServer.masters); endmodule ================================================ FILE: bsv/AvalonBits.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import Connectable::*; interface AvalonMMasterBits#(numeric type addrWidth, numeric type dataWidth); method Bit#(addrWidth) address(); method Bit#(4) burstcount(); method Bit#(4) byteenable(); method Bit#(1) read(); method Action readdata(Bit#(dataWidth) v); method Action readdatavalid(Bit#(1) v); method Action waitrequest(Bit#(1) v); method Bit#(1) write(); method Bit#(dataWidth) writedata(); endinterface interface AvalonMSlaveBits#(numeric type addrWidth, numeric type dataWidth); method Action address(Bit#(addrWidth) v); method Action burstcount(Bit#(4) v); method Action byteenable(Bit#(4) v); method Action read(Bit#(1) v); method Bit#(dataWidth) readdata(); method Bit#(1) readdatavalid(); method Bit#(1) waitrequest(); method Action write(Bit#(1) v); method Action writedata(Bit#(dataWidth) v); endinterface instance Connectable#(AvalonMMasterBits#(addrWidth, dataWidth), AvalonMSlaveBits#(addrWidth, dataWidth)); module mkConnection#(AvalonMMasterBits#(addrWidth, dataWidth) m, AvalonMSlaveBits#(addrWidth, dataWidth) s)(Empty); mkConnection(s.address, m.address); mkConnection(s.burstcount, m.burstcount); mkConnection(s.byteenable, m.byteenable); mkConnection(s.read, m.read); mkConnection(s.write, m.write); mkConnection(s.writedata, m.writedata); mkConnection(m.readdata, s.readdata); mkConnection(m.readdatavalid, s.readdatavalid); mkConnection(m.waitrequest, s.waitrequest); endmodule endinstance ================================================ FILE: bsv/AvalonDdr3Controller.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks ::*; import GetPut ::*; import ClientServer ::*; import ConnectalClocks ::*; import ALTERA_DDR3_WRAPPER::*; `include "ConnectalProjectConfig.bsv" typedef 25 Ddr3AddrWidth; typedef 512 Ddr3DataWidth; interface Ddr3Pins; (* prefix="" *) interface Ddr3 ddr3; method Action osc_50(Bit#(1) b3d, Bit#(1) b4a, Bit#(1) b4d, Bit#(1) b7a, Bit#(1) b7d, Bit#(1) b8a, Bit#(1) b8d); endinterface interface Ddr3; interface Avalonddr3Mem ddr3b; (* prefix="" *) interface Avalonddr3Oct rzq_4; interface Clock sysclk_deleteme_unused_clock; interface Reset sysrst_deleteme_unused_reset; endinterface (* synthesize *) module mkDdr3#(Clock clk50)(Ddr3); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Reset rst50 <- mkAsyncReset( 10, reset, clk50 ); AvalonDdr3 mc <- mkAvalonDdr3(clk50, reset, noReset); interface ddr3b = mc.mem; interface rzq_4 = mc.oct; interface sysclk_deleteme_unused_clock = clock; //fixme interface sysrst_deleteme_unused_reset = reset; //fixme endmodule ================================================ FILE: bsv/AvalonDma.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import ConnectalConfig::*; import FIFO::*; import GetPut::*; import Vector::*; import ClientServer::*; import ConnectalMemTypes::*; import ConnectalMemory::*; import AvalonMasterSlave::*; import AvalonBits::*; import AddressGenerator::*; import AvalonSplitter::*; import Connectable::*; module mkAvalonDmaMaster#(PhysMemMaster#(addrWidth,dataWidth) master)(AvalonMMaster#(addrWidth,dataWidth)); let verbose = True; Wire#(Bool) avalonWait <- mkDWire(False); Wire#(Bool) avalonRead <- mkDWire(False); Wire#(Bool) avalonWrite <- mkDWire(False); Wire#(Bit#(4)) burstcount <- mkDWire(0); Wire#(Bit#(4)) byteEnable <- mkDWire(0); Wire#(Bit#(dataWidth)) avalonReadData <- mkDWire(0); Wire#(Bool) avalonReadDataValid <- mkDWire(False); Wire#(Bit#(addrWidth)) avalonAddress <- mkDWire(0); Wire#(Bit#(dataWidth)) avalonWriteData <- mkDWire(0); Reg#(Bit#(addrWidth)) writeAddress <- mkReg(0); Reg#(Bit#(4)) writeBurstLen <- mkReg(0); Reg#(Bit#(4)) writeBurstCount <- mkReg(0); AddressGenerator#(addrWidth, dataWidth) readAddrGenerator <- mkAddressGenerator(); Reg#(Bit#(32)) cycles <- mkReg(0); rule count; cycles <= cycles + 1; endrule AvalonArbiter#(addrWidth, dataWidth) arbiter <- mkAvalonArbiter(); Vector#(2, FIFO#(AvalonMMRequest#(addrWidth, dataWidth))) req_fifo <- replicateM(mkFIFO); mapM(uncurry(mkConnection), zip(map(toGet, req_fifo), arbiter.in)); FIFO#(AvalonMMData#(dataWidth)) resp_fifo <- mkFIFO; rule deq_dispatcher; let req <- toGet(resp_fifo).get; $display("%d: dispatcher to avalon %h", cycles, req.readdata); endrule rule read_req; let req <- master.read_client.readReq.get; AvalonMMRequest#(addrWidth, dataWidth) readReq; readReq.address = req.addr; readReq.data = ?; readReq.write = False; readReq.burstcount = truncate(req.burstLen >> 2); readReq.sof = True; readReq.eof = True; req_fifo[0].enq(readReq); if (verbose) $display("%d read_address %h bc %d", cycles, req.addr, req.burstLen); endrule rule read_data if (avalonReadDataValid); master.read_client.readData.put(MemData{data: avalonReadData, tag: 0, last: True}); endrule rule write_req; let req <- master.write_client.writeReq.get(); writeAddress <= req.addr; writeBurstLen <= truncate(req.burstLen); writeBurstCount <= truncate(req.burstLen >> 2); if (verbose) $display("%d write_addr %h bc %d", cycles, req.addr, req.burstLen); endrule rule write_data; let data <- master.write_client.writeData.get(); AvalonMMRequest#(addrWidth, dataWidth) writeReq; writeReq.address = writeAddress; writeReq.data = data.data; writeReq.write = True; writeReq.burstcount = writeBurstLen; writeReq.sof = (writeBurstLen == writeBurstCount) ? True : False; writeReq.eof = (writeBurstCount == 0) ? True : False; writeBurstCount <= writeBurstCount - 1; req_fifo[1].enq(writeReq); if (verbose) $display("%d write_data %h write_address %h bc %d", cycles, data.data, writeAddress, writeBurstCount); endrule interface Get request = arbiter.toAvalon; interface Put response = toPut(resp_fifo); endmodule ================================================ FILE: bsv/AvalonGather.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import GetPut::*; import ClientServer::*; import AvalonBits::*; import AvalonMasterSlave::*; module mkAvalonMSlaveGather#(AvalonMSlaveBits#(addrWidth, dataWidth) slave) (AvalonMSlave#(addrWidth, dataWidth)); Wire#(Bit#(addrWidth)) address <- mkDWire(0); Wire#(Bit#(dataWidth)) readdata <- mkDWire(0); Wire#(Bit#(dataWidth)) writedata <- mkDWire(0); Wire#(Bit#(1)) read <- mkDWire(0); Wire#(Bit#(1)) write <- mkDWire(0); Wire#(Bit#(1)) readdatavalid <- mkDWire(0); Wire#(Bit#(4)) burstcount <- mkDWire(0); Wire#(Bit#(4)) byteenable <- mkDWire(0); Wire#(Bit#(1)) waitrequest <- mkDWire(0); FIFO#(AvalonMMRequest#(addrWidth, dataWidth)) req_fifo <- mkFIFO; let verbose = True; Reg#(Bit#(32)) cycles <- mkReg(0); rule count if (verbose); cycles <= cycles + 1; endrule rule handshake0; let req = req_fifo.first; address <= req.address; read <= pack(!req.write); write <= pack(req.write); writedata <= req.data; burstcount <= req.burstcount; if (slave.waitrequest() == 0) req_fifo.deq; endrule rule handshake1; slave.address(address); slave.read(read); slave.write(write); slave.writedata(writedata); slave.burstcount(burstcount); endrule interface Put request = toPut(req_fifo); interface Get response; method ActionValue#(AvalonMMData#(dataWidth)) get() if (slave.readdatavalid == 1); AvalonMMData#(dataWidth) d; d.readdata = slave.readdata(); return d; endmethod endinterface endmodule ================================================ FILE: bsv/AvalonMasterSlave.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; import Connectable::*; typedef struct { Bit#(addrWidth) address; Bit#(dataWidth) data; Bit#(4) burstcount; Bool write; Bool sof; Bool eof; } AvalonMMRequest#(numeric type addrWidth, numeric type dataWidth) deriving (Bits); typedef struct { Bit#(dataWidth) readdata; } AvalonMMData#(numeric type dataWidth) deriving (Bits); interface AvalonMMaster#(numeric type addrWidth, numeric type busWidth); interface Get#(AvalonMMRequest#(addrWidth, busWidth)) request; interface Put#(AvalonMMData#(busWidth)) response; endinterface interface AvalonMSlave#(numeric type addrWidth, numeric type busWidth); interface Put#(AvalonMMRequest#(addrWidth, busWidth)) request; interface Get#(AvalonMMData#(busWidth)) response; endinterface instance Connectable#(AvalonMMaster#(addrWidth, dataWidth), AvalonMSlave#(addrWidth, dataWidth)); module mkConnection#(AvalonMMaster#(addrWidth, dataWidth) m, AvalonMSlave#(addrWidth, dataWidth) s)(Empty); mkConnection(m.request, s.request); mkConnection(s.response, m.response); endmodule endinstance ================================================ FILE: bsv/AvalonSplitter.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import GetPut::*; import Vector::*; import AvalonMasterSlave::*; // AvalonMM interface is shared between read and write operations. // There is an arbiter to control which operation get access to the Avalon Bus interface AvalonArbiter#(numeric type addrWidth, numeric type dataWidth); interface Get#(AvalonMMRequest#(addrWidth, dataWidth)) toAvalon; interface Vector#(2, Put#(AvalonMMRequest#(addrWidth, dataWidth))) in; endinterface module mkAvalonArbiter(AvalonArbiter#(addrWidth, dataWidth)); FIFO#(AvalonMMRequest#(addrWidth, dataWidth)) req_out_fifo <- mkFIFO(); Vector#(2, FIFOF#(AvalonMMRequest#(addrWidth, dataWidth))) req_in_fifo <- replicateM(mkGFIFOF(False, True)); Reg#(Maybe#(Bit#(1))) routeFrom <- mkReg(tagged Invalid); (* fire_when_enabled *) rule arbitrate_outgoing_request; if (routeFrom matches tagged Valid .port) begin if (req_in_fifo[port].notEmpty()) begin AvalonMMRequest#(addrWidth, dataWidth) req <- toGet(req_in_fifo[port]).get; req_out_fifo.enq(req); if (req.eof) routeFrom <= tagged Invalid; end end else begin Bool sentOne = False; for (Integer port=0; port<2; port=port+1) begin if (!sentOne && req_in_fifo[port].notEmpty()) begin AvalonMMRequest#(addrWidth, dataWidth) req <- toGet(req_in_fifo[port]).get; sentOne = True; if (req.sof) begin req_out_fifo.enq(req); if (!req.eof) begin routeFrom <= tagged Valid fromInteger(port); end end end end end endrule: arbitrate_outgoing_request Vector#(2, Put#(AvalonMMRequest#(addrWidth, dataWidth))) intemp; for (Integer i=0; i<2; i=i+1) intemp[i] = toPut(req_in_fifo[i]); interface in = intemp; interface Get toAvalon = toGet(req_out_fifo); endmodule ================================================ FILE: bsv/AwsF1Top.bsv ================================================ // Copyright (c) 2017 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import Vector :: *; import GetPut::*; import Connectable::*; import Portal :: *; import Platform :: *; import Top :: *; import HostInterface :: *; import Pipe::*; import CnocPortal::*; import ConnectalMemTypes:: *; import ConnectalMMU:: *; import MemServer:: *; import MMURequest::*; import MMUIndication::*; import MemServerIndication::*; import MemServerRequest::*; import Platform :: *; import Vector :: *; import SimDma::*; import IfcNames::*; import BuildVector::*; import Axi4MasterSlave::*; import AxiBits::*; import AxiDma::*; import FIFOF::*; import ConnectalFIFO::*; import Clocks::*; `include "ConnectalProjectConfig.bsv" `ifdef PinTypeInclude import `PinTypeInclude::*; `endif `ifdef PinType typedef `PinType PinType; `else typedef Empty PinType; `endif (* always_enabled, always_ready *) interface AwsF1ClSh; method Bit#(1) flr_done(); method Bit#(32) status0(); method Bit#(32) status1(); method Bit#(32) id0(); method Bit#(32) id1(); method Bit#(16) status_vled(); endinterface (* always_enabled, always_ready *) interface AwsF1ShCl; (* prefix="" *) method Action flr_assert(Bit#(1) flr_assert); (* prefix="" *) method Action ctl0(Bit#(32) ctl0); (* prefix="" *) method Action ctl1(Bit#(32) ctl1); (* prefix="" *) method Action status_vdip(Bit#(16) status_vdip); (* prefix="" *) method Action pwr_state(Bit#(2) pwr_state); endinterface (* always_ready, always_enabled *) interface AwsF1Interrupt; (* prefix="" *) method Bit#(16) apppf_irq_req(); method Action apppf_irq_ack(Bit#(16) ack); endinterface module mkAwsF1Interrupt#(Platform platform)(AwsF1Interrupt); Vector#(NumberOfTiles, Reg#(Bool)) intrRegs <- replicateM(mkReg(False)); Vector#(NumberOfTiles, Reg#(Bool)) readyRegs <- replicateM(mkReg(True)); Vector#(NumberOfTiles, Wire#(Bool)) ackWires <- replicateM(mkDWire(False)); for (Integer i = 0; i < valueOf(NumberOfTiles); i = i + 1) begin rule intr_rule if (!intrRegs[i]); if (platform.interrupt[i] && readyRegs[i]) begin intrRegs[i] <= True; readyRegs[i] <= False; end endrule rule ack_rule if (intrRegs[i]); if (ackWires[i]) begin intrRegs[i] <= False; end endrule rule ready_rule if (!platform.interrupt[i]); readyRegs[i] <= True; endrule end method Bit#(16) apppf_irq_req(); Bit#(16) bits = 0; for (Integer i = 0; i < valueOf(NumberOfTiles); i = i + 1) bits[i] = pack(intrRegs[i]); return bits; endmethod method Action apppf_irq_ack(Bit#(16) ack); for (Integer i = 0; i < valueOf(NumberOfTiles); i = i + 1) ackWires[i] <= unpack(ack[i]); endmethod endmodule (* always_ready, always_enabled *) interface AwsF1Top; interface PinType pins; interface AwsF1ShCl sh_cl; interface AwsF1ClSh cl_sh; interface AwsF1Interrupt interrupt; //interface Axi4SlaveBits#(64,512,6,Empty) dmasink; interface Axi4SlaveLiteBits#(32,32) ocl; //interface Axi4SlaveLiteBits#(32,32) sda; //interface Axi4SlaveLiteBits#(32,32) bar1; interface Axi4MasterBits#(PhysAddrWidth,512,16,AwsF1Extra) pcim; endinterface module mkAxi4SlaveLiteBitsFromPhysMemSlave#(PhysMemSlave#(addrWidth,dataWidth) slave) (Axi4SlaveLiteBits#(axiaddrWidth,dataWidth)) provisos (Div#(dataWidth,8,burstLen),Add#(addrWidth,a__,axiaddrWidth)); let burstLen = fromInteger(valueOf(burstLen)); Wire#(Bit#(addrWidth)) araddrWire <- mkDWire(0); Wire#(Bit#(1)) arvalidWire <- mkDWire(0); Wire#(Bit#(1)) rreadyWire <- mkDWire(0); Wire#(Bit#(dataWidth)) rdataWire <- mkDWire(0); Wire#(Bit#(addrWidth)) awaddrWire <- mkDWire(0); Wire#(Bit#(1)) awvalidWire <- mkDWire(0); Wire#(Bit#(1)) wvalidWire <- mkDWire(0); Wire#(Bit#(dataWidth)) wdataWire <- mkDWire(0); Wire#(Bit#(1)) breadyWire <- mkDWire(0); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) arFifo <- mkCFFIFOF(); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) awFifo <- mkCFFIFOF(); FIFOF#(MemData#(dataWidth)) rdataFifo <- mkCFFIFOF(); FIFOF#(MemData#(dataWidth)) wdataFifo <- mkCFFIFOF(); FIFOF#(Bit#(MemTagSize)) brespFifo <- mkCFFIFOF(); rule ar_rule if (arvalidWire == 1 && arFifo.notFull()); let req = PhysMemRequest {addr: araddrWire, burstLen: burstLen, tag: 0 }; arFifo.enq(req); endrule rule ar_to_slave; let req <- toGet(arFifo).get(); slave.read_server.readReq.put(req); endrule rule aw_rule if (awvalidWire == 1 && awFifo.notFull()); let req = PhysMemRequest {addr: awaddrWire, burstLen: burstLen, tag: 0 }; awFifo.enq(req); endrule rule aw_to_slave; let req <- toGet(awFifo).get(); slave.write_server.writeReq.put(req); endrule rule r_rule if (rreadyWire == 1 && rdataFifo.notEmpty()); rdataFifo.deq(); endrule rule rdata_rule; rdataWire <= rdataFifo.first.data; endrule rule rdata_from_slave; let mdata <- slave.read_server.readData.get(); rdataFifo.enq(mdata); endrule rule wdata_rule if (wvalidWire == 1 && wdataFifo.notFull()); wdataFifo.enq(MemData { data: wdataWire, tag: 0, last: True }); endrule rule wdata_to_slave; let mdata <- toGet(wdataFifo).get(); slave.write_server.writeData.put(mdata); endrule rule b_rule if (breadyWire == 1 && brespFifo.notEmpty()); brespFifo.deq(); endrule rule bresp_from_slave; let done <- slave.write_server.writeDone.get(); brespFifo.enq(done); endrule method Action araddr(Bit#(axiaddrWidth) v); araddrWire <= truncate(v); endmethod method Bit#(1) arready(); return pack(arFifo.notFull()); endmethod method Action arvalid(Bit#(1) v); arvalidWire <= v; endmethod method Action awaddr(Bit#(axiaddrWidth) v); awaddrWire <= truncate(v); endmethod method Bit#(1) awready(); return pack(awFifo.notFull()); endmethod method Action awvalid(Bit#(1) v); awvalidWire <= v; endmethod method Action bready(Bit#(1) v); breadyWire <= v; endmethod method Bit#(2) bresp(); return 0; // brespFifo.first(); endmethod method Bit#(1) bvalid(); return pack(brespFifo.notEmpty()); endmethod method Bit#(dataWidth) rdata(); return rdataWire; endmethod method Action rready(Bit#(1) v); rreadyWire <= v; endmethod method Bit#(2) rresp(); return 0; endmethod method Bit#(1) rvalid(); return pack(rdataFifo.notEmpty); endmethod method Action wdata(Bit#(dataWidth) v); wdataWire <= v; endmethod method Bit#(1) wready(); return pack(wdataFifo.notFull()); endmethod method Action wvalid(Bit#(1) v); wvalidWire <= v; endmethod endmodule (* no_default_clock, no_default_reset, clock_prefix="", reset_prefix="" *) module mkAwsF1Top#(Clock clk_main_a0, Clock clk_extra_a1, Clock clk_extra_a2, Clock clk_extra_a3, Clock clk_extra_b0, Clock clk_extra_b1, Clock clk_extra_c0, Clock clk_extra_c1, Reset kernel_rst_n, Reset rst_main_n )(AwsF1Top); Clock defaultClock = clk_main_a0; Reset defaultReset = rst_main_n; `ifdef AWSF1_DERIVED_CLOCK Clock derivedClock = `AWSF1_DERIVED_CLOCK; Reset derivedReset <- mkAsyncReset(5, rst_main_n, derivedClock); `else Clock derivedClock = clk_main_a0; Reset derivedReset = rst_main_n; `endif XsimHost host <- mkXsimHost(derivedClock, derivedReset, defaultClock); let top <- mkConnectalTop( `ifdef IMPORT_HOSTIF host, `else `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary derivedClock, derivedReset, `else // otherwise no params `endif `endif clocked_by defaultClock, reset_by defaultReset ); let platform <- mkPlatform(vec(top), clocked_by defaultClock, reset_by defaultReset); Axi4SlaveLiteBits#(32,32) oclSlave <- mkAxi4SlaveLiteBitsFromPhysMemSlave(platform.slave, clocked_by defaultClock, reset_by defaultReset); Vector#(NumberOfMasters, Axi4Master#(PhysAddrWidth,DataBusWidth,MemTagSize)) axiMasters <- mapM(mkAxi4DmaMaster, platform.masters, clocked_by defaultClock, reset_by defaultReset); Axi4MasterBits#(PhysAddrWidth,512,16,AwsF1Extra) masterBits <- mkAxi4MasterBits(axiMasters[0], clocked_by defaultClock, reset_by defaultReset); let awsF1Interrupt <- mkAwsF1Interrupt(platform, clocked_by defaultClock, reset_by defaultReset); interface AwsF1ClSh cl_sh; method id0 = 32'hF000_1D0F; // 32'hc100_1be7; method id1 = 32'h1D51_FEDD; // 32'hc101_1be7; endinterface interface ocl = oclSlave; interface pcim = masterBits; interface interrupt = awsF1Interrupt; `ifdef PinType interface pins = top.pins; `endif endmodule ================================================ FILE: bsv/Axi4MasterSlave.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import FIFO::*; import GetPut::*; import Connectable::*; import RegFile::*; import ConnectalMemTypes::*; // null_get, null_put typedef struct { Bit#(addrWidth) address; Bit#(8) len; Bit#(3) size; // assume matches bus width of Axi4Master Bit#(2) burst; // drive with 2'b01 Bit#(3) prot; // drive with 3'b000 Bit#(4) cache; // drive with 4'b0011 Bit#(idWidth) id; Bit#(2) lock; Bit#(4) qos; } Axi4ReadRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits); function Bit#(3) axiBusSize(busWidthType busWidth) provisos (Eq#(busWidthType),Literal#(busWidthType)); if (busWidth == 16) return 3'b001; else if (busWidth == 32) return 3'b010; else if (busWidth == 64) return 3'b011; else if (busWidth == 128) return 3'b100; else if (busWidth == 256) return 3'b101; else if (busWidth == 512) return 3'b110; else if (busWidth == 1024) return 3'b111; else return 3'b000; endfunction function Bit#(3) axiBusSizeBytes(busWidthType busWidth) provisos (Eq#(busWidthType),Literal#(busWidthType),Arith#(busWidthType)); return axiBusSize(8*busWidth); endfunction typedef struct { Bit#(busWidth) data; Bit#(2) resp; Bit#(1) last; Bit#(idWidth) id; } Axi4ReadResponse#(numeric type busWidth, numeric type idWidth) deriving (Bits); typedef struct { Bit#(addrWidth) address; Bit#(8) len; Bit#(3) size; // assume matches bus width of Axi4Master Bit#(2) burst; // drive with 2'b01 Bit#(3) prot; // drive with 3'b000 Bit#(4) cache; // drive with 4'b0011 Bit#(idWidth) id; Bit#(2) lock; Bit#(4) qos; } Axi4WriteRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits); typedef struct { Bit#(busWidth) data; Bit#(TDiv#(busWidth,8)) byteEnable; Bit#(1) last; Bit#(idWidth) id; } Axi4WriteData#(numeric type busWidth, numeric type idWidth) deriving (Bits); typedef struct { Bit#(2) resp; Bit#(idWidth) id; } Axi4WriteResponse#(numeric type idWidth) deriving (Bits); interface Axi4Master#(numeric type addrWidth, numeric type busWidth, numeric type idWidth); interface Get#(Axi4ReadRequest#(addrWidth, idWidth)) req_ar; interface Put#(Axi4ReadResponse#(busWidth, idWidth)) resp_read; interface Get#(Axi4WriteRequest#(addrWidth, idWidth)) req_aw; interface Get#(Axi4WriteData#(busWidth, idWidth)) resp_write; interface Put#(Axi4WriteResponse#(idWidth)) resp_b; endinterface interface Axi4Slave#(numeric type addrWidth, numeric type busWidth, numeric type idWidth); interface Put#(Axi4ReadRequest#(addrWidth, idWidth)) req_ar; interface Get#(Axi4ReadResponse#(busWidth, idWidth)) resp_read; interface Put#(Axi4WriteRequest#(addrWidth, idWidth)) req_aw; interface Put#(Axi4WriteData#(busWidth, idWidth)) resp_write; interface Get#(Axi4WriteResponse#(idWidth)) resp_b; endinterface function Axi4Master#(addrWidth, busWidth, idWidth) null_axi_master(); return (interface Axi4Master; interface Get req_ar = null_get; interface Put resp_read = null_put; interface Get req_aw = null_get; interface Get resp_write = null_get; interface Put resp_b = null_put; endinterface); endfunction instance Connectable#(Axi4Master#(addrWidth, busWidth,idWidth), Axi4Slave#(addrWidth, busWidth,idWidth)); module mkConnection#(Axi4Master#(addrWidth, busWidth,idWidth) m, Axi4Slave#(addrWidth, busWidth,idWidth) s)(Empty); mkConnection(m.req_ar, s.req_ar); mkConnection(s.resp_read, m.resp_read); mkConnection(m.req_aw, s.req_aw); mkConnection(m.resp_write, s.resp_write); mkConnection(s.resp_b, m.resp_b); endmodule endinstance function Axi4ReadRequest#(axiAddrWidth,idWidth) toAxi4ReadRequest(PhysMemRequest#(addrWidth,dataBusWidth) req) provisos (Add#(axiAddrWidth,a__,addrWidth) ,Add#(b__, idWidth, MemTagSize)); Axi4ReadRequest#(axiAddrWidth,idWidth) axireq = unpack(0); axireq.address = truncate(req.addr); axireq.id = truncate(req.tag); let dataWidthBytes = valueOf(TDiv#(dataBusWidth,8)); let dataSizeMask = dataWidthBytes-1; let size = req.burstLen & fromInteger(dataSizeMask); let beats = (req.burstLen + fromInteger(dataWidthBytes-1)) / fromInteger(dataWidthBytes); axireq.len = truncate(beats-1); //axireq.size = (beats == 1) ? axiBusSizeBytes(size) : axiBusSizeBytes(dataWidthBytes); axireq.size = axiBusSizeBytes(dataWidthBytes); axireq.burst = 2'b01; axireq.cache = 4'b1111; return axireq; endfunction function Axi4WriteRequest#(axiAddrWidth,idWidth) toAxi4WriteRequest(PhysMemRequest#(addrWidth,dataBusWidth) req) provisos (Add#(axiAddrWidth,a__,addrWidth) ,Add#(b__, idWidth, MemTagSize)); Axi4WriteRequest#(axiAddrWidth,idWidth) axireq = unpack(0); axireq.address = truncate(req.addr); axireq.id = truncate(req.tag); let dataWidthBytes = valueOf(TDiv#(dataBusWidth,8)); let dataSizeMask = dataWidthBytes-1; let size = req.burstLen & fromInteger(dataSizeMask); let beats = (req.burstLen + fromInteger(dataWidthBytes-1)) / fromInteger(dataWidthBytes); axireq.len = truncate(beats-1); //axireq.size = (beats == 1) ? axiBusSizeBytes(size) : axiBusSizeBytes(dataWidthBytes); axireq.size = axiBusSizeBytes(dataWidthBytes); axireq.burst = 2'b01; axireq.cache = 4'b1111; return axireq; endfunction instance MkPhysMemSlave#(Axi4Slave#(axiAddrWidth,dataWidth,idWidth),addrWidth,dataWidth) provisos (Add#(axiAddrWidth,a__,addrWidth),Add#(b__, idWidth, MemTagSize)); module mkPhysMemSlave#(Axi4Slave#(axiAddrWidth,dataWidth,idWidth) axiSlave)(PhysMemSlave#(addrWidth,dataWidth)); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) arfifo <- mkFIFOF(); FIFOF#(MemData#(dataWidth)) rfifo <- mkFIFOF(); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) awfifo <- mkFIFOF(); FIFOF#(MemData#(dataWidth)) wfifo <- mkFIFOF(); FIFOF#(Bit#(MemTagSize)) bfifo <- mkFIFOF(); FIFOF#(Bit#(MemTagSize)) rtagfifo <- mkFIFOF(); FIFOF#(Bit#(MemTagSize)) wtagfifo <- mkFIFOF(); rule rl_arfifo; let req <- toGet(arfifo).get(); Axi4ReadRequest#(axiAddrWidth,idWidth) axireq = toAxi4ReadRequest(req); axiSlave.req_ar.put(axireq); endrule rule rl_rdata; let rdata <- axiSlave.resp_read.get(); rfifo.enq(MemData { data: rdata.data, tag: extend(rdata.id) } ); endrule rule rl_awfifo; let req <- toGet(awfifo).get(); Axi4WriteRequest#(axiAddrWidth,idWidth) axireq = toAxi4WriteRequest(req); axiSlave.req_aw.put(axireq); endrule rule rl_wdata; let md <- toGet(wfifo).get(); //FIXME byteEnable axiSlave.resp_write.put(Axi4WriteData {data: md.data, byteEnable:maxBound, last:pack(md.last), id:truncate(md.tag)}); endrule rule rl_done; let b <- axiSlave.resp_b.get(); bfifo.enq(extend(b.id)); endrule interface PhysMemReadServer read_server; interface Put readReq = toPut(arfifo); interface Get readData = toGet(rfifo); endinterface interface PhysMemWriteServer write_server; interface Put writeReq = toPut(awfifo); interface Put writeData = toPut(wfifo); interface Get writeDone = toGet(bfifo); endinterface endmodule endinstance ================================================ FILE: bsv/AxiBits.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Vector::*; import Clocks::*; import FIFOF::*; import ConnectalFIFO::*; import GetPut::*; import Probe::*; import ConnectalMemTypes::*; import ConnectalEHR::*; import Axi4MasterSlave::*; import Connectable::*; import ConnectalBramFifo::*; interface AxiMasterBits#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType); method Bit#(addrWidth) araddr(); method Bit#(2) arburst(); method Bit#(4) arcache(); method Bit#(1) aresetn(); method Bit#(tagWidth) arid(); method Bit#(4) arlen(); method Bit#(2) arlock(); method Bit#(3) arprot(); method Bit#(4) arqos(); method Action arready(Bit#(1) v); method Bit#(2) arsize(); method Bit#(1) arvalid(); method Bit#(addrWidth) awaddr(); method Bit#(2) awburst(); method Bit#(4) awcache(); method Bit#(tagWidth) awid(); method Bit#(4) awlen(); method Bit#(2) awlock(); method Bit#(3) awprot(); method Bit#(4) awqos(); method Action awready(Bit#(1) v); method Bit#(2) awsize(); method Bit#(1) awvalid(); method Action bid(Bit#(tagWidth) v); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(dataWidth) v); method Action rid(Bit#(tagWidth) v); method Action rlast(Bit#(1) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action rvalid(Bit#(1) v); method Bit#(dataWidth) wdata(); method Bit#(tagWidth) wid(); method Bit#(1) wlast(); method Action wready(Bit#(1) v); method Bit#(TDiv#(dataWidth,8)) wstrb(); method Bit#(1) wvalid(); interface extraType extra; endinterface interface HPType; method Bit#(3) racount(); method Bit#(8) rcount(); method Action rdissuecap1en(Bit#(1) v); method Bit#(6) wacount(); method Bit#(8) wcount(); method Action wrissuecap1en(Bit#(1) v); endinterface interface ACPType; method Action aruser(Bit#(5) v); method Action awuser(Bit#(5) v); endinterface interface AxiSlaveBits#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType); method Action araddr(Bit#(addrWidth) v); method Action arburst(Bit#(2) v); method Action arcache(Bit#(4) v); method Bit#(1) aresetn(); method Action arid(Bit#(tagWidth) v); method Action arlen(Bit#(4) v); method Action arlock(Bit#(2) v); method Action arprot(Bit#(3) v); method Action arqos(Bit#(4) v); method Bit#(1) arready(); method Action arsize(Bit#(2) v); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(addrWidth) v); method Action awburst(Bit#(2) v); method Action awcache(Bit#(4) v); method Action awid(Bit#(tagWidth) v); method Action awlen(Bit#(4) v); method Action awlock(Bit#(2) v); method Action awprot(Bit#(3) v); method Action awqos(Bit#(4) v); method Bit#(1) awready(); method Action awsize(Bit#(2) v); method Action awvalid(Bit#(1) v); method Bit#(tagWidth) bid(); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(dataWidth) rdata(); method Bit#(1) rlast(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(dataWidth) v); method Action wid(Bit#(tagWidth) v); method Action wlast(Bit#(1) v); method Bit#(1) wready(); method Action wstrb(Bit#(TDiv#(dataWidth,8)) v); method Action wvalid(Bit#(1) v); method Bit#(tagWidth) rid(); interface extraType extra; endinterface interface Axi4MasterBits#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType); method Bit#(addrWidth) araddr(); method Bit#(2) arburst(); method Bit#(4) arcache(); method Bit#(1) aresetn(); method Bit#(tagWidth) arid(); method Bit#(8) arlen(); method Bit#(2) arlock(); method Bit#(3) arprot(); method Bit#(4) arqos(); method Action arready(Bit#(1) v); method Bit#(3) arsize(); method Bit#(1) arvalid(); method Bit#(addrWidth) awaddr(); method Bit#(2) awburst(); method Bit#(4) awcache(); method Bit#(tagWidth) awid(); method Bit#(8) awlen(); method Bit#(2) awlock(); method Bit#(3) awprot(); method Bit#(4) awqos(); method Action awready(Bit#(1) v); method Bit#(3) awsize(); method Bit#(1) awvalid(); method Action bid(Bit#(tagWidth) v); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(dataWidth) v); method Action rid(Bit#(tagWidth) v); method Action rlast(Bit#(1) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action rvalid(Bit#(1) v); method Bit#(dataWidth) wdata(); method Bit#(tagWidth) wid(); method Bit#(1) wlast(); method Action wready(Bit#(1) v); method Bit#(TDiv#(dataWidth,8)) wstrb(); method Bit#(1) wvalid(); interface extraType extra; endinterface interface Axi4MasterUntaggedBits#(numeric type addrWidth, numeric type dataWidth); method Bit#(addrWidth) araddr(); method Bit#(2) arburst(); method Bit#(4) arcache(); method Bit#(8) arlen(); //method Bit#(2) arlock(); method Bit#(3) arprot(); //method Bit#(4) arqos(); method Action arready(Bit#(1) v); method Bit#(3) arsize(); method Bit#(1) arvalid(); method Bit#(addrWidth) awaddr(); method Bit#(2) awburst(); method Bit#(4) awcache(); method Bit#(8) awlen(); //method Bit#(2) awlock(); method Bit#(3) awprot(); //method Bit#(4) awqos(); method Action awready(Bit#(1) v); method Bit#(3) awsize(); method Bit#(1) awvalid(); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(dataWidth) v); method Action rlast(Bit#(1) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action rvalid(Bit#(1) v); method Bit#(dataWidth) wdata(); method Bit#(1) wlast(); method Action wready(Bit#(1) v); method Bit#(TDiv#(dataWidth,8)) wstrb(); method Bit#(1) wvalid(); endinterface typeclass ToAxi4MasterBits#(type atype, type btype); function atype toAxi4MasterBits(btype b); endtypeclass instance ToAxi4MasterBits#(Axi4MasterBits#(addrWidth,dataWidth,tagWidth,Empty), Axi4MasterUntaggedBits#(addrWidth,dataWidth)); function Axi4MasterBits#(addrWidth,dataWidth,tagWidth,Empty) toAxi4MasterBits(Axi4MasterUntaggedBits#(addrWidth,dataWidth) m); return (interface Axi4MasterBits#(addrWidth,dataWidth,tagWidth,Empty); method araddr = m.araddr; method arburst = m.arburst; method arcache = m.arcache; //method aresetn = no_reset; method Bit#(tagWidth) arid(); return 0; endmethod method arlen = m.arlen; //method arlock = m.arlock; method arprot = m.arprot; //method arqos = m.arqos; method arready = m.arready; method arsize = m.arsize; method arvalid = m.arvalid; method awaddr = m.awaddr; method awburst = m.awburst; method awcache = m.awcache; method Bit#(tagWidth) awid(); return 0; endmethod method awlen = m.awlen; //method awlock = m.awlock; method awprot = m.awprot; //method awqos = m.awqos; method awready = m.awready; method awsize = m.awsize; method awvalid = m.awvalid; method Action bid(Bit#(tagWidth) v); endmethod method bready = m.bready; method bresp = m.bresp; method bvalid = m.bvalid; method rdata = m.rdata; method Action rid(Bit#(tagWidth) v); endmethod method rlast = m.rlast; method rready = m.rready; method rresp = m.rresp; method rvalid = m.rvalid; method wdata = m.wdata; method Bit#(tagWidth) wid(); return 0; endmethod method wlast = m.wlast; method wready = m.wready; method wstrb = m.wstrb; method wvalid = m.wvalid; interface extra = ?; endinterface); endfunction endinstance (* always_ready, always_enabled *) interface AwsF1Extra; //10:0 Length in DW of the transaction //14:11 are the byte-enable for the first DW (bit value 1 mean byte is enable, i.e. not masked) //18:15 are the byte-enable for the last DW (bit value 1 mean byte is enable, i.e. not masked) method Bit#(19) awuser; // 10:0 Length in DW of the transaction // 18:11 Must be set to 0xFF, could be ignored in next release method Bit#(19) aruser; endinterface module mkAxi4MasterBits#(Axi4Master#(addrWidth,dataWidth,tagWidth) m)(Axi4MasterBits#(addrWidth,busDataWidth,busTagWidth,AwsF1Extra)) provisos (Add#(dataWidth,d__,busDataWidth), Div#(dataWidth,32,dataWidthWords), Add#(tagWidth,t__,busTagWidth), Add#(a__, TDiv#(dataWidth, 8), TDiv#(busDataWidth, 8))); let arfifo <- mkCFFIFOF(); let araddrWire <- mkDWire(0); let arburstWire <- mkDWire(0); let arcacheWire <- mkDWire(0); let aridWire <- mkDWire(0); let arreadyWire <- mkDWire(False); let arprotWire <- mkDWire(0); let arlenWire <- mkDWire(0); let arsizeWire <- mkDWire(0); let aruserWire <- mkDWire(0); let awfifo <- mkCFFIFOF(); let awaddrWire <- mkDWire(0); let awburstWire <- mkDWire(0); let awcacheWire <- mkDWire(0); let awidWire <- mkDWire(0); let awreadyWire <- mkDWire(False); let awprotWire <- mkDWire(0); let awlenWire <- mkDWire(0); let awsizeWire <- mkDWire(0); let awuserWire <- mkDWire(0); let rfifo <- mkCFFIFOF(); let rdataWire <- mkDWire(0); let rrespWire <- mkDWire(0); let rlastWire <- mkDWire(0); let ridWire <- mkDWire(0); let rvalidWire <- mkDWire(False); let wfifo <- mkCFFIFOF(); let wdataWire <- mkDWire(0); let widWire <- mkDWire(0); let wstrbWire <- mkDWire(0); let wlastWire <- mkDWire(0); let wreadyWire <- mkDWire(False); let bfifo <- mkCFFIFOF(); let bidWire <- mkDWire(0); let brespWire <- mkDWire(0); let bvalidWire <- mkDWire(False); rule arfifo_enq; let req <- m.req_ar.get(); arfifo.enq(req); endrule rule arwire_rule; araddrWire <= arfifo.first.address; arlenWire <= arfifo.first.len; Bit#(11) dwlen = extend(arfifo.first.len) / fromInteger(valueOf(dataWidthWords)); Bit#(8) mustbeone = 8'hf; aruserWire <= { mustbeone, dwlen }; arsizeWire <= arfifo.first.size; arburstWire <= 2'b01; //arfifo.first.burst; arprotWire <= 3'b000; //arfifo.first.prot; arcacheWire <= 4'b0011; // arfifo.first.cache; aridWire <= arfifo.first.id; endrule rule ar_handshake if (arreadyWire); arfifo.deq(); endrule rule awfifo_enq; let req <- m.req_aw.get(); awfifo.enq(req); endrule rule awwire_rule; awaddrWire <= awfifo.first.address; let lenbytes = awfifo.first.len; awlenWire <= lenbytes; Bit#(11) dwlen = extend(lenbytes) / fromInteger(valueOf(dataWidthWords)); Bit#(4) firstBE = 4'hf; Bit#(4) lastBE = (lenbytes > 4) ? 4'hf : 0; awuserWire <= { lastBE, firstBE, dwlen }; awsizeWire <= awfifo.first.size; awburstWire <= 2'b01; //awfifo.first.burst; awprotWire <= 3'b000; //awfifo.first.prot; awcacheWire <= 4'b0011; // awfifo.first.cache; awidWire <= awfifo.first.id; endrule rule aw_handshake if (awreadyWire); awfifo.deq(); endrule rule rdata_put; let data <- toGet(rfifo).get(); m.resp_read.put(data); endrule rule r_handshake if (rvalidWire); rfifo.enq(Axi4ReadResponse {data: truncate(rdataWire), resp: rrespWire, last: rlastWire, id: ridWire }); endrule rule wdata_get; let data <- m.resp_write.get(); wfifo.enq(data); endrule rule w_handshake if (wreadyWire); let data <- toGet(wfifo).get(); wdataWire <= extend(data.data); wlastWire <= pack(data.last); wstrbWire <= data.byteEnable; widWire <= data.id; endrule rule bresp_put; let resp <- toGet(bfifo).get(); m.resp_b.put(resp); endrule rule b_handshake if (bvalidWire); bfifo.enq(Axi4WriteResponse {resp: brespWire, id: bidWire }); endrule interface AwsF1Extra extra; method aruser = aruserWire; method awuser = awuserWire; endinterface method araddr = araddrWire; method arburst = arburstWire; method arcache = arcacheWire; method aresetn = 1; method arid = extend(aridWire); method arlen = arlenWire; // method Bit#(2) arlock(); method arprot = arprotWire; // method Bit#(4) arqos(); method Action arready(Bit#(1) v); arreadyWire <= unpack(v); endmethod method arsize = arsizeWire; method arvalid = pack(arfifo.notEmpty); method awaddr = awaddrWire; method awburst = awburstWire; method awcache = awcacheWire; method awid = extend(awidWire); method awlen = awlenWire; //method awlock = awlockWire; method awprot = awprotWire; // method Bit#(4) awqos(); method Action awready(Bit#(1) v); awreadyWire <= unpack(v); endmethod method awsize = awsizeWire; method awvalid = pack(awfifo.notEmpty); method Action bid(Bit#(busTagWidth) v); bidWire <= truncate(v); endmethod method bready = pack(bfifo.notFull()); method Action bresp(Bit#(2) v); brespWire <= v; endmethod method Action bvalid(Bit#(1) v); bvalidWire <= unpack(v); endmethod method Action rdata(Bit#(busDataWidth) v); rdataWire <= v; endmethod method Action rid(Bit#(busTagWidth) v); ridWire <= truncate(v); endmethod method Action rlast(Bit#(1) v); rlastWire <= unpack(v); endmethod method rready = pack(rfifo.notFull()); method Action rresp(Bit#(2) v); rrespWire <= v; endmethod method Action rvalid(Bit#(1) v); rvalidWire <= unpack(v); endmethod method wdata = wdataWire; method wid = extend(widWire); method wlast = wlastWire; method Action wready(Bit#(1) v); wreadyWire <= unpack(v); endmethod method wstrb = extend(wstrbWire); method wvalid = pack(wfifo.notEmpty); endmodule interface Axi4SlaveBits#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType); method Action araddr(Bit#(addrWidth) v); method Action arburst(Bit#(2) v); method Action arcache(Bit#(4) v); method Bit#(1) aresetn(); method Action arid(Bit#(tagWidth) v); method Action arlen(Bit#(8) v); method Action arlock(Bit#(2) v); method Action arprot(Bit#(3) v); method Action arqos(Bit#(4) v); method Bit#(1) arready(); method Action arsize(Bit#(3) v); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(addrWidth) v); method Action awburst(Bit#(2) v); method Action awcache(Bit#(4) v); method Action awid(Bit#(tagWidth) v); method Action awlen(Bit#(8) v); method Action awlock(Bit#(2) v); method Action awprot(Bit#(3) v); method Action awqos(Bit#(4) v); method Bit#(1) awready(); method Action awsize(Bit#(3) v); method Action awvalid(Bit#(1) v); method Bit#(tagWidth) bid(); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(dataWidth) rdata(); method Bit#(1) rlast(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(dataWidth) v); method Action wid(Bit#(tagWidth) v); method Action wlast(Bit#(1) v); method Bit#(1) wready(); method Action wstrb(Bit#(TDiv#(dataWidth,8)) v); method Action wvalid(Bit#(1) v); method Bit#(tagWidth) rid(); interface extraType extra; endinterface interface Axi4SlaveLiteBits#(numeric type addrWidth, numeric type dataWidth); method Action araddr(Bit#(addrWidth) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(addrWidth) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(dataWidth) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(dataWidth) v); method Bit#(1) wready(); method Action wvalid(Bit#(1) v); endinterface typeclass ToAxi4SlaveBits#(type atype, type btype); function atype toAxi4SlaveBits(btype b); endtypeclass module mkAxiFifoF(FIFOF#(t)) provisos(Bits#(t, tSz)); Ehr#(2, t) da <- mkEhr(?); Ehr#(2, Bool) va <- mkEhr(False); Ehr#(2, t) db <- mkEhr(?); Ehr#(2, Bool) vb <- mkEhr(False); rule canon if(vb[1] && !va[1]); da[1] <= db[1]; va[1] <= True; vb[1] <= False; endrule method Bool notFull = !vb[0]; // technically, canEnqueue method Action enq(t x) if(!vb[0]); db[0] <= x; vb[0] <= True; endmethod method Bool notEmpty = va[0]; // technically, canDequeue method Action deq if (va[0]); va[0] <= False; endmethod method t first if (va[0]); return da[0]; endmethod // conflicts with enq, deq, but we do not call it method Action clear; vb[0] <= False; va[0] <= False; endmethod endmodule typedef 40 MpsocMAxiAddrWidth; // MAXI:40bit SAXI:49bit typedef 128 MpsocAxiDataWidth; typedef 16 MpsocMAxiIdWidth; // MAXI:16bit SAXI: 6bit typedef 32 PhysMemDataWidth; typedef 32 PhysMemAddrWidth; instance MkPhysMemMaster#(Axi4MasterBits#(MpsocMAxiAddrWidth,MpsocAxiDataWidth,MpsocMAxiIdWidth,extra),PhysMemAddrWidth,PhysMemDataWidth) provisos (Add#(PhysMemAddrWidth,a__,MpsocMAxiAddrWidth), Add#(c__, 6, MpsocMAxiIdWidth) ); module mkPhysMemMaster#(Axi4MasterBits#(MpsocMAxiAddrWidth,MpsocAxiDataWidth,MpsocMAxiIdWidth,extra) axiMaster)(PhysMemMaster#(PhysMemAddrWidth,PhysMemDataWidth)); FIFOF#(PhysMemRequest#(PhysMemAddrWidth,PhysMemDataWidth)) arfifo <- mkAxiFifoF(); FIFOF#(MemData#(PhysMemDataWidth)) rfifo <- mkAxiFifoF(); FIFOF#(PhysMemRequest#(PhysMemAddrWidth,PhysMemDataWidth)) awfifo <- mkAxiFifoF(); FIFOF#(MemData#(PhysMemDataWidth)) wfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) bfifo <- mkAxiFifoF(); FIFOF#(Bit#(MpsocMAxiIdWidth)) rtagfifo <- mkAxiFifoF(); FIFOF#(Tuple2#(Bit#(MpsocMAxiIdWidth),Bit#(2))) awtagfifo <- mkAxiFifoF(); FIFOF#(Bit#(MpsocMAxiIdWidth)) wtagfifo <- mkAxiFifoF(); let beatShift = fromInteger(valueOf(TLog#(TDiv#(PhysMemDataWidth,8)))); // req_ar (M=>S) let arreadyProbe <- mkProbe(); rule rl_arready; let arready = pack(arfifo.notFull && rtagfifo.notFull); arreadyProbe <= arready; axiMaster.arready(arready); endrule rule rl_arfifo if (axiMaster.arvalid() == 1); let addr = truncate(axiMaster.araddr()); let burstLen = extend(axiMaster.arlen+1) << beatShift; // calculate burstLen arfifo.enq(PhysMemRequest{ addr: addr, burstLen: burstLen, tag: 0 } ); // burstlen corrected rtagfifo.enq(axiMaster.arid()); // what if the single request with multiple transfer endrule // resp_read (S=>M) let rvalidProbe <- mkProbe(); rule rl_rvalid; let rvalid = pack(rfifo.notEmpty && rtagfifo.notEmpty); rvalidProbe <= rvalid; axiMaster.rvalid(rvalid); endrule rule rl_rdata if (axiMaster.rready() == 1); //let rtag <- toGet(rtagfifo).get(); let rtag = rtagfifo.first(); let rdata <- toGet(rfifo).get(); if (rdata.last) begin rtagfifo.deq(); // deq rtagfifo only if last beat end axiMaster.rresp(0); //okay Vector#(4,Bit#(32)) words = replicate(rdata.data); axiMaster.rdata(pack(words)); axiMaster.rid(extend(rtag)); axiMaster.rlast(rdata.last?1:0); // added endrule // req_aw (M=>S) let awreadyProbe <- mkProbe(); rule rl_awvalid_awaddr; let awready = pack(awfifo.notFull && awtagfifo.notFull); awreadyProbe <= awready; axiMaster.awready(awready); endrule rule rl_awfifo if (axiMaster.awvalid() == 1); Bit#(PhysMemAddrWidth) addr = truncate(axiMaster.awaddr()); let burstLen = extend(axiMaster.awlen+1) << beatShift; // calculate burstLen let tag = axiMaster.awid(); awfifo.enq(PhysMemRequest{ addr: addr, tag: truncate(tag), burstLen: burstLen }); // burstlen corrected awtagfifo.enq(tuple2(tag, addr[3:2])); // what if the single request with multiple transfer?? endrule // resp_wr (M=>S) sending data let wreadyProbe <- mkProbe(); rule rl_wready; let wready = pack(wfifo.notFull && awtagfifo.notEmpty && wtagfifo.notFull); wreadyProbe <= wready; axiMaster.wready(wready); endrule rule rl_wdata if (axiMaster.wvalid() == 1); let last = axiMaster.wlast == 1; match { .tag, .lane } = awtagfifo.first; Vector#(4, Bit#(PhysMemDataWidth)) words = unpack(axiMaster.wdata()); wfifo.enq(MemData { data: words[lane], tag: truncate(tag), last: last}); if (last) begin awtagfifo.deq(); wtagfifo.enq(tag); end endrule // resp_b (S=>M) let bvalidProbe <- mkProbe(); rule rl_bvalid; let bvalid = pack(wtagfifo.notEmpty && bfifo.notEmpty); bvalidProbe <= bvalid; axiMaster.bvalid(bvalid); endrule rule rl_done if (axiMaster.bready() == 1); let tag <- toGet(bfifo).get(); let awtag <- toGet(wtagfifo).get(); axiMaster.bid(awtag); axiMaster.bresp(0); //okay // where is b_resp? endrule interface PhysMemReadClient read_client; interface Get readReq = toGet(arfifo); interface Put readData = toPut(rfifo); endinterface interface PhysMemWriteClient write_client; interface Get writeReq = toGet(awfifo); interface Get writeData = toGet(wfifo); interface Put writeDone = toPut(bfifo); endinterface endmodule endinstance: MkPhysMemMaster instance MkPhysMemSlave#(Axi4SlaveLiteBits#(axiAddrWidth,dataWidth),addrWidth,dataWidth) provisos (Add#(axiAddrWidth,a__,addrWidth)); module mkPhysMemSlave#(Axi4SlaveLiteBits#(axiAddrWidth,dataWidth) axiSlave)(PhysMemSlave#(addrWidth,dataWidth)); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) arfifo <- mkAxiFifoF(); FIFOF#(MemData#(dataWidth)) rfifo <- mkAxiFifoF(); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) awfifo <- mkAxiFifoF(); FIFOF#(MemData#(dataWidth)) wfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) bfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) rtagfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) wtagfifo <- mkAxiFifoF(); rule rl_arvalid_araddr; axiSlave.arvalid(pack(arfifo.notEmpty && rtagfifo.notFull)); let addr = 0; if (arfifo.notEmpty) addr = truncate(arfifo.first.addr); axiSlave.araddr(addr); endrule rule rl_arfifo if (axiSlave.arready() == 1); let req <- toGet(arfifo).get(); rtagfifo.enq(req.tag); endrule rule rl_rready; axiSlave.rready(pack(rfifo.notFull && rtagfifo.notEmpty)); endrule rule rl_rdata if (axiSlave.rvalid() == 1); let rtag <- toGet(rtagfifo).get(); rfifo.enq(MemData { data: axiSlave.rdata(), tag: rtag } ); endrule rule rl_awvalid_awaddr; axiSlave.awvalid(pack(awfifo.notEmpty && wtagfifo.notFull)); let addr = 0; if (awfifo.notEmpty) addr = truncate(awfifo.first.addr); axiSlave.awaddr(addr); endrule rule rl_awfifo if (axiSlave.awready() == 1); let req <- toGet(awfifo).get(); wtagfifo.enq(req.tag); endrule rule rl_wvalid; axiSlave.wvalid(pack(wfifo.notEmpty)); endrule rule rl_wdata if (axiSlave.wready() == 1); let wdata = wfifo.first.data; wfifo.deq(); axiSlave.wdata(wdata); endrule rule rl_bready; axiSlave.bready(pack(wtagfifo.notEmpty && bfifo.notFull)); endrule rule rl_done if (axiSlave.bvalid() == 1); let tag <- toGet(wtagfifo).get(); bfifo.enq(tag); endrule interface PhysMemReadServer read_server; interface Put readReq = toPut(arfifo); interface Get readData = toGet(rfifo); endinterface interface PhysMemWriteServer write_server; interface Put writeReq = toPut(awfifo); interface Put writeData = toPut(wfifo); interface Get writeDone = toGet(bfifo); endinterface endmodule endinstance `ifdef BLUECHECK import BlueCheck::*; import StmtFSM::*; module [BlueCheck] mkPhysMemSlaveSpec(); /* This function allows us to make assertions in the properties */ Ensure ensure <- getEnsure; Ensure ensure1 <- getEnsure; Bit#(BurstLenSize) bytesPerBeat = 16; let dataSizeMask = bytesPerBeat-1; function Stmt checkLen(Bit#(8) burstLen8) = seq action Bit#(BurstLenSize) burstLen = extend(burstLen8); PhysMemRequest#(16,128) pmr = PhysMemRequest { addr: 0, burstLen: burstLen }; Axi4ReadRequest#(16,6) amr = toAxi4ReadRequest(pmr); Bit#(8) expectedValue = truncate((burstLen + dataSizeMask) / bytesPerBeat - 1); //$display("burstLen=%d arm.len=%x bytesPerBeat=%x dataSizeMask=%x expectedValue=%x", burstLen, amr.len, bytesPerBeat, dataSizeMask, expectedValue); ensure(extend(amr.len) == expectedValue); ensure1 ((burstLen == 0) || ((extend(amr.len)+1) * bytesPerBeat >= burstLen)); endaction endseq; function Stmt checkSize(Bit#(8) burstLen8) = seq action Bit#(BurstLenSize) burstLen = extend(burstLen8); PhysMemRequest#(16,128) pmr = PhysMemRequest { addr: 0, burstLen: burstLen }; Axi4ReadRequest#(16,6) amr = toAxi4ReadRequest(pmr); Bit#(3) expectedValue = axiBusSizeBytes(16); //$display("burstLen=%d amr.size=%x expectedValue=%x", burstLen, amr.size, expectedValue); ensure((burstLen == 0) || (extend(amr.size) == expectedValue)); endaction endseq; prop("checkLen", checkLen); prop("checkSize", checkSize); endmodule module [Module] mkMkPhysMemSlaveChecker(); blueCheck(mkPhysMemSlaveSpec); endmodule `endif `ifdef FOOBAR //FIXME burst transfers instance MkPhysMemSlave#(Axi4SlaveBits#(axiAddrWidth,dataWidth,tagWidth,Empty),addrWidth,dataWidth) provisos (Add#(axiAddrWidth,a__,addrWidth), Add#(b__, tagWidth, 6)); module mkPhysMemSlave#(Axi4SlaveBits#(axiAddrWidth,dataWidth,tagWidth,Empty) axiSlave)(PhysMemSlave#(addrWidth,dataWidth)); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) arfifo <- mkAxiFifoF(); FIFOF#(MemData#(dataWidth)) rfifo <- mkAxiFifoF(); FIFOF#(PhysMemRequest#(addrWidth,dataWidth)) awfifo <- mkAxiFifoF(); FIFOF#(MemData#(dataWidth)) wfifo <- mkAxiFifoF(); FIFOF#(Bit#(TDiv#(dataWidth,8))) wstrbfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) bfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) rtagfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) wtagfifo <- mkAxiFifoF(); let dataWidthBytes = valueOf(TDiv#(dataWidth,8)); let dataSizeMask = dataWidthBytes-1; rule rl_arvalid; axiSlave.arvalid(pack(arfifo.notEmpty && rtagfifo.notFull)); endrule rule rl_araddr if (arfifo.notEmpty); let req = arfifo.first; Axi4ReadRequest#(axiAddrWidth,tagWidth) axireq = toAxi4ReadRequest(req); axiSlave.araddr(axireq.address); axiSlave.arid(axireq.id); axiSlave.arlen(axireq.len); axiSlave.arsize(axireq.size); axiSlave.arburst(2'b01); axiSlave.arprot(3'b000); axiSlave.arcache(4'b1111); // was 4'b0011 endrule rule rl_arfifo if (axiSlave.arready() == 1); let req <- toGet(arfifo).get(); rtagfifo.enq(req.tag); endrule rule rl_rready; axiSlave.rready(pack(rfifo.notFull && rtagfifo.notEmpty)); endrule rule rl_rdata if (axiSlave.rvalid() == 1); let rtag <- toGet(rtagfifo).get(); rfifo.enq(MemData { data: axiSlave.rdata(), tag: rtag } ); endrule rule rl_awvalid; axiSlave.awvalid(pack(awfifo.notEmpty && wtagfifo.notFull)); endrule rule rl_awaddr if (awfifo.notEmpty); let req = awfifo.first; let dataWidthBytes = valueOf(TDiv#(dataWidth,8)); let dataSizeMask = dataWidthBytes-1; let reqsize = req.burstLen & fromInteger(dataSizeMask); Axi4WriteRequest#(axiAddrWidth,tagWidth) axireq = toAxi4WriteRequest(req); axiSlave.awaddr(axireq.address); axiSlave.awid(axireq.id); axiSlave.awlen(axireq.len); axiSlave.awsize(axireq.size); axiSlave.awburst(2'b01); axiSlave.awprot(3'b000); axiSlave.awcache(4'b0011); //FIXME should go in toAxi4WriteRequest Bit#(TDiv#(dataWidth,8)) wstrb = (1 << reqsize) - 1; wstrbfifo.enq(wstrb); endrule rule rl_awfifo if (axiSlave.awready() == 1); let req <- toGet(awfifo).get(); wtagfifo.enq(req.tag); endrule rule rl_wvalid; axiSlave.wvalid(pack(wfifo.notEmpty)); endrule rule rl_wdata if (axiSlave.wready() == 1); let md <- toGet(wfifo).get(); let wdata = md.data; axiSlave.wdata(wdata); axiSlave.wlast(pack(wfifo.first.last)); axiSlave.wstrb(wstrbfifo.first); if (wfifo.first.last) wstrbfifo.deq(); endrule rule rl_bready; axiSlave.bready(pack(wtagfifo.notEmpty && bfifo.notFull)); endrule rule rl_done if (axiSlave.bvalid() == 1); let tag <- toGet(wtagfifo).get(); bfifo.enq(extend(axiSlave.bid())); endrule interface PhysMemReadServer read_server; interface Put readReq = toPut(arfifo); interface Get readData = toGet(rfifo); endinterface interface PhysMemWriteServer write_server; interface Put writeReq = toPut(awfifo); interface Put writeData = toPut(wfifo); interface Get writeDone = toGet(bfifo); endinterface endmodule endinstance `endif // FOOBAR typeclass PhysMemSlaveExtra#(type extraType); function Action extra_r(extraType ex); function Action extra_w(extraType ex); endtypeclass instance MkPhysMemSlave#(Axi4SlaveBits#(axiAddrWidth,128,idWidth,extraType),addrWidth,dataBusWidth) provisos (Add#(addrWidth,a__,axiAddrWidth) , Add#(b__, idWidth, MemTagSize) , Add#(dw__, dataBusWidth, 128) , PhysMemSlaveExtra#(extraType)); module mkPhysMemSlave#(Axi4SlaveBits#(axiAddrWidth,128,idWidth,extraType) axiSlave)(PhysMemSlave#(addrWidth,dataBusWidth)); FIFOF#(PhysMemRequest#(addrWidth,dataBusWidth)) arfifo <- mkAxiFifoF(); FIFOF#(MemData#(dataBusWidth)) rfifo <- mkAxiFifoF(); FIFOF#(PhysMemRequest#(addrWidth,dataBusWidth)) awfifo <- mkAxiFifoF(); FIFOF#(MemData#(dataBusWidth)) wfifo <- mkAxiFifoF(); FIFOF#(Bit#(MemTagSize)) bfifo <- mkAxiFifoF(); FIFOF#(Bool) arInFlight <- mkSizedFIFOF(valueOf(TExp#(MemTagSize))); FIFOF#(Bool) awInFlight <- mkSizedFIFOF(valueOf(TExp#(MemTagSize))); Probe#(Bit#(1)) arNF <- mkProbe(); Probe#(Bit#(1)) arNE <- mkProbe(); Probe#(Bit#(1)) rNF <- mkProbe(); Probe#(Bit#(1)) rNE <- mkProbe(); Probe#(Bit#(1)) awNF <- mkProbe(); Probe#(Bit#(1)) awNE <- mkProbe(); Probe#(Bit#(1)) wNF <- mkProbe(); Probe#(Bit#(1)) wNE <- mkProbe(); Probe#(Bit#(1)) bNF <- mkProbe(); Probe#(Bit#(1)) bNE <- mkProbe(); Probe#(Bit#(1)) arInFlightNF <- mkProbe(); Probe#(Bit#(1)) arInFlightNE <- mkProbe(); Probe#(Bit#(1)) awInFlightNF <- mkProbe(); Probe#(Bit#(1)) awInFlightNE <- mkProbe(); rule probe_val; arNF <= pack(arfifo.notFull()); arNE <= pack(arfifo.notEmpty()); rNF <= pack(rfifo.notFull()); rNE <= pack(rfifo.notEmpty()); awNF <= pack(awfifo.notFull()); awNE <= pack(awfifo.notEmpty()); wNF <= pack(wfifo.notFull()); wNE <= pack(wfifo.notEmpty()); bNF <= pack(bfifo.notFull()); bNE <= pack(bfifo.notEmpty()); arInFlightNF <= pack(arInFlight.notFull()); arInFlightNE <= pack(arInFlight.notEmpty()); awInFlightNF <= pack(awInFlight.notFull()); awInFlightNE <= pack(awInFlight.notEmpty()); endrule rule rl_arvalid_araddr; axiSlave.arvalid(pack(arfifo.notEmpty && arInFlight.notFull)); endrule rule rl_arfifo if (axiSlave.arready() == 1); let req <- toGet(arfifo).get(); Axi4ReadRequest#(addrWidth,idWidth) axireq = toAxi4ReadRequest(req); axiSlave.araddr(extend(axireq.address)); axiSlave.arid(axireq.id); axiSlave.arsize(axireq.size); axiSlave.arlen(axireq.len); axiSlave.arburst(2'b01); // burst: INCR axiSlave.arcache(4'b0011); // FIXME: 0011? 1111? axiSlave.arlock(2'b0); // normal access axiSlave.arprot(3'b0); // unprevileged, protected, data access axiSlave.arqos(4'b0); // unused - default 0 extra_r(axiSlave.extra); // unused arInFlight.enq(True); endrule rule rl_rready; axiSlave.rready(pack(rfifo.notFull && arInFlight.notEmpty)); endrule rule rl_rdata if (axiSlave.rvalid() == 1); let dummy = arInFlight.first; // implicit guard (arInFlight should not be empty to fire this rule) let last = axiSlave.rlast == 1; if (last) arInFlight.deq; rfifo.enq(MemData { data: truncate(axiSlave.rdata()), tag: extend(axiSlave.rid()), last: last } ); endrule rule rl_awvalid_awaddr; axiSlave.awvalid(pack(awfifo.notEmpty && awInFlight.notFull)); endrule rule rl_awfifo if (axiSlave.awready() == 1); let req <- toGet(awfifo).get(); Axi4WriteRequest#(addrWidth,idWidth) axireq = toAxi4WriteRequest(req); axiSlave.awaddr(extend(axireq.address)); axiSlave.awid(axireq.id); axiSlave.awsize(axireq.size); axiSlave.awlen(axireq.len); axiSlave.awburst(2'b01); // burst: INCR axiSlave.awcache(4'b0011); // FIXME: 0011? 1111? axiSlave.awlock(2'b0); // normal access axiSlave.awprot(3'b0); // unprevileged, protedted, data access axiSlave.awqos(4'b0); // unused - default 0 extra_w(axiSlave.extra); awInFlight.enq(True); endrule rule rl_wvalid; axiSlave.wvalid(pack(wfifo.notEmpty)); endrule rule rl_wdata if (axiSlave.wready() == 1); let wdata = wfifo.first.data; let last = wfifo.first.last; wfifo.deq(); axiSlave.wdata(extend(wdata)); axiSlave.wlast(pack(last)); axiSlave.wstrb(16'hFFFF); // using full 128-bit // wid deprecated; the master must issue the data in the same order in which it issued the write address (aw_req) endrule rule rl_bready; axiSlave.bready(pack(awInFlight.notEmpty && bfifo.notFull)); endrule rule rl_done if (axiSlave.bvalid() == 1); let tag <- toGet(awInFlight).get(); bfifo.enq(extend(axiSlave.bid())); endrule interface PhysMemReadServer read_server; interface Put readReq = toPut(arfifo); interface Get readData = toGet(rfifo); endinterface interface PhysMemWriteServer write_server; interface Put writeReq = toPut(awfifo); interface Put writeData = toPut(wfifo); interface Get writeDone = toGet(bfifo); endinterface endmodule endinstance typeclass AxiToMemReadClient#(type objIdType, numeric type axiAddrWidth, numeric type dataWidth); module mkMemReadClient#(objIdType objId, Axi4MasterBits#(axiAddrWidth,dataWidth,MemTagSize,Empty) m)(MemReadClient#(dataWidth)); module mkMemWriteClient#(objIdType objId, Axi4MasterBits#(axiAddrWidth,dataWidth,MemTagSize,Empty) m)(MemWriteClient#(dataWidth)); endtypeclass typeclass AxiToPhysMemReadClient#(numeric type axiAddrWidth, numeric type dataWidth, numeric type idWidth, type extra); module mkPhysMemReadClient#(Axi4MasterBits#(axiAddrWidth,dataWidth,idWidth,extra) m)(PhysMemReadClient#(axiAddrWidth,dataWidth)); module mkPhysMemWriteClient#(Axi4MasterBits#(axiAddrWidth,dataWidth,idWidth,extra) m)(PhysMemWriteClient#(axiAaddrWidth,dataWidth)); endtypeclass instance AxiToMemReadClient#(Bit#(32),32,dataWidth); module mkMemReadClient#(Bit#(32) objId, Axi4MasterBits#(32,dataWidth,MemTagSize,Empty) m)(MemReadClient#(dataWidth)); let clock <- exposeCurrentClock(); let mClock = clockOf(m); let reset <- exposeCurrentReset(); let mReset = resetOf(m); Wire#(Bit#(1)) arready <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) rvalid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(MemTagSize)) rid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(2)) rresp <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(dataWidth)) rdata <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) rlast <- mkDWire(0, clocked_by mClock, reset_by mReset); FIFOF#(MemRequest) arfifo; FIFOF#(MemData#(dataWidth)) rfifo; if ( isAncestor(clock, mClock)) begin arfifo <- mkCFFIFOF(); rfifo <- mkCFFIFOF(); end else begin arfifo <- mkDualClockBramFIFOF(mClock, mReset, clock, reset); rfifo <- mkDualClockBramFIFOF(clock, reset, mClock, mReset); end rule rl_araddr if (m.arvalid() == 1); let addr = m.araddr(); let burstLenBytes = (extend(m.arlen())+1)*fromInteger(valueOf(TDiv#(dataWidth,8))); arfifo.enq(MemRequest { sglId: objId, offset: extend(addr), burstLen: burstLenBytes, tag: extend(m.arid()) }); endrule rule handshake_ar; m.arready(pack(arfifo.notFull())); endrule rule rl_rdata if (m.rready() == 1); let md <- toGet(rfifo).get(); rdata <= md.data; rlast <= pack(md.last); rresp <= 0; rid <= truncate(md.tag); endrule rule handshake_rdata; m.rvalid(pack(rfifo.notEmpty())); m.rid(rid); m.rresp(rresp); m.rdata(rdata); m.rlast(rlast); endrule interface Get readReq = toGet(arfifo); interface Put readData = toPut(rfifo); endmodule module mkMemWriteClient#(Bit#(32) objId, Axi4MasterBits#(32,dataWidth,MemTagSize,Empty) m)(MemWriteClient#(dataWidth)); let clock <- exposeCurrentClock(); let mClock = clockOf(m); let reset <- exposeCurrentReset(); let mReset = resetOf(m); Wire#(Bit#(1)) awready <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) wready <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) bvalid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(MemTagSize)) bid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(2)) bresp <- mkDWire(0, clocked_by mClock, reset_by mReset); FIFOF#(MemRequest) awfifo; FIFOF#(MemData#(dataWidth)) wfifo; FIFOF#(Bit#(MemTagSize)) bfifo; if ( isAncestor(clock, mClock)) begin awfifo <- mkCFFIFOF(); wfifo <- mkCFFIFOF(); bfifo <- mkCFFIFOF(); end else begin awfifo <- mkDualClockBramFIFOF(mClock, mReset, clock, reset); wfifo <- mkDualClockBramFIFOF(mClock, mReset, clock, reset); bfifo <- mkDualClockBramFIFOF(clock, reset, mClock, mReset); end rule rl_awaddr if (m.awvalid() == 1); let addr = m.awaddr(); let burstLenBytes = (extend(m.awlen())+1)*fromInteger(valueOf(TDiv#(dataWidth,8))); awfifo.enq(MemRequest { sglId: objId, offset: extend(addr), burstLen: burstLenBytes, tag: extend(m.awid()) }); endrule rule handshake_awaddr; m.awready(pack(awfifo.notFull())); endrule rule rl_wdata if (m.wvalid() == 1); wfifo.enq(MemData { data: m.wdata(), last: unpack(m.wlast()), tag: extend(m.wid()) }); endrule rule handshake_wdata; m.wready(pack(wfifo.notFull())); endrule rule rl_bresp if (m.bready() == 1); let tag <- toGet(bfifo).get(); bresp <= 0; bid <= truncate(tag); endrule rule handshake_b; m.bvalid(pack(bfifo.notEmpty())); m.bid(bid); m.bresp(bresp); endrule interface Get writeReq = toGet(awfifo); interface Get writeData = toGet(wfifo); interface Put writeDone = toPut(bfifo); endmodule endinstance interface GetObjId#(numeric type addrWidth); method SGLId objId(Bit#(addrWidth) axiAddr); method Bit#(MemOffsetSize) addr(Bit#(addrWidth) axiAddr); endinterface instance AxiToMemReadClient#(GetObjId#(32),32,dataWidth); module mkMemReadClient#(GetObjId#(32) objId, Axi4MasterBits#(32,dataWidth,MemTagSize,Empty) m)(MemReadClient#(dataWidth)); let clock <- exposeCurrentClock(); let mClock = clockOf(m); let reset <- exposeCurrentReset(); let mReset = resetOf(m); Wire#(Bit#(1)) arready <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) rvalid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(MemTagSize)) rid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(2)) rresp <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(dataWidth)) rdata <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) rlast <- mkDWire(0, clocked_by mClock, reset_by mReset); FIFOF#(MemRequest) arfifo; FIFOF#(MemData#(dataWidth)) rfifo; if ( isAncestor(clock, mClock)) begin arfifo <- mkCFFIFOF(); rfifo <- mkCFFIFOF(); end else begin arfifo <- mkDualClockBramFIFOF(mClock, mReset, clock, reset); rfifo <- mkDualClockBramFIFOF(clock, reset, mClock, mReset); end rule rl_araddr if (m.arvalid() == 1); let addr = m.araddr(); let burstLenBytes = (extend(m.arlen())+1)*fromInteger(valueOf(TDiv#(dataWidth,8))); arfifo.enq(MemRequest { sglId: objId.objId(addr), offset: objId.addr(addr), burstLen: burstLenBytes, tag: extend(m.arid()) }); endrule rule handshake_ar; m.arready(pack(arfifo.notFull())); endrule rule rl_rdata if (m.rready() == 1); let md <- toGet(rfifo).get(); rdata <= md.data; rlast <= pack(md.last); rresp <= 0; rid <= truncate(md.tag); endrule rule handshake_rdata; m.rvalid(pack(rfifo.notEmpty())); m.rid(rid); m.rresp(rresp); m.rdata(rdata); m.rlast(rlast); endrule interface Get readReq = toGet(arfifo); interface Put readData = toPut(rfifo); endmodule module mkMemWriteClient#(GetObjId#(32) objId, Axi4MasterBits#(32,dataWidth,MemTagSize,Empty) m)(MemWriteClient#(dataWidth)); let clock <- exposeCurrentClock(); let mClock = clockOf(m); let reset <- exposeCurrentReset(); let mReset = resetOf(m); Wire#(Bit#(1)) awready <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) wready <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(1)) bvalid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(MemTagSize)) bid <- mkDWire(0, clocked_by mClock, reset_by mReset); Wire#(Bit#(2)) bresp <- mkDWire(0, clocked_by mClock, reset_by mReset); FIFOF#(MemRequest) awfifo; FIFOF#(MemData#(dataWidth)) wfifo; FIFOF#(Bit#(MemTagSize)) bfifo; if ( isAncestor(clock, mClock)) begin awfifo <- mkCFFIFOF(); wfifo <- mkCFFIFOF(); bfifo <- mkCFFIFOF(); end else begin awfifo <- mkDualClockBramFIFOF(mClock, mReset, clock, reset); wfifo <- mkDualClockBramFIFOF(mClock, mReset, clock, reset); bfifo <- mkDualClockBramFIFOF(clock, reset, mClock, mReset); end rule rl_awaddr if (m.awvalid() == 1); let addr = m.awaddr(); let burstLenBytes = (extend(m.awlen())+1)*fromInteger(valueOf(TDiv#(dataWidth,8))); awfifo.enq(MemRequest { sglId: objId.objId(addr), offset: objId.addr(addr), burstLen: burstLenBytes, tag: extend(m.awid()) }); endrule rule handshake_awaddr; m.awready(pack(awfifo.notFull())); endrule rule rl_wdata if (m.wvalid() == 1); wfifo.enq(MemData { data: m.wdata(), last: unpack(m.wlast()), tag: extend(m.wid()) }); endrule rule handshake_wdata; m.wready(pack(wfifo.notFull())); endrule rule rl_bresp if (m.bready() == 1); let tag <- toGet(bfifo).get(); bresp <= 0; bid <= truncate(tag); endrule rule handshake_b; m.bvalid(pack(bfifo.notEmpty())); m.bid(bid); m.bresp(bresp); endrule interface Get writeReq = toGet(awfifo); interface Get writeData = toGet(wfifo); interface Put writeDone = toPut(bfifo); endmodule endinstance typedef AxiMasterBits#(32,32,12,Empty) Pps7Maxigp; typedef AxiSlaveBits#(32,32,6,Empty) Pps7Saxigp; typedef AxiSlaveBits#(32,64,6,HPType) Pps7Saxihp; typedef AxiSlaveBits#(32,64,3,ACPType) Pps7Saxiacp; ================================================ FILE: bsv/AxiDdr3Controller.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks ::*; import GetPut ::*; import ClientServer ::*; import AxiDdr3Wrapper ::*; import AxiBits ::*; import AxiGather ::*; import Axi4MasterSlave ::*; import ConnectalClocks ::*; `include "ConnectalProjectConfig.bsv" typedef 30 Ddr3AddrWidth; typedef 512 Ddr3DataWidth; interface Ddr3Pins; interface AxiDdr3Ddr3 ddr3; interface Clock sysclk_deleteme_unused_clock; interface Reset sysrst_deleteme_unused_reset; endinterface interface Ddr3; interface Axi4Slave#(Ddr3AddrWidth,Ddr3DataWidth,6) slave; interface Ddr3Pins ddr3; // pins interface Clock uiClock; interface Reset uiReset; endinterface function Axi4SlaveBits#(Ddr3AddrWidth,Ddr3DataWidth,6,Empty) toAxiSlaveBits(AxiDdr3S_axi s_axi); return (interface Axi4SlaveBits; method araddr = s_axi.araddr; method arburst = s_axi.arburst; method arcache = s_axi.arcache; method Bit#(1) aresetn(); return 1; endmethod method arid = s_axi.arid; method arlen = s_axi.arlen; method Action arlock(Bit#(2) l); s_axi.arlock(truncate(l)); endmethod //unused method arprot = s_axi.arprot; method arqos = s_axi.arqos; method arready = s_axi.arready; method arsize = s_axi.arsize; method arvalid = s_axi.arvalid; method awaddr = s_axi.awaddr; method awburst = s_axi.awburst; method awcache = s_axi.awcache; method awid = s_axi.awid; method awlen = s_axi.awlen; method Action awlock(Bit#(2) l); s_axi.awlock(truncate(l)); endmethod //unused method awprot = s_axi.awprot; method awqos = s_axi.awqos; method awready = s_axi.awready; method awsize = s_axi.awsize; method awvalid = s_axi.awvalid; method bid = s_axi.bid; method bready = s_axi.bready; method bresp = s_axi.bresp; method bvalid = s_axi.bvalid; method rdata = s_axi.rdata; method rlast = s_axi.rlast; method rready = s_axi.rready; method rresp = s_axi.rresp; method rvalid = s_axi.rvalid; method wdata = s_axi.wdata; method Action wid(Bit#(6) tag); /* no wid method */ endmethod method wlast = s_axi.wlast; method wready = s_axi.wready; method wstrb = s_axi.wstrb; method wvalid = s_axi.wvalid; method rid = s_axi.rid; interface Empty extra; endinterface endinterface); endfunction (* synthesize *) module mkDdr3#(Clock clk200)(Ddr3); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Reset rst200 <- mkSyncReset( 10, reset, clk200 ); `ifndef BSV_POSITIVE_RESET let mcReset = rst200; `else // fixme later `endif //fixme mc.aresetn let aresetn <- mkB2R(clocked_by clk200, reset_by mcReset); AxiDdr3 mc <- mkAxiDdr3(clk200, mcReset, aresetn.r); let ui_reset_n <- mkResetInverter(mc.ui_clk_sync_rst, clocked_by mc.ui_clk); let ui_reset_b <- mkR2B(ui_reset_n); rule rl_aresetn; aresetn.inputreset(ui_reset_b.o); endrule let axiBits = toAxiSlaveBits(mc.s_axi); Axi4SlaveCommon#(Ddr3AddrWidth,Ddr3DataWidth,6,Empty) axiSlaveCommon <- mkAxi4SlaveGather(axiBits, clocked_by mc.ui_clk, reset_by ui_reset_n); rule misc_pins; mc.app.ref_req(0); mc.app.sr_req(0); mc.app.zq_req(0); endrule interface slave = axiSlaveCommon.server; interface Ddr3Pins ddr3; interface AxiDdr3Ddr3 ddr3 = mc.ddr3; interface Clock sysclk_deleteme_unused_clock = clock; //fixme interface Reset sysrst_deleteme_unused_reset = reset; //fixme endinterface interface Clock uiClock = mc.ui_clk; interface Reset uiReset = ui_reset_n; endmodule export Ddr3AddrWidth; export Ddr3DataWidth; export Ddr3Pins(..); export Ddr3(..); export AxiDdr3Ddr3(..); export mkDdr3; ================================================ FILE: bsv/AxiDma.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import ConnectalConfig::*; import FIFO::*; import GetPut::*; import ClientServer::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import ConnectalMemTypes::*; import ConnectalMemory::*; module mkAxiDmaSlave#(PhysMemSlave#(addrWidth,dataWidth) slave) (Axi3Slave#(addrWidth,dataWidth,axiIdSize)) provisos (Add#(MemTagSize, sz__, axiIdSize)); let beatShift = fromInteger(valueOf(TLog#(TDiv#(dataWidth,8)))); interface Put req_ar; method Action put((Axi3ReadRequest#(addrWidth, axiIdSize)) req); let burstLen = extend(req.len+1) << beatShift; slave.read_server.readReq.put(PhysMemRequest{addr:req.address, burstLen:burstLen, tag:truncate(req.id) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }); endmethod endinterface interface Get resp_read; method ActionValue#(Axi3ReadResponse#(dataWidth, axiIdSize)) get; let resp <- slave.read_server.readData.get; return Axi3ReadResponse{data:resp.data, resp:0, last:1, id:extend(resp.tag)}; endmethod endinterface interface Put req_aw; method Action put(Axi3WriteRequest#(addrWidth, axiIdSize) req); let burstLen = extend(req.len+1) << beatShift; slave.write_server.writeReq.put(PhysMemRequest{addr:req.address, burstLen:burstLen, tag:truncate(req.id) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }); endmethod endinterface interface Put resp_write; method Action put(Axi3WriteData#(dataWidth, axiIdSize) resp); slave.write_server.writeData.put(MemData{data:resp.data, tag:truncate(resp.id), last: resp.last == 1}); endmethod endinterface interface Get resp_b; method ActionValue#(Axi3WriteResponse#(axiIdSize)) get; let rv <- slave.write_server.writeDone.get; return Axi3WriteResponse{resp:0, id:extend(rv)}; endmethod endinterface endmodule module mkAxiDmaMaster#(PhysMemMaster#(addrWidth,dataWidth) master) (Axi3Master#(addrWidth,dataWidth,tagWidth)) provisos(Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift), Add#(tagWidth,a__,MemTagSize), Add#(TDiv#(dataWidth,8),b__,dataWidthBytes), Bits#(Tuple3#(Bit#(8),Bit#(TDiv#(dataWidth,8)),Bit#(TDiv#(dataWidth,8))),c__)); Reg#(Bit#(8)) burstReg <- mkReg(0); FIFO#(Tuple3#(Bit#(8),Bit#(TDiv#(dataWidth,8)),Bit#(TDiv#(dataWidth,8)))) reqs <- mkSizedFIFO(32); Reg#(Bit#(dataWidthBytes)) lastbeReg <- mkReg(maxBound); let beat_shift = fromInteger(valueOf(beatShift)); interface Get req_aw; method ActionValue#(Axi3WriteRequest#(addrWidth,tagWidth)) get(); let req <- master.write_client.writeReq.get; reqs.enq(tuple3(truncate(req.burstLen),reqFirstByteEnable(req),reqLastByteEnable(req))); return Axi3WriteRequest{address:req.addr, len:truncate((req.burstLen>>beat_shift)-1), id:truncate(req.tag), size: axiBusSize(valueOf(dataWidth)), burst: 1, prot: 0, cache: 15, lock:0, qos:0}; endmethod endinterface interface Get resp_write; method ActionValue#(Axi3WriteData#(dataWidth,tagWidth)) get(); let tagdata <- master.write_client.writeData.get(); let burstLen = burstReg; Bit#(dataWidthBytes) byteEnable = extend((burstLen == 1) ? lastbeReg : maxBound); if (burstLen == 0) begin match { .bl, .firstbe, .lastbe } = reqs.first; burstLen = bl >> beat_shift; reqs.deq; `ifdef BYTE_ENABLES byteEnable = extend(firstbe); lastbeReg <= lastbe; `endif end burstReg <= burstLen-1; Bit#(1) last = burstLen == 1 ? 1'b1 : 1'b0; return Axi3WriteData { data: tagdata.data, byteEnable: byteEnable, last: last, id: truncate(tagdata.tag) }; endmethod endinterface interface Put resp_b; method Action put(Axi3WriteResponse#(tagWidth) resp); master.write_client.writeDone.put(extend(resp.id)); endmethod endinterface interface Get req_ar; method ActionValue#(Axi3ReadRequest#(addrWidth,tagWidth)) get(); let req <- master.read_client.readReq.get; //$display("req_ar %h", req.tag); return Axi3ReadRequest{address:req.addr, len:truncate((req.burstLen>>beat_shift)-1), id:truncate(req.tag), size: axiBusSize(valueOf(dataWidth)), burst: 1, prot: 0, cache: 15, lock:0, qos:0}; endmethod endinterface interface Put resp_read; method Action put(Axi3ReadResponse#(dataWidth,tagWidth) response); //$display("resp_read %h %h", response.data, response.id); master.read_client.readData.put(MemData { data: response.data, tag: extend(response.id), last: response.last == 1 }); endmethod endinterface endmodule module mkAxi4DmaSlave#(PhysMemSlave#(addrWidth,dataWidth) slave) (Axi4Slave#(addrWidth,dataWidth,axiIdSize)) provisos (Add#(MemTagSize, sz__, axiIdSize)); let beatShift = fromInteger(valueOf(TLog#(TDiv#(dataWidth,8)))); interface Put req_ar; method Action put((Axi4ReadRequest#(addrWidth, axiIdSize)) req); let burstLen = extend(req.len+1) << beatShift; slave.read_server.readReq.put(PhysMemRequest{addr:req.address, burstLen:burstLen, tag:truncate(req.id) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }); endmethod endinterface interface Get resp_read; method ActionValue#(Axi4ReadResponse#(dataWidth, axiIdSize)) get; let resp <- slave.read_server.readData.get; return Axi4ReadResponse{data:resp.data, resp:0, last:1, id:extend(resp.tag)}; endmethod endinterface interface Put req_aw; method Action put(Axi4WriteRequest#(addrWidth, axiIdSize) req); let burstLen = extend(req.len+1) << beatShift; slave.write_server.writeReq.put(PhysMemRequest{addr:req.address, burstLen:burstLen, tag:truncate(req.id) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }); endmethod endinterface interface Put resp_write; method Action put(Axi4WriteData#(dataWidth, axiIdSize) resp); slave.write_server.writeData.put(MemData{data:resp.data, tag:truncate(resp.id), last: resp.last == 1}); endmethod endinterface interface Get resp_b; method ActionValue#(Axi4WriteResponse#(axiIdSize)) get; let rv <- slave.write_server.writeDone.get; return Axi4WriteResponse{resp:0, id:extend(rv)}; endmethod endinterface endmodule module mkAxi4DmaMaster#(PhysMemMaster#(addrWidth,dataWidth) master) (Axi4Master#(addrWidth,dataWidth,tagWidth)) provisos(Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift), Add#(tagWidth,a__,MemTagSize), Add#(TDiv#(dataWidth,8),b__,dataWidthBytes), Bits#(Tuple3#(Bit#(8),Bit#(TDiv#(dataWidth,8)),Bit#(TDiv#(dataWidth,8))),c__)); Reg#(Bit#(8)) burstReg <- mkReg(0); FIFO#(Tuple3#(Bit#(8),Bit#(TDiv#(dataWidth,8)),Bit#(TDiv#(dataWidth,8)))) reqs <- mkSizedFIFO(32); Reg#(Bit#(dataWidthBytes)) lastbeReg <- mkReg(maxBound); let beat_shift = fromInteger(valueOf(beatShift)); interface Get req_aw; method ActionValue#(Axi4WriteRequest#(addrWidth,tagWidth)) get(); let req <- master.write_client.writeReq.get; reqs.enq(tuple3(truncate(req.burstLen),reqFirstByteEnable(req),reqLastByteEnable(req))); return Axi4WriteRequest{address:req.addr, len:truncate((req.burstLen>>beat_shift)-1), id:truncate(req.tag), size: axiBusSize(valueOf(dataWidth)), burst: 1, prot: 0, cache: 15, lock:0, qos:0}; endmethod endinterface interface Get resp_write; method ActionValue#(Axi4WriteData#(dataWidth,tagWidth)) get(); let tagdata <- master.write_client.writeData.get(); let burstLen = burstReg; Bit#(dataWidthBytes) byteEnable = extend((burstLen == 1) ? lastbeReg : maxBound); if (burstLen == 0) begin match { .bl, .firstbe, .lastbe } = reqs.first; burstLen = bl >> beat_shift; reqs.deq; `ifdef BYTE_ENABLES byteEnable = extend(firstbe); lastbeReg <= lastbe; `endif end burstReg <= burstLen-1; Bit#(1) last = burstLen == 1 ? 1'b1 : 1'b0; return Axi4WriteData { data: tagdata.data, byteEnable: byteEnable, last: last, id: truncate(tagdata.tag) }; endmethod endinterface interface Put resp_b; method Action put(Axi4WriteResponse#(tagWidth) resp); master.write_client.writeDone.put(extend(resp.id)); endmethod endinterface interface Get req_ar; method ActionValue#(Axi4ReadRequest#(addrWidth,tagWidth)) get(); let req <- master.read_client.readReq.get; //$display("req_ar %h", req.tag); return Axi4ReadRequest{address:req.addr, len:truncate((req.burstLen>>beat_shift)-1), id:truncate(req.tag), size: axiBusSize(valueOf(dataWidth)), burst: 1, prot: 0, cache: 15, lock:0, qos:0}; endmethod endinterface interface Put resp_read; method Action put(Axi4ReadResponse#(dataWidth,tagWidth) response); //$display("resp_read %h %h", response.data, response.id); master.read_client.readData.put(MemData { data: response.data, tag: extend(response.id), last: response.last == 1 }); endmethod endinterface endmodule ================================================ FILE: bsv/AxiGather.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; import Vector::*; import PPS7LIB::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import AxiBits::*; import GetPutM::*; import FIFOF::*; instance ToPutM#(AxiMasterBits#(addrWidth,dataWidth,tagWidth,Empty), Axi3ReadResponse#(dataWidth, tagWidth)); module toPutM#(AxiMasterBits#(addrWidth, dataWidth, tagWidth, Empty) m)(Put#(Axi3ReadResponse#(dataWidth, tagWidth))); FIFOF#(Axi3ReadResponse#(dataWidth, tagWidth)) dfifo <- mkFIFOF(); rule handshake; m.rvalid(pack(dfifo.notEmpty())); endrule rule deq if (unpack(m.rready())); let d = dfifo.first; m.rid(d.id); m.rresp(d.resp); m.rdata(d.data); m.rlast(d.last); dfifo.deq; endrule return toPut(dfifo); endmodule endinstance instance ToPutM#(AxiMasterBits#(addrWidth,dataWidth,tagWidth,Empty), Axi3WriteResponse#(tagWidth)); module toPutM#(AxiMasterBits#(addrWidth, dataWidth, tagWidth, Empty) m)(Put#(Axi3WriteResponse#(tagWidth))); FIFOF#(Axi3WriteResponse#(tagWidth)) dfifo <- mkFIFOF(); rule handshake; m.bvalid(pack(dfifo.notEmpty())); endrule rule deq if (unpack(m.rready())); let d = dfifo.first; m.bid(d.id); m.bresp(d.resp); dfifo.deq; endrule return toPut(dfifo); endmodule endinstance interface AxiMasterCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth); method Bit#(1) aresetn(); interface Axi3Master#(addrWidth,dataWidth,tagWidth) client; endinterface interface AxiSlaveCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType); method Bit#(1) aresetn(); interface Axi3Slave#(addrWidth,dataWidth,tagWidth) server; interface extraType extra; endinterface interface Axi4SlaveCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType); method Bit#(1) aresetn(); interface Axi4Slave#(addrWidth,dataWidth,tagWidth) server; interface extraType extra; endinterface module mkAxi3MasterGather#(AxiMasterBits#(addrWidth, dataWidth, tagWidth, Empty) axiWires)(AxiMasterCommon#(addrWidth, dataWidth, tagWidth)); Wire#(Bit#(1)) arready <- mkDWire(0); Wire#(Bit#(1)) awready <- mkDWire(0); Wire#(Bit#(1)) rvalid <- mkDWire(0); Wire#(Bit#(1)) wready <- mkDWire(0); Wire#(Bit#(tagWidth)) rid <- mkDWire(0); Wire#(Bit#(2)) rresp <- mkDWire(0); Wire#(Bit#(dataWidth)) rdata <- mkDWire(0); Wire#(Bit#(1)) rlast <- mkDWire(0); Wire#(Bit#(1)) bvalid <- mkDWire(0); Wire#(Bit#(tagWidth)) bid <- mkDWire(0); Wire#(Bit#(2)) bresp <- mkDWire(0); rule handshake1; axiWires.arready(arready); endrule rule handshake2; axiWires.awready(awready); endrule rule handshake4; axiWires.wready(wready); endrule // rule handshake 3 & 5 done in toPutM modules Put#(Axi3ReadResponse#(dataWidth, tagWidth)) resp_read_put <- toPutM(axiWires); Put#(Axi3WriteResponse#(tagWidth)) resp_b_put <- toPutM(axiWires); interface Axi3Master client; interface Get req_ar; method ActionValue#(Axi3ReadRequest#(addrWidth,tagWidth)) get() if (axiWires.arvalid() != 0); Axi3ReadRequest#(addrWidth,tagWidth) v; v.address = axiWires.araddr(); v.burst = axiWires.arburst(); v.cache = axiWires.arcache(); v.id = axiWires.arid(); v.len = axiWires.arlen(); v.lock = axiWires.arlock(); v.prot = axiWires.arprot(); v.qos = axiWires.arqos(); v.size = {0, axiWires.arsize()}; arready <= 1; return v; endmethod endinterface interface Get req_aw; method ActionValue#(Axi3WriteRequest#(addrWidth,tagWidth)) get() if (axiWires.awvalid() != 0); Axi3WriteRequest#(addrWidth,tagWidth) v; v.address = axiWires.awaddr(); v.burst = axiWires.awburst(); v.cache = axiWires.awcache(); v.id = axiWires.awid(); v.len = axiWires.awlen(); v.lock = axiWires.awlock(); v.prot = axiWires.awprot(); v.qos = axiWires.awqos(); v.size = {0, axiWires.awsize()}; awready <= 1; return v; endmethod endinterface interface Put resp_read = resp_read_put; interface Get resp_write; method ActionValue#(Axi3WriteData#(dataWidth,tagWidth)) get() if (axiWires.wvalid() != 0); Axi3WriteData#(dataWidth,tagWidth) v; v.id = axiWires.wid(); v.byteEnable = axiWires.wstrb(); v.data = axiWires.wdata(); v.last = axiWires.wlast(); wready <= 1; return v; endmethod endinterface interface Put resp_b = resp_b_put; endinterface method aresetn = axiWires.aresetn; endmodule module mkAxi3SlaveGather#(AxiSlaveBits#(addrWidth, dataWidth, tagWidth, extraType) axiWires)(AxiSlaveCommon#(addrWidth, dataWidth,tagWidth,extraType)); Wire#(Bit#(addrWidth)) araddr <- mkDWire(0); Wire#(Bit#(2)) arburst <- mkDWire(0); Wire#(Bit#(4)) arcache <- mkDWire(0); Wire#(Bit#(tagWidth)) arid <- mkDWire(0); Wire#(Bit#(4)) arlen <- mkDWire(0); Wire#(Bit#(2)) arlock <- mkDWire(0); Wire#(Bit#(3)) arprot <- mkDWire(0); Wire#(Bit#(4)) arqos <- mkDWire(0); Wire#(Bit#(2)) arsize <- mkDWire(0); Wire#(Bit#(1)) arvalid <- mkDWire(0); Wire#(Bit#(addrWidth)) awaddr <- mkDWire(0); Wire#(Bit#(2)) awburst <- mkDWire(0); Wire#(Bit#(4)) awcache <- mkDWire(0); Wire#(Bit#(tagWidth)) awid <- mkDWire(0); Wire#(Bit#(4)) awlen <- mkDWire(0); Wire#(Bit#(2)) awlock <- mkDWire(0); Wire#(Bit#(3)) awprot <- mkDWire(0); Wire#(Bit#(4)) awqos <- mkDWire(0); Wire#(Bit#(2)) awsize <- mkDWire(0); Wire#(Bit#(1)) awvalid <- mkDWire(0); Wire#(Bit#(1)) rready <- mkDWire(0); Wire#(Bit#(tagWidth)) wid <- mkDWire(0); Wire#(Bit#(TDiv#(dataWidth,8))) wstrb <- mkDWire(0); Wire#(Bit#(dataWidth)) wdata <- mkDWire(0); Wire#(Bit#(1)) wlast <- mkDWire(0); Wire#(Bit#(1)) wvalid <- mkDWire(0); Wire#(Bit#(1)) bready <- mkDWire(0); rule handshake1; axiWires.araddr(araddr); axiWires.arburst(arburst); axiWires.arcache(arcache); axiWires.arid(arid); axiWires.arlen(arlen); axiWires.arlock(arlock); axiWires.arprot(arprot); axiWires.arqos(arqos); axiWires.arsize(arsize); axiWires.arvalid(arvalid); endrule rule handshake2; axiWires.awaddr(awaddr); axiWires.awburst(awburst); axiWires.awcache(awcache); axiWires.awid(awid); axiWires.awlen(awlen); axiWires.awlock(awlock); axiWires.awprot(awprot); axiWires.awqos(awqos); axiWires.awsize(awsize); axiWires.awvalid(awvalid); endrule rule handshake3; axiWires.rready(rready); endrule rule handshake4; axiWires.wid(wid); axiWires.wstrb(wstrb); axiWires.wdata(wdata); axiWires.wlast(wlast); axiWires.wvalid(wvalid); endrule rule handshake5; axiWires.bready(bready); endrule interface Axi3Slave server; interface Put req_ar; method Action put(Axi3ReadRequest#(addrWidth,tagWidth) v) if (axiWires.arready() != 0); araddr <= v.address; arburst <= v.burst; arcache <= v.cache; arid <= v.id; arlen <= v.len; arlock <= v.lock; arprot <= v.prot; arqos <= v.qos; arsize <= v.size[1:0]; arvalid <= 1; endmethod endinterface interface Put req_aw; method Action put(Axi3WriteRequest#(addrWidth,tagWidth) v) if (axiWires.awready() != 0); awaddr <= v.address; awburst <= v.burst; awcache <= v.cache; awid <= v.id; awlen <= v.len; awlock <= v.lock; awprot <= v.prot; awqos <= v.qos; awsize <= v.size[1:0]; awvalid <= 1; endmethod endinterface interface Put resp_write; method Action put(Axi3WriteData#(dataWidth,tagWidth) v) if (axiWires.wready() != 0); wid <= v.id; wstrb <= v.byteEnable; wdata <= v.data; wlast <= v.last; wvalid <= 1; endmethod endinterface interface Get resp_read; method ActionValue#(Axi3ReadResponse#(dataWidth, tagWidth)) get() if (axiWires.rvalid() != 0); Axi3ReadResponse#(dataWidth, tagWidth) v; v.id = axiWires.rid(); v.resp = axiWires.rresp(); v.data = axiWires.rdata(); v.last = axiWires.rlast(); rready <= 1; return v; endmethod endinterface interface Get resp_b; method ActionValue#(Axi3WriteResponse#(tagWidth)) get() if (axiWires.bvalid() != 0); Axi3WriteResponse#(tagWidth) v; v.id = axiWires.bid(); v.resp = axiWires.bresp(); bready <= 1; return v; endmethod endinterface endinterface interface extra = axiWires.extra; method aresetn = axiWires.aresetn; endmodule module mkAxi4SlaveGather#(Axi4SlaveBits#(addrWidth, dataWidth, tagWidth, extraType) axiWires) (Axi4SlaveCommon#(addrWidth, dataWidth,tagWidth,extraType)); Wire#(Bit#(addrWidth)) araddr <- mkDWire(0); Wire#(Bit#(2)) arburst <- mkDWire(0); Wire#(Bit#(4)) arcache <- mkDWire(0); Wire#(Bit#(tagWidth)) arid <- mkDWire(0); Wire#(Bit#(8)) arlen <- mkDWire(0); Wire#(Bit#(2)) arlock <- mkDWire(0); Wire#(Bit#(3)) arprot <- mkDWire(0); Wire#(Bit#(4)) arqos <- mkDWire(0); Wire#(Bit#(3)) arsize <- mkDWire(0); Wire#(Bit#(1)) arvalid <- mkDWire(0); Wire#(Bit#(addrWidth)) awaddr <- mkDWire(0); Wire#(Bit#(2)) awburst <- mkDWire(0); Wire#(Bit#(4)) awcache <- mkDWire(0); Wire#(Bit#(tagWidth)) awid <- mkDWire(0); Wire#(Bit#(8)) awlen <- mkDWire(0); Wire#(Bit#(2)) awlock <- mkDWire(0); Wire#(Bit#(3)) awprot <- mkDWire(0); Wire#(Bit#(4)) awqos <- mkDWire(0); Wire#(Bit#(3)) awsize <- mkDWire(0); Wire#(Bit#(1)) awvalid <- mkDWire(0); Wire#(Bit#(1)) rready <- mkDWire(0); Wire#(Bit#(tagWidth)) wid <- mkDWire(0); Wire#(Bit#(TDiv#(dataWidth,8))) wstrb <- mkDWire(0); Wire#(Bit#(dataWidth)) wdata <- mkDWire(0); Wire#(Bit#(1)) wlast <- mkDWire(0); Wire#(Bit#(1)) wvalid <- mkDWire(0); Wire#(Bit#(1)) bready <- mkDWire(0); rule handshake1; axiWires.araddr(araddr); axiWires.arburst(arburst); axiWires.arcache(arcache); axiWires.arid(arid); axiWires.arlen(arlen); axiWires.arlock(arlock); axiWires.arprot(arprot); axiWires.arqos(arqos); axiWires.arsize(arsize); axiWires.arvalid(arvalid); endrule rule handshake2; axiWires.awaddr(awaddr); axiWires.awburst(awburst); axiWires.awcache(awcache); axiWires.awid(awid); axiWires.awlen(awlen); axiWires.awlock(awlock); axiWires.awprot(awprot); axiWires.awqos(awqos); axiWires.awsize(awsize); axiWires.awvalid(awvalid); endrule rule handshake3; axiWires.rready(rready); endrule rule handshake4; axiWires.wid(wid); axiWires.wstrb(wstrb); axiWires.wdata(wdata); axiWires.wlast(wlast); axiWires.wvalid(wvalid); endrule rule handshake5; axiWires.bready(bready); endrule interface Axi4Slave server; interface Put req_ar; method Action put(Axi4ReadRequest#(addrWidth,tagWidth) v) if (axiWires.arready() != 0); araddr <= v.address; arburst <= v.burst; arcache <= v.cache; arid <= v.id; arlen <= v.len; arlock <= v.lock; arprot <= v.prot; arqos <= v.qos; arsize <= v.size; arvalid <= 1; endmethod endinterface interface Put req_aw; method Action put(Axi4WriteRequest#(addrWidth,tagWidth) v) if (axiWires.awready() != 0); awaddr <= v.address; awburst <= v.burst; awcache <= v.cache; awid <= v.id; awlen <= v.len; awlock <= v.lock; awprot <= v.prot; awqos <= v.qos; awsize <= v.size; awvalid <= 1; endmethod endinterface interface Put resp_write; method Action put(Axi4WriteData#(dataWidth,tagWidth) v) if (axiWires.wready() != 0); wid <= v.id; wstrb <= v.byteEnable; wdata <= v.data; wlast <= v.last; wvalid <= 1; endmethod endinterface interface Get resp_read; method ActionValue#(Axi4ReadResponse#(dataWidth, tagWidth)) get() if (axiWires.rvalid() != 0); Axi4ReadResponse#(dataWidth, tagWidth) v; v.id = axiWires.rid(); v.resp = axiWires.rresp(); v.data = axiWires.rdata(); v.last = axiWires.rlast(); rready <= 1; return v; endmethod endinterface interface Get resp_b; method ActionValue#(Axi4WriteResponse#(tagWidth)) get() if (axiWires.bvalid() != 0); Axi4WriteResponse#(tagWidth) v; v.id = axiWires.bid(); v.resp = axiWires.bresp(); bready <= 1; return v; endmethod endinterface endinterface interface extra = axiWires.extra; method aresetn = axiWires.aresetn; endmodule ================================================ FILE: bsv/AxiMasterSlave.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import FIFO::*; import GetPut::*; import GetPutWithClocks::*; import Connectable::*; import RegFile::*; typeclass RegToWriteOnly#(type a); function WriteOnly#(a) regToWriteOnly(Reg#(a) x); endtypeclass instance RegToWriteOnly#(a); function WriteOnly#(a) regToWriteOnly(Reg#(a) x); return (interface WriteOnly; method Action _write(a v); x._write(v); endmethod endinterface); endfunction endinstance typedef struct { Bit#(addrWidth) address; Bit#(4) len; Bit#(3) size; // assume matches bus width of Axi3Master Bit#(2) burst; // drive with 2'b01 Bit#(3) prot; // drive with 3'b000 Bit#(4) cache; // drive with 4'b0011 Bit#(idWidth) id; Bit#(2) lock; Bit#(4) qos; } Axi3ReadRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits); function Bit#(3) axiBusSize(Integer busWidth); if (busWidth == 16) return 3'b001; else if (busWidth == 32) return 3'b010; else if (busWidth == 64) return 3'b011; else if (busWidth == 128) return 3'b100; else if (busWidth == 256) return 3'b101; else if (busWidth == 512) return 3'b110; else if (busWidth == 1024) return 3'b111; else return 3'b000; endfunction typedef struct { Bit#(busWidth) data; Bit#(2) resp; Bit#(1) last; Bit#(idWidth) id; } Axi3ReadResponse#(numeric type busWidth, numeric type idWidth) deriving (Bits); typedef struct { Bit#(addrWidth) address; Bit#(4) len; Bit#(3) size; // assume matches bus width of Axi3Master Bit#(2) burst; // drive with 2'b01 Bit#(3) prot; // drive with 3'b000 Bit#(4) cache; // drive with 4'b0011 Bit#(idWidth) id; Bit#(2) lock; Bit#(4) qos; } Axi3WriteRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits); typedef struct { Bit#(busWidth) data; Bit#(TDiv#(busWidth,8)) byteEnable; Bit#(1) last; Bit#(idWidth) id; } Axi3WriteData#(numeric type busWidth, numeric type idWidth) deriving (Bits); typedef struct { Bit#(2) resp; Bit#(idWidth) id; } Axi3WriteResponse#(numeric type idWidth) deriving (Bits); function Get#(Axi3ReadResponse#(_b,_c)) get_resp_read(Axi3Slave#(_a,_b,_c) x); return x.resp_read; endfunction function Get#(Axi3WriteResponse#(_c)) get_resp_b(Axi3Slave#(_a,_b,_c) x); return x.resp_b; endfunction interface Axi3Master#(numeric type addrWidth, numeric type busWidth, numeric type idWidth); interface Get#(Axi3ReadRequest#(addrWidth, idWidth)) req_ar; interface Put#(Axi3ReadResponse#(busWidth, idWidth)) resp_read; interface Get#(Axi3WriteRequest#(addrWidth, idWidth)) req_aw; interface Get#(Axi3WriteData#(busWidth, idWidth)) resp_write; interface Put#(Axi3WriteResponse#(idWidth)) resp_b; endinterface interface Axi3Slave#(numeric type addrWidth, numeric type busWidth, numeric type idWidth); interface Put#(Axi3ReadRequest#(addrWidth, idWidth)) req_ar; interface Get#(Axi3ReadResponse#(busWidth, idWidth)) resp_read; interface Put#(Axi3WriteRequest#(addrWidth, idWidth)) req_aw; interface Put#(Axi3WriteData#(busWidth, idWidth)) resp_write; interface Get#(Axi3WriteResponse#(idWidth)) resp_b; endinterface function Put#(t) null_put(); return (interface Put; method Action put(t x) if (False); noAction; endmethod endinterface); endfunction function Get#(t) null_get(); return (interface Get; method ActionValue#(t) get() if (False); return ?; endmethod endinterface); endfunction function Axi3Master#(addrWidth, busWidth, idWidth) null_axi_master(); return (interface Axi3Master; interface Get req_ar = null_get; interface Put resp_read = null_put; interface Get req_aw = null_get; interface Get resp_write = null_get; interface Put resp_b = null_put; endinterface); endfunction instance Connectable#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth)); module mkConnection#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty); mkConnection(m.req_ar, s.req_ar); mkConnection(s.resp_read, m.resp_read); mkConnection(m.req_aw, s.req_aw); mkConnection(m.resp_write, s.resp_write); mkConnection(s.resp_b, m.resp_b); endmodule endinstance instance ConnectableWithClocks#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth)) provisos (ConnectableWithClocks#(Get#(Axi3ReadRequest#(addrWidth, idWidth)), Put#(Axi3ReadRequest#(addrWidth, idWidth))) ,ConnectableWithClocks#(Get#(Axi3ReadResponse#(busWidth, idWidth)), Put#(Axi3ReadResponse#(busWidth, idWidth))) ,ConnectableWithClocks#(Get#(Axi3WriteRequest#(addrWidth, idWidth)), Put#(Axi3WriteRequest#(addrWidth, idWidth))) ,ConnectableWithClocks#(Get#(Axi3WriteData#(busWidth, idWidth)), Put#(Axi3WriteData#(busWidth, idWidth))) ,ConnectableWithClocks#(Get#(Axi3WriteResponse#(idWidth)), Put#(Axi3WriteResponse#(idWidth))) ); module mkConnectionWithClocks2#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty); mkConnectionWithClocks(clockOf(m), resetOf(m), clockOf(s), resetOf(s), m, s); endmodule module mkConnectionWithClocks#(Clock mClock, Reset mReset, Clock sClock, Reset sReset, Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty); mkConnectionWithClocks(mClock, mReset, sClock, sReset, m.req_ar, s.req_ar); mkConnectionWithClocks(sClock, sReset, mClock, mReset, s.resp_read, m.resp_read); mkConnectionWithClocks(mClock, mReset, sClock, sReset, m.req_aw, s.req_aw); mkConnectionWithClocks(mClock, mReset, sClock, sReset, m.resp_write, s.resp_write); mkConnectionWithClocks(sClock, sReset, mClock, mReset, s.resp_b, m.resp_b); endmodule endinstance ================================================ FILE: bsv/AxiStream.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; import FIFOF::*; import GetPut::*; import GetPutM::*; import Probe::*; `include "ConnectalProjectConfig.bsv" (* always_ready, always_enabled *) interface AxiStreamMaster#(numeric type dsz); method Bit#(dsz) tdata(); method Bit#(TDiv#(dsz,8)) tkeep(); method Bit#(1) tlast(); (* prefix = "" *)method Action tready((* port="tready" *) Bit#(1) v); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface AxiStreamSlave#(numeric type dsz); (* prefix = "" *) method Action tdata((* port = "tdata" *) Bit#(dsz) v); (* prefix = "" *) method Action tkeep((* port = "tkeep" *) Bit#(TDiv#(dsz,8)) v); (* prefix = "" *) method Action tlast((* port = "tlast" *) Bit#(1) v); method Bit#(1) tready(); (* prefix = "" *) method Action tvalid((* port = "tvalid" *)Bit#(1) v); endinterface instance Connectable#(AxiStreamMaster#(dataWidth), AxiStreamSlave#(dataWidth)); module mkConnection#(AxiStreamMaster#(dataWidth) from, AxiStreamSlave#(dataWidth) to)(Empty); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO let cnxProbe <- mkProbe; rule rl_probe if (from.tvalid() == 1 && to.tready() == 1); cnxProbe <= from.tdata(); endrule `endif rule rl_axi_stream; to.tdata(from.tdata()); to.tkeep(from.tkeep()); to.tlast(from.tlast()); to.tvalid(from.tvalid()); from.tready(to.tready()); endrule endmodule endinstance instance Connectable#(AxiStreamMaster#(dataWidth), Put#(dtype)) provisos (Bits#(dtype, dataWidth)); module mkConnection#(AxiStreamMaster#(dataWidth) from, Put#(dtype) to)(Empty); FIFOF#(Bit#(dataWidth)) asputfifo <- mkFIFOF(); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO let getProbe <- mkProbe; let putProbe <- mkProbe; `endif rule rl_ready; from.tready(pack(asputfifo.notFull)); endrule rule rl_enq if (from.tvalid == 1); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO getProbe <= from.tdata; `endif asputfifo.enq(from.tdata); endrule rule rl_put; let v <- toGet(asputfifo).get(); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO putProbe <= v; `endif to.put(unpack(v)); endrule endmodule endinstance instance Connectable#(Get#(dtype), AxiStreamSlave#(dataWidth)) provisos (Bits#(dtype, dataWidth)); module mkConnection#(Get#(dtype) from, AxiStreamSlave#(dataWidth) to)(Empty); FIFOF#(Bit#(dataWidth)) asgetfifo <- mkFIFOF(); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO let getProbe <- mkProbe(); let putProbe <- mkProbe(); `endif rule rl_get; let v <- from.get(); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO getProbe <= v; `endif asgetfifo.enq(pack(v)); endrule rule rl_axi_stream; to.tdata(asgetfifo.first); to.tkeep(maxBound); to.tlast(0); endrule rule rl_tvalid; to.tvalid(pack(asgetfifo.notEmpty)); endrule rule rl_deq if (to.tready == 1); `ifdef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO putProbe <= asgetfifo.first(); `endif asgetfifo.deq(); endrule endmodule endinstance //////////////////////////////////////////////////////////// instance ToGetM#(AxiStreamMaster#(asz), Bit#(asz)); module toGetM#(AxiStreamMaster#(asz) m)(Get#(Bit#(asz))); FIFOF#(Bit#(asz)) tmpfifo <- mkFIFOF(); rule handshake; m.tready(pack(tmpfifo.notFull)); endrule rule enq if (unpack(m.tvalid)); tmpfifo.enq(m.tdata()); endrule return toGet(tmpfifo); endmodule endinstance instance ToPutM#(AxiStreamSlave#(asz), Bit#(asz)); module toPutM#(AxiStreamSlave#(asz) m)(Put#(Bit#(asz))); FIFOF#(Bit#(asz)) tmpfifo <- mkFIFOF(); rule handshake; m.tvalid(pack(tmpfifo.notEmpty())); endrule rule deq if (unpack(m.tready())); m.tdata(tmpfifo.first()); m.tkeep(maxBound); m.tlast(1); tmpfifo.deq(); endrule return toPut(tmpfifo); endmodule endinstance //////////////////////////////////////////////////////////// typeclass ToAxiStream#(type atype, type btype); function atype toAxiStream(btype b); endtypeclass typeclass MkAxiStream#(type atype, type btype); module mkAxiStream#(btype b)(atype); endtypeclass instance MkAxiStream#(AxiStreamMaster#(dsize), FIFOF#(Bit#(dsize))); module mkAxiStream#(FIFOF#(Bit#(dsize)) f)(AxiStreamMaster#(dsize)); Wire#(Bool) readyWire <- mkDWire(False); Wire#(Bit#(dsize)) dataWire <- mkDWire(0); rule rl_data if (f.notEmpty()); dataWire <= f.first(); endrule rule rl_deq if (readyWire && f.notEmpty); f.deq(); endrule method Bit#(dsize) tdata(); return dataWire; endmethod method Bit#(TDiv#(dsize,8)) tkeep(); return maxBound; endmethod method Bit#(1) tlast(); return pack(False); endmethod method Action tready(Bit#(1) v); readyWire <= unpack(v); endmethod method Bit#(1) tvalid(); return pack(f.notEmpty()); endmethod endmodule endinstance instance MkAxiStream#(AxiStreamSlave#(dsize), FIFOF#(Bit#(dsize))); module mkAxiStream#(FIFOF#(Bit#(dsize)) f)(AxiStreamSlave#(dsize)); Wire#(Bit#(dsize)) dataWire <- mkDWire(unpack(0)); Wire#(Bool) validWire <- mkDWire(False); rule enq if (validWire && f.notFull()); f.enq(dataWire); endrule method Action tdata(Bit#(dsize) v); dataWire <= v; endmethod method Action tkeep(Bit#(TDiv#(dsize,8)) v); endmethod method Action tlast(Bit#(1) v); endmethod method Bit#(1) tready(); return pack(f.notFull()); endmethod method Action tvalid(Bit#(1) v); validWire <= unpack(v); endmethod endmodule endinstance ================================================ FILE: bsv/BpiFlash.bsv ================================================ `include "ConnectalProjectConfig.bsv" import Vector::*; import Clocks::*; import Connectable::*; import GetPut::*; import FIFOF::*; import BRAM::*; import Probe::*; import StmtFSM::*; import TriState::*; import Vector::*; import ConnectalXilinxCells::*; `ifdef SIMULATION import I28F512P33::*; `endif // interface to BPI Flash (PC28F00AG18FE) (* always_ready, always_enabled *) interface BpiFlashPins; interface Clock deleteme_unused_clock; // interface Reset rst; interface Vector#(16,Inout#(Bit#(1))) data; method Bit#(26) addr(); method Bit#(1) adv_b(); method Bit#(1) ce_b(); method Bit#(1) oe_b(); method Bit#(1) we_b(); `ifdef BPI_HAS_WP method Bit#(1) wp_b(); `endif `ifdef BPI_HAS_VPP method Bit#(1) vpp(); `endif method Action wait_in(Bit#(1) b); endinterface interface BpiPins; interface BpiFlashPins flash; endinterface interface BpiFlash; interface BpiFlashPins flash; method Action setParameters(Bit#(16) cycles, Bool stallOnWaitIn); interface Server#(BRAMRequest#(Bit#(26),Bit#(16)),Bit#(16)) server; endinterface module mkBpiFlash(BpiFlash); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Reg#(Bit#(1)) rst_o <- mkReg(0); Reg#(Bit#(1)) ce <- mkReg(1); Reg#(Bit#(1)) we <- mkReg(1); Reg#(Bit#(1)) oe <- mkReg(1); Reg#(Bit#(1)) adv <- mkReg(1); Reg#(Bit#(16)) data_o <- mkReg(0); Reg#(Bit#(26)) addr_o <- mkReg(0); Reg#(Bit#(16)) delayReg <- mkReg(10); Reg#(Bool) stallOnWaitReg <- mkReg(False); Reg#(BRAMRequest#(Bit#(26),Bit#(16))) reqReg <- mkReg(unpack(0)); FIFOF#(BRAMRequest#(Bit#(26),Bit#(16))) reqFifo <- mkFIFOF(); FIFOF#(Bit#(16)) dataFifo <- mkFIFOF(); `ifndef SIMULATION Wire#(Bit#(1)) wait_in_b <- mkDWire(0); module mkDataIobuf#(Integer i)(IOBUF); (* hide *) let iobuf <- mkIOBUF(we, data_o[i]); return iobuf; endmodule function Inout#(Bit#(1)) iobuf_io(IOBUF iobuf); return iobuf.io; endfunction function Bit#(1) iobuf_o(IOBUF iobuf); return iobuf.o; endfunction Vector#(16, IOBUF) iobuf <- genWithM(mkDataIobuf); let dataIn = pack(map(iobuf_o, iobuf)); `endif `ifdef SIMULATION let flash <- mkI28f512p33Load("flash.hex"); let dataTristate <- mkTriState(oe == 1, data_o); mkConnection(dataTristate.io, flash.dq); let wait_in_b = flash.waitout(); let dataIn = dataTristate; rule rl_flash_inputs; flash.addr(addr_o); flash.advneg(adv); flash.ceneg(ce); flash.oeneg(oe); flash.weneg(we); flash.wpneg(1); flash.vpp(0); endrule `endif Reg#(Bit#(10)) i <- mkReg(0); let readFsm <- mkAutoFSM(seq while (True) seq action reqFifo.deq(); let req = reqFifo.first(); reqReg <= req; addr_o <= req.address; data_o <= req.datain; adv <= 0; ce <= 0; endaction delay(delayReg); adv <= 1; delay(delayReg); action if (reqReg.write) we <= 0; else oe <= 0; endaction delay(delayReg); $display("addr_o=%x\n", addr_o); $display("wait_in_b=%d dataIn=%x", wait_in_b, dataIn); if (reqReg.write) we <= 1; if (!reqReg.write && stallOnWaitReg) await (wait_in_b == 1); $display("wait_in_b=%d dataIn=%x", wait_in_b, dataIn); if (!reqReg.write || reqReg.responseOnWrite) dataFifo.enq(dataIn); delay(delayReg); ce <= 1; oe <= 1; delay(delayReg); endseq endseq); method Action setParameters(Bit#(16) cycles, Bool stallOnWaitIn); delayReg <= cycles; stallOnWaitReg <= stallOnWaitIn; endmethod interface Server server; interface request = toPut(reqFifo); interface response = toGet(dataFifo); endinterface `ifndef SIMULATION interface BpiFlashPins flash; interface deleteme_unused_clock = clock; // interface rst = defaultReset; interface data = map(iobuf_io, iobuf); method Bit#(26) addr = addr_o; method Bit#(1) adv_b = adv; method Bit#(1) ce_b = ce; method Bit#(1) oe_b = oe; method Bit#(1) we_b = we; `ifdef BPI_HAS_WP method Bit#(1) wp_b = 1; `endif `ifdef BPI_HAS_VPP method Bit#(1) vpp = 0; `endif method Action wait_in(Bit#(1) b); wait_in_b <= b; endmethod endinterface `endif endmodule ================================================ FILE: bsv/BramMux.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ClientServer ::*; import BRAM ::*; import Vector ::*; import FIFO ::*; import SpecialFIFOs :: *; interface BramServerMux#(numeric type aszn, type dtype); interface BRAMServer#(Bit#(aszn), dtype) bramServer; endinterface module mkBramServerMux#(Vector#(numServers, BRAMServer#(Bit#(asz),dtype)) bramServers)(BramServerMux#(aszn,dtype)) provisos (Add#(1,a__,numServers), Log#(numServers,csz), Add#(asz,csz,aszn), Bits#(dtype,dsz), Bits#(Tuple2#(Bit#(csz), BRAM::BRAMRequest#(Bit#(asz), dtype)), c__) ); let numServers = valueOf(numServers); FIFO#(dtype) responseFifo <- mkPipelineFIFO(); for (Integer i = 0; i < numServers; i = i + 1) begin (* descending_urgency = "respond" *) rule respond; let response <- bramServers[i].response.get(); responseFifo.enq(response); endrule end interface BRAMServer bramServer; interface Put request; method Action put(BRAMRequest#(Bit#(aszn), dtype) request); Bit#(csz) clientNumber = request.address[valueOf(aszn)-1:valueOf(asz)]; bramServers[clientNumber].request.put( BRAMRequest { write: request.write, responseOnWrite: request.responseOnWrite, address: truncate(request.address), datain: request.datain }); endmethod endinterface interface Get response; method ActionValue#(dtype) get(); responseFifo.deq(); return responseFifo.first(); endmethod endinterface endinterface endmodule module mkGatedBramServerMux#(Reg#(Bool) gate, Vector#(numServers, BRAMServer#(Bit#(asz),dtype)) bramServers)(BramServerMux#(aszn,dtype)) provisos (Add#(1,a__,numServers), Log#(numServers,csz), Add#(asz,csz,aszn), Bits#(dtype,dsz), Bits#(Tuple2#(Bit#(csz), BRAM::BRAMRequest#(Bit#(asz), dtype)), c__) ); let numServers = valueOf(numServers); FIFO#(dtype) responseFifo <- mkPipelineFIFO(); for (Integer i = 0; i < numServers; i = i + 1) begin (* descending_urgency = "respond" *) rule respond if (gate); let response <- bramServers[i].response.get(); responseFifo.enq(response); endrule end interface BRAMServer bramServer; interface Put request; method Action put(BRAMRequest#(Bit#(aszn), dtype) request) if (gate); Bit#(csz) clientNumber = request.address[valueOf(aszn)-1:valueOf(asz)]; bramServers[clientNumber].request.put( BRAMRequest { write: request.write, responseOnWrite: request.responseOnWrite, address: truncate(request.address), datain: request.datain }); endmethod endinterface interface Get response; method ActionValue#(dtype) get(); responseFifo.deq(); return responseFifo.first(); endmethod endinterface endinterface endmodule ================================================ FILE: bsv/CnocPortal.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import FIFOF::*; import Vector::*; import ConnectalMemTypes::*; import Pipe::*; import Portal::*; import HostInterface::*; typedef enum { BpHeader, BpMessage } CnocPortalState deriving (Bits,Eq); interface PortalMsgRequest; method Bit#(SlaveDataBusWidth) id(); interface PipeIn#(Bit#(32)) message; endinterface interface PortalMsgIndication; method Bit#(SlaveDataBusWidth) id(); interface PipeOut#(Bit#(32)) message; endinterface interface CnocTop#(numeric type numRequests, numeric type numIndications, numeric type addrWidth, numeric type dataWidth, type pins, numeric type numMasters ); interface Vector#(numRequests, PortalMsgRequest) requests; interface Vector#(numIndications, PortalMsgIndication) indications; interface Vector#(NumReadClients,MemReadClient#(DataBusWidth)) readers; interface Vector#(NumWriteClients,MemWriteClient#(DataBusWidth)) writers; interface pins pins; endinterface module mkPortalMsgRequest#(Bit#(SlaveDataBusWidth) portalId, Vector#(numRequests, PipeIn#(Bit#(32))) portal)(PortalMsgRequest); Reg#(Bit#(8)) messageWordsReg <- mkReg(0); Reg#(Bit#(8)) methodIdReg <- mkReg(0); Reg#(CnocPortalState) bpState <- mkReg(BpHeader); FIFOF#(Bit#(32)) fifoMsgSink <- mkFIFOF(); Bool verbose = False; rule receiveMessageHeader if (bpState == BpHeader); let hdr = fifoMsgSink.first(); fifoMsgSink.deq(); let methodId = hdr[23:16]; Bit#(8) messageWords = hdr[7:0] - 1; if (messageWords == 0) messageWords = 1; methodIdReg <= methodId; if (verbose) $display("receiveMessageHeader portal=%d hdr=%x methodId=%x messageWords=%d", portalId, hdr, methodId, messageWords); messageWordsReg <= messageWords; if (messageWords != 0) bpState <= BpMessage; endrule rule receiveMessage if (bpState == BpMessage); let data = fifoMsgSink.first(); fifoMsgSink.deq(); if (verbose) $display("receiveMessage portal=%d id=%d data=%x messageWords=%d", portalId, methodIdReg, data, messageWordsReg); portal[methodIdReg].enq(data); messageWordsReg <= messageWordsReg - 1; if (messageWordsReg == 1) bpState <= BpHeader; endrule method Bit#(SlaveDataBusWidth) id(); return portalId; endmethod interface message = toPipeIn(fifoMsgSink); endmodule module mkPortalMsgIndication#(Bit#(SlaveDataBusWidth) portalId, Vector#(numIndications, PipeOut#(Bit#(32))) portal, PortalSize messageSize)(PortalMsgIndication); Reg#(Bit#(16)) messageWordsReg <- mkReg(0); Reg#(Bit#(8)) methodIdReg <- mkReg(0); Reg#(CnocPortalState) bpState <- mkReg(BpHeader); Vector#(numIndications, Bool) readyBits = map(pipeOutNotEmpty, portal); Bool interruptStatus = False; Bit#(8) readyChannel = -1; FIFOF#(Bit#(32)) fifoMsgSource <- mkFIFOF(); function Bool pipeOutNotEmpty(PipeOut#(a) po); return po.notEmpty(); endfunction let verbose = False; for (Integer i = valueOf(numIndications) - 1; i >= 0; i = i - 1) begin if (readyBits[i]) begin interruptStatus = True; readyChannel = fromInteger(i); end end rule sendHeader if (bpState == BpHeader && interruptStatus); Bit#(16) messageBits = messageSize.size(extend(readyChannel)); Bit#(16) roundup = messageBits[4:0] == 0 ? 0 : 1; Bit#(16) numWords = (messageBits >> 5) + roundup; Bit#(32) hdr = extend(readyChannel) << 16 | extend(numWords+1); if (verbose) $display("sendHeader portal=%d hdr=%h messageBits=%d numWords=%d", portalId, hdr, messageBits, numWords); messageWordsReg <= numWords; methodIdReg <= readyChannel; fifoMsgSource.enq(hdr); bpState <= BpMessage; endrule rule sendMessage if (bpState == BpMessage); messageWordsReg <= messageWordsReg - 1; let v = portal[methodIdReg].first; portal[methodIdReg].deq(); fifoMsgSource.enq(v); if (verbose) $display("sendMessage portal=%d id=%d data=%h messageWords=%d", portalId, methodIdReg, v, messageWordsReg); if (messageWordsReg == 1) begin bpState <= BpHeader; end endrule method Bit#(SlaveDataBusWidth) id(); return portalId; endmethod interface message = toPipeOut(fifoMsgSource); endmodule ================================================ FILE: bsv/ConnectableWithTrace.bsv ================================================ // Copyright (c) 2014-2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import AxiMasterSlave::*; import Connectable::*; import BRAM::*; import Bscan::*; import Vector::*; import FIFOF::*; typeclass ConnectableWithTrace#(type a, type b, type c); module mkConnectionWithTrace#(a x1, b x2, c x3)(Empty); endtypeclass //`define TRACE_AXI //`define AXI_READ_TIMING //`define AXI_WRITE_TIMING `define TRACE_ADDR_WIDTH 12 //8 `define TRACE_ADDR_SIZE 4096 //256 instance ConnectableWithTrace#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth), BscanTop) provisos(Add#(0,addrWidth,32)); module mkConnectionWithTrace#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s, BscanTop bscan)(Empty); `ifndef TRACE_AXI mkConnection(m, s); `else Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reg#(Bit#(`TRACE_ADDR_WIDTH)) addrReg <- mkReg(9); BscanBram#(Bit#(`TRACE_ADDR_WIDTH), Bit#(64)) bscanBram <- mkBscanBram(127, addrReg, bscan); BRAM_Configure bramCfg = defaultValue; bramCfg.memorySize = `TRACE_ADDR_SIZE; bramCfg.latency = 1; BRAM2Port#(Bit#(`TRACE_ADDR_WIDTH), Bit#(64)) traceBram <- mkBRAM2Server(bramCfg); mkConnection(bscanBram.bramClient, traceBram.portB); rule tdorule; bscan.tdo(bscanBram.data_out()); endrule Vector#(5, FIFOF#(Bit#(64))) bscan_fifos <- replicateM(mkFIFOF); let interrupt_bit = 1'b0; rule write_bscanBram; Bit#(64) data = ?; if (bscan_fifos[0].notEmpty) begin data = bscan_fifos[0].first; bscan_fifos[0].deq; end else if (bscan_fifos[1].notEmpty) begin data = bscan_fifos[1].first; bscan_fifos[1].deq; end else if (bscan_fifos[2].notEmpty) begin data = bscan_fifos[2].first; bscan_fifos[2].deq; end else if (bscan_fifos[3].notEmpty) begin data = bscan_fifos[3].first; bscan_fifos[3].deq; end else begin data = bscan_fifos[4].first; bscan_fifos[4].deq; end traceBram.portA.request.put(BRAMRequest {write:True, responseOnWrite:False, address:addrReg, datain:data}); addrReg <= addrReg + 1; endrule Reg#(Bit#(16)) seqCounter <- mkReg(0); (* fire_when_enabled *) rule seqinc; seqCounter <= seqCounter + 1; endrule // AXI trace for JTAG //mkConnection(m.req_ar, s.req_ar); rule connect_req_ar; let req <- m.req_ar.get(); s.req_ar.put(req); bscan_fifos[0].enq( {3'h1, interrupt_bit, 6'h0, req.id[5:0], `ifdef AXI_READ_TIMING seqCounter, `else req.len, req.cache, req.prot, req.size, pack(req.burst == 2'b01), pack(req.lock == 0 && req.qos == 0), `endif req.address}); endrule //mkConnection(s.resp_read, m.resp_read); rule connect_resp_read; let resp <- s.resp_read.get(); m.resp_read.put(resp); bscan_fifos[1].enq( {3'h2, interrupt_bit, 6'h0, resp.id[5:0], `ifdef AXI_READ_TIMING seqCounter, `else resp.resp, resp.last, 13'b0, `endif resp.data[31:0]}); endrule //mkConnection(m.req_aw, s.req_aw); rule connect_req_aw; let req <- m.req_aw.get(); s.req_aw.put(req); bscan_fifos[2].enq( {3'h3, interrupt_bit, 6'h0, req.id[5:0], `ifdef AXI_WRITE_TIMING seqCounter, `else req.len, req.cache, req.prot, req.size, pack(req.burst == 2'b01), pack(req.lock == 0 && req.qos == 0), `endif req.address}); endrule //mkConnection(m.resp_write, s.resp_write); rule connect_resp_write; let resp <- m.resp_write.get(); s.resp_write.put(resp); bscan_fifos[3].enq( {3'h4, interrupt_bit, 6'h0, resp.id[5:0], `ifdef AXI_WRITE_TIMING seqCounter, `else resp.last, resp.byteEnable[3:0], 11'b0, `endif resp.data[31:0]}); endrule //mkConnection(s.resp_b, m.resp_b); rule connect_resp_b; let resp <- s.resp_b.get(); m.resp_b.put(resp); bscan_fifos[4].enq( {3'h5, interrupt_bit, 6'h0, resp.id[5:0], resp.resp, 46'b0}); endrule `endif endmodule endinstance interface TraceReadout; interface BRAMClient#(Bit#(`TRACE_ADDR_WIDTH),Bit#(64)) bramClient; endinterface instance ConnectableWithTrace#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth), TraceReadout) provisos(Add#(0,addrWidth,32)); module mkConnectionWithTrace#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s, TraceReadout readout)(Empty); Reg#(Bit#(`TRACE_ADDR_WIDTH)) addrReg <- mkReg(9); BRAM_Configure bramCfg = defaultValue; bramCfg.memorySize = `TRACE_ADDR_SIZE; bramCfg.latency = 1; BRAM2Port#(Bit#(`TRACE_ADDR_WIDTH), Bit#(64)) traceBram <- mkBRAM2Server(bramCfg); mkConnection(readout.bramClient, traceBram.portB); Vector#(5, FIFOF#(Bit#(64))) bscan_fifos <- replicateM(mkFIFOF); let interrupt_bit = 1'b0; rule write_bscanBram; Bit#(64) data = ?; if (bscan_fifos[0].notEmpty) begin data = bscan_fifos[0].first; bscan_fifos[0].deq; end else if (bscan_fifos[1].notEmpty) begin data = bscan_fifos[1].first; bscan_fifos[1].deq; end else if (bscan_fifos[2].notEmpty) begin data = bscan_fifos[2].first; bscan_fifos[2].deq; end else if (bscan_fifos[3].notEmpty) begin data = bscan_fifos[3].first; bscan_fifos[3].deq; end else begin data = bscan_fifos[4].first; bscan_fifos[4].deq; end traceBram.portA.request.put(BRAMRequest {write:True, responseOnWrite:False, address:addrReg, datain:data}); addrReg <= addrReg + 1; endrule Reg#(Bit#(16)) seqCounter <- mkReg(0); (* fire_when_enabled *) rule seqinc; seqCounter <= seqCounter + 1; endrule // AXI trace for JTAG //mkConnection(m.req_ar, s.req_ar); rule connect_req_ar; let req <- m.req_ar.get(); s.req_ar.put(req); bscan_fifos[0].enq( {3'h1, interrupt_bit, 6'h0, req.id[5:0], `ifdef AXI_READ_TIMING seqCounter, `else req.len, req.cache, req.prot, req.size, pack(req.burst == 2'b01), pack(req.lock == 0 && req.qos == 0), `endif req.address}); endrule //mkConnection(s.resp_read, m.resp_read); rule connect_resp_read; let resp <- s.resp_read.get(); m.resp_read.put(resp); bscan_fifos[1].enq( {3'h2, interrupt_bit, 6'h0, resp.id[5:0], `ifdef AXI_READ_TIMING seqCounter, `else resp.resp, resp.last, 13'b0, `endif resp.data[31:0]}); endrule //mkConnection(m.req_aw, s.req_aw); rule connect_req_aw; let req <- m.req_aw.get(); s.req_aw.put(req); bscan_fifos[2].enq( {3'h3, interrupt_bit, 6'h0, req.id[5:0], `ifdef AXI_WRITE_TIMING seqCounter, `else req.len, req.cache, req.prot, req.size, pack(req.burst == 2'b01), pack(req.lock == 0 && req.qos == 0), `endif req.address}); endrule //mkConnection(m.resp_write, s.resp_write); rule connect_resp_write; let resp <- m.resp_write.get(); s.resp_write.put(resp); bscan_fifos[3].enq( {3'h4, interrupt_bit, 6'h0, resp.id[5:0], `ifdef AXI_WRITE_TIMING seqCounter, `else resp.last, resp.byteEnable[3:0], 11'b0, `endif resp.data[31:0]}); endrule //mkConnection(s.resp_b, m.resp_b); rule connect_resp_b; let resp <- s.resp_b.get(); m.resp_b.put(resp); bscan_fifos[4].enq( {3'h5, interrupt_bit, 6'h0, resp.id[5:0], resp.resp, 46'b0}); endrule endmodule endinstance ================================================ FILE: bsv/ConnectalAlteraCells.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks :: *; import DefaultValue :: *; import Vector :: *; import ConnectalClocks ::*; ================================================ FILE: bsv/ConnectalBram.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import BRAM::*; import BRAMCore::*; import GetPut::*; import ClientServer::*; import OldEHR::*; import ConfigCounter::*; interface BRAMServers#(numeric type numServers, type addr, type data); interface Vector#(numServers, BRAM1Port#(addr,data)) ports; endinterface module mkBRAMServers#(BRAM_Configure bramConfig)(BRAMServers#(numServers, addr, data)) provisos (Bits#(addr,asz), Bits#(data,dsz)); let memorySize = bramConfig.memorySize == 0 ? 2**valueOf(asz) : bramConfig.memorySize; BRAM_DUAL_PORT#(addr,data) bram <- mkBRAMCore2(memorySize, True); // latency 2 Vector#(2, FIFOF#(data)) responseFifo <- replicateM(mkSizedFIFOF(2)); // EHR did not work here, CReg doesn't seem to go into a vector, so using Wire. -Jamey Vector#(2, Wire#(Maybe#(Tuple2#(Bool,data)))) data0 <- replicateM(mkDWire(tagged Invalid)); Vector#(2, Reg#(Maybe#(Tuple2#(Bool,data)))) data1 <- replicateM(mkReg(tagged Invalid)); Vector#(2, Reg#(Maybe#(Tuple2#(Bool,data)))) data2 <- replicateM(mkReg(tagged Invalid)); Vector#(2, ConfigCounter#(2)) counter <- replicateM(mkConfigCounter(2)); let verbose = False; function BRAM_PORT#(addr, data) portsel(Integer port); return (port == 0) ? bram.a : bram.b; endfunction for (Integer i = 0; i < 2; i = i + 1) begin rule bramRule; // zeroth stage let d0 = data0[i]; data1[i] <= d0; // first stage // address register let d1 = data1[i]; data2[i] <= d1; // second stage let d2 = data2[i]; if (d2 matches tagged Valid .tpl) begin match { .write, .data } = tpl; if (!write) data = portsel(i).read(); if (responseFifo[i].notFull()) responseFifo[i].enq(data); else $display("Error: responseFifo is unexpectedly full"); end endrule end Reg#(Bit#(32)) cycles <- mkReg(0); rule cyclesRule if (verbose); cycles <= cycles + 1; endrule function BRAM1Port#(addr,data) server(Integer i); return (interface BRAM1Port#(addr,data); interface BRAMServer portA; interface Put request; method Action put(BRAMRequest#(addr,data) req) if (counter[i].positive()); if (verbose) $display("%d %d addr %h data %h write %d counter %d", memorySize, cycles, req.address, req.datain, req.write, counter[i].read()); portsel(i).put(req.write, req.address, req.datain); if (!req.write || req.responseOnWrite) begin counter[i].decrement(1); data0[i] <= tagged Valid tuple2(req.write, req.datain); end endmethod endinterface interface Get response; method ActionValue#(data) get(); let v <- toGet(responseFifo[i]).get(); if (verbose) $display("%d %d data %h counter %d", memorySize, cycles, v, counter[i].read()); counter[i].increment(1); return v; endmethod endinterface: response endinterface: portA method Action portAClear(); //FIXME endmethod endinterface); endfunction interface ports = genWith(server); endmodule module mkBRAM2Server#(BRAM_Configure bramConfig)(BRAM2Port#(addr, data)) provisos (Bits#(addr, a__), Bits#(data, b__)); BRAMServers#(2,addr,data) cbram <- mkBRAMServers(bramConfig); interface portA = cbram.ports[0].portA; interface portB = cbram.ports[1].portA; method portAClear = cbram.ports[0].portAClear; method portBClear = cbram.ports[1].portAClear; endmodule module mkBRAM1Server#(BRAM_Configure bramConfig)(BRAM1Port#(addr, data)) provisos (Bits#(addr, a__), Bits#(data, b__)); BRAMServers#(1,addr,data) cbram <- mkBRAMServers(bramConfig); interface portA = cbram.ports[0].portA; method portAClear = cbram.ports[0].portAClear; endmodule export mkBRAM1Server; export mkBRAM2Server; ================================================ FILE: bsv/ConnectalBramFifo.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import Vector::*; import FIFO::*; import FIFOF::*; import BRAMFIFO::*; import CBus::*; // extendNP and truncateNP `include "ConnectalProjectConfig.bsv" import Arith::*; import ConnectalClocks::*; `ifdef SIMULATION `ifdef BOARD_xsim `define USE_XILINX_MACRO `endif // xsim `else // not SIMULATION `ifdef XILINX `define USE_XILINX_MACRO `endif // XILINX `endif // not SIMULATION `ifdef USE_XILINX_MACRO (* always_ready, always_enabled *) interface X7FifoSyncMacro#(numeric type data_width); method Bit#(1) empty(); method Bit#(1) full(); method Action din(Bit#(data_width) v); method Action wren(Bit#(1) wren); method Bit#(data_width) dout(); method Action rden(Bit#(1) rden); method Bit#(9) wrcount(); method Bit#(9) rdcount(); endinterface import "BVI" FIFO_DUALCLOCK_MACRO = module vmkBramFifo#(String fifo_size, Clock wrClock, Reset wrReset, Clock rdClock, Reset rdReset)(X7FifoSyncMacro#(data_width)); `ifndef BSV_POSITIVE_RESET let rdReset1 <- mkSyncReset(10, rdReset, wrClock); let eitherReset <- mkResetEither(wrReset, rdReset1, clocked_by wrClock); let positiveReset <- mkPositiveReset(10, eitherReset, wrClock); // rst must be asserted for 5 read and write clock cycles let fifoReset = positiveReset.positiveReset; `else let fifoReset = wrReset; `endif `ifdef XilinxUltrascale parameter DEVICE = "ULTRASCALE"; `else parameter DEVICE = "7SERIES"; `endif parameter DATA_WIDTH = valueOf(data_width); parameter FIFO_SIZE = fifo_size; `ifndef SIMULATION parameter FIRST_WORD_FALL_THROUGH = "TRUE"; // not supported by xsim `else parameter FIRST_WORD_FALL_THROUGH = True; `endif default_clock wrClock(WRCLK) = wrClock; no_reset; // RST is asynchronous input_reset wrReset(RST) clocked_by(no_clock) = fifoReset; input_clock rdClock(RDCLK) = rdClock; method EMPTY empty() clocked_by (rdClock) reset_by (wrReset); method FULL full() clocked_by (wrClock) reset_by (wrReset); method din(DI) enable ((*inhigh*)EN_di) clocked_by (wrClock) reset_by (wrReset); method wren(WREN) enable ((*inhigh*)EN_wren) clocked_by (wrClock) reset_by (wrReset); method DO dout() clocked_by (rdClock) reset_by (wrReset); method rden(RDEN) enable ((*inhigh*)EN_rden) clocked_by (rdClock) reset_by (wrReset); // wrcount and rdcount ports are needed for xsim method WRCOUNT wrcount() clocked_by (wrClock) reset_by (wrReset); method RDCOUNT rdcount() clocked_by (rdClock) reset_by (wrReset); schedule (empty, full, dout, din, wren, rden, wrcount, rdcount) CF (empty, full, dout, din, wren, rden, wrcount, rdcount); endmodule module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t)) provisos (Bits#(t,sizet), Add#(1,a__,sizet)); String fifo_size = "18Kb"; Vector#(TDiv#(sizet,36),X7FifoSyncMacro#(36)) fifos <- replicateM(vmkBramFifo(fifo_size, srcClock, srcReset, dstClock, dstReset)); Wire#(Bit#(1)) rdenWire <- mkDWire(0, clocked_by dstClock, reset_by dstReset); Wire#(Bit#(1)) wrenWire <- mkDWire(0, clocked_by srcClock, reset_by srcReset); Vector#(TDiv#(sizet,36),Wire#(Bit#(36))) dinWires <- replicateM(mkDWire(0, clocked_by srcClock, reset_by srcReset)); for (Integer i = 0; i < valueOf(TDiv#(sizet,36)); i = i+1) begin Reg#(Bit#(9)) rdcount <- mkReg(0, clocked_by dstClock, reset_by dstReset); Reg#(Bit#(9)) wrcount <- mkReg(0, clocked_by srcClock, reset_by srcReset); rule rdenRule; fifos[i].rden(rdenWire); endrule rule wrenRule; fifos[i].wren(wrenWire); endrule rule inputs; fifos[i].din(dinWires[i]); endrule rule countrds; rdcount <= fifos[i].rdcount(); endrule rule countwrs; wrcount <= fifos[i].wrcount(); endrule end function Bool fifoNotEmpty(X7FifoSyncMacro#(36) f); return f.empty == 0; endfunction function Bool fifoNotFull(X7FifoSyncMacro#(36) f); return f.full == 0; endfunction method t first() if (all(fifoNotEmpty, fifos)); function Bit#(36) fifoFirst(Integer i); return fifos[i].dout(); endfunction Vector#(TDiv#(sizet,36), Bit#(36)) v = genWith(fifoFirst); return unpack(truncateNP(pack(v))); endmethod method Action deq() if (all(fifoNotEmpty, fifos)); rdenWire <= 1; endmethod method notEmpty = all(fifoNotEmpty, fifos); method Action enq(t v) if (all(fifoNotFull, fifos)); Vector#(TDiv#(sizet,36), Bit#(36)) vs = unpack(extendNP(pack(v))); Vector#(TDiv#(sizet,36), Integer) indices = genVector(); function Action fifoEnq(Integer i); action dinWires[i] <= vs[i]; endaction endfunction mapM_(fifoEnq, indices); wrenWire <= 1; endmethod method notFull = all(fifoNotEmpty, fifos); endmodule module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t)) provisos (Bits#(t,sizet), Add#(1,a__,sizet)); let syncFifo <- mkDualClockBramFIFOF(srcClock, srcReset, dstClock, dstReset); method enq = syncFifo.enq; method deq = syncFifo.deq; method first = syncFifo.first; endmodule `else // compatibility mode module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t)) provisos (Bits#(t,sizet), Add#(1,a__,sizet)); let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock); method enq = syncFifo.enq; method deq = syncFifo.deq; method first = syncFifo.first; method notFull = syncFifo.notFull; method notEmpty = syncFifo.notEmpty; endmodule module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t)) provisos (Bits#(t,sizet), Add#(1,a__,sizet)); let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock); method enq = syncFifo.enq; method deq = syncFifo.deq; method first = syncFifo.first; endmodule `endif ================================================ FILE: bsv/ConnectalClocks.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; `include "ConnectalProjectConfig.bsv" `ifdef PcieClockPeriod Real pcieClockPeriod = `PcieClockPeriod; `endif Real mainClockPeriod = `MainClockPeriod; Real derivedClockPeriod =`DerivedClockPeriod; (* always_ready, always_enabled *) interface B2C; interface Clock c; interface Reset r; method Action inputclock(Bit#(1) v); method Action inputreset(Bit#(1) v); endinterface import "BVI" CONNECTNET2 = module mkB2C(B2C); default_clock no_clock; default_reset no_reset; output_clock c(OUT1); output_reset r(OUT2); method inputclock(IN1) enable((*inhigh*) en_inputclock) clocked_by(c); method inputreset(IN2) enable((*inhigh*) en_inputreset) clocked_by(c); schedule ( inputclock, inputreset) CF ( inputclock, inputreset); endmodule (* always_ready, always_enabled *) interface B2C1; interface Clock c; method Action inputclock(Bit#(1) v); endinterface import "BVI" CONNECTNET = module mkB2C1(B2C1); default_clock clk(); default_reset rst(); output_clock c(OUT); // method inputclock(IN) enable((*inhigh*) en_inputclock); method inputclock(IN) enable((*inhigh*) en_inputclock) clocked_by(c); schedule ( inputclock) CF ( inputclock); endmodule (* always_ready, always_enabled *) interface C2B; method Bit#(1) o(); endinterface import "BVI" CONNECTNET = module mkC2B#(Clock c)(C2B); default_clock clk(); default_reset no_reset; //default_reset rst(); input_clock ck(IN) = c; method OUT o(); schedule ( o) CF ( o); endmodule (* always_ready, always_enabled *) interface B2R; interface Reset r; method Action inputreset(Bit#(1) v); endinterface import "BVI" CONNECTNET = module mkB2R(B2R); default_clock clk(); default_reset rst(); output_reset r(OUT); method inputreset(IN) enable((*inhigh*) en_inputclock); schedule ( inputreset) CF ( inputreset); endmodule (* always_ready, always_enabled *) interface R2B; method Bit#(1) o(); endinterface import "BVI" CONNECTNET = module mkR2B#(Reset r)(C2B); default_clock no_clock; default_reset no_reset; //default_reset rst(); input_reset rst(IN) = r; method OUT o(); schedule ( o) CF ( o); endmodule interface PositiveReset; interface Reset positiveReset; endinterface import "BVI" PositiveReset = module mkPositiveReset#(Integer resetDelay, Reset reset, Clock clock)(PositiveReset); parameter RSTDELAY = resetDelay; default_clock clock(CLK) = clock; default_reset reset(IN_RST) clocked_by (no_clock) = reset; output_reset positiveReset(OUT_RST); endmodule interface FpgaReset; interface Reset fpgaReset; endinterface import "BVI" FpgaReset = module exposeFpgaReset#(Integer resetDelay, Clock clock)(FpgaReset); parameter RSTDELAY = resetDelay; default_clock clock(CLK) = clock; no_reset; output_reset fpgaReset(OUT_RST); endmodule ================================================ FILE: bsv/ConnectalCompletionBuffer.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // BSV Libraries import BRAMFIFO::*; import FIFO::*; import FIFOF::*; import Vector::*; import GetPut::*; import ClientServer::*; import Assert::*; import BRAM::*; import RegFile::*; // CONNECTAL Libraries import ConnectalMemTypes::*; import ConnectalMemory::*; import ConfigCounter::*; interface TagGen#(numeric type numTags); method ActionValue#(Bit#(TLog#(numTags))) getTag; method Action returnTag(Bit#(TLog#(numTags)) tag); method ActionValue#(Bit#(TLog#(numTags))) complete; endinterface module mkTagGen(TagGen#(numTags)) provisos(Log#(numTags,tsz)); BRAM_Configure cfg = defaultValue; cfg.outFIFODepth = 1; //BRAM2Port#(Bit#(tsz),Bool) tags <- mkBRAM2Server(cfg); //Vector#(numTags, Reg#(Bool)) tags <- replicateM(mkReg(False)); Reg#(Bit#(numTags)) tags[2] <- mkCReg(2, 0); Reg#(Bit#(tsz)) head_ptr <- mkReg(0); Reg#(Bit#(tsz)) tail_ptr <- mkReg(0); Reg#(Bool) inited <- mkReg(False); FIFO#(Bit#(tsz)) comp_fifo <- mkFIFO; Reg#(Bit#(numTags)) comp_state <- mkReg(0); ConfigCounter#(TAdd#(tsz,1)) counter <- mkConfigCounter(fromInteger(valueOf(numTags))); let retFifo <- mkFIFO; let tagFifo <- mkFIFO; //rule complete_rule0 (comp_state[0] != 0); //tags.portB.request.put(BRAMRequest{write:False, address:tail_ptr, datain: ?, responseOnWrite: ?}); //endrule rule complete_rule1 (comp_state[0] != 0); //let rv <- tags.portB.response.get; //let rv = tags[tail_ptr]; let rv = tags[1][tail_ptr] == 1; if (!rv) begin tail_ptr <= tail_ptr+1; counter.increment(1); comp_state <= comp_state >> 1; comp_fifo.enq(tail_ptr); end endrule // this used to be in the body of returnTag, but form some reason bsc does not // consider access to portA and portB to be conflict free **sigh** (* descending_urgency = "ret_rule, complete_rule1" *) rule ret_rule; let tag <- toGet(retFifo).get; //tags.portB.request.put(BRAMRequest{write:True, responseOnWrite:False, address:tag, datain:False}); //tags[tag] <= False; begin let t = tags[0]; t[tag] = 0; tags[0] <= t; end comp_state <= 1 | (comp_state << 1); endrule rule init_rule(!inited); //tags.portA.request.put(BRAMRequest{write:True,address:head_ptr,responseOnWrite:False,datain:False}); //Not needed: tags[head_ptr] <= False; head_ptr <= head_ptr+1; inited <= head_ptr+1==0; endrule rule tag_rule if (inited && counter.positive); //tags.portA.request.put(BRAMRequest{write:True, responseOnWrite:False, address:head_ptr, datain:True}); //tags[head_ptr] <= True; begin let t = tags[1]; t[head_ptr] = 1; tags[1] <= t; end head_ptr <= head_ptr+1; tagFifo.enq(head_ptr); counter.decrement(1); endrule method ActionValue#(Bit#(tsz)) getTag(); let tag <- toGet(tagFifo).get(); return tag; endmethod method Action returnTag(Bit#(tsz) tag) if (inited); retFifo.enq(tag); endmethod method ActionValue#(Bit#(tsz)) complete; comp_fifo.deq; return comp_fifo.first; endmethod endmodule ================================================ FILE: bsv/ConnectalConfig.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" `ifndef DataBusWidth `define DataBusWidth 64 `endif // typedef TDiv#(TMax#(128,DataBusWidth),8) TlpDataBytes; // typedef TDiv#(TMax#(128,DataBusWidth),32) TlpDataWords; typedef TDiv#(128,8) TlpDataBytes; typedef TDiv#(128,32) TlpDataWords; typedef `PhysAddrWidth PhysAddrWidth; typedef `SlaveDataBusWidth SlaveDataBusWidth; typedef `DataBusWidth DataBusWidth; typedef `NumberOfMasters NumberOfMasters; typedef `SlaveControlAddrWidth SlaveControlAddrWidth; typedef `NumberOfUserTiles NumberOfUserTiles; typedef TAdd#(`NumberOfUserTiles,1) NumberOfTiles; `ifndef NumReadClients typedef 2 NumReadClients; `else typedef `NumReadClients NumReadClients; `endif `ifndef NumWriteClients typedef 2 NumWriteClients; `else typedef `NumWriteClients NumWriteClients; `endif //typedef `PinType TileExtType; //typedef `PinType PinType; typedef 16 MaxNumberOfPortals; `ifdef PcieLanes typedef `PcieLanes PcieLanes; `endif ================================================ FILE: bsv/ConnectalEHR.bsv ================================================ // Copyright (C) 2012 Muralidaran Vijayaraghavan // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Comments: This EHR design generates the following scheduling constraints (forall i): forall j >= i, r[i] < w[j] forall j < i, r[i] > w[j] forall j > i, w[i] < w[j] w[i] conflicts with w[i] forall j, r[i] is conflict free with r[j] */ import Vector::*; import RWire::*; typedef Vector#(n, Reg#(t)) Ehr#(numeric type n, type t); module mkEhr#(t init)(Ehr#(n, t)) provisos(Bits#(t, tSz)); Vector#(n, RWire#(t)) lat <- replicateM(mkUnsafeRWire); Vector#(n, Reg#(Bool)) dummy2 <- replicateM(mkReg(True)); Reg#(t) rl <- mkReg(init); rule canon; t upd = rl; for(Integer i = 0; i < valueOf(n); i = i + 1) if(lat[i].wget matches tagged Valid .x) upd = x; rl <= upd; endrule function Reg#(t) genEhr(Integer i); return (interface Reg; method Action _write(t x); lat[i].wset(x); dummy2[i] <= True; endmethod method t _read; t upd = rl; Bool yes = True; for(Integer j = i; j < valueOf(n); j = j + 1) yes = yes && dummy2[j]; for(Integer j = 0; j < i; j = j + 1) begin if(lat[j].wget matches tagged Valid .x) upd = x; end return yes? upd : ?; endmethod endinterface); endfunction Ehr#(n, t) r = genWith(genEhr); return r; endmodule ================================================ FILE: bsv/ConnectalFIFO.bsv ================================================ // Copyright (C) 2012 // Arvind // Muralidaran Vijayaraghavan // Jamey Hicks changed interface to FIFOF // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import FIFOF::*; import ConnectalEHR::*; // This Fifo2 <- mkCFFifo generates a two element FIFO where enq and deq are conflict free // {notEmpty, first} < deq < clear < canon // notFull < enq < clear < canon // deq conflict free with enq module mkCFFIFOF(FIFOF#(t)) provisos(Bits#(t, tSz)); Ehr#(3, t) da <- mkEhr(?); Ehr#(3, Bool) va <- mkEhr(False); Ehr#(3, t) db <- mkEhr(?); Ehr#(3, Bool) vb <- mkEhr(False); rule canon if(vb[2] && !va[2]); da[2] <= db[2]; va[2] <= True; vb[2] <= False; endrule method Bool notFull = !vb[0]; method Action enq(t x) if(!vb[0]); db[0] <= x; vb[0] <= True; endmethod method Bool notEmpty = va[0]; method Action deq if (va[0]); va[0] <= False; endmethod method t first if(va[0]); return da[0]; endmethod method Action clear; vb[1] <= False; va[1] <= False; endmethod endmodule ================================================ FILE: bsv/ConnectalMMU.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // BSV Libraries import RegFile::*; import FIFO::*; import FIFOF::*; import Vector::*; import GetPut::*; import Connectable::*; import BRAMFIFO::*; import BRAM::*; import Probe::*; import ConnectalBram::*; import ConnectalMemTypes::*; import StmtFSM::*; import ClientServer::*; import ConnectalConfig::*; import ConnectalMemory::*; import ConnectalCompletionBuffer::*; import Pipe::*; import SimDma::*; `include "ConnectalProjectConfig.bsv" typedef 32 MaxNumSGLists; typedef Bit#(TLog#(MaxNumSGLists)) SGListId; typedef 12 SGListPageShift0; typedef 16 SGListPageShift4; typedef 20 SGListPageShift8; typedef 24 SGListPageShift12; typedef Bit#(TLog#(MaxNumSGLists)) RegionsIdx; typedef 8 IndexWidth; typedef struct { SGListId id; Bit#(MemOffsetSize) off; } AddrTransRequest deriving (Eq,Bits,FShow); typedef struct { DmaErrorType error; Bit#(addrWidth) physAddr; } AddrTransResponse#(numeric type addrWidth) deriving (Eq,Bits,FShow); interface MMU#(numeric type addrWidth); interface MMURequest request; interface Vector#(2,Server#(AddrTransRequest,AddrTransResponse#(addrWidth))) addr; endinterface module mkSimpleMMU#(Bit#(4) mmuid, Bool hostMapped, MMUIndication mmuIndication)(MMU#(addrWidth)) provisos (Add#(b__,8,addrWidth) ,Add#(c__,24,addrWidth) ,Bits#(AddrTransResponse#(addrWidth),d__) ); Vector#(2,FIFOF#(AddrTransRequest)) reqFifos <- replicateM(mkFIFOF()); Vector#(2,FIFOF#(AddrTransResponse#(addrWidth))) respFifos <- replicateM(mkFIFOF()); let probePhysAddr <- mkProbe(); for (Integer i = 0; i < 2; i = i + 1) begin rule rl_process_req; let req <- toGet(reqFifos[i]).get(); Bit#(addrWidth) physAddr = extend(req.off[23:0]); physAddr[31:24] = extend(req.id); probePhysAddr <= physAddr; respFifos[i].enq(AddrTransResponse { error: DmaErrorNone, physAddr: physAddr }); endrule end function Server#(AddrTransRequest,AddrTransResponse#(addrWidth)) genServer(Integer i); return (interface Server#(AddrTransRequest,AddrTransResponse#(addrWidth)); interface request = toPut(reqFifos[i]); interface response = toGet(respFifos[i]); endinterface); endfunction interface MMURequest request; method Action idRequest(SpecialTypeForSendingFd fd); mmuIndication.idResponse(0); endmethod method Action idReturn(Bit#(32) sglId); mmuIndication.idResponse(sglId); endmethod method Action region(Bit#(32) pointer, Bit#(64) barr12, Bit#(32) index12, Bit#(64) barr8, Bit#(32) index8, Bit#(64) barr4, Bit#(32) index4, Bit#(64) barr0, Bit#(32) index0); mmuIndication.configResp(extend(pointer)); endmethod method Action sglist(Bit#(32) pointer, Bit#(32) pointerIndex, Bit#(64) addr, Bit#(32) len); // no response endmethod method Action setInterface(Bit#(32) interfaceId, Bit#(32) sglId); /* this method is only implemented in s/w responders */ endmethod endinterface interface Vector addr = genWith(genServer); endmodule typedef struct { DmaErrorType error; Bit#(3) pageSize; Bit#(SGListPageShift12) value; } Offset deriving (Eq,Bits,FShow); typedef Bit#(TSub#(MemOffsetSize,SGListPageShift0)) Page0; typedef Bit#(TSub#(MemOffsetSize,SGListPageShift4)) Page4; typedef Bit#(TSub#(MemOffsetSize,SGListPageShift8)) Page8; typedef Bit#(TSub#(MemOffsetSize,SGListPageShift12)) Page12; typedef struct { Bit#(TSub#(MemOffsetSize,SGListPageShift0)) barrier; Bit#(IndexWidth) idxOffset; } SingleRegion deriving (Eq,Bits,FShow); typedef struct { SingleRegion reg12; SingleRegion reg8; SingleRegion reg4; SingleRegion reg0; } Region deriving (Eq,Bits,FShow); typedef struct {DmaErrorType errorType; Bit#(32) pref; Bit#(MemOffsetSize) off; } DmaError deriving (Bits); typedef struct { Bool cond12; Bool cond8; Bool cond4; Bool cond0; Bit#(IndexWidth) idxOffset12; Bit#(IndexWidth) idxOffset8; Bit#(IndexWidth) idxOffset4; Bit#(IndexWidth) idxOffset0; AddrTransRequest req; } Stage3Params deriving (Bits); typedef struct { Offset off; Bit#(IndexWidth) pbase; Bit#(IndexWidth) idxOffset; SGListId ptr; } Stage4Params deriving (Bits); // the address translation servers (addr[0], addr[1]) have a latency of 8 and are fully pipelined module mkMMU#(Bit#(4) mmuid, Bool hostMapped, MMUIndication mmuIndication)(MMU#(PhysAddrWidth)) provisos(Log#(MaxNumSGLists, listIdxSize), Add#(listIdxSize,8, entryIdxSize)); let mmu <- mkMMUSynth(mmuid, hostMapped); rule rl_idResponse; let sglId <- toGet(mmu.idResponsePipe).get(); mmuIndication.idResponse(extend(sglId)); endrule rule rl_configResp; let sglId <- toGet(mmu.configResponsePipe).get(); mmuIndication.configResp(extend(sglId)); endrule rule dmaError; let error <- toGet(mmu.errorPipe).get(); mmuIndication.error(extend(pack(error.errorType)), error.pref, extend(error.off), extend(mmuid)); endrule interface request = mmu.request; interface addr = mmu.addr; endmodule interface MMUSynth#(numeric type addrWidth); interface MMURequest request; interface PipeOut#(SGListId) idResponsePipe; interface PipeOut#(SGListId) configResponsePipe; interface PipeOut#(DmaError) errorPipe; interface Vector#(2,Server#(AddrTransRequest,AddrTransResponse#(addrWidth))) addr; endinterface (* synthesize *) module mkMMUSynth#(Bit#(4) mmuid, Bool hostMapped)(MMUSynth#(PhysAddrWidth)); let verbose = False; TagGen#(MaxNumSGLists) sglId_gen <- mkTagGen(); rule complete_sglId_gen; let __x <- sglId_gen.complete; endrule // for simulators SimDma#(32) simDma <- mkSimDma(); // stage 0 (latency == 1) Vector#(2, FIFO#(AddrTransRequest)) incomingReqs <- replicateM(mkFIFO); // stage 1 (latency == 2) BRAM_Configure bramConfig = defaultValue; bramConfig.latency = 2; BRAM2Port#(RegionsIdx, Maybe#(Region)) regall <- ConnectalBram::mkBRAM2Server(bramConfig); Vector#(2,FIFOF#(AddrTransRequest)) reqs0 <- replicateM(mkSizedFIFOF(3)); // stage 2 (latency == 1) Vector#(2, FIFOF#(Stage3Params)) stage3Params <- replicateM(mkFIFOF); // stage 3 (latency == 1) Vector#(2, FIFOF#(Stage4Params)) stage4Params <- replicateM(mkFIFOF); // stage 4 (latency == 2) BRAM2Port#(Bit#(TAdd#(TLog#(MaxNumSGLists),8)),Page0) translationTable <- ConnectalBram::mkBRAM2Server(bramConfig); Vector#(2,FIFOF#(Offset)) offs1 <- replicateM(mkSizedFIFOF(3)); // stage 4 (latnecy == 1) Vector#(2,FIFOF#(AddrTransResponse#(PhysAddrWidth))) pageResponseFifos <- replicateM(mkFIFOF); FIFOF#(DmaError) dmaErrorFifo <- mkFIFOF1(); Vector#(2,FIFO#(DmaError)) dmaErrorFifos <- replicateM(mkFIFO1()); for (Integer i = 0; i < 2; i = i + 1) mkConnection(toGet(dmaErrorFifos[i]), toPut(dmaErrorFifo)); let page_shift0 = fromInteger(valueOf(SGListPageShift0)); let page_shift4 = fromInteger(valueOf(SGListPageShift4)); let page_shift8 = fromInteger(valueOf(SGListPageShift8)); let page_shift12 = fromInteger(valueOf(SGListPageShift12)); function BRAMServer#(a,b) portsel(BRAM2Port#(a,b) x, Integer i); if(i==0) return x.portA; else return x.portB; endfunction for (Integer i = 0; i < 2; i=i+1) begin rule stage1; // first read in the address cutoff values between regions AddrTransRequest req <- toGet(incomingReqs[i]).get(); portsel(regall, i).request.put(BRAMRequest{write:False, responseOnWrite:False, address:truncate(req.id), datain:?}); reqs0[i].enq(req); endrule // pipeline the address lookup rule stage2; // Now compare address cutoffs with requested offset AddrTransRequest req <- toGet(reqs0[i]).get; Maybe#(Region) m_regionall <- portsel(regall,i).response.get; case (m_regionall) matches tagged Valid .regionall: begin Page0 off0 = truncate(req.off >> valueOf(SGListPageShift0)); Page4 off4 = truncate(req.off >> valueOf(SGListPageShift4)); Page8 off8 = truncate(req.off >> valueOf(SGListPageShift8)); Page12 off12 = truncate(req.off >> valueOf(SGListPageShift12)); let cond12 = off12 < truncate(regionall.reg12.barrier); let cond8 = off8 < truncate(regionall.reg8.barrier); let cond4 = off4 < truncate(regionall.reg4.barrier); let cond0 = off0 < regionall.reg0.barrier; if (verbose) $display("mkMMU::stage2: id=%d off=%h (%h %h %h) (%h %h %h)", req.id, req.off, regionall.reg8.barrier, regionall.reg4.barrier, regionall.reg0.barrier, off8, off4, off0); stage3Params[i].enq(Stage3Params {cond12: cond12, cond8: cond8, cond4: cond4, cond0: cond0, idxOffset12: regionall.reg12.idxOffset,idxOffset8: regionall.reg8.idxOffset, idxOffset4: regionall.reg4.idxOffset, idxOffset0: regionall.reg0.idxOffset, req: req }); end tagged Invalid: dmaErrorFifos[0].enq(DmaError { errorType: DmaErrorSGLIdInvalid, pref: extend(req.id), off:req.off }); endcase endrule rule stage3; // Based on results of comparision, select a region, putting it into 'o.pageSize'. idxOffset holds offset in sglist table of relevant entry let params <- toGet(stage3Params[i]).get(); AddrTransRequest req = params.req; Offset o = Offset { error: DmaErrorNone, pageSize: 0, value: truncate(req.off)}; Bit#(IndexWidth) pbase = 0; Bit#(IndexWidth) idxOffset = 0; if (params.cond12) begin if (verbose) $display("mkMMU::request: req.id=%h req.off=%h", req.id, req.off); o.pageSize = 4; pbase = truncate(req.off>>page_shift12); idxOffset = params.idxOffset12; end else if (params.cond8) begin if (verbose) $display("mkMMU::request: req.id=%h req.off=%h", req.id, req.off); o.pageSize = 3; pbase = truncate(req.off>>page_shift8); idxOffset = params.idxOffset8; end else if (params.cond4) begin if (verbose) $display("mkMMU::request: req.id=%h req.off=%h", req.id, req.off); o.pageSize = 2; pbase = truncate(req.off>>page_shift4); idxOffset = params.idxOffset4; end else if (params.cond0) begin if (verbose) $display("mkMMU::request: req.id=%h req.off=%h", req.id, req.off); o.pageSize = 1; pbase = truncate(req.off>>page_shift0); idxOffset = params.idxOffset0; end stage4Params[i].enq(Stage4Params { off: o, pbase: pbase, idxOffset: idxOffset, ptr: req.id }); endrule (* descending_urgency = "stage2, stage4" *) rule stage4; // Read relevant sglist entry let params <- toGet(stage4Params[i]).get(); let off = params.off; let pbase = params.pbase; let idxOffset = params.idxOffset; let ptr = params.ptr; Bit#(IndexWidth) p = pbase + idxOffset; if (off.pageSize == 0) begin if (verbose) $display("mkMMU::addr[%d].request.put: ERROR ptr=%h off=%h\n", i, ptr, off); dmaErrorFifos[1].enq(DmaError { errorType: DmaErrorOffsetOutOfRange, pref: extend(ptr), off:extend(off.value) }); off.error = DmaErrorOffsetOutOfRange; p = 0; // FIXME end if (verbose) $display("mkMMU::translationTable[%d].read %h", i, {ptr,p}); portsel(translationTable, i).request.put(BRAMRequest{write:False, responseOnWrite:False, address:{ptr,p}, datain:?}); offs1[i].enq(off); endrule rule stage5; // Concatenate page base address from sglist entry with LSB offset bits from request and return Page0 page <- portsel(translationTable, i).response.get; let offset <- toGet(offs1[i]).get(); if (verbose) $display("mkMMU::p ages[%d].response page=%h offset=%h", i, page, offset); Bit#(PhysAddrWidth) rv = ?; Page4 b4 = truncate(page); Page8 b8 = truncate(page); Page12 b12 = truncate(page); case (offset.pageSize) 1: rv = {page,truncate(offset.value)}; 2: rv = {b4,truncate(offset.value)}; 3: rv = {b8,truncate(offset.value)}; 4: rv = {b12,truncate(offset.value)}; endcase pageResponseFifos[i].enq(AddrTransResponse { error: offset.error, physAddr: truncate(rv) }); endrule end FIFOF#(SGListId) idResponseFifo <- mkFIFOF1; FIFOF#(SGListId) configResponseFifo <- mkFIFOF1; // given that the BRAM is faster than the connection from software, I see no need for a SizedBRAMFIFOF here. -Jamey FIFOF#(Bit#(32)) idReturnFifo <- mkFIFOF(); rule idReturnRule; let sglId <- toGet(idReturnFifo).get; sglId_gen.returnTag(truncate(sglId)); portsel(regall, 1).request.put(BRAMRequest{write:True, responseOnWrite:False, address: truncate(sglId), datain: tagged Invalid }); $display("idReturn %d", sglId); endrule function Server#(AddrTransRequest,AddrTransResponse#(PhysAddrWidth)) addrServer(Integer i); return (interface Server#(AddrTransRequest,Bit#(PhysAddrWidth)); interface Put request; method Action put(AddrTransRequest req); incomingReqs[i].enq(req); endmethod endinterface interface Get response; method ActionValue#(AddrTransResponse#(PhysAddrWidth)) get(); let rv <- toGet(pageResponseFifos[i]).get(); `ifdef SIMULATION rv.physAddr = rv.physAddr | (extend(mmuid)<>beat_shift)) + unfulfilled.read() < fromInteger(valueOf(bufferDepth))); let req <- toGet(reqOutstanding).get(); unfulfilled.increment(unpack(extend(req.burstLen>>beat_shift))); reqCommitted.enq(req); endrule interface MemReadServer readServer; interface Put readReq = toPut(reqOutstanding); interface Get readData; method ActionValue#(MemData#(dataWidth)) get(); let v <- toGet(readBuffer).get(); unfulfilled.decrement(1); return v; endmethod endinterface: readData endinterface interface MemReadClient readClient; interface Get readReq = toGet(reqCommitted); interface Put readData; method Action put(MemData#(dataWidth) x); readBuffer.enq(x); endmethod endinterface endinterface endmodule interface MemWriter#(numeric type dataWidth); interface MemWriteServer#(dataWidth) writeServer; interface MemWriteClient#(dataWidth) writeClient; endinterface module mkMemWriter(MemWriter#(dataWidth)) provisos(Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift)); FIFOF#(MemData#(dataWidth)) writeBuffer <- mkFIFOF; FIFOF#(MemRequest) reqOutstanding <- mkFIFOF; FIFOF#(Bit#(MemTagSize)) doneTags <- mkFIFOF(); interface MemWriteServer writeServer; interface Put writeReq = toPut(reqOutstanding); interface Put writeData = toPut(writeBuffer); interface Get writeDone = toGet(doneTags); endinterface interface MemWriteClient writeClient; interface Get writeReq = toGet(reqOutstanding); interface Get writeData = toGet(writeBuffer); interface Put writeDone = toPut(doneTags); endinterface endmodule interface MemWriterBuff#(numeric type dataWidth, numeric type bufferDepth); interface MemWriteServer#(dataWidth) writeServer; interface MemWriteClient#(dataWidth) writeClient; endinterface module mkMemWriterBuff(MemWriterBuff#(dataWidth, bufferDepth)) provisos(Log#(bufferDepth,bufferDepthWidth), Max#(TAdd#(bufferDepthWidth,1),BurstLenSize,availableWidth), Add#(a__,BurstLenSize,availableWidth), Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift)); FIFOF#(MemData#(dataWidth)) writeBuffer <- mkSizedBRAMFIFOF(valueOf(bufferDepth)); FIFOF#(MemRequest) reqOutstanding <- mkFIFOF(); FIFOF#(MemRequest) reqCommitted <- mkFIFOF(); FIFOF#(Bit#(MemTagSize)) doneTags <- mkFIFOF(); ConfigCounter#(availableWidth) available <- mkConfigCounter(0); let beat_shift = fromInteger(valueOf(beatShift)); // only issue the writeRequest when sufficient data is available. This includes the data we have already comitted. rule commitReq if (unpack(extend(reqOutstanding.first.burstLen>>beat_shift)) <= available.read()); let req <- toGet(reqOutstanding).get(); available.decrement(unpack(extend(req.burstLen>>beat_shift))); reqCommitted.enq(req); endrule interface MemWriteServer writeServer; interface Put writeReq = toPut(reqOutstanding); interface Put writeData; method Action put(MemData#(dataWidth) d); writeBuffer.enq(d); available.increment(1); endmethod endinterface: writeData interface Get writeDone = toGet(doneTags); endinterface interface MemWriteClient writeClient; interface Get writeReq = toGet(reqCommitted); interface Get writeData; method ActionValue#(MemData#(dataWidth)) get(); writeBuffer.deq; return writeBuffer.first; endmethod endinterface interface Put writeDone = toPut(doneTags); endinterface endmodule interface UGBramFifos#(numeric type numFifos, numeric type fifoDepth, type a); method Action enq(Bit#(TLog#(numFifos)) idx, a v); method Action first_req(Bit#(TLog#(numFifos)) idx); method ActionValue#(a) first_resp(); method Action deq(Bit#(TLog#(numFifos)) idx); method Action upd_head(Bit#(TLog#(numFifos)) idx, a v); endinterface module mkUGBramFifos(UGBramFifos#(numFifos,fifoDepth,a)) provisos(Mul#(fifoDepth,numFifos,buffSz), Log#(buffSz, buffAddrSz), Add#(a__, TLog#(numFifos), TAdd#(1, buffAddrSz)), Bits#(a,b__)); function Bit#(buffAddrSz) hf(Integer i) = fromInteger(i*valueOf(fifoDepth)); Vector#(numFifos, Reg#(Bit#(buffAddrSz))) head <- mapM(mkReg, genWith(hf)); Vector#(numFifos, Reg#(Bit#(buffAddrSz))) tail <- mapM(mkReg, genWith(hf)); BRAM2Port#(Bit#(buffAddrSz),a) buff <- mkBRAM2Server(defaultValue); let fifo_depth = fromInteger(valueOf(fifoDepth)); method Action enq(Bit#(TLog#(numFifos)) idx, a v); buff.portB.request.put(BRAMRequest{write:True, responseOnWrite:False, address:tail[idx], datain:v}); Bit#(TAdd#(1,buffAddrSz)) nt = extend(tail[idx])+1; Bit#(TAdd#(1,buffAddrSz)) li = (extend(idx)+1)*fifo_depth; Bit#(TAdd#(1,buffAddrSz)) rs = (extend(idx)+0)*fifo_depth; if (nt >= li) nt = rs; tail[idx] <= truncate(nt); endmethod method Action first_req(Bit#(TLog#(numFifos)) idx); buff.portA.request.put(BRAMRequest{write:False, responseOnWrite:False, address:head[idx], datain:?}); endmethod method ActionValue#(a) first_resp(); let v <- buff.portA.response.get; return v; endmethod method Action deq(Bit#(TLog#(numFifos)) idx); Bit#(TAdd#(1,buffAddrSz)) nt = extend(head[idx])+1; Bit#(TAdd#(1,buffAddrSz)) li = (extend(idx)+1)*fifo_depth; Bit#(TAdd#(1,buffAddrSz)) rs = (extend(idx)+0)*fifo_depth; if (nt >= li) nt = rs; head[idx] <= truncate(nt); endmethod method Action upd_head(Bit#(TLog#(numFifos)) idx, a v); buff.portA.request.put(BRAMRequest{write:True, responseOnWrite:False, address:head[idx], datain:v}); endmethod endmodule `ifndef BYTE_ENABLES module mkMemServerFromPhysMemSlave#(PhysMemSlave#(addrWidth,dataWidth) ms)(MemServer#(dataWidth)) provisos (Add#(a__, addrWidth, MemOffsetSize)); interface MemReadServer readServer; interface Put readReq; method Action put(MemRequest req); ms.read_server.readReq.put(PhysMemRequest { addr: truncate(req.offset), burstLen: req.burstLen, `ifdef BYTE_ENABLES firstbe: reqFirstByteEnable(req), lastbe: reqLastByteEnable(req), `endif tag: req.tag }); endmethod endinterface interface Get readData = ms.read_server.readData; endinterface interface MemWriteServer writeServer; interface Put writeReq; method Action put(MemRequest req); ms.write_server.writeReq.put(PhysMemRequest { addr: truncate(req.offset), burstLen: req.burstLen, `ifdef BYTE_ENABLES firstbe: reqFirstByteEnable(req), lastbe: reqLastByteEnable(req), `endif tag: req.tag }); endmethod endinterface interface Put writeData = ms.write_server.writeData; interface Get writeDone = ms.write_server.writeDone; endinterface endmodule `endif // not BYTE_ENABLES ================================================ FILE: bsv/ConnectalMemory.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; import Vector::*; // // Dma channel type // typedef enum { ChannelType_Read, ChannelType_Write } ChannelType deriving (Bits,Eq,FShow); // // @brief Channel Identifier // //typedef Bit#(16) DmaChannelId; typedef struct { Bit#(32) x; Bit#(32) y; Bit#(32) z; Bit#(32) w; } DmaDbgRec deriving(Bits); typedef enum { DmaErrorNone, DmaErrorSGLIdOutOfRange_r, DmaErrorSGLIdOutOfRange_w, DmaErrorMMUOutOfRange_r, DmaErrorMMUOutOfRange_w, DmaErrorOffsetOutOfRange, DmaErrorSGLIdInvalid, DmaErrorTileTagOutOfRange } DmaErrorType deriving (Bits,Eq,FShow); // // @brief Events sent from a Dma engine // interface MemServerIndication; method Action addrResponse(Bit#(64) physAddr); method Action reportStateDbg(DmaDbgRec rec); method Action reportMemoryTraffic(Bit#(64) words); method Action error(Bit#(32) code, Bit#(32) sglId, Bit#(64) offset, Bit#(64) extra); endinterface // // @brief Events sent from a MMU // interface MMUIndication; method Action idResponse(Bit#(32) sglId); method Action configResp(Bit#(32) sglId); method Action error(Bit#(32) code, Bit#(32) sglId, Bit#(64) offset, Bit#(64) extra); endinterface typedef Bit#(32) SpecialTypeForSendingFd; // // @brief Configuration interface to an MMU // interface MMURequest; // // @brief Adds an address translation entry to the scatter-gather list for an object // // @param sglId Specifies the object to be translated // @param addr Physical address of the segment // @param len Length of the segment // method Action sglist(Bit#(32) sglId, Bit#(32) sglIndex, Bit#(64) addr, Bit#(32) len); method Action region(Bit#(32) sglId, Bit#(64) barr12, Bit#(32) index12, Bit#(64) barr8, Bit#(32) index8, Bit#(64) barr4, Bit#(32) index4, Bit#(64) barr0, Bit#(32) index0); method Action idRequest(SpecialTypeForSendingFd fd); method Action idReturn(Bit#(32) sglId); method Action setInterface(Bit#(32) interfaceId, Bit#(32) sglId); endinterface typedef enum { Idle, Stopped, Running } TileState deriving (Bits,Eq); typedef struct { Bit#(2) tile; TileState state; } TileControl deriving (Bits); // // @brief Control interface to Dma engine // interface MemServerRequest; // @brief Requests an address translation // method Action addrTrans(Bit#(32) sglId, Bit#(32) offset); // @brief Changes tile status // method Action setTileState(TileControl tc); // // @brief Requests debug info for the specified channel type // method Action stateDbg(ChannelType rc); method Action memoryTraffic(ChannelType rc); endinterface ================================================ FILE: bsv/ConnectalMimo.bsv ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2012 Bluespec, Inc. ALL RIGHTS RESERVED. // $Revision: 32844 $ // $Date: 2013-12-16 16:39:44 +0000 (Mon, 16 Dec 2013) $ //////////////////////////////////////////////////////////////////////////////// // Filename : MIMO.bsv // Description : Multiple-In Multiple-Out //////////////////////////////////////////////////////////////////////////////// package ConnectalMimo; // Notes : // - This module works like a FIFO, but for arbitrary amounts of the base object type. // - The clear method overrides the effects of enq and deq. //////////////////////////////////////////////////////////////////////////////// /// Imports //////////////////////////////////////////////////////////////////////////////// import Vector ::*; import DefaultValue ::*; import BUtils ::*; import FIFO ::*; import FIFOF ::*; import BRAMFIFO ::*; import Counter ::*; import Clocks ::*; import MIMO ::*; import ConnectalBramFifo ::*; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation of BRAM based version /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// module mkMIMOBram#(MIMOConfiguration cfg)(MIMO#(max_in, max_out, size, t)) provisos ( Bits#(t, st) // object must have bit representation , Add#(__f, 1, st) // object is at least 1 byte in size , Add#(2, __a, size) // must have at least 2 elements of storage , Add#(__b, max_in, size) // the max enqueued amount must be less than or equal to the full storage , Add#(__c, max_out, size) // the max dequeued amount must be less than or equal to the full storage , Mul#(st, size, total) // total bits of storage , Mul#(st, max_in, intot) // total bits to be enqueued , Mul#(st, max_out, outtot) // total bits to be dequeued , Add#(__d, outtot, total) // make sure the number of dequeue bits is not larger than the total storage , Max#(max_in, max_out, max) // calculate the max width of the memories , Div#(size, max, em1) // calculate the number of entries for each memory required , Add#(em1, 1, e) , Add#(__e, max_out, max) ); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Vector#(max, FIFOF#(t)) vfStorage <- replicateM(mkDualClockBramFIFOF(clock, reset, clock, reset)); Counter#(32) rDataCount <- mkCounter(0); Reg#(LUInt#(max)) rWriteIndex <- mkReg(0); Reg#(LUInt#(max)) rReadIndex <- mkReg(0); Vector#(max, RWire#(Bool)) vrwDeqFifo <- replicateM(mkRWire); Vector#(max, RWire#(t)) vrwEnqFifo <- replicateM(mkRWire); RWire#(LUInt#(size)) rwDeqCount <- mkRWire; RWire#(LUInt#(size)) rwEnqCount <- mkRWire; RWire#(Bit#(intot)) rwEnqData <- mkRWire; PulseWire pwClear <- mkPulseWire; //////////////////////////////////////////////////////////////////////////////// /// Functions //////////////////////////////////////////////////////////////////////////////// function t getFirst(FIFOF#(t) ifc); return ifc.first(); endfunction function Action doEnq(Bool doit, FIFOF#(t) ifc, t datain); action if (doit) ifc.enq(datain); endaction endfunction function Action doDeq(Bool doit, FIFOF#(t) ifc); action if (doit) ifc.deq(); endaction endfunction function Vector#(max, Bool) createMask(LUInt#(max) count); Bit#(max) v = (1 << count) - 1; return unpack(v); endfunction function Vector#(v, el) rotateRBy(Vector#(v, el) vect, UInt#(logv) n) provisos(Log#(v, logv)); return reverse(rotateBy(reverse(vect), n)); endfunction //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// Rules d = rules (* aggressive_implicit_conditions *) rule dequeue if (rwDeqCount.wget matches tagged Valid .dcount); Vector#(max, Bool) deqDoIt = rotateBy(createMask(cExtend(dcount)), cExtend(rReadIndex)); for(Integer i = 0; i < valueOf(max); i = i + 1) begin if (deqDoIt[i]) vrwDeqFifo[i].wset(True); end rDataCount.dec(cExtend(dcount)); UInt#(32) ridx = cExtend(rReadIndex); UInt#(32) dcnt = cExtend(dcount); if ((ridx + dcnt) >= fromInteger(valueOf(max))) rReadIndex <= rReadIndex - fromInteger(valueOf(max)) + cExtend(dcount); else rReadIndex <= rReadIndex + cExtend(dcount); endrule (* aggressive_implicit_conditions *) rule enqueue if (rwEnqCount.wget matches tagged Valid .ecount &&& rwEnqData.wget matches tagged Valid .edata ); Vector#(max, t) enqData = rotateBy(unpack(cExtend(edata)), cExtend(rWriteIndex)); Vector#(max, Bool) enqDoIt = rotateBy(createMask(cExtend(ecount)), cExtend(rWriteIndex)); for(Integer i = 0; i < valueOf(max); i = i + 1) begin if (enqDoIt[i]) vrwEnqFifo[i].wset(enqData[i]); end rDataCount.inc(cExtend(ecount)); UInt#(32) widx = cExtend(rWriteIndex); UInt#(32) ecnt = cExtend(ecount); if ((widx + ecnt) >= fromInteger(valueOf(max))) rWriteIndex <= rWriteIndex - fromInteger(valueOf(max)) + cExtend(ecount); else rWriteIndex <= rWriteIndex + cExtend(ecount); endrule endrules; Rules re = emptyRules; for(Integer i = 0; i < valueOf(max); i = i + 1) begin re = rJoinConflictFree(re, rules rule enqueue_fifo if (vrwEnqFifo[i].wget matches tagged Valid .enqdata); vfStorage[i].enq(enqdata); endrule endrules ); end Rules rd = emptyRules; for(Integer i = 0; i < valueOf(max); i = i + 1) begin rd = rJoinConflictFree(rd, rules rule dequeue_fifo if (vrwDeqFifo[i].wget matches tagged Valid .*); vfStorage[i].deq(); endrule endrules ); end Rules r = rJoinConflictFree(rd, re); r = rJoin(d, r); r = rJoinPreempts( rules (* fire_when_enabled *) rule clear if (pwClear); function Action getClear(FIFOF#(t) ifc) = ifc.clear(); rDataCount.setF(0); rWriteIndex <= 0; rReadIndex <= 0; joinActions(map(getClear, vfStorage)); endrule endrules, r); addRules(r); //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// method Action enq(LUInt#(max_in) count, Vector#(max_in, t) data) if (cfg.unguarded || (rDataCount.value() < fromInteger(valueOf(size)))); rwEnqCount.wset(cExtend(count)); rwEnqData.wset(pack(data)); endmethod method Vector#(max_out, t) first() if (cfg.unguarded || (rDataCount.value() > 0)); Vector#(max, t) v = newVector; for(Integer i = 0; i < valueOf(max); i = i + 1) begin if (vfStorage[i].notEmpty()) v[i] = vfStorage[i].first(); else v[i] = ?; end return take(rotateRBy(v, cExtend(rReadIndex))); endmethod method Action deq(LUInt#(max_out) count) if (cfg.unguarded || (rDataCount.value() > 0)); LUInt#(size) szcount = cExtend(count); rwDeqCount.wset(szcount); endmethod method Bool enqReady(); return rDataCount.value < fromInteger(valueOf(size)); endmethod method Bool enqReadyN(LUInt#(max_in) count); return (rDataCount.value() + cExtend(count)) <= fromInteger(valueOf(size)); endmethod method Bool deqReady(); return rDataCount.value() > 0; endmethod method Bool deqReadyN(LUInt#(max_out) count); return rDataCount.value() >= cExtend(count); endmethod method LUInt#(size) count(); return cExtend(rDataCount.value()); endmethod method Action clear(); pwClear.send(); endmethod endmodule: mkMIMOBram endpackage: ConnectalMimo ================================================ FILE: bsv/ConnectalPrelude.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. typedef struct { t1 tpl_1; t2 tpl_2; } Tuple2#(type t1, type t2); typedef struct { t1 tpl_1; t2 tpl_2; t3 tpl_3; } Tuple3#(type t1, type t2, type t3); typedef struct { t1 tpl_1; t2 tpl_2; t3 tpl_3; t4 tpl_4; } Tuple4#(type t1, type t2, type t3, type t4); typedef struct { t1 tpl_1; t2 tpl_2; t3 tpl_3; t4 tpl_4; t5 tpl_5; } Tuple5#(type t1, type t2, type t3, type t4, type t5); ================================================ FILE: bsv/ConnectalXilinxCells.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks :: *; import DefaultValue :: *; import XilinxCells :: *; import Vector :: *; `include "ConnectalProjectConfig.bsv" // interface ResetIBUF; // interface Reset reset; // endinterface import "BVI" IBUF = module mkResetIBUF#(Reset inReset)(ResetGenIfc);// provisos(Bits#(one_bit,1)); // default_clock clk(); // default_reset rstn(); default_clock no_clock; // default_reset no_reset; input_reset inReset(I) = inReset; output_reset gen_rst(O) clocked_by(no_clock); // port I = i; // method O _read; // path(I, O); // // path(IB, O); // schedule _read CF _read; endmodule: mkResetIBUF import "BVI" IBUFDS = module mkIBUFDS#(Wire#(one_bit) i, Wire#(one_bit) ib)(ReadOnly#(one_bit)) provisos(Bits#(one_bit,1)); default_clock clk(); default_reset rstn(); parameter CAPACITANCE = "DONT_CARE"; parameter DIFF_TERM = 1; parameter IBUF_DELAY_VALUE = 0; parameter IFD_DELAY_VALUE = "AUTO"; parameter IOSTANDARD = "DEFAULT"; port I = i; port IB = ib; method O _read; path(I, O); path(IB, O); schedule _read CF _read; endmodule: mkIBUFDS import "BVI" IBUFDS = module vMkConnectalClockIBUFDS#(Wire#(one_bit) i, Wire#(one_bit) ib)(ClockGenIfc) provisos(Bits#(one_bit,1)); default_clock clk(); default_reset rstn(); parameter CAPACITANCE = "DONT_CARE"; parameter DIFF_TERM = 1; parameter IBUF_DELAY_VALUE = 0; parameter IFD_DELAY_VALUE = "AUTO"; parameter IOSTANDARD = "DEFAULT"; port I = i; port IB = ib; //method O _read; output_clock gen_clk(O); path(I, O); path(IB, O); //schedule _read CF _read; endmodule: vMkConnectalClockIBUFDS module mkConnectalClockIBUFDS#(Wire#(one_bit) i, Wire#(one_bit) ib)(Clock) provisos(Bits#(one_bit,1)); let _m <- vMkConnectalClockIBUFDS(i, ib); return _m.gen_clk; endmodule: mkConnectalClockIBUFDS interface DiffPair; method Bit#(1) p; method Bit#(1) n; endinterface import "BVI" OBUFDS = module vMkOBUFDS#(Bit#(1) i)(DiffPair); default_clock clk(); default_reset reset(); port I = i; method O p; method OB n; path(I, O); path(I, OB); schedule (p, n) CF (p, n); endmodule: vMkOBUFDS module mkOBUFDS#(Bit#(1) i)(DiffPair); let _m <- vMkOBUFDS(i); return _m; endmodule: mkOBUFDS import "BVI" IBUFDS_GTE2 = module vMkConnectalClockIBUFDS_GTE2#(Bool enable, Wire#(one_bit) i, Wire#(one_bit) ib)(ClockGenIfc) provisos(Bits#(one_bit,1)); default_clock clk(); default_reset rstn(); port CEB = pack(!enable); port I = i; port IB = ib; //method O _read; output_clock gen_clk(O); //output_clock gen_clk2(ODIV2); path(I, O); path(IB, O); //path(I, ODIV2); //path(IB, ODIV2); endmodule: vMkConnectalClockIBUFDS_GTE2 module mkConnectalClockIBUFDS_GTE2#(Bool enable, Wire#(one_bit) i, Wire#(one_bit) ib)(Clock) provisos(Bits#(one_bit,1)); let _m <- vMkConnectalClockIBUFDS_GTE2(enable, i, ib); return _m.gen_clk; endmodule: mkConnectalClockIBUFDS_GTE2 interface GTE2ClockGenIfc; interface Clock gen_clk; interface Clock gen_clk2; endinterface import "BVI" IBUFDS_GTE2 = module vMkClockIBUFDS_GTE2#(IBUFDS_GTE2Params params, Bool enable, Clock clk_p, Clock clk_n)(GTE2ClockGenIfc); default_clock no_clock; default_reset no_reset; input_clock clk_p(I) = clk_p; input_clock clk_n(IB) = clk_n; port CEB = pack(!enable); output_clock gen_clk(O); output_clock gen_clk2(ODIV2); parameter CLKCM_CFG = params.clkcm_cfg; parameter CLKRCV_TRST = params.clkrcv_trst; parameter CLKSWING_CFG = (Bit#(2))'(params.clkswing_cfg); path(I, O); path(IB, O); path(I, ODIV2); path(IB, ODIV2); same_family(clk_p, gen_clk); endmodule: vMkClockIBUFDS_GTE2 import "BVI" IBUFDS_GTE3 = module vMkClockIBUFDS_GTE3#(IBUFDS_GTE2Params params, Bool enable, Clock clk_p, Clock clk_n)(GTE2ClockGenIfc); default_clock no_clock; default_reset no_reset; parameter REFCLK_HROW_CK_SEL = 0; // choose ODIV2 output same as O input_clock clk_p(I) = clk_p; input_clock clk_n(IB) = clk_n; port CEB = pack(!enable); output_clock gen_clk(O); output_clock gen_clk2(ODIV2); path(I, O); path(IB, O); path(I, ODIV2); path(IB, ODIV2); same_family(clk_p, gen_clk); same_family(clk_p, gen_clk2); endmodule: vMkClockIBUFDS_GTE3 import "BVI" IBUFDS_GTE4 = module vMkClockIBUFDS_GTE4#(IBUFDS_GTE2Params params, Bool enable, Clock clk_p, Clock clk_n)(GTE2ClockGenIfc); default_clock no_clock; default_reset no_reset; parameter REFCLK_HROW_CK_SEL = 0; // choose ODIV2 output same as O input_clock clk_p(I) = clk_p; input_clock clk_n(IB) = clk_n; port CEB = pack(!enable); output_clock gen_clk(O); output_clock gen_clk2(ODIV2); path(I, O); path(IB, O); path(I, ODIV2); path(IB, ODIV2); same_family(clk_p, gen_clk); same_family(clk_p, gen_clk2); endmodule: vMkClockIBUFDS_GTE4 module mkClockIBUFDS_GTE#(IBUFDS_GTE2Params params, Bool enable, Clock clk_p, Clock clk_n)(GTE2ClockGenIfc); `ifdef XilinxUltrascalePlus let _m <- vMkClockIBUFDS_GTE4(params, enable, clk_p, clk_n); `else `ifdef XilinxUltrascale let _m <- vMkClockIBUFDS_GTE3(params, enable, clk_p, clk_n); `else let _m <- vMkClockIBUFDS_GTE2(params, enable, clk_p, clk_n); `endif `endif return _m; endmodule: mkClockIBUFDS_GTE import "BVI" OBUFT = module mkOBUFT#(ReadOnly#(one_bit) i, ReadOnly#(oneb_bit) t)(ReadOnly#(onec_bit)) provisos(Bits#(one_bit,1), Bits#(oneb_bit,1), Bits#(onec_bit,1)); default_clock clk(); default_reset rstn(); port I = i; port T = t; method O _read; path(I, O); path(T, O); schedule _read CF _read; endmodule: mkOBUFT typedef struct { String cinvctrl_sel; // "TRUE" to enable dynamic clock inversion, "FALSE" otherwise String delay_src; // "IDATAIN" or "DATAIN" String high_performance_mode; // "TRUE" to reduce jitter, "FALSE" to reduce power String idelay_type; // "FIXED", "VAR_LOAD", or "VAR_LOAD_PIPE" Integer idelay_value; // 0-31 input delay tap setting String pipe_sel; // "TRUE" to select pipelined mode Integer refclk_frequency; // idelayctrl clock input freq in MHz String signal_pattern; // "DATA" or "CLOCK" input signal } IDELAYE2_Config; instance DefaultValue#(IDELAYE2_Config); defaultValue = IDELAYE2_Config { cinvctrl_sel: "FALSE", delay_src: "IDATAIN", high_performance_mode: "FALSE", idelay_type: "FIXED", idelay_value: 0, pipe_sel: "FALSE", refclk_frequency: 200, signal_pattern: "DATA" }; endinstance (* always_ready, always_enabled *) interface IdelayE2; method Bit#(5) cntvalueout(); method Action cinvctrl(Bit#(1) v); method Action cntvaluein(Bit#(5) v); method Action ld(Bit#(1) v); method Action ldpipeen(Bit#(1) v); method Action inc(Bool inc); method Action ce(Bit#(1) v); method Action datain(Bit#(1) v); method Action idatain(Bit#(1) v); method Action reset(Bit#(1) v); method Bit#(1) dataout(); endinterface import "BVI" IDELAYE2 = module mkIDELAYE2#(IDELAYE2_Config cfg, Clock serdes_clock)(IdelayE2); default_clock clk(C); //default_reset rst(REGRST); no_reset; input_clock serdes ()= serdes_clock; parameter CINVCTRL_SEL = cfg.cinvctrl_sel; parameter DELAY_SRC = cfg.delay_src; parameter HIGH_PERFORMANCE_MODE = cfg.high_performance_mode; parameter IDELAY_TYPE = cfg.idelay_type; parameter IDELAY_VALUE = cfg.idelay_value; parameter PIPE_SEL = cfg.pipe_sel; parameter REFCLK_FREQUENCY = cfg.refclk_frequency; parameter SIGNAL_PATTERN = cfg.signal_pattern; method CNTVALUEOUT cntvalueout(); method cinvctrl(CINVCTRL) enable((*inhigh*) en0); method cntvaluein(CNTVALUEIN) enable((*inhigh*) en1); method ld(LD) enable((*inhigh*) en20); // is LDPIPEEN the enable for DATAIN? method ldpipeen(LDPIPEEN) enable((*inhigh*) en21); method DATAOUT dataout(); method inc(INC) enable((*inhigh*) en5); method ce(CE) enable((*inhigh*) en4); method reset(REGRST) enable((*inhigh*) en7); method datain(DATAIN) enable((*inhigh*) en2); method idatain(IDATAIN) enable((*inhigh*) en3) clocked_by(serdes); schedule (datain, idatain, inc, ce) CF (datain, idatain, inc, ce); schedule (reset, cntvalueout, dataout, ld, datain, ldpipeen, inc, cinvctrl, cntvaluein, ce, idatain) CF (reset, cntvalueout, dataout, ld, datain, ldpipeen, inc, cinvctrl, cntvaluein, ce, idatain); endmodule //////////////////////////////////////////////////////////// typedef struct { String data_rate; Integer data_width; String dyn_clk_inv_en; String dyn_clkdiv_inv_en; Integer init_q1; Integer init_q2; Integer init_q3; Integer init_q4; String interface_type; String iobdelay; Integer num_ce; String ofb_used; String serdes_mode; Integer srval_q1; Integer srval_q2; Integer srval_q3; Integer srval_q4; } ISERDESE2_Config; instance DefaultValue#(ISERDESE2_Config); defaultValue = ISERDESE2_Config { data_rate: "DDR", data_width: 8, dyn_clk_inv_en: "FALSE", dyn_clkdiv_inv_en: "FALSE", init_q1: 0, init_q2: 0, init_q3: 0, init_q4: 0, interface_type: "NETWORKING", iobdelay: "IBUF", num_ce: 1, ofb_used: "FALSE", serdes_mode: "MASTER", srval_q1: 0, srval_q2: 0, srval_q3: 0, srval_q4: 0 }; endinstance (* always_ready, always_enabled *) interface IserdesE2; (* prefix = "" *) method Action d(Bit#(1) d); method Bit#(1) o(); method Action bitslip(Bit#(1) bitslip); method Action ce1(Bit#(1) ce1); method Action ce2(Bit#(1) ce2); method Action ddly(Bit#(1) ddly); method Action shiftin1(Bit#(1) shiftin1); method Action shiftin2(Bit#(1) shiftin2); method Bit#(1) q1(); method Bit#(1) q2(); method Bit#(1) q3(); method Bit#(1) q4(); method Bit#(1) q5(); method Bit#(1) q6(); method Bit#(1) q7(); method Bit#(1) q8(); method Bit#(1) shiftout1(); method Bit#(1) shiftout2(); method Action ofb(Bit#(1) ofb); method Action dynclkdivsel(Bit#(1) dynclkdivsel); method Action dynclksel(Bit#(1) dynclksel); method Action oclk(Bit#(1) v); method Action oclkb(Bit#(1) v); method Action reset(Bit#(1) d); endinterface import "BVI" ISERDESE2 = module mkISERDESE2#(ISERDESE2_Config cfg, Clock clk, Clock clkb)(IserdesE2); input_clock clk(CLK) = clk; input_clock clkb(CLKB) = clkb; default_clock clkdiv(CLKDIV); no_reset; parameter DATA_RATE = cfg.data_rate; parameter DATA_WIDTH = cfg.data_width; parameter DYN_CLK_INV_EN = cfg.dyn_clk_inv_en; parameter DYN_CLKDIV_INV_EN = cfg.dyn_clkdiv_inv_en; parameter INIT_Q1 = cfg.init_q1; parameter INIT_Q2 = cfg.init_q2; parameter INIT_Q3 = cfg.init_q3; parameter INIT_Q4 = cfg.init_q4; parameter INTERFACE_TYPE = cfg.interface_type; parameter IOBDELAY = cfg.iobdelay; parameter NUM_CE = cfg.num_ce; parameter OFB_USED = cfg.ofb_used; parameter SERDES_MODE = cfg.serdes_mode; parameter SRVAL_Q1 = cfg.srval_q1; parameter SRVAL_Q2 = cfg.srval_q2; parameter SRVAL_Q3 = cfg.srval_q3; parameter SRVAL_Q4 = cfg.srval_q4; port CLKDIVP = 0; // unused path (D, O); method d(D) enable ((*inhigh*) en0); method O o(); method bitslip(BITSLIP) enable ((*inhigh*)enbitslip); method ce1(CE1) enable ((*inhigh*) en1); method ce2(CE2) enable ((*inhigh*) en2); method ddly(DDLY) enable ((*inhigh*) en3); method shiftin1(SHIFTIN1) enable ((*inhigh*) en4); method shiftin2(SHIFTIN2) enable ((*inhigh*) en5); method Q1 q1(); method Q2 q2(); method Q3 q3(); method Q4 q4(); method Q5 q5(); method Q6 q6(); method Q7 q7(); method Q8 q8(); method SHIFTOUT1 shiftout1(); method SHIFTOUT2 shiftout2(); method ofb(OFB) enable ((*inhigh*) en6); method oclk(OCLK) enable ((*inhigh*) en10); method oclkb(OCLKB) enable ((*inhigh*) en11); method dynclkdivsel(DYNCLKDIVSEL) enable ((*inhigh*) en7); method dynclksel(DYNCLKSEL) enable ((*inhigh*) en8); method reset(RST) enable ((*inhigh*) en14); schedule (reset, o, q1, q2, q3, q4, q5, q6, q7, q8, shiftout1, shiftout2, d, bitslip, ce1, ce2, ddly, shiftin1, shiftin2, ofb, dynclkdivsel, dynclksel, oclk, oclkb) CF (reset, o, q1, q2, q3, q4, q5, q6, q7, q8, shiftout1, shiftout2, d, bitslip, ce1, ce2, ddly, shiftin1, shiftin2, ofb, dynclkdivsel, dynclksel, oclk, oclkb); endmodule import "BVI" BUFR = module mkBUFR5#(Clock clk)(ClockGenIfc); default_clock clkunused(); default_reset rstn(); parameter BUFR_DIVIDE = "5"; input_clock clk(I) = clk; output_clock gen_clk(O); port CE = True; port CLR = False; path(I, O); endmodule import "BVI" BUFIO = module mkBUFIO#(Clock clk)(ClockGenIfc); default_clock clkunused(); default_reset rstn(); input_clock clk(I) = clk; output_clock gen_clk(O); path(I, O); endmodule (* always_ready, always_enabled *) interface ConnectalODDR#(type a); method a q(); method Action s(Bool i); method Action ce(Bool i); method Action d1(a i); method Action d2(a i); endinterface: ConnectalODDR import "BVI" ODDR = module mkConnectalODDR#(ODDRParams#(a) params)(ConnectalODDR#(a)) provisos(Bits#(a, 1), DefaultValue#(a)); if (params.srtype != "SYNC" && params.srtype != "ASYNC") error("There are only two modes of reset of the ODDR cell SYNC and ASYNC. Please specify one of those."); if (params.ddr_clk_edge != "OPPOSITE_EDGE" && params.ddr_clk_edge != "SAME_EDGE") error("There are only two modes of operation of the ODDR cell OPPOSITE_EDGE and SAME_EDGE. Please specify one of those."); no_reset; default_clock clk(C); //default_reset rst(R); port R = 0; parameter DDR_CLK_EDGE = params.ddr_clk_edge; parameter INIT = pack(params.init); parameter SRTYPE = params.srtype; method Q q reset_by(no_reset); method s(S) enable((*inhigh*)en0) reset_by(no_reset); method ce(CE) enable((*inhigh*)en1) reset_by(no_reset); method d1(D1) enable((*inhigh*)en2) reset_by(no_reset); method d2(D2) enable((*inhigh*)en3) reset_by(no_reset); schedule (q) SB (d1, d2); schedule (d1) CF (d2); schedule (d1) C (d1); schedule (d2) C (d2); schedule (q) CF (q); schedule (ce, s) CF (ce, s); schedule (ce, s) SB (d1, d2, q); endmodule: mkConnectalODDR //////////////////////////////////////////////////////////////////////////////// /// ClockGenerator Xilinx 7 Adv //////////////////////////////////////////////////////////////////////////////// typedef struct { String bandwidth; String compensation; Bool clkin_buffer; Real clkin1_period; Real clkin2_period; Integer reset_stages; Real clkfbout_mult_f; Real clkfbout_phase; Integer divclk_divide; Bool clkout0_buffer; Bool clkout0n_buffer; Real clkout0_divide_f; Real clkout0_duty_cycle; Real clkout0_phase; Bool clkout1_buffer; Bool clkout1n_buffer; Integer clkout1_divide; Real clkout1_duty_cycle; Real clkout1_phase; Bool clkout2_buffer; Bool clkout2n_buffer; Integer clkout2_divide; Real clkout2_duty_cycle; Real clkout2_phase; Bool clkout3_buffer; Bool clkout3n_buffer; Integer clkout3_divide; Real clkout3_duty_cycle; Real clkout3_phase; Bool clkout4_buffer; Integer clkout4_divide; Real clkout4_duty_cycle; Real clkout4_phase; Bool clkout5_buffer; Integer clkout5_divide; Real clkout5_duty_cycle; Real clkout5_phase; Bool clkout6_buffer; Integer clkout6_divide; Real clkout6_duty_cycle; Real clkout6_phase; Real ref_jitter1; Real ref_jitter2; Bool use_same_family; } ClockGenerator7AdvParams deriving (Bits, Eq); instance DefaultValue#(ClockGenerator7AdvParams); defaultValue = ClockGenerator7AdvParams { bandwidth: "OPTIMIZED", compensation: "ZHOLD", clkin_buffer: True, clkin1_period: 5.000, clkin2_period: 0.000, reset_stages: 3, clkfbout_mult_f: 1.000, clkfbout_phase: 0.000, divclk_divide: 1, clkout0_buffer: True, clkout0n_buffer: True, clkout0_divide_f: 1.000, clkout0_duty_cycle: 0.500, clkout0_phase: 0.000, clkout1_buffer: True, clkout1n_buffer: True, clkout1_divide: 1, clkout1_duty_cycle: 0.500, clkout1_phase: 0.000, clkout2_buffer: True, clkout2n_buffer: True, clkout2_divide: 1, clkout2_duty_cycle: 0.500, clkout2_phase: 0.000, clkout3_buffer: True, clkout3n_buffer: True, clkout3_divide: 1, clkout3_duty_cycle: 0.500, clkout3_phase: 0.000, clkout4_buffer: True, clkout4_divide: 1, clkout4_duty_cycle: 0.500, clkout4_phase: 0.000, clkout5_buffer: True, clkout5_divide: 1, clkout5_duty_cycle: 0.500, clkout5_phase: 0.000, clkout6_buffer: True, clkout6_divide: 1, clkout6_duty_cycle: 0.500, clkout6_phase: 0.000, ref_jitter1: 0.010, ref_jitter2: 0.010, use_same_family: False }; endinstance interface XVMMCME2; interface Clock clkout0; interface Clock clkout0_n; interface Clock clkout1; interface Clock clkout1_n; interface Clock clkout2; interface Clock clkout2_n; interface Clock clkout3; interface Clock clkout3_n; interface Clock clkout4; interface Clock clkout5; interface Clock clkout6; interface Clock clkfbout; interface Clock clkfbout_n; (* always_ready, always_enabled *) method Bool locked; (* always_ready, always_enabled *) method Action clkfbin(Bit#(1) clk); endinterface import "BVI" MMCME2_ADV = module vMkXMMCME2_ADV#(MMCMParams params)(XVMMCME2); Reset reset <- invertCurrentReset; default_clock clk1(CLKIN1); default_reset rst(RST) = reset; parameter BANDWIDTH = params.bandwidth; parameter CLKFBOUT_USE_FINE_PS = params.clkfbout_use_fine_ps; parameter CLKOUT0_USE_FINE_PS = params.clkout0_use_fine_ps; parameter CLKOUT1_USE_FINE_PS = params.clkout1_use_fine_ps; parameter CLKOUT2_USE_FINE_PS = params.clkout2_use_fine_ps; parameter CLKOUT3_USE_FINE_PS = params.clkout3_use_fine_ps; parameter CLKOUT4_CASCADE = params.clkout4_cascade; parameter CLKOUT4_USE_FINE_PS = params.clkout4_use_fine_ps; parameter CLKOUT5_USE_FINE_PS = params.clkout5_use_fine_ps; parameter CLKOUT6_USE_FINE_PS = params.clkout6_use_fine_ps; parameter COMPENSATION = params.compensation; parameter STARTUP_WAIT = params.startup_wait; parameter CLKFBOUT_MULT_F = params.clkfbout_mult_f; parameter CLKFBOUT_PHASE = params.clkfbout_phase; parameter CLKIN1_PERIOD = params.clkin1_period; parameter CLKIN2_PERIOD = params.clkin2_period; parameter DIVCLK_DIVIDE = params.divclk_divide; parameter CLKOUT0_DIVIDE_F = params.clkout0_divide_f; parameter CLKOUT0_DUTY_CYCLE = params.clkout0_duty_cycle; parameter CLKOUT0_PHASE = params.clkout0_phase; parameter CLKOUT1_DIVIDE = params.clkout1_divide; parameter CLKOUT1_DUTY_CYCLE = params.clkout1_duty_cycle; parameter CLKOUT1_PHASE = params.clkout1_phase; parameter CLKOUT2_DIVIDE = params.clkout2_divide; parameter CLKOUT2_DUTY_CYCLE = params.clkout2_duty_cycle; parameter CLKOUT2_PHASE = params.clkout2_phase; parameter CLKOUT3_DIVIDE = params.clkout3_divide; parameter CLKOUT3_DUTY_CYCLE = params.clkout3_duty_cycle; parameter CLKOUT3_PHASE = params.clkout3_phase; parameter CLKOUT4_DIVIDE = params.clkout4_divide; parameter CLKOUT4_DUTY_CYCLE = params.clkout4_duty_cycle; parameter CLKOUT4_PHASE = params.clkout4_phase; parameter CLKOUT5_DIVIDE = params.clkout5_divide; parameter CLKOUT5_DUTY_CYCLE = params.clkout5_duty_cycle; parameter CLKOUT5_PHASE = params.clkout5_phase; parameter CLKOUT6_DIVIDE = params.clkout6_divide; parameter CLKOUT6_DUTY_CYCLE = params.clkout6_duty_cycle; parameter CLKOUT6_PHASE = params.clkout6_phase; parameter REF_JITTER1 = params.ref_jitter1; parameter REF_JITTER2 = params.ref_jitter2; port CLKIN2 = Bit#(1)'(0); port CLKINSEL = Bit#(1)'(1); port DADDR = Bit#(7)'(0); port DCLK = Bit#(1)'(0); port DEN = Bit#(1)'(0); port DI = Bit#(16)'(0); port DWE = Bit#(1)'(0); port PSCLK = Bit#(1)'(0); port PSEN = Bit#(1)'(0); port PSINCDEC = Bit#(1)'(0); port PWRDWN = Bit#(1)'(0); output_clock clkfbout(CLKFBOUT); output_clock clkfbout_n(CLKFBOUTB); output_clock clkout0(CLKOUT0); output_clock clkout0_n(CLKOUT0B); output_clock clkout1(CLKOUT1); output_clock clkout1_n(CLKOUT1B); output_clock clkout2(CLKOUT2); output_clock clkout2_n(CLKOUT2B); output_clock clkout3(CLKOUT3); output_clock clkout3_n(CLKOUT3B); output_clock clkout4(CLKOUT4); output_clock clkout5(CLKOUT5); output_clock clkout6(CLKOUT6); method LOCKED locked() clocked_by(no_clock) reset_by(no_reset); method clkfbin(CLKFBIN) enable((*inhigh*)en1) clocked_by(clkfbout) reset_by(no_reset); schedule clkfbin C clkfbin; schedule locked CF (clkfbin, locked); endmodule interface XClockGenerator7; interface Clock clkout0; interface Clock clkout0_n; interface Clock clkout1; interface Clock clkout1_n; interface Clock clkout2; interface Clock clkout2_n; interface Clock clkout3; interface Clock clkout3_n; interface Clock clkout4; interface Clock clkout5; interface Clock clkout6; interface Clock clkfbout; (* always_ready *) method Bool locked; (* always_ready, always_enabled *) method Action clkfbin(Bit#(1) clk); endinterface module mkClockGenerator7Adv#(ClockGenerator7AdvParams params)(XClockGenerator7); //////////////////////////////////////////////////////////////////////////////// /// Clocks & Resets //////////////////////////////////////////////////////////////////////////////// Clock clk <- exposeCurrentClock; Clock clk_buffered = ?; if (params.clkin_buffer) begin Clock inbuffer <- mkClockIBUFG `ifdef ClockDefaultParam (defaultValue) `endif ; clk_buffered = inbuffer; end else begin clk_buffered = clk; end //Reset rst_n <- mkSyncResetFromCR(params.reset_stages, clk_buffered); //Reset rst <- mkResetInverter(rst_n); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// MMCMParams clkgen_params = defaultValue; clkgen_params.bandwidth = params.bandwidth; clkgen_params.compensation = params.compensation; clkgen_params.clkin1_period = params.clkin1_period; clkgen_params.clkin2_period = params.clkin2_period; clkgen_params.clkfbout_mult_f = params.clkfbout_mult_f; clkgen_params.clkfbout_phase = params.clkfbout_phase; clkgen_params.divclk_divide = params.divclk_divide; clkgen_params.clkout0_divide_f = params.clkout0_divide_f; clkgen_params.clkout0_duty_cycle = params.clkout0_duty_cycle; clkgen_params.clkout0_phase = params.clkout0_phase; clkgen_params.clkout1_divide = params.clkout1_divide; clkgen_params.clkout1_duty_cycle = params.clkout1_duty_cycle; clkgen_params.clkout1_phase = params.clkout1_phase; clkgen_params.clkout2_divide = params.clkout2_divide; clkgen_params.clkout2_duty_cycle = params.clkout2_duty_cycle; clkgen_params.clkout2_phase = params.clkout2_phase; clkgen_params.clkout3_divide = params.clkout3_divide; clkgen_params.clkout3_duty_cycle = params.clkout3_duty_cycle; clkgen_params.clkout3_phase = params.clkout3_phase; clkgen_params.clkout4_divide = params.clkout4_divide; clkgen_params.clkout4_duty_cycle = params.clkout4_duty_cycle; clkgen_params.clkout4_phase = params.clkout4_phase; clkgen_params.clkout5_divide = params.clkout5_divide; clkgen_params.clkout5_duty_cycle = params.clkout5_duty_cycle; clkgen_params.clkout5_phase = params.clkout5_phase; clkgen_params.clkout6_divide = params.clkout6_divide; clkgen_params.clkout6_duty_cycle = params.clkout6_duty_cycle; clkgen_params.clkout6_phase = params.clkout6_phase; clkgen_params.ref_jitter1 = params.ref_jitter1; clkgen_params.ref_jitter2 = params.ref_jitter2; clkgen_params.use_same_family = params.use_same_family; XVMMCME2 pll <- vMkXMMCME2_ADV(clkgen_params); //(* fire_when_enabled, no_implicit_conditions *) //rule connect_feedback; //pll.clkfbin( pll.clkfbout); //endrule Clock clkout0_buf = ?; Clock clkout0n_buf = ?; Clock clkout1_buf = ?; Clock clkout1n_buf = ?; Clock clkout2_buf = ?; Clock clkout2n_buf = ?; Clock clkout3_buf = ?; Clock clkout3n_buf = ?; Clock clkout4_buf = ?; Clock clkout5_buf = ?; Clock clkout6_buf = ?; if (params.clkout0_buffer) begin Clock clkout0buffer <- mkClockBUFG(clocked_by pll.clkout0); clkout0_buf = clkout0buffer; end else begin clkout0_buf = pll.clkout0; end if (params.clkout0n_buffer) begin Clock clkout0nbuffer <- mkClockBUFG(clocked_by pll.clkout0_n); clkout0n_buf = clkout0nbuffer; end else begin clkout0n_buf = pll.clkout0_n; end if (params.clkout1_buffer) begin Clock clkout1buffer <- mkClockBUFG(clocked_by pll.clkout1); clkout1_buf = clkout1buffer; end else begin clkout1_buf = pll.clkout1; end if (params.clkout1n_buffer) begin Clock clkout1nbuffer <- mkClockBUFG(clocked_by pll.clkout1_n); clkout1n_buf = clkout1nbuffer; end else begin clkout1n_buf = pll.clkout1_n; end if (params.clkout2_buffer) begin Clock clkout2buffer <- mkClockBUFG(clocked_by pll.clkout2); clkout2_buf = clkout2buffer; end else begin clkout2_buf = pll.clkout2; end if (params.clkout2n_buffer) begin Clock clkout2nbuffer <- mkClockBUFG(clocked_by pll.clkout2_n); clkout2n_buf = clkout2nbuffer; end else begin clkout2n_buf = pll.clkout2_n; end if (params.clkout3_buffer) begin Clock clkout3buffer <- mkClockBUFG(clocked_by pll.clkout3); clkout3_buf = clkout3buffer; end else begin clkout3_buf = pll.clkout3; end if (params.clkout3n_buffer) begin Clock clkout3nbuffer <- mkClockBUFG(clocked_by pll.clkout3_n); clkout3n_buf = clkout3nbuffer; end else begin clkout3n_buf = pll.clkout3_n; end if (params.clkout4_buffer) begin Clock clkout4buffer <- mkClockBUFG(clocked_by pll.clkout4); clkout4_buf = clkout4buffer; end else begin clkout4_buf = pll.clkout4; end if (params.clkout5_buffer) begin Clock clkout5buffer <- mkClockBUFG(clocked_by pll.clkout5); clkout5_buf = clkout5buffer; end else begin clkout5_buf = pll.clkout5; end if (params.clkout6_buffer) begin Clock clkout6buffer <- mkClockBUFG(clocked_by pll.clkout6); clkout6_buf = clkout6buffer; end else begin clkout6_buf = pll.clkout6; end //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface Clock clkout0 = clkout0_buf; interface Clock clkout0_n = clkout0n_buf; interface Clock clkout1 = clkout1_buf; interface Clock clkout1_n = clkout1n_buf; interface Clock clkout2 = clkout2_buf; interface Clock clkout2_n = clkout2n_buf; interface Clock clkout3 = clkout3_buf; interface Clock clkout3_n = clkout3n_buf; interface Clock clkout4 = clkout4_buf; interface Clock clkout5 = clkout5_buf; interface Clock clkout6 = clkout6_buf; method Bool locked = pll.locked; interface Clock clkfbout = pll.clkfbout; method clkfbin = pll.clkfbin; endmodule: mkClockGenerator7Adv //////////////////////////////////////////////////////////// (* always_ready, always_enabled *) interface IbufdsTest; (* prefix="" *) method Action in(Bit#(1) i, Bit#(1) ib); interface ReadOnly#(Bit#(1)) o; endinterface module mkIbufdsTest(IbufdsTest); Wire#(Bit#(1)) i_w <- mkDWire(0); Wire#(Bit#(1)) ib_w <- mkDWire(0); ReadOnly#(Bit#(1)) ibufds <- mkIBUFDS(i_w, ib_w); method Action in(Bit#(1) i, Bit#(1) ib); i_w <= i; ib_w <= ib; endmethod interface ReadOnly o = ibufds; endmodule (* always_ready, always_enabled *) interface BIBUF#(numeric type sa); interface Inout#(Bit#(sa)) pad; endinterface import "BVI" GenBIBUF = module mkBIBUF#(Inout#(a) v)(BIBUF#(sa)) provisos(Bits#(a, sa)); let sa = fromInteger(valueOf(sa)); parameter SIZE=sa; default_clock clk(); default_reset rst(); inout IO = v; ifc_inout pad(PAD); endmodule (* always_ready, always_enabled *) interface IOBUF; method Bit#(1) o(); interface Inout#(Bit#(1)) io; endinterface import "BVI" IOBUF = module mkIOBUF#(Bit#(1) t, Bit#(1) i)(IOBUF); default_clock clk(); default_reset rst(); port I = i; port T = t; method O o(); ifc_inout io(IO); schedule (o) CF (o); endmodule ================================================ FILE: bsv/CtrlMux.bsv ================================================ // Copyright (c) 2012 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import GetPut::*; import FIFOF::*; import SpecialFIFOs::*; import FIFO::*; `include "ConnectalProjectConfig.bsv" import ConnectalConfig::*; import HostInterface::*; import Connectable::*; import AddressGenerator::*; import Portal::*; import ConnectalMemTypes::*; import Arith::*; import Pipe::*; interface PortalCtrl#(numeric type addrWidth, numeric type dataWidth); method ActionValue#(Bit#(dataWidth)) read(Bit#(addrWidth) addr); method Action write(Bit#(addrWidth) addr, Bit#(dataWidth) v); endinterface interface PortalCtrlMemSlave#(numeric type addrWidth, numeric type dataWidth); interface PortalCtrl#(addrWidth, dataWidth) memSlave; interface ReadOnly#(Bool) interrupt; interface WriteOnly#(Bit#(dataWidth)) num_portals; endinterface module mkInterruptMux#(Vector#(numPortals,ReadOnly#(Bool)) inputs) (ReadOnly#(Bool)) provisos(Add#(nz, TLog#(numPortals), 4), Add#(1, a__, numPortals)); function Bool my_read(ReadOnly#(Bool) x); return x._read; endfunction method Bool _read; return fold(boolor,map(my_read,inputs)); endmethod endmodule module mkPortalInterrupt#(Vector#(numIndications, PipeOut#(Bit#(dataWidth))) indicationPipes) (PortalInterrupt#(dataWidth)); Bool interruptStatus = False; function Bool pipeOutNotEmpty(PipeOut#(a) po); return po.notEmpty(); endfunction Vector#(numIndications, Bool) readyBits = map(pipeOutNotEmpty, indicationPipes); Bit#(dataWidth) readyChannel = -1; for (Integer i = valueOf(numIndications) - 1; i >= 0; i = i - 1) begin if (readyBits[i]) begin interruptStatus = True; readyChannel = fromInteger(i); end end method Bool status(); return interruptStatus; endmethod method Bit#(dataWidth) channel(); return readyChannel; endmethod endmodule module mkPortalCtrlMemSlave#(Bit#(dataWidth) ifcId, PortalInterrupt#(dataWidth) intr) (PortalCtrlMemSlave#(addrWidth, dataWidth)) provisos(Add#(d__, dataWidth, TMul#(dataWidth, 2))); Reg#(Bit#(dataWidth)) num_portals_reg <- mkReg(0); Reg#(Bool) interruptEnableReg <- mkReg(False); Reg#(Bit#(TMul#(dataWidth,2))) cycle_count <- mkReg(0); Reg#(Bit#(dataWidth)) snapshot <- mkReg(0); let verbose = False; rule count; cycle_count <= cycle_count+1; endrule interface PortalCtrl memSlave; method Action write(Bit#(addrWidth) addr, Bit#(dataWidth) v); if (addr == 4) interruptEnableReg <= v[0] == 1'd1; endmethod method ActionValue#(Bit#(dataWidth)) read(Bit#(addrWidth) addr); let v = 'h05a05a0; if (addr == 0) v = intr.status() ? 1 : 0; if (addr == 4) v = interruptEnableReg ? 1 : 0; if (addr == 8) v = fromInteger(valueOf(NumberOfTiles)); if (addr == 'h00C) begin if (intr.status()) v = intr.channel()+1; else v = 0; end if (addr == 'h010) v = ifcId; if (addr == 'h014) v = num_portals_reg; if (addr == 'h018) begin snapshot <= truncate(cycle_count); v = truncate(cycle_count>>valueOf(dataWidth)); end if (addr == 'h01C) v = snapshot; return v; endmethod endinterface interface ReadOnly interrupt; method Bool _read(); return intr.status() && interruptEnableReg; endmethod endinterface interface WriteOnly num_portals; method Action _write(Bit#(dataWidth) v); num_portals_reg <= v; endmethod endinterface endmodule module mkMemMethodMuxIn#(PortalCtrl#(aw,dataWidth) ctrl, Vector#(numRequests, PipeIn#(Bit#(dataWidth))) requests )(PhysMemSlave#(addrWidth,dataWidth)) provisos(Add#(selWidth,aw,addrWidth) , Add#(a__, TLog#(numRequests), selWidth) , Add#(1, b__, dataWidth) ); AddressGenerator#(aw,dataWidth) fifoReadAddrGenerator <- mkAddressGenerator(); AddressGenerator#(aw,dataWidth) fifoWriteAddrGenerator <- mkAddressGenerator(); FIFO#(Bit#(MemTagSize)) fifoWriteDoneFifo <- mkFIFO(); let port_sel_low = valueOf(aw); let port_sel_high = valueOf(TSub#(addrWidth,1)); function Bit#(selWidth) psel(Bit#(addrWidth) a); Bit#(selWidth) v = a[port_sel_high:port_sel_low]; return v - 1; endfunction function Bool pselCtrl(Bit#(addrWidth) a); Bit#(selWidth) v = a[port_sel_high:port_sel_low]; return v == 0; endfunction function Bit#(aw) asel(Bit#(addrWidth) a); return a[(port_sel_low-1):0]; endfunction FIFO#(Bit#(MemTagSize)) doneFifo <- mkFIFO1(); FIFO#(PhysMemRequest#(aw,dataWidth)) req_ars <- mkFIFO1(); FIFO#(Bit#(TLog#(numRequests))) rs <- mkFIFO1(); FIFO#(Bool) rsCtrl <- mkFIFO1(); FIFO#(PhysMemRequest#(aw,dataWidth)) req_aws <- mkFIFO1(); FIFO#(Bit#(TLog#(numRequests))) ws <- mkFIFO1(); FIFO#(Bool) wsCtrl <- mkFIFO1(); rule write_done; let rv <- toGet(fifoWriteDoneFifo).get(); ws.deq(); wsCtrl.deq(); doneFifo.enq(rv); endrule rule req_aw; let req <- toGet(req_aws).get; fifoWriteAddrGenerator.request.put(req); endrule rule req_ar; let req <- toGet(req_ars).get; fifoReadAddrGenerator.request.put(req); endrule FIFO#(MemData#(dataWidth)) writeDataFifo <- mkFIFO(); rule writeDataRule; let wdata <- toGet(writeDataFifo).get(); //$display("mkMemMethodMux.writeData aw=%d ws=%d data=%h", valueOf(aw), ws.first, wdata.data); let b <- fifoWriteAddrGenerator.addrBeat.get(); //$display("mkPipeInMemSlave.writeData.put addr=%h data=%h", b.addr, wdata.data); if (b.last) fifoWriteDoneFifo.enq(b.tag); if (wsCtrl.first) ctrl.write(b.addr, wdata.data); else begin requests[ws.first].enq(wdata.data); // this used to be where we triggered putFailed end endrule FIFO#(MemData#(dataWidth)) rvFifo <- mkFIFO; rule rvrule; let v = 0; let b <- fifoReadAddrGenerator.addrBeat.get(); if (rsCtrl.first) begin let vr <- ctrl.read(b.addr); v = vr; end else begin if (b.addr == 4) v = extend(pack(requests[rs.first].notFull())); end rvFifo.enq(MemData { data: v, tag: b.tag, last: b.last }); //$display("mkMemMethodMux.readData aw=%d rs=%d data=%h", valueOf(aw), rs.first, rv.data); if (b.last) begin rs.deq(); rsCtrl.deq(); end endrule interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); req_aws.enq(PhysMemRequest{addr:asel(req.addr), burstLen:req.burstLen, tag:req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); if (req.burstLen > 4) $display("**** \n\n mkMemMethodMux.writeReq len=%d \n\n ****", req.burstLen); //$display("mkMemMethodMux.writeReq addr=%h selWidth=%d aw=%d psel=%h pselCtrl=%x", req.addr, valueOf(selWidth), valueOf(aw), psel(req.addr), pselCtrl(req.addr)); ws.enq(truncate(psel(req.addr))); wsCtrl.enq(pselCtrl(req.addr)); endmethod endinterface interface Put writeData; method Action put(MemData#(dataWidth) wdata); writeDataFifo.enq(wdata); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get(); let rv <- toGet(doneFifo).get(); return rv; endmethod endinterface endinterface interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); req_ars.enq(PhysMemRequest{addr:asel(req.addr), burstLen:req.burstLen, tag:req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); //$display("mkMemMethodMux.readReq addr=%h aw=%d psel=%h pselCtrl=%x", req.addr, valueOf(aw), psel(req.addr), pselCtrl(req.addr)); if (req.burstLen > 4) $display("**** \n\n mkMemMethodMux.readReq len=%d \n\n ****", req.burstLen); rs.enq(truncate(psel(req.addr))); rsCtrl.enq(pselCtrl(req.addr)); endmethod endinterface interface Get readData; method ActionValue#(MemData#(dataWidth)) get(); let rv <- toGet(rvFifo).get(); return rv; endmethod endinterface endinterface endmodule module mkMemMethodMuxOut#(PortalCtrl#(aw,dataWidth) ctrl, Vector#(numIndications, PipeOut#(Bit#(dataWidth))) indications)(PhysMemSlave#(addrWidth,dataWidth)) provisos(Add#(selWidth,aw,addrWidth) , Add#(a__, TLog#(numIndications), selWidth) , Add#(1, b__, dataWidth) ); AddressGenerator#(aw,dataWidth) fifoReadAddrGenerator <- mkAddressGenerator(); AddressGenerator#(aw,dataWidth) fifoWriteAddrGenerator <- mkAddressGenerator(); FIFO#(Bit#(MemTagSize)) fifoWriteDoneFifo <- mkFIFO(); let port_sel_low = valueOf(aw); let port_sel_high = valueOf(TSub#(addrWidth,1)); function Bit#(selWidth) psel(Bit#(addrWidth) a); Bit#(selWidth) v = a[port_sel_high:port_sel_low]; return v - 1; endfunction function Bool pselCtrl(Bit#(addrWidth) a); Bit#(selWidth) v = a[port_sel_high:port_sel_low]; return v == 0; endfunction function Bit#(aw) asel(Bit#(addrWidth) a); return a[(port_sel_low-1):0]; endfunction FIFO#(Bit#(MemTagSize)) doneFifo <- mkFIFO1(); FIFO#(PhysMemRequest#(aw,dataWidth)) req_ars <- mkFIFO1(); FIFO#(Bit#(TLog#(numIndications))) rs <- mkFIFO1(); FIFO#(Bool) rsCtrl <- mkFIFO1(); FIFO#(PhysMemRequest#(aw,dataWidth)) req_aws <- mkFIFO1(); FIFO#(Bit#(TLog#(numIndications))) ws <- mkFIFO1(); FIFO#(Bool) wsCtrl <- mkFIFO1(); rule write_done; let rv <- toGet(fifoWriteDoneFifo).get(); ws.deq(); wsCtrl.deq(); doneFifo.enq(rv); endrule rule req_aw; let req <- toGet(req_aws).get; fifoWriteAddrGenerator.request.put(req); endrule rule req_ar; let req <- toGet(req_ars).get; fifoReadAddrGenerator.request.put(req); endrule FIFO#(MemData#(dataWidth)) rvFifo <- mkFIFO; rule rvrule; let b <- fifoReadAddrGenerator.addrBeat.get(); let rv = MemData { data: 0, tag: b.tag, last: b.last }; if (rsCtrl.first) begin let vr <- ctrl.read(b.addr); rv.data = vr; end else begin if (b.addr == 0) rv.data <- toGet(indications[rs.first]).get(); else if (b.addr == 4) rv.data = extend(pack(indications[rs.first].notEmpty())); end rvFifo.enq(rv); //$display("mkMemMethodMux.readData aw=%d rs=%d data=%h", valueOf(aw), rs.first, rv.data); rs.deq(); rsCtrl.deq(); endrule interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); req_aws.enq(PhysMemRequest{addr:asel(req.addr), burstLen:req.burstLen, tag:req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); if (req.burstLen > 4) $display("**** \n\n mkMemMethodMux.writeReq len=%d \n\n ****", req.burstLen); //$display("mkMemMethodMux.writeReq addr=%h selWidth=%d aw=%d psel=%h pselCtrl=%x", req.addr, valueOf(selWidth), valueOf(aw), psel(req.addr), pselCtrl(req.addr)); ws.enq(truncate(psel(req.addr))); wsCtrl.enq(pselCtrl(req.addr)); endmethod endinterface interface Put writeData; method Action put(MemData#(dataWidth) wdata); //$display("mkMemMethodMux.writeData aw=%d ws=%d data=%h", valueOf(aw), ws.first, wdata.data); let b <- fifoWriteAddrGenerator.addrBeat.get(); if (wsCtrl.first) ctrl.write(b.addr, wdata.data); //$display("mkPipeOutMemSlave.writeData.put addr=%h data=%h", b.addr, d.data); if (b.last) fifoWriteDoneFifo.enq(b.tag); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get(); let rv <- toGet(doneFifo).get(); return rv; endmethod endinterface endinterface interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); req_ars.enq(PhysMemRequest{addr:asel(req.addr), burstLen:req.burstLen, tag:req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); //$display("mkMemMethodMux.readReq addr=%h aw=%d psel=%h pselCtrl=%x", req.addr, valueOf(aw), psel(req.addr), pselCtrl(req.addr)); if (req.burstLen > 4) $display("**** \n\n mkMemMethodMux.readReq len=%d \n\n ****", req.burstLen); rs.enq(truncate(psel(req.addr))); rsCtrl.enq(pselCtrl(req.addr)); endmethod endinterface interface Get readData; method ActionValue#(MemData#(dataWidth)) get(); let rv <- toGet(rvFifo).get(); return rv; endmethod endinterface endinterface endmodule module mkPhysMemSlaveMux#(Vector#(numSlaves,PhysMemSlave#(aw,dataWidth)) slaves) (PhysMemSlave#(addrWidth,dataWidth)) provisos(Add#(selWidth,aw,addrWidth) ,Add#(a__, TLog#(numSlaves), selWidth) ,Min#(4,TLog#(numSlaves),bpc) ,Pipe::FunnelPipesPipelined#(1, numSlaves, ConnectalMemTypes::MemData#(dataWidth),bpc) ); let port_sel_low = valueOf(aw); let port_sel_high = valueOf(TSub#(addrWidth,1)); function Bit#(selWidth) psel(Bit#(addrWidth) a); return a[port_sel_high:port_sel_low]; endfunction function Bit#(aw) asel(Bit#(addrWidth) a); return a[(port_sel_low-1):0]; endfunction function Get#(MemData#(dataWidth)) getMemPortalReadData(PhysMemSlave#(aw,dataWidth) x) = x.read_server.readData; function Put#(MemData#(dataWidth)) getMemPortalWriteData(PhysMemSlave#(aw,dataWidth) x) = x.write_server.writeData; Reg#(Bool) lastWriteDataSeen <- mkReg(False); FIFO#(Bit#(MemTagSize)) doneFifo <- mkFIFO1(); FIFO#(PhysMemRequest#(aw,dataWidth)) req_ars <- mkSizedFIFO(1); FIFO#(Bit#(TLog#(numSlaves))) rs <- mkFIFO1(); Vector#(numSlaves, PipeOut#(MemData#(dataWidth))) readDataPipes <- mapM(mkPipeOut, map(getMemPortalReadData,slaves)); FunnelPipe#(1, numSlaves, MemData#(dataWidth), bpc) read_data_funnel <- mkFunnelPipesPipelined(readDataPipes); FIFO#(PhysMemRequest#(aw,dataWidth)) req_aws <- mkFIFO1(); FIFO#(Bit#(TLog#(numSlaves))) ws <- mkFIFO1(); FIFOF#(Tuple2#(Bit#(TLog#(numSlaves)), MemData#(dataWidth))) write_data <- mkFIFOF; UnFunnelPipe#(1, numSlaves, MemData#(dataWidth), bpc) write_data_unfunnel <- mkUnFunnelPipesPipelined(cons(toPipeOut(write_data),nil)); Vector#(numSlaves, PipeIn#(MemData#(dataWidth))) writeDataPipes <- mapM(mkPipeIn, map(getMemPortalWriteData,slaves)); zipWithM_(mkConnection, write_data_unfunnel, writeDataPipes); let verbose = False; rule req_aw; let req <- toGet(req_aws).get; slaves[ws.first].write_server.writeReq.put(req); endrule rule req_ar; let req <- toGet(req_ars).get; slaves[rs.first].read_server.readReq.put(req); endrule rule write_done_rule; let rv <- slaves[ws.first].write_server.writeDone.get(); ws.deq(); doneFifo.enq(rv); endrule interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); req_aws.enq(PhysMemRequest{addr:asel(req.addr), burstLen:req.burstLen, tag:req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); if (req.burstLen > 4) $display("**** \n\n mkPhysMemSlaveMux.writeReq len=%d \n\n ****", req.burstLen); ws.enq(truncate(psel(req.addr))); lastWriteDataSeen <= False; if(verbose) $display("mkPhysMemSlaveMux.writeReq addr=%h aw=%d psel=%h", req.addr, valueOf(aw), psel(req.addr)); endmethod endinterface interface Put writeData; method Action put(MemData#(dataWidth) wdata) if (!lastWriteDataSeen); write_data.enq(tuple2(ws.first,wdata)); if (wdata.last) begin lastWriteDataSeen <= True; end if(verbose) $display("mkPhysMemSlaveMux.writeData dst=%h wdata=%h", ws.first,wdata); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get(); let rv <- toGet(doneFifo).get(); return rv; endmethod endinterface endinterface interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(addrWidth,dataWidth) req); req_ars.enq(PhysMemRequest{addr:asel(req.addr), burstLen:req.burstLen, tag:req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); rs.enq(truncate(psel(req.addr))); if (req.burstLen > 4) $display("**** \n\n mkPhysMemSlaveMux.readReq len=%d \n\n ****", req.burstLen); if(verbose) $display("mkPhysMemSlaveMux.readReq addr=%h aw=%d psel=%h", req.addr, valueOf(aw), psel(req.addr)); endmethod endinterface interface Get readData; method ActionValue#(MemData#(dataWidth)) get(); let rv <- toGet(read_data_funnel[0]).get; rs.deq(); if(verbose) $display("mkPhysMemSlaveMux.readData rs=%d data=%h", rs.first, rv.data); return rv; endmethod endinterface endinterface endmodule module mkSlaveMux#(Vector#(numPortals,MemPortal#(aw,dataWidth)) portals) (PhysMemSlave#(addrWidth,dataWidth)) provisos(Add#(selWidth,aw,addrWidth) ,Add#(a__, TLog#(numPortals), selWidth) ,FunnelPipesPipelined#(1, numPortals, MemData#(dataWidth),TMin#(4, TLog#(numPortals))) ); function PhysMemSlave#(_a,_d) getSlave(MemPortal#(_a,_d) p); return p.slave; endfunction Vector#(numPortals, PhysMemSlave#(aw,dataWidth)) slaves = map(getSlave, portals); for(Integer i = 0; i < valueOf(numPortals); i=i+1) rule writeTop; portals[i].num_portals <= fromInteger(valueOf(numPortals)); endrule let rv <- mkPhysMemSlaveMux(slaves); return rv; endmodule ================================================ FILE: bsv/DisplayInd.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface DisplayInd; endinterface ================================================ FILE: bsv/Dsp48E1.bsv ================================================ import GetPut::*; import FIFO::*; import FIFOF::*; import Clocks::*; import ConnectalClocks::*; `include "ConnectalProjectConfig.bsv" interface Dsp48E1; method Bool notEmpty(); method Bit#(48) p(); method Action deq(); // Control: 4-bit (each) input: Control Inputs/Status Bits method Action alumode(Bit#(4) v); // 4-bit input: ALU control input method Action carryinsel(Bit#(3) v); // 3-bit input: Carry select input method Action inmode(Bit#(5) v); // 5-bit input: INMODE control input method Action opmode(Bit#(7) v); // 7-bit input: Operation mode input method Action a(Bit#(30) v); method Action b(Bit#(18) v); method Action c(Bit#(48) v); method Action d(Bit#(25) v); method Action last(Bit#(1) v); endinterface `ifndef SIMULATION //fixme xsim (* always_ready, always_enabled *) interface PRIM_DSP48E1; method Bit#(48) p(); // Control: 4-bit (each) input: Control Inputs/Status Bits method Action alumode(Bit#(4) v); // 4-bit input: ALU control input method Action carryinsel(Bit#(3) v); // 3-bit input: Carry select input method Action inmode(Bit#(5) v); // 5-bit input: INMODE control input method Action opmode(Bit#(7) v); // 7-bit input: Operation mode input method Action a(Bit#(30) v); method Action b(Bit#(18) v); method Action c(Bit#(48) v); method Action d(Bit#(25) v); method Action acin(Bit#(30) v); method Action bcin(Bit#(18) v); method Action carrycascin(Bit#(1) v); method Action carryin(Bit#(1) v); method Action multsignin(Bit#(1) v); method Action pcin(Bit#(48) v); method Action cea1(Bit#(1) en); // 1-bit input: Clock enable input for 1st stage AREG method Action cea2(Bit#(1) en); // 1-bit input: Clock enable input for 2nd stage AREG method Action cead(Bit#(1) en); // 1-bit input: Clock enable input for ADREG method Action ceb1(Bit#(1) en); // 1-bit input: Clock enable input for 1st stage BREG method Action ceb2(Bit#(1) en); // 1-bit input: Clock enable input for 2nd stage BREG method Action cealumode(Bit#(1) en); // 1-bit input: Clock enable input for ALUMODE method Action cec(Bit#(1) en); // 1-bit input: Clock enable input for CREG method Action cecarryin(Bit#(1) en); // 1-bit input: Clock enable input for CARRYINREG method Action cectrl(Bit#(1) en); // 1-bit input: Clock enable input for OPMODEREG and CARRYINSELREG method Action ced(Bit#(1) en); // 1-bit input: Clock enable input for DREG method Action ceinmode(Bit#(1) en); // 1-bit input: Clock enable input for INMODEREG method Action cem(Bit#(1) en); // 1-bit input: Clock enable input for MREG method Action cep(Bit#(1) en); // 1-bit input: Clock enable input for PREG endinterface import "BVI" DSP48E1 = module vmkDSP48E1(PRIM_DSP48E1); let currentClock <- exposeCurrentClock; let currentReset <- exposeCurrentReset; `ifndef BSV_POSITIVE_RESET let positiveReset <- mkPositiveReset(10, currentReset, currentClock); let dspReset = positiveReset.positiveReset; `else let dspReset = currentReset; `endif default_clock clk(CLK); default_reset rsta(RSTA) = dspReset; input_reset rstb(RSTB) = dspReset; input_reset rstc(RSTC) = dspReset; input_reset rstd(RSTD) = dspReset; input_reset rstallcarryin(RSTALLCARRYIN) = dspReset; input_reset rstalumode(RSTALUMODE) = dspReset; input_reset rstctrl(RSTCTRL) = dspReset; input_reset rstinmode(RSTINMODE) = dspReset; input_reset rstm(RSTM) = dspReset; input_reset rstp(RSTP) = dspReset; method P p(); method alumode(ALUMODE) enable ((*inhigh*)EN_alumode); method carryinsel(CARRYINSEL) enable ((*inhigh*)EN_carryinsel); method inmode(INMODE) enable ((*inhigh*)EN_inmode); method opmode(OPMODE) enable ((*inhigh*)EN_opmode); method a(A) enable ((*inhigh*)EN_a); method b(B) enable ((*inhigh*)EN_b); method c(C) enable ((*inhigh*)EN_c); method d(D) enable ((*inhigh*)EN_d); method acin(ACIN) enable ((*inhigh*)EN_acin); method bcin(BCIN) enable ((*inhigh*)EN_bcin); method carrycascin(CARRYCASCIN) enable ((*inhigh*)EN_carrycascin); method carryin(CARRYIN) enable ((*inhigh*)EN_carryin); method multsignin(MULTSIGNIN) enable ((*inhigh*)EN_multsignin); method pcin(PCIN) enable ((*inhigh*)EN_pcin); method cea1(CEA1) enable ((*inhigh*)EN_cea1); method cea2(CEA2) enable ((*inhigh*)EN_cea2); method cead(CEAD) enable ((*inhigh*)EN_cead); method ceb1(CEB1) enable ((*inhigh*)EN_ceb1); method ceb2(CEB2) enable ((*inhigh*)EN_ceb2); method cealumode(CEALUMODE) enable ((*inhigh*)EN_cealumode); method cec(CEC) enable ((*inhigh*)EN_cec); method cecarryin(CECARRYIN) enable ((*inhigh*)EN_cecarryin); method cectrl(CECTRL) enable ((*inhigh*)EN_cectrl); method ced(CED) enable ((*inhigh*)EN_ced); method ceinmode(CEINMODE) enable ((*inhigh*)EN_ceinmode); method cem(CEM) enable ((*inhigh*)EN_cem); method cep(CEP) enable ((*inhigh*)EN_cep); schedule (alumode,carryinsel,inmode,opmode,a,b,c,d,acin,bcin,carrycascin,carryin,multsignin,pcin,cea1,cea2,cead,ceb1,ceb2,cealumode,cec,cecarryin,cectrl,ced,ceinmode,cem,cep,p) CF (alumode,carryinsel,inmode,opmode,a,b,c,d,acin,bcin,carrycascin,carryin,multsignin,pcin,cea1,cea2,cead,ceb1,ceb2,cealumode,cec,cecarryin,cectrl,ced,ceinmode,cem,cep,p); endmodule (* synthesize *) module mkDsp48E1(Dsp48E1); let dsp <- vmkDSP48E1(); let defaultReset <- exposeCurrentReset; let optionalReset = defaultReset; // noReset Wire#(Bit#(4)) alumodeWire <- mkDWire(0); Reg#(Bit#(4)) alumodeReg <- mkReg(0); Wire#(Bit#(3)) carryinselWire <- mkDWire(0); Wire#(Bit#(5)) inmodeWire <- mkDWire(0); Wire#(Bit#(7)) opmodeWire <- mkDWire(7'h20); Reg#(Bit#(7)) opmode1Reg <- mkReg(0); Reg#(Bit#(7)) opmode2Reg <- mkReg(0); Reg#(Bit#(7)) opmode3Reg <- mkReg(0); Reg#(Bit#(7)) opmode4Reg <- mkReg(0); Wire#(Bit#(30)) aWire <- mkDWire(0); Wire#(Bit#(18)) bWire <- mkDWire(0); Wire#(Bit#(48)) cWire <- mkDWire(0); Wire#(Bit#(25)) dWire <- mkDWire(0); Reg#(Bit#(48)) c1Reg <- mkReg(0); Reg#(Bit#(48)) c2Reg <- mkReg(0); Reg#(Bit#(48)) c3Reg <- mkReg(0); Wire#(Bit#(1)) ce1Wire <- mkDWire(0); Reg#(Bit#(1)) ce2Reg <- mkReg(0, reset_by optionalReset); Reg#(Bit#(1)) cepReg <- mkReg(0, reset_by optionalReset); Wire#(Bit#(1)) lastWire <- mkDWire(0); Reg#(Bit#(1)) last1Reg <- mkReg(0, reset_by optionalReset); Reg#(Bit#(1)) last2Reg <- mkReg(0, reset_by optionalReset); Reg#(Bit#(1)) last3Reg <- mkReg(0, reset_by optionalReset); Reg#(Bit#(1)) last4Reg <- mkReg(0, reset_by optionalReset); Reg#(Bit#(1)) last5Reg <- mkReg(0, reset_by optionalReset); Reg#(Bit#(32)) cycles <- mkReg(0); rule cyclesRule; cycles <= cycles+1; endrule rule clock_enable_and_reset; ce2Reg <= ce1Wire; cepReg <= ce2Reg; last1Reg <= lastWire; last2Reg <= last1Reg; last3Reg <= last2Reg; last4Reg <= last3Reg; last5Reg <= last4Reg; dsp.cea1(1); // (ce1Wire); dsp.cea2(1); // (ce2Reg); dsp.cead(1); dsp.ceb1(1); // (ce1Wire); dsp.ceb2(1); // (ce2Reg); dsp.cealumode(1); // (ce1Wire); dsp.cec(1); dsp.cecarryin(1); dsp.cectrl(1); dsp.ced(1); dsp.ceinmode(1); dsp.cem(1); dsp.cep(1); // (cepReg); endrule rule driveInputs; opmode1Reg <= opmodeWire; opmode2Reg <= opmode1Reg; opmode3Reg <= opmode2Reg; opmode4Reg <= opmode3Reg; alumodeReg <= alumodeWire; c1Reg <= cWire; c2Reg <= c1Reg; c3Reg <= c2Reg; if (False) if (lastWire == 1 || last1Reg == 1 || last2Reg == 1 || last3Reg == 1 || last4Reg == 1 || last5Reg == 1) $display("%d: a=%h b=%h c=%h p=%h lastWire=%d", cycles, aWire, bWire, c3Reg, dsp.p(), lastWire); dsp.alumode(alumodeReg); dsp.carryinsel(carryinselWire); dsp.inmode(inmodeWire); dsp.opmode(opmode1Reg); dsp.a(aWire); dsp.b(bWire); dsp.c(c1Reg); //dsp.d(dWire); dsp.acin(0); dsp.bcin(0); dsp.carrycascin(0); dsp.carryin(0); dsp.pcin(0); endrule method Action alumode(Bit#(4) v); alumodeWire <= v; endmethod method Action carryinsel(Bit#(3) v); carryinselWire <= v; endmethod method Action inmode(Bit#(5) v); inmodeWire <= v; endmethod method Action opmode(Bit#(7) v); opmodeWire <= v; endmethod method Action a(Bit#(30) v); ce1Wire <= 1; aWire <= v; endmethod method Action b(Bit#(18) v); bWire <= v; endmethod method Action c(Bit#(48) v); cWire <= v; endmethod method Action d(Bit#(25) v); dsp.d(v); endmethod method Bool notEmpty(); return last5Reg == 1; endmethod method Bit#(48) p() if (last5Reg == 1); return dsp.p(); endmethod method Action deq() if (last5Reg == 1); endmethod method Action last(Bit#(1) v); lastWire <= v; endmethod endmodule `else module mkDsp48E1(Dsp48E1); let defaultReset <- exposeCurrentReset; let optionalReset = defaultReset; // noReset Reg#(Bit#(48)) accumReg <- mkReg(0); FIFO#(Bool) lastFifo <- mkSizedFIFO(3); FIFO#(Bit#(7)) opmodeFifo <- mkSizedFIFO(3); FIFOF#(Bit#(48)) pFifo <- mkSizedFIFOF(3); FIFO#(Bit#(30)) aFifo <- mkSizedFIFO(3); FIFO#(Bit#(18)) bFifo <- mkSizedFIFO(3); FIFO#(Bit#(48)) abFifo <- mkSizedFIFO(3); FIFO#(Bit#(48)) cFifo <- mkSizedFIFO(3); FIFO#(Bit#(25)) dFifo <- mkSizedFIFO(3); rule prod; let a <- toGet(aFifo).get(); let b <- toGet(bFifo).get(); abFifo.enq(extend(a)*extend(b)); endrule rule accum; let last <- toGet(lastFifo).get(); let opmode <- toGet(opmodeFifo).get(); let ab <- toGet(abFifo).get(); let c <- toGet(cFifo).get(); let d <- toGet(dFifo).get(); let accum = accumReg; if (opmode == 7'h05) accum = 0; if (opmode != 0) accum = accum + ab; accumReg <= accum; if (last) pFifo.enq(accum); endrule method Action alumode(Bit#(4) v); endmethod method Action carryinsel(Bit#(3) v); endmethod method Action inmode(Bit#(5) v); endmethod method Action opmode(Bit#(7) v); opmodeFifo.enq(v); endmethod method Action a(Bit#(30) v); aFifo.enq(v); endmethod method Action b(Bit#(18) v); bFifo.enq(v); endmethod method Action c(Bit#(48) v); cFifo.enq(v); endmethod method Action d(Bit#(25) v); dFifo.enq(v); endmethod method Bool notEmpty(); return pFifo.notEmpty(); endmethod method Action last(Bit#(1) v); lastFifo.enq(unpack(v)); endmethod method Bit#(48) p() if (pFifo.notEmpty()); return pFifo.first; endmethod method Action deq(); pFifo.deq(); endmethod endmodule `endif ================================================ FILE: bsv/GearboxGetPut.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import GetPut::*; import Gearbox::*; instance ToGet #(Gearbox #(m, 1, a), a); function Get #(a) toGet (Gearbox #(m, 1, a) gb); return (interface Get; method ActionValue #(a) get (); gb.deq (); return gb.first ()[0]; endmethod endinterface); endfunction endinstance instance ToGet #(Gearbox #(m, n, a), Vector#(n, a)); function Get #(Vector#(n,a)) toGet (Gearbox #(m, n, a) gb); return (interface Get; method ActionValue #(Vector#(n,a)) get (); gb.deq (); return gb.first (); endmethod endinterface); endfunction endinstance instance ToPut #(Gearbox #(m, n, a), Vector#(m, a)); function Put #(Vector#(m,a)) toPut (Gearbox #(m,n,a) gb); return (interface Put; method Action put(Vector#(m,a) v); gb.enq (v); endmethod endinterface); endfunction endinstance instance ToPut #(Gearbox #(1, n, a), a); function Put #(a) toPut (Gearbox #(1,n,a) gb); return (interface Put; method Action put(a v); gb.enq (vec(v)); endmethod endinterface); endfunction endinstance ================================================ FILE: bsv/GetPutM.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; typeclass ToGetM#(type atype, type btype); module toGetM#(atype m)(Get#(btype)); endtypeclass typeclass ToPutM#(type atype, type btype); module toPutM#(atype m)(Put#(btype)); endtypeclass ================================================ FILE: bsv/GetPutWithClocks.bsv ================================================ // Copyright (c) 2013,2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut :: *; import Connectable :: *; import ClientServer :: *; import Clocks :: *; import ConnectalMemTypes :: *; import FIFOF :: *; import ConnectalBramFifo::*; import Pipe :: *; import Probe::*; import SyncAxisFifo32x8::*; import AxiStream :: *; import Vector::*; `include "ConnectalProjectConfig.bsv" //////////////////////////////////////////////////////////////////////////////// /// Typeclass Definition //////////////////////////////////////////////////////////////////////////////// typeclass ConnectableWithClocks#(type a, type b); module mkConnectionWithClocks2#(a x1, b x2)(Empty); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, a x1, b x2)(Empty); endtypeclass instance ConnectableWithClocks#(Get#(a), Put#(a)) provisos ( Bits#(a, awidth), Add#(1, a__, awidth), Add#(b__, awidth, TMul#(TDiv#(awidth, 32), 32)), Add#(c__, TDiv#(awidth, 8), TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)), Mul#(TDiv#(awidth, 32), 4, TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, Get#(a) in, Put#(a) out)(Empty) provisos (Bits#(a, awidth), Add#(1, a__, awidth)); `ifndef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO SyncFIFOIfc#(a) synchronizer <- mkSyncFIFO(32, inClock, inReset, outClock); //FIFOF#(a) synchronizer <- mkDualClockBramFIFOF(inClock, inReset, outClock, outReset); let getProbe <- mkProbe(clocked_by inClock, reset_by inReset); let putProbe <- mkProbe(clocked_by outClock, reset_by outReset); rule mcwc_doGet; let v <- in.get(); getProbe <= v; synchronizer.enq(v); endrule rule mcwc_doPut; let v = synchronizer.first; putProbe <= v; synchronizer.deq; out.put(v); endrule `else SyncAxisFifo8#(awidth) fifo <- mkSyncAxisFifo8(inClock, inReset, outClock, outReset); mkConnection(in, fifo.s_axis, clocked_by inClock, reset_by inReset); mkConnection(fifo.m_axis, out, clocked_by outClock, reset_by outReset); `endif endmodule module mkConnectionWithClocks2#(Get#(a) in, Put#(a) out)(Empty) provisos (Bits#(a, awidth), Add#(1, a__, awidth)); Clock inClock = clockOf(in); Reset inReset = resetOf(in); Clock outClock = clockOf(out); Reset outReset = resetOf(out); mkConnectionWithClocks(inClock, inReset, outClock, outReset, in, out); endmodule: mkConnectionWithClocks2 endinstance: ConnectableWithClocks instance ConnectableWithClocks#(PipeOut#(a), Put#(a)) provisos ( Bits#(a, awidth), Add#(1, a__, awidth), Add#(b__, awidth, TMul#(TDiv#(awidth, 32), 32)), Add#(c__, TDiv#(awidth, 8), TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)), Mul#(TDiv#(awidth, 32), 4, TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, PipeOut#(a) in, Put#(a) out)(Empty) provisos (Bits#(a, awidth), Add#(1, a__, awidth)); `ifndef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO SyncFIFOIfc#(a) synchronizer <- mkSyncFIFO(8, inClock, inReset, outClock); //FIFOF#(a) synchronizer <- mkDualClockBramFIFOF(inClock, inReset, outClock, outReset); let deqProbe <- mkProbe(clocked_by inClock, reset_by inReset); let enqProbe <- mkProbe(clocked_by outClock, reset_by outReset); rule mcwc_doGet; let v = in.first; in.deq(); deqProbe <= v; synchronizer.enq(v); endrule rule mcwc_doPut; let v = synchronizer.first; enqProbe <= v; synchronizer.deq; out.put(v); endrule `else SyncAxisFifo8#(awidth) fifo <- mkSyncAxisFifo8(inClock, inReset, outClock, outReset); mkConnection(in, fifo.s_axis, clocked_by inClock, reset_by inReset); mkConnection(fifo.m_axis, out, clocked_by outClock, reset_by outReset); `endif endmodule module mkConnectionWithClocks2#(PipeOut#(a) in, Put#(a) out)(Empty) provisos (Bits#(a, awidth), Add#(1, a__, awidth)); Clock inClock = clockOf(in); Reset inReset = resetOf(in); Clock outClock = clockOf(out); Reset outReset = resetOf(out); mkConnectionWithClocks(inClock, inReset, outClock, outReset, in, out); endmodule: mkConnectionWithClocks2 endinstance: ConnectableWithClocks instance ConnectableWithClocks#(Get#(a), PipeIn#(a)) provisos ( Bits#(a, awidth), Add#(1, a__, awidth), Add#(b__, awidth, TMul#(TDiv#(awidth, 32), 32)), Add#(c__, TDiv#(awidth, 8), TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)), Mul#(TDiv#(awidth, 32), 4, TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, Get#(a) in, PipeIn#(a) out)(Empty) provisos (Bits#(a, awidth), Add#(1, a__, awidth)); `ifndef GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO SyncFIFOIfc#(a) synchronizer <- mkSyncFIFO(8, inClock, inReset, outClock); //FIFOF#(a) synchronizer <- mkDualClockBramFIFOF(inClock, inReset, outClock, outReset); let getProbe <- mkProbe(clocked_by inClock, reset_by inReset); let putProbe <- mkProbe(clocked_by outClock, reset_by outReset); rule mcwc_doGet; let v <- in.get(); getProbe <= v; synchronizer.enq(v); endrule rule mcwc_doEnq; let v = synchronizer.first; synchronizer.deq; putProbe <= v; out.enq(v); endrule `else SyncAxisFifo8#(awidth) fifo <- mkSyncAxisFifo8(inClock, inReset, outClock, outReset); mkConnection(in, fifo.s_axis, clocked_by inClock, reset_by inReset); mkConnection(fifo.m_axis, out, clocked_by outClock, reset_by outReset); `endif endmodule module mkConnectionWithClocks2#(Get#(a) in, PipeIn#(a) out)(Empty) provisos (Bits#(a, awidth), Add#(1, a__, awidth)); Clock inClock = clockOf(in); Reset inReset = resetOf(in); Clock outClock = clockOf(out); Reset outReset = resetOf(out); mkConnectionWithClocks(inClock, inReset, outClock, outReset, in, out); endmodule: mkConnectionWithClocks2 endinstance: ConnectableWithClocks instance ConnectableWithClocks#(Client#(a,b), Server#(a,b)) provisos (Bits#(a, awidth), Bits#(b, bwidth), Add#(1, a__, awidth), Add#(1, b__, bwidth), Add#(c__, TDiv#(awidth, 8), TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)), Add#(d__, TDiv#(bwidth, 8), TDiv#(TMul#(TDiv#(bwidth, 32), 32), 8)), Add#(e__, awidth, TMul#(TDiv#(awidth, 32), 32)), Add#(f__, bwidth, TMul#(TDiv#(bwidth, 32), 32)), Mul#(TDiv#(awidth, 32), 4, TDiv#(TMul#(TDiv#(awidth, 32), 32), 8)), Mul#(TDiv#(bwidth, 32), 4, TDiv#(TMul#(TDiv#(bwidth, 32), 32), 8)) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, Client#(a,b) client, Server#(a,b) server)(Empty) provisos (ConnectableWithClocks#(Get#(a), Put#(a)), ConnectableWithClocks#(Get#(b), Put#(b)), Bits#(a, awidth), Bits#(b, bwidth)); let reqCnx <- mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.request, server.request); let respCnx <- mkConnectionWithClocks(outClock, outReset, inClock, inReset, server.response, client.response); endmodule module mkConnectionWithClocks2#(Client#(a,b) client, Server#(a,b) server)(Empty) provisos (ConnectableWithClocks#(Get#(a), Put#(a)), ConnectableWithClocks#(Get#(b), Put#(b)), Bits#(a, awidth), Bits#(b, bwidth)); Clock inClock = clockOf(client); Reset inReset = resetOf(client); Clock outClock = clockOf(server); Reset outReset = resetOf(server); mkConnectionWithClocks(inClock, inReset, outClock, outReset, client, server); endmodule endinstance instance ConnectableWithClocks#(PhysMemReadClient#(addrWidth, dataWidth), PhysMemReadServer#(addrWidth, dataWidth)) provisos ( ConnectableWithClocks#(Get#(PhysMemRequest#(addrWidth,dataWidth)),Put#(PhysMemRequest#(addrWidth,dataWidth))), ConnectableWithClocks#(Get#(MemData#(dataWidth)),Put#(MemData#(dataWidth))) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, PhysMemReadClient#(addrWidth, dataWidth) client, PhysMemReadServer#(addrWidth, dataWidth) server)(Empty); let reqCnx <- mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.readReq, server.readReq); let dataCnx <- mkConnectionWithClocks(outClock, outReset, inClock, inReset, server.readData, client.readData); endmodule module mkConnectionWithClocks2#(PhysMemReadClient#(addrWidth, dataWidth) client, PhysMemReadServer#(addrWidth, dataWidth) server)(Empty); Clock inClock = clockOf(client); Reset inReset = resetOf(client); Clock outClock = clockOf(server); Reset outReset = resetOf(server); mkConnectionWithClocks(inClock, inReset, outClock, outReset, client, server); endmodule endinstance instance ConnectableWithClocks#(PhysMemWriteClient#(addrWidth, dataWidth), PhysMemWriteServer#(addrWidth, dataWidth)) provisos ( ConnectableWithClocks#(Get#(PhysMemRequest#(addrWidth, dataWidth)), Put#(PhysMemRequest#(addrWidth, dataWidth))), ConnectableWithClocks#(Get#(MemData#(dataWidth)),Put#(MemData#(dataWidth))) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, PhysMemWriteClient#(addrWidth, dataWidth) client, PhysMemWriteServer#(addrWidth, dataWidth) server)(Empty); let reqCnx <- mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.writeReq, server.writeReq); let dataCnx <- mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.writeData, server.writeData); let doneCnx <- mkConnectionWithClocks(outClock, outReset, inClock, inReset, server.writeDone, client.writeDone); endmodule module mkConnectionWithClocks2#(PhysMemWriteClient#(addrWidth, dataWidth) client, PhysMemWriteServer#(addrWidth, dataWidth) server)(Empty); Clock inClock = clockOf(client); Reset inReset = resetOf(client); Clock outClock = clockOf(server); Reset outReset = resetOf(server); mkConnectionWithClocks(inClock, inReset, outClock, outReset, client, server); endmodule endinstance instance ConnectableWithClocks#(PhysMemMaster#(addrWidth, dataWidth), PhysMemSlave#(addrWidth, dataWidth)) provisos ( ConnectableWithClocks#(PhysMemWriteClient#(addrWidth,dataWidth),PhysMemWriteServer#(addrWidth,dataWidth)) ); module mkConnectionWithClocks#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, PhysMemMaster#(addrWidth, dataWidth) client, PhysMemSlave#(addrWidth, dataWidth) server)(Empty); let readCnx <- mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.read_client, server.read_server); let writeCnx <- mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.write_client, server.write_server); endmodule module mkConnectionWithClocks2#(PhysMemMaster#(addrWidth, dataWidth) client, PhysMemSlave#(addrWidth, dataWidth) server)(Empty); Clock inClock = clockOf(client); Reset inReset = resetOf(client); Clock outClock = clockOf(server); Reset outReset = resetOf(server); mkConnectionWithClocks(inClock, inReset, outClock, outReset, client, server); endmodule endinstance module mkClockBinder#(a ifc) (a); return ifc; endmodule typeclass ConnectableWithGearbox#(type a, type b); module mkConnectionWithGearbox#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, a x1, b x2)(Empty); endtypeclass instance ConnectableWithGearbox#(PhysMemMaster#(addrWidth, masterdw), PhysMemSlave#(addrWidth, slavedw)) provisos ( Add#(a__, slavedw, masterdw), // master is wider than slave, i.e. master is at slower clock freq // Div#(slavedw, 32, slavedw), // Div#(masterdw, 32, masterdw), // Add#(TMul#(slavewords, 32), 0, slaveword), // 32-bit word aligned // Add#(TMul#(masterwords, 32), 0, masterword), // 32-bit word aligned // Div#(masterdw, slavedw, ratio), // Add#(0, TMul#(ratio, slavedw), masterdw), // ratio is integer // Add#(0, TExp#(TLog#(ratio)), ratio), // ratio is power of two Bits#(Vector#(ratio, Bit#(slavedw)), masterdw), ConnectableWithClocks#(Get#(PhysMemRequest#(addrWidth, slavedw)), Put#(PhysMemRequest#(addrWidth,slavedw))), ConnectableWithClocks#(Get#(PhysMemRequest#(addrWidth, masterdw)), Put#(PhysMemRequest#(addrWidth,masterdw))), ConnectableWithClocks#(Get#(MemData#(masterdw)), Put#(MemData#(masterdw))), ConnectableWithClocks#(Get#(MemData#(slavedw)), Put#(MemData#(slavedw))) ); module mkConnectionWithGearbox#(Clock inClock, Reset inReset, Clock outClock, Reset outReset, PhysMemMaster#(addrWidth, masterdw) client, PhysMemSlave#(addrWidth, slavedw) server)(Empty); // Gearbox#(1, ratio, Bit#(slavedw)) readGB <- mk1toNGearbox(outClock, outReset, inClock, inReset); // Gearbox#(ratio, 1, Bit#(slavedw)) writeGB <- mkNto1Gearbox(inClock, inReset, outClock, outReset); `ifndef BYTE_ENABLES let rdReqGet = (interface Get#(PhysMemRequest#(addrWidth,slavedw)); method ActionValue#(PhysMemRequest#(addrWidth,slavedw)) get; let req <- client.read_client.readReq.get; return PhysMemRequest{addr: req.addr, burstLen: req.burstLen, tag: req.tag}; endmethod endinterface); let wrReqGet = (interface Get#(PhysMemRequest#(addrWidth,slavedw)); method ActionValue#(PhysMemRequest#(addrWidth,slavedw)) get; let req <- client.write_client.writeReq.get; return PhysMemRequest{addr: req.addr, burstLen: req.burstLen, tag: req.tag}; endmethod endinterface); `endif Reg#(Bit#(TLog#(ratio))) rdBeats <- mkReg(0, clocked_by inClock, reset_by inReset); FIFOF#(MemData#(slavedw)) rdDataQ <- mkFIFOF(clocked_by inClock, reset_by inReset); Reg#(Bit#(masterdw)) rdData <- mkRegU(clocked_by inClock, reset_by inReset); rule doRdData; rdBeats <= rdBeats + 1; let rdPayload <- toGet(rdDataQ).get; let newReadData = truncateLSB({rdPayload.data,rdData}); rdData <= newReadData; if ( rdBeats == -1 ) client.read_client.readData.put(MemData{data:newReadData, tag: rdPayload.tag, last:rdPayload.last}); endrule Reg#(Bit#(TLog#(ratio))) wrBeats <- mkReg(0, clocked_by outClock, reset_by outReset); FIFOF#(MemData#(masterdw)) wrDataQ <- mkFIFOF(clocked_by outClock, reset_by outReset); //Reg#(MemData#(masterdw)) wrData <- mkRegU(clocked_by outClock, reset_by outReset); rule doWrData; wrBeats <= wrBeats + 1; let currMemData = wrDataQ.first; if ( wrBeats == -1 ) begin wrDataQ.deq; end Vector#(ratio, Bit#(slavedw)) payload = unpack(currMemData.data); server.write_server.writeData.put(MemData{data:payload[wrBeats], tag: currMemData.tag, last: currMemData.last && wrBeats == -1}); endrule GetPutWithClocks::mkConnectionWithClocks(inClock, inReset, outClock, outReset, client.write_client.writeData, toPut(wrDataQ)); GetPutWithClocks::mkConnectionWithClocks(outClock, outReset, inClock, inReset, server.read_server.readData, toPut(rdDataQ)); GetPutWithClocks::mkConnectionWithClocks(inClock, inReset, outClock, outReset, rdReqGet, server.read_server.readReq); GetPutWithClocks::mkConnectionWithClocks(inClock, inReset, outClock, outReset, wrReqGet, server.write_server.writeReq); GetPutWithClocks::mkConnectionWithClocks(outClock, outReset, inClock, inReset, server.write_server.writeDone, client.write_client.writeDone); // rule doReadDataEnq; // let v <- server.read_server.readData.get; // readGB.enq(unpack(v)); // endrule // rule doReadDataDeq; // let v = readGB.first; // readGB.deq; // client.read_client.readData.put(pack(v)); // endrule // rule doWriteDataEnq; // let v <- client.write_client.writeData.get; // writeGB.enq(unpack(v)); // endrule // rule doWriteDataDeq; // let v = writeGB.first; // writeGB.deq; // server.write_server.writeData.put(pack(v)); // endrule endmodule endinstance ================================================ FILE: bsv/HostInterface.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" ////////////////////////////// common ///////////////////////////////// ////////////////////////////// Bsim ///////////////////////////////// `ifdef BsimHostInterface import Vector :: *; import AxiMasterSlave :: *; import ConnectalMemTypes :: *; // this interface should allow for different master and slave bus paraters; interface BsimHost#(numeric type clientAddrWidth, numeric type clientBusWidth, numeric type clientIdWidth, numeric type serverAddrWidth, numeric type serverBusWidth, numeric type serverIdWidth, numeric type nSlaves); interface PhysMemMaster#(clientAddrWidth, clientBusWidth) mem_client; interface Vector#(nSlaves,PhysMemSlave#(serverAddrWidth, serverBusWidth)) mem_servers; interface Clock derivedClock; interface Reset derivedReset; endinterface typedef BsimHost#(32,32,12,40,DataBusWidth,6,NumberOfMasters) HostInterface; `endif ////////////////////////////// Xsim ///////////////////////////////// `ifdef XsimHostInterface import Vector :: *; import AxiMasterSlave :: *; import ConnectalMemTypes :: *; // this interface should allow for different master and slave bus paraters; interface XsimHost; interface Clock derivedClock; interface Reset derivedReset; interface Clock tsys_clk_200mhz_buf; endinterface module mkXsimHost#(Clock derivedClock, Reset derivedReset, Clock sys_clk)(XsimHost); interface derivedClock = derivedClock; interface derivedReset = derivedReset; interface tsys_clk_200mhz_buf = sys_clk; endmodule typedef XsimHost HostInterface; `endif ////////////////////////////// PciE ///////////////////////////////// `ifndef PcieHostIF `ifdef PcieHostInterface `define PcieHostIF `endif `endif `ifdef PcieHostIF `ifdef PCIE3 typedef TMin#(DataBusWidth, 128) PcieDataBusWidth; `else typedef TMin#(DataBusWidth, 128) PcieDataBusWidth; `endif import Vector :: *; import GetPut :: *; import ClientServer :: *; import BRAM :: *; import PCIE :: *; import Bscan :: *; import PcieCsr :: *; import PcieTracer :: *; import ConnectalMemTypes :: *; import Pipe :: *; `ifndef SIMULATION `ifdef XILINX `ifdef PCIE1 import PCIEWRAPPER :: *; import Pcie1EndpointX7 :: *; `endif // pcie1 `ifdef PCIE2 import PCIEWRAPPER2 :: *; import Pcie2EndpointX7 :: *; `endif // pcie2 `ifdef PCIE3 `ifdef XilinxUltrascale import PCIEWRAPPER3u ::*; `else import PCIEWRAPPER3 :: *; `endif import Pcie3EndpointX7 :: *; `endif `endif `ifdef ALTERA import PcieEndpointS5 :: *; `endif `endif typedef 40 PciePhysAddrWidth; interface PcieHost#(numeric type dsz, numeric type nSlaves); interface Vector#(16,ReadOnly_MSIX_Entry) msixEntry; interface PhysMemMaster#(32,32) master; interface Vector#(nSlaves,PhysMemSlave#(PciePhysAddrWidth,dsz)) slave; interface Put#(Tuple2#(Bit#(64),Bit#(32))) interruptRequest; `ifdef PCIE3 interface Client#(TLPData#(16), TLPData#(16)) pcir; interface Client#(TLPData#(16), TLPData#(16)) pcic; interface PipeIn#(Bit#(64)) changes; `else interface Client#(TLPData#(16), TLPData#(16)) pci; interface PipeIn#(Bit#(64)) changes; `endif interface Put#(TimestampedTlpData) trace; `ifdef PCIE_BSCAN interface BscanTop bscanif; `else `ifdef PCIE_TRACE_PORT interface BRAMServer#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData) traceBramServer; `endif `endif endinterface interface PcieHostTop; interface PcieHost#(PcieDataBusWidth, NumberOfMasters) tpciehost; `ifdef PCIE_CHANGES_HOSTIF interface PipeOut#(Bit#(64)) tchanges; `endif `ifdef XILINX `ifdef XILINX_SYS_CLK interface Clock tsys_clk_200mhz; interface Clock tsys_clk_200mhz_buf; `ifdef VirtexUltrascalePlus interface Clock tsys_clk_300mhz; interface Clock tsys_clk_300mhz_buf; interface Clock tsys_clk1_250mhz; interface Clock tsys_clk1_250mhz_buf; interface Clock tsys_clk2_250mhz; interface Clock tsys_clk2_250mhz_buf; `else `ifdef VirtexUltrascale interface Clock tsys_clk1_300mhz; interface Clock tsys_clk1_300mhz_buf; interface Clock tsys_clk2_300mhz; interface Clock tsys_clk2_300mhz_buf; `endif `endif `endif interface Clock tpci_clk_100mhz_buf; interface PcieEndpointX7#(PcieLanes) tep7; `endif `ifdef ALTERA interface PcieEndpointS5#(PcieLanes) tep7; `endif interface Clock pcieClock; interface Reset pcieReset; interface Clock portalClock; interface Reset portalReset; interface Clock derivedClock; interface Reset derivedReset; endinterface `endif `ifdef PcieHostInterface typedef PcieHostTop HostInterface; `endif ////////////////////////////// Zynq ///////////////////////////////// `ifdef ZynqHostInterface import PS7LIB::*; import Bscan::*; interface HostInterface; interface PS7 ps7; interface Clock portalClock; interface Reset portalReset; interface Clock derivedClock; interface Reset derivedReset; interface BscanTop bscan; `ifdef XILINX_SYS_CLK interface Clock tsys_clk_200mhz; interface Clock tsys_clk_200mhz_buf; `ifdef VirtexUltrascale interface Clock tsys_clk1_300mhz; interface Clock tsys_clk1_300mhz_buf; interface Clock tsys_clk2_300mhz; interface Clock tsys_clk2_300mhz_buf; `endif `endif endinterface //export PS7LIB::*; //export BscanTop; //export HostInterface; //export DataBusWidth; //export NumberOfMasters; //export PhysAddrWidth; `endif ================================================ FILE: bsv/LinkerLib.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; // Generic definitions that should go in a shared library. //typeclass InverseIFC#(type a, type b) //dependencies (a determines b, //b determines a); //endtypeclass interface GetInverter#(type a); interface Get#(a) mod; interface Put#(a) inverse; endinterface interface PutInverter#(type a); interface Put#(a) mod; interface Get#(a) inverse; endinterface interface LinkInverter#(type a); interface Put#(a) mod; interface Get#(a) inverse; method Bool modReady(); method Bool inverseReady(); endinterface import "BVI" GetInverter = module mkGetInverterBvi(GetInverter#(Bit#(asz))); let asz = valueOf(asz); parameter DATA_WIDTH = asz; default_clock (CLK); default_reset (RST); interface Get mod; method get get() enable(EN_get) ready (RDY_get); endinterface interface Put inverse; method put(put) enable (EN_put) ready (RDY_put); endinterface schedule (mod.get, inverse.put) CF (mod.get, inverse.put); endmodule module mkGetInverter(GetInverter#(a)) provisos (Bits#(a, asz)); let inverter <- mkGetInverterBvi(); interface Get mod; method ActionValue#(a) get(); let v <- inverter.mod.get(); return unpack(v); endmethod endinterface interface Put inverse; method Action put(a v); inverter.inverse.put(pack(v)); endmethod endinterface endmodule import "BVI" PutInverter = module mkPutInverterBvi(PutInverter#(Bit#(asz))); let asz = valueOf(asz); parameter DATA_WIDTH = asz; default_clock (CLK); default_reset (RST); interface Put mod; method put(put) enable(EN_put) ready (RDY_put); endinterface interface Get inverse; method get get() enable (EN_get) ready (RDY_get); endinterface schedule (mod.put, inverse.get) CF (mod.put, inverse.get); endmodule module mkPutInverter(PutInverter#(a)) provisos (Bits#(a, asz)); let inverter <- mkPutInverterBvi(); interface Put mod; method Action put(a v); inverter.mod.put(pack(v)); endmethod endinterface interface Get inverse; method ActionValue#(a) get(); let v <- inverter.inverse.get(); return unpack(v); endmethod endinterface endmodule import "BVI" LinkInverter = module mkLinkInverterBvi(LinkInverter#(Bit#(asz))); let asz = valueOf(asz); parameter DATA_WIDTH = asz; default_clock (CLK); default_reset (RST); interface Put mod; method put(put) enable(EN_put) ready (RDY_put); endinterface interface Get inverse; method get get() enable (EN_get) ready (RDY_get); endinterface method modReady modReady(); method inverseReady inverseReady(); schedule (mod.put, inverse.get, modReady, inverseReady) CF (mod.put, inverse.get, modReady, inverseReady); endmodule module mkLinkInverter(LinkInverter#(a)) provisos (Bits#(a, asz)); let inverter <- mkLinkInverterBvi(); interface Put mod; method Action put(a v); inverter.mod.put(pack(v)); endmethod endinterface interface Get inverse; method ActionValue#(a) get(); let v <- inverter.inverse.get(); return unpack(v); endmethod endinterface method Bool modReady(); return inverter.modReady(); endmethod method Bool inverseReady(); return inverter.inverseReady(); endmethod endmodule ================================================ FILE: bsv/MIFO.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import Arith ::*; import FIFOF ::*; import GetPut::*; import Pipe ::*; import MIMO ::*; //LUInt interface MIFO#(numeric type max_in, numeric type n_out, numeric type size, type t); method Action enq(LUInt#(max_in) count, Vector#(max_in, t) data); method Vector#(n_out, t) first(); method Action deq(); (* always_ready *) method Bool enqReady(); (* always_ready *) method Bool deqReady(); endinterface instance ToGet #(MIFO #(max_in, n_out, size, a), Vector#(n_out, a)); function Get #(Vector#(n_out, a)) toGet (MIFO #(max_in, n_out, size, a) mifo); return (interface Get; method ActionValue #(Vector#(n_out, a)) get (); mifo.deq (); return mifo.first (); endmethod endinterface); endfunction endinstance module mkMIFO(MIFO#(max_in, n_out, size, t)) provisos (Log#(max_in, max_in_sz), Log#(n_out, n_out_sz), Add#(n_out, a__, max_in), Add#(1, b__, n_out), Bits#(t, c__), Bits#(Vector#(max_in, t), d__), Add#(e__, max_in_sz, TLog#(TAdd#(max_in, 1))), Add#(f__, 2, max_in_sz) ); FIFOF#(Vector#(max_in, t)) inFifo <- mkFIFOF(); FIFOF#(UInt#(max_in_sz)) posFifo <- mkFIFOF(); FIFOF#(LUInt#(max_in)) inCountFifo <- mkFIFOF(); FIFOF#(Bit#(max_in)) weFifo <- mkFIFOF(); Vector#(max_in, FIFOF#(t)) fifos <- replicateM(mkSizedFIFOF(valueOf(size))); Reg#(UInt#(max_in_sz)) inPos <- mkReg(0); Reg#(UInt#(max_in_sz)) outPos <- mkReg(0); LUInt#(max_in) i_max_in = fromInteger(valueOf(max_in)); let verbose = False; function a fifoFirst(FIFOF#(a) fifo); if (fifo.notEmpty()) return fifo.first(); else return ?; endfunction function Bool fifoNotEmpty(FIFOF#(a) fifo); return fifo.notEmpty(); endfunction function Bool fifoNotFull(FIFOF#(a) fifo); return fifo.notFull(); endfunction FIFOF#(Bool) checkInFifo <- mkFIFOF(); rule checkin if (verbose); let v <- toGet(checkInFifo).get(); $display("checkIn: inPos=%d outPos=%d notEmpties: %h notFulls: %h values: %h", inPos, outPos, map(fifoNotEmpty, fifos), map(fifoNotFull, fifos), map(fifoFirst, fifos)); endrule rule tofifos; let values = inFifo.first; let count = inCountFifo.first; let pos = posFifo.first; let we = weFifo.first; Bool ready = True; // for (Integer i = 0; i < valueOf(max_in); i = i+1) begin // if (we[i] == 1) // ready = ready && fifos[i].notFull(); // end if (ready) begin for (Integer i = 0; i < valueOf(max_in); i = i+1) begin if (we[i] == 1) fifos[i].enq(values[i]); end inFifo.deq(); inCountFifo.deq(); weFifo.deq(); posFifo.deq(); if (verbose) begin $display("tofifos: pos=%d count=%d we=%h", pos, count, we, " values: %h notFull: %h", values, map(fifoNotFull, fifos)); checkInFifo.enq(True); end end endrule function Bool deqReadyInternal(); LUInt#(max_in) rot = i_max_in - extend(outPos); Vector#(n_out, Bool) notEmpties = take(rotateBy(map(fifoNotEmpty, fifos), truncate(rot))); return fold(booland, notEmpties); endfunction FIFOF#(Bool) checkFifo <- mkFIFOF(); rule check if (verbose); let v <- toGet(checkFifo).get(); LUInt#(max_in) rot = i_max_in - extend(outPos); Vector#(max_in, Bool) allNotEmpties = map(fifoNotEmpty, fifos); Vector#(max_in, Bool) notEmpties = rotateBy(map(fifoNotEmpty, fifos), truncate(rot)); Vector#(4, Bool) testv = replicate(False); testv[outPos] = True; UInt#(2) testpos = 3 - truncate(outPos); Vector#(4, Bool) rotatedTestv = rotateBy(testv, 1); if (verbose) $display("check outPos: ", outPos, " notEmpty: ", fifos[outPos].notEmpty(), " notEmpties: ", notEmpties, " allNotEmpties: %h", allNotEmpties); endrule method Action enq(LUInt#(max_in) count, Vector#(max_in, t) data); function Bool lessThanCount(Integer i); return fromInteger(i) < count; endfunction Vector#(max_in, Bool) we = genWith(lessThanCount); inFifo.enq(rotateBy(data, inPos)); inCountFifo.enq(count); weFifo.enq(pack(rotateBy(we, inPos))); posFifo.enq(inPos); inPos <= truncate((extend(inPos) + count) % i_max_in); if (verbose) $display("enq: inPos=%d we=%h", inPos, we); endmethod method Vector#(n_out, t) first if (deqReadyInternal()); function t firstN(Integer i); return fifos[(extend(outPos) + fromInteger(i)) % i_max_in].first; endfunction return genWith(firstN); endmethod method Action deq() if (deqReadyInternal()); function t firstN(Integer i); return fifos[(extend(outPos) + fromInteger(i)) % i_max_in].first; endfunction for (Integer i = 0; i < valueOf(n_out); i = i+1) fifos[(extend(outPos) + fromInteger(i)) % i_max_in].deq(); UInt#(max_in_sz) nextOutPos = truncate((extend(outPos) + fromInteger(valueOf(n_out))) % i_max_in); outPos <= nextOutPos; if (verbose) begin LUInt#(max_in) rot = i_max_in - extend(outPos); Vector#(n_out, t) v = genWith(firstN); Vector#(max_in, Bool) allNotEmpties = rotateBy(map(fifoNotEmpty, fifos), truncate(rot)); Vector#(n_out, Bool) notEmpties = take(map(fifoNotEmpty, rotateBy(fifos, truncate(rot)))); $display("first: ", v, " outPos: ", outPos, " nextOutPos: ", nextOutPos, " nextNotEmpty: ", fifos[nextOutPos].notEmpty(), " notEmpties: ", notEmpties, " allNotEmpties: %h", allNotEmpties); checkFifo.enq(True); end endmethod method Bool enqReady = inFifo.notFull; method Bool deqReady = deqReadyInternal; endmodule interface FIMO#(numeric type n_in, numeric type max_out, numeric type size, type t); interface PipeIn#(Vector#(n_in, t)) in; interface Vector#(TAdd#(max_out,1), PipeOut#(Vector#(max_out, t))) out; endinterface module mkFIMO(FIMO#(n_in, max_out, size, t)) provisos (Log#(n_in, n_in_sz), Log#(max_out, max_out_sz), Add#(n_in, a__, max_out), Add#(1, b__, max_out), Bits#(t, c__), Add#(d__, max_out_sz, TLog#(TAdd#(max_out, 1))) ); FIFOF#(Vector#(max_out, t)) inFifo <- mkFIFOF(); FIFOF#(UInt#(max_out_sz)) posFifo <- mkFIFOF(); FIFOF#(Bit#(max_out)) weFifo <- mkFIFOF(); Vector#(max_out, FIFOF#(t)) fifos <- replicateM(mkFIFOF()); Reg#(UInt#(max_out_sz)) inPos <- mkReg(0); Reg#(UInt#(max_out_sz)) outPos <- mkReg(0); LUInt#(max_out) i_n_in = fromInteger(valueOf(n_in)); LUInt#(max_out) i_max_out = fromInteger(valueOf(max_out)); let verbose = False; function a fifoFirst(FIFOF#(a) fifo); if (fifo.notEmpty()) return fifo.first(); else return ?; endfunction function Bool fifoNotEmpty(FIFOF#(a) fifo); return fifo.notEmpty(); endfunction function Bool fifoNotFull(FIFOF#(a) fifo); return fifo.notFull(); endfunction FIFOF#(Bool) checkInFifo <- mkFIFOF(); rule checkin if (verbose); let v <- toGet(checkInFifo).get(); $display("checkIn: inPos=%d outPos=%d notEmpties: %h notFulls: %h values: %h", inPos, outPos, map(fifoNotEmpty, fifos), map(fifoNotFull, fifos), map(fifoFirst, fifos)); endrule rule tofifos; let values = inFifo.first; let pos = posFifo.first; let we = weFifo.first; Bool ready = True; // for (Integer i = 0; i < valueOf(max_out); i = i+1) begin // if (we[i] == 1) // ready = ready && fifos[i].notFull(); // end $display("tofifos: we=%h", we); if (ready) begin for (Integer i = 0; i < valueOf(max_out); i = i+1) begin if (we[i] == 1) fifos[i].enq(values[i]); end inFifo.deq(); weFifo.deq(); posFifo.deq(); if (verbose) begin $display("tofifos: pos=%d we=%h", pos, we, " values: %h notFull: %h", values, map(fifoNotFull, fifos)); checkInFifo.enq(True); end end endrule function Bool deqReadyInternal(Integer n_out); LUInt#(max_out) rot = i_max_out - extend(outPos); Vector#(max_out, Bool) notEmpties = rotateBy(map(fifoNotEmpty, fifos), truncate(rot)); function Bool n_notEmpty(Integer i); if (i < n_out) return notEmpties[i]; else return True; endfunction Vector#(max_out, Bool) n_notEmpties = genWith(n_notEmpty); return fold(booland, n_notEmpties); endfunction FIFOF#(Bool) checkFifo <- mkFIFOF(); rule check if (verbose); let v <- toGet(checkFifo).get(); LUInt#(max_out) rot = i_max_out - extend(outPos); Vector#(max_out, Bool) allNotEmpties = map(fifoNotEmpty, fifos); Vector#(max_out, Bool) notEmpties = rotateBy(map(fifoNotEmpty, fifos), truncate(rot)); if (verbose) $display("check outPos: ", outPos, " notEmpty: ", fifos[outPos].notEmpty(), " notEmpties: ", notEmpties, " allNotEmpties: %h", allNotEmpties); endrule function PipeIn#(Vector#(n_in, t)) genInPipe(Integer i); return (interface PipeIn#(Vector#(n_in, t)) method Action enq(Vector#(n_in, t) data); function Bool lessThanCount(Integer i); return fromInteger(i) < i_n_in; endfunction Vector#(max_out, Bool) we = genWith(lessThanCount); Vector#(max_out, t) wdata = append(data, replicate(?)); inFifo.enq(rotateBy(wdata, inPos)); posFifo.enq(inPos); weFifo.enq(pack(rotateBy(we, inPos))); inPos <= truncate((extend(inPos) + extend(i_n_in)) % i_max_out); if (verbose) begin $display("enq: inPos=%d we=%h", inPos, we); end endmethod method notFull = inFifo.notFull; endinterface); endfunction function PipeOut#(Vector#(max_out, t)) genOutPipe(Integer n_out); function t firstN(Integer i); if (i < n_out) return fifos[(extend(outPos) + fromInteger(i)) % i_max_out].first; else return ?; endfunction PipeOut#(Vector#(max_out, t)) pipeOut = (interface PipeOut#(Vector#(max_out, t)) method Vector#(max_out, t) first if (deqReadyInternal(n_out)); return genWith(firstN); endmethod method Action deq() if (deqReadyInternal(n_out)); for (Integer i = 0; i < n_out; i = i+1) fifos[(extend(outPos) + fromInteger(i)) % i_max_out].deq(); UInt#(max_out_sz) nextOutPos = truncate((extend(outPos) + fromInteger(valueOf(max_out))) % i_max_out); outPos <= nextOutPos; if (verbose) begin LUInt#(max_out) rot = i_max_out - extend(outPos); Vector#(max_out, t) v = genWith(firstN); Vector#(max_out, Bool) allNotEmpties = rotateBy(map(fifoNotEmpty, fifos), truncate(rot)); Vector#(max_out, Bool) notEmpties = map(fifoNotEmpty, rotateBy(fifos, truncate(rot))); $display("first: ", v, " outPos: ", outPos, " nextOutPos: ", nextOutPos, " nextNotEmpty: ", fifos[nextOutPos].notEmpty(), " notEmpties: ", notEmpties, " allNotEmpties: %h", allNotEmpties); checkFifo.enq(True); end endmethod method notEmpty = deqReadyInternal(n_out); endinterface); return pipeOut; endfunction interface Vector in = genInPipe(0); interface Vector out = genWith(genOutPipe); endmodule ================================================ FILE: bsv/MemPipe.bsv ================================================ // Copyright (c) 2015 Connectal Project. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import GetPut::*; import ClientServer::*; import BRAM::*; import Vector::*; import Probe::*; import ConnectalMemTypes::*; import Pipe::*; import ConfigCounter::*; interface MemReaderPipe#(numeric type dsz); interface PipeOut#(MemData#(dsz)) data; interface MemReadClient#(dsz) readClient; endinterface module mkMemReaderPipe#(Reg#(SGLId) ptrReg, IteratorIfc#(Bit#(addrsz)) addrIterator, Bit#(BurstLenSize) burstLen)(MemReaderPipe#(dsz)) provisos (Add#(a__, addrsz, MemOffsetSize), Add#(b__, BurstLenSize, addrsz)); let verbose = False; ConfigCounter#(addrsz) counter <- mkConfigCounter(0); FIFO#(MemRequest) readReqFifo <- mkFIFO(); FIFOF#(MemData#(dsz)) readDataFifo <- mkSizedFIFOF(8); Reg#(Bit#(MemTagSize)) tagReg <- mkReg(0); // 8+1 outstanding reads rule startReadReqRule if (counter.read() <= (extend(unpack(burstLen)) << 3)); counter.increment(extend(unpack(burstLen))); let offset <- toGet(addrIterator.pipe).get(); let tag = tagReg; if (addrIterator.isFirst()) tag = 0; if (verbose) $display("startReadReqRule: offset=%d counter=%d", offset, counter.read() + (extend(unpack(burstLen)) << 3)); readReqFifo.enq(MemRequest { sglId: ptrReg, offset: extend(offset), burstLen: burstLen, tag: extend(tag) }); tagReg <= tag + 1; endrule interface data = toPipeOut(readDataFifo); interface MemReadClient readClient; interface Get readReq = toGet(readReqFifo); interface Put readData; method Action put(MemData#(dsz) md); readDataFifo.enq(md); counter.decrement(fromInteger(valueOf(TDiv#(dsz,8)))); if (verbose) $display("memreader.readData counter.read() %d", counter.read()); endmethod endinterface endinterface endmodule interface MemWriterPipe#(numeric type dsz); interface PipeOut#(Bool) lastPipe; interface MemWriteClient#(dsz) writeClient; endinterface module mkMemWriterPipe#(Reg#(SGLId) ptrReg, IteratorIfc#(Bit#(addrsz)) addrIterator, PipeOut#(dtype) dataPipe, Bit#(BurstLenSize) burstLen)(MemWriterPipe#(dsz)) provisos (Bits#(dtype, dsz), Add#(a__, addrsz, MemOffsetSize), Add#(b__, BurstLenSize, addrsz)); ConfigCounter#(addrsz) counter <- mkConfigCounter(0); FIFO#(MemRequest) reqFifo <- mkSizedFIFO(4); FIFO#(MemRequest) writeReqFifo <- mkFIFO(); FIFOF#(MemData#(dsz)) writeDataFifo <- mkSizedFIFOF(4); FIFO#(Bit#(MemTagSize)) writeDoneFifo <- mkSizedFIFO(4); FIFOF#(Bool) lastFifo <- mkSizedFIFOF(4); FIFOF#(Bool) doneFifo <- mkSizedFIFOF(4); rule writeReqRule; let offset <- toGet(addrIterator.pipe).get(); let tag = 22; $display("writeReqRule: offset=%h burstLen=%d addrIterator.isLast %d", offset, burstLen, addrIterator.isLast()); reqFifo.enq(MemRequest { sglId: ptrReg, offset: extend(offset), burstLen: burstLen, tag: tag }); lastFifo.enq(addrIterator.isLast()); endrule rule writeReqReadyRule if (counter.read() >= extend(unpack(burstLen))); let req <- toGet(reqFifo).get(); writeReqFifo.enq(req); counter.decrement(extend(unpack(burstLen))); endrule rule writeDataRule; let tag = 22; let v <- toGet(dataPipe).get(); //$display("MemWriterPipe.writeDataRule: data=%h", v); writeDataFifo.enq(MemData { data: pack(v), tag: tag, last: False }); counter.increment(fromInteger(valueOf(TDiv#(dsz,8)))); endrule rule writeDone; let last <- toGet(lastFifo).get(); let tag <- toGet(writeDoneFifo).get(); doneFifo.enq(last); endrule interface PipeOut lastPipe = toPipeOut(doneFifo); interface MemWriteClient writeClient; interface Get writeReq = toGet(writeReqFifo); interface Get writeData = toGet(writeDataFifo); interface Put writeDone = toPut(writeDoneFifo); endinterface endmodule module mkMemWriterPipe2#(Bool lastOnly, Reg#(SGLId) ptrReg, IteratorWithContext#(Bit#(addrsz),Bit#(MemTagSize)) addrIterator, PipeOut#(dtype) dataPipe, Bit#(BurstLenSize) burstLen)(MemWriterPipe#(dsz)) provisos (Bits#(dtype, dsz), Add#(a__, addrsz, MemOffsetSize), Add#(b__, BurstLenSize, addrsz)); ConfigCounter#(addrsz) counter <- mkConfigCounter(0); FIFO#(MemRequest) reqFifo <- mkSizedFIFO(4); FIFO#(MemRequest) writeReqFifo <- mkFIFO(); FIFOF#(MemData#(dsz)) writeDataFifo <- mkSizedFIFOF(4); FIFO#(Bit#(MemTagSize)) writeDoneFifo <- mkSizedFIFO(4); FIFOF#(Bool) lastFifo <- mkSizedFIFOF(4); FIFOF#(Bool) doneFifo <- mkFIFOF(); rule writeReqRule; let iv <- toGet(addrIterator.ivpipe).get(); let offset = iv.value; let tag = 22; $display("MemWriterPipe2.writeReqRule: offset=%h burstLen=%d addrIterator.isLast %d", offset, burstLen, addrIterator.isLast()); reqFifo.enq(MemRequest { sglId: ptrReg, offset: extend(offset), burstLen: burstLen, tag: tag }); lastFifo.enq(iv.last); endrule rule writeReqReadyRule if (counter.read() >= extend(unpack(burstLen))); let req <- toGet(reqFifo).get(); writeReqFifo.enq(req); counter.decrement(extend(unpack(burstLen))); endrule rule writeDataRule; let tag = 22; let v <- toGet(dataPipe).get(); $display("MemWriterPipe2.writeDataRule: data=%h", v); writeDataFifo.enq(MemData { data: pack(v), tag: tag, last: False }); counter.increment(fromInteger(valueOf(TDiv#(dsz,8)))); endrule rule writeDone; let last <- toGet(lastFifo).get(); let tag <- toGet(writeDoneFifo).get(); if (!lastOnly || last) begin $display("writeDone lastOnly=%d last=%d", lastOnly, last); doneFifo.enq(last); end endrule interface PipeOut lastPipe = toPipeOut(doneFifo); interface MemWriteClient writeClient; interface Get writeReq = toGet(writeReqFifo); interface Get writeData = toGet(writeDataFifo); interface Put writeDone = toPut(writeDoneFifo); endinterface endmodule module mkBramReaderPipe#(BRAMServer#(Bit#(addrsz), dataType) bramServer, PipeOut#(IteratorValue#(Bit#(addrsz),void)) addrIterator)(PipeOut#(IteratorValue#(dataType,void))) provisos (Add#(a__, addrsz, MemOffsetSize), Bits#(dataType,dsz)); FIFOF#(Tuple2#(Bool,Bool)) firstlastFifo <- mkFIFOF(); FIFOF#(IteratorValue#(dataType,void)) readDataFifo <- mkFIFOF(); let verbose = False; rule issueBramReadRequest; let item <- toGet(addrIterator).get(); bramServer.request.put(BRAMRequest{write: False, responseOnWrite: False, address: item.value, datain: unpack(0)}); firstlastFifo.enq(tuple2(item.first, item.last)); if (verbose) $display("issueBramReadRequest addr=%h first=%d last=%d", item.value, item.first, item.last); endrule rule readData; let v <- bramServer.response.get(); match { .first, .last } <- toGet(firstlastFifo).get(); readDataFifo.enq(IteratorValue { value: v, first: first, last: last }); endrule return toPipeOut(readDataFifo); endmodule module mkBramReaderPipeV#(Vector#(n, BRAMServer#(Bit#(addrsz), dataType)) bramServer, PipeOut#(IteratorValue#(Bit#(addrsz),void)) addrIterator)(PipeOut#(IteratorValue#(Vector#(n,dataType),void))) provisos (Add#(a__, addrsz, MemOffsetSize), Bits#(dataType,dsz)); FIFOF#(Tuple2#(Bool,Bool)) firstlastFifo <- mkFIFOF(); FIFOF#(IteratorValue#(Vector#(n,dataType),void)) readDataFifo <- mkFIFOF(); let verbose = False; rule issueBramReadRequest; let item <- toGet(addrIterator).get(); for (Integer i = 0; i < valueOf(n); i = i + 1) bramServer[i].request.put(BRAMRequest{write: False, responseOnWrite: False, address: item.value, datain: unpack(0)}); firstlastFifo.enq(tuple2(item.first, item.last)); if (verbose) $display("issueBramReadRequest addr=%h first=%d last=%d", item.value, item.first, item.last); endrule rule readData; Vector#(n, dataType) vs = unpack(0); for (Integer i = 0; i < valueOf(n); i = i + 1) vs[i] <- bramServer[i].response.get(); match { .first, .last } <- toGet(firstlastFifo).get(); readDataFifo.enq(IteratorValue { value: vs, first: first, last: last }); endrule return toPipeOut(readDataFifo); endmodule interface BramWriterPipe#(numeric type dsz); interface PipeOut#(Bool) lastPipe; endinterface module mkBramWriterPipe#(BRAMServer#(Bit#(addrsz), dtype) bramServer, IteratorIfc#(Bit#(addrsz)) addrIterator, PipeOut#(dtype) dataPipe)(BramWriterPipe#(dsz)) provisos (Bits#(dtype, dsz), Add#(a__, addrsz, MemOffsetSize)); FIFOF#(Bool) lastFifo <- mkFIFOF(); FIFOF#(Bool) doneFifo <- mkFIFOF(); Reg#(Bit#(32)) wrrCount <- mkReg(0); Reg#(Bit#(32)) wdoneCount <- mkReg(0); rule writeReqRule; let offset <- toGet(addrIterator.pipe).get(); let v <- toGet(dataPipe).get(); wrrCount <= wrrCount + 1; //$display("BramWriter.writeReqRule: offset=%h addrIterator.isLast %d wrr %d", offset, addrIterator.isLast(), wrrCount); bramServer.request.put(BRAMRequest { write: True, responseOnWrite: False, address: offset, datain: v }); lastFifo.enq(addrIterator.isLast()); endrule rule writeDone; let last <- toGet(lastFifo).get(); //$display("writeDone: wdoneCount=%d last=%d", wdoneCount, last); wdoneCount <= wdoneCount + 1; doneFifo.enq(last); endrule interface PipeOut lastPipe = toPipeOut(doneFifo); endmodule ================================================ FILE: bsv/MemReadEngine.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import Cntrs::*; import FIFOF::*; import FIFO::*; import GetPut::*; import Assert::*; import ClientServer::*; import BRAM::*; import BRAMFIFO::*; import ConfigCounter::*; import Connectable::*; import ConnectalMemory::*; import ConnectalBramFifo::*; import ConnectalMemTypes::*; import Pipe::*; import ConnectalMemUtils::*; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" typedef 2 MemReadFunnelBPC; module mkMemReadEngine(MemReadEngine#(busWidth, userWidth, cmdQDepth, numServers)) provisos( Mul#(TDiv#(busWidth, 8), 8, busWidth) ,Add#(1, a__, numServers) ,Add#(busWidth, 0, userWidth) // ,Min#(MemReadFunnelBPC, TLog#(numServers), bpc) ,Add#(0,MemReadFunnelBPC,bpc) ,FunnelPipesPipelined#(1, numServers, ConnectalMemTypes::MemData#(userWidth), bpc) ,Pipe::FunnelPipesPipelined#(1, numServers, ConnectalMemTypes::MemRequest, bpc) ,Add#(b__, TLog#(numServers), MemTagSize) ); let rv <- mkMemReadEngineBuff(valueOf(cmdQDepth) * valueOf(TExp#(BurstLenSize))); return rv; endmodule typedef struct { Bit#(BurstLenSize) len; Bool last; } NextReq deriving (Bits, Eq); function NextReq getNext(Bit#(32) len, Bit#(BurstLenSize) burst); NextReq v; v.last = (len <= extend(burst)); v.len = v.last ? truncate(len) : burst; return v; endfunction interface MemReadChannel#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth); interface PipeOut#(MemRequest) readReq; interface PipeIn#(MemData#(busWidth)) readData; interface MemReadEngineServer#(userWidth) readServer; endinterface module mkMemReadChannel#(Integer bufferSizeBytes, Integer channelNumber, PipeOut#(MemData#(userWidth)) dataPipe) (MemReadChannel#(busWidth, userWidth, cmdQDepth)) provisos (Div#(busWidth,8,busWidthBytes), Mul#(busWidthBytes,8,busWidth), Log#(busWidthBytes,beatShift), Log#(cmdQDepth,logCmdQDepth), Add#(busWidth, 0, userWidth), Add#(1,logCmdQDepth, outCntSz)); let verbose = False; let beatShift = fromInteger(valueOf(beatShift)); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Integer bufferSizeBeats = bufferSizeBytes/valueOf(busWidthBytes); Reg#(Bool) clientInFlight <- mkReg(False); ConfigCounter#(16) clientAvail <- mkConfigCounter(fromInteger(bufferSizeBeats)); Reg#(MemengineCmd) clientCommand <- mkReg(unpack(0)); `ifdef USE_DUAL_CLOCK_FIFOF FIFOF#(MemDataF#(userWidth)) clientDataFifo <- mkDualClockBramFIFOF(clock, reset, clock, reset); `else FIFOF#(MemDataF#(userWidth)) clientDataFifo <- mkSizedBRAMFIFOF(bufferSizeBeats); `endif FIFO#(MemengineCmd) clientRequest <- mkFIFO(); Reg#(Bit#(32)) clientLen <- mkReg(unpack(0)); Reg#(Bit#(32)) clientBase <- mkReg(unpack(0)); Reg#(NextReq) clientNext <- mkReg(unpack(0)); Count#(Bit#(32)) clientCycles <- mkCount(0); FIFOF#(MemRequestCycles) clientCyclesFifo <- mkFIFOF(); FIFO#(Tuple3#(Bool,Bool,Bit#(BurstLenSize))) serverCheckAvail <- mkSizedFIFO(1); FIFOF#(MemRequest) dmaRequest <- mkSizedFIFOF(valueOf(cmdQDepth)); FIFO#(Tuple3#(Bit#(BurstLenSize),Bit#(MemTagSize),Bool)) serverProcessing <- mkSizedFIFO(valueOf(cmdQDepth)); FIFOF#(MemData#(busWidth)) serverDataFifo <- mkFIFOF; Reg#(Bit#(BurstLenSize)) respCnt <- mkReg(0); Reg#(Bit#(32)) counter <- mkReg(0); rule incCounter; counter <= counter + 1; endrule rule rule_cycles; clientCycles.incr(1); endrule rule rule_startNew if (!clientInFlight); let cmd <- toGet(clientRequest).get(); clientInFlight <= True; clientCommand <= cmd; clientLen <= cmd.len - extend(cmd.burstLen); clientBase <= cmd.base; clientNext <= getNext(cmd.len, cmd.burstLen); clientCycles <= 0; if (verbose) $display("mkMemReadEngineBuff::%d rule_startNew %d", counter, clientAvail.read); endrule rule rule_checkAvail if (clientInFlight); let cmd_len = clientNext.len; let last_burst = clientNext.last; let cond0 <- clientAvail.maybeDecrement(unpack(extend(cmd_len>>beatShift))); serverCheckAvail.enq(tuple3(cond0,last_burst,cmd_len)); if (verbose) $display("mkMemReadEngineBuff::%d chan=%d rule_checkAvail avail %d burstLen %d cond0 %d last_burst %d", counter, channelNumber, clientAvail.read(), cmd_len>>beatShift, cond0, last_burst); endrule rule rule_requestServer if (clientInFlight); match {.cond0,.last_burst,.cmd_len} <- toGet(serverCheckAvail).get; if (cond0) begin if (verbose) $display("mkMemReadEngineBuff::%d chan=%d rule_requestServer clientLen %d cond0 %d last_burst %d", counter, channelNumber, clientLen, cond0, last_burst); serverProcessing.enq(tuple3(truncate(cmd_len>>beatShift), clientCommand.tag, last_burst)); if (verbose) $display("MemReadEngine::%d chan=%d readReq idx %d offset %h burstLenBytes %h last %d", counter, channelNumber, 0, clientBase, cmd_len, last_burst); dmaRequest.enq(MemRequest { sglId: clientCommand.sglId, offset: extend(clientBase), burstLen:cmd_len, tag: fromInteger(channelNumber) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }); clientBase <= clientBase + extend(cmd_len); clientLen <= clientLen - extend(cmd_len); clientNext <= getNext(clientLen, clientCommand.burstLen); if (last_burst) begin if (verbose) $display("mkMemReadEngineBuff::%d chan=%d rule_requestServer last_burst %d", counter, channelNumber, last_burst); clientInFlight <= False; `ifdef MEMENGINE_REQUEST_CYCLES $display("clientCycles = %d", clientCycles); clientCyclesFifo.enq(MemRequestCycles { tag:clientCommand.tag, cycles: clientCycles }); `endif end end endrule rule read_data_rule; let d <- toGet(dataPipe).get(); match {.rc, .tag, .last_burst} = serverProcessing.first; let new_respCnt = respCnt+1; let l = False; if (verbose) $display("mkMemReadEngineBuff::%d chan=%d data %h new_respCnt %d rc %d last_burst %d tag %d clientInFlight %d eob %d", counter, channelNumber, d.data, new_respCnt, rc, last_burst, tag, clientInFlight, d.last); if (new_respCnt == rc) begin respCnt <= 0; serverProcessing.deq; l = last_burst; end else begin respCnt <= new_respCnt; end clientDataFifo.enq(MemDataF { data: d.data, tag: d.tag, first: (respCnt == 0), last: l}); endrule MemReadEngineServer#(userWidth) rs = (interface MemReadEngineServer#(userWidth); interface Put request; method Action put(MemengineCmd cmd); `ifdef SIMULATION Bit#(32) bsb = fromInteger(bufferSizeBytes); Bit#(32) dw = fromInteger(valueOf(busWidthBytes)); let mdw = ((cmd.len)/dw)*dw != cmd.len; let bbl = extend(cmd.burstLen) > bsb; if(bbl || mdw) begin if (bbl) $display("XXXXXXXXXX mkMemReadEngineBuff::unsupported burstLen %d %d", bsb, cmd.burstLen); if (mdw) $display("XXXXXXXXXX mkMemReadEngineBuff::unsupported len %d", cmd.len); end else `endif begin clientRequest.enq(cmd); end endmethod endinterface interface data = interface PipeOut; method MemDataF#(userWidth) first; return clientDataFifo.first; endmethod method Action deq; if (verbose) $display("mkMemReadEngineBuff::check_out: chan=%d data %h clientAvail %d eob %d", channelNumber, clientDataFifo.first.data, clientAvail.read(), clientDataFifo.first.last); clientDataFifo.deq; clientAvail.increment(1); endmethod method Bool notEmpty = clientDataFifo.notEmpty; endinterface; interface requestCycles = toPipeOut(clientCyclesFifo); endinterface); interface readServer = rs; interface PipeOut readReq = toPipeOut(dmaRequest); endmodule module mkUnfunnelDataPipes#(PipeOut#(MemData#(busWidth)) inPipe)(Vector#(numServers, PipeOut#(MemData#(busWidth)))) provisos (Log#(numServers,serverIndexSize), Add#(serverIndexSize,a__,MemTagSize)); Vector#(numServers, FIFOF#(MemData#(busWidth))) dataFifos <- replicateM(mkFIFOF()); rule unfunnel; let md <- toGet(inPipe).get(); let tag = md.tag; Bit#(serverIndexSize) fifoNumber = truncate(tag); dataFifos[fifoNumber].enq(md); endrule return map(toPipeOut, dataFifos); endmodule module mkMemReadEngineBuff#(Integer bufferSizeBytes) (MemReadEngine#(busWidth, userWidth, cmdQDepth, numServers)) provisos (Div#(busWidth,8,busWidthBytes), Mul#(busWidthBytes,8,busWidth), Add#(busWidth, 0, userWidth), // Min#(MemReadFunnelBPC, TLog#(numServers), bpc), Add#(0,MemReadFunnelBPC,bpc), FunnelPipesPipelined#(1, numServers, ConnectalMemTypes::MemData#(userWidth), bpc), FunnelPipesPipelined#(1, numServers, ConnectalMemTypes::MemRequest, bpc), Add#(a__, TLog#(numServers), MemTagSize) ); let verbose = False; let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Integer bufferSizeBeats = bufferSizeBytes/valueOf(busWidthBytes); FIFOF#(MemData#(busWidth)) readDataFifo <- mkFIFOF(); Vector#(numServers, PipeOut#(MemData#(busWidth))) dataPipes <- mkUnfunnelDataPipes(toPipeOut(readDataFifo)); Vector#(numServers, MemReadChannel#(busWidth,userWidth,cmdQDepth)) readChannels <- zipWithM(mkMemReadChannel(bufferSizeBytes), genVector(), dataPipes); Vector#(numServers, FIFOF#(Bit#(MemTagSize))) readtagFifos <- replicateM(mkSizedFIFOF(valueOf(cmdQDepth))); function PipeOut#(MemRequest) readChannelDmaReadReq(Integer i); return readChannels[i].readReq; endfunction function MemReadEngineServer#(userWidth) readChannelServer(Integer i); return readChannels[i].readServer; endfunction FIFOF#(MemRequest) reqFifo <- mkFIFOF(); FunnelPipe#(1,numServers,MemRequest,bpc) reqFunnel <- mkFunnelPipesPipelined(genWith(readChannelDmaReadReq)); interface Vector readServers = genWith(readChannelServer); interface MemReadClient dmaClient; interface Get readReq = toGet(reqFunnel[0]); interface Put readData = toPut(readDataFifo); endinterface endmodule ================================================ FILE: bsv/MemServer.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; import List::*; import GetPut::*; import ClientServer::*; import Assert::*; import StmtFSM::*; import SpecialFIFOs::*; import Connectable::*; import HostInterface::*; import ConnectalMemTypes::*; import ConnectalConfig::*; import ConnectalMemory::*; import ConnectalMMU::*; import MemServerInternal::*; interface MemServer#(numeric type addrWidth, numeric type busWidth, numeric type nMasters); interface MemServerRequest request; interface Vector#(nMasters,PhysMemMaster#(addrWidth, busWidth)) masters; endinterface interface MemServerWithMMU#(numeric type addrWidth, numeric type busWidth, numeric type nMasters); interface MemServerRequest memServerRequest; interface Vector#(nMasters,PhysMemMaster#(addrWidth, busWidth)) masters; interface MMURequest mmuRequest; endinterface interface MemServerRead#(numeric type addrWidth, numeric type busWidth, numeric type numClients, numeric type numServers); interface MemServerRequest request; interface Vector#(numClients, PhysMemReadClient#(addrWidth,busWidth)) clients; interface Vector#(numServers, MemReadServer#(busWidth)) servers; endinterface interface MemServerWrite#(numeric type addrWidth, numeric type busWidth, numeric type numClients, numeric type numServers); interface MemServerRequest request; interface Vector#(numClients, PhysMemWriteClient#(addrWidth,busWidth)) clients; interface Vector#(numServers, MemWriteServer#(busWidth)) servers; endinterface typedef struct { DmaErrorType errorType; Bit#(32) pref; } DmaError deriving (Bits); module mkMemServer#(Vector#(numReadClients, MemReadClient#(busWidth)) readClients, Vector#(numWriteClients, MemWriteClient#(busWidth)) writeClients, Vector#(numMMUs,MMU#(addrWidth)) mmus, MemServerIndication indication) (MemServer#(addrWidth, busWidth, nMasters)) provisos(Mul#(TDiv#(numWriteClients, nMasters),nMasters,nws) ,Mul#(TDiv#(numReadClients, nMasters),nMasters,nrs) ,Add#(TLog#(TDiv#(busWidth, 8)), a__, 8) ,Add#(TLog#(TDiv#(busWidth, 8)), b__, BurstLenSize) ,Add#(c__, addrWidth, 64) ,Add#(numWriteClients, d__, nws) ,Add#(numReadClients, e__, nrs) ,Add#(f__, TDiv#(busWidth, 8), ByteEnableSize) ); MemServerRead#(addrWidth,busWidth,nMasters,nrs) reader <- mkMemServerRead(indication, mmus); MemServerWrite#(addrWidth,busWidth,nMasters,nws) writer <- mkMemServerWrite(indication, mmus); zipWithM_(mkConnection,readClients,take(reader.servers)); zipWithM_(mkConnection,writeClients,take(writer.servers)); function PhysMemMaster#(addrWidth,busWidth) mkm(Integer i) = (interface PhysMemMaster#(addrWidth,busWidth); interface PhysMemReadClient read_client = reader.clients[i]; interface PhysMemWriteClient write_client = writer.clients[i]; endinterface); interface MemServerRequest request; method Action setTileState(TileControl tc); reader.request.setTileState(tc); writer.request.setTileState(tc); endmethod method Action stateDbg(ChannelType rc); if (rc == ChannelType_Read) reader.request.stateDbg(rc); else writer.request.stateDbg(rc); endmethod method Action memoryTraffic(ChannelType rc); if (rc == ChannelType_Read) reader.request.memoryTraffic(rc); else writer.request.memoryTraffic(rc); endmethod method Action addrTrans(Bit#(32) pointer, Bit#(32) offset); writer.request.addrTrans(pointer,offset); endmethod endinterface interface masters = map(mkm,genVector); endmodule module mkMemServerRead#(MemServerIndication indication, Vector#(numMMUs,MMU#(addrWidth)) mmus) (MemServerRead#(addrWidth, busWidth, numClients, numServers)) provisos(Mul#(nrc, numClients, numServers) ,Add#(a__, addrWidth, 64) ,Add#(TLog#(TDiv#(busWidth, 8)), b__, 8) ,Add#(TLog#(TDiv#(busWidth, 8)), c__, BurstLenSize) ,Add#(d__, TDiv#(busWidth, 8), ByteEnableSize) ); FIFO#(Bit#(32)) addrReqFifo <- mkFIFO; Reg#(Bit#(8)) dbgPtr <- mkReg(0); Reg#(Bit#(8)) trafficPtr <- mkReg(0); Reg#(Bit#(64)) trafficAccum <- mkReg(0); function Server#(AddrTransRequest,AddrTransResponse#(addrWidth)) selectMMUPort(Integer i); return mmus[i].addr[0]; endfunction Vector#(numMMUs,ArbitratedMMU#(addrWidth,numClients)) mmu_servers <- mapM(mkArbitratedMMU,map(selectMMUPort,genVector)); Vector#(numClients,MemReadInternal#(addrWidth,busWidth,MemServerTags,nrc)) readers; Vector#(numClients, PhysMemReadClient#(addrWidth,busWidth)) read_clients; Vector#(numServers, MemReadServer#(busWidth)) read_servers; for(Integer i = 0; i < valueOf(numClients); i = i+1) begin Vector#(numMMUs,Server#(AddrTransRequest,AddrTransResponse#(addrWidth))) ss; for(Integer j = 0; j < valueOf(numMMUs); j=j+1) ss[j] = mmu_servers[j].servers[i]; readers[i] <- mkMemReadInternal(indication,ss); read_clients[i] = readers[i].client; for(Integer j = 0; j < valueOf(nrc); j=j+1) read_servers[i*valueOf(nrc)+j] = readers[i].servers[j]; end rule mmuEntry; addrReqFifo.deq; let addrTransResponse <- mmus[addrReqFifo.first[31:16]].addr[0].response.get; indication.addrResponse(zeroExtend(addrTransResponse.physAddr)); endrule Stmt dbgStmt = seq for(dbgPtr <= 0; dbgPtr < fromInteger(valueOf(numClients)); dbgPtr <= dbgPtr+1) (action let rv <- readers[dbgPtr].dbg.dbg; indication.reportStateDbg(rv); endaction); endseq; FSM dbgFSM <- mkFSM(dbgStmt); Stmt trafficStmt = seq trafficAccum <= 0; for(trafficPtr <= 0; trafficPtr < fromInteger(valueOf(numClients)); trafficPtr <= trafficPtr+1) (action let rv <- readers[trafficPtr].dbg.getMemoryTraffic(); trafficAccum <= trafficAccum + rv; endaction); indication.reportMemoryTraffic(trafficAccum); endseq; FSM trafficFSM <- mkFSM(trafficStmt); interface servers = read_servers; interface clients = read_clients; interface MemServerRequest request; method Action setTileState(TileControl tc); for(Integer i = 0; i < valueOf(numClients); i=i+1) readers[i].tileControl.put(tc); endmethod method Action stateDbg(ChannelType rc); if (rc == ChannelType_Read) dbgFSM.start; endmethod method Action memoryTraffic(ChannelType rc); if (rc == ChannelType_Read) trafficFSM.start; endmethod method Action addrTrans(Bit#(32) pointer, Bit#(32) offset); addrReqFifo.enq(pointer); mmus[pointer[31:16]].addr[0].request.put(AddrTransRequest{id:truncate(pointer), off:extend(offset)}); endmethod endinterface endmodule module mkMemServerWrite#(MemServerIndication indication, Vector#(numMMUs,MMU#(addrWidth)) mmus) (MemServerWrite#(addrWidth, busWidth, numClients, numServers)) provisos(Mul#(nwc, numClients, numServers) ,Add#(a__, addrWidth, 64) ,Add#(TLog#(TDiv#(busWidth, 8)), b__, 8) ,Add#(TLog#(TDiv#(busWidth, 8)), c__, BurstLenSize) ,Add#(d__, TDiv#(busWidth, 8), ByteEnableSize) ); FIFO#(Bit#(32)) addrReqFifo <- mkFIFO; Reg#(Bit#(8)) dbgPtr <- mkReg(0); Reg#(Bit#(8)) trafficPtr <- mkReg(0); Reg#(Bit#(64)) trafficAccum <- mkReg(0); function Server#(AddrTransRequest,AddrTransResponse#(addrWidth)) selectMMUPort(Integer i); return mmus[i].addr[1]; endfunction Vector#(numMMUs,ArbitratedMMU#(addrWidth,numClients)) mmu_servers <- mapM(mkArbitratedMMU,map(selectMMUPort,genVector)); Vector#(numClients,MemWriteInternal#(addrWidth,busWidth,MemServerTags,nwc)) writers; Vector#(numClients, PhysMemWriteClient#(addrWidth,busWidth)) write_clients; Vector#(numServers, MemWriteServer#(busWidth)) write_servers; for(Integer i = 0; i < valueOf(numClients); i = i+1) begin Vector#(numMMUs,Server#(AddrTransRequest,AddrTransResponse#(addrWidth))) ss; for(Integer j = 0; j < valueOf(numMMUs); j=j+1) ss[j] = mmu_servers[j].servers[i]; writers[i] <- mkMemWriteInternal(indication, ss); write_clients[i] = writers[i].client; for(Integer j = 0; j < valueOf(nwc); j=j+1) write_servers[i*valueOf(nwc)+j] = writers[i].servers[j]; end rule mmuEntry; addrReqFifo.deq; let addrTransResponse <- mmus[addrReqFifo.first[31:16]].addr[1].response.get; let physAddr = addrTransResponse.physAddr; indication.addrResponse(zeroExtend(physAddr)); endrule Stmt dbgStmt = seq for(dbgPtr <= 0; dbgPtr < fromInteger(valueOf(numClients)); dbgPtr <= dbgPtr+1) (action let rv <- writers[dbgPtr].dbg.dbg; indication.reportStateDbg(rv); endaction); endseq; FSM dbgFSM <- mkFSM(dbgStmt); Stmt trafficStmt = seq trafficAccum <= 0; for(trafficPtr <= 0; trafficPtr < fromInteger(valueOf(numClients)); trafficPtr <= trafficPtr+1) (action let rv <- writers[trafficPtr].dbg.getMemoryTraffic(); trafficAccum <= trafficAccum + rv; endaction); indication.reportMemoryTraffic(trafficAccum); endseq; FSM trafficFSM <- mkFSM(trafficStmt); interface servers = write_servers; interface clients = write_clients; interface MemServerRequest request; method Action setTileState(TileControl tc); for(Integer i = 0; i < valueOf(numClients); i=i+1) writers[i].tileControl.put(tc); endmethod method Action stateDbg(ChannelType rc); if (rc == ChannelType_Write) dbgFSM.start; endmethod method Action memoryTraffic(ChannelType rc); if (rc == ChannelType_Write) trafficFSM.start; endmethod method Action addrTrans(Bit#(32) pointer, Bit#(32) offset); addrReqFifo.enq(pointer); mmus[pointer[31:16]].addr[1].request.put(AddrTransRequest{id:truncate(pointer), off:extend(offset)}); endmethod endinterface endmodule module mkMemServerWithMMU#(Vector#(numReadClients, MemReadClient#(busWidth)) readClients, Vector#(numWriteClients, MemWriteClient#(busWidth)) writeClients, MemServerIndication indication, MMUIndication mmuIndication)(MemServerWithMMU#(PhysAddrWidth, busWidth,nMasters)) provisos(Add#(TLog#(TDiv#(busWidth, 8)), e__, 8) ,Add#(TLog#(TDiv#(busWidth, 8)), f__, BurstLenSize) ,Add#(c__, PhysAddrWidth, 64) ,Add#(d__, PhysAddrWidth, MemOffsetSize) ,Add#(numWriteClients, a__, TMul#(TDiv#(numWriteClients, nMasters),nMasters)) ,Add#(numReadClients, b__, TMul#(TDiv#(numReadClients, nMasters),nMasters)) ,Add#(g__, TDiv#(busWidth, 8), ByteEnableSize) ); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, mmuIndication); MemServer#(PhysAddrWidth,busWidth,nMasters) dma <- mkMemServer(readClients, writeClients, cons(hostMMU,nil), indication); interface MemServerRequest memServerRequest = dma.request; interface MMURequest mmuRequest = hostMMU.request; interface Vector masters = dma.masters; endmodule ================================================ FILE: bsv/MemServerInternal.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // BSV Libraries import BRAMFIFO::*; import FIFO::*; import FIFOF::*; import Vector::*; import GetPut::*; import ClientServer::*; import Assert::*; import BRAM::*; import DefaultValue::*; // CONNECTAL Libraries import ConnectalMemTypes::*; import ConnectalMemory::*; import ConnectalClocks::*; import ConnectalMMU::*; import ConnectalCompletionBuffer::*; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" typedef 32 BeatCountSize; typedef 9 MMU_PIPELINE_DEPTH; interface DmaDbg; method ActionValue#(Bit#(64)) getMemoryTraffic(); method ActionValue#(DmaDbgRec) dbg(); endinterface interface MemWriteInternal#(numeric type addrWidth, numeric type busWidth, numeric type numTags, numeric type numServers); interface DmaDbg dbg; interface Put#(TileControl) tileControl; interface PhysMemWriteClient#(addrWidth,busWidth) client; interface Vector#(numServers, MemWriteServer#(busWidth)) servers; endinterface interface MemReadInternal#(numeric type addrWidth, numeric type busWidth, numeric type numTags, numeric type numServers); interface DmaDbg dbg; interface Put#(TileControl) tileControl; interface PhysMemReadClient#(addrWidth,busWidth) client; interface Vector#(numServers, MemReadServer#(busWidth)) servers; endinterface function Bool sglid_outofrange(SGLId p); return ((p[15:0]) >= fromInteger(valueOf(MaxNumSGLists))); endfunction import RegFile::*; typedef struct {MemRequest req; Bit#(TLog#(TMax#(1,numClients))) client; } LRec#(numeric type numClients, numeric type addrWidth) deriving(Bits); typedef struct {MemRequest req; Bit#(addrWidth) pa; Bit#(MemTagSize) rename_tag; Bit#(TLog#(TMax#(1,numClients))) client; } RRec#(numeric type numClients, numeric type addrWidth) deriving(Bits); typedef struct {Bit#(MemTagSize) req_tag; Bit#(BurstLenSize) req_burstLen; Bit#(MemTagSize) rename_tag; Bit#(TLog#(TMax#(1,numClients))) client; Bool last; } DRec#(numeric type numClients, numeric type addrWidth) deriving(Bits); typedef struct {Bit#(MemTagSize) orig_tag; Bit#(TLog#(TMax#(1,numClients))) client; } RResp#(numeric type numClients, numeric type addrWidth) deriving(Bits); typedef struct {DmaErrorType errorType; Bit#(32) pref; } DmaError deriving (Bits); module mkMemReadInternal#(MemServerIndication ind, Vector#(numMMUs,Server#(AddrTransRequest,AddrTransResponse#(addrWidth))) mmus) (MemReadInternal#(addrWidth, busWidth, numTags, numServers)) provisos(Log#(busWidthBytes,beatShift) ,Div#(busWidth,8,busWidthBytes) ,Add#(beatShift, a__, 8) ,Add#(b__, TLog#(numTags), MemTagSize) ,Add#(beatShift, c__, BurstLenSize) ,Add#(d__, TDiv#(busWidth, 8), ByteEnableSize) ); // stopping/killing infra Vector#(4,Reg#(Bool)) killv <- replicateM(mkReg(False)); Vector#(4,Reg#(Bool)) stopv <- replicateM(mkReg(False)); // stage 0: address translation (latency = MMU_PIPELINE_DEPTH) FIFO#(LRec#(numServers,addrWidth)) clientRequest <- mkSizedFIFO(valueOf(MMU_PIPELINE_DEPTH)); // stage 1: address validation (latency = 1) FIFO#(RRec#(numServers,addrWidth)) serverRequest <- mkFIFO; // stage 2: read commands BRAM_Configure bramConfig = defaultValue; if (mainClockPeriod < 8) bramConfig.latency = 2; BRAM2Port#(Bit#(TLog#(numTags)), DRec#(numServers,addrWidth)) serverProcessing <- mkBRAM2Server(bramConfig); BRAM2Port#(Bit#(TAdd#(TLog#(numTags),TSub#(BurstLenSize,beatShift))), MemData#(busWidth)) clientData <- mkBRAM2Server(bramConfig); // stage 3: read data FIFO#(MemData#(busWidth)) serverData <- mkFIFO; let verbose = False; RegFile#(Bit#(TLog#(numTags)),Tuple2#(Bool,Bit#(BurstLenSize))) clientBurstLen <- mkRegFileFull(); Reg#(Bit#(BurstLenSize)) burstReg <- mkReg(0); Reg#(Bool) firstReg <- mkReg(True); Reg#(Bit#(32)) beatCount <- mkReg(0); let beat_shift = fromInteger(valueOf(beatShift)); TagGen#(numTags) tag_gen <- mkTagGen; Reg#(Bit#(BurstLenSize)) compCountReg <- mkReg(0); Reg#(Bit#(TLog#(numTags))) compTagReg <- mkReg(0); Reg#(Bit#(TLog#(TMax#(1,numServers)))) compClientReg <- mkReg(0); Reg#(Bit#(2)) compTileReg <- mkReg(0); FIFO#(Bit#(TAdd#(1,TLog#(TMax#(1,numServers))))) clientSelect <- mkFIFO; FIFO#(Bit#(TLog#(numTags))) serverTag <- mkFIFO; // performance analytics Reg#(Bit#(64)) cycle_cnt <- mkReg(0); Reg#(Bit#(64)) last_loadClient <- mkReg(0); Reg#(Bit#(64)) last_mmuResp <- mkReg(0); Reg#(Bit#(64)) last_comp <- mkReg(0); Reg#(Bit#(64)) last_readReq <- mkReg(0); Reg#(Bit#(64)) last_readData <- mkReg(0); (* fire_when_enabled *) rule cycle; cycle_cnt <= cycle_cnt+1; endrule FIFO#(DmaError) dmaErrorFifo <- mkFIFO(); rule dmaError; let error <- toGet(dmaErrorFifo).get(); ind.error(extend(pack(error.errorType)), error.pref, 0, 0); endrule rule checkMmuResp; let request <- toGet(clientRequest).get(); let addrTransResponse <- mmus[request.req.sglId[31:16]].response.get; let physAddr = addrTransResponse.physAddr; let rename_tag <- tag_gen.getTag; let burstLenBeats = request.req.burstLen >> beat_shift; clientBurstLen.upd(truncate(rename_tag), tuple2(burstLenBeats == 1, burstLenBeats)); serverRequest.enq(RRec{req:request.req, pa:physAddr, client:request.client, rename_tag:extend(rename_tag)}); if (verbose) $display("mkMemReadInternal::checkMmuResp: client=%d, tag=%d rename_tag=%d burstLen=%d", request.client, request.req.tag, rename_tag, burstLenBeats); if (verbose) $display("mkMemReadInternal::mmuResp %d %d", request.client, cycle_cnt-last_mmuResp); last_mmuResp <= cycle_cnt; endrule rule read_data; let response <- toGet(serverData).get(); let drq <- serverProcessing.portA.response.get; let tag = drq.req_tag; match { .last, .burstLen } = clientBurstLen.sub(truncate(response.tag)); let first = firstReg; if (first) begin dynamicAssert(last == (burstLen==1), "Last incorrect"); end if (last && burstLen != 1) $display("rename_tag=%d tag=%d burstLen=%d last=%d", response.tag, tag, burstLen, last); Bit#(TLog#(numTags)) tt = truncate(response.tag); clientData.portA.request.put(BRAMRequest{write:True, responseOnWrite:False, datain:MemData{data: response.data, tag: tag, last: last}, address:{tt,truncate(burstLen)}}); if (last) begin tag_gen.returnTag(truncate(response.tag)); end last_readData <= cycle_cnt; if (verbose) $display("mkMemReadInternal::read_data cyclediff %d", cycle_cnt-last_readData); clientBurstLen.upd(truncate(response.tag), tuple2((burstLen-1 == 1),burstLen-1)); firstReg <= response.last; endrule rule tag_completed; let tag <- tag_gen.complete; serverProcessing.portB.request.put(BRAMRequest{write:False, address:tag, datain: ?, responseOnWrite: ?}); serverTag.enq(tag); if(verbose) $display("mkMemReadInternal::complete_burst0 %h", tag); endrule rule complete_burst1a if (compCountReg==0); let drq <- serverProcessing.portB.response.get; let req_burstLen = drq.req_burstLen; let client = drq.client; let cnt = req_burstLen >> beat_shift; let tag <- toGet(serverTag).get; if(killv[drq.req_tag[5:4]] == False) begin clientSelect.enq(extend(client)); clientData.portB.request.put(BRAMRequest{write:False, address:{tag,truncate(cnt)}, datain: ?, responseOnWrite: ?}); end compCountReg <= cnt-1; compTagReg <= tag; compClientReg <= client; compTileReg <= drq.req_tag[5:4]; if(verbose) $display("mkMemReadInternal::complete_burst1a %h", client); endrule rule burst_remainder if (compCountReg > 0); let cnt = compCountReg; let tag = compTagReg; let client = compClientReg; if(killv[compTileReg] == False) begin clientSelect.enq(extend(client)); clientData.portB.request.put(BRAMRequest{write:False, address:{tag,truncate(cnt)}, datain: ?, responseOnWrite: ?}); end compCountReg <= cnt-1; if(verbose) $display("mkMemReadInternal::complete_burst1b count %h", compCountReg); endrule Vector#(numServers, MemReadServer#(busWidth)) sv = newVector; for(Integer i = 0; i < valueOf(numServers); i=i+1) sv[i] = (interface MemReadServer; interface Put readReq; method Action put(MemRequest req); last_loadClient <= cycle_cnt; let mmusel = req.sglId[31:16]; if (verbose) $display("mkMemReadInternal::loadClient server %d mmusel %d burstLen %d tag %d cycle %d", i, mmusel, req.burstLen >> beat_shift, req.tag, cycle_cnt-last_loadClient); if (mmusel >= fromInteger(valueOf(numMMUs))) dmaErrorFifo.enq(DmaError { errorType: DmaErrorMMUOutOfRange_r, pref: req.sglId }); else if (sglid_outofrange(req.sglId)) dmaErrorFifo.enq(DmaError { errorType: DmaErrorSGLIdOutOfRange_r, pref: req.sglId }); else if (stopv[req.tag[5:4]] == False) begin clientRequest.enq(LRec{req:req, client:fromInteger(i)}); mmus[mmusel].request.put(AddrTransRequest{id:truncate(req.sglId),off:req.offset}); end endmethod endinterface interface Get readData; method ActionValue#(MemData#(busWidth)) get if (clientSelect.first == fromInteger(i)); clientSelect.deq; let data <- clientData.portB.response.get; if (verbose) $display("mkMemReadInternal::comp server %d data %x cycle %d", i, data.data, cycle_cnt-last_comp); last_comp <= cycle_cnt; return data; endmethod endinterface endinterface); interface servers = sv; interface PhysMemReadClient client; interface Get readReq; method ActionValue#(PhysMemRequest#(addrWidth,busWidth)) get(); let request <- toGet(serverRequest).get; let req = request.req; if (False && request.pa[31:24] != 0) $display("mkMemReadInternal::req_ar: funny physAddr req.sglId=%d req.offset=%h physAddr=%h", req.sglId, req.offset, request.pa); serverProcessing.portB.request.put(BRAMRequest{write:True, responseOnWrite:False, address:truncate(request.rename_tag), datain:DRec{req_tag:req.tag, req_burstLen: req.burstLen, client:request.client, rename_tag:request.rename_tag, last:(req.burstLen == fromInteger(valueOf(busWidthBytes)))}}); //$display("mkMemReadInternal::readReq: client=%d, rename_tag=%d, physAddr=%h req.burstLen=%d beat_shift=%d last=%d", request.client,request.rename_tag,request.pa, req.burstLen, beat_shift, req.burstLen == beat_shift); if (verbose) $display("mkMemReadInternal::read_client.readReq %d", cycle_cnt-last_readReq); last_readReq <= cycle_cnt; return PhysMemRequest{addr:request.pa, burstLen:req.burstLen, tag:request.rename_tag `ifdef BYTE_ENABLES , firstbe: truncate(request.req.firstbe), lastbe: truncate(request.req.lastbe) `endif }; endmethod endinterface interface Put readData; method Action put(MemData#(busWidth) response); serverData.enq(response); serverProcessing.portA.request.put(BRAMRequest{write:False, address:truncate(response.tag), datain: ?, responseOnWrite: ?}); beatCount <= beatCount+1; endmethod endinterface endinterface interface Put tileControl; method Action put(TileControl tc); let tile = tc.tile; let kv = True; let sv = True; if (tc.state == Running || tc.state == Stopped) kv = False; if (tc.state == Running) sv = False; killv[tile] <= kv; stopv[tile] <= sv; endmethod endinterface interface DmaDbg dbg; method ActionValue#(DmaDbgRec) dbg(); return DmaDbgRec{x:0, y:0, z:0, w:0}; endmethod method ActionValue#(Bit#(64)) getMemoryTraffic(); return extend(beatCount); endmethod endinterface endmodule module mkMemWriteInternal#(MemServerIndication ind, Vector#(numMMUs,Server#(AddrTransRequest,AddrTransResponse#(addrWidth))) mmus) (MemWriteInternal#(addrWidth, busWidth, numTags, numServers)) provisos(Log#(busWidthBytes,beatShift) ,Div#(busWidth,8,busWidthBytes) ,Add#(beatShift, a__, 8) ,Add#(b__, TLog#(numTags), MemTagSize) ,Add#(beatShift, c__, BurstLenSize) ,Add#(d__, TDiv#(busWidth, 8), ByteEnableSize) ); let verbose = False; // stopping/killing infra Vector#(4,Reg#(Bool)) killv <- replicateM(mkReg(False)); Vector#(4,Reg#(Bool)) stopv <- replicateM(mkReg(False)); // stage 0: address translation (latency = MMU_PIPELINE_DEPTH) FIFO#(LRec#(numServers,addrWidth)) clientRequest <- mkSizedFIFO(valueOf(MMU_PIPELINE_DEPTH)); // stage 1: address validation (latency = 1) FIFO#(RRec#(numServers,addrWidth)) serverRequest <- mkFIFO; // stage 2: write commands FIFO#(DRec#(numServers, addrWidth)) serverProcessing <- mkSizedFIFO(valueOf(numTags)); // stage 3: write data BRAM2Port#(Bit#(TLog#(numTags)), RResp#(numServers,addrWidth)) respFifos <- mkBRAM2Server(defaultValue); TagGen#(numTags) tag_gen <- mkTagGen; FIFO#(RResp#(numServers,addrWidth)) clientResponse <- mkFIFO; Reg#(Bit#(BurstLenSize)) burstReg <- mkReg(0); Reg#(Bool) firstReg <- mkReg(True); Reg#(Bool) lastReg <- mkReg(False); Reg#(Bit#(BeatCountSize)) beatCount <- mkReg(0); let beat_shift = fromInteger(valueOf(beatShift)); Reg#(Bit#(64)) cycle_cnt <- mkReg(0); Reg#(Bit#(64)) last_loadClient <- mkReg(0); Reg#(Bit#(64)) last_mmuResp <- mkReg(0); (* fire_when_enabled *) rule cycle; cycle_cnt <= cycle_cnt+1; endrule FIFO#(DmaError) dmaErrorFifo <- mkFIFO(); rule dmaError; let error <- toGet(dmaErrorFifo).get(); ind.error(extend(pack(error.errorType)), error.pref, 0, 0); endrule rule checkMmuResp; let request <- toGet(clientRequest).get; let req = request.req; let client = request.client; let addrTransResponse <- mmus[req.sglId[31:16]].response.get; let physAddr = addrTransResponse.physAddr; let rename_tag <- tag_gen.getTag; serverRequest.enq(RRec{req:req, pa:physAddr, client:client, rename_tag:extend(rename_tag)}); //if (verbose) $display("mkMemWriteInternal::checkMmuResp: client=%d, rename_tag=%d", client,rename_tag); if (verbose) $display("mkMemWriteInternal::mmuResp %d %d", client, cycle_cnt-last_mmuResp); last_mmuResp <= cycle_cnt; endrule rule writeDoneComp0; let tag <- tag_gen.complete; respFifos.portB.request.put(BRAMRequest{write:False, address:tag, datain: ?, responseOnWrite: ?}); endrule FIFO#(MemData#(busWidth)) memDataFifo <- mkFIFO(); Vector#(numServers, FIFO#(MemData#(busWidth))) clientWriteData <- replicateM(mkFIFO); if(valueOf(numServers) > 0) rule memdata; let drq = serverProcessing.first; let req_tag = drq.req_tag; let req_burstLen = drq.req_burstLen; let rename_tag = drq.rename_tag; let client = drq.client; MemData#(busWidth) tagdata = unpack(0); if (killv[req_tag[5:4]] == False) begin tagdata = clientWriteData[client].first; clientWriteData[client].deq; end let burstLen = burstReg; let first = firstReg; let last = lastReg; if (first) begin burstLen = req_burstLen >> beat_shift; last = serverProcessing.first.last; respFifos.portA.request.put(BRAMRequest{write:True,responseOnWrite:False, address:truncate(rename_tag), datain:RResp{orig_tag:req_tag, client:client}}); end burstReg <= burstLen-1; firstReg <= (burstLen-1 == 0); lastReg <= (burstLen-1 == 1); beatCount <= beatCount+1; if (last) serverProcessing.deq(); //$display("mkMemWriteInternal::writeData: client=%d, rename_tag=%d", client, rename_tag); memDataFifo.enq(MemData { data: tagdata.data, `ifdef BYTE_ENABLES_MEM_DATA byte_enables: tagdata.byte_enables, `endif tag:extend(rename_tag), last: last }); endrule rule fill_clientResponse; let rv <- respFifos.portB.response.get; clientResponse.enq(rv); endrule Vector#(numServers, MemWriteServer#(busWidth)) sv = newVector; for(Integer i = 0; i < valueOf(numServers); i=i+1) sv[i] = (interface MemWriteServer; interface Put writeReq; method Action put(MemRequest req); if (verbose) $display("mkMemWriteInternal::loadClient %d %d", i, cycle_cnt-last_loadClient); last_loadClient <= cycle_cnt; let mmusel = req.sglId[31:16]; if (mmusel >= fromInteger(valueOf(numMMUs))) dmaErrorFifo.enq(DmaError { errorType: DmaErrorMMUOutOfRange_w, pref: req.sglId }); else if (sglid_outofrange(req.sglId)) dmaErrorFifo.enq(DmaError { errorType: DmaErrorSGLIdOutOfRange_w, pref: req.sglId }); else if (stopv[req.tag[5:4]] == False) begin clientRequest.enq(LRec{req:req, client:fromInteger(i)}); mmus[mmusel].request.put(AddrTransRequest{id:truncate(req.sglId),off:req.offset}); end endmethod endinterface interface Put writeData = toPut(clientWriteData[i]); interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get if (clientResponse.first.client == fromInteger(i)); clientResponse.deq; return clientResponse.first.orig_tag; endmethod endinterface endinterface); interface servers = sv; interface PhysMemWriteClient client; interface Get writeReq; method ActionValue#(PhysMemRequest#(addrWidth,busWidth)) get(); let request <- toGet(serverRequest).get(); let req = request.req; let physAddr = request.pa; let client = request.client; let rename_tag = request.rename_tag; serverProcessing.enq(DRec{req_tag:req.tag, req_burstLen: req.burstLen, client:client, rename_tag:rename_tag, last: (req.burstLen == fromInteger(valueOf(busWidthBytes))) }); //$display("mkMemWriteInternal::writeReq: client=%d, rename_tag=%d", client,rename_tag); return PhysMemRequest{addr:physAddr, burstLen:req.burstLen, tag:extend(rename_tag) `ifdef BYTE_ENABLES , firstbe: truncate(req.firstbe), lastbe: truncate(req.lastbe) `endif }; endmethod endinterface interface Get writeData = toGet(memDataFifo); interface Put writeDone; method Action put(Bit#(MemTagSize) resp); tag_gen.returnTag(truncate(resp)); if (verbose) $display("mkMemWriteInternal::writeDone: resp=%d", resp); endmethod endinterface endinterface interface Put tileControl; method Action put(TileControl tc); let tile = tc.tile; let kv = True; let sv = True; if (tc.state == Running || tc.state == Stopped) kv = False; if (tc.state == Running) sv = False; killv[tile] <= kv; stopv[tile] <= sv; endmethod endinterface interface DmaDbg dbg; method ActionValue#(DmaDbgRec) dbg(); return DmaDbgRec{x:fromInteger(valueOf(numServers)), y:?, z:?, w:?}; endmethod method ActionValue#(Bit#(64)) getMemoryTraffic(); return extend(beatCount); endmethod endinterface endmodule ================================================ FILE: bsv/MemServerPortal.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; import GetPut::*; import FIFOF::*; import ConfigCounter::*; import ConnectalFIFO::*; import ConnectalConfig::*; import ConnectalMemTypes::*; // // provides softare ability to read/write a PhysMemSlave or MemServer // interface MemServerPortalRequest; method Action read32(Bit#(32) addr); method Action write32(Bit#(32) addr, Bit#(32) data); method Action read64(Bit#(32) addr); method Action write64(Bit#(32) addr, Bit#(64) data); endinterface interface MemServerPortalResponse; method Action read32Done(Bit#(32) data); method Action read64Done(Bit#(64) data); method Action writeDone(); endinterface interface MemServerPortal; interface MemServerPortalRequest request; endinterface module mkPhysMemSlavePortal#(PhysMemSlave#(addrWidth,dataBusWidth) ms, MemServerPortalResponse ind)(MemServerPortal) provisos (Add#(dataBusWidth,7,a__) ,Add#(b__,addrWidth,32) ,Add#(c__, dataBusWidth, 128) ,Bits#(ConnectalMemTypes::MemData#(dataBusWidth), a__)); FIFOF#(PhysMemRequest#(addrWidth,dataBusWidth)) araddrFifo <- mkFIFOF(); FIFOF#(PhysMemRequest#(addrWidth,dataBusWidth)) awaddrFifo <- mkFIFOF(); FIFOF#(MemData#(dataBusWidth)) rdataFifo <- mkCFFIFOF(); FIFOF#(MemData#(dataBusWidth)) wdataFifo <- mkCFFIFOF(); FIFOF#(Bit#(6)) doneFifo <- mkFIFOF(); FIFOF#(Bit#(8)) readLenFifo <- mkCFFIFOF(); let araddrCnx <- mkConnection(toGet(araddrFifo), ms.read_server.readReq); let awaddrCnx <- mkConnection(toGet(awaddrFifo), ms.write_server.writeReq); let rdataCnx <- mkConnection(ms.read_server.readData, toPut(rdataFifo)); let wdataCnx <- mkConnection(toGet(wdataFifo), ms.write_server.writeData); let doneCnx <- mkConnection(ms.write_server.writeDone, toPut(doneFifo)); ConfigCounter#(16) timeoutCounter <- mkConfigCounter(0); rule rl_timeout if (readLenFifo.notEmpty() && !rdataFifo.notEmpty()); timeoutCounter.increment(1); UInt#(16) timeout = 10; if (timeoutCounter.read() == timeout) $display("read timeout %d cycles", timeout); endrule Reg#(Bit#(32)) readDataCount <- mkReg(0); rule rl_rdata32 if (readLenFifo.first == 32); let rdata <- toGet(rdataFifo).get(); readLenFifo.deq(); Bit#(128) data = extend(rdata.data); if (True) $display("read32done data=%h count=%d", data[31:0], readDataCount); readDataCount <= readDataCount + 1; ind.read32Done(truncate(data)); endrule rule rl_rdata64 if (readLenFifo.first == 64); let rdata <- toGet(rdataFifo).get(); readLenFifo.deq(); Bit#(128) data = extend(rdata.data); ind.read64Done(truncate(data)); endrule rule rl_writeDone; let tag <- toGet(doneFifo).get(); ind.writeDone(); endrule Reg#(Bit#(32)) readCount <- mkReg(0); interface MemServerPortalRequest request; method Action read32(Bit#(32) addr); if (True) $display("MemServerPortal.read32 addr=%h count=%d", addr, readCount); readCount <= readCount + 1; araddrFifo.enq(PhysMemRequest { addr: truncate(addr), burstLen: fromInteger(valueOf(TDiv#(32,8))), tag: 0 }); readLenFifo.enq(32); timeoutCounter.decrement(timeoutCounter.read()); endmethod method Action write32(Bit#(32) addr, Bit#(32) value); awaddrFifo.enq(PhysMemRequest { addr: truncate(addr), burstLen: fromInteger(valueOf(TDiv#(32,8))), tag: 0 }); Bit#(128) data = extend(value); wdataFifo.enq(MemData {data: truncate(data), tag: 0, last: True}); endmethod method Action read64(Bit#(32) addr); araddrFifo.enq(PhysMemRequest { addr: truncate(addr), burstLen: fromInteger(valueOf(TDiv#(64,8))), tag: 0 }); readLenFifo.enq(64); timeoutCounter.decrement(timeoutCounter.read()); endmethod method Action write64(Bit#(32) addr, Bit#(64) value); awaddrFifo.enq(PhysMemRequest { addr: truncate(addr), burstLen: fromInteger(valueOf(TDiv#(64,8))), tag: 0 }); Bit#(128) data = extend(value); wdataFifo.enq(MemData {data: truncate(data), tag: 0, last: True}); endmethod endinterface endmodule ================================================ FILE: bsv/MemToPcie.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO :: *; import FIFOF :: *; import GetPut :: *; import Connectable :: *; import PCIE :: *; import DefaultValue :: *; import Vector :: *; import ClientServer :: *; import MIMO :: *; import Probe :: *; import ConnectalMimo :: *; import MIFO :: *; import ConnectalMemTypes :: *; import ConfigCounter ::*; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" typedef struct { TLPData#(TlpDataBytes) tlp; TLPLength dwCount; Bool is3dw; Bool isHeaderOnly; } TlpWriteHeaderInfo deriving (Bits); interface MemToPcie#(numeric type buswidth); interface Client#(TLPData#(TlpDataBytes), TLPData#(TlpDataBytes)) tlp; interface PhysMemSlave#(40,buswidth) slave; method Bool tlpOutFifoNotEmpty(); interface Reg#(Bool) use4dw; endinterface: MemToPcie `ifdef XILINX `define AXI `elsif SIMULATION `define AXI `elsif ALTERA `define AVALON `endif `ifdef PCIE3 typedef 1024 WriteDataBurstLen; // max payload size is 1024 bytes `else // typedef 256 WriteDataBurstLen; // max payload size is 256 bytes for Xilinx gen2 core typedef 512 WriteDataBurstLen; // max payload size is 256 bytes for Xilinx gen2 core `endif typedef TDiv#(WriteDataBurstLen,4) WriteDataMimoSize; // number of words to hold in the MIMO typedef BurstLenSize WriteDataBurstLenSize; module mkMemToPcie#(PciId my_id)(MemToPcie#(buswidth)) provisos (Div#(buswidth, 8, busWidthBytes), Div#(buswidth, 32, busWidthWords), Bits#(Vector#(busWidthWords, Bit#(32)), buswidth), Log#(busWidthBytes,beatShift), Add#(aaa, 32, buswidth), Add#(bbb, buswidth, 256), Add#(ccc, TMul#(8, busWidthWords), 64), Add#(ddd, TMul#(32, busWidthWords), 256), Add#(eee, busWidthWords, 8), Add#(1, a__, busWidthWords), Add#(b__, busWidthWords, TlpDataWords), Add#(c__, busWidthWords, WriteDataMimoSize), Add#(0,16,TlpDataBytes) ); let verbose = False; let beat_shift = fromInteger(valueOf(beatShift)); FIFOF#(TLPData#(TlpDataBytes)) tlpOutFifo <- mkFIFOF; FIFOF#(TLPData#(TlpDataBytes)) tlpInFifo <- mkFIFOF; FIFOF#(TlpWriteHeaderInfo) tlpWriteHeaderFifo <- mkFIFOF; FIFOF#(Bool) writeReadyFifo <- mkFIFOF(); Reg#(Bit#(7)) hitReg <- mkReg(0); Reg#(Bool) use4dwReg <- mkReg(True); // default configuration for MIMO is for guarded enq() and deq(). // However, the implicit guard only checks for space for 1 element for enq(), and availability of 1 element for deq(). MIMOConfiguration mimoCfg = defaultValue; MIFO#(TlpDataWords,busWidthWords,16,Bit#(32)) completionMimo <- mkMIFO(); MIFO#(TlpDataWords,busWidthWords,16,Tuple2#(TLPTag,Bool)) completionTagMimo <- mkMIFO(); // tag, last beat of burst mimoCfg.bram_based = True; mimoCfg.unguarded = True; MIMO#(busWidthWords,TlpDataWords,WriteDataMimoSize,Bit#(32)) writeDataMimo <- MIMO::mkMIMO(mimoCfg); ConfigCounter#(8) writeDataCnt <- mkConfigCounter(0); Reg#(Bit#(WriteDataBurstLenSize)) writeBurstCount <- mkReg(0); FIFO#(Bit#(WriteDataBurstLenSize)) writeBurstCountFifo <- mkFIFO(); Reg#(TLPLength) writeDwCount <- mkReg(0); // how many 4 byte (double) words to send Reg#(LUInt#(TlpDataWords)) tlpDwCount <- mkReg(0); // how many to send in the next tlp (at most 4) Reg#(Bool) lastTlp <- mkReg(False); // if the next tlp sent is the last one Reg#(Bool) writeInProgress <- mkReg(False); FIFOF#(TLPTag) writeTag <- mkSizedFIFOF(16); FIFOF#(TLPTag) doneTag <- mkSizedFIFOF(16); Reg#(Bool) quadAlignedTlpHandled <- mkReg(True); Wire#(Bool) writeHeaderTlpWire <- mkDWire(False); Wire#(Bool) writeDataMimoEnqWire <- mkDWire(False); Reg#(Bool) writeDataMimoHasRoom <- mkReg(False); rule updateWriteDataMimoHasRoom; writeDataMimoHasRoom <= (writeDataCnt.read <= fromInteger(valueOf(WriteDataMimoSize) - valueOf(busWidthWords))); endrule // guard: (writeDataCnt.read >= truncate(unpack(tlpWriteHeaderFifo.first.dwCount))) rule writeHeaderTlp if (!writeInProgress); // update for next cycle let ready <- toGet(writeReadyFifo).get(); writeHeaderTlpWire <= True; let info <- toGet(tlpWriteHeaderFifo).get(); let tlp = info.tlp; let dwCount = info.dwCount; let is3dw = info.is3dw; let isHeaderOnly = info.isHeaderOnly; TLPMemory4DWHeader hdr_4dw = unpack(truncate(tlp.data)); TLPMemoryIO3DWHeader hdr_3dw = unpack(truncate(tlp.data)); if (is3dw) begin if (hdr_3dw.format != MEM_WRITE_3DW_DATA) $display("MemToPcie: expecting MEM_WRITE_3DW_DATA, got %d", hdr_3dw.format); Vector#(TlpDataWords, Bit#(32)) v = unpack(0); tlp.sof = True; `ifdef AXI v = writeDataMimo.first(); writeDataMimo.deq(1); hdr_3dw.data = byteSwap(v[0]); //FIXME: assert deqReadyN here tlp.eof = (dwCount == 1) ? True : False; dwCount = dwCount - 1; writeDataCnt.decrement(1); `elsif AVALON let quadWordAligned = isQuadWordAligned(getLowerAddr(hdr_3dw.addr, hdr_3dw.firstbe)); // if quad-word aligned, insert bubble. if (!quadWordAligned) begin v = writeDataMimo.first(); writeDataMimo.deq(1); hdr_3dw.data = v[0]; end else begin hdr_3dw.data = unpack(0); end tlp.eof = (dwCount == 1 && !quadWordAligned) ? True : False; if (!quadWordAligned) begin dwCount = dwCount - 1; writeDataCnt.decrement(1); end `endif tlp.be = 'hffff; tlp.data = extend(pack(hdr_3dw)); end else begin quadAlignedTlpHandled <= isQuadWordAligned(getLowerAddr(truncate(unpack(hdr_4dw.addr)), hdr_4dw.firstbe)); tlp.be = 'hffff; end tlpOutFifo.enq(tlp); writeDwCount <= dwCount; tlpDwCount <= truncate(min(fromInteger(valueOf(TlpDataWords)),unpack(dwCount))); lastTlp <= (dwCount <= fromInteger(valueOf(TlpDataWords))); writeInProgress <= (dwCount != 0); if (isHeaderOnly) begin doneTag.enq(writeTag.first()); writeTag.deq(); end endrule rule writeTlps if (writeInProgress); // already verified writeDataMimo.deqReadyN(tlpDwCount)) for this transaction TLPData#(TlpDataBytes) tlp = defaultValue; tlp.sof = False; Vector#(TlpDataWords, Bit#(32)) v = unpack(0); Integer currDwCount = valueOf(TlpDataWords); `ifdef AVALON if (!quadAlignedTlpHandled) begin currDwCount = 3; // 3 Data Dwords in this cycle. quadAlignedTlpHandled <= True; end `endif // The MIMO implicit guard only checks for availability of 1 element // so we explicitly check for the number of elements required writeDataMimo.deq(tlpDwCount); v = writeDataMimo.first(); let dwCount = writeDwCount - extend(pack(tlpDwCount)); writeDwCount <= dwCount; tlpDwCount <= truncate(min(fromInteger(currDwCount),unpack(dwCount))); writeDataCnt.decrement(unpack(extend(pack(tlpDwCount)))); lastTlp <= (dwCount <= fromInteger(valueOf(TlpDataWords))); tlp.be = maxBound << (4*(fromInteger(valueOf(TlpDataWords))-tlpDwCount)); tlp.eof = lastTlp; if (lastTlp) begin writeInProgress <= False; doneTag.enq(writeTag.first()); writeTag.deq(); $display("writeDwCount=%d will be zero", writeDwCount); end for (Integer i = 0; i < currDwCount; i = i + 1) begin `ifdef AXI `ifdef PCIE3 tlp.data[(i+1)*32-1:i*32] = v[i]; `else tlp.data[(i+1)*32-1:i*32] = byteSwap(v[(currDwCount-1)-i]); `endif `elsif AVALON tlp.data[(i+1)*32-1:i*32] = v[(currDwCount-1)-i]; `endif end tlpOutFifo.enq(tlp); endrule: writeTlps Reg#(TLPTag) lastTag <- mkReg(0); FIFOF#(TLPData#(TlpDataBytes)) tlpDecodeFifo <- mkFIFOF(); Reg#(TLPLength) wordCountReg <- mkReg(0); rule tlpInRule; let tlp <- toGet(tlpInFifo).get(); tlpDecodeFifo.enq(tlp); endrule rule handleTlpRule; let tlp = tlpDecodeFifo.first; Bool handled = False; TLPMemoryIO3DWHeader h = unpack(truncate(tlp.data)); hitReg <= tlp.hit; TLPMemoryIO3DWHeader hdr_3dw = unpack(truncate(tlp.data)); TLPCompletionHeader hdr_completion = unpack(truncate(tlp.data)); Vector#(TlpDataWords, Bit#(32)) vec = unpack(0); Vector#(TlpDataWords, Bit#(32)) tlpvec = unpack(tlp.data); let wordCount = wordCountReg; `ifdef AXI let dataInSecondTlp = False; `elsif AVALON let quadWordAligned = isQuadWordAligned(getLowerAddr(hdr_3dw.addr, hdr_3dw.firstbe)); let dataInSecondTlp = quadWordAligned; `endif if (!tlp.sof) begin `ifdef PCIE3 vec = tlpvec; `else vec = reverse(tlpvec); `endif // The MIMO implicit guard only checks for space to enqueue 1 element // so we explicitly check for the number of elements required // otherwise elements in the queue will be overwritten. if (completionMimo.enqReady() && completionTagMimo.enqReady()) begin LUInt#(TlpDataWords) count = fromInteger(valueOf(TlpDataWords)); if (tlp.eof) begin count = truncate(unpack(wordCountReg)); end wordCount = wordCountReg - extend(pack(count)); completionMimo.enq(count, vec); function Tuple2#(TLPTag,Bool) taglast(Integer i); return tuple2(lastTag, (fromInteger(i) == (count-1)) ? tlp.eof : False); endfunction Vector#(TlpDataWords, Tuple2#(TLPTag,Bool)) tagvec = genWith(taglast); completionTagMimo.enq(count, tagvec); handled = True; end end else if (hdr_3dw.format == MEM_WRITE_3DW_DATA && hdr_3dw.pkttype == COMPLETION && completionMimo.enqReady() && completionTagMimo.enqReady()) begin TLPTag tag = hdr_completion.tag; lastTag <= tag; if (!dataInSecondTlp) begin vec[0] = hdr_3dw.data; wordCount = hdr_3dw.length - 1; completionMimo.enq(1, vec); completionTagMimo.enq(1, replicate(tuple2(tag,tlp.eof))); end else begin wordCount = hdr_3dw.length; end handled = True; end wordCountReg <= wordCount; if (verbose) $display("tlpIn handled=%d tlp=%h", handled, tlp); if (handled) begin tlpDecodeFifo.deq(); end endrule FIFO#(PhysMemRequest#(40,buswidth)) readReqFifo <- mkFIFO(); rule readReqRule if (!writeInProgress); // && !writeDataMimo.deqReady()); let req <- toGet(readReqFifo).get(); let burstLen = req.burstLen >> beat_shift; let addr = req.addr; let arid = req.tag; TLPData#(TlpDataBytes) tlp = defaultValue; tlp.sof = True; tlp.eof = True; tlp.hit = 7'h00; TLPLength tlplen = fromInteger(valueOf(busWidthWords))*truncate(burstLen); if (addr[39:32] != 0) begin TLPMemory4DWHeader hdr_4dw = defaultValue; hdr_4dw.format = MEM_READ_4DW_NO_DATA; hdr_4dw.tag = extend(arid); hdr_4dw.reqid = my_id; hdr_4dw.nosnoop = SNOOPING_REQD; hdr_4dw.addr = addr[40-1:2]; hdr_4dw.length = tlplen; Bit#(TDiv#(buswidth,8)) firstbe = reqFirstByteEnable(req); Bit#(TDiv#(buswidth,8)) lastbe = reqLastByteEnable(req); hdr_4dw.firstbe = firstbe[3:0]; hdr_4dw.lastbe = (tlplen > 1) ? lastbe[valueOf(busWidthBytes)-1:valueOf(busWidthBytes)-4] : 0; tlp.data = extend(pack(hdr_4dw)); tlp.be = 'hffff; end else begin TLPMemoryIO3DWHeader hdr_3dw = defaultValue; hdr_3dw.format = MEM_READ_3DW_NO_DATA; hdr_3dw.tag = extend(arid); hdr_3dw.reqid = my_id; hdr_3dw.nosnoop = SNOOPING_REQD; hdr_3dw.addr = addr[32-1:2]; hdr_3dw.length = tlplen; Bit#(TDiv#(buswidth,8)) firstbe = reqFirstByteEnable(req); Bit#(TDiv#(buswidth,8)) lastbe = reqLastByteEnable(req); hdr_3dw.firstbe = firstbe[3:0]; hdr_3dw.lastbe = (tlplen > 1) ? lastbe[valueOf(busWidthBytes)-1:valueOf(busWidthBytes)-4] : 0; tlp.data = extend(pack(hdr_3dw)); tlp.be = 'hfff0; end tlpOutFifo.enq(tlp); endrule interface Client tlp; interface request = toGet(tlpOutFifo); interface response = toPut(tlpInFifo); endinterface interface PhysMemSlave slave; interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(40,buswidth) req); // if (writeBurstCount == 0); Bit#(WriteDataBurstLenSize) burstLen = truncate(req.burstLen >> beat_shift); let addr = req.addr; let awid = req.tag; let writeIs3dw = False; let use3dw = True; `ifdef PCIE3 awid = awid | (1 << (valueOf(MemTagSize)-1)); use3dw = False; `endif TLPLength tlplen = fromInteger(valueOf(busWidthWords))*truncate(burstLen); TLPData#(TlpDataBytes) tlp = defaultValue; tlp.sof = True; tlp.eof = False; tlp.hit = 7'h00; tlp.be = 'hffff; if (verbose) $display("slave.writeAddr tlplen=%d burstLen=%d", tlplen, burstLen); if ((addr >> 32) != 0 || !use3dw) begin TLPMemory4DWHeader hdr_4dw = defaultValue; hdr_4dw.format = MEM_WRITE_4DW_DATA; hdr_4dw.tag = extend(awid); hdr_4dw.reqid = my_id; hdr_4dw.nosnoop = SNOOPING_REQD; hdr_4dw.addr = addr[40-1:2]; hdr_4dw.length = tlplen; Bit#(TDiv#(buswidth,8)) firstbe = reqFirstByteEnable(req); Bit#(TDiv#(buswidth,8)) lastbe = reqLastByteEnable(req); hdr_4dw.firstbe = firstbe[3:0]; hdr_4dw.lastbe = (tlplen > 1) ? lastbe[valueOf(busWidthBytes)-1:valueOf(busWidthBytes)-4] : 0; tlp.data = extend(pack(hdr_4dw)); end else begin writeIs3dw = True; TLPMemoryIO3DWHeader hdr_3dw = defaultValue; hdr_3dw.format = MEM_WRITE_3DW_DATA; hdr_3dw.tag = extend(awid); hdr_3dw.reqid = my_id; hdr_3dw.nosnoop = SNOOPING_REQD; hdr_3dw.addr = addr[32-1:2]; hdr_3dw.length = tlplen; Bit#(TDiv#(buswidth,8)) firstbe = reqFirstByteEnable(req); Bit#(TDiv#(buswidth,8)) lastbe = reqLastByteEnable(req); hdr_3dw.firstbe = firstbe[3:0]; hdr_3dw.lastbe = (tlplen > 1) ? lastbe[valueOf(busWidthBytes)-1:valueOf(busWidthBytes)-4] : 0; tlp.be = 'hfff0; // no data word in this TLP tlp.data = extend(pack(hdr_3dw)); end tlpWriteHeaderFifo.enq(TlpWriteHeaderInfo {tlp: tlp, dwCount: tlplen, is3dw: writeIs3dw, isHeaderOnly: (writeIs3dw && tlplen == 1) }); writeBurstCountFifo.enq(burstLen); writeTag.enq(extend(awid)); endmethod endinterface interface Put writeData; method Action put(MemData#(buswidth) wdata) provisos (Bits#(Vector#(busWidthWords, Bit#(32)), busWidth)) if (writeDataMimoHasRoom); //.enqReadyN(fromInteger(valueOf(busWidthWords)))); let burstLen = writeBurstCount; if (burstLen == 0) begin burstLen <- toGet(writeBurstCountFifo).get(); end if (burstLen == 1) begin writeReadyFifo.enq(True); end writeBurstCount <= extend(burstLen-1); Vector#(busWidthWords, Bit#(32)) v = unpack(wdata.data); $display("writeData.put %h tag %h v %h writeDataCnt", wdata.data, wdata.tag, v, writeDataCnt.read); writeDataMimo.enq(fromInteger(valueOf(busWidthWords)), v); writeDataCnt.increment(fromInteger(valueOf(busWidthWords))); writeDataMimoEnqWire <= True; endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get(); let tag = doneTag.first(); doneTag.deq(); return truncate(tag); endmethod endinterface endinterface interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(40,buswidth) req); readReqFifo.enq(req); endmethod endinterface interface Get readData; method ActionValue#(MemData#(buswidth)) get() if (completionMimo.deqReady() && completionTagMimo.deqReady()); let data_v = completionMimo.first; let tag_last_v = completionTagMimo.first; match { .tag, .last } = tag_last_v[fromInteger(valueOf(busWidthWords))-1]; completionMimo.deq(); completionTagMimo.deq(); Bit#(buswidth) v = 0; for (Integer i = 0; i < valueOf(busWidthWords); i = i+1) begin `ifdef AXI `ifdef PCIE3 v[(i+1)*32-1:i*32] = data_v[i]; `else v[(i+1)*32-1:i*32] = byteSwap(data_v[i]); `endif `elsif AVALON v[(i+1)*32-1:i*32] = data_v[i]; `endif end return MemData { data: v, tag: truncate(tag), last: last}; // last beat of this response burst endmethod endinterface endinterface endinterface: slave method Bool tlpOutFifoNotEmpty() = tlpOutFifo.notEmpty; interface Reg use4dw = use4dwReg; endmodule: mkMemToPcie ================================================ FILE: bsv/MemWriteEngine.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import Cntrs::*; import FIFOF::*; import FIFO::*; import GetPut::*; import Connectable::*; import BRAMFIFO::*; import ConfigCounter::*; import ConnectalMemTypes::*; import Pipe::*; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" module mkMemWriteEngine(MemWriteEngine#(busWidth, userWidth, cmdQDepth, numServers)) provisos( Add#(1, d__, busWidth) ,Add#(1, d__, userWidth) ,Add#(e__, TLog#(numServers), MemTagSize) ,FunnelPipesPipelined#(1, numServers, MemData#(userWidth), 2) ,FunnelPipesPipelined#(1, numServers, MemRequest, 2) ,FunnelPipesPipelined#(1, numServers, Bit#(MemTagSize), 2) ); let rv <- mkMemWriteEngineBuff(valueOf(TExp#(BurstLenSize))); return rv; endmodule interface MemWriteChannel#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth); interface PipeIn#(Bit#(MemTagSize)) writeGnt; // grants request interface PipeOut#(MemRequest) writeReq; interface PipeOut#(MemData#(userWidth)) writeData; interface PipeIn#(Bit#(MemTagSize)) writeDone; interface MemWriteEngineServer#(userWidth) writeServer; endinterface module mkMemWriteChannel#(Integer bufferSizeBytes, Integer channelNumber, PipeOut#(Bit#(MemTagSize)) writeGntPipe, PipeOut#(Bit#(MemTagSize)) writeDonePipe) (MemWriteChannel#(busWidth, userWidth, cmdQDepth)) provisos ( Div#(busWidth,8,busWidthBytes) ,Log#(busWidthBytes,beatShift) ,Add#(1, d__, userWidth) ,Add#(userWidth, 0, busWidth) ); Integer bufferSizeBeats = bufferSizeBytes/valueOf(busWidthBytes); Reg#(Bool) load_in_progress <- mkReg(False); FIFO#(Tuple3#(MemengineCmd,Bool,Bool)) serverCond <- mkFIFO1(); FIFO#(Tuple2#(Bit#(MemTagSize),MemengineCmd)) serverReq <- mkSizedFIFO(valueOf(cmdQDepth)); FIFO#(Tuple3#(Bit#(BurstLenSize),Bit#(MemTagSize),Bool))inProgress <- mkSizedFIFO(valueOf(cmdQDepth)); FIFO#(Tuple3#(Bit#(MemTagSize),Bit#(MemTagSize),Bool)) serverDone <- mkSizedFIFO(valueOf(cmdQDepth)); FIFOF#(MemRequest) writeReqFifo <- mkFIFOF(); FIFOF#(MemData#(userWidth)) writeDataFifo <- mkFIFOF(); Reg#(Bool) clientInFlight <- mkReg(False); Reg#(Bool) clientBursts <- mkReg(False); ConfigCounter#(16) clientAvail <- mkConfigCounter(0); Reg#(MemengineCmd) clientStart <- mkReg(unpack(0)); FIFO#(Bool) clientFinished <- mkSizedFIFO(1); FIFOF#(MemengineCmd) clientCommand <- mkSizedFIFOF(1); Count#(Bit#(32)) clientCycles <- mkCount(0); FIFOF#(MemRequestCycles) clientCyclesFifo <- mkFIFOF(); FIFOF#(Bit#(userWidth)) dataBuffer <- mkSizedBRAMFIFOF(bufferSizeBeats); Reg#(Bit#(32)) cycles <- mkReg(0); rule rl_cycles; cycles <= cycles + 1; endrule Reg#(Bit#(BurstLenSize)) respCnt <- mkReg(0); let beat_shift = fromInteger(valueOf(beatShift)); rule store_cmd if (!clientInFlight); let cmd <- toGet(clientCommand).get(); clientInFlight <= True; clientBursts <= True; clientStart <= cmd; $display("cycles %d starting request %d bytes %d", cycles, cmd.tag, cmd.len); clientCycles <= 0; endrule rule rule_request_cycles; clientCycles.incr(1); endrule rule load_ctxt_a if (!load_in_progress); if (clientBursts) begin load_in_progress <= True; let cmd = clientStart; let cond1 = cmd.len <= extend(cmd.burstLen); Bool cond0 = False; if (cond1) begin cond0 <- clientAvail.maybeDecrement(unpack(truncate(cmd.len>>beat_shift))); end else begin cond0 <- clientAvail.maybeDecrement(unpack(extend(cmd.burstLen>>beat_shift))); end serverCond.enq(tuple3(cmd,cond0,cond1)); end endrule rule load_ctxt_b if (load_in_progress); load_in_progress <= False; match {.cmd,.cond0,.cond1} <- toGet(serverCond).get; if (cond0) begin //$display("load_ctxt_b cycles %d %h", cycles, cmd.base); serverReq.enq(tuple2(0,cmd)); if (cond1) begin clientBursts <= False; end else begin clientStart <= MemengineCmd{sglId:cmd.sglId, base:cmd.base+extend(cmd.burstLen), burstLen:cmd.burstLen, len:cmd.len-extend(cmd.burstLen), tag:cmd.tag}; end end endrule rule rlWriteReq; match {.idx, .cmd} <- toGet(serverReq).get; Bit#(BurstLenSize) bl = cmd.burstLen; Bool last = False; if (cmd.len <= extend(bl)) begin last = True; bl = truncate(cmd.len); end inProgress.enq(tuple3(truncate(bl>>beat_shift), cmd.tag, last)); //$display("writeReq %d, %h %h %h", channelNumber, cmd.base, bl, last); writeReqFifo.enq(MemRequest { sglId: cmd.sglId, offset: extend(cmd.base), burstLen:bl, tag: fromInteger(channelNumber)}); endrule rule rlWriteData; match {.rc, .client_tag, .last} = inProgress.first; //let gnt = writeGntPipe.first; let new_respCnt = respCnt+1; let lastBeat = False; if (new_respCnt == rc) begin respCnt <= 0; inProgress.deq(); //writeGntPipe.deq(); serverDone.enq(tuple3(0,client_tag,last)); lastBeat = True; end else begin respCnt <= new_respCnt; end let wd <- toGet(dataBuffer).get(); writeDataFifo.enq(MemData{data:wd, tag:fromInteger(channelNumber), last:lastBeat}); endrule rule rlWriteDone; let tag <- toGet(writeDonePipe).get(); match {.idx, .req_tag, .last} <- toGet(serverDone).get; if (last) begin clientInFlight <= False; clientFinished.enq(True); `ifdef MEMENGINE_REQUEST_CYCLES $display("cycles %d req_tag %d clientCycles = %d", cycles, req_tag, clientCycles); clientCyclesFifo.enq(MemRequestCycles { tag: req_tag, cycles: clientCycles }); `endif end //$display("writeDone %d %d", channelNumber, last); endrule MemWriteEngineServer#(userWidth) ws = (interface MemWriteEngineServer#(userWidth); interface Put request; method Action put(MemengineCmd cmd); Bit#(32) bsb = fromInteger(bufferSizeBytes); `ifdef SIMULATION Bit#(32) dw = fromInteger(valueOf(busWidthBytes)); Bit#(32) bl = extend(cmd.burstLen); // this is because bsc lifts the divide operation (below) // and on startup the simulator gets a floating-point exception if (bl ==0) bl = 1; let mdw1 = ((cmd.len)/dw)*dw != cmd.len; let bbl = extend(cmd.burstLen) > bsb; if(bbl || mdw1 || cmd.len == 0) begin if (bbl) $display("XXXXXXXXXX mkMemWriteEngineBuff::unsupported burstLen %d %d", bsb, cmd.burstLen); if (mdw1 || cmd.len == 0) $display("XXXXXXXXXX mkMemWriteEngineBuff::unsupported len %h mdw1=%d", cmd.len, mdw1); end else `endif begin clientCommand.enq(cmd); $display("(%d) %h %h %h", channelNumber, cmd.base, cmd.len, cmd.burstLen); end endmethod endinterface interface Get done; method ActionValue#(Bool) get = toGet(clientFinished).get; endinterface interface PipeIn data = interface PipeIn; method Bool notFull = dataBuffer.notFull; method Action enq(Bit#(userWidth) v); dataBuffer.enq(v); clientAvail.increment(1); endmethod endinterface; interface PipeOut requestCycles = toPipeOut(clientCyclesFifo); endinterface); interface writeServer = ws; interface writeReq = toPipeOut(writeReqFifo); interface writeData = toPipeOut(writeDataFifo); endmodule module mkMemWriteChannelPipelined#(Integer bufferSizeBytes, Integer channelNumber, PipeOut#(Bit#(MemTagSize)) writeGntPipe, PipeOut#(Bit#(MemTagSize)) writeDonePipe) (MemWriteChannel#(busWidth, userWidth, cmdQDepth)) provisos ( Div#(busWidth,8,busWidthBytes) ,Log#(busWidthBytes,beatShift) ,Add#(1, d__, userWidth) ,Add#(uqserWidth, 0, busWidth) ); Integer bufferSizeBeats = bufferSizeBytes/valueOf(busWidthBytes); // Reg#(Bool) load_in_progress <- mkReg(False); // FIFO#(Tuple3#(MemengineCmd,Bool,Bool)) serverCond <- mkFIFO1(); // FIFO#(Tuple2#(Bit#(MemTagSize),MemengineCmd)) serverReq <- mkSizedFIFO(valueOf(cmdQDepth)); FIFO#(Tuple3#(Bit#(BurstLenSize),Bit#(MemTagSize),Bool)) inProgress <- mkSizedFIFO(valueOf(cmdQDepth)); FIFO#(Tuple3#(Bit#(MemTagSize),Bit#(MemTagSize),Bool)) serverDone <- mkSizedFIFO(valueOf(cmdQDepth)); FIFOF#(MemRequest) writeReqFifo <- mkFIFOF(); FIFOF#(MemData#(userWidth)) writeDataFifo <- mkFIFOF(); // Reg#(Bool) clientInFlight <- mkReg(False); // Reg#(Bool) clientBursts <- mkReg(False); ConfigCounter#(16) clientAvail <- mkConfigCounter(0); // Reg#(MemengineCmd) clientStart <- mkReg(unpack(0)); FIFOF#(Bool) clientFinished <- mkSizedFIFOF(valueOf(cmdQDepth)); FIFOF#(MemengineCmd) clientCommand <- mkSizedFIFOF(valueOf(cmdQDepth)); // Count#(Bit#(32)) clientCycles <- mkCount(0); FIFOF#(Bit#(32)) clientCyclesFifoStart <- mkSizedFIFOF(valueOf(cmdQDepth)); FIFOF#(MemRequestCycles) clientCyclesFifo <- mkFIFOF(); FIFOF#(Bit#(userWidth)) dataBuffer <- mkSizedBRAMFIFOF(bufferSizeBeats); Reg#(Bit#(32)) cycles <- mkReg(0); rule rl_cycles; cycles <= cycles + 1; endrule Reg#(Bit#(BurstLenSize)) respCnt <- mkReg(0); let beat_shift = fromInteger(valueOf(beatShift)); // rule store_cmd if (!clientInFlight); // let cmd <- toGet(clientCommand).get(); // clientInFlight <= True; // clientBursts <= True; // clientStart <= cmd; // $display("cycles %d starting request %d bytes %d", cycles, cmd.tag, cmd.len); // clientCycles <= 0; // endrule // rule rule_request_cycles; // clientCycles.incr(1); // endrule // rule load_ctxt_a if (!load_in_progress); // if (clientBursts) begin // load_in_progress <= True; // let cmd = clientStart; // let cond1 = cmd.len <= extend(cmd.burstLen); // Bool cond0 = False; // if (cond1) begin // cond0 <- clientAvail.maybeDecrement(unpack(truncate(cmd.len>>beat_shift))); // end // else begin // cond0 <- clientAvail.maybeDecrement(unpack(extend(cmd.burstLen>>beat_shift))); // end // serverCond.enq(tuple3(cmd,cond0,cond1)); // end // endrule // rule load_ctxt_b if (load_in_progress); // load_in_progress <= False; // match {.cmd,.cond0,.cond1} <- toGet(serverCond).get; // if (cond0) begin // //$display("load_ctxt_b cycles %d %h", cycles, cmd.base); // serverReq.enq(tuple2(0,cmd)); // if (cond1) begin // clientBursts <= False; // end // else begin // clientStart <= MemengineCmd{sglId:cmd.sglId, base:cmd.base+extend(cmd.burstLen), // burstLen:cmd.burstLen, len:cmd.len-extend(cmd.burstLen), tag:cmd.tag}; // end // end // endrule /* rule fullReqQ (!clientCommand.notFull); $display("**WARNING** %m clientCommand Channel Num = %d is FULL...", channelNumber); endrule rule fullDataQ (!dataBuffer.notFull); $display("**WARNING** %m writeData Channel Num = %d is FULL...", channelNumber); endrule rule fullRespQ (!clientFinished.notFull); $display("**WARNING** %m clientFinished Channel Num = %d is FULL... (@ %t)", channelNumber, $time); endrule rule fullOutReqQ (!writeReqFifo.notFull); $display("**WARNING** %m writeReqFifo Channel Num = %d is FULL... (@ %t)", channelNumber, $time); endrule rule fullOutDataQ (!writeDataFifo.notFull); $display("**WARNING** %m writeDataFifo Channel Num = %d is FULL... (@ %t)", channelNumber, $time); endrule */ // rule emptyReqQ (!clientCommand.notEmpty); // $display("**WARNING** %m clientCommand is EMPTY..."); // endrule // rule emptyDataQ (!dataBuffer.notEmpty); // $display("**WARNING** %m writeData is EMPTY..."); // endrule // rule emptyRespQ (!clientFinished.notEmpty); // $display("**WARNING** %m clientFinished is EMPTY..."); // endrule Reg#(Bit#(32)) lenCnt <- mkReg(0); rule rlWriteReq; let cmd = clientCommand.first; let last = lenCnt + extend(cmd.burstLen) >= cmd.len; Bit#(BurstLenSize) bl = last ? truncate(cmd.len - lenCnt): cmd.burstLen; // this is to make sure we had enough data to burst // let actFlag <- clientAvail.maybeDecrement(unpack(extend(bl>>beat_shift))); // if ( actFlag ) begin lenCnt <= last ? 0 : lenCnt + extend(cmd.burstLen); if ( last ) begin clientCommand.deq; end $display("%m writeReq %d, %h %h %h (@ %t)", channelNumber, cmd.base, bl, last, $time); inProgress.enq(tuple3(truncate(bl>>beat_shift), cmd.tag, last)); writeReqFifo.enq(MemRequest { sglId: cmd.sglId, offset: extend(cmd.base+lenCnt), burstLen:bl, tag: fromInteger(channelNumber)}); // end endrule rule rlWriteData; match {.rc, .client_tag, .last} = inProgress.first; let new_respCnt = respCnt+1; let lastBeat = False; if (new_respCnt == rc) begin respCnt <= 0; inProgress.deq(); serverDone.enq(tuple3(0,client_tag,last)); lastBeat = True; end else begin respCnt <= new_respCnt; end let wd <- toGet(dataBuffer).get(); $display("%m writeData channel = %d, data:%h, last: %d (@%t)", channelNumber, wd, lastBeat, $time); writeDataFifo.enq(MemData{data:wd, tag:fromInteger(channelNumber), last:lastBeat}); endrule rule rlWriteDone; let tag <- toGet(writeDonePipe).get(); match {.idx, .req_tag, .last} <- toGet(serverDone).get; $display("%m writeDone idx: %d, req_tag: %d, last: %d (@ %t) ", idx, req_tag, last, $time); if (last) begin let startCycle <- toGet(clientCyclesFifoStart).get; // clientInFlight <= False; clientFinished.enq(True); `ifdef MEMENGINE_REQUEST_CYCLES $display("cycles %d req_tag %d clientCycles = %d", cycles-startCycle, req_tag, clientCycles); clientCyclesFifo.enq(MemRequestCycles { tag: req_tag, cycles: cyles - startCycle}); `endif end //$display("writeDone %d %d", channelNumber, last); endrule MemWriteEngineServer#(userWidth) ws = (interface MemWriteEngineServer#(userWidth); interface Put request; method Action put(MemengineCmd cmd); Bit#(32) bsb = fromInteger(bufferSizeBytes); `ifdef SIMULATION Bit#(32) dw = fromInteger(valueOf(busWidthBytes)); Bit#(32) bl = extend(cmd.burstLen); // this is because bsc lifts the divide operation (below) // and on startup the simulator gets a floating-point exception if (bl ==0) bl = 1; let mdw1 = ((cmd.len)/dw)*dw != cmd.len; let bbl = extend(cmd.burstLen) > bsb; if(bbl || mdw1 || cmd.len == 0) begin if (bbl) $display("XXXXXXXXXX mkMemWriteEngineBuff::unsupported burstLen %d %d", bsb, cmd.burstLen); if (mdw1 || cmd.len == 0) $display("XXXXXXXXXX mkMemWriteEngineBuff::unsupported len %h mdw1=%d", cmd.len, mdw1); end else `endif begin clientCommand.enq(cmd); // dataBeatQ.enq(cmd.len >> beat_shift); $display("(%d) %h %h %h", channelNumber, cmd.base, cmd.len, cmd.burstLen); clientCyclesFifoStart.enq(cycles); end endmethod endinterface interface Get done; method ActionValue#(Bool) get = toGet(clientFinished).get; endinterface interface PipeIn data = interface PipeIn; method Bool notFull = dataBuffer.notFull; method Action enq(Bit#(userWidth) v); dataBuffer.enq(v); // clientAvail.increment(1); endmethod endinterface; interface PipeOut requestCycles = toPipeOut(clientCyclesFifo); endinterface); interface writeServer = ws; interface writeReq = toPipeOut(writeReqFifo); interface writeData = toPipeOut(writeDataFifo); endmodule module mkMemWriteEngineBuff#(Integer bufferSizeBytes)(MemWriteEngine#(busWidth, userWidth, cmdQDepth, numServers)) provisos ( Div#(busWidth,8,busWidthBytes) ,Log#(busWidthBytes,beatShift) ,Add#(1, a__, userWidth) ,Add#(userWidth, 0, busWidth) ,Add#(b__, TLog#(numServers), MemTagSize) ,FunnelPipesPipelined#(1, numServers, MemData#(userWidth), 2) ,FunnelPipesPipelined#(1, numServers, MemRequest, 2) ,FunnelPipesPipelined#(1, numServers, Bit#(MemTagSize), 2) ); FIFOF#(Bit#(MemTagSize)) writeDoneFifo <- mkFIFOF(); function Tuple2#(Bit#(TLog#(numServers)),Bit#(MemTagSize)) tagDone(Bit#(MemTagSize) tag); return tuple2(truncate(tag), tag); endfunction `ifdef ARB_FUNNEL FIFOF#(Bit#(MemTagSize)) arbFifo <- mkFIFOF1(); UnFunnelPipe#(1,numServers,Bit#(MemTagSize),2) arbPipes <- mkUnFunnelPipesPipelined(vec(mapPipe(tagDone, toPipeOut(arbFifo)))); UnFunnelPipe#(1,numServers,Bit#(MemTagSize),2) donePipes <- mkUnFunnelPipesPipelined(vec(mapPipe(tagDone, toPipeOut(writeDoneFifo)))); `else Vector#(numServers, FIFOF#(Bit#(MemTagSize))) arbFifos <- replicateM(mkFIFOF); Vector#(numServers, PipeOut#(Bit#(MemTagSize))) arbPipes = map(toPipeOut, arbFifos); Vector#(numServers, FIFOF#(Bit#(MemTagSize))) doneFifos <- replicateM(mkFIFOF); Vector#(numServers, PipeOut#(Bit#(MemTagSize))) donePipes = map(toPipeOut, doneFifos); `endif // Vector#(numServers, MemWriteChannel#(busWidth,userWidth,cmdQDepth)) writeChannels <- zipWith3M(mkMemWriteChannel(bufferSizeBytes), // genVector(), // arbPipes, // donePipes); Vector#(numServers, MemWriteChannel#(busWidth,userWidth,cmdQDepth)) writeChannels <- zipWith3M(mkMemWriteChannelPipelined(bufferSizeBytes), genVector(), arbPipes, donePipes); function PipeOut#(MemRequest) writeChannelDmaWriteReq(Integer i); return writeChannels[i].writeReq; endfunction function PipeOut#(MemData#(userWidth)) writeChannelDmaWriteData(Integer i); return writeChannels[i].writeData; endfunction function MemWriteEngineServer#(userWidth) writeChannelServer(Integer i); return writeChannels[i].writeServer; endfunction Reg#(Bool) reqInFlight <- mkReg(False); Reg#(Bool) reqNotDone <- mkReg(False); Reg#(Bit#(TLog#(numServers))) currentChannel <- mkReg(0); FIFOF#(MemRequest) writeReqFifo <- mkFIFOF(); FIFOF#(MemData#(userWidth)) writeDataFifo <- mkSizedFIFOF(16); // FunnelPipe#(1,numServers,MemRequest,2) reqFunnel <- mkFunnelPipesPipelinedRR(genWith(writeChannelDmaWriteReq), 1); FunnelPipe#(1,numServers,MemRequest,2) reqFunnel <- mkFunnelPipesPipelined(genWith(writeChannelDmaWriteReq)); // FunnelPipe#(1,numServers,MemData#(userWidth),2) dataFunnel <- mkFunnelPipesPipelined(genWith(writeChannelDmaWriteData)); FIFO#(Bit#(TLog#(numServers))) channelQ <- mkSizedFIFO(valueOf(cmdQDepth)*valueOf(numServers)); rule rl_arbitration;// if (!reqInFlight );// && !reqNotDone); let req <- toGet(reqFunnel[0]).get(); // tag is channel number // currentChannel <= truncate(req.tag); // reqNotDone <= True; writeReqFifo.enq(req); // reqInFlight <= True; channelQ.enq(truncate(req.tag)); endrule rule rl_writeData;// if (reqInFlight); let currChannel = channelQ.first; MemData#(userWidth) md <- toGet(writeChannels[currChannel].writeData).get(); // MemData#(userWidth) md <- toGet(writeChannels[currentChannel].writeData).get(); if (md.last) channelQ.deq; // reqInFlight <= False; writeDataFifo.enq(md); endrule rule rl_writeDone; let tag <- toGet(writeDoneFifo).get(); doneFifos[tag].enq(tag); // reqNotDone <= False; endrule interface writeServers = genWith(writeChannelServer); interface MemWriteClient dmaClient; interface writeReq = toGet(writeReqFifo); interface writeData = toGet(writeDataFifo); interface writeDone = toPut(writeDoneFifo); endinterface: dmaClient endmodule ================================================ FILE: bsv/OldEHR.bsv ================================================ //----------------------------------------------------------------------// // The MIT License // // Copyright (c) 2008 Myron King, Nirav Dave // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. //----------------------------------------------------------------------// // // Neither of these two modules (mkEHR or mkEHRF) should be used // without being enclosed immediately in a synthesize boundry. // This is due to bug in the Bluespec compiler which really // screws things up. Finding this out was painful. Avoid the // pain and follow this warning. (I'm not sure if this is still // the case (mdk)) // // Second point: These two EHR implementations are close to what // Dan Rosenband outlined in his thesis. What they lack is // scheduling constraints between read/write pairs. That is to // say that read_1 and write_1 are conflict free whereas they // should be FORCED to schedule read_1 < write_1 ... import Vector ::*; import RWire ::*; import Probe ::*; typedef Vector#(n_sz, Reg#(alpha)) EHR#(type n_sz, type alpha); /*********************************************************************/ // mkVirtualReg adds one level of ephemeralness to 'base'. 'state' // is the concrete interface underlying the virtual register (the // register itself). With state and base as input, mkVirtualReg // connects them with Rwires and probes so as to enforce the proper // rule scheduling and behavior: // ... < read_n < write_n < read_n+1 < write_n+1 < ... /*********************************************************************/ module mkVirtualReg#(Reg#(alpha) state, Reg#(alpha) base) (Tuple2#(Reg#(alpha), Reg#(alpha))) provisos(Bits#(alpha,asz)); // enforce ordering and data forewarding using wires and probes RWire#(alpha) w <- mkRWire(); Probe#(alpha) probe <- mkProbe; Reg#(alpha) i0 = interface Reg method _read(); return base._read(); endmethod method Action _write(x); w.wset(x); probe <= base._read(); endmethod endinterface; Reg#(alpha) i1 = interface Reg method _read() = fromMaybe(base._read, w.wget()); method _write(x) = noAction; // never used endinterface; return (tuple2(i0,i1)); endmodule /*********************************************************************/ // Creates an EHR module by layering virtual registers // .idx[i] holds read_i and write_i methods. reg.read_n // is expressec as reg[n]._read(); /*********************************************************************/ module mkEHRF#(alpha init)(EHR#(n,alpha)) provisos(Bits#(alpha, asz), Add#(li, 1, n)); Reg#(alpha) r <- mkReg(init); Vector#(n,Reg#(alpha)) vidx = newVector(); // 'old' is a placeholder which also ensures that the last-written value // won't get dropped since r and old are both the initial register during // the first iteration of the 'for' loop. Reg #(alpha) old = r; Tuple2#(Reg#(alpha),Reg#(alpha)) tinf; // make interfaces for(Integer i = 0; i < valueOf(n); i = i + 1) begin tinf <- mkVirtualReg(r,old); vidx[i] = tinf.fst(); old = tinf.snd(); end rule do_stuff(True); r <= tinf.snd._read(); endrule return vidx; endmodule /*********************************************************************/ // alternate implementation, not quite as cool as the functional // version, but less code and possibly easier to understand /*********************************************************************/ module mkEHR#(alpha init) (EHR#(n,alpha)) provisos(Bits#(alpha, asz), Add#(li, 1, n)); Reg#(alpha) r <- mkReg(init); Vector#(n, RWire#(alpha)) wires <- replicateM(mkRWire); Vector#(n, RWire#(alpha)) probes <- replicateM(mkRWire); Vector#(n, Reg#(alpha)) vidx = newVector(); Vector#(n, alpha) chain = newVector(); for(Integer i = 0; i < valueOf(n); i = i + 1) begin if(i==0) chain[i] = r; else chain[i] = fromMaybe(chain[i-1], wires[i-1].wget()); end for(Integer j = 0; j < valueOf(n); j = j + 1) begin vidx[j] = interface Reg method _read(); return chain[j]; endmethod method Action _write(x); wires[j].wset(x); probes[j].wset(chain[j]); endmethod endinterface; end (*fire_when_enabled, no_implicit_conditions *) rule do_stuff(True); r <= fromMaybe(chain[valueOf(li)], wires[valueOf(li)].wget()); endrule return vidx; endmodule interface EHR2BSV#(type t); interface Reg#(t) r1; interface Reg#(t) r2; endinterface (* synthesize *) module mkEHR2BSV (EHR2BSV#(Bit#(32))); EHR#(2,Bit#(32)) ehr <- mkEHR(0); interface r1 = ehr[0]; interface r2 = ehr[1]; endmodule ================================================ FILE: bsv/PS4LIB.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Copyright (c) 2014 Cornell Univeristy. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Stratix IV PCIe Wrapper. import Clocks ::*; import Vector ::*; import Connectable ::*; import ConnectalAlteraCells ::*; import ConnectalClocks ::*; import ALTERA_PCIE_SIV_WRAPPER ::*; (* always_ready, always_enabled *) interface PcieLmi#(numeric type address_width, numeric type data_width); method Action rden(Bit#(1) rden); method Action wren(Bit#(1) wren); method Action addr(Bit#(address_width) addr); method Action din(Bit#(data_width) din); method Bit#(data_width) dout(); method Bit#(1) ack(); endinterface (* always_ready, always_enabled *) interface PcieRxSt#(numeric type data_width); method Bit#(1) sop ; method Bit#(1) eop ; method Bit#(data_width) data ; method Bit#(1) valid ; method Bit#(1) err ; method Bit#(1) empty ; method Bit#(8) bar ; method Bit#(16) be ; method Action ready(Bit#(1) ready) ; method Action mask(Bit#(1) mask) ; endinterface (* always_ready, always_enabled *) interface PcieTxSt#(numeric type data_width); method Action sop(Bit#(1) sop); method Action eop(Bit#(1) eop); method Action valid(Bit#(1) valid); method Action err(Bit#(1) err); method Action empty(Bit#(1) empty); method Bit#(1) ready; method Action data(Bit#(data_width) data); endinterface (* always_ready, always_enabled *) interface PcieMsi; method Bit#(1) int_ack(); method Action int_sts (Bit#(1) int_sts); method Bit#(1) msi_ack(); method Action msi_num(Bit#(5)num); method Action msi_req(Bit#(1)req); method Action msi_tc(Bit#(3)tc); method Action pex_msi_num(Bit#(5) pex_msi_num); endinterface (* always_ready, always_enabled *) interface PcieTlCfg; method Bit#(4) add(); method Bit#(32) ctl(); method Bit#(1) ctl_wr(); method Bit#(53) sts(); method Bit#(1) sts_wr(); method Action cpl_pending(Bit#(1) cpl_pending); method Action cpl_err(Bit#(7) cpl_err); endinterface (* always_ready, always_enabled *) interface PcieHipRst; method Bit#(1) serdes_pll_locked(); method Action reconfig_clk_locked(Bit#(1) locked); endinterface (* always_ready, always_enabled *) interface PcieTxCred; method Bit#(36) cred(); endinterface (* always_ready, always_enabled *) interface PcieRxin; (* prefix="", result="in" *) method Action in((* port="in" *) Vector#(8, Bit#(1)) a); endinterface (* always_ready, always_enabled *) interface PcieTxout; method Vector#(8, Bit#(1)) out(); endinterface interface PcieHipSerial; interface PcieRxin rx; interface PcieTxout tx; endinterface interface PcieHipPipe; (* prefix="", result="rxdata" *) method Action rxdata (Vector#(8, Bit#(8)) rxdata); (* prefix="", result="rxdatak" *) method Action rxdatak ((* port="rxdatak" *) Vector#(8, Bit#(1)) rxdatak); (* prefix="", result="rxelecidle" *) method Action rxelecidle(Vector#(8, Bit#(1)) rxelecidle); (* prefix="", result="rxstatus" *) method Action rxstatus (Vector#(8, Bit#(3)) rxstatus); (* prefix="", result="rxvalid" *) method Action rxvalid (Vector#(8, Bit#(1)) rxvalid); (* prefix="", result="phystatus" *) method Action phystatus (Vector#(1, Bit#(1)) phystatus); (* prefix="", result="sim_pipe_pclk_in" *) method Action sim_pipe_pclk_in(Bit#(1) sim_pipe_pclk_in); method Vector#(8, Bit#(1)) rxpolarity(); method Vector#(8, Bit#(1)) txcompl(); (* prefix="", result="txdata" *) method Vector#(8, Bit#(8)) txdata(); method Vector#(8, Bit#(1)) txdatak(); method Vector#(1, Bit#(1)) txdetectrx(); method Vector#(8, Bit#(1)) txelecidle(); method Vector#(1, Bit#(2)) powerdown(); method Bit#(5) sim_ltssmstate(); method Bit#(1) sim_pipe_rate(); endinterface (* always_ready, always_enabled *) interface PcieHipCtrl; (* prefix="", result="test_in" *) method Action test_in(Bit#(40) test_in); (* prefix="", result="simu_mode_pipe" *) method Action simu_mode_pipe(Bit#(1) simu_mode_pipe); endinterface (* always_ready, always_enabled *) interface PcieWrap#(numeric type address_width, numeric type data_width, numeric type app_width); interface PcieLmi#(address_width, data_width) lmi; interface PcieRxSt#(app_width) rx_st; interface PcieTxSt#(app_width) tx_st; interface PcieMsi msi; interface PcieTlCfg tl_cfg; interface PcieHipRst hip_rst; interface PcieTxCred tx_cred; interface PcieRxin rx; interface PcieTxout tx; interface PcieHipPipe hip_pipe; interface PcieHipCtrl hip_ctrl; interface Clock coreclkout_hip; interface Reset core_reset; endinterface //(* synthesize *) module mkPcieS4Wrap#(Clock refclk, Clock reconfig_clk, Clock serdes_clk, Reset pcie_rstn, Reset local_rstn)(PcieWrap#(12, 32, 128)); Vector#(8, Wire#(Bit#(1))) rx_in_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(8))) rxdata_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) rxdatak_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) rxelecidle_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(3))) rxstatus_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) rxvalid_wires <- replicateM(mkDWire(0)); Vector#(1, Wire#(Bit#(1))) phystatus_wires <- replicateM(mkDWire(0)); Clock default_clock <- exposeCurrentClock; Reset default_reset <- exposeCurrentReset; Reset reset_high <- invertCurrentReset; PcieS4Wrap pcie <- mkPPS4Wrap(refclk, reconfig_clk, serdes_clk, pcie_rstn, local_rstn); Clock coreclk = pcie.core.clk_out; Reset corerst <- mkSyncReset(1, pcie.sr.stn, coreclk); (* no_implicit_conditions *) rule pcie_rx; pcie.rx.in0(rx_in_wires[0]); pcie.rx.in1(rx_in_wires[1]); pcie.rx.in2(rx_in_wires[2]); pcie.rx.in3(rx_in_wires[3]); pcie.rx.in4(rx_in_wires[4]); pcie.rx.in5(rx_in_wires[5]); pcie.rx.in6(rx_in_wires[6]); pcie.rx.in7(rx_in_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxdata; pcie.rx.data0_ext(rxdata_wires[0]); pcie.rx.data1_ext(rxdata_wires[1]); pcie.rx.data2_ext(rxdata_wires[2]); pcie.rx.data3_ext(rxdata_wires[3]); pcie.rx.data4_ext(rxdata_wires[4]); pcie.rx.data5_ext(rxdata_wires[5]); pcie.rx.data6_ext(rxdata_wires[6]); pcie.rx.data7_ext(rxdata_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxdatak; pcie.rx.datak0_ext(rxdatak_wires[0]); pcie.rx.datak1_ext(rxdatak_wires[1]); pcie.rx.datak2_ext(rxdatak_wires[2]); pcie.rx.datak3_ext(rxdatak_wires[3]); pcie.rx.datak4_ext(rxdatak_wires[4]); pcie.rx.datak5_ext(rxdatak_wires[5]); pcie.rx.datak6_ext(rxdatak_wires[6]); pcie.rx.datak7_ext(rxdatak_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxelecidle; pcie.rx.elecidle0_ext(rxelecidle_wires[0]); pcie.rx.elecidle1_ext(rxelecidle_wires[1]); pcie.rx.elecidle2_ext(rxelecidle_wires[2]); pcie.rx.elecidle3_ext(rxelecidle_wires[3]); pcie.rx.elecidle4_ext(rxelecidle_wires[4]); pcie.rx.elecidle5_ext(rxelecidle_wires[5]); pcie.rx.elecidle6_ext(rxelecidle_wires[6]); pcie.rx.elecidle7_ext(rxelecidle_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxstatus; pcie.rx.status0_ext(rxstatus_wires[0]); pcie.rx.status1_ext(rxstatus_wires[1]); pcie.rx.status2_ext(rxstatus_wires[2]); pcie.rx.status3_ext(rxstatus_wires[3]); pcie.rx.status4_ext(rxstatus_wires[4]); pcie.rx.status5_ext(rxstatus_wires[5]); pcie.rx.status6_ext(rxstatus_wires[6]); pcie.rx.status7_ext(rxstatus_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxvalid; pcie.rx.valid0_ext(rxvalid_wires[0]); pcie.rx.valid1_ext(rxvalid_wires[1]); pcie.rx.valid2_ext(rxvalid_wires[2]); pcie.rx.valid3_ext(rxvalid_wires[3]); pcie.rx.valid4_ext(rxvalid_wires[4]); pcie.rx.valid5_ext(rxvalid_wires[5]); pcie.rx.valid6_ext(rxvalid_wires[6]); pcie.rx.valid7_ext(rxvalid_wires[7]); endrule (* no_implicit_conditions *) rule pcie_phystatus; pcie.phystatus.ext(phystatus_wires[0]); endrule (* no_implicit_conditions *) rule power_mgmt; pcie.pm.auxpwr(0); pcie.pm.data(10'b0); pcie.pm_e.vent(0); pcie.pm.e_to_cr(0); endrule C2B c2b <- mkC2B(coreclk); rule pld_clk_rule; pcie.pld.clk(c2b.o()); endrule method Clock coreclkout_hip; return coreclk; endmethod method Reset core_reset; return corerst; endmethod interface PcieLmi lmi; method Bit#(32) dout(); return pcie.lmi.dout; endmethod method Bit#(1) ack (); return pcie.lmi.ack; endmethod method rden = pcie.lmi.rden; method wren = pcie.lmi.wren; method addr = pcie.lmi.addr; method din = pcie.lmi.din; endinterface interface PcieMsi msi; method Bit#(1) int_ack; return pcie.app.int_ack; endmethod method Bit#(1) msi_ack; return pcie.app.msi_ack; endmethod method msi_num = pcie.app.msi_num; method msi_req = pcie.app.msi_req; method msi_tc = pcie.app.msi_tc; method int_sts = pcie.app.int_sts; method pex_msi_num = pcie.pex_msi.num; endinterface interface PcieTlCfg tl_cfg; method Bit#(4) add(); return pcie.tl_cfg.add; endmethod method Bit#(32) ctl(); return pcie.tl_cfg.ctl; endmethod method Bit#(1) ctl_wr(); return pcie.tl_cfg.ctl_wr; endmethod method Bit#(53) sts(); return pcie.tl_cfg.sts; endmethod method Bit#(1) sts_wr(); return pcie.tl_cfg.sts_wr; endmethod method cpl_pending = pcie.cpl.pending; method cpl_err = pcie.cpl.err; endinterface interface PcieRxSt rx_st; method Bit#(1) sop(); return pcie.rx_st.sop0; endmethod method Bit#(1) eop(); return pcie.rx_st.eop0; endmethod method Bit#(128) data(); return pcie.rx_st.data0; endmethod method Bit#(1) valid(); return pcie.rx_st.valid0; endmethod method Bit#(1) err(); return pcie.rx_st.err0; endmethod method Bit#(1) empty(); return pcie.rx_st.empty0; endmethod method Bit#(8) bar(); return pcie.rx_st.bardec0; endmethod method Bit#(16) be(); return pcie.rx_st.be0; endmethod method ready = pcie.rx_st.ready0; method mask = pcie.rx_st.mask0; endinterface interface PcieTxSt tx_st; method Bit#(1) ready (); return pcie.tx_st.ready0; endmethod method sop = pcie.tx_st.sop0 ; method eop = pcie.tx_st.eop0 ; method valid = pcie.tx_st.valid0 ; method err = pcie.tx_st.err0 ; method empty = pcie.tx_st.empty0 ; method data = pcie.tx_st.data0 ; endinterface interface PcieRxin rx; method Action in(Vector#(8, Bit#(1)) a); writeVReg(rx_in_wires, a); endmethod endinterface interface PcieTxout tx; method Vector#(8, Bit#(1)) out(); Vector#(8, Bit#(1)) ret_val; ret_val[0] = pcie.tx.out0; ret_val[1] = pcie.tx.out1; ret_val[2] = pcie.tx.out2; ret_val[3] = pcie.tx.out3; ret_val[4] = pcie.tx.out4; ret_val[5] = pcie.tx.out5; ret_val[6] = pcie.tx.out6; ret_val[7] = pcie.tx.out7; return ret_val; endmethod endinterface interface PcieHipPipe hip_pipe; method Action rxdata(Vector#(8, Bit#(8)) a); writeVReg(rxdata_wires, a); endmethod method Action rxdatak(Vector#(8, Bit#(1)) a); writeVReg(rxdatak_wires, a); endmethod method Action rxelecidle(Vector#(8, Bit#(1)) a); writeVReg(rxelecidle_wires, a); endmethod method Action rxstatus(Vector#(8, Bit#(3)) a); writeVReg(rxstatus_wires, a); endmethod method Action rxvalid(Vector#(8, Bit#(1)) a); writeVReg(rxvalid_wires, a); endmethod method Action phystatus(Vector#(1, Bit#(1)) a); writeVReg(phystatus_wires, a); endmethod method rxpolarity(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.rx.polarity7_ext, pcie.rx.polarity6_ext, pcie.rx.polarity5_ext, pcie.rx.polarity4_ext, pcie.rx.polarity3_ext, pcie.rx.polarity2_ext, pcie.rx.polarity1_ext, pcie.rx.polarity0_ext}); return retval; endmethod method txcompl(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.compl7_ext, pcie.tx.compl6_ext, pcie.tx.compl5_ext, pcie.tx.compl4_ext, pcie.tx.compl3_ext, pcie.tx.compl2_ext, pcie.tx.compl1_ext, pcie.tx.compl0_ext}); return retval; endmethod method txdata(); Vector#(8, Bit#(8)) retval; retval = unpack({pcie.tx.data7_ext, pcie.tx.data6_ext, pcie.tx.data5_ext, pcie.tx.data4_ext, pcie.tx.data3_ext, pcie.tx.data2_ext, pcie.tx.data1_ext, pcie.tx.data0_ext}); return retval; endmethod method txdatak(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.datak7_ext, pcie.tx.datak6_ext, pcie.tx.datak5_ext, pcie.tx.datak4_ext, pcie.tx.datak3_ext, pcie.tx.datak2_ext, pcie.tx.datak1_ext, pcie.tx.datak0_ext}); return retval; endmethod method txdetectrx(); Vector#(1, Bit#(1)) retval; retval = unpack(pcie.tx.detectrx_ext); return retval; endmethod method txelecidle(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.elecidle7_ext, pcie.tx.elecidle6_ext, pcie.tx.elecidle5_ext, pcie.tx.elecidle4_ext, pcie.tx.elecidle3_ext, pcie.tx.elecidle2_ext, pcie.tx.elecidle1_ext, pcie.tx.elecidle0_ext}); return retval; endmethod method powerdown(); Vector#(1, Bit#(2)) retval; retval = unpack(pcie.powerdown.ext); return retval; endmethod method sim_pipe_pclk_in = pcie.pclk.in; method sim_ltssmstate(); return pcie.lts.sm; endmethod method sim_pipe_rate(); return pcie.rate.ext; endmethod endinterface interface PcieHipCtrl hip_ctrl; method test_in = pcie.test.in; method simu_mode_pipe = pcie.pipe.mode; endinterface interface PcieHipRst hip_rst; method Bit#(1) serdes_pll_locked; return pcie.rc_pll.locked; endmethod method reconfig_clk_locked = pcie.reconfig.clk_locked; endinterface interface PcieTxCred tx_cred; method cred(); return pcie.tx.cred0; endmethod endinterface endmodule ================================================ FILE: bsv/PS5LIB.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Copyright (c) 2014 Cornell Univeristy. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Stratix V PCIe Wrapper import Clocks ::*; import Vector ::*; import Connectable ::*; import ConnectalAlteraCells ::*; import ConnectalClocks ::*; import ALTERA_XCVR_RECONFIG_WRAPPER ::*; import ALTERA_PCIE_RECONFIG_DRIVER_WRAPPER ::*; import ALTERA_PCIE_SV_WRAPPER ::*; //import ALTERA_PLL_WRAPPER ::*; (* always_ready, always_enabled *) interface PcieRxSt#(numeric type data_width); method Bit#(1) sop; method Bit#(1) eop; method Bit#(data_width) data; method Action ready(Bit#(1) ready); method Bit#(1) valid; method Bit#(1) err; method Bit#(2) empty; method Action mask(Bit#(1) mask); method Bit#(8) bar(); method Bit#(16) be(); endinterface (* always_ready, always_enabled *) interface PcieTxSt#(numeric type data_width); method Action sop(Bit#(1) sop); method Action eop(Bit#(1) eop); method Action valid(Bit#(1) valid); method Action err(Bit#(1) err); method Action empty(Bit#(2) empty); method Bit#(1) ready; method Action data(Bit#(data_width) data); endinterface (* always_ready, always_enabled *) interface PcieMsi; method Bit#(1) int_ack(); method Action int_sts (Bit#(1) int_sts); method Bit#(1) msi_ack(); method Action msi_num(Bit#(5)num); method Action msi_req(Bit#(1)req); method Action msi_tc(Bit#(3)tc); endinterface (* always_ready, always_enabled *) interface PcieTlCfg; method Bit#(8) bus_number; method Bit#(5) dev_number; method Action cpl_pending(Bit#(1) cpl_pending); method Action cpl_err(Bit#(7) cpl_err); endinterface (* always_ready, always_enabled *) interface PcieHipRst; method Bit#(1) serdes_pll_locked(); method Bit#(1) pld_clk_inuse(); method Action core_ready(Bit#(1) core_ready); endinterface (* always_ready, always_enabled *) interface PcieTxCred; method Bit#(12) datafccp(); method Bit#(12) datafcnp(); method Bit#(12) datafcp(); method Bit#(8) hdrfccp(); method Bit#(8) hdrfcnp(); method Bit#(8) hdrfcp(); method Bit#(6) fchipcons(); method Bit#(6) fcinfinite(); endinterface (* always_ready, always_enabled *) interface PcieRxin; (* prefix="", result="in" *) method Action in(Vector#(8, Bit#(1)) a); endinterface (* always_ready, always_enabled *) interface PcieTxout; method Vector#(8, Bit#(1)) out(); endinterface (* always_ready, always_enabled *) interface PcieHipStatus; method Bit#(1) cor_ext_rcv; method Bit#(1) cor_ext_rpl; method Bit#(1) rpl; method Bit#(1) dlup; method Bit#(1) dlup_exit; method Bit#(1) ev128ns; method Bit#(1) ev1us; method Bit#(1) hotrst; method Bit#(4) int_status; method Bit#(1) l2_exit; method Bit#(4) lane_act; method Bit#(5) ltssmstate; method Bit#(1) rx_par_err; method Bit#(2) tx_par_err; (* prefix="", result="cfg_par_err" *) method Bit#(1) cfg_par_err; method Bit#(12) ko_cpl_spc_data; method Bit#(8) ko_cpl_spc_header; endinterface interface PcieHipSerial; interface PcieRxin rx; interface PcieTxout tx; endinterface interface PcieHipPipe; (* prefix="", result="rxdata" *) method Action rxdata (Vector#(8, Bit#(8)) rxdata); (* prefix="", result="rxdatak" *) method Action rxdatak (Vector#(8, Bit#(1)) rxdatak); (* prefix="", result="rxelecidle" *) method Action rxelecidle(Vector#(8, Bit#(1)) rxelecidle); (* prefix="", result="rxstatus" *) method Action rxstatus (Vector#(8, Bit#(3)) rxstatus); (* prefix="", result="rxvalid" *) method Action rxvalid (Vector#(8, Bit#(1)) rxvalid); (* prefix="", result="phystatus" *) method Action phystatus (Vector#(8, Bit#(1)) phystatus); method Vector#(8, Bit#(1)) rxpolarity(); method Vector#(8, Bit#(1)) txcompl(); method Vector#(8, Bit#(8)) txdata(); method Vector#(8, Bit#(1)) txdatak(); method Vector#(8, Bit#(1)) txdeemph(); method Vector#(8, Bit#(1)) txdetectrx(); method Vector#(8, Bit#(1)) txelecidle(); method Vector#(8, Bit#(3)) txmargin(); method Vector#(8, Bit#(1)) txswing(); method Vector#(8, Bit#(2)) powerdown(); method Vector#(8, Bit#(3)) eidleinfersel(); method Bit#(5) sim_ltssmstate(); method Bit#(2) sim_pipe_rate(); endinterface (* always_ready, always_enabled *) interface PcieHipCtrl; (* prefix="", result="test_in" *) method Action test_in(Bit#(32) test_in); endinterface (* always_ready, always_enabled *) interface PcieWrap#(numeric type address_width, numeric type data_width, numeric type app_width); interface PcieRxSt#(app_width) rx_st; interface PcieTxSt#(app_width) tx_st; interface PcieMsi msi; interface PcieTlCfg tl_cfg; interface PcieHipRst hip_rst; interface PcieTxCred tx_cred; interface PcieRxin rx; interface PcieTxout tx; interface PcieHipStatus hip_status; interface PcieHipPipe hip_pipe; interface PcieHipCtrl hip_ctrl; interface Clock coreclkout_hip; interface Reset core_reset; endinterface //(* synthesize *) module mkPcieS5Wrap#(Clock clk_100Mhz, Clock clk_50Mhz, Reset npor, Reset pin_perst)(PcieWrap#(12, 32, 128)); Vector#(8, Wire#(Bit#(1))) rx_in_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(8))) rxdata_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) rxdatak_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) rxelecidle_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(3))) rxstatus_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) rxvalid_wires <- replicateM(mkDWire(0)); Vector#(8, Wire#(Bit#(1))) phystatus_wires <- replicateM(mkDWire(0)); Clock default_clock <- exposeCurrentClock; Reset default_reset <- exposeCurrentReset; Reset reset_high <- invertCurrentReset; PcieS5Wrap pcie <- mkPPS5Wrap(clk_100Mhz, npor, pin_perst, reset_high); Clock coreclk = pcie.coreclkout.hip; Reset corerst <- mkSyncReset(1, pcie.reset.status, coreclk); Reset core_resetn <- mkResetInverter(corerst, clocked_by coreclk); AlteraPcieHipRs hip_rs <- mkAlteraPcieHipRs(coreclk, core_resetn); PcieReconfigWrap pcie_cfg <- mkPcieReconfigWrap(coreclk, clk_50Mhz, npor, reset_high, reset_high); XcvrReconfigWrap xcvr_cfg <- mkXcvrReconfigWrap(clk_50Mhz, reset_high, reset_high); Reg#(Bit#(8)) bus_number_reg <- mkReg(0, clocked_by coreclk, reset_by core_resetn); Reg#(Bit#(5)) dev_number_reg <- mkReg(0, clocked_by coreclk, reset_by core_resetn); rule pertick1; pcie.pld.core_ready(pcie.serdes.pll_locked); endrule rule pertick3; hip_rs.dlup_exit(pcie.dl.up_exit); hip_rs.hotrst_exit(pcie.hotrst.exit); hip_rs.l2_exit(pcie.l2.exit); hip_rs.ltssm(pcie.ltssm.state); endrule (* no_implicit_conditions *) rule connectReconfigMgmt; xcvr_cfg.reconfig_mgmt.read(pcie_cfg.reconfig_mgmt.read); xcvr_cfg.reconfig_mgmt.write(pcie_cfg.reconfig_mgmt.write); xcvr_cfg.reconfig_mgmt.address(pcie_cfg.reconfig_mgmt.address); xcvr_cfg.reconfig_mgmt.writedata(pcie_cfg.reconfig_mgmt.writedata); pcie_cfg.reconfig_mgmt.readdata(xcvr_cfg.reconfig_mgmt.readdata); pcie_cfg.reconfig_mgmt.waitrequest(xcvr_cfg.reconfig_mgmt.waitrequest); endrule (* no_implicit_conditions *) rule connectCurrentSpeed; pcie_cfg.current.speed(pcie.current.speed); endrule (* no_implicit_conditions *) rule connect_xcvr_reconfig; pcie.reconfig.to_xcvr(xcvr_cfg.reconfig.to_xcvr); xcvr_cfg.reconfig.from_xcvr(pcie.reconfig.from_xcvr); endrule (* no_implicit_conditions *) rule connectBusy; pcie_cfg.reconfig_b.usy(xcvr_cfg.reconfig.busy); endrule (* no_implicit_conditions *) rule connectHipStatus; pcie_cfg.derr.cor_ext_rcv_drv(pcie.derr.cor_ext_rcv); pcie_cfg.derr.cor_ext_rpl_drv(pcie.derr.cor_ext_rpl); pcie_cfg.derr.rpl_drv(pcie.derr.rpl); pcie_cfg.dlup.drv(pcie.dl.up); pcie_cfg.dlup.exit_drv(pcie.dl.up_exit); pcie_cfg.ev128ns.drv(pcie.ev128.ns); pcie_cfg.ev1us.drv(pcie.ev1.us); pcie_cfg.hotrst.exit_drv(pcie.hotrst.exit); pcie_cfg.int_s.tatus_drv(pcie.int_s.tatus); pcie_cfg.lane.act_drv(pcie.lane.act); pcie_cfg.l2.exit_drv(pcie.l2.exit); pcie_cfg.ltssmstate.drv(pcie.ltssm.state); pcie_cfg.tx.par_err_drv(pcie.tx_par.err); pcie_cfg.rx.par_err_drv(pcie.rx_par.err); pcie_cfg.cfg.par_err_drv(pcie.cfg_par.err); pcie_cfg.ko.cpl_spc_data_drv(pcie.ko.cpl_spc_data); pcie_cfg.ko.cpl_spc_header_drv(pcie.ko.cpl_spc_header); endrule (* no_implicit_conditions *) rule power_mgmt; pcie.pm.auxpwr(0); pcie.pm.data(10'b0); pcie.pm_e.vent(0); pcie.pme.to_cr(0); pcie.hpg.ctrler(5'b0); endrule C2B c2b <- mkC2B(pcie.coreclkout.hip); rule pld_clk_rule; pcie.pld.clk(c2b.o()); endrule (* no_implicit_conditions *) rule pcie_rx; pcie.rx.in0(rx_in_wires[0]); pcie.rx.in1(rx_in_wires[1]); pcie.rx.in2(rx_in_wires[2]); pcie.rx.in3(rx_in_wires[3]); pcie.rx.in4(rx_in_wires[4]); pcie.rx.in5(rx_in_wires[5]); pcie.rx.in6(rx_in_wires[6]); pcie.rx.in7(rx_in_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxdata; pcie.rx.data0(rxdata_wires[0]); pcie.rx.data1(rxdata_wires[1]); pcie.rx.data2(rxdata_wires[2]); pcie.rx.data3(rxdata_wires[3]); pcie.rx.data4(rxdata_wires[4]); pcie.rx.data5(rxdata_wires[5]); pcie.rx.data6(rxdata_wires[6]); pcie.rx.data7(rxdata_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxdatak; pcie.rx.datak0(rxdatak_wires[0]); pcie.rx.datak1(rxdatak_wires[1]); pcie.rx.datak2(rxdatak_wires[2]); pcie.rx.datak3(rxdatak_wires[3]); pcie.rx.datak4(rxdatak_wires[4]); pcie.rx.datak5(rxdatak_wires[5]); pcie.rx.datak6(rxdatak_wires[6]); pcie.rx.datak7(rxdatak_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxelecidle; pcie.rx.elecidle0(rxelecidle_wires[0]); pcie.rx.elecidle1(rxelecidle_wires[1]); pcie.rx.elecidle2(rxelecidle_wires[2]); pcie.rx.elecidle3(rxelecidle_wires[3]); pcie.rx.elecidle4(rxelecidle_wires[4]); pcie.rx.elecidle5(rxelecidle_wires[5]); pcie.rx.elecidle6(rxelecidle_wires[6]); pcie.rx.elecidle7(rxelecidle_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxstatus; pcie.rx.status0(rxstatus_wires[0]); pcie.rx.status1(rxstatus_wires[1]); pcie.rx.status2(rxstatus_wires[2]); pcie.rx.status3(rxstatus_wires[3]); pcie.rx.status4(rxstatus_wires[4]); pcie.rx.status5(rxstatus_wires[5]); pcie.rx.status6(rxstatus_wires[6]); pcie.rx.status7(rxstatus_wires[7]); endrule (* no_implicit_conditions *) rule pcie_rxvalid; pcie.rx.valid0(rxvalid_wires[0]); pcie.rx.valid1(rxvalid_wires[1]); pcie.rx.valid2(rxvalid_wires[2]); pcie.rx.valid3(rxvalid_wires[3]); pcie.rx.valid4(rxvalid_wires[4]); pcie.rx.valid5(rxvalid_wires[5]); pcie.rx.valid6(rxvalid_wires[6]); pcie.rx.valid7(rxvalid_wires[7]); endrule (* no_implicit_conditions *) rule pcie_phystatus; pcie.phy.status0(phystatus_wires[0]); pcie.phy.status1(phystatus_wires[1]); pcie.phy.status2(phystatus_wires[2]); pcie.phy.status3(phystatus_wires[3]); pcie.phy.status4(phystatus_wires[4]); pcie.phy.status5(phystatus_wires[5]); pcie.phy.status6(phystatus_wires[6]); pcie.phy.status7(phystatus_wires[7]); endrule rule capture_deviceid(pcie.tl.cfg_add == 4'hF); bus_number_reg <= pcie.tl.cfg_ctl[12:5]; dev_number_reg <= pcie.tl.cfg_ctl[4:0]; endrule method Clock coreclkout_hip; return pcie.coreclkout.hip; endmethod method Reset core_reset; return corerst; endmethod interface PcieTlCfg tl_cfg; method Bit#(8) bus_number(); return bus_number_reg; endmethod method Bit#(5) dev_number(); return dev_number_reg; endmethod method cpl_pending = pcie.cpl.pending; method cpl_err = pcie.cpl.err; endinterface interface PcieRxSt rx_st; method Bit#(1) sop(); return pcie.rx_st.sop0; endmethod method Bit#(1) eop(); return pcie.rx_st.eop0; endmethod method Bit#(128) data(); return pcie.rx_st.data0; endmethod method Bit#(1) valid(); return pcie.rx_st.valid0; endmethod method Bit#(1) err(); return pcie.rx_st.err0; endmethod method Bit#(2) empty(); return pcie.rx_st.empty0; endmethod method Bit#(8) bar (); return pcie.rx_st.bar0; endmethod method Bit#(16) be(); return pcie.rx_st.be0; endmethod method ready = pcie.rx_st.ready0; method mask = pcie.rx_st.mask0; endinterface interface PcieTxSt tx_st; method Bit#(1) ready (); return pcie.tx_st.ready0; endmethod method sop = pcie.tx_st.sop0 ; method eop = pcie.tx_st.eop0 ; method valid = pcie.tx_st.valid0 ; method err = pcie.tx_st.err0 ; method empty = pcie.tx_st.empty0 ; method data = pcie.tx_st.data0 ; endinterface interface PcieMsi msi; method Bit#(1) int_ack(); return pcie.app.int_ack; endmethod method Bit#(1) msi_ack(); return pcie.app.msi_ack; endmethod method int_sts = pcie.app.int_sts; method msi_num = pcie.app.msi_num; method msi_req = pcie.app.msi_req; method msi_tc = pcie.app.msi_tc; endinterface interface PcieHipRst hip_rst; method Bit#(1) serdes_pll_locked(); return pcie.serdes.pll_locked; endmethod method Bit#(1) pld_clk_inuse(); return pcie.pld.clk_inuse; endmethod method core_ready = pcie.pld.core_ready; endinterface interface PcieTxCred tx_cred; method Bit#(12) datafccp(); return pcie.tx_cred.datafccp; endmethod method Bit#(12) datafcnp(); return pcie.tx_cred.datafcnp; endmethod method Bit#(12) datafcp(); return pcie.tx_cred.datafcp; endmethod method Bit#(8) hdrfccp(); return pcie.tx_cred.hdrfccp; endmethod method Bit#(8) hdrfcnp(); return pcie.tx_cred.hdrfcnp; endmethod method Bit#(8) hdrfcp(); return pcie.tx_cred.hdrfcp; endmethod method Bit#(6) fchipcons(); return pcie.tx_cred.fchipcons; endmethod method Bit#(6) fcinfinite();return pcie.tx_cred.fcinfinite;endmethod endinterface interface PcieRxin rx; method Action in(Vector#(8, Bit#(1)) a); writeVReg(rx_in_wires, a); endmethod endinterface interface PcieTxout tx; method Vector#(8, Bit#(1)) out(); Vector#(8, Bit#(1)) ret_val; ret_val[0] = pcie.tx.out0; ret_val[1] = pcie.tx.out1; ret_val[2] = pcie.tx.out2; ret_val[3] = pcie.tx.out3; ret_val[4] = pcie.tx.out4; ret_val[5] = pcie.tx.out5; ret_val[6] = pcie.tx.out6; ret_val[7] = pcie.tx.out7; return ret_val; endmethod endinterface interface PcieHipStatus hip_status; method Bit#(1) cor_ext_rcv; return pcie.derr.cor_ext_rcv; endmethod method Bit#(1) cor_ext_rpl; return pcie.derr.cor_ext_rpl; endmethod method Bit#(1) rpl; return pcie.derr.rpl; endmethod method Bit#(1) dlup; return pcie.dl.up; endmethod method Bit#(1) dlup_exit; return pcie.dl.up_exit; endmethod method Bit#(1) ev128ns; return pcie.ev128.ns; endmethod method Bit#(1) ev1us; return pcie.ev1.us; endmethod method Bit#(1) hotrst; return pcie.hotrst.exit; endmethod method Bit#(4) int_status; return pcie.int_s.tatus; endmethod method Bit#(1) l2_exit; return pcie.l2.exit; endmethod method Bit#(4) lane_act; return pcie.lane.act; endmethod method Bit#(5) ltssmstate; return pcie.ltssm.state; endmethod method Bit#(1) rx_par_err; return pcie.rx_par.err; endmethod method Bit#(2) tx_par_err; return pcie.tx_par.err; endmethod method Bit#(1) cfg_par_err; return pcie.cfg_par.err; endmethod method Bit#(12) ko_cpl_spc_data; return pcie.ko.cpl_spc_data; endmethod method Bit#(8) ko_cpl_spc_header;return pcie.ko.cpl_spc_header;endmethod endinterface interface PcieHipPipe hip_pipe; method Action rxdata(Vector#(8, Bit#(8)) a); writeVReg(rxdata_wires, a); endmethod method Action rxdatak(Vector#(8, Bit#(1)) a); writeVReg(rxdatak_wires, a); endmethod method Action rxelecidle(Vector#(8, Bit#(1)) a); writeVReg(rxelecidle_wires, a); endmethod method Action rxstatus(Vector#(8, Bit#(3)) a); writeVReg(rxstatus_wires, a); endmethod method Action rxvalid(Vector#(8, Bit#(1)) a); writeVReg(rxvalid_wires, a); endmethod method Action phystatus(Vector#(8, Bit#(1)) a); writeVReg(phystatus_wires, a); endmethod method rxpolarity(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.rx.polarity7, pcie.rx.polarity6, pcie.rx.polarity5, pcie.rx.polarity4, pcie.rx.polarity3, pcie.rx.polarity2, pcie.rx.polarity1, pcie.rx.polarity0}); return retval; endmethod method txcompl(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.compl7, pcie.tx.compl6, pcie.tx.compl5, pcie.tx.compl4, pcie.tx.compl3, pcie.tx.compl2, pcie.tx.compl1, pcie.tx.compl0}); return retval; endmethod method txdata(); Vector#(8, Bit#(8)) retval; retval = unpack({pcie.tx.data7, pcie.tx.data6, pcie.tx.data5, pcie.tx.data4, pcie.tx.data3, pcie.tx.data2, pcie.tx.data1, pcie.tx.data0}); return retval; endmethod method txdatak(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.datak7, pcie.tx.datak6, pcie.tx.datak5, pcie.tx.datak4, pcie.tx.datak3, pcie.tx.datak2, pcie.tx.datak1, pcie.tx.datak0}); return retval; endmethod method txdeemph(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.deemph7, pcie.tx.deemph6, pcie.tx.deemph5, pcie.tx.deemph4, pcie.tx.deemph3, pcie.tx.deemph2, pcie.tx.deemph1, pcie.tx.deemph0}); return retval; endmethod method txdetectrx(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.detectrx7, pcie.tx.detectrx6, pcie.tx.detectrx5, pcie.tx.detectrx4, pcie.tx.detectrx3, pcie.tx.detectrx2, pcie.tx.detectrx1, pcie.tx.detectrx0}); return retval; endmethod method txelecidle(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.elecidle7, pcie.tx.elecidle6, pcie.tx.elecidle5, pcie.tx.elecidle4, pcie.tx.elecidle3, pcie.tx.elecidle2, pcie.tx.elecidle1, pcie.tx.elecidle0}); return retval; endmethod method txmargin(); Vector#(8, Bit#(3)) retval; retval = unpack({pcie.tx.margin7, pcie.tx.margin6, pcie.tx.margin5, pcie.tx.margin4, pcie.tx.margin3, pcie.tx.margin2, pcie.tx.margin1, pcie.tx.margin0}); return retval; endmethod method txswing(); Vector#(8, Bit#(1)) retval; retval = unpack({pcie.tx.swing7, pcie.tx.swing6, pcie.tx.swing5, pcie.tx.swing4, pcie.tx.swing3, pcie.tx.swing2, pcie.tx.swing1, pcie.tx.swing0}); return retval; endmethod method powerdown(); Vector#(8, Bit#(2)) retval; retval = unpack({pcie.power.down7, pcie.power.down6, pcie.power.down5, pcie.power.down4, pcie.power.down3, pcie.power.down2, pcie.power.down1, pcie.power.down0}); return retval; endmethod method eidleinfersel(); Vector#(8, Bit#(3)) retval; retval = unpack({pcie.eidle.infersel7, pcie.eidle.infersel6, pcie.eidle.infersel5, pcie.eidle.infersel4, pcie.eidle.infersel3, pcie.eidle.infersel2, pcie.eidle.infersel1, pcie.eidle.infersel0}); return retval; endmethod method sim_ltssmstate(); return pcie.sim.ltssmstate; endmethod method sim_pipe_rate(); return pcie.sim.pipe_rate; endmethod endinterface interface PcieHipCtrl hip_ctrl; method test_in = pcie.test.in; endinterface endmodule // Altera PCIe HIP Reset (* always_ready, always_enabled *) interface AlteraPcieHipRs; (* prefix="", result="dlup_exit" *) method Action dlup_exit(Bit#(1) dlup_exit); (* prefix="", result="hotrst_exit" *) method Action hotrst_exit(Bit#(1) hotrst_exit); (* prefix="", result="l2_exit" *) method Action l2_exit(Bit#(1) l2_exit); (* prefix="", result="ltssm" *) method Action ltssm(Bit#(5) ltssm); method Reset app_rstn; endinterface typedef enum { LTSSM_POL = 5'b00010, LTSSM_CPL = 5'b00011, LTSSM_DET = 5'b00000, LTSSM_RCV = 5'b01100, LTSSM_DIS = 5'b10000 } LTSSM deriving (Bits, Eq); typedef enum { RCV_TIMEOUT = 23'd6000000 } TIMEOUT deriving (Bits, Eq); typedef enum { RSTN_CNT_MAX = 11'h400, RSTN_CTN_MAX_SIM = 11'h20 } RSTN_CNT deriving (Bits, Eq); //(* synthesize, no_default_clock, no_default_reset, clock_prefix="", reset_prefix="" *) (* synthesize *) (* always_ready, always_enabled, no_default_clock, no_default_reset, clock_prefix="", reset_prefix="" *) module mkAlteraPcieHipRs#(Clock pld_clk, Reset npor)(AlteraPcieHipRs); Reset npor_sync_pld_clk <- mkAsyncReset(3, npor, pld_clk); Reg #(Bit#(5)) ltssm_r <- mkReg(0, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(1)) dlup_exit_r <- mkReg(1, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(1)) hotrst_exit_r <- mkReg(1, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(1)) l2_exit_r <- mkReg(1, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(11)) rsnt_cntn <- mkReg(0, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(23)) recovery_cnt <- mkReg(0, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(1)) recovery_rst <- mkReg(0, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); Reg #(Bit#(1)) exits_r <- mkReg(0, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); let app_rstn_out <- mkReset(0, True, pld_clk, clocked_by(pld_clk), reset_by(npor_sync_pld_clk)); rule exit_v ((l2_exit_r == 1'b0) || (hotrst_exit_r == 1'b0) || (dlup_exit_r == 1'b0) || (ltssm_r == pack(LTSSM_DIS)) || (recovery_rst == 1'b1)); exits_r <= 1'b1; endrule //Delay HIP reset upon npor rule delay_hip0 if (exits_r == 1'b1); rsnt_cntn <= 11'h3f0; endrule rule delay_hip1 if (exits_r != 1'b1); rsnt_cntn <= rsnt_cntn + 11'h1; endrule rule delay_hip2 if ((exits_r != 1'b1) && (rsnt_cntn == pack(RSTN_CNT_MAX))); app_rstn_out.assertReset; endrule // Monitor if LTSSM is frozen in RECOVERY state // Issue reset if timeout RCV_TIMEOUT rule recovery_cnt0 ((recovery_cnt != pack(RCV_TIMEOUT)) && (ltssm_r != pack(LTSSM_RCV))); recovery_cnt <= 23'b0; endrule rule recovery_cnt1 ((recovery_cnt == pack(RCV_TIMEOUT)) && (ltssm_r == pack(LTSSM_RCV))); recovery_cnt <= recovery_cnt; endrule rule recovery_cnt2 ((recovery_cnt != pack(RCV_TIMEOUT)) && (ltssm_r == pack(LTSSM_RCV))); recovery_cnt <= recovery_cnt + 23'h1; endrule rule recovery_rst0 (recovery_cnt == pack(RCV_TIMEOUT)); recovery_rst <= 1'b1; endrule rule recovery_rst1 (ltssm_r != pack(LTSSM_RCV) && recovery_cnt != pack(RCV_TIMEOUT)); recovery_rst <= 1'b0; endrule // interface method Action dlup_exit(Bit#(1) v); dlup_exit_r <= v; endmethod method Action ltssm(Bit#(5) v); ltssm_r <= v; endmethod method Action l2_exit(Bit#(1) v); l2_exit_r <= v; endmethod method Action hotrst_exit(Bit#(1) v); hotrst_exit_r <= v; endmethod method app_rstn; return app_rstn_out.new_rst; endmethod endmodule ================================================ FILE: bsv/PS7LIB.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import BuildVector::*; import Clocks::*; import DefaultValue::*; import GetPut::*; import Connectable::*; import ConnectableWithTrace::*; import Bscan::*; import Vector::*; import PPS7LIB::*; import AxiMasterSlave::*; import AxiDma::*; import XilinxCells::*; import ConnectalXilinxCells::*; import ConnectalClocks::*; import AxiBits::*; import AxiGather::*; (* always_ready, always_enabled *) interface Bidir#(numeric type data_width); method Action i(Bit#(data_width) v); method Bit#(data_width) o(); method Bit#(data_width) t(); endinterface interface PS7LIB; `ifdef PS7EXTENDED interface Vector#(2, Pps7Emiocan) can; interface Vector#(4, Pps7Dma) dma; interface Vector#(2, Pps7Emioenet) enet; interface Pps7Event event_; // interface Vector#(4,Pps7Fclk_clktrig)fclk_clktrig; // interface Pps7Fpga fpga; interface Pps7Ftmd ftmd; interface Pps7Ftmt ftmt; interface Pps7Emiopjtag pjtag; interface Vector#(2, Pps7Emiosdio) sdio; interface Vector#(2, Pps7Emiospi) spi; // interface Pps7Sram sram; interface Pps7Emiotrace trace; interface Vector#(2, Pps7Emiottc) ttc; interface Vector#(2, Pps7Emiouart) uart; interface Vector#(2, Pps7Emiousb) usb; interface Pps7Emiowdt wdt; `endif interface Pps7Ddr ddr; method Bit#(4) fclkclk(); method Action fclkclktrign(Bit#(4) v); method Bit#(4) fclkresetn(); method Action fpgaidlen(Bit#(1) v); interface Pps7Emiogpio gpio; interface Vector#(2, Pps7Emioi2c) i2c; interface Pps7Irq irq; interface Inout#(Bit#(54)) mio; interface Pps7Ps ps; interface Vector#(2, AxiMasterCommon#(32,32,12)) m_axi_gp; interface Vector#(2, AxiSlaveCommon#(32,32,6,Empty)) s_axi_gp; interface Vector#(4, AxiSlaveCommon#(32,64,6,HPType)) s_axi_hp; interface AxiSlaveCommon#(32,64,3,ACPType) s_axi_acp; endinterface module mkPS7LIB#(Clock axi_clock, Reset axi_reset)(PS7LIB); PPS7LIB foo <- mkPPS7LIB( axi_clock, axi_clock, axi_clock, axi_clock, axi_clock, axi_clock, axi_clock, axi_clock, axi_clock, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset); `ifdef PS7EXTENDED Vector#(2, Pps7Emiocan) vcan; Vector#(4, Pps7Dma) vdma; Vector#(2, Pps7Emioenet) venet; Vector#(2, Pps7Emiosdio) vsdio; Vector#(2, Pps7Emiospi) vspi; Vector#(2, Pps7Emiottc) vttc; Vector#(2, Pps7Emiouart) vuart; Vector#(2, Pps7Emiousb) vusb; `endif Vector#(2, Pps7Emioi2c) vi2c; Vector#(2, AxiMasterCommon#(32,32,12)) vtopm_axi_gp; Vector#(2, AxiSlaveCommon#(32,32,6,Empty)) vtops_axi_gp; Vector#(1, AxiSlaveCommon#(32,64,3,ACPType)) vtops_axi_acp; Vector#(4, AxiSlaveCommon#(32,64,6,HPType)) vtops_axi_hp; `ifdef PS7EXTENDED vcan[0] = foo.emiocan0; vcan[1] = foo.emiocan1; vdma[0] = foo.dma0; vdma[1] = foo.dma1; vdma[2] = foo.dma2; vdma[3] = foo.dma3; venet[0] = foo.emioenet0; venet[1] = foo.emioenet1; vsdio[0] = foo.emiosdio0; vsdio[1] = foo.emiosdio1; vspi[0] = foo.emiospi0; vspi[1] = foo.emiospi1; vttc[0] = foo.emiottc0; vttc[1] = foo.emiottc1; vuart[0] = foo.emiouart0; vuart[1] = foo.emiouart1; vusb[0] = foo.emiousb0; vusb[1] = foo.emiousb1; `endif vi2c[0] = foo.emioi2c0; vi2c[1] = foo.emioi2c1; vtopm_axi_gp[0] <- mkAxi3MasterGather(foo.maxigp0, clocked_by axi_clock, reset_by axi_reset); vtopm_axi_gp[1] <- mkAxi3MasterGather(foo.maxigp1, clocked_by axi_clock, reset_by axi_reset); vtops_axi_gp[0] <- mkAxi3SlaveGather(foo.saxigp0, clocked_by axi_clock, reset_by axi_reset); vtops_axi_gp[1] <- mkAxi3SlaveGather(foo.saxigp1, clocked_by axi_clock, reset_by axi_reset); vtops_axi_acp[0] <- mkAxi3SlaveGather(foo.saxiacp, clocked_by axi_clock, reset_by axi_reset); vtops_axi_hp[0] <- mkAxi3SlaveGather(foo.saxihp0, clocked_by axi_clock, reset_by axi_reset); vtops_axi_hp[1] <- mkAxi3SlaveGather(foo.saxihp1, clocked_by axi_clock, reset_by axi_reset); vtops_axi_hp[2] <- mkAxi3SlaveGather(foo.saxihp2, clocked_by axi_clock, reset_by axi_reset); vtops_axi_hp[3] <- mkAxi3SlaveGather(foo.saxihp3, clocked_by axi_clock, reset_by axi_reset); Wire#(Bit#(1)) fpgaidlenw <- mkDWire(1); rule fpgaidle; foo.fpgaidlen(fpgaidlenw); endrule rule misc; foo.emiosramintin(0); // UG585 "fclkclktrign is currently not supported and must be tied to ground" foo.fclkclktrign(0); endrule `ifdef PS7EXTENDED interface Pps7Can can = vcan; interface Pps7Dma dma = vdma; interface Pps7Enet enet = venet; interface Pps7Sdio sdio = vsdio; interface Pps7Spi spi = vspi; interface Pps7Ttc ttc = vttc; interface Pps7Uart uart = vuart; interface Pps7Usb usb = vusb; interface Pps7Event event_ = foo.event_; // interface Pps7Fpga fpga = foo.fpga; interface Pps7Ftmd ftmd = foo.ftmd; interface Pps7Ftmt ftmt = foo.ftmt; interface Pps7Pjtag pjtag = foo.emiopjtag; // interface Pps7Sram sram = foo.sram; interface Pps7Emiotrace trace = foo.emiotrace; interface Pps7Wdt wdt = foo.emiowdt; `endif interface i2c = vi2c; interface ddr = foo.ddr; interface fclkclk = foo.fclkclk; interface fclkresetn = foo.fclkresetn; method Action fclkclktrign(Bit#(4) v); foo.fclkclktrign(v); endmethod method Action fpgaidlen(Bit#(1) v); fpgaidlenw <= v; endmethod interface gpio = foo.emiogpio; interface irq = foo.irq; interface mio = foo.mio; interface ps = foo.ps; interface m_axi_gp = vtopm_axi_gp; interface s_axi_gp = vtops_axi_gp; interface s_axi_hp = vtops_axi_hp; interface s_axi_acp = vtops_axi_acp[0]; endmodule interface ZynqPins; (* prefix="DDR_Addr" *) interface Inout#(Bit#(15)) a; (* prefix="DDR_BankAddr" *) interface Inout#(Bit#(3)) ba; (* prefix="DDR_CAS_n" *) interface Inout#(Bit#(1)) casb; (* prefix="DDR_CKE" *) interface Inout#(Bit#(1)) cke; (* prefix="DDR_CS_n" *) interface Inout#(Bit#(1)) csb; (* prefix="DDR_Clk_n" *) interface Inout#(Bit#(1)) ckn; (* prefix="DDR_Clk_p" *) interface Inout#(Bit#(1)) ck; (* prefix="DDR_DM" *) interface Inout#(Bit#(4)) dm; (* prefix="DDR_DQ" *) interface Inout#(Bit#(32)) dq; (* prefix="DDR_DQS_n" *) interface Inout#(Bit#(4)) dqsn; (* prefix="DDR_DQS_p" *) interface Inout#(Bit#(4)) dqs; (* prefix="DDR_DRSTB" *) interface Inout#(Bit#(1)) drstb; (* prefix="DDR_ODT" *) interface Inout#(Bit#(1)) odt; (* prefix="DDR_RAS_n" *) interface Inout#(Bit#(1)) rasb; (* prefix="FIXED_IO_ddr_vrn" *) interface Inout#(Bit#(1)) vrn; (* prefix="FIXED_IO_ddr_vrp" *) interface Inout#(Bit#(1)) vrp; (* prefix="DDR_WEB" *) interface Inout#(Bit#(1)) web; (* prefix="MIO" *) interface Inout#(Bit#(54)) mio; (* prefix="FIXED_IO_ps" *) interface Pps7Ps ps; endinterface interface PS7; (* prefix="" *) interface ZynqPins pins; interface Vector#(2, AxiMasterCommon#(32,32,12)) m_axi_gp; interface Vector#(2, AxiSlaveCommon#(32,32,6,Empty)) s_axi_gp; interface Vector#(4, AxiSlaveCommon#(32,64,6,HPType)) s_axi_hp; interface Vector#(1, AxiSlaveCommon#(32,64,3,ACPType)) s_axi_acp; method Action interrupt(Bit#(1) v); interface Vector#(4, Clock) fclkclk; interface Vector#(4, Reset) fclkreset; interface Vector#(2, Pps7Emioi2c) i2c; interface Clock portalClock; interface Reset portalReset; interface Clock derivedClock; interface Reset derivedReset; `ifdef PS7EXTENDED interface Pps7Emiosdio emiosdio1; interface Pps7Emiospi emiospi0; `endif endinterface module mkPS7#(Clock axiClock)(PS7); // B2C converts a bit to a clock, enabling us to break the apparent cycle Vector#(4, B2C) b2c <- replicateM(mkB2C()); // need the bufg here to reduce clock skew module mkBufferedClock#(Integer i)(Clock); let c <- mkClockBUFG(clocked_by b2c[i].c); return c; endmodule module mkBufferedReset#(Integer i)(Reset); let r <- mkResetBUFG(clocked_by b2c[i].c, reset_by b2c[i].r); return r; endmodule Vector#(4, Clock) fclk <- genWithM(mkBufferedClock); Vector#(4, Reset) freset <- genWithM(mkBufferedReset); `ifndef TOP_SOURCES_PORTAL_CLOCK Clock single_clock = fclk[0]; `ifdef ZYNQ_NO_RESET freset[0] = noReset; `endif let single_reset = freset[0]; `else //Clock axiClockBuf <- mkClockBUFG(clocked_by axiClock); Clock axiClockBuf = axiClock; Clock single_clock = axiClockBuf; Reset axiResetUnbuffered <- mkSyncReset(10, freset[0], single_clock); Reset axiReset <- mkResetBUFG(clocked_by axiClockBuf, reset_by axiResetUnbuffered); let single_reset = axiReset; `endif ClockGenerator7Params clockParams = defaultValue; // input clock 200MHz for speed grade -2, 100MHz for speed grade -1 // fpll needs to be in the range 600MHz - 1200MHz for either input clock // // fclkin = 1e9 / mainClockPeriod // fpll = 1e9 = mult_f * 1e9 / mainClockPeriod // mult_f = mainClockPeriod // // fclkout0 = 1e9 / divide_f = 1e9 / derivedClockPeriod // divide_f = derivedClockPeriod // clockParams.clkfbout_mult_f = mainClockPeriod; clockParams.clkfbout_phase = 0.0; clockParams.clkfbout_phase = 0.0; clockParams.clkin1_period = mainClockPeriod; clockParams.clkout0_divide_f = derivedClockPeriod; clockParams.clkout0_duty_cycle = 0.5; clockParams.clkout0_phase = 0.0000; clockParams.clkout0_buffer = True; clockParams.clkin_buffer = False; ClockGenerator7 clockGen <- mkClockGenerator7(clockParams, clocked_by single_clock, reset_by single_reset); let derived_clock = clockGen.clkout0; let derived_reset_unbuffered <- mkSyncReset(10, single_reset, derived_clock); let derived_reset <- mkResetBUFG(clocked_by derived_clock, reset_by derived_reset_unbuffered); PS7LIB ps7 <- mkPS7LIB(single_clock, single_reset, clocked_by single_clock, reset_by single_reset); // this rule connects the fclkclk wires to the clock net via B2C for (Integer i = 0; i < 4; i = i + 1) begin ReadOnly#(Bit#(4)) fclkb; ReadOnly#(Bit#(4)) fclkresetnb; fclkb <- mkNullCrossingWire(b2c[i].c, ps7.fclkclk); fclkresetnb <- mkNullCrossingWire(b2c[i].c, ps7.fclkresetn); `ifndef BSV_POSITIVE_RESET let resetValue = 0; `else let resetValue = 1; `endif rule b2c_rule1; b2c[i].inputclock(fclkb[i]); b2c[i].inputreset(fclkresetnb[i] == 0 ? resetValue : ~resetValue); endrule rule issue_rule; ps7.s_axi_hp[i].extra.rdissuecap1en(0); ps7.s_axi_hp[i].extra.wrissuecap1en(0); endrule end IDELAYCTRL idel <- mkIDELAYCTRL(2, clocked_by fclk[3], reset_by freset[0]); rule arb_rule; ps7.ddr.arb(4'b0); endrule `ifdef PS7EXTENDED interface Pps7Emiosdio emiosdio1 = ps7.sdio[1]; interface Pps7Emiospi emiospi0 = ps7.spi[0]; `endif interface ZynqPins pins; interface a = ps7.ddr.a; interface ba = ps7.ddr.ba; interface casb = ps7.ddr.casb; interface cke = ps7.ddr.cke; interface csb = ps7.ddr.csb; interface ckn = ps7.ddr.ckn; interface ck = ps7.ddr.ckp; interface dm = ps7.ddr.dm; interface dq = ps7.ddr.dq; interface dqsn = ps7.ddr.dqsn; interface dqs = ps7.ddr.dqsp; interface drstb = ps7.ddr.drstb; interface odt = ps7.ddr.odt; interface rasb = ps7.ddr.rasb; interface vrn = ps7.ddr.vrn; interface vrp = ps7.ddr.vrp; interface web = ps7.ddr.web; interface mio = ps7.mio; interface ps = ps7.ps; endinterface interface m_axi_gp = ps7.m_axi_gp; interface s_axi_gp = ps7.s_axi_gp; interface s_axi_hp = ps7.s_axi_hp; interface fclkclk = fclk; interface fclkreset = freset; `ifndef TOP_SOURCES_PORTAL_CLOCK interface portalClock = fclk[0]; interface portalReset = freset[0]; `else interface portalClock = axiClockBuf; interface portalReset = axiReset; `endif interface derivedClock = derived_clock; interface derivedReset = derived_reset; method Action interrupt(Bit#(1) v); ps7.irq.f2p({19'b0, v}); endmethod interface i2c = ps7.i2c; interface s_axi_acp = vec(ps7.s_axi_acp); endmodule ================================================ FILE: bsv/PS7Trace.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import Connectable::*; import ConnectableWithTrace::*; import Vector::*; import HostInterface::*; import PS7LIB::*; import Portal::*; import AxiMasterSlave::*; import AxiDma::*; import AxiBits::*; import AxiGather::*; import Platform::*; `include "ConnectalProjectConfig.bsv" `ifdef USE_ACP typedef 1 NumAcp; `else typedef 0 NumAcp; `endif instance ConnectableWithTrace#(PS7, Platform, traceType) provisos (ConnectableWithTrace::ConnectableWithTrace#(AxiMasterSlave::Axi3Master#(32,64,6),AxiMasterSlave::Axi3Slave#(32, 64, 6),traceType), ConnectableWithTrace::ConnectableWithTrace#(AxiMasterSlave::Axi3Master#(32,32,12),AxiMasterSlave::Axi3Slave#(32,32,12),traceType)); module mkConnectionWithTrace#(PS7 ps7, Platform top, traceType readout)(Empty) provisos (ConnectableWithTrace#(Axi3Master#(32,64,6), Axi3Slave#(32,64,6),traceType)); Axi3Slave#(32,32,12) ctrl <- mkAxiDmaSlave(top.slave); mkConnectionWithTrace(ps7.m_axi_gp[0].client, ctrl, readout); `ifdef USE_ACP begin Axi3Master#(32,64,3) acp_m_axi <- mkAxiDmaMaster(top.masters[0]); mkConnection(acp_m_axi, ps7.s_axi_acp[0].server); end rule acp_aruser; ps7.s_axi_acp[0].extra.aruser(5'h1f); endrule rule acp_awuser; ps7.s_axi_acp[0].extra.awuser(5'h1f); endrule `endif module mkAxiMasterConnection#(Integer i)(Axi3Master#(32,64,6)); let m_axi <- mkAxiDmaMaster(top.masters[i+valueOf(NumAcp)]); mkConnection(m_axi, ps7.s_axi_hp[i].server); return m_axi; endmodule Vector#(TSub#(NumberOfMasters,NumAcp), Axi3Master#(32,64,6)) m_axis <- genWithM(mkAxiMasterConnection); endmodule endinstance ================================================ FILE: bsv/PS8LIB.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import ConnectalConfig::*; import BuildVector::*; import Clocks::*; import DefaultValue::*; import FIFOF::*; import GetPut::*; import Connectable::*; import ConnectableWithTrace::*; import Bscan::*; import Vector::*; import XilinxCells::*; import ConnectalXilinxCells::*; import ConnectalClocks::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import AxiDma::*; import AxiBits::*; import ConnectalMemTypes::*; import Platform::*; import ZYNQ_ULTRA::*; import Probe::*; (* always_ready, always_enabled *) interface Bidir#(numeric type data_width); method Action i(Bit#(data_width) v); method Bit#(data_width) o(); method Bit#(data_width) t(); endinterface interface ZynqPins; endinterface interface PS8LIB; (* prefix="" *) interface Vector#(1, Ps8Maxigp) m_axi_gp; interface Vector#(7, Ps8Saxigp) s_axi_gp; interface Vector#(1, Ps8Saxiacp) s_axi_acp; method Action interrupt(Bit#(1) v); interface Vector#(4, Clock) plclk; interface Clock portalClock; interface Reset portalReset; interface Clock derivedClock; interface Reset derivedReset; endinterface module mkPS8LIB#(Clock axiClock)(PS8LIB); // B2C converts a bit to a clock, enabling us to break the apparent cycle Vector#(4, B2C) b2c <- replicateM(mkB2C()); // need the bufg here to reduce clock skew module mkBufferedClock#(Integer i)(Clock); let c <- mkClockBUFG(clocked_by b2c[i].c); return c; endmodule module mkBufferedReset#(Integer i)(Reset); let r <- mkResetBUFG(clocked_by b2c[i].c, reset_by b2c[i].r); return r; endmodule Vector#(4, Clock) fclk <- genWithM(mkBufferedClock); Vector#(4, Reset) freset <- genWithM(mkBufferedReset); `ifndef TOP_SOURCES_PORTAL_CLOCK Clock single_clock = fclk[0]; `ifdef ZYNQ_NO_RESET freset[0] = noReset; `endif let single_reset = freset[0]; `else //Clock axiClockBuf <- mkClockBUFG(clocked_by axiClock); Clock axiClockBuf = axiClock; Clock single_clock = axiClockBuf; Reset axiResetUnbuffered <- mkSyncReset(10, freset[0], single_clock); Reset axiReset <- mkResetBUFG(clocked_by axiClockBuf, reset_by axiResetUnbuffered); let single_reset = axiReset; `endif ClockGenerator7Params clockParams = defaultValue; // input clock 200MHz for speed grade -2, 100MHz for speed grade -1 // fpll needs to be in the range 600MHz - 1200MHz for either input clock // // fclkin = 1e9 / mainClockPeriod // fpll = 1e9 = mult_f * 1e9 / mainClockPeriod // mult_f = mainClockPeriod // // fclkout0 = 1e9 / divide_f = 1e9 / derivedClockPeriod // divide_f = derivedClockPeriod // clockParams.clkfbout_mult_f = mainClockPeriod; clockParams.clkfbout_phase = 0.0; clockParams.clkfbout_phase = 0.0; clockParams.clkin1_period = mainClockPeriod; clockParams.clkout0_divide_f = derivedClockPeriod; clockParams.clkout0_duty_cycle = 0.5; clockParams.clkout0_phase = 0.0000; clockParams.clkout0_buffer = True; clockParams.clkin_buffer = False; ClockGenerator7 clockGen <- mkClockGenerator7(clockParams, clocked_by single_clock, reset_by single_reset); let derived_clock = clockGen.clkout0; let derived_reset_unbuffered <- mkSyncReset(10, single_reset, derived_clock); let derived_reset <- mkResetBUFG(clocked_by derived_clock, reset_by derived_reset_unbuffered); // FIXME: enable multiple clock domains ZYNQ_ULTRA::PS8 psu <- ZYNQ_ULTRA::mkPS8(single_clock, single_clock, single_clock, single_clock, single_clock, single_clock, single_clock, single_clock, single_clock, single_clock, single_clock); // this rule connects the pl_clk wires to the clock net via B2C for (Integer i = 0; i < 1; i = i + 1) begin ReadOnly#(Bit#(1)) fclkb; ReadOnly#(Bit#(1)) fclkresetnb; fclkb <- mkNullCrossingWire(b2c[i].c, psu.pl.clk0); fclkresetnb <- mkNullCrossingWire(b2c[i].c, psu.pl.resetn0); `ifndef BSV_POSITIVE_RESET let resetValue = 0; `else let resetValue = 1; `endif rule b2c_rule1; b2c[i].inputclock(fclkb[i]); b2c[i].inputreset(fclkresetnb[i] == 0 ? resetValue : ~resetValue); endrule end interface m_axi_gp = vec(psu.maxigp0); interface s_axi_gp = vec(psu.saxigp0, psu.saxigp1, psu.saxigp2, psu.saxigp3, psu.saxigp4, psu.saxigp5, psu.saxigp6); interface s_axi_acp = vec(psu.saxiacp); interface plclk = fclk; `ifndef TOP_SOURCES_PORTAL_CLOCK interface portalClock = fclk[0]; interface portalReset = freset[0]; `else interface portalClock = axiClockBuf; interface portalReset = axiReset; `endif interface derivedClock = derived_clock; interface derivedReset = derived_reset; method Action interrupt(Bit#(1) v); psu.pl.ps_irq0(v); endmethod endmodule interface Ps8MaxigpExtra; method Bit#(16) aruser(); method Bit#(16) awuser(); endinterface interface Ps8SaxigpExtra; method Action aruser(Bit#(1) v); method Action awuser(Bit#(1) v); endinterface interface Ps8SaxiacpExtra; method Action aruser(Bit#(2) v); method Action awuser(Bit#(2) v); endinterface instance ToAxi4MasterBits#(Axi4MasterBits#(40,128,16,Ps8MaxigpExtra), Ps8Maxigp); function Axi4MasterBits#(40,128,16,Ps8MaxigpExtra) toAxi4MasterBits(Ps8Maxigp m); return (interface Axi4MasterBits#(40,128,16,Ps8MaxigpExtra); method araddr = m.araddr; method arburst = m.arburst; method arcache = m.arcache; method aresetn = 1; method arid = m.arid; method arlen = m.arlen; method arlock = extend(m.arlock); method arprot = m.arprot; method arqos = m.arqos; method arready = m.arready; method arsize = m.arsize; method arvalid = m.arvalid; method awaddr = m.awaddr; method awburst = m.awburst; method awcache = m.awcache; method awid = m.awid; method awlen = m.awlen; method awlock = extend(m.awlock); method awprot = m.awprot; method awqos = m.awqos; method awready = m.awready; method awsize = m.awsize; method awvalid = m.awvalid; method bid = m.bid; method bready = m.bready; method bresp = m.bresp; method bvalid = m.bvalid; method rdata = m.rdata; method rid = m.rid; method rlast = m.rlast; method rready = m.rready; method rresp = m.rresp; method rvalid = m.rvalid; method wdata = m.wdata; //method wid = m.wid; method wlast = m.wlast; method wready = m.wready; method wstrb = m.wstrb; method wvalid = m.wvalid; interface extra = ?; endinterface); endfunction: toAxi4MasterBits endinstance instance ToAxi4SlaveBits#(Axi4SlaveBits#(49,128,6,Ps8SaxigpExtra), Ps8Saxigp); function Axi4SlaveBits#(49,128,6,Ps8SaxigpExtra) toAxi4SlaveBits(Ps8Saxigp s); return (interface Axi4SlaveBits#(49,128,6,Ps8SaxigpExtra); method araddr = s.araddr; method arburst = s.arburst; method arcache = s.arcache; //method aresetn = 1; //no aresetn port in zcu method arid = s.arid; method arlen = s.arlen; method arlock = compose(s.arlock, truncate); method arprot = s.arprot; method arqos = s.arqos; method arready = s.arready; method arsize = s.arsize; method arvalid = s.arvalid; method awaddr = s.awaddr; method awburst = s.awburst; method awcache = s.awcache; method awid = s.awid; method awlen = s.awlen; method awlock = compose(s.awlock, truncate); method awprot = s.awprot; method awqos = s.awqos; method awready = s.awready; method awsize = s.awsize; method awvalid = s.awvalid; method bid = s.bid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rid = s.rid; method rlast = s.rlast; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; //method wid = s.wid; //wid not present in Axi4 method wlast = s.wlast; method wready = s.wready; method wvalid = s.wvalid; method wstrb = s.wstrb; interface Ps8SaxigpExtra extra; method aruser = s.aruser; method awuser = s.awuser; endinterface endinterface); endfunction endinstance instance ToAxi4SlaveBits#(Axi4SlaveBits#(40,128,5,Ps8SaxiacpExtra), Ps8Saxiacp); function Axi4SlaveBits#(40,128,5,Ps8SaxiacpExtra) toAxi4SlaveBits(Ps8Saxiacp s); return (interface Axi4SlaveBits#(40,128,5,Ps8SaxiacpExtra); method araddr = s.araddr; method arburst = s.arburst; method arcache = s.arcache; //method aresetn = 1; //no aresetn port in zcu method arid = s.arid; method arlen = s.arlen; method arlock = compose(s.arlock, truncate); method arprot = s.arprot; method arqos = s.arqos; method arready = s.arready; method arsize = s.arsize; method arvalid = s.arvalid; method awaddr = s.awaddr; method awburst = s.awburst; method awcache = s.awcache; method awid = s.awid; method awlen = s.awlen; method awlock = compose(s.awlock, truncate); method awprot = s.awprot; method awqos = s.awqos; method awready = s.awready; method awsize = s.awsize; method awvalid = s.awvalid; method bid = s.bid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rid = s.rid; method rlast = s.rlast; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; //method wid = s.wid; //wid not present in Axi4 method wlast = s.wlast; method wready = s.wready; method wvalid = s.wvalid; method wstrb = s.wstrb; interface Ps8SaxiacpExtra extra; method aruser = s.aruser; method awuser = s.awuser; endinterface endinterface); endfunction endinstance instance PhysMemSlaveExtra#(Empty); function Action extra_r(Empty ex); action endaction endfunction function Action extra_w(Empty ex); action endaction endfunction endinstance instance PhysMemSlaveExtra#(Ps8SaxigpExtra); function Action extra_r(Ps8SaxigpExtra ex); action ex.aruser(1'b0); endaction endfunction function Action extra_w(Ps8SaxigpExtra ex); action ex.awuser(1'b0); endaction endfunction endinstance instance PhysMemSlaveExtra#(Ps8SaxiacpExtra); function Action extra_r(Ps8SaxiacpExtra ex); action // inner shareable ex.aruser(2'b01); endaction endfunction function Action extra_w(Ps8SaxiacpExtra ex); action // inner shareable ex.awuser(2'b01); endaction endfunction endinstance instance ConnectableWithTrace#(PS8LIB, Platform, traceType); module mkConnectionWithTrace#(PS8LIB psu, Platform top, traceType readout)(Empty); Axi4MasterBits#(40,128,16,Ps8MaxigpExtra) master = toAxi4MasterBits(psu.m_axi_gp[0]); PhysMemMaster#(32,32) physMemMaster <- mkPhysMemMaster(master); mkConnection(physMemMaster, top.slave); `ifdef USE_ACP Axi4SlaveBits#(40,128,5,Ps8SaxiacpExtra) slave = toAxi4SlaveBits(psu.s_axi_acp[0]); PhysMemSlave#(40,DataBusWidth) physMemSlaveAcp <- mkPhysMemSlave(slave); `endif // USE_ACP Vector#(7, Axi4SlaveBits#(49,128,6,Ps8SaxigpExtra)) slaves = map(toAxi4SlaveBits, psu.s_axi_gp); Vector#(7, PhysMemSlave#(40,DataBusWidth)) physMemSlaves <- mapM(mkPhysMemSlave, slaves); `ifdef USE_ACP physMemSlaves[0] = physMemSlaveAcp; `endif // makes NumberOfMasters connections zipWithM(mkConnection, top.masters, take(physMemSlaves)); endmodule endinstance ================================================ FILE: bsv/ParallellaTop.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Initially, this is a copy of ZynqTop // The plan for changes: // Use ps7.s_axi_hp[3] to connect to the Parallella verilog dma master // restrict the Connectal stuff to 3 masters, so that [3] will be free // Use psy.m_axi_gp[1] to connect to the Parallella verilog axi slave // verify this leave the addressing unchanged, or make matching changes // the address ranges for the two _gp ports are explained in the // zynq TRM. You also have to set these to match in the device tree // The device drivers use the values in the DTB, but confirm this // Since both parallella and connectal use gp[0] to start, one has to change // but if this is done right the software shouldn't have to change // Establish pin connections for the ELink to the epiphany chip // Establish pin connections for the GPIO // establish I2C 0 connections // make clock connections (see parallella_z7_top.v // tie off HDMI signals import Clocks :: *; import Vector :: *; import Connectable :: *; import ConnectableWithTrace::*; import Portal :: *; import ConnectalMemTypes :: *; import AxiMasterSlave :: *; import XilinxCells :: *; import ConnectalXilinxCells :: *; import PS7LIB::*; import PS7Trace::*; import PPS7LIB::*; import CtrlMux::*; import AxiDma :: *; import Top :: *; import Bscan :: *; import HostInterface::*; `include "ConnectalProjectConfig.bsv" import `PinTypeInclude::*; interface I2C_Pins; interface Inout#(Bit#(1)) scl; interface Inout#(Bit#(1)) sda; endinterface (* always_ready, always_enabled *) interface ZynqTop; (* prefix="" *) interface ZynqPins zynq; `ifdef USE_I2C0 (* prefix="I2C0" *) interface I2C_Pins i2c0; `endif `ifdef USE_I2C1 (* prefix="I2C1" *) interface I2C_Pins i2c1; `endif (* prefix="" *) interface `PinType pins; interface Vector#(4, Clock) deleteme_unused_clock; interface Vector#(4, Reset) deleteme_unused_reset; endinterface module mkZynqTop(ZynqTop); PS7 ps7 <- mkPS7(); Clock mainclock = ps7.fclkclk[0]; Reset mainreset = ps7.fclkreset[0]; `ifdef USE_I2C0 let tscl0 <- mkIOBUF(~ps7.i2c[0].scltn, ps7.i2c[0].sclo, clocked_by mainclock, reset_by mainreset); let tsda0 <- mkIOBUF(~ps7.i2c[0].sdatn, ps7.i2c[0].sdao, clocked_by mainclock, reset_by mainreset); rule sdai0; ps7.i2c[0].sdai(tsda0.o); ps7.i2c[0].scli(tscl0.o); endrule `endif `ifdef USE_I2C1 let tscl1 <- mkIOBUF(~ps7.i2c[1].scltn, ps7.i2c[1].sclo, clocked_by mainclock, reset_by mainreset); let tsda1 <- mkIOBUF(~ps7.i2c[1].sdatn, ps7.i2c[1].sdao, clocked_by mainclock, reset_by mainreset); rule sdai1; ps7.i2c[1].sdai(tsda1.o); ps7.i2c[1].scli(tscl1.o); endrule `endif BscanTop bscan <- mkBscanTop(3, clocked_by mainclock, reset_by mainreset); // Use USER3 (JTAG IDCODE address 0x22) BscanLocal lbscan <- mkBscanLocal(bscan, clocked_by bscan.tck, reset_by bscan.rst); `ifdef IMPORT_HOSTIF let top <- mkConnectalTop( (interface HostInterface; interface ps7 = ps7; interface portalClock = mainclock; interface portalReset = mainreset; interface derivedClock = ps7.derivedClock; interface derivedReset = ps7.derivedReset; interface bscan = lbscan.loc[0]; endinterface), clocked_by mainclock, reset_by mainreset); `else let top <- mkConnectalTop(clocked_by mainclock, reset_by mainreset); `endif mkConnectionWithTrace(ps7, top, lbscan.loc[1], clocked_by mainclock, reset_by mainreset); let intr_mux <- mkInterruptMux(top.interrupt); rule send_int_rule; ps7.interrupt(pack(intr_mux)); endrule module bufferClock#(Integer i)(Clock); let bc <- mkClockBUFG(clocked_by ps7.fclkclk[i]); return bc; endmodule module bufferReset#(Integer i)(Reset); let rc <- mkSyncReset(5, ps7.fclkreset[i], ps7.fclkclk[0]); return rc; endmodule Vector#(4, Clock) unused_clock <- genWithM(bufferClock); Vector#(4, Reset) unused_reset <- genWithM(bufferReset); interface zynq = ps7.pins; `ifdef USE_I2C0 interface I2C_Pins i2c0; interface Inout scl = tscl0.io; interface Inout sda = tsda0.io; endinterface `endif `ifdef USE_I2C1 interface I2C_Pins i2c1; interface Inout scl = tscl1.io; interface Inout sda = tsda1.io; endinterface `endif interface pins = top.pins; interface deleteme_unused_clock = unused_clock; interface deleteme_unused_reset = unused_reset; endmodule ================================================ FILE: bsv/Pcie1EndpointX7.bsv ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2012 Bluespec, Inc. ALL RIGHTS RESERVED. //////////////////////////////////////////////////////////////////////////////// // Filename : ConnectalXilinx7PCIE.bsv // Description : //////////////////////////////////////////////////////////////////////////////// import ConnectalConfig ::*; import Clocks ::*; import Vector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import SpecialFIFOs ::*; import ClientServer ::*; import Real ::*; import ConnectalClocks ::*; import ConnectalXilinxCells ::*; import XilinxCells ::*; import PCIE ::*; import PCIEWRAPPER ::*; import Bufgctrl ::*; import PcieGearbox :: *; import PcieStateChanges ::*; import Pipe :: *; `include "ConnectalProjectConfig.bsv" (* always_ready, always_enabled *) interface PCIE_X7#(numeric type lanes); interface PciewrapPci_exp#(lanes) pcie; interface PciewrapUser#(lanes) user; interface PciewrapFc#(lanes) fc; interface PciewrapTx#(lanes) tx; interface PciewrapS_axis_tx#(lanes) s_axis_tx; interface PciewrapM_axis_rx#(lanes) m_axis_rx; interface PciewrapRx#(lanes) rx; interface PciewrapCfg#(lanes) cfg; method Action cfg_dsn(Bit#(64) i); interface Clock pipe_txoutclk_out; method Action pipe_mmcm_lock_in(Bit#(1) v); method Bit#(lanes) pipe_pclk_sel_out(); endinterface import "BVI" pcie_7x_0 = module vMkXilinx7PCIExpress#(PCIEParams params, Clock clk_125mhz, Clock pipe_userclk1_in, Clock pclk_in)(PCIE_X7#(lanes)) provisos( Add#(1, z, lanes)); let sys_rst_n <- exposeCurrentReset; default_clock clk(sys_clk); // 100 MHz refclk default_reset rstn(sys_rst_n) = sys_rst_n; input_clock clk_125mhz(pipe_dclk_in) = clk_125mhz; input_clock clk_oobclk_in(pipe_oobclk_in) = clk_125mhz; input_clock pipe_userclk1_in(pipe_userclk1_in) = pipe_userclk1_in; input_clock pipe_userclk2_in(pipe_userclk2_in) = pipe_userclk1_in; input_clock pclk_in(pipe_pclk_in) = pclk_in; input_clock pclk_usrin(pipe_rxusrclk_in) = pclk_in; method pipe_mmcm_lock_in(pipe_mmcm_lock_in) enable((*inhigh*)en_pipe_mmcm_lock_in); method pipe_pclk_sel_out pipe_pclk_sel_out clocked_by(pclk_in); interface PciewrapPci_exp pcie; method rxp(pci_exp_rxp) enable((*inhigh*)en0) reset_by(no_reset); method rxn(pci_exp_rxn) enable((*inhigh*)en1) reset_by(no_reset); method pci_exp_txp txp reset_by(no_reset); method pci_exp_txn txn reset_by(no_reset); endinterface interface PciewrapUser user; output_clock clk_out(user_clk_out); output_reset reset_out(user_reset_out); method user_lnk_up lnk_up clocked_by(no_clock) reset_by(no_reset); /* semi-static */ method user_app_rdy app_rdy clocked_by(no_clock) reset_by(no_reset); endinterface interface PciewrapFc fc; method fc_ph ph clocked_by(user_clk_out) reset_by(no_reset); method fc_pd pd clocked_by(user_clk_out) reset_by(no_reset); method fc_nph nph clocked_by(user_clk_out) reset_by(no_reset); method fc_npd npd clocked_by(user_clk_out) reset_by(no_reset); method fc_cplh cplh clocked_by(user_clk_out) reset_by(no_reset); method fc_cpld cpld clocked_by(user_clk_out) reset_by(no_reset); method sel(fc_sel) enable((*inhigh*)en01) clocked_by(user_clk_out) reset_by(no_reset); endinterface interface PciewrapTx tx; method tx_buf_av buf_av clocked_by(user_clk_out) reset_by(no_reset); method tx_err_drop err_drop clocked_by(user_clk_out) reset_by(no_reset); method tx_cfg_req cfg_req clocked_by(user_clk_out) reset_by(no_reset); method cfg_gnt(tx_cfg_gnt) enable((*inhigh*)en07) clocked_by(user_clk_out) reset_by(no_reset); endinterface interface PciewrapS_axis_tx s_axis_tx; method tlast(s_axis_tx_tlast) enable((*inhigh*)en02) clocked_by(user_clk_out) reset_by(no_reset); method tdata(s_axis_tx_tdata) enable((*inhigh*)en03) clocked_by(user_clk_out) reset_by(no_reset); method tkeep(s_axis_tx_tkeep) enable((*inhigh*)en04) clocked_by(user_clk_out) reset_by(no_reset); method tvalid(s_axis_tx_tvalid) enable((*inhigh*)en05) clocked_by(user_clk_out) reset_by(no_reset); method tuser(s_axis_tx_tuser) enable((*inhigh*)en06) clocked_by(user_clk_out) reset_by(no_reset); method s_axis_tx_tready tready clocked_by(user_clk_out) reset_by(no_reset); endinterface interface PciewrapM_axis_rx m_axis_rx; method m_axis_rx_tlast tlast clocked_by(user_clk_out) reset_by(no_reset); method m_axis_rx_tdata tdata clocked_by(user_clk_out) reset_by(no_reset); method m_axis_rx_tkeep tkeep clocked_by(user_clk_out) reset_by(no_reset); method m_axis_rx_tuser tuser clocked_by(user_clk_out) reset_by(no_reset); method m_axis_rx_tvalid tvalid clocked_by(user_clk_out) reset_by(no_reset); method tready(m_axis_rx_tready) enable((*inhigh*)en08) clocked_by(user_clk_out) reset_by(no_reset); endinterface interface PciewrapRx rx; method np_ok(rx_np_ok) enable((*inhigh*)en09) clocked_by(user_clk_out) reset_by(no_reset); method np_req(rx_np_req) enable((*inhigh*)en10) clocked_by(user_clk_out) reset_by(no_reset); endinterface method cfg_dsn(cfg_dsn) enable((*inhigh*)en25) clocked_by(user_clk_out); interface PciewrapCfg cfg; method cfg_bus_number bus_number clocked_by(no_clock) reset_by(no_reset); method cfg_device_number device_number clocked_by(no_clock) reset_by(no_reset); method cfg_function_number function_number clocked_by(no_clock) reset_by(no_reset); method cfg_lcommand lcommand clocked_by(user_clk_out) reset_by(no_reset); method interrupt(cfg_interrupt) enable((*inhigh*)en32) clocked_by(user_clk_out) reset_by(no_reset); method cfg_bridge_serr_en bridge_serr_en(); method cfg_command command(); method cfg_dcommand dcommand(); method cfg_dcommand2 dcommand2(); method cfg_lstatus lstatus(); method cfg_pcie_link_state pcie_link_state(); method pciecap_interrupt_msgnum(cfg_pciecap_interrupt_msgnum) enable((*inhigh*) EN_cfg_pciecap_interrupt_msgnum); method cfg_received_func_lvl_rst received_func_lvl_rst(); method cfg_slot_control_electromech_il_ctl_pulse slot_control_electromech_il_ctl_pulse(); method cfg_status status(); method cfg_to_turnoff to_turnoff(); method trn_pending(cfg_trn_pending) enable((*inhigh*) EN_cfg_trn_pending); method turnoff_ok(cfg_turnoff_ok) enable((*inhigh*) EN_cfg_turnoff_ok); method cfg_vc_tcvc_map vc_tcvc_map(); endinterface output_clock pipe_txoutclk_out(pipe_txoutclk_out); schedule (user_lnk_up, user_app_rdy, fc_ph, fc_pd, fc_nph, fc_npd, fc_cplh, fc_cpld, fc_sel, s_axis_tx_tlast, s_axis_tx_tdata, s_axis_tx_tkeep, s_axis_tx_tvalid, s_axis_tx_tready, s_axis_tx_tuser, tx_buf_av, tx_err_drop, tx_cfg_req, tx_cfg_gnt, m_axis_rx_tlast, m_axis_rx_tdata, m_axis_rx_tkeep, m_axis_rx_tuser, m_axis_rx_tvalid, m_axis_rx_tready, rx_np_ok, rx_np_req, cfg_bus_number, cfg_device_number, cfg_function_number, cfg_lcommand, cfg_command, cfg_dcommand, cfg_dcommand2, cfg_lstatus, cfg_pcie_link_state, cfg_received_func_lvl_rst, cfg_status, cfg_to_turnoff, cfg_vc_tcvc_map, cfg_bridge_serr_en, cfg_slot_control_electromech_il_ctl_pulse, cfg_pciecap_interrupt_msgnum, cfg_trn_pending, cfg_turnoff_ok, cfg_interrupt, cfg_dsn, pcie_txp, pcie_txn, pcie_rxp, pcie_rxn, pipe_mmcm_lock_in, pipe_pclk_sel_out ) CF (user_lnk_up, user_app_rdy, fc_ph, fc_pd, fc_nph, fc_npd, fc_cplh, fc_cpld, fc_sel, s_axis_tx_tlast, s_axis_tx_tdata, s_axis_tx_tkeep, s_axis_tx_tvalid, s_axis_tx_tready, s_axis_tx_tuser, tx_buf_av, tx_err_drop, tx_cfg_req, tx_cfg_gnt, m_axis_rx_tlast, m_axis_rx_tdata, m_axis_rx_tkeep, m_axis_rx_tuser, m_axis_rx_tvalid, m_axis_rx_tready, rx_np_ok, rx_np_req, cfg_bus_number, cfg_device_number, cfg_function_number, cfg_lcommand, cfg_command, cfg_dcommand, cfg_dcommand2, cfg_lstatus, cfg_pcie_link_state, cfg_received_func_lvl_rst, cfg_status, cfg_to_turnoff, cfg_vc_tcvc_map, cfg_bridge_serr_en, cfg_slot_control_electromech_il_ctl_pulse, cfg_pciecap_interrupt_msgnum, cfg_trn_pending, cfg_turnoff_ok, cfg_interrupt, cfg_dsn, pcie_txp, pcie_txn, pcie_rxp, pcie_rxn, pipe_mmcm_lock_in, pipe_pclk_sel_out ); endmodule: vMkXilinx7PCIExpress //////////////////////////////////////////////////////////////////////////////// /// Interfaces //////////////////////////////////////////////////////////////////////////////// interface PcieEndpointX7#(numeric type lanes); interface PciewrapPci_exp#(lanes) pcie; interface PciewrapUser#(lanes) user; interface PciewrapCfg#(lanes) cfg; interface Server#(TLPData#(16), TLPData#(16)) tlp; interface PipeOut#(Bit#(64)) regChanges; interface Clock epPcieClock; interface Reset epPcieReset; interface Clock epPortalClock; interface Reset epPortalReset; interface Clock epDerivedClock; interface Reset epDerivedReset; endinterface typedef struct { Bit#(22) user; Bit#(1) last; Bit#(8) keep; Bit#(64) data; } AxiRx deriving (Bits, Eq); typedef struct { Bit#(1) last; Bit#(8) keep; Bit#(64) data; } AxiTx deriving (Bits, Eq); (* synthesize *) module mkPcieEndpointX7(PcieEndpointX7#(PcieLanes)); PCIEParams params = defaultValue; //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// B2C1 b2c <- mkB2C1(); ClockGenerator7AdvParams clockParams = defaultValue; clockParams.bandwidth = "OPTIMIZED"; clockParams.compensation = "INTERNAL"; clockParams.clkfbout_mult_f = 10.000; clockParams.clkfbout_phase = 0.0; clockParams.clkin1_period = 10.000; clockParams.clkout0_divide_f = 8.000; clockParams.clkout0_duty_cycle = 0.5; clockParams.clkout0_phase = 0.0000; clockParams.clkout1_divide = 4; clockParams.clkout1_duty_cycle = 0.5; clockParams.clkout1_phase = 0.0000; clockParams.clkout2_divide = 4; clockParams.clkout2_duty_cycle = 0.5; clockParams.clkout2_phase = 0.0000; clockParams.divclk_divide = 1; clockParams.ref_jitter1 = 0.010; clockParams.clkin_buffer = False; XClockGenerator7 clockGen <- mkClockGenerator7Adv(clockParams, clocked_by b2c.c); C2B c2b_fb <- mkC2B(clockGen.clkfbout, clocked_by clockGen.clkfbout); rule txoutrule5; clockGen.clkfbin(c2b_fb.o()); endrule Reset defaultReset <- exposeCurrentReset(); Bufgctrl bbufc <- mkBufgctrl(clockGen.clkout0, defaultReset, clockGen.clkout1, defaultReset); Reset rsto <- mkSyncReset(5, defaultReset, bbufc.o); Reg#(Bit#(1)) pclk_sel <- mkReg(0, clocked_by bbufc.o, reset_by rsto); Reg#(Bit#(PcieLanes)) pclk_sel_reg1 <- mkReg(0, clocked_by bbufc.o, reset_by rsto); Reg#(Bit#(PcieLanes)) pclk_sel_reg2 <- mkReg(0, clocked_by bbufc.o, reset_by rsto); rule bufcruleinit; bbufc.ce0(1); bbufc.ce1(1); bbufc.ignore0(0); bbufc.ignore1(0); endrule rule bufcrule; bbufc.s0(~pclk_sel); bbufc.s1(pclk_sel); endrule PCIE_X7#(PcieLanes) pcie_ep <- vMkXilinx7PCIExpress(params, clockGen.clkout0, clockGen.clkout2, bbufc.o); //new PcieWrap#(PcieLanes) pciew <- mkPcieWrap(); FIFOF#(AxiTx) fAxiTx <- mkBypassFIFOF(clocked_by pcie_ep.user.clk_out, reset_by noReset); FIFOF#(AxiRx) fAxiRx <- mkBypassFIFOF(clocked_by pcie_ep.user.clk_out, reset_by noReset); (* fire_when_enabled, no_implicit_conditions *) rule every1; pcie_ep.fc.sel(0 /*RECEIVE_BUFFER_AVAILABLE_SPACE*/); pcie_ep.cfg_dsn({ 32'h0000_0001, {{ 8'h1 } , 24'h000A35 }}); pcie_ep.rx.np_ok(1); pcie_ep.rx.np_req(1); pcie_ep.tx.cfg_gnt(1); pcie_ep.s_axis_tx.tuser(4'b0); pcie_ep.m_axis_rx.tready(pack(fAxiRx.notFull)); endrule rule every2; pcie_ep.pipe_mmcm_lock_in(pack(clockGen.locked)); endrule rule every3; pclk_sel_reg1 <= pcie_ep.pipe_pclk_sel_out(); endrule Clock txoutclk_buf <- mkClockBUFG(clocked_by pcie_ep.pipe_txoutclk_out); C2B c2b <- mkC2B(txoutclk_buf); rule txoutrule; b2c.inputclock(c2b.o()); endrule rule update_psel; let ps = pclk_sel; pclk_sel_reg2 <= pclk_sel_reg1; if ((~pclk_sel_reg2) == 0) ps = 1; else if (pclk_sel_reg2 == 0) ps = 0; pclk_sel <= ps; endrule let txready = (pcie_ep.s_axis_tx.tready != 0 && fAxiTx.notEmpty); //(* fire_when_enabled, no_implicit_conditions *) rule drive_axi_tx if (txready); let info = fAxiTx.first; fAxiTx.deq; pcie_ep.s_axis_tx.tvalid(1); pcie_ep.s_axis_tx.tlast(info.last); pcie_ep.s_axis_tx.tdata(info.data); pcie_ep.s_axis_tx.tkeep(info.keep); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_tx2 if (!txready); pcie_ep.s_axis_tx.tvalid(0); pcie_ep.s_axis_tx.tlast(0); pcie_ep.s_axis_tx.tdata(0); pcie_ep.s_axis_tx.tkeep(0); endrule (* fire_when_enabled *) rule sink_axi_rx if (pcie_ep.m_axis_rx.tvalid != 0); fAxiRx.enq(AxiRx {user: pcie_ep.m_axis_rx.tuser, last: pcie_ep.m_axis_rx.tlast, keep: pcie_ep.m_axis_rx.tkeep, data: pcie_ep.m_axis_rx.tdata }); endrule // The PCIe endpoint exports full (250MHz) and half-speed (125MHz) clocks Clock clock250 = pcie_ep.user.clk_out; Reset user_reset_n <- mkResetInverter(pcie_ep.user.reset_out, clocked_by clock250); Reset reset250 <- mkSyncReset(5, user_reset_n, clock250); ClockGenerator7Params clkgenParams = defaultValue; clkgenParams.clkin1_period = 4.000; // 250MHz clkgenParams.clkin1_period = 4.000; clkgenParams.clkin_buffer = False; clkgenParams.clkfbout_mult_f = 4.000; // 1000MHz clkgenParams.clkout0_divide_f = derivedClockPeriod; clkgenParams.clkout1_divide = round(mainClockPeriod); // defaults to 125MHz; clkgenParams.clkout1_duty_cycle = 0.5; clkgenParams.clkout1_phase = 0.0000; ClockGenerator7 clkgen <- mkClockGenerator7(clkgenParams, clocked_by clock250, reset_by user_reset_n); Clock clock125 = clkgen.clkout1; /* 125MHz user_clk */ Reset reset125 <- mkSyncReset(5, user_reset_n, clock125); Clock derivedClock = clkgen.clkout0; Reset derivedReset <- mkSyncReset(5, user_reset_n, derivedClock); FIFOF#(RegChange) changeFifo <- mkFIFOF(clocked_by clock125, reset_by reset125); //mkSizedBRAMFIFOF(128, clocked_by clock125, reset_by reset125); Server#(TLPData#(8), TLPData#(8)) tlp8 = (interface Server; interface Put request; method Action put(TLPData#(8) data); fAxiTx.enq(AxiTx {last: pack(data.eof), keep: dwordSwap64BE(data.be), data: dwordSwap64(data.data) }); endmethod endinterface interface Get response; method ActionValue#(TLPData#(8)) get(); let info <- toGet(fAxiRx).get; TLPData#(8) retval = defaultValue; retval.sof = (info.user[14] == 1); retval.eof = info.last != 0; retval.hit = info.user[8:2]; retval.be= dwordSwap64BE(info.keep); retval.data = dwordSwap64(info.data); return retval; endmethod endinterface endinterface); `ifdef PCIE_250MHZ Clock portalClock = clock250; Reset portalReset = reset250; `else Clock portalClock = clock125; Reset portalReset = reset125; `endif // The PCIE endpoint is processing TLPData#(8)s at 250MHz. The // AXI bridge is accepting TLPData#(16)s at 125 MHz. The // connection between the endpoint and the AXI contains GearBox // instances for the TLPData#(8)@250 <--> TLPData#(16)@125 // conversion. PcieGearbox gb <- mkPcieGearbox(clock250, reset250, portalClock, portalReset); mkConnection(tlp8, gb.tlp, clocked_by portalClock, reset_by portalReset); interface tlp = gb.pci; interface pcie = pcie_ep.pcie; interface PciewrapUser user = pcie_ep.user; interface PciewrapCfg cfg = pcie_ep.cfg; interface regChanges = mapPipe(pack, toPipeOut(changeFifo)); interface Clock epPcieClock = clock125; interface Reset epPcieReset = reset125; interface Clock epPortalClock = portalClock; interface Reset epPortalReset = portalReset; interface Clock epDerivedClock = derivedClock; interface Reset epDerivedReset = derivedReset; endmodule: mkPcieEndpointX7 ================================================ FILE: bsv/Pcie2EndpointX7.bsv ================================================ // Copyright (c) 2012-2013 Nokia, Inc. // Copyright (c) 2014-2015 Quanta Research Cambridge, Inc. // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package Pcie2EndpointX7; `include "ConnectalProjectConfig.bsv" import ConnectalConfig ::*; import BRAMFIFO ::*; import Clocks ::*; import Vector ::*; import BuildVector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import SpecialFIFOs ::*; import ClientServer ::*; import Real ::*; import ConnectalClocks ::*; import ConnectalXilinxCells ::*; import XilinxCells ::*; import PCIE ::*; import PCIEWRAPPER2 ::*; import Pipe ::*; import PcieStateChanges ::*; import Bufgctrl ::*; //////////////////////////////////////////////////////////////////////////////// /// Interfaces //////////////////////////////////////////////////////////////////////////////// interface PcieEndpointX7#(numeric type lanes); interface PciewrapPci_exp#(lanes) pcie; interface PciewrapUser#(lanes) user; interface PciewrapCfg#(lanes) cfg; interface Server#(TLPData#(16), TLPData#(16)) tlp; interface PipeOut#(Bit#(64)) regChanges; interface Clock epPcieClock; interface Reset epPcieReset; interface Clock epPortalClock; interface Reset epPortalReset; interface Clock epDerivedClock; interface Reset epDerivedReset; endinterface typedef struct { Bit#(22) user; Bit#(1) last; Bit#(16) keep; Bit#(128) data; } AxiRx deriving (Bits, Eq); typedef struct { Bit#(1) last; Bit#(16) keep; Bit#(128) data; } AxiTx deriving (Bits, Eq); (* synthesize *) module mkPcieEndpointX7(PcieEndpointX7#(PcieLanes)); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); PcieWrap#(PcieLanes) pcie_ep <- mkPcieWrap(defaultClock, defaultReset); Clock user_clk = pcie_ep.user_clk_out; Reset user_reset_n <- mkResetInverter(pcie_ep.user_reset_out, clocked_by user_clk); FIFOF#(AxiTx) fAxiTx <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n); FIFOF#(AxiRx) fAxiRx <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n); (* fire_when_enabled, no_implicit_conditions *) rule every1; pcie_ep.fc.sel(0 /*RECEIVE_BUFFER_AVAILABLE_SPACE*/); pcie_ep.cfg_dsn({ 32'h0000_0001, {{ 8'h1 } , 24'h000A35 }}); pcie_ep.rx.np_ok(1); pcie_ep.rx.np_req(1); pcie_ep.tx.cfg_gnt(1); pcie_ep.s_axis_tx.tuser(4'b0); pcie_ep.m_axis_rx.tready(pack(fAxiRx.notFull)); endrule rule every_cfg_err; pcie_ep.cfg_err.acs(0); pcie_ep.cfg_err.aer_headerlog(0); pcie_ep.cfg_err.atomic_egress_blocked(0); pcie_ep.cfg_err.cor(0); pcie_ep.cfg_err.cpl_abort(0); pcie_ep.cfg_err.cpl_timeout(0); pcie_ep.cfg_err.cpl_unexpect(0); pcie_ep.cfg_err.ecrc(0); pcie_ep.cfg_err.internal_cor(0); pcie_ep.cfg_err.internal_uncor(0); pcie_ep.cfg_err.locked(0); pcie_ep.cfg_err.malformed(0); pcie_ep.cfg_err.mc_blocked(0); pcie_ep.cfg_err.norecovery(0); pcie_ep.cfg_err.poisoned(0); pcie_ep.cfg_err.posted(0); pcie_ep.cfg_err.tlp_cpl_header(0); pcie_ep.cfg_err.ur(0); endrule rule every_interrupt; pcie_ep.cfg_interrupt.zzassert(0); pcie_ep.cfg_interrupt.di(0); pcie_ep.cfg_interrupt.stat(0); endrule rule every_mgmt; pcie_ep.cfg_mgmt.byte_en(0); pcie_ep.cfg_mgmt.di(0); pcie_ep.cfg_mgmt.dwaddr(0); pcie_ep.cfg_mgmt.rd_en(0); pcie_ep.cfg_mgmt.wr_en(0); pcie_ep.cfg_mgmt.wr_readonly(0); endrule rule every_pm; pcie_ep.cfg_pm.force_state(0); pcie_ep.cfg_pm.force_state_en(0); pcie_ep.cfg_pm.halt_aspm_l0s(0); pcie_ep.cfg_pm.halt_aspm_l1(0); pcie_ep.cfg_pm.send_pme_to(0); pcie_ep.cfg_pm.wake(0); endrule rule every_pl; pcie_ep.pl.directed_link_auton(0); pcie_ep.pl.directed_link_change(0); pcie_ep.pl.directed_link_speed(0); pcie_ep.pl.directed_link_width(0); pcie_ep.pl.downstream_deemph_source(0); pcie_ep.pl.transmit_hot_rst(0); pcie_ep.pl.upstream_prefer_deemph(1); endrule Reg#(Bit#(32)) cyclesReg <- mkReg(0, clocked_by user_clk, reset_by user_reset_n); rule rl_cycles; cyclesReg <= cyclesReg + 1; endrule `ifdef DebugPcieStateMachine Vector#(17,Tuple2#(PcieCfgType,Bit#(24))) changeValues = vec( //tuple2(PcieCfg_initial_link_width, extend(pcie_ep.pl.initial_link_width)), //tuple2(PcieCfg_lane_reversal_mode, extend(pcie_ep.pl.lane_reversal_mode)), tuple2(PcieCfg_ltssm_state, extend(pcie_ep.pl.ltssm_state)), tuple2(PcieCfg_phy_link_up, extend(pcie_ep.pl.phy_lnk_up)), tuple2(PcieCfg_received_hot_rst, extend(pcie_ep.pl.received_hot_rst)), //tuple2(PcieCfg_rx_pm_state, extend(pcie_ep.pl.rx_pm_state)), tuple2(PcieCfg_sel_lnk_rate, extend(pcie_ep.pl.sel_lnk_rate)), //tuple2(PcieCfg_negotiated_width, extend(pcie_ep.pl.sel_lnk_width)), //tuple2(PcieCfg_tx_pm_state, extend(pcie_ep.pl.tx_pm_state)), tuple2(PcieCfg_link_up, extend(pcie_ep.user.lnk_up)), tuple2(PcieCfg_link_gen2_cap, extend(pcie_ep.pl_link_gen2_cap)), tuple2(PcieCfg_link_partner_gen2_supported, extend(pcie_ep.pl_link_partner_gen2_supported)), tuple2(unpack(50), extend(pcie_ep.cfg.pcie_link_state)), tuple2(unpack(51), extend(pcie_ep.cfg_aer.rooterr_corr_err_received)), tuple2(unpack(52), extend(pcie_ep.cfg_aer.rooterr_fatal_err_received)), tuple2(unpack(53), extend(pcie_ep.cfg_msg.received)), tuple2(unpack(54), extend(pcie_ep.cfg_msg.received_err_cor)), tuple2(unpack(55), extend(pcie_ep.cfg_msg.received_err_fatal)), tuple2(unpack(56), extend(pcie_ep.cfg_msg.received_err_non_fatal)), tuple2(unpack(57), extend(pcie_ep.cfg_pmcsr.pme_en)), tuple2(unpack(58), extend(pcie_ep.cfg_pmcsr.pme_status)), tuple2(unpack(59), extend(pcie_ep.cfg_pmcsr.powerstate))); let change_pipes <- mapM(mkChangeSource(cyclesReg), changeValues, clocked_by user_clk, reset_by user_reset_n); FunnelPipe#(1,17,RegChange,3) changePipe <- mkFunnelPipesPipelined(change_pipes, clocked_by user_clk, reset_by user_reset_n); FIFOF#(RegChange) changeFifo <- mkSizedBRAMFIFOF(128, clocked_by user_clk, reset_by user_reset_n); mkConnection(changePipe[0], toPipeIn(changeFifo), clocked_by user_clk, reset_by user_reset_n); `else FIFOF#(RegChange) changeFifo <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n); `endif let txready = (pcie_ep.s_axis_tx.tready == 1 && fAxiTx.notEmpty); (* fire_when_enabled *) rule drive_axi_tx if (txready); let info = unpack(0); if (fAxiTx.notEmpty) begin info <- toGet(fAxiTx).get(); end pcie_ep.s_axis_tx.tlast(info.last); pcie_ep.s_axis_tx.tdata(info.data); pcie_ep.s_axis_tx.tkeep(info.keep); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_txvalid if (fAxiTx.notEmpty); pcie_ep.s_axis_tx.tvalid(1); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_tx2 if (!fAxiTx.notEmpty); pcie_ep.s_axis_tx.tvalid(0); pcie_ep.s_axis_tx.tlast(0); pcie_ep.s_axis_tx.tdata(0); pcie_ep.s_axis_tx.tkeep(0); endrule (* fire_when_enabled *) rule sink_axi_rx if (pcie_ep.m_axis_rx.tvalid == 1); fAxiRx.enq(AxiRx {user: pcie_ep.m_axis_rx.tuser, last: pcie_ep.m_axis_rx.tlast, keep: pcie_ep.m_axis_rx.tkeep, data: pcie_ep.m_axis_rx.tdata }); endrule ClockGenerator7Params clkgenParams = defaultValue; clkgenParams.clkin1_period = 4.000; // 250MHz clkgenParams.clkin_buffer = False; clkgenParams.clkfbout_mult_f = 4.000; // 1000MHz clkgenParams.clkout0_divide_f = derivedClockPeriod; clkgenParams.clkout1_divide = round(mainClockPeriod); clkgenParams.clkout1_duty_cycle = 0.5; clkgenParams.clkout1_phase = 0.0000; clkgenParams.clkout2_divide = 4; // 250MHz clkgenParams.clkout2_duty_cycle = 0.5; clkgenParams.clkout2_phase = 0.0000; ClockGenerator7 clkgen <- mkClockGenerator7(clkgenParams, clocked_by user_clk, reset_by user_reset_n); Clock portalClock; Reset portalReset; if (mainClockPeriod == pcieClockPeriod) begin portalClock = user_clk; portalReset = user_reset_n; end else begin portalClock = clkgen.clkout1; portalReset <- mkSyncReset(5, user_reset_n, portalClock); end Clock derivedClock = clkgen.clkout0; Reset derivedReset <- mkSyncReset(5, user_reset_n, derivedClock); Server#(TLPData#(16), TLPData#(16)) tlp16 = (interface Server; interface Put request; method Action put(TLPData#(16) data); fAxiTx.enq(AxiTx {last: pack(data.eof), keep: dwordSwap128BE(data.be), data: dwordSwap128(data.data) }); endmethod endinterface interface Get response; method ActionValue#(TLPData#(16)) get(); let info <- toGet(fAxiRx).get; TLPData#(16) retval = defaultValue; retval.sof = (info.user[14] == 1); retval.eof = (info.user[21] == 1); // 128-bit interface uses tuser bits instead of tlast to indicate EOF retval.hit = info.user[8:2]; retval.be= dwordSwap128BE(info.keep); retval.data = dwordSwap128(info.data); return retval; endmethod endinterface endinterface); interface tlp = tlp16; interface pcie = pcie_ep.pci_exp; interface PciewrapUser user = pcie_ep.user; interface PciewrapCfg cfg = pcie_ep.cfg; interface regChanges = mapPipe(pack, toPipeOut(changeFifo)); interface Clock epPcieClock = user_clk; interface Reset epPcieReset = user_reset_n; interface Clock epPortalClock = portalClock; interface Reset epPortalReset = portalReset; interface Clock epDerivedClock = derivedClock; interface Reset epDerivedReset = derivedReset; endmodule: mkPcieEndpointX7 endpackage: Pcie2EndpointX7 ================================================ FILE: bsv/Pcie3EndpointX7.bsv ================================================ // Copyright (c) 2014-2015 Quanta Research Cambridge, Inc. // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package Pcie3EndpointX7; `include "ConnectalProjectConfig.bsv" import BRAMFIFO ::*; import Clocks ::*; import Vector ::*; import BuildVector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import ConnectalFIFO ::*; import SpecialFIFOs ::*; import ClientServer ::*; import Real ::*; import XilinxVirtex7PCIE ::*; import BUtils ::*; import Probe ::*; import ConnectalConfig::*; import ConnectalClocks ::*; import ConnectalXilinxCells ::*; import XilinxCells ::*; import PCIE ::*; `ifdef VirtexUltrascalePlus import PCIEWRAPPER3uplus ::*; `else `ifdef XilinxUltrascale import PCIEWRAPPER3u ::*; `else import PCIEWRAPPER3 ::*; `endif `endif import Bufgctrl ::*; import PcieGearbox :: *; import Pipe :: *; interface PcieEndpointX7#(numeric type lanes); interface PciewrapPci_exp#(lanes) pcie; interface PciewrapUser#(lanes) user; interface Server#(TLPData#(16), TLPData#(16)) tlpr; interface Server#(TLPData#(16), TLPData#(16)) tlpc; interface Put#(Tuple2#(Bit#(64),Bit#(32))) interruptRequest; interface PipeOut#(Bit#(64)) regChanges; interface Clock epPcieClock; interface Reset epPcieReset; interface Clock epPortalClock; interface Reset epPortalReset; interface Clock epDerivedClock; interface Reset epDerivedReset; endinterface typedef struct { Bit #(256) data; Bool sop; Bool eop; Bit #(8) keep; TLPFirstDWBE first_be; TLPFirstDWBE last_be; } AxiStCq deriving (Bits, Eq); typedef struct { Bit #(256) data; Bit #(8) keep; Bool last; } AxiStCc deriving (Bits, Eq); typedef struct { Bit #(256) data; Bool last; Bit #(8) keep; Bit #(4) first_be; Bit #(4) last_be; } AxiStRq deriving (Bits, Eq); typedef struct { Bit #(256) data; Bool sop; Bool eop; Bit #(8) keep; Bit #(8) be; } AxiStRc deriving (Bits, Eq); function TLPData#(16) convertCQDescriptorToTLP16(CQDescriptor desc, Bit#(32) data, TLPFirstDWBE first, TLPLastDWBE last); TLPMemoryIO3DWHeader header = defaultValue; header.format = tpl_1(convertCQReqTypeToTLPFmtType(desc.reqtype)); header.pkttype = tpl_2(convertCQReqTypeToTLPFmtType(desc.reqtype)); header.tclass = desc.tclass; header.relaxed = desc.relaxed; header.nosnoop = desc.nosnoop; header.length = (desc.dwcount == 1024) ? 0 : truncate(desc.dwcount); header.reqid = desc.reqid; header.tag = desc.tag; header.lastbe = last; header.firstbe = first; header.addr = truncate(desc.address); header.data = convertDW(data); Bool is3DW = isReadReqType(desc.reqtype); Bool is3Or4DW = isReadReqType(desc.reqtype) || (desc.dwcount == 1); TLPData#(16) retval = defaultValue; retval.sof = True; retval.eof = is3Or4DW; retval.hit = (1 << pack(desc.barid)); retval.data = pack(header); retval.be = (is3DW ? 16'hFFF0 : 16'hFFFF); return retval; endfunction function TLPData#(16) convertRCDescriptorToTLP16(RCDescriptor desc, Bit#(32) data); TLPCompletionHeader header = defaultValue; header.tclass = desc.tclass; header.relaxed = desc.relaxed; header.nosnoop = desc.nosnoop; header.cmplid = desc.complid; header.tag = desc.tag; header.reqid = desc.reqid; header.poison = desc.poisoned; header.cstatus = desc.status; header.length = (desc.dwcount == 1024) ? 0 : truncate(desc.dwcount); header.bytecount = (desc.bytecount == 4096) ? 0 : truncate(desc.bytecount); header.loweraddr = truncate(desc.loweraddr); header.data = convertDW(data); Bool is3DW = (desc.dwcount == 0); Bool is3Or4DW = (desc.dwcount == 0) || (desc.dwcount == 1); TLPData#(16) retval = defaultValue; retval.sof = True; retval.eof = is3Or4DW; retval.hit = 1; // XXX retval.data = pack(header); retval.be = (is3DW ? 16'hFFF0 : 16'hFFFF); return retval; endfunction typedef struct { Bit#(32) timestamp; Bit#(8) src; Bit#(24) value; } RegChange deriving (Bits); typedef enum { Pcie3Cfg_none, Pcie3Cfg_current_speed, Pcie3Cfg_dpa_substate_change, Pcie3Cfg_err_cor_out, Pcie3Cfg_err_fatal_out, Pcie3Cfg_err_nonfatal_out, Pcie3Cfg_flr_in_process, Pcie3Cfg_function_power_state, Pcie3Cfg_function_status, Pcie3Cfg_hot_reset_out, Pcie3Cfg_link_power_state, Pcie3Cfg_ltr_enable, Pcie3Cfg_ltssm_state, Pcie3Cfg_max_payload, Pcie3Cfg_max_read_req, Pcie3Cfg_negotiated_width, Pcie3Cfg_obff_enable, Pcie3Cfg_phy_link_down, Pcie3Cfg_phy_link_status, Pcie3Cfg_pl_status_change, Pcie3Cfg_power_state_change_interrupt, Pcie3Cfg_rcb_status, Pcie3Cfg_rq_backpressure } Pcie3CfgType deriving (Bits,Eq); (* synthesize *) module mkPcieEndpointX7#(Clock pcie_sys_clk_gt)(PcieEndpointX7#(PcieLanes)); PCIEParams params = defaultValue; Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reset defaultResetInverted <- mkResetInverter(defaultReset, clocked_by defaultClock); PcieWrap#(PcieLanes) pcie_ep <- mkPcieWrap(defaultClock, `ifdef XilinxUltrascale pcie_sys_clk_gt, defaultReset `else defaultResetInverted `endif ); // The PCIe endpoint exports full (250MHz) and half-speed (125MHz) clocks Clock pcieClock250 = pcie_ep.user_clk; Reset user_reset_n <- mkResetInverter(pcie_ep.user_reset, clocked_by pcie_ep.user_clk); Reset pcieReset250 <- mkSyncReset(5, user_reset_n, pcieClock250); ClockGenerator7Params clkgenParams = defaultValue; clkgenParams.clkin1_period = 4.000; // 250MHz clkgenParams.clkin1_period = 4.000; clkgenParams.clkin_buffer = False; clkgenParams.clkfbout_mult_f = 4.000; // 1000MHz clkgenParams.clkout0_divide_f = derivedClockPeriod; clkgenParams.clkout1_divide = round(mainClockPeriod); clkgenParams.clkout1_duty_cycle = 0.5; clkgenParams.clkout1_phase = 0.0000; ClockGenerator7 clkgen <- mkClockGenerator7(clkgenParams, clocked_by pcieClock250, reset_by pcieReset250); Clock mainClock = clkgen.clkout1; Reset mainReset <- mkSyncReset(10, pcieReset250, mainClock); Clock derivedClock = clkgen.clkout0; Reset derivedReset <- mkSyncReset(5, pcieReset250, derivedClock); Reset user_reset <- mkSyncReset(5, pcie_ep.user_reset, pcie_ep.user_clk); // FIFOS FIFOF#(AxiStCq) fAxiCq <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(AxiStRc) fAxiRc <- mkCFFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(AxiStRq) fAxiRq <- mkCFFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(AxiStCc) fAxiCc <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) fcq <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) frc <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) fcc <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) frq <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(Tuple2#(Bit#(64),Bit#(32))) intrFifo <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); // Drive s_axis_rq let rq_txready = (pcie_ep.s_axis_rq.tready != 0 && fAxiRq.notEmpty); //(* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rq; let tvalid = 0; let tlast = 0; let tdata = 0; let tkeep = 0; let tuser = 0; if (rq_txready) begin let info = fAxiRq.first; fAxiRq.deq; tvalid = 1; tlast = pack(info.last); tdata = info.data; tkeep = info.keep; tuser = {0, info.last_be, info.first_be}; end pcie_ep.s_axis_rq.tvalid(tvalid); pcie_ep.s_axis_rq.tlast(tlast); pcie_ep.s_axis_rq.tdata(tdata); pcie_ep.s_axis_rq.tkeep(tkeep); pcie_ep.s_axis_rq.tuser(tuser); endrule Reg#(Bit#(16)) rqBackpressureCycles <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bit#(16)) rqBackpressureCount <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bool) rqBackpressure <- mkReg(False, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bit#(32)) rqBackpressureCountSum <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bit#(32)) rqBackpressureEvents <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); rule rlBackpressureEnter if (!rqBackpressure); if (pcie_ep.s_axis_rq.tready == 0 && fAxiRq.notEmpty) begin rqBackpressure <= True; rqBackpressureCycles <= 0; end endrule rule rlBackpressureExit if (rqBackpressure); rqBackpressureCycles <= rqBackpressureCycles + 1; if (pcie_ep.s_axis_rq.tready != 0 || !fAxiRq.notEmpty) begin rqBackpressure <= False; let count = rqBackpressureCycles; count[15] = ~rqBackpressureCount[15]; if (count > 5) rqBackpressureCount <= count; rqBackpressureCountSum <= rqBackpressureCountSum + extend(count); rqBackpressureEvents <= rqBackpressureEvents + 1; end endrule // Drive s_axis_cc let cc_txready = (pcie_ep.s_axis_cc.tready != 0 && fAxiCc.notEmpty); //(* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cc if (cc_txready); let info = fAxiCc.first; fAxiCc.deq; $display("drive axi_cc, data: %h, keep: %h, last: %h", info.data, info.keep, info.last); pcie_ep.s_axis_cc.tvalid(1); pcie_ep.s_axis_cc.tlast(pack(info.last)); pcie_ep.s_axis_cc.tdata(info.data); pcie_ep.s_axis_cc.tkeep(info.keep); pcie_ep.s_axis_cc.tuser(0); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cc2 if (!cc_txready); pcie_ep.s_axis_cc.tvalid(0); pcie_ep.s_axis_cc.tlast(0); pcie_ep.s_axis_cc.tdata(0); pcie_ep.s_axis_cc.tkeep(0); pcie_ep.s_axis_cc.tuser(0); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rc_ready; pcie_ep.m_axis_rc.tready (duplicate (pack (fAxiRc.notFull))); endrule // Drive m_axis_rc (* fire_when_enabled *) rule sink_axi_rc if (pcie_ep.m_axis_rc.tvalid != 0 && fAxiRc.notFull); let rc = AxiStRc {data:pcie_ep.m_axis_rc.tdata, sop: unpack (pcie_ep.m_axis_rc.tuser [32]), // tuser.is_sof_0 eop: unpack (pcie_ep.m_axis_rc.tlast), keep:pcie_ep.m_axis_rc.tkeep, be: truncate (pcie_ep.m_axis_rc.tuser [31:0])}; // tuser.byte_en fAxiRc.enq (rc); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cq_ready; pcie_ep.m_axis_cq.tready (duplicate (pack (fAxiCq.notFull))); endrule (* fire_when_enabled *) rule sink_axi_cq if (pcie_ep.m_axis_cq.tvalid != 0 && fAxiCq.notFull); let cq = AxiStCq {data: pcie_ep.m_axis_cq.tdata, sop: unpack (pcie_ep.m_axis_cq.tuser [40]), // tuser.sop eop: unpack (pcie_ep.m_axis_cq.tlast), keep: pcie_ep.m_axis_cq.tkeep, first_be: pcie_ep.m_axis_cq.tuser [3:0], // tuser.first_be, last_be: pcie_ep.m_axis_cq.tuser [7:4]}; // tuser.last_be fAxiCq.enq (cq); endrule // CQ. CQDescriptor cq_desc = unpack(fAxiCq.first.data [127:0]); rule rl_cq_wr_header (fAxiCq.first.sop && ((cq_desc.reqtype == MEMORY_WRITE) || (cq_desc.reqtype == IO_WRITE))); Bit#(32) data = fAxiCq.first.data[159:128]; // get data; TLPData#(16) tlp16 = convertCQDescriptorToTLP16(cq_desc, data, fAxiCq.first.first_be, fAxiCq.first.last_be); $display("cq_desc.reqtype=%h", cq_desc.reqtype); // enqueue? fcq.enq(tlp16); fAxiCq.deq; endrule // Write data payload, no data remaining rule rl_cq_wr_payload((!fAxiCq.first.sop)); fAxiCq.deq; endrule // Write data payload, 1 to 3 DWs remaining // Write data payload, 4 or more DWs remaining rule rl_cq_rd_header (fAxiCq.first.sop && ((cq_desc.reqtype == MEMORY_READ) || (cq_desc.reqtype == IO_READ))); Bit#(32) data = 0; TLPData#(16) tlp16 = convertCQDescriptorToTLP16(cq_desc, data, fAxiCq.first.first_be, fAxiCq.first.last_be); $display("rl_cq_rd_header: cq_desc = %16x", cq_desc); fcq.enq(tlp16); fAxiCq.deq; endrule // RC. Reg#(DWCount) rc_dwcount <- mkRegU(clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bool) rc_even <- mkReg(True, clocked_by pcie_ep.user_clk, reset_by user_reset_n); rule rl_rc_header (fAxiRc.first.sop && rc_even); RCDescriptor rc_desc = unpack(fAxiRc.first.data [95:0]); // RC descriptor always 96 bytes with first data word in bits 127:96 Bit#(32) data = byteSwap(fAxiRc.first.data[127:96]); TLPData#(16) tlp16 = convertRCDescriptorToTLP16(rc_desc, data); rc_dwcount <= (rc_desc.dwcount == 0) ? 0 : rc_desc.dwcount - 1; frc.enq(tlp16); let even = False; if (rc_desc.dwcount == 0 || rc_desc.dwcount == 1) begin fAxiRc.deq; even = True; end rc_even <= even; endrule rule rl_rc_data ((!rc_even || !(fAxiRc.first.sop)) && (rc_dwcount != 0)); Bit#(16) be16; case (rc_dwcount) 1: be16 = 16'hF000; 2: be16 = 16'hFF00; 3: be16 = 16'hFFF0; default: be16 = 16'hFFFF; endcase let last = (rc_dwcount <= 4); let dwcount = rc_dwcount - 4; if (last) dwcount = 0; let data = (rc_even) ? fAxiRc.first.data[127:0]: fAxiRc.first.data[255:128]; TLPData#(16) tlp16 = TLPData{sof: False, eof: last, hit: 0, be: be16, data: pack(data)}; frc.enq(tlp16); if (last || !rc_even) begin fAxiRc.deq; end rc_dwcount <= dwcount; rc_even <= (last) ? True : !rc_even; endrule Reg#(DWCount) cc_dwcount <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) fcc_tlps <- mkFIFOF (clocked_by pcie_ep.user_clk, reset_by user_reset_n); // CC. rule get_cc_tlps; let tlp <- toGet(fcc).get; fcc_tlps.enq(tlp); endrule rule rl_cc_header(fcc_tlps.first.sof); match { .cc_desc, .dw} = convertTLP16ToCCDescriptor(fcc_tlps.first); cc_dwcount <= cc_desc.dwcount - 1; fAxiCc.enq(AxiStCc {data: zeroExtend({dw, pack(cc_desc)[95:0]}), last: fcc_tlps.first.eof, keep: 8'h0F}); fcc_tlps.deq; endrule rule rl_cc_data((!fcc_tlps.first.sof) && (cc_dwcount != 0)); Bit#(256) x = zeroExtend(fcc_tlps.first.data); //FIXME fAxiCc.enq(AxiStCc {data: {x}, last: cc_dwcount <= 4, keep: (cc_dwcount == 3) ? 8'h0F : 8'hFF}); fcc_tlps.deq; endrule // RQ. FIFOF#(TLPData#(16)) frq_tlps <- mkFIFOF (clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bit#(4)) rq_first_be <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bit#(4)) rq_last_be <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(Bool) rq_even <- mkRegU(clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(DWCount) rq_dwcount <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); Reg#(AxiStRq) rq_rq <- mkRegU(clocked_by pcie_ep.user_clk, reset_by user_reset_n); rule rl_rq_tlps; let tlp <- toGet(frq).get; frq_tlps.enq(tlp); endrule rule rl_rq_header if (frq_tlps.first.sof); TLPData#(16) tlp <- toGet(frq_tlps).get(); match { .rq_desc, .first_be, .last_be, .mdata} = convertTLP16ToRQDescriptor(tlp); let dwcount = ((rq_desc.reqtype == MEMORY_WRITE) ? rq_desc.dwcount : 0); rq_dwcount <= dwcount; rq_even <= False; rq_first_be <= first_be; rq_last_be <= last_be; let last = (rq_desc.reqtype == MEMORY_WRITE) ? (dwcount <= 4) : True; let rq = AxiStRq {data: zeroExtend(pack(rq_desc)), //FIXME: last: last, keep: 8'h0F, first_be: first_be, last_be: last_be}; if (rq_desc.reqtype == MEMORY_WRITE) rq_rq <= rq; else fAxiRq.enq(rq); endrule // more data rule rl_rq_data if (rq_dwcount != 0); TLPData#(16) tlp <- toGet(frq_tlps).get(); let rq = rq_rq; let last = (rq_dwcount <= 4); let dwcount = rq_dwcount - 4; Bit#(8) keep; if (last) dwcount = 0; if (rq_even) begin rq.data[127:0] = tlp.data; case (rq_dwcount) 1: keep = 8'h01; 2: keep = 8'h03; 3: keep = 8'h07; default: keep = 8'h0f; endcase end else begin rq.data[255:128] = tlp.data; case (rq_dwcount) 1: keep = 8'h1f; 2: keep = 8'h3f; 3: keep = 8'h7f; default: keep = 8'hff; endcase end rq.last = last; rq.first_be = rq_first_be; rq.last_be = rq_last_be; rq.keep = keep; if (!rq_even || last) fAxiRq.enq(rq); if (rq_even) rq_rq <= rq; rq_dwcount <= dwcount; rq_even <= (last) ? False : !rq_even; endrule FIFO#(Bool) intrMutex <- mkFIFO1(clocked_by pcie_ep.user_clk, reset_by user_reset_n); Wire#(Bool) msix_int_enable <- mkDWire(False, clocked_by pcie_ep.user_clk, reset_by user_reset_n); rule rl_intr; if (pcie_ep.cfg.interrupt_msix_enable[0] == 1) begin match { .addr, .data } <- toGet(intrFifo).get(); pcie_ep.cfg.interrupt_msix_address(addr); pcie_ep.cfg.interrupt_msix_data(data); msix_int_enable <= True; intrMutex.enq(True); end endrule: rl_intr rule rl_intr_enable; pcie_ep.cfg.interrupt_msix_int(pack(msix_int_enable)); endrule rule rl_intr_sent if ( `ifdef VirtexUltrascalePlus // both MSI and MSI-X use these ports on Ultrascale Plus pcie_ep.cfg.interrupt_msi_sent() == 1|| pcie_ep.cfg.interrupt_msi_fail() == 1 `else pcie_ep.cfg.interrupt_msix_sent() == 1|| pcie_ep.cfg.interrupt_msix_fail() == 1 `endif ); intrMutex.deq(); endrule Reg#(Bit#(32)) cyclesReg <- mkReg(0, clocked_by pcie_ep.user_clk, reset_by user_reset_n); rule rl_cycles; cyclesReg <= cyclesReg + 1; endrule module mkChangeSource#(Tuple2#(Pcie3CfgType,Bit#(24)) tpl)(PipeOut#(RegChange)); match { .src, .v } = tpl; let snapshot <- mkReg(0); let changeFifo <- mkFIFOF1(); rule rl_update if (v != snapshot); if (changeFifo.notFull) begin changeFifo.enq(RegChange { timestamp: cyclesReg, src: extend(pack(src)), value: extend(v) }); snapshot <= v; end endrule return toPipeOut(changeFifo); endmodule // let phy_link_status_probe <- mkProbe(clocked_by pcie_ep.user_clk, reset_by pcie_ep.user_reset); // let ltssm_state_probe <- mkProbe(clocked_by pcie_ep.user_clk, reset_by pcie_ep.user_reset); // rule probe_phy_link_status; // phy_link_status_probe <= pcie_ep.cfg.phy_link_status; // ltssm_state_probe <= pcie_ep.cfg.ltssm_state; // endrule `ifdef DebugPcieStateMachine Vector#(20,Tuple2#(Pcie3CfgType,Bit#(24))) changeValues = vec( tuple2(Pcie3Cfg_rq_backpressure, extend(rqBackpressureCount)), tuple2(Pcie3Cfg_current_speed, extend(pcie_ep.cfg.current_speed)), // tuple2(Pcie3Cfg_dpa_substate_change, extend(pcie_ep.cfg.dpa_substate_change)), tuple2(Pcie3Cfg_err_cor_out, extend(pcie_ep.cfg.err_cor_out)), tuple2(Pcie3Cfg_err_fatal_out, extend(pcie_ep.cfg.err_fatal_out)), tuple2(Pcie3Cfg_err_nonfatal_out, extend(pcie_ep.cfg.err_nonfatal_out)), tuple2(Pcie3Cfg_flr_in_process, extend(pcie_ep.cfg.flr_in_process)), tuple2(Pcie3Cfg_function_power_state, extend(pcie_ep.cfg.function_power_state)), tuple2(Pcie3Cfg_function_status, extend(pcie_ep.cfg.function_status)), tuple2(Pcie3Cfg_hot_reset_out, extend(pcie_ep.cfg.hot_reset_out)), tuple2(Pcie3Cfg_link_power_state, extend(pcie_ep.cfg.link_power_state)), // tuple2(Pcie3Cfg_ltr_enable, extend(pcie_ep.cfg.ltr_enable)), tuple2(Pcie3Cfg_ltssm_state, extend(pcie_ep.cfg.ltssm_state)), tuple2(Pcie3Cfg_max_payload, extend(pcie_ep.cfg.max_payload)), tuple2(Pcie3Cfg_max_read_req, extend(pcie_ep.cfg.max_read_req)), tuple2(Pcie3Cfg_negotiated_width, extend(pcie_ep.cfg.negotiated_width)), tuple2(Pcie3Cfg_obff_enable, extend(pcie_ep.cfg.obff_enable)), tuple2(Pcie3Cfg_phy_link_down, extend(pcie_ep.cfg.phy_link_down)), tuple2(Pcie3Cfg_phy_link_status, extend(pcie_ep.cfg.phy_link_status)), tuple2(Pcie3Cfg_pl_status_change, extend(pcie_ep.cfg.pl_status_change)), tuple2(Pcie3Cfg_power_state_change_interrupt, extend(pcie_ep.cfg.power_state_change_interrupt)), tuple2(Pcie3Cfg_rcb_status, extend(pcie_ep.cfg.rcb_status))); let change_pipes <- mapM(mkChangeSource, changeValues, clocked_by pcie_ep.user_clk, reset_by user_reset_n); FunnelPipe#(1,20,RegChange,3) changePipe <- mkFunnelPipesPipelined(change_pipes, clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(RegChange) changeFifo <- mkSizedBRAMFIFOF(128, clocked_by pcie_ep.user_clk, reset_by user_reset_n); mkConnection(changePipe[0], toPipeIn(changeFifo), clocked_by pcie_ep.user_clk, reset_by user_reset_n); `else let cs <- mkChangeSource(tuple2(Pcie3Cfg_rq_backpressure, extend(rqBackpressureCount)), clocked_by pcie_ep.user_clk, reset_by user_reset_n); FIFOF#(RegChange) changeFifo <- mkFIFOF(clocked_by pcie_ep.user_clk, reset_by user_reset_n); mkConnection(cs, toPipeIn(changeFifo), clocked_by pcie_ep.user_clk, reset_by user_reset_n); `endif rule rl_drive_cfg_status_if; pcie_ep.cfg.config_space_enable(1); pcie_ep.cfg.dsn(64'hf001ba7700000000); pcie_ep.cfg.ds_bus_number(0); pcie_ep.cfg.ds_device_number(0); pcie_ep.cfg.ds_port_number(0); pcie_ep.cfg.err_cor_in(0); pcie_ep.cfg.err_uncor_in(0); pcie_ep.cfg.flr_done(0); pcie_ep.cfg.hot_reset_in(0); pcie_ep.cfg.link_training_enable(1); `ifndef VirtexUltrascalePlus pcie_ep.cfg.per_function_number(0); pcie_ep.cfg.per_function_output_request(0); pcie_ep.cfg.subsys_vend_id(16'h1be8); `endif `ifdef VirtexUltrascalePlus pcie_ep.cfg.pm_aspm_l1_entry_reject(0); pcie_ep.cfg.pm_aspm_tx_l0s_entry_disable(1); `endif pcie_ep.cfg.power_state_change_ack(1); pcie_ep.cfg.vf_flr_done(0); pcie_ep.pcie.cq_np_req(1); pcie_ep.cfg_req_pm_transition.l23_ready(0); endrule // The PCIE endpoint is processing Gen3 descriptors at 250MHz. The // AXI bridge is accepting TLPData#(16)s at 250 MHz. The // conversion uses half of Gen3 descriptor. //mkConnection(tlp8, gb.tlp, clocked_by portalClock, reset_by portalReset); let portalClock = (mainClockPeriod == pcieClockPeriod) ? pcieClock250 : mainClock; let portalReset = (mainClockPeriod == pcieClockPeriod) ? pcieReset250 : mainReset; interface Server tlpr; interface request = toPut(frq); interface response = toGet(frc); endinterface // Requests from other PCIe devices interface Server tlpc; interface request = toPut(fcc); interface response = toGet(fcq); endinterface interface interruptRequest = toPut(intrFifo); interface pcie = pcie_ep.pci_exp; interface Pcie3wrapUser user = pcie_ep.user; interface regChanges = mapPipe(pack, toPipeOut(changeFifo)); interface Clock epPcieClock = pcieClock250; interface Reset epPcieReset = pcieReset250; interface Clock epPortalClock = portalClock; interface Reset epPortalReset = portalReset; interface Clock epDerivedClock = derivedClock; interface Reset epDerivedReset = derivedReset; endmodule: mkPcieEndpointX7 endpackage: Pcie3EndpointX7 ================================================ FILE: bsv/Pcie3RootPortX7.bsv ================================================ // Copyright (c) 2014-2015 Quanta Research Cambridge, Inc. // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package Pcie3RootPortX7; `include "ConnectalProjectConfig.bsv" import BRAMFIFO ::*; import Clocks ::*; import Vector ::*; import BuildVector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import CFFIFO ::*; import SpecialFIFOs ::*; import ClientServer ::*; import Real ::*; import XilinxVirtex7PCIE ::*; import BUtils ::*; import Probe ::*; import ConnectalConfig::*; import ConnectalClocks ::*; import ConnectalXilinxCells ::*; import XilinxCells ::*; import PCIE ::*; import ROOTPCIEWRAPPER3 ::*; import Bufgctrl ::*; import PcieGearbox :: *; import Pipe :: *; interface PcieRootPortX7#(numeric type lanes); interface PcieRpPci_exp#(lanes) pcie; interface PcieRpUser#(lanes) user; interface PcieRpPipe#(lanes) pipe; interface PcieRpCommon#(lanes) common; interface Server#(TLPData#(16), TLPData#(16)) tlpr; interface Server#(TLPData#(16), TLPData#(16)) tlpc; interface Put#(Tuple2#(Bit#(64),Bit#(32))) interruptRequest; interface PipeOut#(Bit#(64)) regChanges; interface Clock epPcieClock; interface Reset epPcieReset; interface Clock epPortalClock; interface Reset epPortalReset; interface Clock epDerivedClock; interface Reset epDerivedReset; endinterface typedef struct { Bit #(256) data; Bool sop; Bool eop; Bit #(8) keep; TLPFirstDWBE first_be; TLPFirstDWBE last_be; } AxiStCq deriving (Bits, Eq); typedef struct { Bit #(256) data; Bit #(8) keep; Bool last; } AxiStCc deriving (Bits, Eq); typedef struct { Bit #(256) data; Bool last; Bit #(8) keep; Bit #(4) first_be; Bit #(4) last_be; } AxiStRq deriving (Bits, Eq); typedef struct { Bit #(256) data; Bool sop; Bool eop; Bit #(8) keep; Bit #(8) be; } AxiStRc deriving (Bits, Eq); function TLPData#(16) convertCQDescriptorToTLP16(CQDescriptor desc, Bit#(32) data, TLPFirstDWBE first, TLPLastDWBE last); TLPMemoryIO3DWHeader header = defaultValue; header.format = tpl_1(convertCQReqTypeToTLPFmtType(desc.reqtype)); header.pkttype = tpl_2(convertCQReqTypeToTLPFmtType(desc.reqtype)); header.tclass = desc.tclass; header.relaxed = desc.relaxed; header.nosnoop = desc.nosnoop; header.length = (desc.dwcount == 1024) ? 0 : truncate(desc.dwcount); header.reqid = desc.reqid; header.tag = desc.tag; header.lastbe = last; header.firstbe = first; header.addr = truncate(desc.address); header.data = convertDW(data); Bool is3DW = isReadReqType(desc.reqtype); Bool is3Or4DW = isReadReqType(desc.reqtype) || (desc.dwcount == 1); TLPData#(16) retval = defaultValue; retval.sof = True; retval.eof = is3Or4DW; retval.hit = (1 << pack(desc.barid)); retval.data = pack(header); retval.be = (is3DW ? 16'hFFF0 : 16'hFFFF); return retval; endfunction function TLPData#(16) convertRCDescriptorToTLP16(RCDescriptor desc, Bit#(32) data); TLPCompletionHeader header = defaultValue; header.tclass = desc.tclass; header.relaxed = desc.relaxed; header.nosnoop = desc.nosnoop; header.cmplid = desc.complid; header.tag = desc.tag; header.reqid = desc.reqid; header.poison = desc.poisoned; header.cstatus = desc.status; header.length = (desc.dwcount == 1024) ? 0 : truncate(desc.dwcount); header.bytecount = (desc.bytecount == 4096) ? 0 : truncate(desc.bytecount); header.loweraddr = truncate(desc.loweraddr); header.data = convertDW(data); Bool is3DW = (desc.dwcount == 0); Bool is3Or4DW = (desc.dwcount == 0) || (desc.dwcount == 1); TLPData#(16) retval = defaultValue; retval.sof = True; retval.eof = is3Or4DW; retval.hit = 1; // XXX retval.data = pack(header); retval.be = (is3DW ? 16'hFFF0 : 16'hFFFF); return retval; endfunction typedef struct { Bit#(32) timestamp; Bit#(8) src; Bit#(24) value; } RegChange deriving (Bits); typedef enum { Pcie3Cfg_none, Pcie3Cfg_current_speed, Pcie3Cfg_dpa_substate_change, Pcie3Cfg_err_cor_out, Pcie3Cfg_err_fatal_out, Pcie3Cfg_err_nonfatal_out, Pcie3Cfg_flr_in_process, Pcie3Cfg_function_power_state, Pcie3Cfg_function_status, Pcie3Cfg_hot_reset_out, Pcie3Cfg_link_power_state, Pcie3Cfg_ltr_enable, Pcie3Cfg_ltssm_state, Pcie3Cfg_max_payload, Pcie3Cfg_max_read_req, Pcie3Cfg_negotiated_width, Pcie3Cfg_obff_enable, Pcie3Cfg_phy_link_down, Pcie3Cfg_phy_link_status, Pcie3Cfg_pl_status_change, Pcie3Cfg_power_state_change_interrupt, Pcie3Cfg_rcb_status, Pcie3Cfg_rq_backpressure } Pcie3CfgType deriving (Bits,Eq); (* synthesize *) module mkPcieRootPortX7(PcieRootPortX7#(PcieLanes)); PCIEParams params = defaultValue; Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reset defaultResetInverted <- mkResetInverter(defaultReset, clocked_by defaultClock); PcieRp#(PcieLanes) pcie_rp <- mkPcieRp(defaultClock, defaultResetInverted); // The PCIe rootport exports full (250MHz) and half-speed (125MHz) clocks Clock pcieClock250 = pcie_rp.user_clk; Reset user_reset_n <- mkResetInverter(pcie_rp.user_reset, clocked_by pcie_rp.user_clk); Reset pcieReset250 <- mkSyncReset(5, user_reset_n, pcieClock250); ClockGenerator7Params clkgenParams = defaultValue; clkgenParams.clkin1_period = 4.000; // 250MHz clkgenParams.clkin1_period = 4.000; clkgenParams.clkin_buffer = False; clkgenParams.clkfbout_mult_f = 4.000; // 1000MHz clkgenParams.clkout0_divide_f = derivedClockPeriod; clkgenParams.clkout1_divide = round(mainClockPeriod); clkgenParams.clkout1_duty_cycle = 0.5; clkgenParams.clkout1_phase = 0.0000; ClockGenerator7 clkgen <- mkClockGenerator7(clkgenParams, clocked_by pcieClock250, reset_by pcieReset250); Clock mainClock = clkgen.clkout1; Reset mainReset <- mkSyncReset(5, pcieReset250, mainClock); Clock derivedClock = clkgen.clkout0; Reset derivedReset <- mkSyncReset(5, pcieReset250, derivedClock); Reset user_reset <- mkSyncReset(5, pcie_rp.user_reset, pcie_rp.user_clk); // FIFOS FIFOF#(AxiStCq) fAxiCq <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(AxiStRc) fAxiRc <- mkCFFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(AxiStRq) fAxiRq <- mkCFFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(AxiStCc) fAxiCc <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) fcq <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) frc <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) fcc <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) frq <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(Tuple2#(Bit#(64),Bit#(32))) intrFifo <- mkFIFOF(clocked_by pcie_rp.user_clk, reset_by user_reset_n); // Drive s_axis_rq let rq_txready = (pcie_rp.s_axis_rq.tready != 0 && fAxiRq.notEmpty); //(* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rq if (rq_txready); let info = fAxiRq.first; fAxiRq.deq; pcie_rp.s_axis_rq.tvalid(1); pcie_rp.s_axis_rq.tlast(pack(info.last)); pcie_rp.s_axis_rq.tdata(info.data); pcie_rp.s_axis_rq.tkeep(info.keep); pcie_rp.s_axis_rq.tuser({0, info.last_be, info.first_be}); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rq2 if (!rq_txready); pcie_rp.s_axis_rq.tvalid(0); pcie_rp.s_axis_rq.tlast(0); pcie_rp.s_axis_rq.tdata(0); pcie_rp.s_axis_rq.tkeep(0); pcie_rp.s_axis_rq.tuser(0); endrule Reg#(Bit#(16)) rqBackpressureCycles <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bit#(16)) rqBackpressureCount <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bool) rqBackpressure <- mkReg(False, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bit#(32)) rqBackpressureCountSum <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bit#(32)) rqBackpressureEvents <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_rqBackpressureCycles <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_rqBackpressureCount <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_rqBackpressure <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); Probe#(Bit#(32)) probe_rqBackpressureCountSum <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); Probe#(Bit#(32)) probe_rqBackpressureEvents <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_fAxiRqNotEmpty <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_SAxsiRqTReady <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); rule rltready; probe_fAxiRqNotEmpty <= fAxiRq.notEmpty(); probe_SAxsiRqTReady <= pcie_rp.s_axis_rq.tready; endrule rule rlBackpressureEnter if (!rqBackpressure); if (pcie_rp.s_axis_rq.tready == 0 && fAxiRq.notEmpty) begin rqBackpressure <= True; rqBackpressureCycles <= 0; probe_rqBackpressure <= True; probe_rqBackpressureCycles <= 0; end endrule rule rlBackpressureExit if (rqBackpressure); rqBackpressureCycles <= rqBackpressureCycles + 1; probe_rqBackpressureCycles <= rqBackpressureCycles + 1; if (pcie_rp.s_axis_rq.tready != 0 || !fAxiRq.notEmpty) begin rqBackpressure <= False; let count = rqBackpressureCycles; count[15] = ~rqBackpressureCount[15]; if (count > 5) rqBackpressureCount <= count; rqBackpressureCountSum <= rqBackpressureCountSum + extend(count); rqBackpressureEvents <= rqBackpressureEvents + 1; probe_rqBackpressure <= False; probe_rqBackpressureCount <= count; probe_rqBackpressureCountSum <= rqBackpressureCountSum + extend(count); probe_rqBackpressureEvents <= rqBackpressureEvents + 1; end else begin probe_rqBackpressure <= True; end endrule // Drive s_axis_cc let cc_txready = (pcie_rp.s_axis_cc.tready != 0 && fAxiCc.notEmpty); //(* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cc if (cc_txready); let info = fAxiCc.first; fAxiCc.deq; $display("drive axi_cc, data: %h, keep: %h, last: %h", info.data, info.keep, info.last); pcie_rp.s_axis_cc.tvalid(1); pcie_rp.s_axis_cc.tlast(pack(info.last)); pcie_rp.s_axis_cc.tdata(info.data); pcie_rp.s_axis_cc.tkeep(info.keep); pcie_rp.s_axis_cc.tuser(0); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cc2 if (!cc_txready); pcie_rp.s_axis_cc.tvalid(0); pcie_rp.s_axis_cc.tlast(0); pcie_rp.s_axis_cc.tdata(0); pcie_rp.s_axis_cc.tkeep(0); pcie_rp.s_axis_cc.tuser(0); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rc_ready; pcie_rp.m_axis_rc.tready (duplicate (pack (fAxiRc.notFull))); endrule // Drive m_axis_rc (* fire_when_enabled *) rule sink_axi_rc if (pcie_rp.m_axis_rc.tvalid != 0 && fAxiRc.notFull); let rc = AxiStRc {data:pcie_rp.m_axis_rc.tdata, sop: unpack (pcie_rp.m_axis_rc.tuser [32]), // tuser.is_sof_0 eop: unpack (pcie_rp.m_axis_rc.tlast), keep:pcie_rp.m_axis_rc.tkeep, be: truncate (pcie_rp.m_axis_rc.tuser [31:0])}; // tuser.byte_en fAxiRc.enq (rc); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cq_ready; pcie_rp.m_axis_cq.tready (duplicate (pack (fAxiCq.notFull))); endrule (* fire_when_enabled *) rule sink_axi_cq if (pcie_rp.m_axis_cq.tvalid != 0 && fAxiCq.notFull); let cq = AxiStCq {data: pcie_rp.m_axis_cq.tdata, sop: unpack (pcie_rp.m_axis_cq.tuser [40]), // tuser.sop eop: unpack (pcie_rp.m_axis_cq.tlast), keep: pcie_rp.m_axis_cq.tkeep, first_be: pcie_rp.m_axis_cq.tuser [3:0], // tuser.first_be, last_be: pcie_rp.m_axis_cq.tuser [7:4]}; // tuser.last_be fAxiCq.enq (cq); endrule // CQ. CQDescriptor cq_desc = unpack(fAxiCq.first.data [127:0]); rule rl_cq_wr_header (fAxiCq.first.sop && ((cq_desc.reqtype == MEMORY_WRITE) || (cq_desc.reqtype == IO_WRITE))); Bit#(32) data = fAxiCq.first.data[159:128]; // get data; TLPData#(16) tlp16 = convertCQDescriptorToTLP16(cq_desc, data, fAxiCq.first.first_be, fAxiCq.first.last_be); $display("cq_desc.reqtype=%h", cq_desc.reqtype); // enqueue? fcq.enq(tlp16); fAxiCq.deq; endrule // Write data payload, no data remaining rule rl_cq_wr_payload((!fAxiCq.first.sop)); fAxiCq.deq; endrule // Write data payload, 1 to 3 DWs remaining // Write data payload, 4 or more DWs remaining rule rl_cq_rd_header (fAxiCq.first.sop && ((cq_desc.reqtype == MEMORY_READ) || (cq_desc.reqtype == IO_READ))); Bit#(32) data = 0; TLPData#(16) tlp16 = convertCQDescriptorToTLP16(cq_desc, data, fAxiCq.first.first_be, fAxiCq.first.last_be); $display("rl_cq_rd_header: cq_desc = %16x", cq_desc); fcq.enq(tlp16); fAxiCq.deq; endrule // RC. Reg#(DWCount) rc_dwcount <- mkRegU(clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bool) rc_even <- mkReg(True, clocked_by pcie_rp.user_clk, reset_by user_reset_n); rule rl_rc_header (fAxiRc.first.sop && rc_even); RCDescriptor rc_desc = unpack(fAxiRc.first.data [95:0]); // RC descriptor always 96 bytes with first data word in bits 127:96 Bit#(32) data = byteSwap(fAxiRc.first.data[127:96]); TLPData#(16) tlp16 = convertRCDescriptorToTLP16(rc_desc, data); rc_dwcount <= (rc_desc.dwcount == 0) ? 0 : rc_desc.dwcount - 1; frc.enq(tlp16); let even = False; if (rc_desc.dwcount == 0 || rc_desc.dwcount == 1) begin fAxiRc.deq; even = True; end rc_even <= even; endrule rule rl_rc_data ((!rc_even || !(fAxiRc.first.sop)) && (rc_dwcount != 0)); Bit#(16) be16; case (rc_dwcount) 1: be16 = 16'hF000; 2: be16 = 16'hFF00; 3: be16 = 16'hFFF0; default: be16 = 16'hFFFF; endcase let last = (rc_dwcount <= 4); let dwcount = rc_dwcount - 4; if (last) dwcount = 0; let data = (rc_even) ? fAxiRc.first.data[127:0]: fAxiRc.first.data[255:128]; TLPData#(16) tlp16 = TLPData{sof: False, eof: last, hit: 0, be: be16, data: pack(data)}; frc.enq(tlp16); if (last || !rc_even) begin fAxiRc.deq; end rc_dwcount <= dwcount; rc_even <= (last) ? True : !rc_even; endrule Reg#(DWCount) cc_dwcount <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(TLPData#(16)) fcc_tlps <- mkFIFOF (clocked_by pcie_rp.user_clk, reset_by user_reset_n); // CC. rule get_cc_tlps; let tlp <- toGet(fcc).get; fcc_tlps.enq(tlp); endrule rule rl_cc_header(fcc_tlps.first.sof); match { .cc_desc, .dw} = convertTLP16ToCCDescriptor(fcc_tlps.first); cc_dwcount <= cc_desc.dwcount - 1; fAxiCc.enq(AxiStCc {data: zeroExtend({dw, pack(cc_desc)[95:0]}), last: fcc_tlps.first.eof, keep: 8'h0F}); fcc_tlps.deq; endrule rule rl_cc_data((!fcc_tlps.first.sof) && (cc_dwcount != 0)); Bit#(256) x = zeroExtend(fcc_tlps.first.data); //FIXME fAxiCc.enq(AxiStCc {data: {x}, last: cc_dwcount <= 4, keep: (cc_dwcount == 3) ? 8'h0F : 8'hFF}); fcc_tlps.deq; endrule // RQ. FIFOF#(TLPData#(16)) frq_tlps <- mkFIFOF (clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bit#(4)) rq_first_be <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bit#(4)) rq_last_be <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(Bool) rq_even <- mkRegU(clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(DWCount) rq_dwcount <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); Reg#(AxiStRq) rq_rq <- mkRegU(clocked_by pcie_rp.user_clk, reset_by user_reset_n); rule rl_rq_tlps; let tlp <- toGet(frq).get; frq_tlps.enq(tlp); endrule rule rl_rq_header if (frq_tlps.first.sof); TLPData#(16) tlp <- toGet(frq_tlps).get(); match { .rq_desc, .first_be, .last_be, .mdata} = convertTLP16ToRQDescriptor(tlp); let dwcount = ((rq_desc.reqtype == MEMORY_WRITE) ? rq_desc.dwcount : 0); rq_dwcount <= dwcount; rq_even <= False; rq_first_be <= first_be; rq_last_be <= last_be; let last = (rq_desc.reqtype == MEMORY_WRITE) ? (dwcount <= 4) : True; let rq = AxiStRq {data: zeroExtend(pack(rq_desc)), //FIXME: last: last, keep: 8'h0F, first_be: first_be, last_be: last_be}; if (rq_desc.reqtype == MEMORY_WRITE) rq_rq <= rq; else fAxiRq.enq(rq); endrule // more data rule rl_rq_data if (rq_dwcount != 0); TLPData#(16) tlp <- toGet(frq_tlps).get(); let rq = rq_rq; let last = (rq_dwcount <= 4); let dwcount = rq_dwcount - 4; Bit#(8) keep; if (last) dwcount = 0; if (rq_even) begin rq.data[127:0] = tlp.data; case (rq_dwcount) 1: keep = 8'h01; 2: keep = 8'h03; 3: keep = 8'h07; default: keep = 8'h0f; endcase end else begin rq.data[255:128] = tlp.data; case (rq_dwcount) 1: keep = 8'h1f; 2: keep = 8'h3f; 3: keep = 8'h7f; default: keep = 8'hff; endcase end rq.last = last; rq.first_be = rq_first_be; rq.last_be = rq_last_be; rq.keep = keep; if (!rq_even || last) fAxiRq.enq(rq); if (rq_even) rq_rq <= rq; rq_dwcount <= dwcount; rq_even <= (last) ? False : !rq_even; endrule FIFO#(Bool) intrMutex <- mkFIFO1(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_current_speed <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_dpa_substate_change <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_err_cor_out <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_err_fatal_out <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_err_nonfatal_out <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_flr_in_process <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_function_power_state <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_function_status <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_hot_reset_out <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_link_power_state <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_ltr_enable <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_ltssm_state <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_max_payload <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_max_read_req <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_negotiated_width <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_obff_enable <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_phy_link_down <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_phy_link_status <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_pl_status_change <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_power_state_change_interrupt <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_rcb_status <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_tph_requester_enable <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_tph_st_mode <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_rq_seq_num <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); let probe_rq_seq_num_vld <- mkProbe(clocked_by pcie_rp.user_clk, reset_by user_reset_n); rule rl_drive_probes; probe_current_speed <= pcie_rp.cfg.current_speed; probe_dpa_substate_change <= pcie_rp.cfg.dpa_substate_change; probe_err_cor_out <= pcie_rp.cfg.err_cor_out; probe_err_fatal_out <= pcie_rp.cfg.err_fatal_out; probe_err_nonfatal_out <= pcie_rp.cfg.err_nonfatal_out; probe_flr_in_process <= pcie_rp.cfg.flr_in_process; probe_function_power_state <= pcie_rp.cfg.function_power_state; probe_function_status <= pcie_rp.cfg.function_status; probe_hot_reset_out <= pcie_rp.cfg.hot_reset_out; probe_link_power_state <= pcie_rp.cfg.link_power_state; probe_ltr_enable <= pcie_rp.cfg.ltr_enable; probe_ltssm_state <= pcie_rp.cfg.ltssm_state; probe_max_payload <= pcie_rp.cfg.max_payload; probe_max_read_req <= pcie_rp.cfg.max_read_req; probe_negotiated_width <= pcie_rp.cfg.negotiated_width; probe_obff_enable <= pcie_rp.cfg.obff_enable; probe_phy_link_down <= pcie_rp.cfg.phy_link_down; probe_phy_link_status <= pcie_rp.cfg.phy_link_status; probe_pl_status_change <= pcie_rp.cfg.pl_status_change; probe_power_state_change_interrupt <= pcie_rp.cfg.power_state_change_interrupt; probe_rcb_status <= pcie_rp.cfg.rcb_status; probe_tph_requester_enable <= pcie_rp.cfg.tph_requester_enable; probe_tph_st_mode <= pcie_rp.cfg.tph_st_mode; probe_rq_seq_num <= pcie_rp.pcie.rq_seq_num; probe_rq_seq_num_vld <= pcie_rp.pcie.rq_seq_num_vld; endrule Reg#(Bit#(32)) cyclesReg <- mkReg(0, clocked_by pcie_rp.user_clk, reset_by user_reset_n); rule rl_cycles; cyclesReg <= cyclesReg + 1; endrule module mkChangeSource#(Tuple2#(Pcie3CfgType,Bit#(24)) tpl)(PipeOut#(RegChange)); match { .src, .v } = tpl; let snapshot <- mkReg(0); let changeFifo <- mkFIFOF1(); let probe_snapshot <- mkProbe(); rule rl_update if (v != snapshot); if (changeFifo.notFull) begin changeFifo.enq(RegChange { timestamp: cyclesReg, src: extend(pack(src)), value: extend(v) }); snapshot <= v; probe_snapshot <= v; end endrule return toPipeOut(changeFifo); endmodule `ifndef FOO Vector#(22,Tuple2#(Pcie3CfgType,Bit#(24))) changeValues = vec(tuple2(Pcie3Cfg_current_speed, extend(pcie_rp.cfg.current_speed)), tuple2(Pcie3Cfg_dpa_substate_change, extend(pcie_rp.cfg.dpa_substate_change)), tuple2(Pcie3Cfg_err_cor_out, extend(pcie_rp.cfg.err_cor_out)), tuple2(Pcie3Cfg_err_fatal_out, extend(pcie_rp.cfg.err_fatal_out)), tuple2(Pcie3Cfg_err_nonfatal_out, extend(pcie_rp.cfg.err_nonfatal_out)), tuple2(Pcie3Cfg_flr_in_process, extend(pcie_rp.cfg.flr_in_process)), tuple2(Pcie3Cfg_function_power_state, extend(pcie_rp.cfg.function_power_state)), tuple2(Pcie3Cfg_function_status, extend(pcie_rp.cfg.function_status)), tuple2(Pcie3Cfg_hot_reset_out, extend(pcie_rp.cfg.hot_reset_out)), tuple2(Pcie3Cfg_link_power_state, extend(pcie_rp.cfg.link_power_state)), tuple2(Pcie3Cfg_ltr_enable, extend(pcie_rp.cfg.ltr_enable)), tuple2(Pcie3Cfg_ltssm_state, extend(pcie_rp.cfg.ltssm_state)), tuple2(Pcie3Cfg_max_payload, extend(pcie_rp.cfg.max_payload)), tuple2(Pcie3Cfg_max_read_req, extend(pcie_rp.cfg.max_read_req)), tuple2(Pcie3Cfg_negotiated_width, extend(pcie_rp.cfg.negotiated_width)), tuple2(Pcie3Cfg_obff_enable, extend(pcie_rp.cfg.obff_enable)), tuple2(Pcie3Cfg_phy_link_down, extend(pcie_rp.cfg.phy_link_down)), tuple2(Pcie3Cfg_phy_link_status, extend(pcie_rp.cfg.phy_link_status)), tuple2(Pcie3Cfg_pl_status_change, extend(pcie_rp.cfg.pl_status_change)), tuple2(Pcie3Cfg_power_state_change_interrupt, extend(pcie_rp.cfg.power_state_change_interrupt)), tuple2(Pcie3Cfg_rcb_status, extend(pcie_rp.cfg.rcb_status)), tuple2(Pcie3Cfg_rq_backpressure, extend(rqBackpressureCount))); let change_pipes <- mapM(mkChangeSource, changeValues, clocked_by pcie_rp.user_clk, reset_by user_reset_n); FunnelPipe#(1,22,RegChange,3) changePipe <- mkFunnelPipesPipelined(change_pipes, clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(RegChange) changeFifo <- mkSizedBRAMFIFOF(128, clocked_by pcie_rp.user_clk, reset_by user_reset_n); mkConnection(changePipe[0], toPipeIn(changeFifo), clocked_by pcie_rp.user_clk, reset_by user_reset_n); `else let cs <- mkChangeSource(tuple2(Pcie3Cfg_rq_backpressure, extend(rqBackpressureCount)), clocked_by pcie_rp.user_clk, reset_by user_reset_n); FIFOF#(RegChange) changeFifo <- mkSizedBRAMFIFOF(128, clocked_by pcie_rp.user_clk, reset_by user_reset_n); mkConnection(cs, toPipeIn(changeFifo), clocked_by pcie_rp.user_clk, reset_by user_reset_n); `endif rule rl_drive_cfg_status_if; pcie_rp.cfg.config_space_enable(1); pcie_rp.cfg.dsn(64'hf001ba7700000000); pcie_rp.cfg.ds_bus_number(0); pcie_rp.cfg.ds_device_number(0); pcie_rp.cfg.ds_port_number(0); pcie_rp.cfg.err_cor_in(0); pcie_rp.cfg.err_uncor_in(0); pcie_rp.cfg.flr_done(0); pcie_rp.cfg.hot_reset_in(0); pcie_rp.cfg.link_training_enable(1); pcie_rp.cfg.per_function_number(0); pcie_rp.cfg.per_function_output_request(0); pcie_rp.cfg.power_state_change_ack(0); pcie_rp.cfg.subsys_vend_id(16'h1be8); pcie_rp.cfg.vf_flr_done(0); pcie_rp.pcie.cq_np_req(1); pcie_rp.cfg_req_pm_transition.l23_ready(0); endrule // The PCIE rootport is processing Gen3 descriptors at 250MHz. The // AXI bridge is accepting TLPData#(16)s at 250 MHz. The // conversion uses half of Gen3 descriptor. //mkConnection(tlp8, gb.tlp, clocked_by portalClock, reset_by portalReset); let portalClock = (mainClockPeriod == pcieClockPeriod) ? pcieClock250 : mainClock; let portalReset = (mainClockPeriod == pcieClockPeriod) ? pcieReset250 : mainReset; interface Server tlpr; interface request = toPut(frq); interface response = toGet(frc); endinterface // Requests from other PCIe devices interface Server tlpc; interface request = toPut(fcc); interface response = toGet(fcq); endinterface interface interruptRequest = toPut(intrFifo); interface pcie = pcie_rp.pci_exp; interface Pcie3wrapUser user = pcie_rp.user; interface PcieRpPipe pipe = pcie_rp.pipe; interface PcieRpCommon common= pcie_rp.common; interface regChanges = mapPipe(pack, toPipeOut(changeFifo)); interface Clock epPcieClock = pcieClock250; interface Reset epPcieReset = pcieReset250; interface Clock epPortalClock = portalClock; interface Reset epPortalReset = portalReset; interface Clock epDerivedClock = derivedClock; interface Reset epDerivedReset = derivedReset; endmodule: mkPcieRootPortX7 endpackage: Pcie3RootPortX7 ================================================ FILE: bsv/PcieCsr.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector :: *; import BRAM :: *; import FIFOF :: *; import BRAMFIFO :: *; import GetPut :: *; import Connectable :: *; import PCIE :: *; import Clocks :: *; import PcieTracer :: *; import ConnectalMemTypes :: *; import AddressGenerator::*; import Pipe :: *; `include "ConnectalProjectConfig.bsv" // starting word of MSIX config registers `define msix_base 1024 // An MSIX table entry, as defined in the PCIe spec interface MSIX_Entry; interface Reg#(Bit#(32)) addr_lo; interface Reg#(Bit#(32)) addr_hi; interface Reg#(Bit#(32)) msg_data; interface Reg#(Bool) masked; endinterface interface ReadOnly_MSIX_Entry; interface ReadOnly#(Bit#(32)) addr_lo; interface ReadOnly#(Bit#(32)) addr_hi; interface ReadOnly#(Bit#(32)) msg_data; interface ReadOnly#(Bool) masked; endinterface function ReadOnly_MSIX_Entry toReadOnlyMsixEntry(MSIX_Entry msix); return (interface ReadOnly_MSIX_Entry; interface ReadOnly addr_lo = regToReadOnly(msix.addr_lo); interface ReadOnly addr_hi = regToReadOnly(msix.addr_hi); interface ReadOnly msg_data = regToReadOnly(msix.msg_data); interface ReadOnly masked = regToReadOnly(msix.masked); endinterface); endfunction // control and status registers accessed from PCIe interface PcieControlAndStatusRegs; interface PhysMemSlave#(32,32) memSlave; interface Vector#(16,ReadOnly_MSIX_Entry) msixEntry; interface PipeIn#(Bit#(64)) changes; interface TlpTraceClient traceClient; endinterface: PcieControlAndStatusRegs // This module encapsulates all of the logic for instantiating and // accessing the control and status registers. It defines the // registers, the address map, and how the registers respond to reads // and writes. (* synthesize *) module mkPcieControlAndStatusRegs(PcieControlAndStatusRegs); // Utility for module creating all of the storage for a single MSIX // table entry module mkMSIXEntry(MSIX_Entry); Reg#(Bit#(32)) _addr_lo <- mkReg(0); Reg#(Bit#(32)) _addr_hi <- mkReg(0); Reg#(Bit#(32)) _msg_data <- mkReg(0); Reg#(Bool) _masked <- mkReg(True); interface addr_lo = _addr_lo; interface addr_hi = _addr_hi; interface msg_data = _msg_data; interface masked = _masked; endmodule: mkMSIXEntry // Registers and their default values Vector#(16,MSIX_Entry) msix_entry <- replicateM(mkMSIXEntry); Reg#(TimestampedTlpData) pcieTraceBramResponse <- mkReg(unpack(0)); // Function to return a one-word slice of the tlpTraceBramResponse function Bit#(32) tlpTraceBramResponseSlice(Reg#(TimestampedTlpData) data, Integer i); Bit#(8) i8 = fromInteger(i); begin Bit#(TMul#(12,32)) v = extend(pack(data)); return v[31 + (i8*32) : 0 + (i8*32)]; end endfunction FIFOF#(BRAMRequest#(Bit#(TAdd#(TlpTraceAddrSize,1)),TimestampedTlpData)) bramRequestFifo <- mkFIFOF(); FIFOF#(TimestampedTlpData) bramResponseFifo <- mkFIFOF(); Reg#(Bool) tlpTracingReg <- mkReg(True); Reg#(Bit#(TlpTraceAddrSize)) tlpTraceLimitReg <- mkReg(0); Reg#(Bit#(TlpTraceAddrSize)) tlpTraceBramWrAddrReg <- mkReg(0); FIFOF#(Bit#(64)) changeFifo <- mkSizedBRAMFIFOF(256); // State used to actually service read and write requests rule brmMuxResponse; let v <- toGet(bramResponseFifo).get(); pcieTraceBramResponse <= v; endrule AddressGenerator#(16,32) csrRag <- mkAddressGenerator; AddressGenerator#(16,32) csrWag <- mkAddressGenerator; FIFOF#(MemData#(32)) readResponseFifo <- mkFIFOF(); FIFOF#(MemData#(32)) writeDataFifo <- mkFIFOF(); FIFOF#(Bit#(MemTagSize)) writeDoneFifo <- mkFIFOF(); FIFOF#(AddrBeat#(16)) csrRagBeatFifo <- mkFIFOF(); FIFOF#(Bool) csrIsMsixAddrFifo <- mkFIFOF(); FIFOF#(Bit#(2)) csrOneHotFifo000 <- mkFIFOF(); FIFOF#(Bit#(29)) csrOneHotFifo774 <- mkFIFOF(); FIFOF#(Bit#(2)) csrOneHotFifo992 <- mkFIFOF(); FIFOF#(AddrBeat#(16)) csrWagBeatFifo <- mkFIFOF(); FIFOF#(Bool) csrWagIsMsixAddrFifo <- mkFIFOF(); FIFOF#(Bit#(8)) csrWagOneHotFifo768 <- mkFIFOF(); FIFOF#(Bit#(3)) csrWagOneHotFifo792 <- mkFIFOF(); rule readDataRule; let beat <- csrRag.addrBeat.get(); let addr = beat.addr >> 2; // word address Bit#(32) data = 0; let modaddr = (addr % 8192); let msixaddr = modaddr - `msix_base; csrRagBeatFifo.enq(beat); csrIsMsixAddrFifo.enq(msixaddr >= 0 && msixaddr <= 63); Bit#(1024) onehot = (1 << addr[9:0]); csrOneHotFifo000.enq(onehot[1:0]); csrOneHotFifo774.enq(onehot[802:774]); csrOneHotFifo992.enq(onehot[993:992]); endrule rule readDataRule2; let beat <- toGet(csrRagBeatFifo).get(); let isMsixAddr <- toGet(csrIsMsixAddrFifo).get(); let addr = beat.addr >> 2; // word address Bit#(32) data = 32'hbad0add0; let modaddr = (addr % 8192); let msix_base = `msix_base; let msixaddr = modaddr - msix_base; let oneHotDecode000 <- toGet(csrOneHotFifo000).get(); let oneHotDecode774 <- toGet(csrOneHotFifo774).get(); let oneHotDecode992 <- toGet(csrOneHotFifo992).get(); if (isMsixAddr) begin begin let groupaddr = (msixaddr / 4); //******************************** msix_base has to match CONFIG.MXIx_Table_Offset in scripts/connectal-synth-pcie.tcl case (msixaddr % 4) 0: data = msix_entry[groupaddr].addr_lo; 1: data = msix_entry[groupaddr].addr_hi; 2: data = msix_entry[groupaddr].msg_data; 3: data = {'0, pack(msix_entry[groupaddr].masked)}; // vector control default: data = 32'hbad0add0; //******************************** end of MSIX Table endcase end end else begin // board identification if (oneHotDecode000[0] == 1) data = 32'h65756c42; // Blue if (oneHotDecode000[1] == 1) data = 32'h63657073; // spec if (oneHotDecode774[774-774] == 1) data = fromInteger(2**valueOf(TAdd#(TlpTraceAddrSize,1))); if (oneHotDecode774[775-774] == 1) data = (tlpTracingReg ? 1 : 0); if (oneHotDecode774[776-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 0); if (oneHotDecode774[777-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 1); if (oneHotDecode774[778-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 2); if (oneHotDecode774[779-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 3); if (oneHotDecode774[780-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 4); if (oneHotDecode774[781-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 5); if (oneHotDecode774[792-774] == 1) data = extend(tlpTraceBramWrAddrReg); if (oneHotDecode774[794-774] == 1) data = extend(tlpTraceLimitReg); if (oneHotDecode774[795-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 6); if (oneHotDecode774[796-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 7); if (oneHotDecode774[797-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 8); if (oneHotDecode774[798-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 9); if (oneHotDecode774[799-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 10); if (oneHotDecode774[800-774] == 1) data = tlpTraceBramResponseSlice(pcieTraceBramResponse, 11); if (oneHotDecode774[801-774] == 1) data = (changeFifo.notEmpty()) ? (changeFifo.first()[31:0]) : 0; if (oneHotDecode774[802-774] == 1) data = (changeFifo.notEmpty()) ? (changeFifo.first()[63:32]) : 0; //******************************** msix_base has to match CONFIG.MXIx_PBA_Offset in scripts/connectal-synth-pcie.tcl // 16-bit MSIx pending bit field if (oneHotDecode992[992-992] == 1) data = '0; // PBA structure (low) if (oneHotDecode992[993-992] == 1) data = '0; // PBA structure (high) //******************************** end of PBA Table end if (oneHotDecode774[802-774] == 1 && changeFifo.notEmpty()) changeFifo.deq(); readResponseFifo.enq(MemData { data: data, tag: beat.tag, last: beat.last }); endrule rule writeDataRule; let beat <- csrWag.addrBeat.get(); let addr = beat.addr >> 2; // word address let modaddr = (addr % 8192); let msixaddr = modaddr - `msix_base; csrWagBeatFifo.enq(beat); csrWagIsMsixAddrFifo.enq(msixaddr >= 0 && msixaddr <= 63); Bit#(1024) onehot = (1 << addr[9:0]); $display("addr: %h", addr); csrWagOneHotFifo768.enq(onehot[775:768]); csrWagOneHotFifo792.enq(onehot[794:792]); endrule rule writeDataRule2; let memData <- toGet(writeDataFifo).get(); let dword = memData.data; $display("data: %h, last: %h, tag: %h", dword, memData.last, memData.tag); let beat <- toGet(csrWagBeatFifo).get(); let isMsixAddr <- toGet(csrWagIsMsixAddrFifo).get(); let addr = beat.addr >> 2; // word address let modaddr = (addr % 8192); let msix_base = `msix_base; let msixaddr = modaddr - msix_base; let oneHotDecode768 <- toGet(csrWagOneHotFifo768).get(); let oneHotDecode792 <- toGet(csrWagOneHotFifo792).get(); if (isMsixAddr) begin let groupaddr = (msixaddr / 4); //******************************** area referenced from xilinx_x7_pcie_wrapper.v case (msixaddr % 4) 0: msix_entry[groupaddr].addr_lo <= (dword & 32'hfffffffc); 1: msix_entry[groupaddr].addr_hi <= dword; 2: msix_entry[groupaddr].msg_data <= dword; 3: msix_entry[groupaddr].masked <= unpack(dword[0]); endcase end else begin if (oneHotDecode768[775-768] == 1) tlpTracingReg <= (dword != 0) ? True : False; if (oneHotDecode768[768-768] == 1) bramRequestFifo.enq(BRAMRequest{ write: False, responseOnWrite: False, address: truncate(dword), datain: ?}); if (oneHotDecode792[792-792] == 1) tlpTraceBramWrAddrReg <= truncate(dword); if (oneHotDecode792[794-792] == 1) tlpTraceLimitReg <= truncate(dword); end if (beat.last) writeDoneFifo.enq(beat.tag); endrule interface PhysMemSlave memSlave; interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(32,32) req); csrRag.request.put(PhysMemRequest { addr: truncate(req.addr), burstLen: req.burstLen, tag: req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); endmethod endinterface interface Get readData = toGet(readResponseFifo); endinterface: read_server interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(32,32) req); $display("csrWag Request, addr=%h, burstLen=%h, tag=%h", req.addr, req.burstLen, req.tag); csrWag.request.put(PhysMemRequest { addr: truncate(req.addr), burstLen: req.burstLen, tag: req.tag `ifdef BYTE_ENABLES , firstbe: req.firstbe, lastbe: req.lastbe `endif }); endmethod endinterface interface Put writeData = toPut(writeDataFifo); interface Get writeDone = toGet(writeDoneFifo); endinterface: write_server endinterface interface changes = toPipeIn(changeFifo); interface TlpTraceClient traceClient; interface Reg tlpTracing = tlpTracingReg; interface Reg tlpTraceLimit = tlpTraceLimitReg; interface Reg tlpTraceBramWrAddr = tlpTraceBramWrAddrReg; interface BRAMClient bramClient; interface Get request = toGet(bramRequestFifo); interface Put response = toPut(bramResponseFifo); endinterface: bramClient endinterface: traceClient interface Vector msixEntry = map(toReadOnlyMsixEntry, msix_entry); endmodule: mkPcieControlAndStatusRegs ================================================ FILE: bsv/PcieEndpointS5.bsv ================================================ // Copyright (c) 2014 Cornell University // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package PcieEndpointS5; import ConnectalConfig ::*; import Clocks ::*; import Vector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import SpecialFIFOs ::*; import ClientServer ::*; import Real ::*; import PCIE ::*; `include "ConnectalProjectConfig.bsv" `ifdef BOARD_de5 import PS5LIB ::*; `elsif BOARD_htg4 import PS4LIB ::*; `endif (* always_ready, always_enabled *) interface PciewrapPci_exp#(numeric type lanes); (* prefix="", result="tx_p" *) method Bit#(lanes) tx_p(); (* prefix="", result="rx_p" *) method Action rx_p(Bit#(lanes) rx_p); endinterface (* always_ready, always_enabled *) interface PciewrapUser#(numeric type lanes); interface Clock clk_out; endinterface (* always_ready, always_enabled *) interface PciewrapCfg#(numeric type lanes); method Bit#(8) bus_number(); method Bit#(5) device_number(); method Bit#(3) function_number(); endinterface //////////////////////////////////////////////////////////////////////////////// /// Interfaces //////////////////////////////////////////////////////////////////////////////// interface PcieEndpointS5#(numeric type lanes); interface PciewrapPci_exp#(lanes) pcie; interface PciewrapUser#(lanes) user; interface Server#(TLPData#(16), TLPData#(16)) tlp; interface Clock epPcieClock; interface Reset epPcieReset; interface Clock epPortalClock; interface Reset epPortalReset; interface Clock epDerivedClock; interface Reset epDerivedReset; method PciId device; endinterface typedef struct { Bit#(1) sop; Bit#(1) eop; Bit#(7) hit; Bit#(bytes) be; Bit#(TMul#(bytes, 8)) data; } AvalonStRx#(type bytes) deriving (Bits, Eq); typedef struct { Bit#(1) sop; Bit#(1) eop; Bit#(bytes) be; Bit#(TMul#(bytes, 8)) data; } AvalonStTx#(type bytes) deriving (Bits, Eq); (* synthesize *) module mkPcieEndpointS5#(Clock clk_100MHz, Clock clk_50MHz, Reset perst_n)(PcieEndpointS5#(PcieLanes)); PCIEParams params = defaultValue; Clock default_clock <- exposeCurrentClock; Reset default_reset <- exposeCurrentReset; Reset reset_high <- invertCurrentReset; Reset npor = perst_n; //No soft reset signal from Application `ifdef BOARD_de5 PcieWrap#(12, 32, 128) pcie_ep <- mkPcieS5Wrap(clk_100MHz, clk_50MHz, npor, perst_n); `elsif BOARD_htg4 PcieWrap#(12, 32, 128) pcie_ep <- mkPcieS4Wrap(clk_100MHz, clk_50MHz, clk_100MHz, npor, perst_n); `endif Clock core_clk = pcie_ep.coreclkout_hip; Reset core_reset = pcie_ep.core_reset; Reset core_resetn <- mkResetInverter(pcie_ep.core_reset, clocked_by core_clk); Reg#(PciId) deviceReg <- mkReg(defaultValue, clocked_by core_clk, reset_by noReset); FIFOF#(AvalonStTx#(16)) fAvalonStTx <- mkBypassFIFOF(clocked_by core_clk, reset_by noReset); FIFOF#(AvalonStRx#(16)) fAvalonStRx <- mkBypassFIFOF(clocked_by core_clk, reset_by noReset); let txready = (pcie_ep.tx_st.ready != 0 && fAvalonStTx.notEmpty); function Bit#(2) getTxStEmpty (Bit#(16) be); if (be == 16'h000f || be == 16'h00ff) begin return 2'b1; end else begin return 2'b0; end endfunction rule drive_avalon_tx if (txready); let info = fAvalonStTx.first; fAvalonStTx.deq; pcie_ep.tx_st.valid(1); pcie_ep.tx_st.sop(info.sop); pcie_ep.tx_st.eop(info.eop); let txStEmpty = getTxStEmpty(info.be); `ifdef BOARD_de5 pcie_ep.tx_st.empty(txStEmpty); `elsif BOARD_htg4 pcie_ep.tx_st.empty(txStEmpty[0]); `endif pcie_ep.tx_st.err(0); pcie_ep.tx_st.data(info.data); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_avalon_tx2 if (!txready); pcie_ep.tx_st.valid(0); pcie_ep.tx_st.sop(0); pcie_ep.tx_st.eop(0); pcie_ep.tx_st.empty(0); pcie_ep.tx_st.err(0); pcie_ep.tx_st.data(0); endrule (* fire_when_enabled *) rule sink_avalon_rx if (pcie_ep.rx_st.valid != 0); AvalonStRx#(16) beat; beat.sop = pcie_ep.rx_st.sop; beat.eop = pcie_ep.rx_st.eop; beat.be = pcie_ep.rx_st.be; // bar[7] is reserved for endpoints. beat.hit = pcie_ep.rx_st.bar[6:0]; // 128-bit interface // when rx_st_empty==1, rx_st_data[63:0] are valid if (pcie_ep.rx_st.empty[0] == 1 && pcie_ep.rx_st.eop == 1) begin if (pcie_ep.rx_st.be == 16'h000f) begin beat.data = {96'h0, pcie_ep.rx_st.data[31:0]}; end else if (pcie_ep.rx_st.be == 16'h00ff) begin beat.data = {64'h0, pcie_ep.rx_st.data[63:0]}; end else begin beat.data = pcie_ep.rx_st.data; end end // else, rx_st_data[127:0] are valid else begin beat.data = pcie_ep.rx_st.data; end // 256-bit interface requires a more complex decoder. fAvalonStRx.enq(beat); endrule rule pertick1; pcie_ep.rx_st.ready(pack(fAvalonStRx.notFull)); pcie_ep.hip_rst.core_ready(pcie_ep.hip_rst.serdes_pll_locked); endrule rule every1; pcie_ep.hip_ctrl.test_in({26'h2, 1'b1, 5'b01000}); endrule rule capture_deviceid; deviceReg <= PciId {bus: pcie_ep.tl_cfg.bus_number, dev: pcie_ep.tl_cfg.dev_number, func: 0}; endrule rule pulldown_msi; pcie_ep.msi.msi_num(0); pcie_ep.msi.msi_req(0); pcie_ep.msi.msi_tc(0); pcie_ep.msi.int_sts(0); endrule rule pulldown_cpl; pcie_ep.tl_cfg.cpl_pending(0); pcie_ep.tl_cfg.cpl_err(0); endrule rule unused_non_posted_signal; pcie_ep.rx_st.mask(0); endrule // The PCIE endpoint is processing TLPData#(16)s at 125MHz. The // AXI bridge is accepting TLPData#(16)s at 125 MHz. For gen1 and // gen2, there is no need for gearbox conversion. // coreclkout_hip depends on link width, data rate and width of APP/TL interface // Link Width | Link Rate | Avalon Interface Width | coreclkout_hip // x8 gen1 128 bit 125 Mhz // x8 gen2 128 bit 250 Mhz // x8 gen3 256 bit 250 Mhz Server#(TLPData#(16), TLPData#(16)) tlp16 = (interface Server; interface Put request; method Action put(TLPData#(16) data); fAvalonStTx.enq(AvalonStTx { eop: pack(data.eof), sop: pack(data.sof), be: dwordSwap128BE(data.be), data: dwordSwap128(data.data) }); endmethod endinterface interface Get response; method ActionValue#(TLPData#(16)) get(); let info <- toGet(fAvalonStRx).get; TLPData#(16) retval = defaultValue; retval.sof = (info.sop == 1); retval.eof = (info.eop == 1); retval.be = dwordSwap128BE(info.be); retval.hit = info.hit; retval.data = dwordSwap128(info.data); return retval; endmethod endinterface endinterface); method PciId device = deviceReg; interface PciewrapUser user; method Clock clk_out(); return core_clk; endmethod endinterface interface PciewrapPci_exp pcie; Bit#(PcieLanes) vt = pack(pcie_ep.tx.out); method Bit#(PcieLanes) tx_p(); return vt; endmethod method Action rx_p(Bit#(PcieLanes) v); action pcie_ep.rx.in(unpack(v)); endaction endmethod endinterface interface tlp = tlp16; interface Clock epPcieClock = core_clk; interface Reset epPcieReset = core_resetn; interface Clock epPortalClock = core_clk; interface Reset epPortalReset = core_resetn; interface Clock epDerivedClock = core_clk; interface Reset epDerivedReset = core_resetn; endmodule: mkPcieEndpointS5 endpackage: PcieEndpointS5 ================================================ FILE: bsv/PcieEndpointS5Test.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Copyright (c) 2014 Cornell Univeristy. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks ::*; import Connectable ::*; import ConnectalAlteraCells ::*; import ALTERA_PCIE_ED_WRAPPER ::*; import PS5LIB ::*; `include "ConnectalProjectConfig.bsv" // Default Pcie Application (* always_ready, always_enabled *) interface PcieS5AppRxSt#(numeric type data_width); method Action sop(Bit#(1) sop); method Action eop(Bit#(1) eop); method Action data(Bit#(data_width) data); method Action valid(Bit#(1) valid); method Action empty(Bit#(2) empty); method Action err(Bit#(1) err); method Bit#(1) ready; endinterface (* always_ready, always_enabled *) interface PcieS5AppRxBar; method Action bar(Bit#(8) bar); method Bit#(1) mask; endinterface (* always_ready, always_enabled *) interface PcieS5AppTxSt#(numeric type data_width); method Bit#(1) sop; method Bit#(1) eop; method Bit#(1) valid; method Bit#(1) err; method Bit#(2) empty; method Bit#(data_width) data; method Action ready(Bit#(1) ready); endinterface (* always_ready, always_enabled *) interface PcieS5AppTxCred; method Action datafccp(Bit#(12) datafccp); method Action datafcnp(Bit#(12) datafcnp); method Action datafcp(Bit#(12) datafcp); method Action fchipcons(Bit#(6) fchipcons); method Action fcinfinite(Bit#(6) fcinfinite); method Action hdrfccp(Bit#(8) hdrfccp); method Action hdrfcnp(Bit#(8) hdrfcnp); method Action hdrfcp(Bit#(8) hdrfcp); endinterface (* always_ready, always_enabled *) interface PcieS5AppHipRst; method Action serdes_pll_locked(Bit#(1) serdes_pll_locked); method Action pld_clk_inuse(Bit#(1) pld_clk_inuse); method Bit#(1) core_ready; endinterface (* always_ready, always_enabled *) interface PcieS5AppMsi; method Action int_ack(Bit#(1) int_ack); method Bit#(1) int_sts(); method Action msi_ack(Bit#(1) msi_ack); method Bit#(5) msi_num(); method Bit#(1) msi_req(); method Bit#(3) msi_tc(); endinterface (* always_ready, always_enabled *) interface PcieS5AppHipStatus; method Action cor_ext_rcv(Bit#(1) cor_ext_rcv); method Action cor_ext_rpl(Bit#(1) cor_ext_rpl); method Action rpl (Bit#(1) rpl); method Action dlup (Bit#(1) dlup); method Action dlup_exit (Bit#(1) dlup_exit); method Action ev128ns (Bit#(1) ev128ns); method Action ev1us (Bit#(1) ev1us); method Action hotrst (Bit#(1) hotrstexit); method Action int_status (Bit#(4) int_status); method Action l2_exit (Bit#(1) l2_exit); method Action lane_act (Bit#(4) lane_act); method Action ltssmstate (Bit#(5) ltssmstate); method Action rx_par_err (Bit#(1) rx_par_err); method Action tx_par_err (Bit#(2) tx_par_err); method Action cfg_par_err (Bit#(1) cfg_par_err); method Action ko_cpl_spc_data (Bit#(12) ko_cpl_spc_data); method Action ko_cpl_spc_header (Bit#(8) ko_cpl_spc_header); endinterface (* always_ready, always_enabled *) interface PcieS5AppTlCfg; method Action cfg_add(Bit#(4) cfg_add); method Action cfg_ctl(Bit#(32) cfg_ctl); method Action cfg_sts(Bit#(53) cfg_sts); method Bit#(1) cpl_pending; method Bit#(7) cpl_err; endinterface (* always_ready, always_enabled *) interface PcieS5AppLmi; method Action ack(Bit#(1) ack); method Bit#(12) addr(); method Bit#(32) din(); method Action dout(Bit#(32) dout); method Bit#(1) rden(); method Bit#(1) wren(); endinterface interface PcieS5App; interface PcieS5AppRxSt#(128) rx_st; interface PcieS5AppRxBar rx_bar; interface PcieS5AppTxSt#(128) tx_st; interface PcieS5AppTxCred tx_cred; interface PcieS5AppHipRst hip_rst; interface PcieS5AppMsi msi; interface PcieS5AppHipStatus hip_status; interface PcieS5AppTlCfg tl; interface PcieS5AppLmi lmi; endinterface instance Connectable#(PcieS5App, PcieS5Wrap#(12, 32, 128)); module mkConnection#(PcieS5App a, PcieS5Wrap#(12, 32, 128) b)(Empty); (* fire_when_enabled, no_implicit_conditions *) rule rx_st; a.rx_st.sop(b.rx_st.sop); a.rx_st.eop(b.rx_st.eop); a.rx_st.data(b.rx_st.data); a.rx_st.valid(b.rx_st.valid); a.rx_st.empty(b.rx_st.empty); a.rx_st.err(b.rx_st.err); b.rx_st.ready(a.rx_st.ready); endrule rule tx_st; b.tx_st.sop(a.tx_st.sop); b.tx_st.eop(a.tx_st.eop); b.tx_st.data(a.tx_st.data); b.tx_st.valid(a.tx_st.valid); b.tx_st.empty(a.tx_st.empty); b.tx_st.err(a.tx_st.err); a.tx_st.ready(b.tx_st.ready); endrule rule rx_bar; a.rx_bar.bar(b.rx_specific.bar); b.rx_specific.mask(a.rx_bar.mask); endrule rule tx_cred; a.tx_cred.datafccp(b.tx_cred.datafccp); a.tx_cred.datafcnp(b.tx_cred.datafcnp); a.tx_cred.datafcp(b.tx_cred.datafcp); a.tx_cred.hdrfccp(b.tx_cred.hdrfccp); a.tx_cred.hdrfcnp(b.tx_cred.hdrfcnp); a.tx_cred.hdrfcp(b.tx_cred.hdrfcp); a.tx_cred.fchipcons(b.tx_cred.fchipcons); a.tx_cred.fcinfinite(b.tx_cred.fcinfinite); endrule rule hip_rst; a.hip_rst.serdes_pll_locked(b.hip_rst.serdes_pll_locked); a.hip_rst.pld_clk_inuse(b.hip_rst.pld_clk_inuse); b.hip_rst.core_ready(a.hip_rst.core_ready); endrule rule msi; a.msi.int_ack(b.msi.int_ack); a.msi.msi_ack(b.msi.msi_ack); b.msi.int_sts(a.msi.int_sts); b.msi.msi_num(a.msi.msi_num); b.msi.msi_req(a.msi.msi_req); b.msi.msi_tc(a.msi.msi_tc); endrule rule tl; a.tl.cfg_add(b.tl.cfg_add); a.tl.cfg_ctl(b.tl.cfg_ctl); a.tl.cfg_sts(b.tl.cfg_sts); b.tl.cpl_pending(a.tl.cpl_pending); b.tl.cpl_err(a.tl.cpl_err); endrule rule lmi; a.lmi.ack(b.lmi.ack); a.lmi.dout(b.lmi.dout); b.lmi.addr(a.lmi.addr); b.lmi.din(a.lmi.din); b.lmi.rden(a.lmi.rden); b.lmi.wren(a.lmi.wren); endrule rule hipstatus; a.hip_status.cor_ext_rcv(b.hip_status.cor_ext_rcv); a.hip_status.cor_ext_rpl(b.hip_status.cor_ext_rpl); a.hip_status.rpl(b.hip_status.rpl); a.hip_status.dlup(b.hip_status.dlup); a.hip_status.dlup_exit(b.hip_status.dlup_exit); a.hip_status.ev128ns(b.hip_status.ev128ns); a.hip_status.ev1us(b.hip_status.ev1us); a.hip_status.hotrst(b.hip_status.hotrst); a.hip_status.int_status(b.hip_status.int_status); a.hip_status.l2_exit(b.hip_status.l2_exit); a.hip_status.lane_act(b.hip_status.lane_act); a.hip_status.ltssmstate(b.hip_status.ltssmstate); a.hip_status.rx_par_err(b.hip_status.rx_par_err); a.hip_status.tx_par_err(b.hip_status.tx_par_err); a.hip_status.cfg_par_err(b.hip_status.cfg_par_err); a.hip_status.ko_cpl_spc_data(b.hip_status.ko_cpl_spc_data); a.hip_status.ko_cpl_spc_header(b.hip_status.ko_cpl_spc_header); endrule endmodule endinstance module mkPcieS5App#(Clock core_clk, Reset core_clk_rst) (PcieS5App); PcieEdWrap pcie_app <- mkPcieEdWrap(core_clk, core_clk_rst); rule every1; pcie_app.testin.zero(0); pcie_app.pme.to_sr(0); pcie_app.reset.status(0); pcie_app.rx_s.t_be(16'hFFFF); // rx_st.be is deprecated. endrule interface PcieS5AppRxSt rx_st; method sop = pcie_app.rx_s.t_sop; method eop = pcie_app.rx_s.t_eop; method data = pcie_app.rx_s.t_data; method valid = pcie_app.rx_s.t_valid; method empty = pcie_app.rx_s.t_empty; method err = pcie_app.rx_s.t_err; method Bit#(1) ready; return pcie_app.rx_s.t_ready; endmethod endinterface interface PcieS5AppRxBar rx_bar; method bar = pcie_app.rx_s.t_bar; method Bit#(1) mask; return pcie_app.rx_s.t_mask; endmethod endinterface interface PcieS5AppTxSt tx_st; method Bit#(1) sop; return pcie_app.tx_s.t_sop; endmethod method Bit#(1) eop; return pcie_app.tx_s.t_eop; endmethod method Bit#(1) valid; return pcie_app.tx_s.t_valid; endmethod method Bit#(1) err; return pcie_app.tx_s.t_err; endmethod method Bit#(2) empty; return pcie_app.tx_s.t_empty; endmethod method Bit#(128) data; return pcie_app.tx_s.t_data; endmethod method ready = pcie_app.tx_s.t_ready; endinterface interface PcieS5AppTxCred tx_cred; method datafccp = pcie_app.tx_cred.datafccp; method datafcnp = pcie_app.tx_cred.datafcnp; method datafcp = pcie_app.tx_cred.datafcp; method fchipcons = pcie_app.tx_cred.fchipcons; method fcinfinite = pcie_app.tx_cred.fcinfinite; method hdrfccp = pcie_app.tx_cred.hdrfccp; method hdrfcnp = pcie_app.tx_cred.hdrfcnp; method hdrfcp = pcie_app.tx_cred.hdrfcp; endinterface interface PcieS5AppHipRst hip_rst; method serdes_pll_locked = pcie_app.serdes.pll_locked; method pld_clk_inuse = pcie_app.pld.clk_inuse; method Bit#(1) core_ready; return pcie_app.pld.core_ready; endmethod endinterface interface PcieS5AppMsi msi; method Bit#(1) int_sts; return pcie_app.app.int_sts; endmethod method Bit#(5) msi_num; return pcie_app.app.msi_num; endmethod method Bit#(1) msi_req; return pcie_app.app.msi_req; endmethod method Bit#(3) msi_tc; return pcie_app.app.msi_tc; endmethod method int_ack = pcie_app.app.int_ack; method msi_ack = pcie_app.app.msi_ack; endinterface interface PcieS5AppHipStatus hip_status; method cor_ext_rcv = pcie_app.derr.cor_ext_rcv; method cor_ext_rpl = pcie_app.derr.cor_ext_rpl; method rpl = pcie_app.derr.rpl; method dlup = pcie_app.dl.up; method dlup_exit = pcie_app.dl.up_exit; method ev128ns = pcie_app.ev128.ns; method ev1us = pcie_app.ev1.us; method hotrst = pcie_app.hotrst.exit; method int_status = pcie_app.int_s.tatus; method l2_exit = pcie_app.l2.exit; method lane_act = pcie_app.lane.act; method ltssmstate = pcie_app.ltssm.state; method rx_par_err = pcie_app.rx_par.err; method tx_par_err = pcie_app.tx_par.err; method cfg_par_err = pcie_app.cfg_par.err; method ko_cpl_spc_data = pcie_app.ko.cpl_spc_data; method ko_cpl_spc_header = pcie_app.ko.cpl_spc_header; endinterface interface PcieS5AppTlCfg tl; method cfg_add = pcie_app.tl.cfg_add; method cfg_ctl = pcie_app.tl.cfg_ctl; method cfg_sts = pcie_app.tl.cfg_sts; method cpl_pending; return pcie_app.cpl.pending; endmethod method cpl_err; return pcie_app.cpl.err; endmethod endinterface interface PcieS5AppLmi lmi; method Bit#(12) addr; return pcie_app.lmi.addr; endmethod method Bit#(32) din; return pcie_app.lmi.din; endmethod method Bit#(1) rden; return pcie_app.lmi.rden; endmethod method Bit#(1) wren; return pcie_app.lmi.wren; endmethod method ack = pcie_app.lmi.ack; method dout = pcie_app.lmi.dout; endinterface endmodule `ifdef PCIES5_SIM // PcieS5Top // Used for simulation with Default Pcie Application (* always_ready, always_enabled *) interface PcieS5Top; interface PcieS5HipSerial hip_serial; interface PcieS5HipPipe hip_pipe; interface PcieS5HipCtrl hip_ctrl; endinterface (* synthesize, no_default_clock, no_default_reset, clock_prefix="", reset_prefix="" *) module mkPcieS5Top #(Clock clk_50_clk, Clock clk_100_clk, Reset clk_50_rst_reset_n, Reset rst_n_npor, Reset rst_n_pin_perst) (PcieS5Top); PcieS5Wrap#(12, 32, 128) pcie <- mkPcieS5Wrap(clk_100_clk, clk_50_clk, rst_n_npor, rst_n_pin_perst, clk_50_rst_reset_n, clocked_by clk_100_clk, reset_by clk_50_rst_reset_n); Clock coreclk = pcie.coreclkout_hip; PcieS5App pcie_app <- mkPcieS5App(coreclk, clk_50_rst_reset_n, clocked_by clk_100_clk, reset_by clk_50_rst_reset_n); mkConnection(pcie_app, pcie); interface PcieS5HipSerial hip_serial; interface rx = pcie.rx; interface tx = pcie.tx; endinterface interface PcieS5HipPipe hip_pipe = pcie.hip_pipe; interface PcieS5HipCtrl hip_ctrl = pcie.hip_ctrl; endmodule `endif ================================================ FILE: bsv/PcieGearbox.bsv ================================================ // Copyright (c) 2008- 2009 Bluespec, Inc. All rights reserved. // $Revision$ // $Date$ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // PCI-Express for Xilinx 7 // FPGAs. `include "ConnectalProjectConfig.bsv" import Vector :: *; import GetPut :: *; import PCIE :: *; import Clocks :: *; import DefaultValue :: *; import TieOff :: *; import XilinxCells :: *; import ClientServer :: *; `ifdef XILINX import PCIEWRAPPER :: *; `endif import Connectable ::*; import Reserved ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import SpecialFIFOs ::*; // Interface wrapper for PCIE interface PcieGearbox; interface Client#(TLPData#(8), TLPData#(8)) tlp; interface Server#(TLPData#(16), TLPData#(16)) pci; endinterface // This module builds the transactor hierarchy, the clock // generation logic and the PCIE-to-port logic. (* no_default_clock, no_default_reset, synthesize *) module mkPcieGearbox#(Clock epClock250, Reset epReset250, Clock epClock125, Reset epReset125)(PcieGearbox); // Connections between TLPData#(16) and a PCIE endpoint, using a gearbox // to match data rates between the endpoint and design clocks. Gearbox#(1, 2, TLPData#(8)) fifoRxData <- mk1toNGearbox(epClock250, epReset250, epClock125, epReset125); Reg#(Bool) rOddBeat <- mkRegA(False, clocked_by epClock250, reset_by epReset250); Reg#(Bool) rSendInvalid <- mkRegA(False, clocked_by epClock250, reset_by epReset250); FIFO#(TLPData#(8)) inFifo <- mkFIFO(clocked_by epClock250, reset_by epReset250); FIFO#(TLPData#(8)) outFifo <- mkFIFO(clocked_by epClock250, reset_by epReset250); Gearbox#(2, 1, TLPData#(8)) fifoTxData <- mkNto1Gearbox(epClock125, epReset125, epClock250, epReset250); rule process_incoming_packets1(!rSendInvalid); let data = inFifo.first; inFifo.deq; rOddBeat <= !rOddBeat; rSendInvalid <= !rOddBeat && data.eof; Vector#(1, TLPData#(8)) v = defaultValue; v[0] = data; fifoRxData.enq(v); endrule rule send_invalid_packets1(rSendInvalid); rOddBeat <= !rOddBeat; rSendInvalid <= False; Vector#(1, TLPData#(8)) v = defaultValue; v[0].eof = True; v[0].be = 0; fifoRxData.enq(v); endrule rule process_outgoing_packets; let data = fifoTxData.first; fifoTxData.deq; let temp = head(data); // filter out TLPs with 00 byte enable if (temp.be != 0) outFifo.enq(temp); endrule interface Server pci; interface Get response; method ActionValue#(TLPData#(16)) get(); function TLPData#(16) combine(Vector#(2, TLPData#(8)) in); return TLPData {sof: in[0].sof, eof: in[1].eof, hit: in[0].hit, be: { in[0].be, in[1].be }, data: { in[0].data, in[1].data } }; endfunction fifoRxData.deq; return combine(fifoRxData.first); endmethod endinterface interface Put request; method Action put(TLPData#(16) data); function Vector#(2, TLPData#(8)) split(TLPData#(16) in); Vector#(2, TLPData#(8)) v = defaultValue; v[0].sof = in.sof; v[0].eof = (in.be[7:0] == 0) ? in.eof : False; v[0].hit = in.hit; v[0].be = in.be[15:8]; v[0].data = in.data[127:64]; v[1].sof = False; v[1].eof = in.eof; v[1].hit = in.hit; v[1].be = in.be[7:0]; v[1].data = in.data[63:0]; return v; endfunction fifoTxData.enq(split(data)); endmethod endinterface endinterface interface Client tlp; interface request = toGet(outFifo); interface response = toPut(inFifo); endinterface endmodule: mkPcieGearbox ================================================ FILE: bsv/PcieHost.bsv ================================================ // Copyright (c) 2014-2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector :: *; import BuildVector :: *; import Clocks :: *; import GetPut :: *; import FIFO :: *; import Connectable :: *; import ClientServer :: *; import BRAM :: *; import DefaultValue :: *; import ConnectalConfig :: *; import PCIE :: *; import PcieSplitter :: *; import PcieTracer :: *; import Xilinx :: *; import ConnectalXilinxCells :: *; import Bscan :: *; import Portal :: *; import MemToPcie :: *; import PcieToMem :: *; import PcieCsr :: *; import ConnectalMemTypes :: *; `include "ConnectalProjectConfig.bsv" `ifndef SIMULATION `ifdef XILINX `ifdef PCIE1 import PCIEWRAPPER :: *; import Pcie1EndpointX7 :: *; `endif // pcie1 `ifdef PCIE2 import PCIEWRAPPER2 :: *; import Pcie2EndpointX7 :: *; `endif // pcie2 `ifdef PCIE3 `ifdef VirtexUltrascalePlus import PCIEWRAPPER3uplus::*; `else `ifdef XilinxUltrascale import PCIEWRAPPER3u ::*; `else import PCIEWRAPPER3 :: *; `endif `endif import Pcie3EndpointX7 :: *; `endif // pcie3 `elsif ALTERA import PcieEndpointS5 :: *; `endif `endif import HostInterface :: *; `ifdef XILINX_SYS_CLK `ifdef VirtexUltrascalePlus `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, Clock sys_clk_300_p, Clock sys_clk_300_n, Clock sys_clk1_250_p, Clock sys_clk1_250_n, Clock sys_clk2_250_p, Clock sys_clk2_250_n, `define SYS_CLK_ARG sys_clk_p, sys_clk_n, sys_clk_300_p, sys_clk_300_n, sys_clk1_250_p, sys_clk1_250_n, sys_clk2_250_p, sys_clk2_250_n, `else `ifdef VirtexUltrascale `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, Clock sys_clk1_300_p, Clock sys_clk1_300_n, Clock sys_clk2_300_p, Clock sys_clk2_300_n, `define SYS_CLK_ARG sys_clk_p, sys_clk_n, sys_clk1_300_p, sys_clk1_300_n, sys_clk2_300_p, sys_clk2_300_n, `else `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, `define SYS_CLK_ARG sys_clk_p, sys_clk_n, `endif `endif `else `define SYS_CLK_PARAM `define SYS_CLK_ARG `endif `ifdef PCIE3 typedef TMin#(DataBusWidth, 128) PcieDataBusWidth; `else typedef TMin#(DataBusWidth, 128) PcieDataBusWidth; `endif (* synthesize *) module mkMemToPcieSynth#(PciId my_id)(MemToPcie#(PcieDataBusWidth)); let memSlaveEngine <- mkMemToPcie(my_id); return memSlaveEngine; endmodule // ================================================== // PCIE Gen3 PcieHost // `ifdef PCIE3 (* synthesize *) module mkPcieHost#(PciId my_pciId)(PcieHost#(PcieDataBusWidth, NumberOfMasters)); TLPDispatcher dispatcher <- mkTLPDispatcher; TLPArbiter arbiter <- mkTLPArbiter; MemToPcie#(PcieDataBusWidth) sEngine <- mkMemToPcieSynth(my_pciId); `ifdef PCIE3 MemInterrupt intr <- mkMemInterrupt(my_pciId); `endif Vector#(PortMax, PcieToMem) mvec; for (Integer i=0; i < valueOf(PortMax) - 1; i=i+1) begin let tlp; if (i == portInterrupt) tlp = intr.tlp; else begin mvec[i] <- mkPcieToMem(my_pciId); tlp = mvec[i].tlp; end mkConnection((interface Server; interface response = dispatcher.out[i]; interface request = arbiter.in[i]; endinterface), tlp); end PcieTracer traceif <- mkPcieTracer(); let splitter = (interface Client; interface request = arbiter.outToBus; interface response = dispatcher.inFromBus; endinterface); `ifdef TRACE_PORTAL mkConnection(traceif.bus, splitter); `else mkConnection(traceif.bus, sEngine.tlp); `endif PcieControlAndStatusRegs csr <- mkPcieControlAndStatusRegs(); mkConnection(mvec[portConfig].master, csr.memSlave); mkConnection(csr.traceClient, traceif.traceServer); interface msixEntry = csr.msixEntry; interface master = mvec[portPortal].master; interface slave = vec(sEngine.slave); interface interruptRequest = intr.interruptRequest; `ifdef TRACE_PORTAL interface pcic = traceif.pci; interface pcir = sEngine.tlp; `else interface pcic = splitter; interface pcir = traceif.pci; `endif interface changes = csr.changes; endmodule: mkPcieHost `else //NOT PCIE3 // ====================================================== // PCIE GEN1 and GEN2 PcieHost //(* synthesize *) commented out so that the guards in MemServer aren't destroyed (mdk) module mkPcieHost#(PciId my_pciId)(PcieHost#(PcieDataBusWidth, NumberOfMasters)); let dispatcher <- mkTLPDispatcher; let arbiter <- mkTLPArbiter; Vector#(NumberOfMasters,MemToPcie#(PcieDataBusWidth)) sEngine <- replicateM(mkMemToPcieSynth(my_pciId)); Vector#(NumberOfMasters,PhysMemSlave#(PciePhysAddrWidth,PcieDataBusWidth)) slavearr; MemInterrupt intr <- mkMemInterrupt(my_pciId); `ifdef PCIE_BSCAN BscanTop bscan <- mkBscanTop(3); // Use USER3 (JTAG IDCODE address 0x22) BscanLocal lbscan <- mkBscanLocal(bscan, clocked_by bscan.tck, reset_by bscan.rst); `endif Vector#(PortMax, PcieToMem) mvec; for (Integer i = 0; i < valueOf(PortMax) - 1 + valueOf(NumberOfMasters); i=i+1) begin let tlp; if (i == portInterrupt) tlp = intr.tlp; else if (i >= portAxi) begin tlp = sEngine[i - portAxi].tlp; slavearr[i - portAxi] = sEngine[i - portAxi].slave; end else begin mvec[i] <- mkPcieToMem(my_pciId); tlp = mvec[i].tlp; end mkConnection((interface Server; interface response = dispatcher.out[i]; interface request = arbiter.in[i]; endinterface), tlp); end PcieTracer traceif <- mkPcieTracer(); mkConnection(traceif.bus, (interface Client; interface request = arbiter.outToBus; interface response = dispatcher.inFromBus; endinterface)); `ifndef SIMULATION `ifdef PCIE_BSCAN Reg#(Bit#(TAdd#(TlpTraceAddrSize,1))) bscanPcieTraceBramWrAddrReg <- mkReg(0); BscanBram#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData) pcieBscanBram <- mkBscanBram(127, bscanPcieTraceBramWrAddrReg, lbscan.loc[1]); mkConnection(pcieBscanBram.bramClient, traceif.tlpdata.altBramServer); rule tdorule; lbscan.loc[1].tdo(pcieBscanBram.data_out()); endrule `endif `endif PcieControlAndStatusRegs csr <- mkPcieControlAndStatusRegs; mkConnection(mvec[portConfig].master, csr.memSlave); mkConnection(csr.traceClient, traceif.traceServer); interface msixEntry = csr.msixEntry; interface master = mvec[portPortal].master; interface slave = slavearr; interface interruptRequest = intr.interruptRequest; interface pci = traceif.pci; interface changes = csr.changes; `ifdef PCIE_BSCAN interface BscanTop bscanif = lbscan.loc[0]; `else `ifdef PCIE_TRACE_PORT interface BRAMServer traceBramServer = traceif.tlpdata.altBramServer; `endif `endif endmodule: mkPcieHost `endif //PCIE3 interface PcieTop#(type ipins); `ifndef SIMULATION (* prefix="PCIE" *) interface PciewrapPci_exp#(PcieLanes) pcie; `ifdef PINS_ALWAYS_READY (* always_ready *) `endif (* prefix="" *) interface ipins pins; `endif endinterface `ifdef SIMULATION module mkBsimPcieHostTop #(Clock pci_sys_clk_p, Clock pci_sys_clk_n, `SYS_CLK_PARAM Reset pci_sys_reset_n)(PcieHostTop); let dc <- exposeCurrentClock; let dr <- exposeCurrentReset; PcieHost#(PcieDataBusWidth, NumberOfMasters) pciehost <- mkPcieHost(PciId{ bus:0, dev:0, func:0}); // connect pciehost.pci to bdip functions here rule from_bdpi if (can_get_tlp); TLPData#(16) foo <- get_tlp; pciehost.pci.response.put(foo); //$display("from_bdpi: %h %d", foo, valueOf(SizeOf#(TLPData#(16)))); endrule rule to_bdpi if (can_put_tlp); TLPData#(16) foo <- pciehost.pci.request.get; put_tlp(foo); //$display("to_bdpi"); endrule interface Clock pcieClock = dc; interface Reset pcieReset = dr; interface PcieHost tpciehost = pciehost; endmodule `endif `ifdef XILINX (* no_default_clock, no_default_reset *) module mkXilinxPcieHostTop #(Clock pci_sys_clk_p, Clock pci_sys_clk_n, `SYS_CLK_PARAM Reset pci_sys_reset_n)(PcieHostTop); // Clock and PcieEndpoint for Xilinx `ifdef XILINX_SYS_CLK Clock sys_clk_200mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk_p, sys_clk_n); Clock sys_clk_200mhz_buf <- mkClockBUFG(clocked_by sys_clk_200mhz); `ifdef VirtexUltrascalePlus Clock sys_clk_300mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk_300_p, sys_clk_300_n); Clock sys_clk_300mhz_buf <- mkClockBUFG(clocked_by sys_clk_300mhz); Clock sys_clk1_250mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk1_250_p, sys_clk1_250_n); Clock sys_clk1_250mhz_buf <- mkClockBUFG(clocked_by sys_clk1_250mhz); Clock sys_clk2_250mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk2_250_p, sys_clk2_250_n); Clock sys_clk2_250mhz_buf <- mkClockBUFG(clocked_by sys_clk2_250mhz); `else `ifdef VirtexUltrascale Clock sys_clk1_300mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk1_300_p, sys_clk1_300_n); Clock sys_clk1_300mhz_buf <- mkClockBUFG(clocked_by sys_clk1_300mhz); Clock sys_clk2_300mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk2_300_p, sys_clk2_300_n); Clock sys_clk2_300mhz_buf <- mkClockBUFG(clocked_by sys_clk2_300mhz); `endif // VirtexUltrascale `endif // VirtexUltrascalePlus `endif // XILINX_SYS_CLK GTE2ClockGenIfc clockGen <- mkClockIBUFDS_GTE( `ifdef ClockDefaultParam defaultValue, `endif True, pci_sys_clk_p, pci_sys_clk_n); `ifdef XilinxUltrascale Clock pci_clk_100mhz_buf = clockGen.gen_clk2; `else Clock pci_clk_100mhz_buf = clockGen.gen_clk; `endif let pci_sys_reset_n_c <- mkResetIBUF(defaultValue, reset_by pci_sys_reset_n); // Instantiate the PCIE endpoint PcieEndpointX7#(PcieLanes) ep7 <- mkPcieEndpointX7( `ifdef PCIE3 clockGen.gen_clk, `endif clocked_by pci_clk_100mhz_buf, reset_by pci_sys_reset_n_c); Clock pcieClock_ = ep7.epPcieClock; Reset pcieReset_ = ep7.epPcieReset; PcieHost#(PcieDataBusWidth, NumberOfMasters) pciehost <- mkPcieHost( `ifdef PCIE3 PciId{bus: 0, dev: 0, func:0}, `else PciId{ bus: ep7.cfg.bus_number(), dev: ep7.cfg.device_number(), func: ep7.cfg.function_number()}, `endif clocked_by pcieClock_, reset_by pcieReset_); `ifdef PCIE3 mkConnection(ep7.tlpr, pciehost.pcir, clocked_by pcieClock_, reset_by pcieReset_); mkConnection(ep7.tlpc, pciehost.pcic, clocked_by pcieClock_, reset_by pcieReset_); `ifndef PCIE_CHANGES_HOSTIF mkConnection(ep7.regChanges, pciehost.changes); `endif let ipciehost = (interface PcieHost; interface msixEntry = pciehost.msixEntry; interface master = pciehost.master; interface slave = pciehost.slave; interface pcir = pciehost.pcir; interface pcic = pciehost.pcic; interface trace = pciehost.trace; interface interruptRequest = ep7.interruptRequest; endinterface); `else mkConnection(ep7.tlp, pciehost.pci, clocked_by pcieClock_, reset_by pcieReset_); `ifndef PCIE_CHANGES_HOSTIF mkConnection(ep7.regChanges, pciehost.changes, clocked_by pcieClock_, reset_by pcieReset_); `endif let ipciehost = pciehost; `endif `ifdef XILINX_SYS_CLK interface Clock tsys_clk_200mhz = sys_clk_200mhz; interface Clock tsys_clk_200mhz_buf = sys_clk_200mhz_buf; `ifdef VirtexUltrascalePlus interface Clock tsys_clk_300mhz = sys_clk_300mhz; interface Clock tsys_clk_300mhz_buf = sys_clk_300mhz_buf; interface Clock tsys_clk1_250mhz = sys_clk1_250mhz; interface Clock tsys_clk1_250mhz_buf = sys_clk1_250mhz_buf; interface Clock tsys_clk2_250mhz = sys_clk2_250mhz; interface Clock tsys_clk2_250mhz_buf = sys_clk2_250mhz_buf; `else `ifdef VirtexUltrascale interface Clock tsys_clk1_300mhz = sys_clk1_300mhz; interface Clock tsys_clk1_300mhz_buf = sys_clk1_300mhz_buf; interface Clock tsys_clk2_300mhz = sys_clk2_300mhz; interface Clock tsys_clk2_300mhz_buf = sys_clk2_300mhz_buf; `endif // VirtexUltrascale `endif // VirtexUltrascalePlus `endif // XILINX_SYS_CLK interface Clock tpci_clk_100mhz_buf = pci_clk_100mhz_buf; interface PcieEndpointX7 tep7 = ep7; interface PcieHost tpciehost = ipciehost; `ifdef PCIE_CHANGES_HOSTIF interface PipeOut tchanges = ep7.regChanges; `endif interface pcieClock = ep7.epPcieClock; interface pcieReset = ep7.epPcieReset; interface portalClock = ep7.epPortalClock; interface portalReset = ep7.epPortalReset; interface derivedClock = ep7.epDerivedClock; interface derivedReset = ep7.epDerivedReset; endmodule `endif `ifdef ALTERA `define ALTERA_TOP `endif `ifdef ALTERA_TOP (* no_default_clock, no_default_reset *) module mkAlteraPcieHostTop #(Clock clk_100MHz, Clock clk_50MHz, Reset perst_n)(PcieHostTop); PcieEndpointS5#(PcieLanes) ep7 <- mkPcieEndpointS5(clk_100MHz, clk_50MHz, perst_n, clocked_by clk_100MHz, reset_by perst_n); Clock epPcieClock = ep7.epPcieClock; Reset epPcieReset = ep7.epPcieReset; Clock portalClock_ = epPcieClock; Reset portalReset_ = epPcieReset; PcieHost#(PcieDataBusWidth, NumberOfMasters) pciehost <- mkPcieHost(ep7.device, clocked_by portalClock_, reset_by portalReset_); mkConnection(ep7.tlp, pciehost.pci, clocked_by portalClock_, reset_by portalReset_); interface PcieEndpointS5 tep7 = ep7; interface PcieHost tpciehost = pciehost; interface Clock pcieClock = epPcieClock; interface Reset pcieReset = epPcieReset; interface portalClock = portalClock_; interface portalReset = portalReset_; interface derivedClock = ep7.epDerivedClock; interface derivedReset = ep7.epDerivedReset; endmodule `endif `ifdef SIMULATION module mkPcieHostTop #(Clock pci_sys_clk_p, Clock pci_sys_clk_n, `SYS_CLK_PARAM Reset pci_sys_reset_n)(PcieHostTop); (* hide *) PcieHostTop pcieHostTop <- mkBsimPcieHostTop(pci_sys_clk_p, pci_sys_clk_n, `SYS_CLK_ARG pci_sys_reset_n); return pcieHostTop; endmodule `elsif XILINX // XILINX //(* synthesize, no_default_clock, no_default_reset *) (* no_default_clock, no_default_reset *) module mkPcieHostTop #(Clock pci_sys_clk_p, Clock pci_sys_clk_n, `SYS_CLK_PARAM Reset pci_sys_reset_n)(PcieHostTop); (* hide *) PcieHostTop pcieHostTop <- mkXilinxPcieHostTop(pci_sys_clk_p, pci_sys_clk_n, `SYS_CLK_ARG pci_sys_reset_n); return pcieHostTop; endmodule `elsif ALTERA_TOP //(* synthesize, no_default_clock, no_default_reset *) (* no_default_clock, no_default_reset *) module mkPcieHostTop #(Clock clk_100MHz, Clock clk_50MHz, Reset perst_n)(PcieHostTop); (* hide *) PcieHostTop pcieHostTop <- mkAlteraPcieHostTop(clk_100MHz, clk_50MHz, perst_n); return pcieHostTop; endmodule `endif // NOT ALTERA ================================================ FILE: bsv/PcieRootDevice.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; import Connectable::*; interface PcieRoot#(numeric type n); interface Get#(TLPData#(n)) fromRoot; interface Put#(TLPData#(n)) toRoot; endinterface interface PcieDevice#(numeric type n); interface Put#(TLPData#(n)) fromRoot; interface Get#(TLPData#(n)) toRoot; endinterface instance Connectable#(PcieRoot#(n),PcieDevice#(n)); module mkConnection(PcieRoot#(n) r, PcieDevice#(n) d); mkConnection(r.fromRoot, d.fromRoot); mkConnection(r.toRoot, d.toRoot); endmodule endinstance ================================================ FILE: bsv/PcieRootPortX7.bsv ================================================ // Copyright (c) 2013-2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package PcieRootPortX7; import Clocks ::*; import Vector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import SpecialFIFOs ::*; import ClientServer ::*; import Real ::*; import ConnectalClocks ::*; import ConnectalXilinxCells ::*; import XilinxCells ::*; import PCIE ::*; import PCIEWRAPPER ::*; import Bufgctrl ::*; //////////////////////////////////////////////////////////////////////////////// /// Interfaces //////////////////////////////////////////////////////////////////////////////// interface PcieRootPortX7#(numeric type lanes); interface PciewrapPci_exp#(lanes) pcie; interface PciewrapUser#(lanes) user; interface PciewrapCfg#(lanes) cfg; interface Server#(TLPData#(16), TLPData#(16)) tlp; interface Clock portalClock; interface Reset portalReset; interface Clock epDerivedClock; interface Reset epDerivedReset; endinterface typedef struct { Bit#(22) user; Bit#(1) last; Bit#(16) keep; Bit#(128) data; } AxiRx deriving (Bits, Eq); typedef struct { Bit#(1) last; Bit#(16) keep; Bit#(128) data; } AxiTx deriving (Bits, Eq); (* synthesize *) module mkPcieRootPortX7(PcieRootPortX7#(PcieLanes)); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); PcieWrap#(PcieLanes) pcie_ep <- mkPcieWrap(defaultClock, defaultReset); Clock user_clk = pcie_ep.user_clk_out; Reset user_reset_n <- mkResetInverter(pcie_ep.user_reset_out, clocked_by user_clk); FIFOF#(AxiTx) fAxiTx <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n); FIFOF#(AxiRx) fAxiRx <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n); (* fire_when_enabled, no_implicit_conditions *) rule every1; pcie_ep.fc.sel(0 /*RECEIVE_BUFFER_AVAILABLE_SPACE*/); pcie_ep.cfg_dsn({ 32'h0000_0001, {{ 8'h1 } , 24'h000A35 }}); pcie_ep.rx.np_ok(1); pcie_ep.rx.np_req(1); pcie_ep.tx.cfg_gnt(1); pcie_ep.s_axis_tx.tuser(4'b0); pcie_ep.m_axis_rx.tready(pack(fAxiRx.notFull)); endrule rule every_cfg_err; pcie_ep.cfg_err.acs(0); pcie_ep.cfg_err.aer_headerlog(0); pcie_ep.cfg_err.atomic_egress_blocked(0); pcie_ep.cfg_err.cor(0); pcie_ep.cfg_err.cpl_abort(0); pcie_ep.cfg_err.cpl_timeout(0); pcie_ep.cfg_err.cpl_unexpect(0); pcie_ep.cfg_err.ecrc(0); pcie_ep.cfg_err.internal_cor(0); pcie_ep.cfg_err.internal_uncor(0); pcie_ep.cfg_err.locked(0); pcie_ep.cfg_err.malformed(0); pcie_ep.cfg_err.mc_blocked(0); pcie_ep.cfg_err.norecovery(0); pcie_ep.cfg_err.poisoned(0); pcie_ep.cfg_err.posted(0); pcie_ep.cfg_err.tlp_cpl_header(0); pcie_ep.cfg_err.ur(0); endrule rule every_interrupt; pcie_ep.cfg_interrupt.zzassert(0); pcie_ep.cfg_interrupt.di(0); pcie_ep.cfg_interrupt.stat(0); endrule rule every_mgmt; pcie_ep.cfg_mgmt.byte_en(0); pcie_ep.cfg_mgmt.di(0); pcie_ep.cfg_mgmt.dwaddr(0); pcie_ep.cfg_mgmt.rd_en(0); pcie_ep.cfg_mgmt.wr_en(0); pcie_ep.cfg_mgmt.wr_readonly(0); endrule rule every_pm; pcie_ep.cfg_pm.force_state(0); pcie_ep.cfg_pm.force_state_en(0); pcie_ep.cfg_pm.halt_aspm_l0s(0); pcie_ep.cfg_pm.halt_aspm_l1(0); pcie_ep.cfg_pm.send_pme_to(0); pcie_ep.cfg_pm.wake(0); endrule rule every_pl; pcie_ep.pl.directed_link_auton(0); pcie_ep.pl.directed_link_change(0); pcie_ep.pl.directed_link_speed(0); pcie_ep.pl.directed_link_width(0); pcie_ep.pl.downstream_deemph_source(0); pcie_ep.pl.transmit_hot_rst(0); pcie_ep.pl.upstream_prefer_deemph(1); endrule let txready = (pcie_ep.s_axis_tx.tready == 1 && fAxiTx.notEmpty); (* fire_when_enabled *) rule drive_axi_tx if (txready); let info = unpack(0); if (fAxiTx.notEmpty) begin info <- toGet(fAxiTx).get(); end pcie_ep.s_axis_tx.tlast(info.last); pcie_ep.s_axis_tx.tdata(info.data); pcie_ep.s_axis_tx.tkeep(info.keep); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_txvalid if (fAxiTx.notEmpty); pcie_ep.s_axis_tx.tvalid(1); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_tx2 if (!fAxiTx.notEmpty); pcie_ep.s_axis_tx.tvalid(0); pcie_ep.s_axis_tx.tlast(0); pcie_ep.s_axis_tx.tdata(0); pcie_ep.s_axis_tx.tkeep(0); endrule (* fire_when_enabled *) rule sink_axi_rx if (pcie_ep.m_axis_rx.tvalid == 1); fAxiRx.enq(AxiRx {user: pcie_ep.m_axis_rx.tuser, last: pcie_ep.m_axis_rx.tlast, keep: pcie_ep.m_axis_rx.tkeep, data: pcie_ep.m_axis_rx.tdata }); endrule Reset user_reset <- mkSyncReset(5, user_reset_n, user_clk); ClockGenerator7Params clkgenParams = defaultValue; clkgenParams.clkin1_period = 4.000; // 250MHz clkgenParams.clkin_buffer = False; clkgenParams.clkfbout_mult_f = 4.000; // 1000MHz clkgenParams.clkout0_divide_f = 4.000; // 250MHz clkgenParams.clkout1_divide = round(derivedClockPeriod); clkgenParams.clkout1_duty_cycle = 0.5; clkgenParams.clkout1_phase = 0.0000; ClockGenerator7 clkgen <- mkClockGenerator7(clkgenParams, clocked_by user_clk, reset_by user_reset_n); Clock derivedClock = clkgen.clkout1; Reset derivedReset <- mkSyncReset(5, user_reset_n, derivedClock); Server#(TLPData#(16), TLPData#(16)) tlp16 = (interface Server; interface Put request; method Action put(TLPData#(16) data); fAxiTx.enq(AxiTx {last: pack(data.eof), keep: dwordSwap128BE(data.be), data: dwordSwap128(data.data) }); endmethod endinterface interface Get response; method ActionValue#(TLPData#(16)) get(); let info <- toGet(fAxiRx).get; TLPData#(16) retval = defaultValue; retval.sof = (info.user[14] == 1); retval.eof = info.last != 0; retval.hit = info.user[8:2]; retval.be= dwordSwap128BE(info.keep); retval.data = dwordSwap128(info.data); return retval; endmethod endinterface endinterface); interface Clock portalClock = user_clk; interface Reset portalReset = user_reset_n; interface tlp = tlp16; interface pcie = pcie_ep.pci_exp; interface PciewrapUser user = pcie_ep.user; interface PciewrapCfg cfg = pcie_ep.cfg; interface Clock epDerivedClock = derivedClock; interface Reset epDerivedReset = derivedReset; endmodule: mkPcieRootPortX7 endpackage: PcieRootPortX7 ================================================ FILE: bsv/PcieSplitter.bsv ================================================ // Copyright (c) 2008- 2009 Bluespec, Inc. All rights reserved. // $Revision$ // $Date$ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // PCI-Express for Xilinx 7 // FPGAs. package PcieSplitter; // This is a package which acts as a bridge between a TLP-based PCIe // interface on one side and an AXI slave (portal) and AXI Master on // the other. import GetPut :: *; import Connectable :: *; import Vector :: *; import FIFO :: *; import FIFOF :: *; import Counter :: *; import PCIE :: *; import Clocks :: *; import ClientServer :: *; Integer portConfig = 0; Integer portPortal = 1; Integer portInterrupt = 2; Integer portAxi = 3; typedef 4 PortMax; // When TLP packets come in from the PCIe bus, they are dispatched to // either the configuration register block, the portal (AXI slave) or // the AXI master. interface TLPDispatcher; // TLPs in from PCIe interface Put#(TLPData#(16)) inFromBus; // TLPs out to the bridge implementation interface Vector#(PortMax, Get#(TLPData#(16))) out; endinterface: TLPDispatcher typedef function Bool tlpMatchFunction(TLPData#(16) tlp, TLPMemoryIO3DWHeader hdr_3dw) TlpMatchFunction; (* synthesize *) module mkTLPDispatcher(TLPDispatcher); FIFO#(TLPData#(16)) tlp_in_fifo <- mkFIFO(); Vector#(PortMax, FIFOF#(TLPData#(16))) tlp_out_fifo <- replicateM(mkGFIFOF(True,False)); // unguarded enq Reg#(Maybe#(Bit#(TLog#(PortMax)))) routeToPort <- mkReg(tagged Invalid); Vector#(PortMax, TlpMatchFunction) matchFunctions = newVector; function Bool configMatch(TLPData#(16) tlp, TLPMemoryIO3DWHeader hdr_3dw); return tlp.hit == 7'h01 && pack(hdr_3dw.r1) == 0 && // not a TLP Prefix (hdr_3dw.format == MEM_READ_3DW_NO_DATA /* read */ || (hdr_3dw.format == MEM_WRITE_3DW_DATA && hdr_3dw.pkttype != COMPLETION)); /* write */ endfunction function Bool axiMatch(TLPData#(16) tlp, TLPMemoryIO3DWHeader hdr_3dw); return tlp.hit == 7'h04 && pack(hdr_3dw.r1) == 0 && // not a TLP Prefix (hdr_3dw.format == MEM_READ_3DW_NO_DATA /* read */ || (hdr_3dw.format == MEM_WRITE_3DW_DATA && hdr_3dw.pkttype != COMPLETION)); /* write */ endfunction function Bool axiCompletionMatch(TLPData#(16) tlp, TLPMemoryIO3DWHeader hdr_3dw); return (pack(hdr_3dw.r1) == 0) && // not a TLP Prefix hdr_3dw.format == MEM_WRITE_3DW_DATA && hdr_3dw.pkttype == COMPLETION; endfunction matchFunctions[portConfig] = configMatch; matchFunctions[portPortal] = axiMatch; matchFunctions[portAxi] = axiCompletionMatch; (* fire_when_enabled *) rule dispatch_incoming_TLP; TLPData#(16) tlp = tlp_in_fifo.first(); TLPMemoryIO3DWHeader hdr_3dw = unpack(tlp.data); if (tlp.sof) begin Bool matched = False; // route the packet based on this header for (Integer port = 0; port < valueOf(PortMax); port = port+1) if (!matched && matchFunctions[port](tlp, hdr_3dw)) begin matched = True; if (tlp_out_fifo[port].notFull()) begin tlp_in_fifo.deq(); tlp_out_fifo[port].enq(tlp); if (!tlp.eof) routeToPort <= tagged Valid fromInteger(port); end end if (!matched) begin // unknown packet type -- just discard it tlp_in_fifo.deq(); end end else if (routeToPort matches tagged Valid .port) begin if (tlp_out_fifo[port].notFull()) begin tlp_in_fifo.deq(); tlp_out_fifo[port].enq(tlp); if (tlp.eof) routeToPort <= tagged Invalid; end end else begin // unknown packet type -- just discard it tlp_in_fifo.deq(); end endrule: dispatch_incoming_TLP Vector#(PortMax, Get#(TLPData#(16))) outtemp; for (Integer i = 0; i < valueOf(PortMax); i=i+1) outtemp[i] = toGet(tlp_out_fifo[i]); interface out = outtemp; interface Put inFromBus = toPut(tlp_in_fifo); endmodule: mkTLPDispatcher // Multiple sources of TLP packets must all share the PCIe bus. There // is an arbiter which controls which source gets access to the PCIe // endpoint. interface TLPArbiter; // TLPs out to PCIe interface Get#(TLPData#(16)) outToBus; // TLPs in from the bridge implementation interface Vector#(PortMax, Put#(TLPData#(16))) in; endinterface: TLPArbiter (* synthesize *) module mkTLPArbiter(TLPArbiter); FIFO#(TLPData#(16)) tlp_out_fifo <- mkFIFO(); Vector#(PortMax, FIFOF#(TLPData#(16))) tlp_in_fifo <- replicateM(mkGFIFOF(False,True)); // unguarded deq Reg#(Maybe#(Bit#(TLog#(PortMax)))) routeFrom <- mkReg(tagged Invalid); (* fire_when_enabled *) rule arbitrate_outgoing_TLP; if (routeFrom matches tagged Valid .port) begin if (tlp_in_fifo[port].notEmpty()) begin TLPData#(16) tlp <- toGet(tlp_in_fifo[port]).get(); tlp_out_fifo.enq(tlp); if (tlp.eof) routeFrom <= tagged Invalid; end end else begin Bool sentOne = False; for (Integer port = 0; port < valueOf(PortMax); port = port+1) begin if (!sentOne && tlp_in_fifo[port].notEmpty()) begin TLPData#(16) tlp <- toGet(tlp_in_fifo[port]).get(); sentOne = True; if (tlp.sof) begin tlp_out_fifo.enq(tlp); if (!tlp.eof) routeFrom <= tagged Valid fromInteger(port); end end end end endrule: arbitrate_outgoing_TLP Vector#(PortMax, Put#(TLPData#(16))) intemp; for (Integer i = 0; i < valueOf(PortMax); i=i+1) intemp[i] = toPut(tlp_in_fifo[i]); interface in = intemp; interface Get outToBus = toGet(tlp_out_fifo); endmodule endpackage: PcieSplitter ================================================ FILE: bsv/PcieStateChanges.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF ::*; import Probe ::*; import Pipe ::*; typedef enum { PcieCfg_none, PcieCfg_current_speed, PcieCfg_dpa_substate_change, PcieCfg_err_cor_out, PcieCfg_err_fatal_out, PcieCfg_err_nonfatal_out, PcieCfg_flr_in_process, PcieCfg_function_power_state, PcieCfg_function_status, PcieCfg_hot_reset_out, PcieCfg_link_power_state, PcieCfg_ltr_enable, PcieCfg_ltssm_state, PcieCfg_max_payload, PcieCfg_max_read_req, PcieCfg_negotiated_width, PcieCfg_obff_enable, PcieCfg_phy_link_down, PcieCfg_phy_link_status, PcieCfg_pl_status_change, PcieCfg_power_state_change_interrupt, PcieCfg_rcb_status, PcieCfg_rq_backpressure, PcieCfg_initial_link_width, PcieCfg_lane_reversal_mode, PcieCfg_phy_link_up, PcieCfg_received_hot_rst, PcieCfg_rx_pm_state, PcieCfg_sel_lnk_rate, PcieCfg_tx_pm_state, PcieCfg_link_gen2_cap, PcieCfg_link_partner_gen2_supported, PcieCfg_link_up } PcieCfgType deriving (Bits,Eq); typedef struct { Bit#(32) timestamp; Bit#(8) src; Bit#(24) value; } RegChange deriving (Bits); module mkChangeSource#(Reg#(Bit#(32)) cyclesReg, Tuple2#(PcieCfgType,Bit#(24)) tpl)(PipeOut#(RegChange)); match { .src, .v } = tpl; Reg#(Bit#(24)) snapshot <- mkReg(0); FIFOF#(RegChange) changeFifo <- mkFIFOF1(); rule rl_update if (v != snapshot); if (changeFifo.notFull) begin changeFifo.enq(RegChange { timestamp: cyclesReg, src: extend(pack(src)), value: extend(v) }); snapshot <= v; end endrule return toPipeOut(changeFifo); endmodule ================================================ FILE: bsv/PcieToMem.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF :: *; import Vector :: *; import GetPut :: *; import Connectable :: *; import MIMO :: *; import PCIE :: *; import DefaultValue :: *; import ClientServer :: *; import ConnectalMemTypes :: *; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" // // Top interface: PCIe transaction level packets (TLPs) // Bottom interface: MemMaster that sends read/write requests to an MemSlave // Also sources interrupt MSIX requests interface PcieToMem; interface Client#(TLPData#(16), TLPData#(16)) tlp; interface PhysMemMaster#(32,32) master; endinterface `ifdef XILINX `define AXI `elsif SIMULATION `define AXI `elsif ALTERA `define AVALON `elsif VSIM `define AVALON `endif (* synthesize *) module mkPcieToMem#(PciId my_id)(PcieToMem); let verbose = False; Reg#(Bit#(7)) hitReg <- mkReg(0); FIFOF#(TLPMemoryIO3DWHeader) readHeaderFifo <- mkSizedFIFOF(8); FIFOF#(TLPMemoryIO3DWHeader) readDataFifo <- mkSizedFIFOF(8); FIFOF#(TLPMemoryIO3DWHeader) writeHeaderFifo <- mkSizedFIFOF(8); FIFOF#(TLPMemoryIO3DWHeader) writeDataFifo <- mkSizedFIFOF(8); FIFOF#(TLPData#(16)) tlpOutFifo <- mkSizedFIFOF(8); Reg#(TLPTag) tlpTag <- mkReg(0); MIMOConfiguration mimoCfg = defaultValue; MIMO#(1,4,4,Bit#(32)) completionMimo <- mkMIMO(mimoCfg); Reg#(TLPLength) readBurstCount <- mkReg(0); Reg#(LUInt#(4)) completionMimoDeqCount <- mkReg(0); Reg#(Bool) readBurstCountGreaterThan4 <- mkReg(False); Reg#(Bool) readInProgress <- mkReg(False); Reg#(Bit#(7)) address <- mkReg(0); rule completionHeader if (!readInProgress && readDataFifo.notEmpty() && completionMimo.deqReadyN(1)); let hdr = readDataFifo.first; TLPLength rbc = hdr.length; Vector#(4, Bit#(32)) dvec = unpack(0); `ifdef AXI dvec = completionMimo.first(); completionMimo.deq(1); `elsif AVALON let quadWordAligned = isQuadWordAligned(getLowerAddr(hdr.addr, hdr.firstbe)); // if quad-word aligned, insert bubble. if (!quadWordAligned) begin dvec = completionMimo.first(); completionMimo.deq(1); end `endif if (verbose) $display("completionHeader length=%d rbc=%d addr=%x", hdr.length, rbc, hdr.addr); TLPCompletionHeader completion = defaultValue; completion.format = MEM_WRITE_3DW_DATA; completion.pkttype = COMPLETION; completion.relaxed = hdr.relaxed; completion.nosnoop = hdr.nosnoop; completion.length = hdr.length; completion.tclass = hdr.tclass; completion.cmplid = my_id; completion.tag = truncate(hdr.tag); completion.bytecount = 4; completion.reqid = hdr.reqid; completion.loweraddr = getLowerAddr(hdr.addr, hdr.firstbe); `ifdef AXI completion.data = byteSwap(dvec[0]); `elsif AVALON if (!quadWordAligned) begin completion.data = (dvec[0]); end else begin completion.data = unpack(0); end `endif TLPData#(16) tlp = defaultValue; tlp.data = pack(completion); tlp.sof = True; `ifdef AXI tlp.eof = (rbc == 1) ? True : False; `elsif AVALON tlp.eof = (rbc == 1 && !quadWordAligned) ? True : False; `endif tlp.be = 16'hFFFF; tlp.hit = hitReg; tlpOutFifo.enq(tlp); `ifdef AXI rbc = rbc - 1; `elsif AVALON if (!quadWordAligned) begin rbc = rbc - 1; end `endif readBurstCount <= rbc; completionMimoDeqCount <= truncate(min(4,unpack(rbc))); readInProgress <= (rbc != 0); readBurstCountGreaterThan4 <= (rbc > 4); if (rbc == 0) begin readDataFifo.deq; end endrule function Bit#(16) tlpBe(TLPLength len); if (len == 0) return 0; else if (len == 1) return 16'hf000; else if (len == 2) return 16'hff00; else if (len == 3) return 16'hfff0; else return 16'hffff; endfunction rule continuation if (readInProgress && completionMimo.deqReadyN(completionMimoDeqCount)); let rbc = readBurstCount; TLPData#(16) tlp = defaultValue; Vector#(4, Bit#(32)) dvec = unpack(0); tlp.sof = False; dvec = completionMimo.first(); completionMimo.deq(completionMimoDeqCount); if (readBurstCountGreaterThan4) begin rbc = rbc - 4; tlp.be = tlpBe(4); tlp.eof = False; end else begin tlp.be = tlpBe(rbc); if (verbose) $display("tlp.data=%h tlp.be=%h", tlp.data, tlp.be); tlp.eof = True; rbc = 0; end readBurstCount <= rbc; completionMimoDeqCount <= truncate(min(4,unpack(rbc))); readBurstCountGreaterThan4 <= (rbc > 4); if (!readBurstCountGreaterThan4) begin readDataFifo.deq(); readInProgress <= False; end for (Integer i = 0; i < 4; i = i + 1) `ifdef AXI tlp.data[(i+1)*32-1:i*32] = byteSwap(dvec[3-i]); `elsif AVALON tlp.data[(i+1)*32-1:i*32] = (dvec[3-i]); tlp.hit = hitReg; `endif tlpOutFifo.enq(tlp); endrule interface Client tlp; interface Put response; method Action put(TLPData#(16) tlp); if (verbose) $display("PcieToMem.put tlp=%h", tlp); TLPMemoryIO3DWHeader h = unpack(tlp.data); hitReg <= tlp.hit; TLPMemoryIO3DWHeader hdr_3dw = unpack(tlp.data); `ifdef AVALON // For Altera, the position of payload in a 3DW TLP depends on alignment. let quadWordAligned = isQuadWordAligned(getLowerAddr(hdr_3dw.addr, hdr_3dw.firstbe)); `endif if (tlp.sof && hdr_3dw.format == MEM_READ_3DW_NO_DATA) begin if (readHeaderFifo.notFull()) readHeaderFifo.enq(hdr_3dw); else begin // FIXME: should generate a response or host will lock up end end else begin //FIXME: should rewrite to allow burst write. if (tlp.sof && writeHeaderFifo.notFull()) begin writeHeaderFifo.enq(hdr_3dw); end end endmethod endinterface interface Get request = toGet(tlpOutFifo); endinterface: tlp interface PhysMemMaster master; interface PhysMemWriteClient write_client; interface Get writeReq; method ActionValue#(PhysMemRequest#(32,32)) get(); let hdr = writeHeaderFifo.first; writeHeaderFifo.deq; writeDataFifo.enq(hdr); let burstLen = extend(hdr.length << 2); if (verbose) $display("burstLen = %h", hdr.length << 2); return PhysMemRequest { addr: extend(writeHeaderFifo.first.addr) << 2, burstLen: burstLen, tag: truncate(writeHeaderFifo.first.tag) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }; endmethod endinterface interface Get writeData; method ActionValue#(MemData#(32)) get(); let hdr <- toGet(writeDataFifo).get(); `ifdef AXI let data = byteSwap(hdr.data); `elsif AVALON let data = hdr.data; `endif return MemData { data: data, tag: truncate(hdr.tag), last: True}; endmethod endinterface interface Put writeDone; method Action put(Bit#(MemTagSize) resp); endmethod endinterface endinterface interface PhysMemReadClient read_client; interface Get readReq; method ActionValue#(PhysMemRequest#(32,32)) get(); let hdr = readHeaderFifo.first; readHeaderFifo.deq; //if (verbose) $display("req_ar hdr.length=%d hdr.addr=%h", hdr.length, hdr.addr); readDataFifo.enq(hdr); let burstLen = extend(hdr.length << 2); return PhysMemRequest { addr: extend(readHeaderFifo.first.addr) << 2, burstLen: burstLen, tag: truncate(readHeaderFifo.first.tag) `ifdef BYTE_ENABLES , firstbe: maxBound, lastbe: maxBound `endif }; endmethod endinterface interface Put readData; method Action put(MemData#(32) resp) if (completionMimo.enqReadyN(1)); Vector#(1, Bit#(32)) vec = cons(resp.data, nil); completionMimo.enq(1, vec); endmethod endinterface endinterface endinterface: master endmodule: mkPcieToMem interface MemInterrupt; interface Client#(TLPData#(16), TLPData#(16)) tlp; interface Put#(Tuple2#(Bit#(64),Bit#(32))) interruptRequest; interface Get#(Tuple2#(Bit#(64),Bit#(32))) interruptTrace; endinterface typedef struct { Bit#(64) addr; Bit#(32) data; Bool mswIsZero; Bool lswIsZero; } InterruptRequest deriving (Bits); (* synthesize *) module mkMemInterrupt#(PciId my_id)(MemInterrupt); FIFOF#(InterruptRequest) interruptRequestFifo <- mkFIFOF(); FIFOF#(InterruptRequest) interruptTraceFifo <- mkSizedFIFOF(4); Reg#(Maybe#(Bit#(32))) interruptSecondHalf <- mkReg(tagged Invalid); Reg#(TLPTag) tlpTag <- mkReg(0); FIFOF#(TLPData#(16)) tlpOutFifo <- mkSizedFIFOF(8); function Bool isQuadWordAligned(Bit#(7) lower_addr); return (lower_addr[2:0]==3'b0); endfunction rule interruptTlpOut if (interruptRequestFifo.notEmpty &&& interruptSecondHalf matches tagged Invalid); TLPData#(16) tlp = defaultValue; tlp.sof = True; tlp.eof = False; tlp.hit = 7'h00; tlp.be = 16'hffff; let deqInterruptRequestFifo = False; let sendInterrupt = False; let interruptRequest = interruptRequestFifo.first; let interruptAddr = interruptRequest.addr; let interruptData = interruptRequest.data; let mswIsZero = interruptRequest.mswIsZero; let lswIsZero = interruptRequest.lswIsZero; `ifdef AXI let dataInSecondTlp = False; `elsif AVALON let quadWordAligned = isQuadWordAligned(truncate(interruptAddr)); let dataInSecondTlp = quadWordAligned; `endif if (mswIsZero && lswIsZero) begin // do not write to 0 -- it wedges the host deqInterruptRequestFifo = True; end else if (mswIsZero) begin TLPMemoryIO3DWHeader hdr_3dw = defaultValue(); hdr_3dw.format = MEM_WRITE_3DW_DATA; //hdr_3dw.pkttype = MEM_READ_WRITE; hdr_3dw.tag = tlpTag; hdr_3dw.reqid = my_id; hdr_3dw.length = 1; hdr_3dw.firstbe = '1; hdr_3dw.lastbe = '0; hdr_3dw.addr = interruptAddr[31:2]; `ifdef AXI hdr_3dw.data = byteSwap(interruptData); `elsif AVALON hdr_3dw.data = interruptData; `endif tlp.data = pack(hdr_3dw); if (dataInSecondTlp) begin tlp.eof = False; interruptSecondHalf <= tagged Valid interruptData; end else begin tlp.eof = True; deqInterruptRequestFifo = True; end sendInterrupt = True; end else begin TLPMemory4DWHeader hdr_4dw = defaultValue; hdr_4dw.format = MEM_WRITE_4DW_DATA; //hdr_4dw.pkttype = MEM_READ_WRITE; hdr_4dw.tag = tlpTag; hdr_4dw.reqid = my_id; hdr_4dw.nosnoop = SNOOPING_REQD; hdr_4dw.addr = interruptAddr[40-1:2]; hdr_4dw.length = 1; hdr_4dw.firstbe = 4'hf; hdr_4dw.lastbe = 0; tlp.data = pack(hdr_4dw); sendInterrupt = True; interruptSecondHalf <= tagged Valid interruptData; end if (deqInterruptRequestFifo) begin interruptRequestFifo.deq(); end if (sendInterrupt) tlpOutFifo.enq(tlp); endrule rule interruptTlpDataOut if (interruptSecondHalf matches tagged Valid .interruptData); TLPData#(16) tlp = defaultValue; tlp.sof = False; tlp.eof = True; tlp.hit = 7'h00; tlp.be = 16'hf000; `ifdef AXI tlp.data[7+8*15:8*12] = byteSwap(interruptData); `elsif AVALON tlp.data[7+8*15:8*12] = interruptData; `endif tlpOutFifo.enq(tlp); interruptSecondHalf <= tagged Invalid; interruptRequestFifo.deq(); endrule interface Client tlp; interface Put response; method Action put(TLPData#(16) tlp); endmethod endinterface interface Get request = toGet(tlpOutFifo); endinterface: tlp interface Put interruptRequest; method Action put(Tuple2#(Bit#(64),Bit#(32)) intr); match { .addr, .data } = intr; Bool mswIsZero = (addr[63:32] == 0); Bool lswIsZero = (addr[31:0] == 0); let interruptRequest = InterruptRequest { addr: addr, data: data, mswIsZero: mswIsZero, lswIsZero: lswIsZero }; interruptRequestFifo.enq(interruptRequest); if (interruptTraceFifo.notFull()) interruptTraceFifo.enq(interruptRequest); endmethod endinterface interface Get interruptTrace; method ActionValue#(Tuple2#(Bit#(64),Bit#(32))) get(); let req = interruptTraceFifo.first(); interruptTraceFifo.deq(); return tuple2(req.addr, req.data); endmethod endinterface endmodule: mkMemInterrupt ================================================ FILE: bsv/PcieTop.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector :: *; import Clocks :: *; import GetPut :: *; import FIFO :: *; import Connectable :: *; import ClientServer :: *; import DefaultValue :: *; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" import PcieSplitter :: *; import Xilinx :: *; import Portal :: *; import Top :: *; import PcieCsr :: *; import ConnectalMemTypes :: *; import Bscan :: *; import ConnectalClocks :: *; import GetPutWithClocks :: *; `ifdef XILINX `ifdef PCIE3 `ifdef XilinxUltrascale import PCIEWRAPPER3u ::*; `else import PCIEWRAPPER3 :: *; `endif import Pcie3EndpointX7 :: *; `endif `ifdef PCIE2 import PCIEWRAPPER2 :: *; import Pcie2EndpointX7 :: *; `endif // pcie2 `ifdef PCIE1 import PCIEWRAPPER :: *; import Pcie1EndpointX7 :: *; `endif // pcie2 `elsif ALTERA import PcieEndpointS5 :: *; `endif import PcieHost :: *; import HostInterface :: *; import `PinTypeInclude::*; import Platform :: *; `ifndef DataBusWidth `define DataBusWidth 64 `endif `ifdef XILINX_SYS_CLK `ifdef VirtexUltrascalePlus `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, Clock sys_clk_300_p, Clock sys_clk_300_n, Clock sys_clk1_250_p, Clock sys_clk1_250_n, Clock sys_clk2_250_p, Clock sys_clk2_250_n, `define SYS_CLK_ARG sys_clk_p, sys_clk_n, sys_clk_300_p, sys_clk_300_n, sys_clk1_250_p, sys_clk1_250_n, sys_clk2_250_p, sys_clk2_250_n, `else `ifdef VirtexUltrascale `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, Clock sys_clk1_300_p, Clock sys_clk1_300_n, Clock sys_clk2_300_p, Clock sys_clk2_300_n, `define SYS_CLK_ARG sys_clk_p, sys_clk_n, sys_clk1_300_p, sys_clk1_300_n, sys_clk2_300_p, sys_clk2_300_n, `else `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, `define SYS_CLK_ARG sys_clk_p, sys_clk_n, `endif `endif `else `define SYS_CLK_PARAM `define SYS_CLK_ARG `endif // `ifdef XILINX_SYS_CLK // `ifdef VirtexUltrascale // `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, Clock sys_clk1_300_p, Clock sys_clk1_300_n, Clock sys_clk2_300_p, Clock sys_clk2_300_n, // `define SYS_CLK_ARG sys_clk_p, sys_clk_n, sys_clk1_300_p, sys_clk1_300_n, sys_clk2_300_p, sys_clk2_300_n, // `else // `define SYS_CLK_PARAM Clock sys_clk_p, Clock sys_clk_n, // `define SYS_CLK_ARG sys_clk_p, sys_clk_n, // `endif // `else // `define SYS_CLK_PARAM // `define SYS_CLK_ARG // `endif (* synthesize, no_default_clock, no_default_reset *) `ifdef XILINX module mkPcieTop #(Clock pci_sys_clk_p, Clock pci_sys_clk_n, `SYS_CLK_PARAM Reset pci_sys_reset_n) (PcieTop#(`PinType)); PcieHostTop host <- mkPcieHostTop(pci_sys_clk_p, pci_sys_clk_n, `SYS_CLK_ARG pci_sys_reset_n); `elsif ALTERA (* clock_prefix="", reset_prefix="" *) module mkPcieTop #(Clock pcie_refclk_p, Clock osc_50_b3b, Reset pcie_perst_n) (PcieTop#(`PinType)); PcieHostTop host <- mkPcieHostTop(pcie_refclk_p, osc_50_b3b, pcie_perst_n); `endif Vector#(NumberOfUserTiles,ConnectalTop#(`PinType)) tile <- replicateM(mkConnectalTop( `ifdef IMPORT_HOSTIF // no synthesis boundary host, `else // enables synthesis boundary `ifdef IMPORT_HOST_CLOCKS host.derivedClock, host.derivedReset, `endif `endif clocked_by host.portalClock, reset_by host.portalReset)); Platform portalTop <- mkPlatform(tile, clocked_by host.portalClock, reset_by host.portalReset); if (mainClockPeriod == pcieClockPeriod) begin mkConnection(host.tpciehost.master, portalTop.slave, clocked_by host.portalClock, reset_by host.portalReset); if (valueOf(NumberOfMasters) > 0) begin for ( Integer i = 0; i < valueOf(NumberOfMasters); i = i + 1) begin `ifndef USE_WIDE_WIDTH mkConnection(portalTop.masters[i], host.tpciehost.slave[i]); `else let memCnx <- GetPutWithClocks::mkConnectionWithGearbox(host.portalClock, host.portalReset, host.pcieClock, host.pcieReset, portalTop.masters[i], host.tpciehost.slave[i]); `endif end end end else begin let portalCnx <- GetPutWithClocks::mkConnectionWithClocks(host.pcieClock, host.pcieReset, host.portalClock, host.portalReset, host.tpciehost.master, portalTop.slave); if (valueOf(NumberOfMasters) > 0) begin //zipWithM_(GetPutWithClocks::mkConnectionWithClocks2, portalTop.masters, host.tpciehost.slave); for (Integer i = 0; i < valueOf(NumberOfMasters); i = i + 1) begin `ifndef USE_WIDE_WIDTH GetPutWithClocks::mkConnectionWithClocks(host.portalClock, host.portalReset, host.pcieClock, host.pcieReset, portalTop.masters[i], host.tpciehost.slave[i]); `else let memCnx <- GetPutWithClocks::mkConnectionWithGearbox(host.portalClock, host.portalReset, host.pcieClock, host.pcieReset, portalTop.masters[i], host.tpciehost.slave[i]); `endif end end end // going from level to edge-triggered interrupt FIFO#(Bit#(4)) intrFifo <- mkFIFO(clocked_by host.portalClock, reset_by host.portalReset); //(8, host.portalClock, host.portalReset, host.pcieClock); Vector#(16, Reg#(Bool)) interruptRequested <- replicateM(mkReg(False, clocked_by host.portalClock, reset_by host.portalReset)); rule interrupt_rule; Maybe#(Bit#(4)) intr = tagged Invalid; for (Integer i = 0; i < 16; i = i + 1) begin if (portalTop.interrupt[i] && !interruptRequested[i]) intr = tagged Valid fromInteger(i); interruptRequested[i] <= portalTop.interrupt[i]; end if (intr matches tagged Valid .intr_num) begin intrFifo.enq(intr_num); end endrule Put#(Bit#(4)) intrPut = (interface Put; method Action put(Bit#(4) intr_num); ReadOnly_MSIX_Entry msixEntry = host.tpciehost.msixEntry[intr_num]; host.tpciehost.interruptRequest.put(tuple2({msixEntry.addr_hi, msixEntry.addr_lo}, msixEntry.msg_data)); endmethod endinterface); GetPutWithClocks::mkConnectionWithClocks(host.portalClock, host.portalReset, host.pcieClock, host.pcieReset, toGet(intrFifo), intrPut); interface pcie = host.tep7.pcie; interface pins = portalTop.pins; endmodule ================================================ FILE: bsv/PcieTracer.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector :: *; import Clocks :: *; import GetPut :: *; import Connectable :: *; import FIFO :: *; import FIFOF :: *; import PCIE :: *; import BRAM :: *; import BramMux :: *; import ConnectalBram ::*; `include "ConnectalProjectConfig.bsv" `ifdef PCIE_BSCAN `define PCIE_ALT_BRAM_SERVER `endif typedef 11 TlpTraceAddrSize; typedef TAdd#(TlpTraceAddrSize,1) TlpTraceAddrSize1; typedef struct { Bit#(32) timestamp; Bit#(7) source; // 4==frombus 8=tobus TLPData#(16) tlp; // 153 bits } TimestampedTlpData deriving (Bits); typedef SizeOf#(TimestampedTlpData) TimestampedTlpDataSize; typedef SizeOf#(TLPData#(16)) TlpData16Size; typedef SizeOf#(TLPCompletionHeader) TLPCompletionHeaderSize; interface TlpTrace; interface Get#(TimestampedTlpData) tlp; endinterface interface TlpTraceServer; interface Reg#(Bool) tlpTracing; interface Reg#(Bit#(TlpTraceAddrSize)) tlpTraceLimit; interface Reg#(Bit#(TlpTraceAddrSize)) tlpTraceBramWrAddr; interface BRAMServer#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData) bramServer; `ifdef PCIE_ALT_BRAM_SERVER interface BRAMServer#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData) altBramServer; `endif endinterface interface TlpTraceClient; interface Reg#(Bool) tlpTracing; interface Reg#(Bit#(TlpTraceAddrSize)) tlpTraceLimit; interface Reg#(Bit#(TlpTraceAddrSize)) tlpTraceBramWrAddr; interface BRAMClient#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData) bramClient; endinterface interface PcieTracer; interface Client#(TLPData#(16), TLPData#(16)) pci; interface Put#(TimestampedTlpData) trace; interface Server#(TLPData#(16), TLPData#(16)) bus; interface TlpTraceServer traceServer; endinterface: PcieTracer // The PCIe-to-AXI bridge puts all of the elements together (* synthesize *) module mkPcieTracer(PcieTracer); // Trace Support Reg#(Bool) tlpTracingReg <- mkReg(False); Reg#(Bit#(TlpTraceAddrSize)) tlpTraceLimitReg <- mkReg(0); FIFOF#(Bit#(TlpTraceAddrSize)) tlpTraceBramWrAddrFifo <- mkFIFOF(); Reg#(Bit#(TlpTraceAddrSize)) tlpTraceBramWrAddrReg <- mkReg(0); Integer memorySize = 2**valueOf(TlpTraceAddrSize); BRAM_Configure bramCfg = defaultValue; bramCfg.memorySize = memorySize; bramCfg.latency = 1; `ifdef PCIE_ALT_BRAM_SERVER BRAM2Port#(Bit#(TlpTraceAddrSize), TimestampedTlpData) fromPcieTraceBram <- ConnectalBram::mkBRAM2Server(bramCfg); BRAM2Port#(Bit#(TlpTraceAddrSize), TimestampedTlpData) toPcieTraceBram <- ConnectalBram::mkBRAM2Server(bramCfg); `else BRAM1Port#(Bit#(TlpTraceAddrSize), TimestampedTlpData) fromPcieTraceBram <- ConnectalBram::mkBRAM1Server(bramCfg); BRAM1Port#(Bit#(TlpTraceAddrSize), TimestampedTlpData) toPcieTraceBram <- ConnectalBram::mkBRAM1Server(bramCfg); `endif Vector#(2, BRAMServer#(Bit#(TlpTraceAddrSize), TimestampedTlpData)) bramServers; bramServers[0] = fromPcieTraceBram.portA; bramServers[1] = toPcieTraceBram.portA; Reg#(Bool) tlpNotTracingReg = (interface Reg; method Bool _read(); return !tlpTracingReg; endmethod method Action _write(Bool w); endmethod endinterface); BramServerMux#(TAdd#(TlpTraceAddrSize,1), TimestampedTlpData) bramMuxReg <- mkGatedBramServerMux(tlpNotTracingReg, bramServers); `ifdef PCIE_ALT_BRAM_SERVER Vector#(2, BRAMServer#(Bit#(TlpTraceAddrSize), TimestampedTlpData)) altBramServers; altBramServers[0] = fromPcieTraceBram.portB; altBramServers[1] = toPcieTraceBram.portB; BramServerMux#(TAdd#(TlpTraceAddrSize,1), TimestampedTlpData) altBramMux <- mkBramServerMux(altBramServers); `endif Reg#(Bit#(32)) timestamp <- mkReg(0); rule incTimestamp; timestamp <= timestamp + 1; endrule // rule endTrace if (tlpTracingReg && tlpTraceLimitReg != 0 && tlpTraceBramWrAddr > truncate(tlpTraceLimitReg)); // tlpTracingReg <= False; // endrule FIFO#(TLPData#(16)) tlpFromBusFifo <- mkFIFO(); FIFO#(TLPData#(16)) tlpToBusFifo <- mkFIFO(); FIFO#(TLPData#(16)) tlpBusResponseFifo <- mkFIFO(); Reg#(Bool) skippingIncomingTlps <- mkReg(False); FIFO#(Bool) isRootBroadcastMessage <- mkFIFO(); PulseWire fromPcie <- mkPulseWire; PulseWire toPcie <- mkPulseWire; Wire#(TLPData#(16)) fromPcieTlp <- mkDWire(unpack(0)); Wire#(TLPData#(16)) toPcieTlp <- mkDWire(unpack(0)); rule sniffTlpFromBus; let tlp <- toGet(tlpFromBusFifo).get(); tlpBusResponseFifo.enq(tlp); TLPMemoryIO3DWHeader hdr_3dw = unpack(tlp.data); // skip root_broadcast_messages sent to tlp.hit 0 isRootBroadcastMessage.enq(tlp.sof && tlp.hit == 0 && hdr_3dw.pkttype != COMPLETION); endrule rule doTracing if (tlpTracingReg && (fromPcie || toPcie)); TimestampedTlpData fromttd = fromPcie ? TimestampedTlpData { timestamp: timestamp, source: 7'h04, tlp: fromPcieTlp } : unpack(0); let writeAddr = tlpTraceBramWrAddrReg; if (tlpTraceBramWrAddrFifo.notEmpty) writeAddr <- toGet(tlpTraceBramWrAddrFifo).get(); fromPcieTraceBram.portA.request.put(BRAMRequest{ write: True, responseOnWrite: False, address: writeAddr, datain: fromttd }); TimestampedTlpData tottd = toPcie ? TimestampedTlpData { timestamp: timestamp, source: 7'h08, tlp: toPcieTlp } : unpack(0); toPcieTraceBram.portA.request.put(BRAMRequest{ write: True, responseOnWrite: False, address: writeAddr, datain: tottd }); tlpTraceBramWrAddrReg <= writeAddr + 1; endrule interface Server bus; interface Get response; method ActionValue#(TLPData#(16)) get(); let tlp <- toGet(tlpBusResponseFifo).get(); if (tlpTracingReg) begin if (tlp.sof && isRootBroadcastMessage.first) begin skippingIncomingTlps <= True; end else if (skippingIncomingTlps && !tlp.sof) begin // do nothing end else begin fromPcie.send(); fromPcieTlp <= tlp; skippingIncomingTlps <= False; end end isRootBroadcastMessage.deq(); return tlp; endmethod endinterface interface Put request; method Action put(TLPData#(16) tlp); tlpToBusFifo.enq(tlp); if (tlpTracingReg) begin toPcie.send(); toPcieTlp <= tlp; end endmethod endinterface endinterface interface Client pci; interface request = toGet(tlpToBusFifo); interface response = toPut(tlpFromBusFifo); endinterface interface Put trace; method Action put(TimestampedTlpData ttd) if (!fromPcie && !toPcie); if (tlpTracingReg) begin ttd.timestamp = timestamp; toPcieTraceBram.portA.request.put(BRAMRequest{ write: True, responseOnWrite: False, address: truncate(tlpTraceBramWrAddrReg), datain: ttd }); tlpTraceBramWrAddrReg <= tlpTraceBramWrAddrReg + 1; end endmethod endinterface: trace interface TlpTraceServer traceServer; interface Reg tlpTracing = tlpTracingReg; interface Reg tlpTraceLimit = tlpTraceLimitReg; interface Reg tlpTraceBramWrAddr; method Bit#(TlpTraceAddrSize) _read(); return tlpTraceBramWrAddrReg; endmethod method Action _write(Bit#(TlpTraceAddrSize) v); tlpTraceBramWrAddrFifo.enq(v); endmethod endinterface interface Server bramServer = bramMuxReg.bramServer; `ifdef PCIE_ALT_BRAM_SERVER interface Server altBramServer = altBramMux.bramServer; `endif endinterface endmodule: mkPcieTracer instance Connectable#(TlpTraceClient,TlpTraceServer); module mkConnection#(TlpTraceClient client, TlpTraceServer tracer)(Empty); mkConnection(client.bramClient, tracer.bramServer); Reg#(Bool) tlpTracingReg <- mkReg(False); Reg#(Bit#(TlpTraceAddrSize)) tlpTraceLimitReg <- mkReg(0); Reg#(Bit#(TlpTraceAddrSize)) tlpTraceBramWrAddrReg <- mkReg(0); rule tracingRule if (tlpTracingReg != client.tlpTracing); tracer.tlpTracing <= client.tlpTracing; tlpTracingReg <= client.tlpTracing; endrule rule traceLimitRule if (tlpTraceLimitReg != client.tlpTraceLimit); tracer.tlpTraceLimit <= client.tlpTraceLimit; tlpTraceLimitReg <= client.tlpTraceLimit; endrule // both client and server update the tlpBramWrAddr rule traceBramWrAddrRule if (tlpTraceBramWrAddrReg != client.tlpTraceBramWrAddr); tracer.tlpTraceBramWrAddr <= client.tlpTraceBramWrAddr; tlpTraceBramWrAddrReg <= client.tlpTraceBramWrAddr; endrule endmodule endinstance ================================================ FILE: bsv/PhysMemSlaveFromBram.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFOF::*; import FIFO::*; import GetPut::*; import ConnectalMemTypes::*; import AddressGenerator::*; import BRAM::*; import Memory::*; module mkPhysMemSlaveFromBram#(BRAMServer#(Bit#(bramAddrWidth), Bit#(busDataWidth)) br) (PhysMemSlave#(busAddrWidth, busDataWidth)) provisos(Add#(a__, bramAddrWidth, busAddrWidth)); FIFOF#(Bit#(6)) readTagFifo <- mkFIFOF(); FIFOF#(Bit#(6)) writeTagFifo <- mkFIFOF(); FIFO#(Bool) readLastFifo <- mkFIFO(); AddressGenerator#(busAddrWidth,busDataWidth) readAddrGenerator <- mkAddressGenerator(); AddressGenerator#(busAddrWidth,busDataWidth) writeAddrGenerator <- mkAddressGenerator(); let verbose = False; Reg#(Bit#(32)) cycles <- mkReg(0); rule count; cycles <= cycles + 1; endrule rule read_req; let addrBeat <- readAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; let tag = addrBeat.tag; let burstCount = addrBeat.bc; readTagFifo.enq(tag); readLastFifo.enq(addrBeat.last); Bit#(bramAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); br.request.put(BRAMRequest{write:False, responseOnWrite:False, address:regFileAddr, datain:?}); if (verbose) $display("%d read_server.readData (a) %h %d last=%d", cycles, addr, burstCount, addrBeat.last); endrule interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(busAddrWidth, busDataWidth) req); if (verbose) $display("%d axiSlave.read.readAddr %h bc %d", cycles, req.addr, req.burstLen); readAddrGenerator.request.put(req); endmethod endinterface interface Get readData; method ActionValue#(MemData#(busDataWidth)) get(); let tag = readTagFifo.first; readTagFifo.deq; readLastFifo.deq; let data <- br.response.get; if (verbose) $display("%d read_server.readData (b) %h", cycles, data); return MemData { data: data, tag: tag, last: readLastFifo.first }; endmethod endinterface endinterface interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(busAddrWidth, busDataWidth) req); writeAddrGenerator.request.put(req); if (verbose) $display("%d write_server.writeAddr %h bc %d", cycles, req.addr, req.burstLen); endmethod endinterface interface Put writeData; method Action put(MemData#(busDataWidth) resp); let addrBeat <- writeAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; Bit#(bramAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:regFileAddr, datain:resp.data}); if (verbose) $display("%d write_server.writeData %h %h %d", cycles, addr, resp.data, addrBeat.bc); if (addrBeat.last) writeTagFifo.enq(addrBeat.tag); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(6)) get(); writeTagFifo.deq; return writeTagFifo.first; endmethod endinterface endinterface endmodule module mkPhysMemSlaveFromBramBE#(BRAMServerBE#(Bit#(bramAddrWidth), Bit#(busDataWidth), dataWidthBytes) br) (PhysMemSlave#(busAddrWidth, busDataWidth)) provisos(Add#(a__, bramAddrWidth, busAddrWidth) ,Mul#(dataWidthBytes, 8, busDataWidth) ,Div#(busDataWidth, 8, dataWidthBytes) ); let verbose = False; FIFOF#(Bit#(6)) readTagFifo <- mkFIFOF(); FIFOF#(Bit#(6)) writeTagFifo <- mkFIFOF(); FIFO#(Bool) readLastFifo <- mkFIFO(); FIFOF#(Bit#(TDiv#(busDataWidth, 8))) readByteEnableFifo <- mkFIFOF; FIFOF#(Bit#(TDiv#(busDataWidth, 8))) writeByteEnableFifo <- mkFIFOF; AddressGenerator#(busAddrWidth,busDataWidth) readAddrGenerator <- mkAddressGenerator(); AddressGenerator#(busAddrWidth,busDataWidth) writeAddrGenerator <- mkAddressGenerator(); FIFO#(PhysMemRequest#(busAddrWidth, busDataWidth)) req_ars <- mkFIFO1; FIFO#(Bit#(bramAddrWidth)) req_addr <- mkFIFO1; FIFO#(BRAMRequestBE#(Bit#(bramAddrWidth), Bit#(busDataWidth), dataWidthBytes)) req_aws <- mkFIFO1; Reg#(Bit#(32)) cycles <- mkReg(0); rule count if (verbose); cycles <= cycles + 1; endrule rule req_ar; let req <- toGet(req_ars).get; readAddrGenerator.request.put(req); endrule rule read_req; let addrBeat <- readAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; let tag = addrBeat.tag; let burstCount = addrBeat.bc; readTagFifo.enq(tag); readLastFifo.enq(addrBeat.last); Bit#(bramAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); req_addr.enq(regFileAddr); if (verbose) $display("%d read_server.readData (a) %h %d last=%d", cycles, addr, burstCount, addrBeat.last); endrule rule read_bram_req; let addr <- toGet(req_addr).get; br.request.put(BRAMRequestBE{writeen:0, responseOnWrite:False, address:addr, datain:?}); endrule rule req_aw; let req <- toGet(req_aws).get; br.request.put(req); endrule interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(busAddrWidth, busDataWidth) req); if (verbose) $display("%d read_server.readAddr %h bc %d fbe %x lbe %x", cycles, req.addr, req.burstLen `ifdef BYTE_ENABLES , req.firstbe, req.lastbe `endif ); req_ars.enq(req); readByteEnableFifo.enq(reqLastByteEnable(req)); endmethod endinterface interface Get readData; method ActionValue#(MemData#(busDataWidth)) get(); let tag = readTagFifo.first; readTagFifo.deq; readLastFifo.deq; let data <- br.response.get; let readBE = readByteEnableFifo.first; Bit#(dataWidthBytes) byteEnable = readLastFifo.first ? readBE : maxBound; let newdata = updateDataWithMask(0, data, byteEnable); if (verbose) $display("%d read_server.readData (b) %h, %h", cycles, data, newdata); if (readLastFifo.first) begin readByteEnableFifo.deq; end return MemData { data: newdata, tag: tag, last: readLastFifo.first }; endmethod endinterface endinterface interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(busAddrWidth, busDataWidth) req); writeAddrGenerator.request.put(req); writeByteEnableFifo.enq(reqLastByteEnable(req)); if (verbose) $display("%d write_server.writeAddr %h bc %d fbe %x lbe %x", cycles, req.addr, req.burstLen `ifdef BYTE_ENABLES , req.firstbe, req.lastbe `endif ); endmethod endinterface interface Put writeData; method Action put(MemData#(busDataWidth) resp); let addrBeat <- writeAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; Bit#(bramAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); let writeBE = writeByteEnableFifo.first; Bit#(dataWidthBytes) byteEnable = addrBeat.last ? writeBE : maxBound; req_aws.enq(BRAMRequestBE{writeen:byteEnable, responseOnWrite:False, address:regFileAddr, datain:resp.data}); if (verbose) $display("%d write_server.writeData %h %h %d", cycles, addr, resp.data, addrBeat.bc); if (addrBeat.last) writeByteEnableFifo.deq; writeTagFifo.enq(addrBeat.tag); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(6)) get(); writeTagFifo.deq; return writeTagFifo.first; endmethod endinterface endinterface endmodule module mkMemServerFromBram#(BRAMServer#(Bit#(bramAddrWidth), Bit#(busDataWidth)) br) (MemServer#(busDataWidth)) provisos(Add#(a__, bramAddrWidth, MemOffsetSize)); FIFOF#(Tuple2#(Bit#(6),Bool)) readTagFifo <- mkFIFOF(); FIFOF#(Bit#(6)) writeTagFifo <- mkFIFOF(); AddressGenerator#(bramAddrWidth,busDataWidth) readAddrGenerator <- mkAddressGenerator(); AddressGenerator#(bramAddrWidth,busDataWidth) writeAddrGenerator <- mkAddressGenerator(); let verbose = False; Reg#(Bit#(32)) cycles <- mkReg(0); rule count; cycles <= cycles + 1; endrule rule read_req; let addrBeat <- readAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; let tag = addrBeat.tag; let burstCount = addrBeat.bc; readTagFifo.enq(tuple2(tag, addrBeat.last)); Bit#(bramAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); br.request.put(BRAMRequest{write:False, responseOnWrite:False, address:regFileAddr, datain:?}); if (verbose) $display("%d read_server.readData (a) %h %d last=%d", cycles, addr, burstCount, addrBeat.last); endrule interface MemReadServer readServer; interface Put readReq; method Action put(MemRequest req); if (verbose) $display("%d axiSlave.read.readAddr %h bc %d", cycles, req.offset, req.burstLen); readAddrGenerator.request.put(PhysMemRequest { addr: truncate(req.offset), burstLen: req.burstLen, tag: req.tag }); endmethod endinterface interface Get readData; method ActionValue#(MemData#(busDataWidth)) get(); match { .tag, .last } = readTagFifo.first; readTagFifo.deq; let data <- br.response.get; if (verbose) $display("%d read_server.readData (b) %h", cycles, data); return MemData { data: data, tag: tag, last: last }; endmethod endinterface endinterface interface MemWriteServer writeServer; interface Put writeReq; method Action put(MemRequest req); writeAddrGenerator.request.put(PhysMemRequest { addr: truncate(req.offset), burstLen: req.burstLen, tag: req.tag}); if (verbose) $display("%d write_server.writeAddr %h bc %d", cycles, req.offset, req.burstLen); endmethod endinterface interface Put writeData; method Action put(MemData#(busDataWidth) resp); let addrBeat <- writeAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; Bit#(bramAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:regFileAddr, datain:resp.data}); if (verbose) $display("%d write_server.writeData %h %h %d", cycles, addr, resp.data, addrBeat.bc); if (addrBeat.last) writeTagFifo.enq(addrBeat.tag); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(6)) get(); writeTagFifo.deq; return writeTagFifo.first; endmethod endinterface endinterface endmodule ================================================ FILE: bsv/Pipe.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import Connectable::*; import Vector::*; import BuildVector::*; import MIMO::*; import DefaultValue::*; import Gearbox::*; import Clocks::*; import AxiStream::*; typedef Tuple3#(x,x,x) Triplet#(type x); typedef Tuple2#(x,x) Pair#(type x); interface PipeIn#(type a); method Action enq(a v); method Bool notFull(); endinterface interface PipeOut#(type a); method a first(); method Action deq(); method Bool notEmpty(); endinterface function Bool pipeInNotFull(PipeIn#(a) pipein); return pipein.notFull(); endfunction function Bool pipeOutNotEmpty(PipeOut#(a) pipein); return pipein.notEmpty(); endfunction typeclass ToPipeIn#(type a, type b) dependencies (b determines a); function PipeIn#(a) toPipeIn(b in); endtypeclass typeclass ToPipeOut#(type a, type b) dependencies ( b determines a); function PipeOut#(a) toPipeOut(b in); endtypeclass typeclass MkPipeOut#(type a, type b) dependencies ( b determines a); module mkPipeOut#(b in)(PipeOut#(a)); endtypeclass typeclass MkPipeIn#(type a, type b) dependencies ( b determines a); module mkPipeIn#(b in)(PipeIn#(a)); endtypeclass instance ToPipeIn#(a, FIFOF#(a)); function PipeIn#(a) toPipeIn(FIFOF#(a) in); return (interface PipeIn#(a); method enq = in.enq; method notFull = in.notFull; endinterface); endfunction endinstance instance ToPipeOut#(a, function a pipefn()); function PipeOut#(a) toPipeOut(function a pipefn()); return (interface PipeOut#(a); method first(); return pipefn(); endmethod method Action deq(); endmethod method Bool notEmpty(); return False; endmethod endinterface); endfunction endinstance instance ToPipeOut#(a, Reg#(a)); function PipeOut#(a) toPipeOut(Reg#(a) in); return (interface PipeOut#(a); method first(); return in; endmethod method Action deq(); endmethod method Bool notEmpty(); return False; endmethod endinterface); endfunction endinstance instance ToPipeIn#(a, Gearbox#(1, n, a)); function PipeIn#(a) toPipeIn(Gearbox#(1, n, a) in); return (interface PipeIn#(a); method Action enq(a v); in.enq(vec(v)); endmethod method notFull = in.notFull; endinterface); endfunction endinstance instance ToPipeIn#(Vector#(m, a), Gearbox#(m, n, a)); function PipeIn#(Vector#(m, a)) toPipeIn(Gearbox#(m, n, a) in); return (interface PipeIn#(Vector#(m, a)); method enq = in.enq; method notFull = in.notFull; endinterface); endfunction endinstance instance ToPipeOut#(a, FIFOF#(a)); function PipeOut#(a) toPipeOut(FIFOF#(a) in); return (interface PipeOut#(a); method first = in.first; method deq = in.deq; method notEmpty = in.notEmpty; endinterface); endfunction endinstance instance ToPipeOut#(Vector#(n,a), MIMO#(k,n,sz,a)); function PipeOut#(Vector#(n,a)) toPipeOut(MIMO#(k,n,sz,a) in); return (interface PipeOut#(a); method first = in.first; method Action deq() if (in.deqReadyN(fromInteger(valueOf(n)))); in.deq(fromInteger(valueOf(n))); endmethod method Bool notEmpty(); return in.deqReadyN(fromInteger(valueOf(n))); endmethod endinterface); endfunction endinstance instance ToPipeOut#(Vector#(n, a), Gearbox#(m, n, a)); function PipeOut#(Vector#(n, a)) toPipeOut(Gearbox#(m, n, a) in); return (interface PipeOut#(Vector#(n,a)); method first = in.first; method deq = in.deq; method notEmpty = in.notEmpty; endinterface); endfunction endinstance instance ToPipeOut#(a, Gearbox#(m, 1, a)); function PipeOut#(a) toPipeOut(Gearbox#(m, 1, a) in); return (interface PipeOut#(a); method a first(); return in.first[0]; endmethod method deq = in.deq; method notEmpty = in.notEmpty; endinterface); endfunction endinstance instance ToPipeIn#(a, SyncFIFOIfc#(a)); function PipeIn#(a) toPipeIn(SyncFIFOIfc#(a) in); return (interface PipeIn#(a); method enq = in.enq; method notFull = in.notFull; endinterface); endfunction endinstance instance ToPipeOut#(a, SyncFIFOIfc#(a)); function PipeOut#(a) toPipeOut(SyncFIFOIfc#(a) in); return (interface PipeOut#(a); method first = in.first; method deq = in.deq; method notEmpty = in.notEmpty; endinterface); endfunction endinstance instance MkPipeOut#(a, ActionValue#(a)) provisos (Bits#(a, asz)); module mkPipeOut#(ActionValue#(a) in)(PipeOut#(a)); FIFOF#(a) fifo <- mkFIFOF(); rule connect; let v <- in; fifo.enq(v); endrule return toPipeOut(fifo); endmodule endinstance instance MkPipeOut#(a, Get#(a)) provisos (Bits#(a, asz)); module mkPipeOut#(Get#(a) in)(PipeOut#(a)); FIFOF#(a) fifo <- mkFIFOF(); rule connect; let v <- in.get(); fifo.enq(v); endrule return toPipeOut(fifo); endmodule endinstance instance MkPipeIn#(a, Put#(a)) provisos (Bits#(a, asz)); module mkPipeIn#(Put#(a) out)(PipeIn#(a)); FIFOF#(a) fifo <- mkFIFOF(); rule connect; let v <- toGet(fifo).get; out.put(v); endrule return toPipeIn(fifo); endmodule endinstance function PipeOut#(a) toCountedPipeOut(Reg#(Bit#(n)) r, PipeOut#(a) pipe); return (interface PipeOut#(Vector#(n,a)); method first = pipe.first; method Action deq(); pipe.deq; r <= r + 1; endmethod method notEmpty = pipe.notEmpty; endinterface); endfunction instance ToGet #(PipeOut #(a), a); function Get #(a) toGet (PipeOut #(a) po); return (interface Get; method ActionValue #(a) get (); po.deq (); return po.first (); endmethod endinterface); endfunction endinstance instance ToPut #(PipeIn #(a), a); function Put #(a) toPut (PipeIn #(a) pi); return (interface Put; method Action put(a v); pi.enq (v); endmethod endinterface); endfunction endinstance instance Connectable#(PipeOut#(a),Put#(a)); module mkConnection#(PipeOut#(a) in, Put#(a) out)(Empty); rule connect if (in.notEmpty); let v = in.first; in.deq(); out.put(v); endrule endmodule endinstance instance Connectable#(ActionValue#(a),PipeIn#(a)); module mkConnection#(ActionValue#(a) in, PipeIn#(a) out)(Empty); rule connect; let v <- in; out.enq(v); endrule endmodule endinstance instance Connectable#(PipeOut#(a),PipeIn#(a)); module mkConnection#(PipeOut#(a) in, PipeIn#(a) out)(Empty); rule connect if (in.notEmpty); let v = in.first; in.deq(); out.enq(v); endrule endmodule endinstance function PipeOut#(a) unvectorPipeOut(PipeOut#(Vector#(1,a)) in); return (interface PipeOut#(a); method first = in.first[0]; method deq = in.deq; method notEmpty = in.notEmpty; endinterface); endfunction function PipeOut#(Tuple2#(a,b)) zipPipeOut(PipeOut#(a) ina, PipeOut#(b) inb); return (interface PipeOut#(Tuple2#(a,b)); method Tuple2#(a,b) first(); return tuple2(ina.first, inb.first); endmethod method Action deq(); ina.deq(); inb.deq(); endmethod method Bool notEmpty(); return ina.notEmpty() && inb.notEmpty(); endmethod endinterface); endfunction module mkFunnel#(PipeOut#(Vector#(mk,a)) in)(PipeOut#(Vector#(m, a))) provisos (Mul#(m, k, mk), Bits#(a, asz), Add#(a__, TMul#(asz, m), TMul#(asz, mk)), Add#(1, b__, asz), Add#(2, c__, mk), Add#(d__, m, mk), Add#(asz, m, e__), Add#(asz, mk, f__)); let m = fromInteger(valueOf(m)); let mk = fromInteger(valueOf(mk)); MIMOConfiguration cfg = defaultValue(); MIMO#(mk, m, mk, a) mimo <- mkMIMO(cfg); rule consumer if (mimo.enqReadyN(mk)); Vector#(mk, a) v = in.first(); in.deq(); mimo.enq(mk, v); endrule method Vector#(m, a) first() if (mimo.deqReadyN(m)); return mimo.first(); endmethod method Action deq() if (mimo.deqReadyN(m)); mimo.deq(m); endmethod method notEmpty(); return mimo.deqReadyN(m); endmethod endmodule module mkFunnel1#(PipeOut#(Vector#(k,a)) in)(PipeOut#(a)) provisos (Bits#(a, asz), Log#(k,ksz)); Reg#(Bit#(ksz)) selector <- mkReg(0); method a first(); return in.first[selector]; endmethod method Action deq(); if (selector == fromInteger(valueOf(k)-1)) begin in.deq(); selector <= 0; end else selector <= selector + 1; endmethod method notEmpty(); return in.notEmpty(); endmethod endmodule module mkFunnelGB1#(Clock slowClock, Reset slowReset, Clock fastClock, Reset fastReset, PipeOut#(Vector#(k,a)) in)(PipeOut#(a)) provisos (Bits#(a, asz), Log#(k,ksz), Add#(1,a__,k)); Gearbox#(k,1,a) gb <- mkNto1Gearbox(slowClock, slowReset, fastClock, fastReset); PipeIn#(Vector#(k,a)) toGb = toPipeIn(gb); mkConnection(in, toGb); PipeOut#(Vector#(1,a)) fromGb = toPipeOut(gb); return mapPipe(head, fromGb); endmodule // 'j' is the width of the narrow end, and 'k' is the width of the wide end typedef Vector#(j,PipeOut#(a)) FunnelPipe#(numeric type j, numeric type k, type a, numeric type bitsPerCycle); typedef Vector#(k,PipeOut#(a)) UnFunnelPipe#(numeric type j, numeric type k, type a, numeric type bitsPerCycle); typeclass FunnelPipesPipelined#(numeric type j, numeric type k, type a, numeric type bpc); module mkFunnelPipesPipelined#(Vector#(k,PipeOut#(a)) in) (FunnelPipe#(j,k,a,bpc)); module mkFunnelPipesPipelinedRR#(Vector#(k,PipeOut#(a)) in, Integer c) (FunnelPipe#(j,k,a,bpc)); module mkUnFunnelPipesPipelined#(Vector#(j,PipeOut#(Tuple2#(Bit#(TLog#(k)),a))) in) (UnFunnelPipe#(j,k,a,bpc)); module mkUnFunnelPipesPipelinedRR#(Vector#(j,PipeOut#(a)) in, Integer c) (UnFunnelPipe#(j,k,a,bpc)); endtypeclass function PipeOut#(b) pipeSecond(PipeOut#(Tuple2#(a,b)) x) = (interface PipeOut; method b first; return tpl_2(x.first); endmethod method Action deq = x.deq; method Bool notEmpty = x.notEmpty; endinterface); instance FunnelPipesPipelined#(1,1,a,bpc) provisos (Bits#(a,a__)); module mkFunnelPipesPipelined#(Vector#(1,PipeOut#(a)) in) (FunnelPipe#(1,1,a,bpc)); return in; endmodule module mkFunnelPipesPipelinedRR#(Vector#(1,PipeOut#(a)) in, Integer c) (FunnelPipe#(1,1,a,bpc)); return in; endmodule module mkUnFunnelPipesPipelined#(Vector#(1,PipeOut#(Tuple2#(Bit#(0),a))) in) (UnFunnelPipe#(1,1,a,bpc)); return map(pipeSecond, in); endmodule module mkUnFunnelPipesPipelinedRR#(Vector#(1,PipeOut#(a)) in, Integer c) (UnFunnelPipe#(1,1,a,bpc)); return in; endmodule endinstance module mkUnFunnelPipesPipelinedInternal#(Vector#(1, PipeOut#(Tuple2#(Bit#(TLog#(k)),a))) in) (UnFunnelPipe#(1,k,a,bpc)) provisos (Log#(k, logk), Bits#(a,a__), Add#(1,b__,k), Div#(k,TExp#(bpc),c__), Mul#(c__,TExp#(bpc),krounded), Add#(1, d__, krounded), Add#(k, e__, krounded), Div#(logk,bpc,stages)); Vector#(krounded, PipeOut#(Tuple2#(Bit#(logk),a))) ins = append(in,replicate(?)); Vector#(krounded, PipeOut#(Tuple2#(Bit#(logk),a))) outs = newVector; for(Integer j = 0; j < valueOf(stages); j=j+1) begin for(Integer i = 0; i < min(valueOf(krounded), 2**(j*valueOf(bpc))); i=i+1) begin Integer bits = (j == valueOf(stages)-1) ? valueOf(logk)-(j*valueOf(bpc)) : valueOf(bpc); function Bit#(bpc) sh(Bit#(bpc) x) = x<<(valueOf(bpc)-bits); for(Integer l = 0; l < 2**bits; l=l+1) begin let buff <- mkFIFOF; // extra conditional in case 'k' is not a power of 2 let idx = (2**bits)*i+l; if (idx < valueOf(k)) begin outs[idx] = toPipeOut(buff); rule xfer if(tpl_1(ins[i].first)[(valueOf(logk)-1):max(0,(valueOf(logk)-valueOf(bpc)))] == sh(fromInteger(l))); match{.idx, .v} <- toGet(ins[i]).get; buff.enq(tuple2(idx< 0; j=j-1) begin Integer width = min(valueOf(krounded),2**(j*valueOf(bpc))); Integer stride = valueOf(TExp#(bpc)); Vector#(krounded,PipeOut#(a)) pipes = infss[j]; for(Integer i = 0; i < width && i < valueOf(k); i=i+stride) begin Vector#(TExp#(bpc),PipeOut#(a)) inpipes = takeAt(i, pipes); Integer numPipes = stride; if (i + stride > valueOf(k)) numPipes = valueOf(k) - i; mkFunnelNode(inpipes, numPipes, toPut(buffs[j-1][i/stride])); end end return vec(infss[0][0]); endmodule module mkFunnelPipesPipelinedRR#(Vector#(k,PipeOut#(a)) in, Integer c) (FunnelPipe#(1,k,a,bpc)); Vector#(stages, Vector#(k, FIFOF#(a))) buffs <- replicateM(replicateM(mkFIFOF)); Vector#(TAdd#(stages,1), Vector#(k, PipeOut#(a))) infss = append(map(map(toPipeOut),buffs), cons(in,nil)); for(Integer j = valueOf(stages); j > 0; j=j-1) begin Vector#(k, FIFOF#(void)) ctrl <- replicateM(mkFIFOF1()); for(Integer i = 0; i < 2**(j*valueOf(bpc)) && i < valueOf(k); i=i+1) begin let first = i==0; Reg#(Bit#(32)) cnt <- mkReg(0); let maxp = (2**((valueOf(stages)-j)*valueOf(bpc)))*c; let last = (maxp*(i+1) >= valueOf(k)*c); if (maxp*(i+1) > valueOf(k)*c) begin maxp = valueOf(k)*c-maxp*i; end let xfer_guard = True; if (!first) xfer_guard = xfer_guard && ctrl[(i-1)].notEmpty; if (!last) xfer_guard = xfer_guard && (!ctrl[i].notEmpty); rule xfer if (xfer_guard); let new_cnt = cnt+1; if (new_cnt==fromInteger(maxp)) begin cnt <= 0; if (!last) ctrl[i].enq(?); if (last) for(Integer ff = 0; ff < i; ff=ff+1) ctrl[ff].deq; end else begin cnt <= new_cnt; end let v <- toGet(infss[j][i]).get; toPut(buffs[j-1][i/(2**valueOf(bpc))]).put(v); endrule end end return cons(infss[0][0],nil); endmodule module mkUnFunnelPipesPipelined#(Vector#(1, PipeOut#(Tuple2#(Bit#(logk),a))) in) (UnFunnelPipe#(1,k,a,bpc)); (* hide *) let rv <- mkUnFunnelPipesPipelinedInternal(in); return rv; endmodule module mkUnFunnelPipesPipelinedRR#(Vector#(1, PipeOut#(a)) in, Integer c) (UnFunnelPipe#(1,k,a,bpc)); Vector#(1, FIFOF#(Tuple2#(Bit#(logk),a))) tagged_in_buffers <- replicateM(mkFIFOF); Vector#(1, PipeOut#(Tuple2#(Bit#(logk),a))) tagged_in = map(toPipeOut, tagged_in_buffers); let rv <- mkUnFunnelPipesPipelinedInternal(tagged_in); Reg#(Bit#(TAdd#(logk,1))) dest <- mkReg(0); Reg#(Bit#(32)) cnt <- mkReg(0); rule fill; let new_cnt = cnt+1; let new_dest = dest; if (new_cnt == fromInteger(c)) begin new_cnt = 0; new_dest = dest+1; if(new_dest==fromInteger(valueOf(k))) new_dest=0; end cnt <= new_cnt; dest <= new_dest; let v <- toGet(in[0]).get; tagged_in_buffers[0].enq(tuple2(truncate(dest),v)); //$display("mkUnFunnelPipesPipelinedInternal::fill %d", dest); endrule return rv; endmodule endinstance module mkUnfunnel#(PipeOut#(Vector#(m,a)) in)(PipeOut#(Vector#(mk, a))) provisos (Mul#(m, k, mk), Bits#(a, asz), Add#(1, b__, asz), Add#(2, c__, mk), Add#(d__, m, mk), Add#(asz, m, e__), Add#(asz, mk, f__)); let m = fromInteger(valueOf(m)); let mk = fromInteger(valueOf(mk)); MIMOConfiguration cfg = defaultValue(); MIMO#(m, mk, mk, a) mimo <- mkMIMO(cfg); rule consumer if (mimo.enqReadyN(m)); Vector#(m, a) v = in.first(); in.deq(); mimo.enq(m, v); endrule method Vector#(mk, a) first() if (mimo.deqReadyN(mk)); return mimo.first(); endmethod method Action deq() if (mimo.deqReadyN(mk)); mimo.deq(mk); endmethod method notEmpty(); return mimo.deqReadyN(mk); endmethod endmodule module mkUnfunnelGB#(Clock slowClock, Reset slowReset, Clock fastClock, Reset fastReset, PipeOut#(Vector#(1,a)) in)(PipeOut#(Vector#(k, a))) provisos (Bits#(a, asz), Add#(1, a__, k), Add#(1, b__, asz), Add#(1, c__, TMul#(2,k)), Add#(k, d__, TMul#(2,k)) ); let k = fromInteger(valueOf(k)); Gearbox#(1,k,a) gb <- mk1toNGearbox(fastClock, fastReset, slowClock, slowReset); PipeIn#(Vector#(1,a)) toGb = toPipeIn(gb); PipeOut#(Vector#(k,a)) fromGb = toPipeOut(gb); mkConnection(in,toGb); return fromGb; endmodule: mkUnfunnelGB module mkFunnelPipes#(Vector#(mk, PipeOut#(a)) ins)(Vector#(m, PipeOut#(a))) provisos (Mul#(m, k, mk), Bits#(a, asz), Log#(k,ksz) ); let k = fromInteger(valueOf(k)); let m = fromInteger(valueOf(m)); let mk = fromInteger(valueOf(mk)); Vector#(m, FIFOF#(a)) fifos <- replicateM(mkFIFOF); for (Integer i = 0; i < m; i = i+1) begin Reg#(Bit#(asz)) which <- mkReg(0); rule consumer; let index = (which << valueOf(ksz)) + fromInteger(i); let v <- toGet(ins[index]).get(); fifos[i].enq(v); which <= (which + 1) % k; endrule end return map(toPipeOut, fifos); endmodule module mkFunnelPipes1#(Vector#(k, PipeOut#(a)) ins)(PipeOut#(a)) provisos (Bits#(a, asz), Log#(k,ksz) ); let k = fromInteger(valueOf(k)); Reg#(Bit#(ksz)) selector <- mkReg(0); method a first(); return ins[selector].first(); endmethod method Action deq(); ins[selector].deq(); if (selector == fromInteger(valueOf(k)-1)) selector <= 0; else selector <= selector + 1; endmethod method Bool notEmpty(); return ins[selector].notEmpty(); endmethod endmodule module mkUnfunnelPipes#(Vector#(m, PipeOut#(a)) ins)(Vector#(mk, PipeOut#(a))) provisos (Mul#(m, k, mk), Log#(k,ksz), Bits#(a,asz)); let m = fromInteger(valueOf(m)); let k = fromInteger(valueOf(k)); let mk = fromInteger(valueOf(mk)); Vector#(mk, FIFOF#(a)) fifos <- replicateM(mkFIFOF); for (Integer i = 0; i < m; i = i + 1) begin Reg#(Bit#(TAdd#(1,ksz))) which <- mkReg(0); rule consumer; let index = which + fromInteger(i)*k; let v <- toGet(ins[i]).get(); fifos[index].enq(v); which <= (which + 1) % k; endrule end return map(toPipeOut, fifos); endmodule module mkRepeat#(UInt#(n) repetitions, PipeOut#(a) inpipe)(PipeOut#(a)); Reg#(UInt#(n)) count <- mkReg(0); method first = inpipe.first; method Action deq(); let c = count + 1; if (count == (repetitions - 1)) begin c = 0; inpipe.deq(); end count <= c; endmethod method notEmpty = inpipe.notEmpty; endmodule module mkForkVectorPipelined#(PipeOut#(a) inpipe)(UnFunnelPipe#(1,k,a,bpc)) provisos ( Bits#(a,a__) ,Add#(1,b__,k) ,Log#(k,logk) ,Div#(logk,bpc,stages)); Vector#(k, FIFOF#(a)) buffs = newVector; Vector#(k, PipeOut#(a)) infs = cons(inpipe,replicate(?)); for(Integer j = 0; j < valueOf(stages); j=j+1)begin for(Integer i = 0; i < 2**((j+1)*valueOf(bpc)) && i < valueOf(k); i=i+1) buffs[i] <- mkFIFOF; rule xfer; for(Integer i = 0; i < 2**(j*valueOf(bpc)) && i < valueOf(k); i=i+1) begin for(Integer l = 0; l < 2**valueOf(bpc) && l < valueOf(k); l=l+1) begin Integer idx = (i*(2**valueOf(bpc)))+l; if (idx < valueOf(k)) buffs[idx].enq(infs[i].first); end infs[i].deq; end endrule infs = map(toPipeOut, buffs); end return infs; endmodule module mkForkVector#(PipeOut#(a) inpipe)(Vector#(n, PipeOut#(a))) provisos (Bits#(a, asz)); Vector#(n, FIFOF#(a)) fifos <- replicateM(mkFIFOF()); rule forkelts; let v = inpipe.first(); inpipe.deq; for (Integer i = 0; i < valueOf(n); i = i + 1) begin fifos[i].enq(v); end endrule return map(toPipeOut, fifos); endmodule module mkSizedForkVector#(Integer size, PipeOut#(a) inpipe)(Vector#(n, PipeOut#(a))) provisos (Bits#(a, asz)); Vector#(n, FIFOF#(a)) fifos <- replicateM(mkSizedFIFOF(size)); rule forkelts; let v = inpipe.first(); inpipe.deq; for (Integer i = 0; i < valueOf(n); i = i + 1) begin fifos[i].enq(v); end endrule return map(toPipeOut, fifos); endmodule module mkJoin#(function c f(a av, b bv), PipeOut#(a) apipe, PipeOut#(b) bpipe)(PipeOut#(c)); method c first(); let av = apipe.first(); let bv = bpipe.first(); return f(av, bv); endmethod method Action deq(); apipe.deq(); bpipe.deq(); endmethod method Bool notEmpty(); return apipe.notEmpty() && bpipe.notEmpty(); endmethod endmodule module mkJoinBuffered#(function c f(a av, b bv), PipeOut#(a) apipe, PipeOut#(b) bpipe)(PipeOut#(c)) provisos (Bits#(c, csz)); FIFOF#(c) joinFifo <- mkFIFOF(); rule joinrule; let av <- toGet(apipe).get(); let bv <- toGet(bpipe).get(); joinFifo.enq(f(av, bv)); endrule return toPipeOut(joinFifo); endmodule module mkJoinVector#(function b f(Vector#(n, a) av), Vector#(n, PipeOut#(a)) apipes)(PipeOut#(b)) provisos (Bits#(Vector#(n,a),vasz)); method b first(); function a getfirst(PipeOut#(a) pipein); return pipein.first(); endfunction Vector#(n,a) vec = map(getfirst, apipes); return f(vec); endmethod method Action deq(); function a getfirst(PipeOut#(a) pipein); return pipein.first(); endfunction for (Integer i = 0; i < valueOf(n); i = i + 1) apipes[i].deq(); endmethod method Bool notEmpty(); function Bool myand(Bool a, Bool b); return a && b; endfunction return foldl(myand, True, map(pipeOutNotEmpty, apipes)); endmethod endmodule function PipeOut#(b) mapPipe(function b f(a av), PipeOut#(a) apipe); return (interface PipeOut#(b); method b first(); let av = apipe.first(); return f(av); endmethod method Action deq(); apipe.deq(); endmethod method Bool notEmpty(); return apipe.notEmpty(); endmethod endinterface); endfunction function PipeIn#(a) mapPipeIn(function b f(a av), PipeIn#(b) apipe); return (interface PipeIn#(b); method Action enq(a v); apipe.enq(f(v)); endmethod method Bool notFull(); return apipe.notFull(); endmethod endinterface); endfunction // buffered version of mapPipe module mkMapPipe#(function b f(a av), PipeOut#(a) apipe)(PipeOut#(b)) provisos (Bits#(b,bsz)); FIFOF#(b) fifo <- mkFIFOF(); rule compute; let v <- toGet(apipe).get(); fifo.enq(f(v)); endrule return toPipeOut(fifo); endmodule typedef (function tb f(ta x)) CombinePipe#(type ta, type tb); typeclass ReducePipe#( numeric type n, type a); module mkReducePipe#(CombinePipe#(Tuple2#(a,a), a) combinepipe, PipeOut#(Vector#(n,a)) inpipe) (PipeOut#(a)); module mkReducePipes#(CombinePipe#(Tuple2#(a,a), a) combinepipe, Vector#(n,PipeOut#(a)) inpipe) (PipeOut#(a)); endtypeclass instance ReducePipe#(1, a); module mkReducePipe#(CombinePipe#(Tuple2#(a,a), a) combinepipe, PipeOut#(Vector#(1,a)) inpipe) (PipeOut#(a)); let pipe = mapPipe(head, inpipe); return pipe; endmodule module mkReducePipes#(CombinePipe#(Tuple2#(a,a), a) combinepipe, Vector#(1,PipeOut#(a)) inpipes) (PipeOut#(a)); return inpipes[0]; endmodule endinstance instance ReducePipe#(2, a) provisos(Bits#(a,a__)); module mkReducePipe#(CombinePipe#(Tuple2#(a,a), a) combinepipe, PipeOut#(Vector#(2,a)) inpipe) (PipeOut#(a)); function a foo(Vector#(2,a) invec); return combinepipe(tuple2(invec[0], invec[1])); endfunction let pipe <- mkMapPipe(foo, inpipe); return pipe; endmodule module mkReducePipes#(CombinePipe#(Tuple2#(a,a), a) combinepipe, Vector#(2,PipeOut#(a)) inpipes) (PipeOut#(a)); function a foo(Tuple2#(a,a) invec); return combinepipe(invec); endfunction let pipe <- mkMapPipe(foo, zipPipeOut(inpipes[0], inpipes[1])); return pipe; endmodule endinstance instance ReducePipe#(n, a) provisos (Add#(TDiv#(n,2), a__, n), Bits#(Vector#(TDiv#(n,2), a), b__), ReducePipe#(TDiv#(n,2),a), ReducePipe#(TSub#(n, TDiv#(n, 2)), a) ); module mkReducePipe#(CombinePipe#(Tuple2#(a,a), a) combinepipe, PipeOut#(Vector#(n,a)) inpipe) (PipeOut#(a)); FIFOF#(Vector#(TDiv#(n,2),a)) infifo0 <- mkFIFOF; FIFOF#(Vector#(TSub#(n,TDiv#(n,2)),a)) infifo1 <- mkFIFOF; rule splitinput; let v = inpipe.first(); inpipe.deq(); infifo0.enq(takeAt(0, v)); infifo1.enq(takeAt(valueOf(TDiv#(n,2)), v)); endrule PipeOut#(Vector#(TDiv#(n,2),a)) inpipe0 = toPipeOut(infifo0); PipeOut#(Vector#(TSub#(n,TDiv#(n,2)),a)) inpipe1 = toPipeOut(infifo1); PipeOut#(a) p0 <- mkReducePipe(combinepipe, inpipe0); PipeOut#(a) p1 <- mkReducePipe(combinepipe, inpipe1); function a foo(Tuple2#(a,a) invec); return combinepipe(invec); endfunction let pipe <- mkMapPipe(foo,zipPipeOut(p0, p1)); return pipe; endmodule module mkReducePipes#(CombinePipe#(Tuple2#(a,a), a) combinepipe, Vector#(n, PipeOut#(a)) inpipes) (PipeOut#(a)); Vector#(TDiv#(n,2),PipeOut#(a)) pipes0 = takeAt(0, inpipes); Vector#(TSub#(n,TDiv#(n,2)),PipeOut#(a)) pipes1 = takeAt(valueOf(TDiv#(n,2)), inpipes); PipeOut#(a) p0 <- mkReducePipes(combinepipe, pipes0); PipeOut#(a) p1 <- mkReducePipes(combinepipe, pipes1); function a foo(Tuple2#(a,a) invec); return combinepipe(invec); endfunction let pipe <- mkMapPipe(foo,zipPipeOut(p0, p1)); return pipe; endmodule endinstance interface FirstLastPipe#(type a); interface PipeOut#(Tuple2#(Bool,Bool)) pipe; method Action start(a count); endinterface module mkFirstLastPipe(FirstLastPipe#(a)) provisos (Bits#(a,asz), Ord#(a), Arith#(a), Eq#(a)); Reg#(a) countReg <- mkReg(0); Reg#(Bool) firstReg <- mkReg(False); Reg#(Bool) lastReg <- mkReg(False); interface PipeOut pipe; method Tuple2#(Bool, Bool) first(); return tuple2(firstReg, lastReg); endmethod method Action deq() if (countReg > 0); firstReg <= False; let c = countReg - 1; if (c == 1) lastReg <= True; countReg <= c; endmethod method Bool notEmpty(); return countReg > 0; endmethod endinterface method Action start(a count) if (countReg == 0); firstReg <= True; lastReg <= False; countReg <= count; endmethod endmodule typedef struct { a xbase; a xlimit; a xstep; } IteratorConfig#(type a) deriving (Bits, FShow); typedef struct { a value; Bool first; Bool last; b ctxt; } IteratorValue#(type a, type b) deriving (Bits); function a iteratorValueData(IteratorValue#(a,b) ivd); return ivd.value; endfunction interface IteratorWithContext#(type a, type c); interface PipeOut#(a) pipe; interface PipeOut#(IteratorValue#(a,c)) ivpipe; method a count(); method Bool isFirst(); method Bool isLast(); method Action start(IteratorConfig#(a) cfg, c ctxt); method c ctxt(); endinterface interface IteratorIfc#(type a); interface PipeOut#(a) pipe; interface PipeOut#(IteratorValue#(a,void)) ivpipe; method a count(); method Bool isFirst(); method Bool isLast(); method Action start(IteratorConfig#(a) cfg); endinterface module mkIteratorWithContext(IteratorWithContext#(a,c)) provisos (Arith#(a), Bits#(a,awidth), Eq#(a), Ord#(a), Bits#(c,cwidth)); Reg#(c) ctxtReg <- mkReg(unpack(0)); Reg#(a) countReg <- mkReg(0); Reg#(a) x <- mkReg(0); Reg#(a) xbase <- mkReg(0); Reg#(a) xstep <- mkReg(0); // inclusive limit Reg#(a) xlimit <- mkReg(0); Reg#(Bool) first <- mkReg(False); Reg#(Bool) last <- mkReg(False); Reg#(Bool) idle <- mkReg(True); Bool verbose = False; interface PipeOut pipe; method a first(); return x; endmethod method Action deq if (!idle); let next_x = x + xstep; countReg <= countReg + 1; x <= x + xstep; first <= False; last <= (x + xstep*2 >= xlimit); idle <= last; endmethod method Bool notEmpty(); return !idle; endmethod endinterface interface PipeOut ivpipe; method IteratorValue#(a,c) first(); return IteratorValue { value: x, first: first, last: last, ctxt: ctxtReg }; endmethod method Action deq if (!idle); let next_x = x + xstep; countReg <= countReg + 1; x <= x + xstep; first <= False; last <= (x + xstep*2 >= xlimit); idle <= last; endmethod method Bool notEmpty(); return !idle; endmethod endinterface method Action start(IteratorConfig#(a) cfg, c ctxt) if (idle); countReg <= 0; x <= cfg.xbase; xbase <= cfg.xbase; xstep <= cfg.xstep; xlimit <= cfg.xlimit; first <= True; last <= (cfg.xbase+cfg.xstep >= cfg.xlimit); idle <= False; ctxtReg <= ctxt; if (verbose) $display("mkIterator xbase=%d xstep=%d xlimit=%d last=%d notEmpty=%d", cfg.xbase, cfg.xstep, cfg.xlimit, (cfg.xbase+cfg.xstep >= cfg.xlimit), (cfg.xbase < cfg.xlimit)); endmethod method Bool isFirst() = first; method Bool isLast() = last; method a count() = countReg; method c ctxt() = ctxtReg; endmodule: mkIteratorWithContext module mkIterator(IteratorIfc#(a)) provisos (Arith#(a), Bits#(a,awidth), Eq#(a), Ord#(a)); IteratorWithContext#(a,void) iter <- mkIteratorWithContext(); interface PipeOut pipe = iter.pipe; interface PipeOut ivpipe = iter.ivpipe; method Action start(IteratorConfig#(a) cfg); iter.start(cfg, ?); endmethod method a count() = iter.count(); method isFirst = iter.isFirst; method isLast = iter.isLast; endmodule typedef struct { a xbase; a xlimit; a xstep; a ybase; a ylimit; a ystep; } XYIteratorConfig#(type a) deriving (Bits, FShow); interface XYIteratorIfc#(type a); interface PipeOut#(Tuple2#(a,a)) pipe; method Bool isFirst(); method Bool isLast(); method Action start(XYIteratorConfig#(a) cfg); method Action display(); endinterface module mkXYIterator(XYIteratorIfc#(a)) provisos (Arith#(a), Bits#(a,awidth), Eq#(a), Ord#(a)); Reg#(a) x <- mkReg(0); Reg#(a) y <- mkReg(0); Reg#(a) xbase <- mkReg(0); Reg#(a) ybase <- mkReg(0); Reg#(a) xstep <- mkReg(0); Reg#(a) ystep <- mkReg(0); Reg#(a) xlimit <- mkReg(0); Reg#(a) ylimit <- mkReg(0); Reg#(Bool) isFirstReg <- mkReg(False); Reg#(Bool) isLastReg <- mkReg(False); let guard = x < xlimit && y < ylimit; interface PipeOut pipe; method Tuple2#(a,a) first() if (guard); return tuple2(x,y); endmethod method Action deq if (guard); let newx = x; let newy = y+ystep; if (newy >= ylimit && x < xlimit) begin newy = ybase; newx = newx + xstep; end x <= newx; y <= newy; isLastReg <= (newx+xstep >= xlimit && newy+ystep >= ylimit); isFirstReg <= False; endmethod method Bool notEmpty(); return guard; endmethod endinterface method Action start(XYIteratorConfig#(a) cfg) if (!guard); x <= cfg.xbase; y <= cfg.ybase; xbase <= cfg.xbase; ybase <= cfg.ybase; xstep <= cfg.xstep; ystep <= cfg.ystep; xlimit <= cfg.xlimit; ylimit <= cfg.ylimit; isFirstReg <= True; isLastReg <= (cfg.xbase+cfg.xstep) > cfg.xlimit && (cfg.ybase+cfg.ystep) > cfg.ylimit; endmethod method Bool isFirst(); return isFirstReg; endmethod method Bool isLast(); return isLastReg; endmethod method Action display(); $display("XYIterator x=%d xlimit=%d y=%d ylimit=%d xstep=%d ystep=%d", x, xlimit, xstep, y, ylimit, ystep); endmethod endmodule: mkXYIterator instance MkAxiStream#(AxiStreamMaster#(dsize), PipeOut#(dtype)) provisos (Bits#(dtype,dsize)); module mkAxiStream#(PipeOut#(dtype) f)(AxiStreamMaster#(dsize)); Wire#(Bool) readyWire <- mkDWire(False); rule rl_deq if (readyWire && f.notEmpty); f.deq(); endrule method Bit#(dsize) tdata(); if (f.notEmpty()) return pack(f.first()); else return 0; endmethod method Bit#(TDiv#(dsize,8)) tkeep(); return maxBound; endmethod method Bit#(1) tlast(); return 0; endmethod method Action tready(Bit#(1) v); readyWire <= unpack(v); endmethod method Bit#(1) tvalid(); return pack(f.notEmpty()); endmethod endmodule endinstance instance MkAxiStream#(AxiStreamSlave#(dsize), PipeIn#(dtype)) provisos (Bits#(dtype,dsize)); module mkAxiStream#(PipeIn#(dtype) f)(AxiStreamSlave#(dsize)); Wire#(Bit#(dsize)) dataWire <- mkDWire(unpack(0)); Wire#(Bool) validWire <- mkDWire(False); rule enq if (validWire && f.notFull()); f.enq(unpack(dataWire)); endrule method Action tdata(Bit#(dsize) v); dataWire <= v; endmethod method Action tkeep(Bit#(TDiv#(dsize,8)) v); endmethod method Action tlast(Bit#(1) v); endmethod method Bit#(1) tready(); return pack(f.notFull()); endmethod method Action tvalid(Bit#(1) v); validWire <= unpack(v); endmethod endmodule endinstance instance Connectable#(AxiStreamMaster#(dataWidth), PipeIn#(dtype)) provisos (Bits#(dtype, dataWidth)); module mkConnection#(AxiStreamMaster#(dataWidth) from, PipeIn#(dtype) to)(Empty); rule rl_ready; from.tready(pack(to.notFull)); endrule rule rl_enq if (from.tvalid == 1); to.enq(unpack(from.tdata)); endrule endmodule endinstance instance Connectable#(PipeOut#(dtype), AxiStreamSlave#(dataWidth)) provisos (Bits#(dtype, dataWidth)); module mkConnection#(PipeOut#(dtype) from, AxiStreamSlave#(dataWidth) to)(Empty); rule rl_tvalid; to.tvalid(pack(from.notEmpty())); endrule rule rl_axi_stream; to.tdata(pack(from.first)); to.tkeep(maxBound); to.tlast(0); endrule rule rl_deq if (to.tready == 1); from.deq(); endrule endmodule endinstance ================================================ FILE: bsv/Platform.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import Vector::*; import BuildVector::*; import Portal::*; import HostInterface::*; import ConnectalMMU::*; import MemServer::*; import ConnectalMemTypes::*; import CtrlMux::*; import FIFO::*; import GetPut::*; import SpecialFIFOs::*; import Pipe::*; import ConnectalMemory::*; import MMURequest::*; import MMUIndication::*; import MemServerIndication::*; import MemServerRequest::*; import IfcNames::*; `include "ConnectalProjectConfig.bsv" import `PinTypeInclude::*; interface Platform; interface PhysMemSlave#(32,32) slave; interface Vector#(NumberOfMasters,PhysMemMaster#(PhysAddrWidth, DataBusWidth)) masters; interface Vector#(MaxNumberOfPortals,ReadOnly#(Bool)) interrupt; interface `PinType pins; endinterface typedef TMax#(TLog#(TSub#(NumberOfTiles,1)),1) TileTagBits; function Bit#(TSub#(MemTagSize,TileTagBits)) tagLsb(Bit#(MemTagSize) tag); return truncate(tag); endfunction function Bit#(TileTagBits) tagMsb(Bit#(MemTagSize) tag); return truncate(tag >> valueOf(TSub#(MemTagSize,TileTagBits))); endfunction module renameReads#(Integer tile, MemReadClient#(DataBusWidth) reader, MemServerIndication err)(MemReadClient#(DataBusWidth)); interface Get readReq; method ActionValue#(MemRequest) get; let req <- reader.readReq.get; Bit#(TSub#(MemTagSize,TileTagBits)) lsb = tagLsb(req.tag); Bit#(TileTagBits) msb = tagMsb(req.tag); if(req.tag != extend(lsb) && valueOf(NumberOfTiles) > 2) begin // one mgmt tile and one user tile $display("renameReads tile tag out of range: 'h%h", req.tag); err.error(extend(pack(DmaErrorTileTagOutOfRange)), req.sglId, extend(req.tag), fromInteger(tile)); end req.tag = {fromInteger(tile),lsb}; return req; endmethod endinterface interface Put readData; method Action put(MemData#(DataBusWidth) v); reader.readData.put(MemData{data:v.data, tag:{0,tagLsb(v.tag)}, `ifdef BYTE_ENABLES_MEM_DATA byte_enables: v.byte_enables, `endif last:v.last}); endmethod endinterface endmodule module renameWrites#(Integer tile, MemWriteClient#(DataBusWidth) writer, MemServerIndication err)(MemWriteClient#(DataBusWidth)); interface Get writeReq; method ActionValue#(MemRequest) get; let req <- writer.writeReq.get; Bit#(TSub#(MemTagSize,TileTagBits)) lsb = tagLsb(req.tag); Bit#(TileTagBits) msb = tagMsb(req.tag); if(req.tag != extend(lsb) && valueOf(NumberOfTiles) > 2) begin // one mgmt tile and one user tile $display("renameWrites tile tag out of range: 'h%h", req.tag); err.error(extend(pack(DmaErrorTileTagOutOfRange)), req.sglId, extend(req.tag), fromInteger(tile)); end req.tag = {fromInteger(tile),lsb}; return req; endmethod endinterface interface Get writeData; method ActionValue#(MemData#(DataBusWidth)) get; let rv <- writer.writeData.get; return MemData{data:rv.data, tag:{0,tagLsb(rv.tag)}, `ifdef BYTE_ENABLES_MEM_DATA byte_enables: rv.byte_enables, `endif last:rv.last}; endmethod endinterface interface Put writeDone; method Action put(Bit#(MemTagSize) v); writer.writeDone.put({0,tagLsb(v)}); endmethod endinterface endmodule module mkPlatform#(Vector#(NumberOfUserTiles, ConnectalTop#(`PinType)) tiles)(Platform); ///////////////////////////////////////////////////////////// // connecting up the tiles Vector#(NumberOfUserTiles, PhysMemSlave#(18,32)) tile_slaves; Vector#(NumberOfUserTiles, ReadOnly#(Bool)) tile_interrupts; Vector#(NumberOfUserTiles, Vector#(NumReadClients, MemReadClient#(DataBusWidth))) tile_read_clients; Vector#(NumberOfUserTiles, Vector#(NumWriteClients, MemWriteClient#(DataBusWidth))) tile_write_clients; Vector#(NumberOfUserTiles, Vector#(NumReadClients, Integer)) read_client_tile_numbers; Vector#(NumberOfUserTiles, Vector#(NumWriteClients, Integer)) write_client_tile_numbers; for(Integer i = 0; i < valueOf(NumberOfUserTiles); i=i+1) begin tile_slaves[i] = tiles[i].slave; let imux <- mkInterruptMux(tiles[i].interrupt); //ReadOnly#(Bool) imux = tiles[i].interrupt; tile_interrupts[i] = imux; tile_read_clients[i] = tiles[i].readers; tile_write_clients[i] = tiles[i].writers; read_client_tile_numbers[i] = replicate(i); write_client_tile_numbers[i] = replicate(i); end ///////////////////////////////////////////////////////////// // framework internal portals MMUIndicationProxy lMMUIndicationProxy <- mkMMUIndicationProxy(PlatformIfcNames_MMUIndicationH2S); MemServerIndicationProxy lMemServerIndicationProxy <- mkMemServerIndicationProxy(PlatformIfcNames_MemServerIndicationH2S); `ifdef USE_SIMPLE_MMU MMU#(PhysAddrWidth) lMMU <- mkSimpleMMU(0,True, lMMUIndicationProxy.ifc); `else MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationProxy.ifc); `endif Vector#(TMul#(NumberOfUserTiles,NumReadClients), MemReadClient#(DataBusWidth)) tile_read_clients_renamed <- zipWith3M(renameReads, concat(read_client_tile_numbers), concat(tile_read_clients), replicate(lMemServerIndicationProxy.ifc)); Vector#(TMul#(NumberOfUserTiles,NumWriteClients), MemWriteClient#(DataBusWidth)) tile_write_clients_renamed <- zipWith3M(renameWrites, concat(write_client_tile_numbers), concat(tile_write_clients), replicate(lMemServerIndicationProxy.ifc)); MemServer#(PhysAddrWidth,DataBusWidth,NumberOfMasters) lMemServer <- mkMemServer(tile_read_clients_renamed, tile_write_clients_renamed, vec(lMMU), lMemServerIndicationProxy.ifc); MMURequestWrapper lMMURequestWrapper <- mkMMURequestWrapper(PlatformIfcNames_MMURequestS2H, lMMU.request); MemServerRequestWrapper lMemServerRequestWrapper <- mkMemServerRequestWrapper(PlatformIfcNames_MemServerRequestS2H, lMemServer.request); Vector#(4,StdPortal) framework_portals; framework_portals[0] = lMMUIndicationProxy.portalIfc; framework_portals[1] = lMemServerIndicationProxy.portalIfc; framework_portals[2] = lMMURequestWrapper.portalIfc; framework_portals[3] = lMemServerRequestWrapper.portalIfc; PhysMemSlave#(18,32) framework_ctrl_mux <- mkSlaveMux(framework_portals); let framework_intr <- mkInterruptMux(getInterruptVector(framework_portals)); ///////////////////////////////////////////////////////////// // expose interface to top PhysMemSlave#(32,32) ctrl_mux <- mkPhysMemSlaveMux(cons(framework_ctrl_mux,tile_slaves)); Vector#(MaxNumberOfPortals, ReadOnly#(Bool)) interrupts = replicate(interface ReadOnly; method Bool _read(); return False; endmethod endinterface); interrupts[0] = framework_intr; for (Integer i = 1; i < valueOf(NumberOfTiles); i = i + 1) interrupts[i] = tile_interrupts[i-1]; interface interrupt = interrupts; interface slave = ctrl_mux; interface masters = lMemServer.masters; interface pins = tiles[0].pins; endmodule ================================================ FILE: bsv/Portal.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import Vector::*; import ConnectalMemTypes::*; import Pipe::*; import ConnectalMemory::*; import HostInterface::*; `include "ConnectalProjectConfig.bsv" import `PinTypeInclude::*; interface PortalInterrupt#(numeric type dataWidth); method Bool status(); method Bit#(dataWidth) channel(); endinterface interface PortalSize; method Bit#(16) size(Bit#(16) methodNumber); endinterface typeclass PortalMessageSize#(type t); function Bit#(16) portalMessageSize(t p, Bit#(16) methodNumber); endtypeclass // implementation of a Portal as a group of Pipes interface PipePortal#(numeric type numRequests, numeric type numIndications, numeric type slaveDataWidth); interface PortalSize messageSize; interface Vector#(numRequests, PipeIn#(Bit#(slaveDataWidth))) requests; //method PipeIn#(Bit#(slaveDataWidth)) requestsPipe(Integer a); interface Vector#(numIndications, PipeOut#(Bit#(slaveDataWidth))) indications; //method PipeOut#(Bit#(slaveDataWidth)) indicationsPipe(Integer a); interface PortalInterrupt#(slaveDataWidth) intr; endinterface // implementation of a Portal as a physical memory slave interface MemPortal#(numeric type slaveAddrWidth, numeric type slaveDataWidth); interface PhysMemSlave#(slaveAddrWidth,slaveDataWidth) slave; interface ReadOnly#(Bool) interrupt; interface WriteOnly#(Bit#(slaveDataWidth)) num_portals; endinterface function ReadOnly#(Bool) getInterrupt(MemPortal#(_a,_d) p); return p.interrupt; endfunction function Vector#(MaxNumberOfPortals, ReadOnly#(Bool)) getInterruptVector(Vector#(numPortals, MemPortal#(_a,_d)) portals); Vector#(MaxNumberOfPortals, ReadOnly#(Bool)) interrupts = replicate(interface ReadOnly; method Bool _read(); return False; endmethod endinterface); for (Integer i = 0; i < valueOf(numPortals); i = i + 1) interrupts[i] = getInterrupt(portals[i]); return interrupts; endfunction interface SharedMemoryPortalConfig; method Action setSglId(Bit#(32) sglId); endinterface interface SharedMemoryPortal#(numeric type dataBusWidth); interface SharedMemoryPortalConfig cfg; interface ReadOnly#(Bool) interrupt; endinterface typedef MemPortal#(12,32) StdPortal; interface ConnectalTop#(type pinType); interface PhysMemSlave#(18,32) slave; interface Vector#(MaxNumberOfPortals,ReadOnly#(Bool)) interrupt; interface Vector#(NumReadClients,MemReadClient#(DataBusWidth)) readers; interface Vector#(NumWriteClients,MemWriteClient#(DataBusWidth)) writers; `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource; `endif interface pinType pins; endinterface ================================================ FILE: bsv/SimDma.bsv ================================================ // Copyright (c) 2015 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFO::*; import FIFOF::*; import GetPut::*; import ConnectalMemTypes::*; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" `ifdef SIM_DMA_READ_LATENCY typedef `SIM_DMA_READ_LATENCY SimDmaReadLatency; `else typedef 150 SimDmaReadLatency; `endif `ifdef SIM_DMA_WRITE_LATENCY typedef `SIM_DMA_WRITE_LATENCY SimDmaWriteLatency; `else typedef 150 SimDmaWriteLatency; `endif interface SimDma#(numeric type dataWidth); method Action init(Bit#(32) id, Bit#(32) handle, Bit#(32) size); method Action initfd(Bit#(32) id, Bit#(32) fd); method Action idreturn(Bit#(32) id); method Action write(Bit#(32) handle, Bit#(32) addr, Bit#(dataWidth) v, Bit#(TDiv#(dataWidth,8)) byteEnable); method Action readrequest(Bit#(32) handle, Bit#(32) addr); method ActionValue#(Bit#(dataWidth)) readresponse(); endinterface `ifdef BOARD_bluesim import "BDPI" function ActionValue#(Bit#(32)) simDma_init(Bit#(32) id, Bit#(32) handle, Bit#(32) size); import "BDPI" function ActionValue#(Bit#(32)) simDma_initfd(Bit#(32) id, Bit#(32) fd); import "BDPI" function ActionValue#(Bit#(32)) simDma_idreturn(Bit#(32) id); // implemented in BsimDma.cpp import "BDPI" function Action write_simDma32(Bit#(32) handle, Bit#(32) addr, Bit#(32) v, Bit#(4) byteEnable); import "BDPI" function Action write_simDma64(Bit#(32) handle, Bit#(32) addr, Bit#(64) v, Bit#(8) byteEnable); import "BDPI" function ActionValue#(Bit#(32)) read_simDma32(Bit#(32) handle, Bit#(32) addr); import "BDPI" function ActionValue#(Bit#(64)) read_simDma64(Bit#(32) handle, Bit#(32) addr); module mkSimDma(SimDma#(dataWidth) ifc) provisos (Mul#(TDiv#(dataWidth, 32), 32, dataWidth), Bits#(Vector#(TDiv#(dataWidth, 32), Bit#(4)), TDiv#(dataWidth, 8)) ); FIFO#(Bit#(dataWidth)) dataFifo <- mkFIFO(); method Action init(Bit#(32) id, Bit#(32) handle, Bit#(32) size); let v <- simDma_init(id, handle, size); //return v; endmethod method Action initfd(Bit#(32) id, Bit#(32) fd); let v <- simDma_initfd(id, fd); //return v; endmethod method Action idreturn(Bit#(32) id); let v <- simDma_idreturn(id); //return v; endmethod method Action write(Bit#(32) handle, Bit#(32) addr, Bit#(dataWidth) v, Bit#(TDiv#(dataWidth,8)) byteEnable); let aligned_addr = addr & ~7; Vector#(TDiv#(dataWidth, 32), Bit#(32)) vs = unpack(v); Vector#(TDiv#(dataWidth, 32), Bit#(4)) byteEnables = unpack(byteEnable); function Action write32(Integer i); action write_simDma32(handle, aligned_addr+4*fromInteger(i), vs[i], byteEnables[i]); endaction endfunction Vector#(TDiv#(dataWidth,32),Integer) indices = genVector(); mapM_(write32, indices); endmethod method Action readrequest(Bit#(32) handle, Bit#(32) addr); function ActionValue#(Bit#(32)) read32(Integer i); actionvalue let v <- read_simDma32(handle, addr+4*fromInteger(i)); return v; endactionvalue endfunction Vector#(TDiv#(dataWidth,32),Bit#(32)) vs <- mapM(read32, genVector()); dataFifo.enq(pack(vs)); endmethod method ActionValue#(Bit#(dataWidth)) readresponse(); let v <- toGet(dataFifo).get(); return v; endmethod endmodule `endif `ifdef SVDPI interface XsimDmaReadWrite; method Action init(Bit#(32) id, Bit#(32) handle, Bit#(32) size); method Action initfd(Bit#(32) id, Bit#(32) fd); method Action idreturn(Bit#(32) id); method Action write32(Bit#(32) handle, Bit#(32) addr, Bit#(32) v, Bit#(4) byteEnable); method Action readrequest(Bit#(32) handle, Bit#(32) addr); method ActionValue#(Bit#(32)) readresponse(); endinterface import "BVI" XsimDmaReadWrite = module mkXsimReadWrite(XsimDmaReadWrite); method init(init_id, init_handle, init_size) enable (en_init); method initfd(initfd_id, initfd_fd) enable (en_initfd); method idreturn(idreturn_id) enable (en_idreturn); method write32(write32_handle, write32_addr, write32_data, write32_byteenable) enable (en_write32); method readrequest(readrequest_handle, readrequest_addr) enable (en_readrequest) ready (rdy_readrequest); method readresponse_data readresponse() enable (en_readresponse) ready (rdy_readresponse); schedule (init, initfd, write32, readrequest, readresponse, idreturn) CF (init, initfd, write32, readrequest, readresponse, idreturn); endmodule module mkSimDma(SimDma#(dataWidth) ifc) provisos (Mul#(TDiv#(dataWidth, 32), 32, dataWidth), Bits#(Vector#(TDiv#(dataWidth, 32), Bit#(4)), TDiv#(dataWidth, 8))); Vector#(TDiv#(dataWidth,32),XsimDmaReadWrite) rws <- replicateM(mkXsimReadWrite()); method Action init(Bit#(32) id, Bit#(32) handle, Bit#(32) size); rws[0].init(id, handle, size); endmethod method Action initfd(Bit#(32) id, Bit#(32) fd); rws[0].initfd(id, fd); endmethod method Action idreturn(Bit#(32) id); rws[0].idreturn(id); endmethod method Action write(Bit#(32) handle, Bit#(32) addr, Bit#(dataWidth) v, Bit#(TDiv#(dataWidth,8)) byteEnable); Vector#(TDiv#(dataWidth, 32), Bit#(32)) vs = unpack(v); Vector#(TDiv#(dataWidth, 32), Bit#(4)) byteEnables = unpack(byteEnable); let aligned_addr = addr & ~7; function Action write32(Integer i); action rws[i].write32(handle, aligned_addr+4*fromInteger(i), vs[i], byteEnables[i]); endaction endfunction Vector#(TDiv#(dataWidth,32),Integer) indices = genVector(); mapM_(write32, indices); endmethod method Action readrequest(Bit#(32) handle, Bit#(32) addr); function Action doreadrequest(Integer i); action rws[i].readrequest(handle, addr+4*fromInteger(i)); endaction endfunction Vector#(TDiv#(dataWidth,32),Integer) indexes = genVector(); mapM_(doreadrequest, indexes); endmethod method ActionValue#(Bit#(dataWidth)) readresponse(); function ActionValue#(Bit#(32)) readresponse32(Integer i); actionvalue let v <- rws[i].readresponse(); return v; endactionvalue endfunction Vector#(TDiv#(dataWidth,32),Bit#(32)) vs <- mapM(readresponse32, genVector()); return pack(vs); endmethod endmodule `endif `ifndef SIMULATION module mkSimDma(SimDma#(dataWidth) ifc); method Action init(Bit#(32) id, Bit#(32) handle, Bit#(32) size); endmethod method Action initfd(Bit#(32) id, Bit#(32) fd); endmethod method Action idreturn(Bit#(32) id); endmethod method Action write(Bit#(32) handle, Bit#(32) addr, Bit#(dataWidth) v, Bit#(TDiv#(dataWidth,8)) byteEnable); endmethod method Action readrequest(Bit#(32) handle, Bit#(32) addr); endmethod method ActionValue#(Bit#(dataWidth)) readresponse(); return 0; endmethod endmodule `endif // SIMULATION module mkSimDmaDmaMaster(PhysMemSlave#(serverAddrWidth,serverBusWidth)) provisos(Div#(serverBusWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,serverBusWidth), Log#(dataWidthBytes,beatShift), Mul#(TDiv#(serverBusWidth, 32), 32, serverBusWidth), Mul#(TDiv#(serverBusWidth, 32), 4, TDiv#(serverBusWidth, 8)), Bits#(Tuple2#(Bit#(64), PhysMemRequest#(serverAddrWidth,serverBusWidth)), a__), Add#(b__, ByteEnableSize, TDiv#(serverBusWidth, 8)) ); let verbose = False; SimDma#(serverBusWidth) rw <- mkSimDma(); Reg#(Bit#(BurstLenSize)) readLenReg <- mkReg(0); Reg#(Bit#(32)) readOffsetReg <- mkReg(0); Reg#(Bit#(BurstLenSize)) writeLenReg <- mkReg(0); Reg#(Bit#(32)) writeOffsetReg <- mkReg(0); let readLatency_I = valueOf(SimDmaReadLatency); let writeLatency_I = valueOf(SimDmaWriteLatency); Bit#(64) readLatency = fromInteger(readLatency_I); Bit#(64) writeLatency = fromInteger(writeLatency_I); Reg#(Bit#(64)) req_ar_b_ts <- mkReg(0); Reg#(Bit#(64)) req_aw_b_ts <- mkReg(0); Reg#(Bit#(64)) cycles <- mkReg(0); Reg#(Bit#(64)) last_reqAr <- mkReg(0); Reg#(Bit#(64)) last_read_eob <- mkReg(0); Reg#(Bit#(64)) last_write_eob <- mkReg(0); FIFOF#(Tuple2#(Bit#(64), PhysMemRequest#(serverAddrWidth,serverBusWidth))) readDelayFifo <- mkSizedFIFOF(readLatency_I); FIFOF#(Tuple2#(Bit#(64),PhysMemRequest#(serverAddrWidth,serverBusWidth))) writeDelayFifo <- mkSizedFIFOF(writeLatency_I); FIFOF#(Tuple2#(Bit#(64), Bit#(MemTagSize))) bFifo <- mkSizedFIFOF(writeLatency_I); FIFOF#(Tuple2#(Bit#(MemTagSize),Bool)) taglastfifo <- mkFIFOF(); rule increment_cycle; cycles <= cycles+1; endrule let read_jitter = True; //cycles[4:0] == 0; let write_jitter = True; //cycles[4:0] == 5; Reg#(Bit#(8)) burstReg <- mkReg(0); FIFO#(Bit#(8)) reqs <- mkSizedFIFO(32); let beat_shift = fromInteger(valueOf(beatShift)); rule read_rule if (readDelayFifo.notEmpty() && (cycles-tpl_1(readDelayFifo.first) >= readLatency)); match { .reqTime, .req } = readDelayFifo.first; Bit#(BurstLenSize) readLen = readLenReg; Bit#(32) readOffset = readOffsetReg; Bit#(MemTagSize) tag = req.tag; Bit#(8) handle = req.addr[39:32]; if (readLen == 0) begin req_ar_b_ts <= cycles; readLen = req.burstLen>>beat_shift; readOffset = 0; end rw.readrequest(extend(handle), req.addr[31:0]+readOffset); let last = (readLen == 1); if (last) readDelayFifo.deq(); taglastfifo.enq(tuple2(tag, last)); readLenReg <= readLen - 1; readOffsetReg <= readOffset + fromInteger(valueOf(serverBusWidth)/8); endrule interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(serverAddrWidth,serverBusWidth) req); if (verbose) $display("mkSimDmaDmaMaster::%d axiSlave.read.readAddr %h bc %d", cycles, req.addr, req.burstLen); //readAddrGenerator.request.put(req); readDelayFifo.enq(tuple2(cycles,req)); endmethod endinterface interface Get readData; method ActionValue#(MemData#(serverBusWidth)) get(); match { .tag, .last } <- toGet(taglastfifo).get(); let v <- rw.readresponse(); //if (verbose) $display("mkSimDmaDmaMaster::%d axiSlave.read.readData %h tag %d last %d", cycles, v, tag, last); return MemData { data: v, tag: tag, last: last }; endmethod endinterface endinterface interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(serverAddrWidth,serverBusWidth) req); //$display("mkSimDmaDmaMaster::req_aw id=%d", req.tag); writeDelayFifo.enq(tuple2(cycles,req)); endmethod endinterface interface Put writeData; method Action put(MemData#(serverBusWidth) resp) if (writeDelayFifo.notEmpty && (cycles-tpl_1(writeDelayFifo.first)) >= writeLatency); match { .reqTime, .req } = writeDelayFifo.first; Bit#(BurstLenSize) writeLen = writeLenReg; Bit#(32) writeOffset = writeOffsetReg; Bit#(MemTagSize) tag = req.tag; Bit#(8) handle = req.addr[39:32]; Bit#(TDiv#(serverBusWidth,8)) byteEnable = maxBound; if (writeLen == 1) byteEnable = reqLastByteEnable(req); if (writeLenReg == 0) begin req_aw_b_ts <= cycles; writeLen = req.burstLen>>beat_shift; writeOffset = 0; byteEnable = reqFirstByteEnable(req); end `ifdef BYTE_ENABLES_MEM_DATA byteEnable = resp.byte_enables; `endif rw.write(extend(handle), req.addr[31:0] + writeOffset, resp.data, extend(byteEnable)); writeLenReg <= writeLen - 1; writeOffsetReg <= writeOffset + fromInteger(valueOf(serverBusWidth)/8); if (writeLen == 1) begin bFifo.enq(tuple2(cycles,tag)); writeDelayFifo.deq; end endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get() if ((cycles-tpl_1(bFifo.first)) >= writeLatency); bFifo.deq(); return tpl_2(bFifo.first()); endmethod endinterface endinterface endmodule ================================================ FILE: bsv/SimLink.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut :: *; import Connectable :: *; import FIFOF :: *; import Pipe :: *; `include "ConnectalProjectConfig.bsv" interface SimLink#(numeric type dataWidth); method Action start(Bit#(32) linknumber, Bool listening); method Bool linkUp(); interface PipeOut#(Bit#(dataWidth)) rx; interface PipeIn#(Bit#(dataWidth)) tx; endinterface `ifdef BOARD_bluesim import "BDPI" function Action bsimLinkOpen(Bit#(32) linknumber, Bool listening); import "BDPI" function Bit#(1) bsimLinkUp(Bit#(32) linknumber, Bool listening); import "BDPI" function Bool bsimLinkCanReceive(Bit#(32) linknumber, Bool listening); import "BDPI" function Bool bsimLinkCanTransmit(Bit#(32) linknumber, Bool listening); import "BDPI" function ActionValue#(Bit#(32)) bsimLinkReceive32(Bit#(32) linknumber, Bool listening); import "BDPI" function Action bsimLinkTransmit32(Bit#(32) linknumber, Bool listening, Bit#(32) value); import "BDPI" function ActionValue#(Bit#(64)) bsimLinkReceive64(Bit#(32) linknumber, Bool listening); import "BDPI" function Action bsimLinkTransmit64(Bit#(32) linknumber, Bool listening, Bit#(64) value); typeclass SelectLinkWidth#(numeric type dsz); function ActionValue#(Bit#(dsz)) bsimLinkReceive(Bit#(32) linknumber, Bool listening); function Action bsimLinkTransmit(Bit#(32) linknumber, Bool listening, Bit#(dsz) value); endtypeclass instance SelectLinkWidth#(32); function ActionValue#(Bit#(32)) bsimLinkReceive(Bit#(32) linknumber, Bool listening); actionvalue let v <- bsimLinkReceive32(linknumber, listening); return v; endactionvalue endfunction function Action bsimLinkTransmit(Bit#(32) linknumber, Bool listening, Bit#(32) value); action bsimLinkTransmit32(linknumber, listening, value); endaction endfunction endinstance instance SelectLinkWidth#(64); function ActionValue#(Bit#(64)) bsimLinkReceive(Bit#(32) linknumber, Bool listening); actionvalue let v <- bsimLinkReceive64(linknumber, listening); return v; endactionvalue endfunction function Action bsimLinkTransmit(Bit#(32) linknumber, Bool listening, Bit#(64) value); action bsimLinkTransmit64(linknumber, listening, value); endaction endfunction endinstance module mkSimLink(SimLink#(dataWidth)) provisos (SelectLinkWidth#(dataWidth)); FIFOF#(Bit#(dataWidth)) rxFifo <- mkFIFOF(); FIFOF#(Bit#(dataWidth)) txFifo <- mkFIFOF(); Reg#(Bit#(32)) linknumber <- mkReg(0); Reg#(Bool) opened <- mkReg(False); Reg#(Bool) listening <- mkReg(False); Reg#(Bool) started <- mkReg(False); rule open if (!opened && started); bsimLinkOpen(linknumber, listening); opened <= True; endrule rule receive if (bsimLinkCanReceive(linknumber, listening)); let v <- bsimLinkReceive(linknumber, listening); rxFifo.enq(v); endrule rule transmit if (bsimLinkCanTransmit(linknumber, listening)); let v <- toGet(txFifo).get(); bsimLinkTransmit(linknumber, listening, v); endrule interface rx = toPipeOut(rxFifo); interface tx = toPipeIn(txFifo); method Action start(Bit#(32) number, Bool l); linknumber <= number; started <= True; listening <= l; endmethod method Bool linkUp(); if (started) return unpack(bsimLinkUp(linknumber, listening)); else return False; endmethod endmodule `endif `ifdef SVDPI import "BVI" XsimLink = module mkSimLink(SimLink#(dataWidth)); parameter DATAWIDTH=valueOf(dataWidth); method start(start_linknumber, start_listening) enable (en_start); method link_up linkUp(); interface PipeOut rx; method rx_first first() ready (rdy_rx_first); method deq() enable (en_rx_deq) ready (rdy_rx_deq); method rx_not_empty notEmpty(); endinterface interface PipeIn tx; method enq(tx_enq_v) enable (en_tx_enq) ready (rdy_tx_enq); method tx_not_full notFull(); endinterface schedule (rx_first, rx_notEmpty, tx_notFull, rx_deq, tx_enq, start, linkUp) CF (rx_first, rx_notEmpty, tx_notFull, rx_deq, tx_enq, start, linkUp); endmodule `endif //SVDPI ================================================ FILE: bsv/SyncAxisFifo32x8.bsv ================================================ /* ../../generated/scripts/importbvi.py -I SyncAxisFifo32x8 -P SyncAxisFifo32x8 -c m_aclk -c s_aclk -r s_aresetn -o SyncAxisFifo32x8.bsv cores/nfsume/dual_clock_axis_fifo_32x8/dual_clock_axis_fifo_32x8_stub.v */ import Clocks::*; import ConnectalFIFO::*; import DefaultValue::*; import FIFOF::*; import XilinxCells::*; import GetPut::*; import Connectable::*; import AxiBits::*; import AxiStream::*; import Vector::*; (* always_ready, always_enabled *) interface SyncAxisFifo8#(numeric type dwidth); interface AxiStreamMaster#(dwidth) m_axis; interface AxiStreamSlave#(dwidth) s_axis; endinterface import "BVI" dual_clock_axis_fifo_32x8 = module mkSyncAxisFifo32x8#(Clock s_aclk, Reset s_aresetn, Clock m_aclk, Reset m_aresetn)(SyncAxisFifo8#(32)); default_clock no_clock; default_reset no_reset; input_clock m_aclk(m_aclk, (* unused *) GATE) = m_aclk; input_clock s_aclk(s_aclk, (* unused *) GATE) = s_aclk; input_reset s_aresetn(s_aresetn) clocked_by (s_aclk) = s_aresetn; input_reset m_aresetn_foo() clocked_by (m_aclk) = m_aresetn; interface AxiStreamMaster m_axis; method m_axis_tdata tdata() clocked_by (m_aclk) reset_by (m_aresetn_foo); method m_axis_tkeep tkeep() clocked_by (m_aclk) reset_by (m_aresetn_foo); method m_axis_tlast tlast() clocked_by (m_aclk) reset_by (m_aresetn_foo); method tready(m_axis_tready) enable((*inhigh*) EN_m_axis_tready) clocked_by (m_aclk) reset_by (m_aresetn_foo); method m_axis_tvalid tvalid() clocked_by (m_aclk) reset_by (m_aresetn_foo); endinterface interface AxiStreamSlave s_axis; method tdata(s_axis_tdata) enable((*inhigh*) EN_s_axis_tdata) clocked_by (s_aclk) reset_by (s_aresetn); method tkeep(s_axis_tkeep) enable((*inhigh*) EN_s_axis_tkeep) clocked_by (s_aclk) reset_by (s_aresetn); method tlast(s_axis_tlast) enable((*inhigh*) EN_s_axis_tlast) clocked_by (s_aclk) reset_by (s_aresetn); method s_axis_tready tready() clocked_by (s_aclk) reset_by (s_aresetn); method tvalid(s_axis_tvalid) enable((*inhigh*) EN_s_axis_tvalid) clocked_by (s_aclk) reset_by (s_aresetn); endinterface schedule (m_axis.tdata, m_axis.tkeep, m_axis.tlast, m_axis.tready, m_axis.tvalid, s_axis.tdata, s_axis.tkeep, s_axis.tlast, s_axis.tready, s_axis.tvalid) CF (m_axis.tdata, m_axis.tkeep, m_axis.tlast, m_axis.tready, m_axis.tvalid, s_axis.tdata, s_axis.tkeep, s_axis.tlast, s_axis.tready, s_axis.tvalid); endmodule (* no_default_clock, no_default_reset *) module mkSyncAxisFifo8#(Clock sclk, Reset srst, Clock dclk, Reset drst)(SyncAxisFifo8#(dwidth)) provisos (Div#(dwidth, 32, numFifos), Mul#(numFifos, 32, numBits), Add#(a__, dwidth, numBits), Bits#(Vector#(numFifos, Bit#(4)), TDiv#(numBits, 8)), Add#(b__, TDiv#(dwidth, 8), TDiv#(numBits, 8)) ); Vector#(numFifos,SyncAxisFifo8#(32)) fifos <- replicateM(mkSyncAxisFifo32x8(sclk, srst, dclk, drst)); Integer numFifos = valueOf(numFifos); interface AxiStreamSlave s_axis; method tready = fifos[0].s_axis.tready; method Action tdata(Bit#(dwidth) v); Vector#(numFifos,Bit#(32)) data = unpack(extend(v)); for (Integer i = 0; i < numFifos; i = i + 1) fifos[i].s_axis.tdata(data[i]); endmethod method Action tkeep(Bit#(TDiv#(dwidth,8)) v); Vector#(numFifos,Bit#(4)) keep = unpack(extend(v)); for (Integer i = 0; i < numFifos; i = i + 1) fifos[i].s_axis.tkeep(keep[i]); endmethod method Action tlast(Bit#(1) v); for (Integer i = 0; i < numFifos; i = i + 1) fifos[i].s_axis.tlast(v); endmethod method Action tvalid(Bit#(1) v); function Action fifo_tvalid(SyncAxisFifo8#(32) f); action f.s_axis.tvalid(v); endaction endfunction mapM_(fifo_tvalid, fifos); endmethod endinterface interface AxiStreamMaster m_axis; method Bit#(dwidth) tdata(); function Bit#(32) fifo_tdata(SyncAxisFifo8#(32) f); return f.m_axis.tdata(); endfunction Vector#(numFifos,Bit#(32)) datavec = map(fifo_tdata, fifos); Bit#(numBits) data = pack(datavec); return truncate(data); endmethod method Bit#(TDiv#(dwidth,8)) tkeep(); function Bit#(4) fifo_tkeep(SyncAxisFifo8#(32) f); return f.m_axis.tkeep(); endfunction Vector#(numFifos,Bit#(4)) keepvec = map(fifo_tkeep, fifos); Bit#(TDiv#(dwidth,8)) keep = truncate(pack(keepvec)); return truncate(keep); endmethod method Bit#(1) tlast(); return fifos[0].m_axis.tlast(); endmethod method Action tready(Bit#(1) v); function Action fifo_tready(SyncAxisFifo8#(32) f); action f.m_axis.tready(v); endaction endfunction mapM_(fifo_tready, fifos); endmethod method Bit#(1) tvalid(); return fifos[0].m_axis.tvalid(); endmethod endinterface endmodule (* no_default_clock, no_default_reset *) module mkSyncFifo8#(Clock fromClock, Reset fromReset, Clock toClock, Reset toReset)(FIFOF#(a)) provisos (Bits#(a, asz), Div#(asz,32,afifos), Mul#(afifos,32,fsz), Div#(fsz, 32, afifos), Mul#(TDiv#(fsz, 32), 4, TDiv#(fsz, 8)), Add#(a__, asz, fsz) ); FIFOF#(a) fromFIFOF <- mkCFFIFOF(clocked_by fromClock, reset_by fromReset); SyncAxisFifo8#(fsz) syncFIFOF <- mkSyncAxisFifo8(fromClock, fromReset, toClock, toReset); FIFOF#(a) toFIFOF <- mkCFFIFOF(clocked_by toClock, reset_by toReset); rule rl_from if (syncFIFOF.s_axis.tready() == 1); syncFIFOF.s_axis.tdata(extend(pack(fromFIFOF.first()))); fromFIFOF.deq(); endrule rule rl_from_handshake; syncFIFOF.s_axis.tvalid(pack(fromFIFOF.notEmpty())); syncFIFOF.s_axis.tkeep(maxBound); syncFIFOF.s_axis.tlast(1); endrule rule rl_to if (syncFIFOF.m_axis.tvalid() == 1); toFIFOF.enq(unpack(truncate(syncFIFOF.m_axis.tdata))); endrule rule rl_to_handshake; syncFIFOF.m_axis.tready(pack(toFIFOF.notFull())); endrule method notEmpty = toFIFOF.notEmpty; method first = toFIFOF.first; method deq = toFIFOF.deq; method enq = fromFIFOF.enq; method notFull = fromFIFOF.notFull; endmodule ================================================ FILE: bsv/SyncBits.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import Clocks::*; module mkSyncBits#(a initValue, Clock sClkIn, Reset sRst, Clock dClkIn, Reset dRst)(SyncBitIfc#(a)) provisos (Bits#(a,awidth)); Reg#(a) ff0 <- mkReg(initValue, clocked_by sClkIn, reset_by sRst); Reg#(a) ff1 <- mkReg(initValue, clocked_by dClkIn, reset_by dRst); Reg#(a) ff2 <- mkReg(initValue, clocked_by dClkIn, reset_by dRst); ReadOnly#(a) ff0cross <- mkNullCrossingWire(dClkIn, ff0); rule update; ff1 <= ff0cross; ff2 <= ff1; endrule method a read(); return ff2; endmethod: read method Action send(a value); ff0 <= value; endmethod: send endmodule ================================================ FILE: bsv/Trace.bsv ================================================ import BRAM::*; import BRAMFIFO::*; import ConnectalFIFO::*; import DefaultValue::*; import FIFOF::*; import GetPut::*; import ConnectalMemTypes::*; typedef struct { MemRequest readReq; } TraceRecord deriving (Bits); typedef struct { Bit#(32) timestamp; Bool readReqValid; MemRequest readReq; Bool readDataValid; Bit#(64) readData; Bit#(8) readDataTag; Bool readDataLast; } TimestampedTraceRecord deriving (Bits); interface TraceIndication; method Action traceEntry(Bit#(32) timestamp, Bool readReqValid, Bit#(8) sglId, Bit#(32) offset, Bit#(16) burstLen, Bit#(8) tag, Bool readDataValid, Bit#(64) readData, Bit#(8) readDataTag, Bool readDataLast); endinterface interface TraceValue#(type a); interface Wire#(a) w; method a m(); endinterface interface TraceAction#(type a); interface Wire#(a) w; method Action m(a v); endinterface interface TraceGet#(type a); method Bool valid(); interface Wire#(a) w; interface Get#(a) get; endinterface interface TracePut#(type a); method Bool valid(); interface Wire#(a) w; interface Put#(a) put; endinterface module mkTraceValue#(a f)(TraceValue#(a)) provisos (Bits#(a, asz)); Wire#(a) _w <- mkDWire(unpack(0)); rule rl_value; _w <= f(); endrule interface w = _w; method a m(); return f(); endmethod endmodule module mkTraceAction#(function Action f(a v))(TraceAction#(a)) provisos (Bits#(a, asz)); Wire#(a) _w <- mkDWire(unpack(0)); interface w = _w; method Action m(a v); _w <= v; f(v); endmethod endmodule module mkTraceGet#(Get#(a) g)(TraceGet#(a)) provisos (Bits#(a, asz)); Wire#(Bool) _valid <- mkDWire(False); Wire#(a) _w <- mkDWire(unpack(0)); method valid = _valid; interface w = _w; interface Get get; method ActionValue#(a) get(); let v <- g.get(); _valid <= True; _w <= v; return v; endmethod endinterface endmodule module mkTracePut#(Put#(a) p)(TracePut#(a)) provisos (Bits#(a, asz)); Wire#(Bool) _valid <- mkDWire(False); Wire#(a) _w <- mkDWire(unpack(0)); method valid = _valid; interface w = _w; interface Put put; method Action put(a v); _valid <= True; _w <= v; p.put(v); endmethod endinterface endmodule module mkTracer#(MemReadClient#(64) client, TraceIndication tind)(MemReadClient#(64)); Reg#(Bit#(32)) cycles <- mkReg(0); let addrReg <- mkReg(0); let traceFifo <- mkSizedBRAMFIFOF(1024); rule rl_cycles; cycles <= cycles + 1; endrule let readReqTrace <- mkTraceGet(client.readReq); let readDataTrace <- mkTracePut(client.readData); rule rl_trace if (readReqTrace.valid); let record = TimestampedTraceRecord { timestamp: cycles, readReqValid: readReqTrace.valid, readReq: readReqTrace.w, readDataValid: readDataTrace.valid, readData: truncate(readDataTrace.w.data), readDataTag: extend(readDataTrace.w.tag), readDataLast: readDataTrace.w.last }; if (traceFifo.notFull()) begin traceFifo.enq(record); end endrule rule rl_upload; let tr <- toGet(traceFifo).get(); tind.traceEntry(tr.timestamp, tr.readReqValid, truncate(tr.readReq.sglId), truncate(tr.readReq.offset), extend(tr.readReq.burstLen), extend(tr.readReq.tag), tr.readDataValid, tr.readData, tr.readDataTag, tr.readDataLast ); endrule interface readReq = readReqTrace.get; interface readData = readDataTrace.put; endmodule ================================================ FILE: bsv/TraceMemClient.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import Pipe::*; import GetPut::*; import ConnectalMemTypes::*; import ConnectalMemory::*; module mkTraceReadClient#(PipeIn#(Tuple4#(dmaChanId,Bool,MemRequest,Bit#(timeStampWidth))) tracePipe, PipeIn#(Tuple4#(dmaChanId,Bool,MemData#(dataWidth),Bit#(timeStampWidth))) traceDataPipe, dmaChanId chan, MemReadClient#(dataWidth) m) (MemReadClient#(dataWidth)); Reg#(Bit#(timeStampWidth)) cycles <- mkReg(0); rule rl_cycles; cycles <= cycles + 1; endrule let reqFifo <- mkFIFOF(); let dataFifo <- mkFIFOF(); rule rl_rd_req; let mr <- m.readReq.get(); if (tracePipe.notFull()) tracePipe.enq(tuple4(chan, False, mr, cycles)); reqFifo.enq(mr); endrule rule rl_rd_data; let md <- toGet(dataFifo).get(); if (traceDataPipe.notFull()) traceDataPipe.enq(tuple4(chan, False, md, cycles)); m.readData.put(md); endrule interface Get readReq = toGet(reqFifo); interface Put readData = toPut(dataFifo); endmodule module mkTraceWriteClient#(PipeIn#(Tuple4#(dmaChanId,Bool,MemRequest,Bit#(timeStampWidth))) tracePipe, PipeIn#(Tuple4#(dmaChanId,Bool,MemData#(dataWidth),Bit#(timeStampWidth))) traceDataPipe, PipeIn#(Tuple2#(dmaChanId,Bit#(timeStampWidth))) traceDonePipe, dmaChanId chan, MemWriteClient#(dataWidth) m) (MemWriteClient#(dataWidth)); Reg#(Bit#(timeStampWidth)) cycles <- mkReg(0); rule rl_cycles; cycles <= cycles + 1; endrule let reqFifo <- mkFIFOF(); let dataFifo <- mkFIFOF(); let doneFifo <- mkFIFOF(); rule rl_wr_req; let mr <- m.writeReq.get(); if (tracePipe.notFull()) tracePipe.enq(tuple4(chan, True, mr, cycles)); reqFifo.enq(mr); endrule rule rl_wr_data; let md <- m.writeData.get(); if (traceDataPipe.notFull()) traceDataPipe.enq(tuple4(chan, True, md, cycles)); dataFifo.enq(md); endrule rule rl_wr_done; let tag <- toGet(doneFifo).get(); if (traceDonePipe.notFull()) traceDonePipe.enq(tuple2(chan, cycles)); m.writeDone.put(tag); endrule interface Get writeReq = toGet(reqFifo); interface Get writeData = toGet(dataFifo); interface Put writeDone = toPut(doneFifo); endmodule ================================================ FILE: bsv/UntetheredTop.bsv ================================================ // Copyright (c) 2017 Accelerated Tech, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector :: *; import Clocks :: *; import GetPut :: *; import FIFO :: *; import Connectable :: *; import ClientServer :: *; import DefaultValue :: *; import Real :: *; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" import Xilinx :: *; import Portal :: *; import Top :: *; import ConnectalMemTypes :: *; import ConnectalClocks :: *; import GetPutWithClocks :: *; import HostInterface :: *; import `PinTypeInclude::*; import Platform :: *; `ifndef DataBusWidth `define DataBusWidth 64 `endif interface UntetheredTop#(type pintype); (* prefix="" *) interface pintype pins; endinterface interface UntetheredHost; interface Clock portalClock; interface Reset portalReset; interface Clock derivedClock; interface Reset derivedReset; endinterface `ifdef VirtexUltrascale `define SYS_CLK_PARAM Clock sys_clk1_300_p, Clock sys_clk1_300_n, Clock sys_clk2_300_p, Clock sys_clk2_300_n, `define SYS_CLK_ARG sys_clk1_300_p, sys_clk1_300_n, sys_clk2_300_p, sys_clk2_300_n, `else `define SYS_CLK_PARAM `define SYS_CLK_ARG `endif (* synthesize, no_default_clock, no_default_reset, reset_prefix="RST" *) module mkUntetheredTop #(Clock sys_clk_p, Clock sys_clk_n, `SYS_CLK_PARAM Reset cpu_reset) (UntetheredTop#(`PinType)); Clock sys_clk_200mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk_p, sys_clk_n); Clock sys_clk_200mhz_buf <- mkClockBUFG(clocked_by sys_clk_200mhz); Reset sys_reset_n <- mkResetInverter(cpu_reset, clocked_by sys_clk_200mhz_buf); ClockGenerator7Params clkgenParams = defaultValue; clkgenParams.clkin1_period = 5.000; // 200MHz clkgenParams.clkin_buffer = False; clkgenParams.clkfbout_mult_f = 5.000; // 1000MHz clkgenParams.clkout0_divide_f = derivedClockPeriod; clkgenParams.clkout1_divide = round(mainClockPeriod); clkgenParams.clkout1_duty_cycle = 0.5; clkgenParams.clkout1_phase = 0.0000; clkgenParams.clkout2_divide = 4; // 250MHz clkgenParams.clkout2_duty_cycle = 0.5; clkgenParams.clkout2_phase = 0.0000; ClockGenerator7 clkgen <- mkClockGenerator7(clkgenParams, clocked_by sys_clk_200mhz_buf, reset_by sys_reset_n); Clock portalClock; Reset portalReset; if (mainClockPeriod == 5) begin portalClock = sys_clk_200mhz_buf; portalReset = sys_reset_n; end else begin portalClock = clkgen.clkout1; portalReset <- mkSyncReset(5, sys_reset_n, portalClock); end Clock derivedClock = clkgen.clkout0; Reset derivedReset <- mkSyncReset(5, sys_reset_n, derivedClock); UntetheredHost host = (interface UntetheredHost; interface portalClock = portalClock; interface portalReset = portalReset; interface derivedClock = derivedClock; interface derivedReset = derivedReset; endinterface); Vector#(NumberOfUserTiles,ConnectalTop#(`PinType)) tile <- replicateM(mkConnectalTop( `ifdef IMPORT_HOSTIF // no synthesis boundary host, `else // enables synthesis boundary `ifdef IMPORT_HOST_CLOCKS host.derivedClock, host.derivedReset, `endif `endif clocked_by host.portalClock, reset_by host.portalReset)); Platform portalTop <- mkPlatform(tile, clocked_by host.portalClock, reset_by host.portalReset); interface pins = portalTop.pins; endmodule ================================================ FILE: bsv/XsimIF.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. typedef enum { XsimIfcNames_XsimMsgRequest, XsimIfcNames_XsimMsgIndication } XsimIfcNames; interface XsimMsgRequest; method Action msgSink(Bit#(32) portal, Bit#(32) data); method Action msgSinkFd(Bit#(32) portal, SpecialTypeForSendingFd data); endinterface interface XsimMsgIndication; method Action msgSource(Bit#(32) portal, Bit#(32) data); endinterface ================================================ FILE: bsv/XsimTop.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import Vector :: *; import GetPut::*; import Connectable::*; import Portal :: *; import Top :: *; import HostInterface :: *; import Pipe::*; import CnocPortal::*; import ConnectalMemTypes:: *; import ConnectalMMU:: *; import MemServer:: *; import MMURequest::*; import MMUIndication::*; import MemServerIndication::*; import MemServerRequest::*; import SimDma::*; import IfcNames::*; import BuildVector::*; `include "ConnectalProjectConfig.bsv" `ifdef PinTypeInclude import `PinTypeInclude::*; `endif `ifdef PinType typedef `PinType PinType; `else typedef Empty PinType; `endif `ifndef SVDPI import "BDPI" function Action dpi_init(); import "BDPI" function ActionValue#(Bool) dpi_cycle(); // returns non-zero if verilog should $finish(). `endif interface XsimTop; interface PinType pins; endinterface interface XsimSource; method Action beat(Bit#(32) v); endinterface `ifdef SVDPI import "BVI" XsimSource = module mkXsimSourceBVI#(Bit#(32) portal)(XsimSource); port portal = portal; method beat(beat) enable(en_beat); schedule (beat) C (beat); endmodule module mkXsimSource#(PortalMsgIndication indication)(Empty); let tmp <- mkXsimSourceBVI(indication.id); rule ind_dst_rdy; indication.message.deq(); tmp.beat(indication.message.first()); endrule endmodule `else import "BDPI" function Action dpi_msgSource_beat(Bit#(32) portal, Bit#(32) beat); module mkXsimSource#(PortalMsgIndication indication)(Empty); rule ind_dst_rdy; indication.message.deq(); dpi_msgSource_beat(indication.id, indication.message.first()); endrule endmodule `endif interface MsgSinkR#(numeric type bytes_per_beat); method ActionValue#(Bit#(32)) beat(); endinterface `ifdef SVDPI import "BVI" XsimSink = module mkXsimSinkBVI#(Bit#(32) portal)(MsgSinkR#(4)); port portal = portal; method beat beat() enable (EN_beat) ready (RDY_beat); schedule (beat) C (beat); endmodule module mkXsimSink#(PortalMsgRequest request)(Empty); let sink <- mkXsimSinkBVI(request.id); rule req_src_rdy; let beat <- sink.beat(); request.message.enq(beat); endrule endmodule `else import "BDPI" function ActionValue#(Bit#(33)) dpi_msgSink_beat(Bit#(32) portal); module mkXsimSink#(PortalMsgRequest request)(Empty); rule req_src_rdy; let beat <- dpi_msgSink_beat(request.id); if (unpack(beat[32])) request.message.enq(beat[31:0]); endrule endmodule `endif module mkXsimMemoryConnection#(PhysMemMaster#(addrWidth, dataWidth) master)(Empty) provisos (Mul#(TDiv#(dataWidth, 8), 8, dataWidth), Mul#(TDiv#(dataWidth, 32), 32, dataWidth), Add#(a__, TDiv#(DataBusWidth,8), TDiv#(dataWidth, 8)), Mul#(TDiv#(dataWidth, 32), 4, TDiv#(dataWidth, 8))); PhysMemSlave#(addrWidth,dataWidth) slave <- mkSimDmaDmaMaster(); mkConnection(master, slave); endmodule module mkXsimTop#(Clock derivedClock, Reset derivedReset, Clock sys_clk)(XsimTop); Reg#(Bool) dumpstarted <- mkReg(False); rule startdump if (!dumpstarted); //$dumpfile("dump.vcd"); //$dumpvars; $display("XsimTop starting"); dumpstarted <= True; endrule XsimHost host <- mkXsimHost(derivedClock, derivedReset, sys_clk); let top <- mkCnocTop( `ifdef IMPORT_HOSTIF host `else `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary derivedClock, derivedReset `else // otherwise no params `endif `endif ); `ifndef SVDPI Reg#(Bool) initCalled <- mkReg(False); rule call_init if (!initCalled); dpi_init(); initCalled <= True; endrule rule finish; let doFinish <- dpi_cycle(); if (doFinish) begin $display("simulator calling $finish"); $finish(); end endrule `endif MMUIndicationOutput lMMUIndicationOutput <- mkMMUIndicationOutput; MMURequestInput lMMURequestInput <- mkMMURequestInput; MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationOutput.ifc); mkConnection(lMMURequestInput.pipes, lMMU.request); MemServerIndicationOutput lMemServerIndicationOutput <- mkMemServerIndicationOutput; MemServerRequestInput lMemServerRequestInput <- mkMemServerRequestInput; MemServer::MemServer#(PhysAddrWidth,DataBusWidth,NumberOfMasters) lMemServer <- mkMemServer(top.readers, top.writers, cons(lMMU,nil), lMemServerIndicationOutput.ifc); mkConnection(lMemServerRequestInput.pipes, lMemServer.request); let lMMUIndicationOutputNoc <- mkPortalMsgIndication(extend(pack(PlatformIfcNames_MMUIndicationH2S)), lMMUIndicationOutput.portalIfc.indications, lMMUIndicationOutput.portalIfc.messageSize); let lMMURequestInputNoc <- mkPortalMsgRequest(extend(pack(PlatformIfcNames_MMURequestS2H)), lMMURequestInput.portalIfc.requests); let lMemServerIndicationOutputNoc <- mkPortalMsgIndication(extend(pack(PlatformIfcNames_MemServerIndicationH2S)), lMemServerIndicationOutput.portalIfc.indications, lMemServerIndicationOutput.portalIfc.messageSize); let lMemServerRequestInputNoc <- mkPortalMsgRequest(extend(pack(PlatformIfcNames_MemServerRequestS2H)), lMemServerRequestInput.portalIfc.requests); mapM_(mkXsimSink, append(top.requests, append(vec(lMMURequestInputNoc), vec(lMemServerRequestInputNoc)))); mapM_(mkXsimSource, append(top.indications, append(vec(lMMUIndicationOutputNoc), vec(lMemServerIndicationOutputNoc)))); mapM_(mkXsimMemoryConnection, lMemServer.masters); `ifdef PinType interface pins = top.pins; `endif endmodule ================================================ FILE: bsv/ZynqTop.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import ConnectalClocks::*; import Clocks :: *; import DefaultValue :: *; import Vector :: *; import Connectable :: *; import ConnectableWithTrace::*; import Portal :: *; import ConnectalMemTypes :: *; import AxiMasterSlave :: *; import XilinxCells :: *; import ConnectalXilinxCells :: *; import PS7LIB::*; import PS7Trace::*; import PPS7LIB::*; import CtrlMux::*; import AxiDma :: *; import Top :: *; import Bscan :: *; import HostInterface :: *; import Platform :: *; `include "ConnectalProjectConfig.bsv" import `PinTypeInclude::*; `ifdef XILINX_SYS_CLK `define SYS_CLK_PARAM #( Clock sys_clk_p, Clock sys_clk_n ) `define SYS_CLK_ARG sys_clk_p, sys_clk_n, `else `define SYS_CLK_PARAM `define SYS_CLK_ARG `endif interface I2C_Pins; interface Inout#(Bit#(1)) scl; interface Inout#(Bit#(1)) sda; endinterface (* always_ready, always_enabled *) interface ZynqTop; (* prefix="" *) interface ZynqPins zynq; `ifdef USE_I2C0 (* prefix="I2C0" *) interface I2C_Pins i2c0; `endif `ifdef USE_I2C1 (* prefix="I2C1" *) interface I2C_Pins i2c1; `endif (* prefix="" *) interface `PinType pins; interface Vector#(4, Clock) deleteme_unused_clock; interface Vector#(4, Reset) deleteme_unused_reset; endinterface module mkZynqTop `SYS_CLK_PARAM (ZynqTop); `ifndef TOP_SOURCES_PORTAL_CLOCK let axiClock <- exposeCurrentClock(); `else B2C axiClockB2C <- mkB2C(); let axiClock = axiClockB2C.c; `endif PS7 ps7 <- mkPS7(axiClock); Clock mainclock = ps7.portalClock; Reset mainreset = ps7.portalReset; `ifdef XILINX_SYS_CLK Clock sys_clk_200mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk_p, sys_clk_n); Clock sys_clk_200mhz_buf <- mkClockBUFG(clocked_by sys_clk_200mhz); `endif // XILINX_SYS_CLK `ifdef USE_I2C0 let tscl0 <- mkIOBUF(~ps7.i2c[0].scltn, ps7.i2c[0].sclo, clocked_by mainclock, reset_by mainreset); let tsda0 <- mkIOBUF(~ps7.i2c[0].sdatn, ps7.i2c[0].sdao, clocked_by mainclock, reset_by mainreset); rule sdai0; ps7.i2c[0].sdai(tsda0.o); ps7.i2c[0].scli(tscl0.o); endrule `endif `ifdef USE_I2C1 let tscl1 <- mkIOBUF(~ps7.i2c[1].scltn, ps7.i2c[1].sclo, clocked_by mainclock, reset_by mainreset); let tsda1 <- mkIOBUF(~ps7.i2c[1].sdatn, ps7.i2c[1].sdao, clocked_by mainclock, reset_by mainreset); rule sdai1; ps7.i2c[1].sdai(tsda1.o); ps7.i2c[1].scli(tscl1.o); endrule `endif BscanTop bscan <- mkBscanTop(3, clocked_by mainclock, reset_by mainreset); // Use USER3 (JTAG IDCODE address 0x22) BscanLocal lbscan <- mkBscanLocal(bscan, clocked_by bscan.tck, reset_by bscan.rst); Vector#(NumberOfUserTiles,ConnectalTop#(`PinType)) ts <- replicateM(mkConnectalTop( `ifdef IMPORT_HOSTIF (interface HostInterface; interface ps7 = ps7; interface portalClock = mainclock; interface portalReset = mainreset; interface derivedClock = ps7.derivedClock; interface derivedReset = ps7.derivedReset; interface bscan = lbscan.loc[0]; `ifdef XILINX_SYS_CLK interface tsys_clk_200mhz = sys_clk_200mhz; interface tsys_clk_200mhz_buf = sys_clk_200mhz_buf; `endif endinterface), `else // enables synthesis boundary `ifdef IMPORT_HOST_CLOCKS ps7.derivedClock, ps7.derivedReset, `endif `endif clocked_by mainclock, reset_by mainreset)); `ifdef TOP_SOURCES_PORTAL_CLOCK C2B portalClockC2B <- mkC2B(ts[0].portalClockSource, clocked_by axiClockB2C.c); rule rl_portal_clock_source; axiClockB2C.inputclock(portalClockC2B.o); endrule `endif Platform top <- mkPlatform(ts, clocked_by mainclock, reset_by mainreset); mkConnectionWithTrace(ps7, top, lbscan.loc[1], clocked_by mainclock, reset_by mainreset); let intr_mux <- mkInterruptMux(top.interrupt); rule send_int_rule; ps7.interrupt(pack(intr_mux)); endrule module bufferClock#(Integer i)(Clock); let bc <- mkClockBUFG(clocked_by ps7.fclkclk[i]); return bc; endmodule module bufferReset#(Integer i)(Reset); let rc <- mkSyncReset(10, ps7.fclkreset[i], ps7.fclkclk[0]); return rc; endmodule Vector#(4, Clock) unused_clock <- genWithM(bufferClock); Vector#(4, Reset) unused_reset <- genWithM(bufferReset); interface zynq = ps7.pins; `ifdef USE_I2C0 interface I2C_Pins i2c0; interface Inout scl = tscl0.io; interface Inout sda = tsda0.io; endinterface `endif `ifdef USE_I2C1 interface I2C_Pins i2c1; interface Inout scl = tscl1.io; interface Inout sda = tsda1.io; endinterface `endif interface pins = top.pins; interface deleteme_unused_clock = unused_clock; interface deleteme_unused_reset = unused_reset; endmodule ================================================ FILE: bsv/ZynqUltraTop.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import ConnectalClocks::*; import Clocks :: *; import DefaultValue :: *; import Vector :: *; import Connectable :: *; import ConnectableWithTrace::*; import Portal :: *; import ConnectalMemTypes :: *; import AxiMasterSlave :: *; import XilinxCells :: *; import ConnectalXilinxCells :: *; import PS8LIB::*; import ZYNQ_ULTRA::*; import CtrlMux::*; import AxiDma :: *; import Top :: *; import Bscan :: *; import HostInterface :: *; import Platform :: *; `include "ConnectalProjectConfig.bsv" import `PinTypeInclude::*; `ifdef XILINX_SYS_CLK `define SYS_CLK_PARAM #( Clock sys_clk_p, Clock sys_clk_n ) `define SYS_CLK_ARG sys_clk_p, sys_clk_n, `else `define SYS_CLK_PARAM `define SYS_CLK_ARG `endif interface I2C_Pins; interface Inout#(Bit#(1)) scl; interface Inout#(Bit#(1)) sda; endinterface (* always_ready, always_enabled *) interface ZynqUltraTop; (* prefix="" *) interface ZynqPins zynq; `ifdef USE_I2C0 (* prefix="I2C0" *) interface I2C_Pins i2c0; `endif `ifdef USE_I2C1 (* prefix="I2C1" *) interface I2C_Pins i2c1; `endif (* prefix="" *) interface `PinType pins; interface Vector#(4, Clock) deleteme_unused_clock; //interface Vector#(4, Reset) deleteme_unused_reset; endinterface module mkZynqUltraTop `SYS_CLK_PARAM (ZynqUltraTop); `ifndef TOP_SOURCES_PORTAL_CLOCK let axiClock <- exposeCurrentClock(); `else B2C axiClockB2C <- mkB2C(); let axiClock = axiClockB2C.c; `endif PS8LIB ps8 <- mkPS8LIB(axiClock); Clock mainclock = ps8.portalClock; Reset mainreset = ps8.portalReset; `ifdef XILINX_SYS_CLK Clock sys_clk_200mhz <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif sys_clk_p, sys_clk_n); Clock sys_clk_200mhz_buf <- mkClockBUFG(clocked_by sys_clk_200mhz); `endif // XILINX_SYS_CLK BscanTop bscan <- mkBscanTop(3, clocked_by mainclock, reset_by mainreset); // Use USER3 (JTAG IDCODE address 0x22) BscanLocal lbscan <- mkBscanLocal(bscan, clocked_by bscan.tck, reset_by bscan.rst); Vector#(NumberOfUserTiles,ConnectalTop#(`PinType)) ts <- replicateM(mkConnectalTop( `ifdef IMPORT_HOSTIF (interface HostInterface; interface ps8 = ps8; interface portalClock = mainclock; interface portalReset = mainreset; interface derivedClock = ps8.derivedClock; interface derivedReset = ps8.derivedReset; interface bscan = lbscan.loc[0]; `ifdef XILINX_SYS_CLK interface tsys_clk_200mhz = sys_clk_200mhz; interface tsys_clk_200mhz_buf = sys_clk_200mhz_buf; `endif endinterface), `else // enables synthesis boundary `ifdef IMPORT_HOST_CLOCKS ps8.derivedClock, ps8.derivedReset, `endif `endif clocked_by mainclock, reset_by mainreset)); `ifdef TOP_SOURCES_PORTAL_CLOCK C2B portalClockC2B <- mkC2B(ts[0].portalClockSource, clocked_by axiClockB2C.c); rule rl_portal_clock_source; axiClockB2C.inputclock(portalClockC2B.o); endrule `endif Platform top <- mkPlatform(ts, clocked_by mainclock, reset_by mainreset); mkConnectionWithTrace(ps8, top, lbscan.loc[1], clocked_by mainclock, reset_by mainreset); let intr_mux <- mkInterruptMux(top.interrupt); rule send_int_rule; ps8.interrupt(pack(intr_mux)); endrule module bufferClock#(Integer i)(Clock); let bc <- mkClockBUFG(clocked_by ps8.plclk[i]); return bc; endmodule //module bufferReset#(Integer i)(Reset); let rc <- mkSyncReset(10, ps8.fclkreset[i], ps8.fclkclk[0]); return rc; endmodule Vector#(4, Clock) unused_clock <- genWithM(bufferClock); //Vector#(4, Reset) unused_reset <- genWithM(bufferReset); //interface zynq = ps8.pins; interface pins = top.pins; interface deleteme_unused_clock = unused_clock; //interface deleteme_unused_reset = unused_reset; endmodule ================================================ FILE: constraints/altera/de5.qsf ================================================ #============================================================ # BUTTON #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to button[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to button[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to button[2] set_instance_assignment -name IO_STANDARD "2.5 V" -to button[3] #============================================================ # CLOCK #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to clock_scl set_instance_assignment -name IO_STANDARD "2.5 V" -to clock_sda #============================================================ # CPU #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_reset_n #============================================================ # DDR3A #============================================================ set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[3] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[4] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[5] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[6] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[7] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[8] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[9] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[10] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[11] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[12] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[13] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[14] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_a[15] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_ba[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_ba[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_ba[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_cas_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_ck[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_ck[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_cke[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_cke[1] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_ck_n[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_ck_n[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_cs_n[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_cs_n[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[3] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[4] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[5] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[6] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dm[7] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[3] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[4] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[5] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[6] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[7] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[8] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[9] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[10] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[11] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[12] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[13] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[14] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[15] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[16] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[17] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[18] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[19] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[20] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[21] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[22] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[23] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[24] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[25] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[26] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[27] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[28] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[29] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[30] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[31] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[32] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[33] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[34] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[35] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[36] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[37] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[38] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[39] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[40] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[41] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[42] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[43] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[44] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[45] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[46] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[47] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[48] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[49] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[50] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[51] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[52] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[53] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[54] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[55] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[56] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[57] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[58] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[59] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[60] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[61] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[62] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_dq[63] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[1] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[2] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[3] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[4] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[5] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[6] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs[7] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[1] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[2] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[3] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[4] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[5] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[6] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3a_dqs_n[7] set_instance_assignment -name IO_STANDARD "1.5 V" -to ddr3a_event_n set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_odt[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_odt[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_ras_n set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_reset_n set_instance_assignment -name IO_STANDARD "1.5 V" -to ddr3a_scl set_instance_assignment -name IO_STANDARD "1.5 V" -to ddr3a_sda set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3a_we_n #============================================================ # DDR3B #============================================================ set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[3] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[4] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[5] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[6] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[7] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[8] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[9] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[10] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[11] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[12] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[13] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[14] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_a[15] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_ba[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_ba[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_ba[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_cas_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_ck[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_ck[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_cke[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_cke[1] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_ck_n[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_ck_n[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_cs_n[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_cs_n[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[3] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[4] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[5] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[6] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dm[7] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[2] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[3] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[4] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[5] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[6] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[7] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[8] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[9] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[10] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[11] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[12] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[13] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[14] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[15] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[16] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[17] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[18] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[19] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[20] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[21] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[22] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[23] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[24] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[25] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[26] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[27] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[28] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[29] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[30] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[31] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[32] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[33] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[34] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[35] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[36] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[37] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[38] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[39] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[40] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[41] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[42] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[43] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[44] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[45] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[46] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[47] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[48] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[49] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[50] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[51] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[52] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[53] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[54] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[55] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[56] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[57] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[58] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[59] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[60] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[61] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[62] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_dq[63] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[1] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[2] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[3] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[4] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[5] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[6] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs[7] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[0] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[1] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[2] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[3] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[4] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[5] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[6] set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.5-V SSTL CLASS I" -to ddr3b_dqs_n[7] set_instance_assignment -name IO_STANDARD "1.5 V" -to ddr3b_event_n set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_odt[0] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_odt[1] set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_ras_n set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_reset_n set_instance_assignment -name IO_STANDARD "1.5 V" -to ddr3b_scl set_instance_assignment -name IO_STANDARD "1.5 V" -to ddr3b_sda set_instance_assignment -name IO_STANDARD "SSTL-15 CLASS I" -to ddr3b_we_n #============================================================ # FAN #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to fan_ctrl #============================================================ # FLASH #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_adv_n set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_ce_n[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_ce_n[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_clk set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_oe_n set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_rdy_bsy_n[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_rdy_bsy_n[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_reset_n set_instance_assignment -name IO_STANDARD "2.5 V" -to flash_we_n #============================================================ # FSM #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[2] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[3] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[4] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[5] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[6] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[7] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[8] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[9] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[10] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[11] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[12] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[13] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[14] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[15] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[16] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[17] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[18] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[19] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[20] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[21] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[22] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[23] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[24] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[25] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_a[26] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[2] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[3] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[4] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[5] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[6] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[7] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[8] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[9] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[10] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[11] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[12] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[13] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[14] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[15] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[16] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[17] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[18] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[19] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[20] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[21] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[22] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[23] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[24] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[25] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[26] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[27] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[28] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[29] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[30] set_instance_assignment -name IO_STANDARD "2.5 V" -to fsm_d[31] #============================================================ # HEX0 #============================================================ set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[0] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[1] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[2] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[3] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[4] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[5] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_d[6] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex0_dp #============================================================ # HEX1 #============================================================ set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[0] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[1] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[2] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[3] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[4] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[5] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_d[6] set_instance_assignment -name IO_STANDARD "1.5 V" -to hex1_dp #============================================================ # LED #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to leds[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to leds[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to leds[2] set_instance_assignment -name IO_STANDARD "2.5 V" -to leds[3] set_instance_assignment -name IO_STANDARD "2.5 V" -to led_bracket[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to led_bracket[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to led_bracket[2] set_instance_assignment -name IO_STANDARD "2.5 V" -to led_bracket[3] set_instance_assignment -name IO_STANDARD "2.5 V" -to led_rj45_l set_instance_assignment -name IO_STANDARD "2.5 V" -to led_rj45_r #============================================================ # MAX2 #============================================================ #============================================================ # OSC #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to osc_50_b3b set_instance_assignment -name IO_STANDARD "1.8 V" -to osc_50_b3d set_instance_assignment -name IO_STANDARD "1.8 V" -to osc_50_b4a set_instance_assignment -name IO_STANDARD "1.8 V" -to osc_50_b4d set_instance_assignment -name IO_STANDARD "1.5 V" -to osc_50_b7a set_instance_assignment -name IO_STANDARD "1.5 V" -to osc_50_b7d set_instance_assignment -name IO_STANDARD "1.5 V" -to osc_50_b8a set_instance_assignment -name IO_STANDARD "1.8 V" -to osc_50_b8d #============================================================ # PCIE #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to pcie_perst_n set_instance_assignment -name IO_STANDARD HCSL -to pcie_refclk_p set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[0] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[2] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[3] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[4] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[5] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[6] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_rx_p[7] set_instance_assignment -name IO_STANDARD "2.5 V" -to pcie_smbclk set_instance_assignment -name IO_STANDARD "2.5 V" -to pcie_smbdat set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[0] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[2] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[3] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[4] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[5] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[6] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to PCIE_tx_p[7] set_instance_assignment -name IO_STANDARD "2.5 V" -to pcie_wake_n #============================================================ # QDRIIA #============================================================ set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[18] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[19] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_a[20] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_bws_n[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_bws_n[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_cq_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_cq_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_d[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_doff_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriia_k_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriia_k_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_odt set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_q[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_qvld set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_rps_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriia_wps_n #============================================================ # QDRIIB #============================================================ set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[18] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[19] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_a[20] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_bws_n[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_bws_n[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_cq_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_cq_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_d[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_doff_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriib_k_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriib_k_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_odt set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_q[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_qvld set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_rps_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriib_wps_n #============================================================ # QDRIIC #============================================================ set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[18] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[19] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_a[20] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_bws_n[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_bws_n[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_cq_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_cq_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_d[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_doff_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriic_k_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriic_k_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_odt set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_q[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_qvld set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_rps_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriic_wps_n #============================================================ # QDRIID #============================================================ set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[18] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[19] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_a[20] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_bws_n[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_bws_n[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_cq_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_cq_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_d[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_doff_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriid_k_n set_instance_assignment -name IO_STANDARD "DIFFERENTIAL 1.8-V HSTL CLASS I" -to qdriid_k_p set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_odt set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[0] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[1] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[2] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[3] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[4] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[5] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[6] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[7] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[8] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[9] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[10] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[11] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[12] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[13] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[14] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[15] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[16] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_q[17] set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_qvld set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_rps_n set_instance_assignment -name IO_STANDARD "1.8-V HSTL CLASS I" -to qdriid_wps_n #============================================================ # RS422 #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to rs422_de set_instance_assignment -name IO_STANDARD "2.5 V" -to rs422_din set_instance_assignment -name IO_STANDARD "2.5 V" -to rs422_dout set_instance_assignment -name IO_STANDARD "2.5 V" -to rs422_re_n set_instance_assignment -name IO_STANDARD "2.5 V" -to rs422_te #============================================================ # RZQ #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to rzq_0 set_instance_assignment -name IO_STANDARD "1.8 V" -to rzq_1 set_instance_assignment -name IO_STANDARD "1.5 V" -to rzq_4 set_instance_assignment -name IO_STANDARD "1.5 V" -to rzq_5 #============================================================ # SATA #============================================================ #============================================================ # SFP10G #============================================================ #============================================================ # SFP1G #============================================================ set_instance_assignment -name IO_STANDARD HCSL -to sfp1g_refclk_p #============================================================ # SFPA #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_los set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_mod0_prsnt_n set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_mod1_scl set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_mod2_sda set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_ratesel[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_ratesel[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpa_rx_p set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_txdisable set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpa_txfault set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpa_tx_p #============================================================ # SFPB #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_los set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_mod0_prsnt_n set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_mod1_scl set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_mod2_sda set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_ratesel[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_ratesel[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpb_rx_p set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_txdisable set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpb_txfault set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpb_tx_p #============================================================ # SFPC #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_los set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_mod0_prsnt_n set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_mod1_scl set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_mod2_sda set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_ratesel[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_ratesel[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpc_rx_p set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_txdisable set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpc_txfault set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpc_tx_p #============================================================ # SFPD #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_los set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_mod0_prsnt_n set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_mod1_scl set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_mod2_sda set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_ratesel[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_ratesel[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpd_rx_p set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_txdisable set_instance_assignment -name IO_STANDARD "2.5 V" -to sfpd_txfault set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sfpd_tx_p set_instance_assignment -name IO_STANDARD HCSL -to sfp_refclk_p #============================================================ # SMA #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to sma_clkin set_instance_assignment -name IO_STANDARD "2.5 V" -to sma_clkout #============================================================ # SW #============================================================ set_instance_assignment -name IO_STANDARD "1.8 V" -to sw[0] set_instance_assignment -name IO_STANDARD "1.8 V" -to sw[1] set_instance_assignment -name IO_STANDARD "1.8 V" -to sw[2] set_instance_assignment -name IO_STANDARD "1.8 V" -to sw[3] #============================================================ # TEMP #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to temp_clk set_instance_assignment -name IO_STANDARD "2.5 V" -to temp_data set_instance_assignment -name IO_STANDARD "2.5 V" -to temp_int_n set_instance_assignment -name IO_STANDARD "2.5 V" -to temp_overt_n #============================================================ # SATA #============================================================ set_instance_assignment -name IO_STANDARD HCSL -to sata_host_refclk_p set_instance_assignment -name IO_STANDARD HCSL -to sata_device_refclk_p set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_device_rx_p[0] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_device_rx_p[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_device_tx_p[0] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_device_tx_p[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_host_rx_p[0] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_host_rx_p[1] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_host_tx_p[0] set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to sata_host_tx_p[1] #============================================================ # SATA #============================================================ set_instance_assignment -name IO_STANDARD "2.5 V" -to pll_scl set_location_assignment PIN_AF32 -to pll_scl set_instance_assignment -name IO_STANDARD "2.5 V" -to pll_sda set_location_assignment PIN_AG32 -to pll_sda #============================================================ # End of pin assignments by Terasic System Builder #============================================================ set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" set_location_assignment PIN_AK15 -to button[0] set_location_assignment PIN_AK14 -to button[1] set_location_assignment PIN_AL14 -to button[2] set_location_assignment PIN_AL15 -to button[3] set_location_assignment PIN_AE15 -to clock_scl set_location_assignment PIN_AE16 -to clock_sda set_location_assignment PIN_BC37 -to cpu_reset_n set_location_assignment PIN_M39 -to ddr3a_a[0] set_location_assignment PIN_L35 -to ddr3a_a[1] set_location_assignment PIN_N38 -to ddr3a_a[2] set_location_assignment PIN_L36 -to ddr3a_a[3] set_location_assignment PIN_H36 -to ddr3a_a[4] set_location_assignment PIN_K29 -to ddr3a_a[5] set_location_assignment PIN_D37 -to ddr3a_a[6] set_location_assignment PIN_K35 -to ddr3a_a[7] set_location_assignment PIN_K32 -to ddr3a_a[8] set_location_assignment PIN_K37 -to ddr3a_a[9] set_location_assignment PIN_M38 -to ddr3a_a[10] set_location_assignment PIN_C37 -to ddr3a_a[11] set_location_assignment PIN_K36 -to ddr3a_a[12] set_location_assignment PIN_M33 -to ddr3a_a[13] set_location_assignment PIN_K34 -to ddr3a_a[14] set_location_assignment PIN_B38 -to ddr3a_a[15] set_location_assignment PIN_M37 -to ddr3a_ba[0] set_location_assignment PIN_P39 -to ddr3a_ba[1] set_location_assignment PIN_J36 -to ddr3a_ba[2] set_location_assignment PIN_M36 -to ddr3a_cas_n set_location_assignment PIN_G37 -to ddr3a_ck[0] set_location_assignment PIN_J37 -to ddr3a_ck[1] set_location_assignment PIN_E36 -to ddr3a_cke[0] set_location_assignment PIN_B35 -to ddr3a_cke[1] set_location_assignment PIN_F36 -to ddr3a_ck_n[0] set_location_assignment PIN_H37 -to ddr3a_ck_n[1] set_location_assignment PIN_P36 -to ddr3a_cs_n[0] set_location_assignment PIN_R28 -to ddr3a_cs_n[1] set_location_assignment PIN_C36 -to ddr3a_dm[0] set_location_assignment PIN_E32 -to ddr3a_dm[1] set_location_assignment PIN_H34 -to ddr3a_dm[2] set_location_assignment PIN_L32 -to ddr3a_dm[3] set_location_assignment PIN_N32 -to ddr3a_dm[4] set_location_assignment PIN_W32 -to ddr3a_dm[5] set_location_assignment PIN_K30 -to ddr3a_dm[6] set_location_assignment PIN_T28 -to ddr3a_dm[7] set_location_assignment PIN_A35 -to ddr3a_dq[0] set_location_assignment PIN_A34 -to ddr3a_dq[1] set_location_assignment PIN_D36 -to ddr3a_dq[2] set_location_assignment PIN_C33 -to ddr3a_dq[3] set_location_assignment PIN_B32 -to ddr3a_dq[4] set_location_assignment PIN_D35 -to ddr3a_dq[5] set_location_assignment PIN_D33 -to ddr3a_dq[6] set_location_assignment PIN_E33 -to ddr3a_dq[7] set_location_assignment PIN_A32 -to ddr3a_dq[8] set_location_assignment PIN_A31 -to ddr3a_dq[9] set_location_assignment PIN_C30 -to ddr3a_dq[10] set_location_assignment PIN_D30 -to ddr3a_dq[11] set_location_assignment PIN_B29 -to ddr3a_dq[12] set_location_assignment PIN_E30 -to ddr3a_dq[13] set_location_assignment PIN_F31 -to ddr3a_dq[14] set_location_assignment PIN_G31 -to ddr3a_dq[15] set_location_assignment PIN_F35 -to ddr3a_dq[16] set_location_assignment PIN_G34 -to ddr3a_dq[17] set_location_assignment PIN_J33 -to ddr3a_dq[18] set_location_assignment PIN_J34 -to ddr3a_dq[19] set_location_assignment PIN_F34 -to ddr3a_dq[20] set_location_assignment PIN_E35 -to ddr3a_dq[21] set_location_assignment PIN_J31 -to ddr3a_dq[22] set_location_assignment PIN_K31 -to ddr3a_dq[23] set_location_assignment PIN_P34 -to ddr3a_dq[24] set_location_assignment PIN_R33 -to ddr3a_dq[25] set_location_assignment PIN_M34 -to ddr3a_dq[26] set_location_assignment PIN_L33 -to ddr3a_dq[27] set_location_assignment PIN_R34 -to ddr3a_dq[28] set_location_assignment PIN_T34 -to ddr3a_dq[29] set_location_assignment PIN_W34 -to ddr3a_dq[30] set_location_assignment PIN_V35 -to ddr3a_dq[31] set_location_assignment PIN_P33 -to ddr3a_dq[32] set_location_assignment PIN_P32 -to ddr3a_dq[33] set_location_assignment PIN_V33 -to ddr3a_dq[34] set_location_assignment PIN_V34 -to ddr3a_dq[35] set_location_assignment PIN_N31 -to ddr3a_dq[36] set_location_assignment PIN_M31 -to ddr3a_dq[37] set_location_assignment PIN_U32 -to ddr3a_dq[38] set_location_assignment PIN_U33 -to ddr3a_dq[39] set_location_assignment PIN_R31 -to ddr3a_dq[40] set_location_assignment PIN_W31 -to ddr3a_dq[41] set_location_assignment PIN_U30 -to ddr3a_dq[42] set_location_assignment PIN_P31 -to ddr3a_dq[43] set_location_assignment PIN_T31 -to ddr3a_dq[44] set_location_assignment PIN_Y32 -to ddr3a_dq[45] set_location_assignment PIN_T29 -to ddr3a_dq[46] set_location_assignment PIN_P30 -to ddr3a_dq[47] set_location_assignment PIN_H32 -to ddr3a_dq[48] set_location_assignment PIN_H31 -to ddr3a_dq[49] set_location_assignment PIN_L30 -to ddr3a_dq[50] set_location_assignment PIN_L29 -to ddr3a_dq[51] set_location_assignment PIN_F32 -to ddr3a_dq[52] set_location_assignment PIN_G32 -to ddr3a_dq[53] set_location_assignment PIN_M30 -to ddr3a_dq[54] set_location_assignment PIN_N29 -to ddr3a_dq[55] set_location_assignment PIN_U29 -to ddr3a_dq[56] set_location_assignment PIN_V28 -to ddr3a_dq[57] set_location_assignment PIN_Y28 -to ddr3a_dq[58] set_location_assignment PIN_W29 -to ddr3a_dq[59] set_location_assignment PIN_V30 -to ddr3a_dq[60] set_location_assignment PIN_V29 -to ddr3a_dq[61] set_location_assignment PIN_W28 -to ddr3a_dq[62] set_location_assignment PIN_Y27 -to ddr3a_dq[63] set_location_assignment PIN_C34 -to ddr3a_dqs[0] set_location_assignment PIN_C31 -to ddr3a_dqs[1] set_location_assignment PIN_H35 -to ddr3a_dqs[2] set_location_assignment PIN_U35 -to ddr3a_dqs[3] set_location_assignment PIN_T33 -to ddr3a_dqs[4] set_location_assignment PIN_T30 -to ddr3a_dqs[5] set_location_assignment PIN_J30 -to ddr3a_dqs[6] set_location_assignment PIN_Y30 -to ddr3a_dqs[7] set_location_assignment PIN_B34 -to ddr3a_dqs_n[0] set_location_assignment PIN_B31 -to ddr3a_dqs_n[1] set_location_assignment PIN_G35 -to ddr3a_dqs_n[2] set_location_assignment PIN_T35 -to ddr3a_dqs_n[3] set_location_assignment PIN_T32 -to ddr3a_dqs_n[4] set_location_assignment PIN_R30 -to ddr3a_dqs_n[5] set_location_assignment PIN_H30 -to ddr3a_dqs_n[6] set_location_assignment PIN_Y29 -to ddr3a_dqs_n[7] set_location_assignment PIN_K19 -to ddr3a_event_n set_location_assignment PIN_V36 -to ddr3a_odt[0] set_location_assignment PIN_W35 -to ddr3a_odt[1] set_location_assignment PIN_P38 -to ddr3a_ras_n set_location_assignment PIN_H33 -to ddr3a_reset_n set_location_assignment PIN_C15 -to ddr3a_scl set_location_assignment PIN_P15 -to ddr3a_sda set_location_assignment PIN_N37 -to ddr3a_we_n set_location_assignment PIN_G17 -to ddr3b_a[0] set_location_assignment PIN_F17 -to ddr3b_a[1] set_location_assignment PIN_N17 -to ddr3b_a[2] set_location_assignment PIN_F19 -to ddr3b_a[3] set_location_assignment PIN_N19 -to ddr3b_a[4] set_location_assignment PIN_H16 -to ddr3b_a[5] set_location_assignment PIN_M17 -to ddr3b_a[6] set_location_assignment PIN_T18 -to ddr3b_a[7] set_location_assignment PIN_H17 -to ddr3b_a[8] set_location_assignment PIN_J19 -to ddr3b_a[9] set_location_assignment PIN_C19 -to ddr3b_a[10] set_location_assignment PIN_R18 -to ddr3b_a[11] set_location_assignment PIN_K18 -to ddr3b_a[12] set_location_assignment PIN_E18 -to ddr3b_a[13] set_location_assignment PIN_T19 -to ddr3b_a[14] set_location_assignment PIN_R19 -to ddr3b_a[15] set_location_assignment PIN_C18 -to ddr3b_ba[0] set_location_assignment PIN_G19 -to ddr3b_ba[1] set_location_assignment PIN_M20 -to ddr3b_ba[2] set_location_assignment PIN_A17 -to ddr3b_cas_n set_location_assignment PIN_B16 -to ddr3b_ck[0] set_location_assignment PIN_E17 -to ddr3b_ck[1] set_location_assignment PIN_P17 -to ddr3b_cke[0] set_location_assignment PIN_V18 -to ddr3b_cke[1] set_location_assignment PIN_A16 -to ddr3b_ck_n[0] set_location_assignment PIN_D17 -to ddr3b_ck_n[1] set_location_assignment PIN_B19 -to ddr3b_cs_n[0] set_location_assignment PIN_B17 -to ddr3b_cs_n[1] set_location_assignment PIN_R15 -to ddr3b_dm[0] set_location_assignment PIN_K15 -to ddr3b_dm[1] set_location_assignment PIN_V12 -to ddr3b_dm[2] set_location_assignment PIN_G10 -to ddr3b_dm[3] set_location_assignment PIN_T12 -to ddr3b_dm[4] set_location_assignment PIN_C16 -to ddr3b_dm[5] set_location_assignment PIN_H15 -to ddr3b_dm[6] set_location_assignment PIN_B11 -to ddr3b_dm[7] set_location_assignment PIN_Y17 -to ddr3b_dq[0] set_location_assignment PIN_W17 -to ddr3b_dq[1] set_location_assignment PIN_V15 -to ddr3b_dq[2] set_location_assignment PIN_T15 -to ddr3b_dq[3] set_location_assignment PIN_V13 -to ddr3b_dq[4] set_location_assignment PIN_V16 -to ddr3b_dq[5] set_location_assignment PIN_W14 -to ddr3b_dq[6] set_location_assignment PIN_U15 -to ddr3b_dq[7] set_location_assignment PIN_T17 -to ddr3b_dq[8] set_location_assignment PIN_T16 -to ddr3b_dq[9] set_location_assignment PIN_R16 -to ddr3b_dq[10] set_location_assignment PIN_P16 -to ddr3b_dq[11] set_location_assignment PIN_N16 -to ddr3b_dq[12] set_location_assignment PIN_M15 -to ddr3b_dq[13] set_location_assignment PIN_M14 -to ddr3b_dq[14] set_location_assignment PIN_L14 -to ddr3b_dq[15] set_location_assignment PIN_T14 -to ddr3b_dq[16] set_location_assignment PIN_U14 -to ddr3b_dq[17] set_location_assignment PIN_U11 -to ddr3b_dq[18] set_location_assignment PIN_T13 -to ddr3b_dq[19] set_location_assignment PIN_U12 -to ddr3b_dq[20] set_location_assignment PIN_R13 -to ddr3b_dq[21] set_location_assignment PIN_P13 -to ddr3b_dq[22] set_location_assignment PIN_N13 -to ddr3b_dq[23] set_location_assignment PIN_K12 -to ddr3b_dq[24] set_location_assignment PIN_J12 -to ddr3b_dq[25] set_location_assignment PIN_J10 -to ddr3b_dq[26] set_location_assignment PIN_H12 -to ddr3b_dq[27] set_location_assignment PIN_N11 -to ddr3b_dq[28] set_location_assignment PIN_M11 -to ddr3b_dq[29] set_location_assignment PIN_H10 -to ddr3b_dq[30] set_location_assignment PIN_H11 -to ddr3b_dq[31] set_location_assignment PIN_T10 -to ddr3b_dq[32] set_location_assignment PIN_R10 -to ddr3b_dq[33] set_location_assignment PIN_M12 -to ddr3b_dq[34] set_location_assignment PIN_L12 -to ddr3b_dq[35] set_location_assignment PIN_V10 -to ddr3b_dq[36] set_location_assignment PIN_V9 -to ddr3b_dq[37] set_location_assignment PIN_R12 -to ddr3b_dq[38] set_location_assignment PIN_P12 -to ddr3b_dq[39] set_location_assignment PIN_D14 -to ddr3b_dq[40] set_location_assignment PIN_C13 -to ddr3b_dq[41] set_location_assignment PIN_B14 -to ddr3b_dq[42] set_location_assignment PIN_B13 -to ddr3b_dq[43] set_location_assignment PIN_E14 -to ddr3b_dq[44] set_location_assignment PIN_F14 -to ddr3b_dq[45] set_location_assignment PIN_A14 -to ddr3b_dq[46] set_location_assignment PIN_A13 -to ddr3b_dq[47] set_location_assignment PIN_K13 -to ddr3b_dq[48] set_location_assignment PIN_K16 -to ddr3b_dq[49] set_location_assignment PIN_H13 -to ddr3b_dq[50] set_location_assignment PIN_H14 -to ddr3b_dq[51] set_location_assignment PIN_J13 -to ddr3b_dq[52] set_location_assignment PIN_J16 -to ddr3b_dq[53] set_location_assignment PIN_G13 -to ddr3b_dq[54] set_location_assignment PIN_F13 -to ddr3b_dq[55] set_location_assignment PIN_D11 -to ddr3b_dq[56] set_location_assignment PIN_C10 -to ddr3b_dq[57] set_location_assignment PIN_A10 -to ddr3b_dq[58] set_location_assignment PIN_B10 -to ddr3b_dq[59] set_location_assignment PIN_G11 -to ddr3b_dq[60] set_location_assignment PIN_F11 -to ddr3b_dq[61] set_location_assignment PIN_E11 -to ddr3b_dq[62] set_location_assignment PIN_E12 -to ddr3b_dq[63] set_location_assignment PIN_Y16 -to ddr3b_dqs[0] set_location_assignment PIN_V17 -to ddr3b_dqs[1] set_location_assignment PIN_P14 -to ddr3b_dqs[2] set_location_assignment PIN_K11 -to ddr3b_dqs[3] set_location_assignment PIN_U9 -to ddr3b_dqs[4] set_location_assignment PIN_E15 -to ddr3b_dqs[5] set_location_assignment PIN_L15 -to ddr3b_dqs[6] set_location_assignment PIN_D12 -to ddr3b_dqs[7] set_location_assignment PIN_W16 -to ddr3b_dqs_n[0] set_location_assignment PIN_U17 -to ddr3b_dqs_n[1] set_location_assignment PIN_N14 -to ddr3b_dqs_n[2] set_location_assignment PIN_L11 -to ddr3b_dqs_n[3] set_location_assignment PIN_T9 -to ddr3b_dqs_n[4] set_location_assignment PIN_D15 -to ddr3b_dqs_n[5] set_location_assignment PIN_K14 -to ddr3b_dqs_n[6] set_location_assignment PIN_C12 -to ddr3b_dqs_n[7] set_location_assignment PIN_K17 -to ddr3b_event_n set_location_assignment PIN_M18 -to ddr3b_odt[0] set_location_assignment PIN_A19 -to ddr3b_odt[1] set_location_assignment PIN_H19 -to ddr3b_ras_n set_location_assignment PIN_T20 -to ddr3b_reset_n set_location_assignment PIN_P18 -to ddr3b_scl set_location_assignment PIN_P19 -to ddr3b_sda set_location_assignment PIN_D18 -to ddr3b_we_n set_location_assignment PIN_AR32 -to fan_ctrl set_location_assignment PIN_AK29 -to flash_adv_n set_location_assignment PIN_AE27 -to flash_ce_n[0] set_location_assignment PIN_BA31 -to flash_ce_n[1] set_location_assignment PIN_AL29 -to flash_clk set_location_assignment PIN_AY30 -to flash_oe_n set_location_assignment PIN_BA29 -to flash_rdy_bsy_n[0] set_location_assignment PIN_BB32 -to flash_rdy_bsy_n[1] set_location_assignment PIN_AE28 -to flash_reset_n set_location_assignment PIN_AR31 -to flash_we_n set_location_assignment PIN_AU32 -to fsm_a[0] set_location_assignment PIN_AH30 -to fsm_a[1] set_location_assignment PIN_AJ30 -to fsm_a[2] set_location_assignment PIN_AH31 -to fsm_a[3] set_location_assignment PIN_AK30 -to fsm_a[4] set_location_assignment PIN_AJ32 -to fsm_a[5] set_location_assignment PIN_AG33 -to fsm_a[6] set_location_assignment PIN_AL30 -to fsm_a[7] set_location_assignment PIN_AK33 -to fsm_a[8] set_location_assignment PIN_AJ33 -to fsm_a[9] set_location_assignment PIN_AN30 -to fsm_a[10] set_location_assignment PIN_AH33 -to fsm_a[11] set_location_assignment PIN_AK32 -to fsm_a[12] set_location_assignment PIN_AM32 -to fsm_a[13] set_location_assignment PIN_AM31 -to fsm_a[14] set_location_assignment PIN_AL31 -to fsm_a[15] set_location_assignment PIN_AN33 -to fsm_a[16] set_location_assignment PIN_AP33 -to fsm_a[17] set_location_assignment PIN_AT32 -to fsm_a[18] set_location_assignment PIN_AT29 -to fsm_a[19] set_location_assignment PIN_AP31 -to fsm_a[20] set_location_assignment PIN_AR30 -to fsm_a[21] set_location_assignment PIN_AU30 -to fsm_a[22] set_location_assignment PIN_AJ31 -to fsm_a[23] set_location_assignment PIN_AP30 -to fsm_a[24] set_location_assignment PIN_AN31 -to fsm_a[25] set_location_assignment PIN_AT30 -to fsm_a[26] set_location_assignment PIN_AG26 -to fsm_d[0] set_location_assignment PIN_AD33 -to fsm_d[1] set_location_assignment PIN_AE34 -to fsm_d[2] set_location_assignment PIN_AF31 -to fsm_d[3] set_location_assignment PIN_AG28 -to fsm_d[4] set_location_assignment PIN_AG30 -to fsm_d[5] set_location_assignment PIN_AF29 -to fsm_d[6] set_location_assignment PIN_AE29 -to fsm_d[7] set_location_assignment PIN_AG25 -to fsm_d[8] set_location_assignment PIN_AF34 -to fsm_d[9] set_location_assignment PIN_AE33 -to fsm_d[10] set_location_assignment PIN_AE31 -to fsm_d[11] set_location_assignment PIN_AF28 -to fsm_d[12] set_location_assignment PIN_AE30 -to fsm_d[13] set_location_assignment PIN_AG29 -to fsm_d[14] set_location_assignment PIN_AG27 -to fsm_d[15] set_location_assignment PIN_AP28 -to fsm_d[16] set_location_assignment PIN_AN28 -to fsm_d[17] set_location_assignment PIN_AU31 -to fsm_d[18] set_location_assignment PIN_AW32 -to fsm_d[19] set_location_assignment PIN_BD32 -to fsm_d[20] set_location_assignment PIN_AY31 -to fsm_d[21] set_location_assignment PIN_BA30 -to fsm_d[22] set_location_assignment PIN_BB30 -to fsm_d[23] set_location_assignment PIN_AM29 -to fsm_d[24] set_location_assignment PIN_AR29 -to fsm_d[25] set_location_assignment PIN_AV31 -to fsm_d[26] set_location_assignment PIN_AV32 -to fsm_d[27] set_location_assignment PIN_BC31 -to fsm_d[28] set_location_assignment PIN_AW30 -to fsm_d[29] set_location_assignment PIN_BC32 -to fsm_d[30] set_location_assignment PIN_BD31 -to fsm_d[31] set_location_assignment PIN_G8 -to hex0_d[0] set_location_assignment PIN_H8 -to hex0_d[1] set_location_assignment PIN_J9 -to hex0_d[2] set_location_assignment PIN_K10 -to hex0_d[3] set_location_assignment PIN_K8 -to hex0_d[4] set_location_assignment PIN_K9 -to hex0_d[5] set_location_assignment PIN_N8 -to hex0_d[6] set_location_assignment PIN_P8 -to hex0_dp set_location_assignment PIN_H18 -to hex1_d[0] set_location_assignment PIN_G16 -to hex1_d[1] set_location_assignment PIN_F16 -to hex1_d[2] set_location_assignment PIN_A7 -to hex1_d[3] set_location_assignment PIN_B7 -to hex1_d[4] set_location_assignment PIN_C9 -to hex1_d[5] set_location_assignment PIN_D10 -to hex1_d[6] set_location_assignment PIN_E9 -to hex1_dp set_location_assignment PIN_AW37 -to leds[0] set_location_assignment PIN_AV37 -to leds[1] set_location_assignment PIN_BB36 -to leds[2] set_location_assignment PIN_BB39 -to leds[3] set_location_assignment PIN_AH15 -to led_bracket[0] set_location_assignment PIN_AH13 -to led_bracket[1] set_location_assignment PIN_AJ13 -to led_bracket[2] set_location_assignment PIN_AJ14 -to led_bracket[3] set_location_assignment PIN_AG15 -to led_rj45_l set_location_assignment PIN_AG16 -to led_rj45_r set_location_assignment PIN_AW35 -to osc_50_b3b set_location_assignment PIN_BC28 -to osc_50_b3d set_location_assignment PIN_AP10 -to osc_50_b4a set_location_assignment PIN_AY18 -to osc_50_b4d set_location_assignment PIN_M8 -to osc_50_b7a set_location_assignment PIN_J18 -to osc_50_b7d set_location_assignment PIN_R36 -to osc_50_b8a set_location_assignment PIN_R25 -to osc_50_b8d set_location_assignment PIN_AU33 -to pcie_perst_n set_location_assignment PIN_AK38 -to pcie_refclk_p set_location_assignment PIN_BB43 -to PCIE_rx_p[0] set_location_assignment PIN_BA41 -to PCIE_rx_p[1] set_location_assignment PIN_AW41 -to PCIE_rx_p[2] set_location_assignment PIN_AY43 -to PCIE_rx_p[3] set_location_assignment PIN_AT43 -to PCIE_rx_p[4] set_location_assignment PIN_AP43 -to PCIE_rx_p[5] set_location_assignment PIN_AM43 -to PCIE_rx_p[6] set_location_assignment PIN_AK43 -to PCIE_rx_p[7] set_location_assignment PIN_BD34 -to pcie_smbclk set_location_assignment PIN_AT33 -to pcie_smbdat set_location_assignment PIN_AY39 -to PCIE_tx_p[0] set_location_assignment PIN_AV39 -to PCIE_tx_p[1] set_location_assignment PIN_AT39 -to PCIE_tx_p[2] set_location_assignment PIN_AU41 -to PCIE_tx_p[3] set_location_assignment PIN_AN41 -to PCIE_tx_p[4] set_location_assignment PIN_AL41 -to PCIE_tx_p[5] set_location_assignment PIN_AJ41 -to PCIE_tx_p[6] set_location_assignment PIN_AG41 -to PCIE_tx_p[7] set_location_assignment PIN_BD35 -to pcie_wake_n set_location_assignment PIN_AU29 -to qdriia_a[0] set_location_assignment PIN_BA28 -to qdriia_a[1] set_location_assignment PIN_AP27 -to qdriia_a[2] set_location_assignment PIN_AK27 -to qdriia_a[3] set_location_assignment PIN_AN27 -to qdriia_a[4] set_location_assignment PIN_AM28 -to qdriia_a[5] set_location_assignment PIN_AV28 -to qdriia_a[6] set_location_assignment PIN_AY27 -to qdriia_a[7] set_location_assignment PIN_BC29 -to qdriia_a[8] set_location_assignment PIN_AU28 -to qdriia_a[9] set_location_assignment PIN_AW27 -to qdriia_a[10] set_location_assignment PIN_AY28 -to qdriia_a[11] set_location_assignment PIN_BD28 -to qdriia_a[12] set_location_assignment PIN_AV29 -to qdriia_a[13] set_location_assignment PIN_AW29 -to qdriia_a[14] set_location_assignment PIN_BB29 -to qdriia_a[15] set_location_assignment PIN_BD29 -to qdriia_a[16] set_location_assignment PIN_AL27 -to qdriia_a[17] set_location_assignment PIN_AR27 -to qdriia_a[18] set_location_assignment PIN_AL28 -to qdriia_a[19] set_location_assignment PIN_AR28 -to qdriia_a[20] set_location_assignment PIN_AJ24 -to qdriia_bws_n[0] set_location_assignment PIN_AT27 -to qdriia_bws_n[1] set_location_assignment PIN_BA25 -to qdriia_cq_n set_location_assignment PIN_AH22 -to qdriia_cq_p set_location_assignment PIN_AH28 -to qdriia_d[0] set_location_assignment PIN_AH27 -to qdriia_d[1] set_location_assignment PIN_AH25 -to qdriia_d[2] set_location_assignment PIN_AJ28 -to qdriia_d[3] set_location_assignment PIN_AJ27 -to qdriia_d[4] set_location_assignment PIN_AJ26 -to qdriia_d[5] set_location_assignment PIN_AJ25 -to qdriia_d[6] set_location_assignment PIN_AL25 -to qdriia_d[7] set_location_assignment PIN_AH24 -to qdriia_d[8] set_location_assignment PIN_AN25 -to qdriia_d[9] set_location_assignment PIN_AM26 -to qdriia_d[10] set_location_assignment PIN_AM25 -to qdriia_d[11] set_location_assignment PIN_AL26 -to qdriia_d[12] set_location_assignment PIN_AK26 -to qdriia_d[13] set_location_assignment PIN_AU27 -to qdriia_d[14] set_location_assignment PIN_AU26 -to qdriia_d[15] set_location_assignment PIN_AV26 -to qdriia_d[16] set_location_assignment PIN_AW26 -to qdriia_d[17] set_location_assignment PIN_AR23 -to qdriia_doff_n set_location_assignment PIN_AR26 -to qdriia_k_n set_location_assignment PIN_AP25 -to qdriia_k_p set_location_assignment PIN_AN23 -to qdriia_odt set_location_assignment PIN_AK23 -to qdriia_q[0] set_location_assignment PIN_BB26 -to qdriia_q[1] set_location_assignment PIN_BD26 -to qdriia_q[2] set_location_assignment PIN_BA24 -to qdriia_q[3] set_location_assignment PIN_AL23 -to qdriia_q[4] set_location_assignment PIN_AJ23 -to qdriia_q[5] set_location_assignment PIN_AL21 -to qdriia_q[6] set_location_assignment PIN_AK21 -to qdriia_q[7] set_location_assignment PIN_AJ22 -to qdriia_q[8] set_location_assignment PIN_AW24 -to qdriia_q[9] set_location_assignment PIN_BC26 -to qdriia_q[10] set_location_assignment PIN_AY25 -to qdriia_q[11] set_location_assignment PIN_AU24 -to qdriia_q[12] set_location_assignment PIN_AV25 -to qdriia_q[13] set_location_assignment PIN_AU25 -to qdriia_q[14] set_location_assignment PIN_AR25 -to qdriia_q[15] set_location_assignment PIN_AP24 -to qdriia_q[16] set_location_assignment PIN_AL24 -to qdriia_q[17] set_location_assignment PIN_AM23 -to qdriia_qvld set_location_assignment PIN_AT26 -to qdriia_rps_n set_location_assignment PIN_AK24 -to qdriia_wps_n set_location_assignment PIN_AR24 -to qdriib_a[0] set_location_assignment PIN_BB23 -to qdriib_a[1] set_location_assignment PIN_AK20 -to qdriib_a[2] set_location_assignment PIN_AJ19 -to qdriib_a[3] set_location_assignment PIN_AL20 -to qdriib_a[4] set_location_assignment PIN_AG19 -to qdriib_a[5] set_location_assignment PIN_AT23 -to qdriib_a[6] set_location_assignment PIN_AU23 -to qdriib_a[7] set_location_assignment PIN_AV23 -to qdriib_a[8] set_location_assignment PIN_AM22 -to qdriib_a[9] set_location_assignment PIN_AJ20 -to qdriib_a[10] set_location_assignment PIN_AG20 -to qdriib_a[11] set_location_assignment PIN_AW23 -to qdriib_a[12] set_location_assignment PIN_BB24 -to qdriib_a[13] set_location_assignment PIN_AY24 -to qdriib_a[14] set_location_assignment PIN_BD23 -to qdriib_a[15] set_location_assignment PIN_BC23 -to qdriib_a[16] set_location_assignment PIN_AG21 -to qdriib_a[17] set_location_assignment PIN_AM20 -to qdriib_a[18] set_location_assignment PIN_AK18 -to qdriib_a[19] set_location_assignment PIN_AN22 -to qdriib_a[20] set_location_assignment PIN_AV20 -to qdriib_bws_n[0] set_location_assignment PIN_AU21 -to qdriib_bws_n[1] set_location_assignment PIN_AP18 -to qdriib_cq_n set_location_assignment PIN_AJ15 -to qdriib_cq_p set_location_assignment PIN_BB21 -to qdriib_d[0] set_location_assignment PIN_BD20 -to qdriib_d[1] set_location_assignment PIN_BC20 -to qdriib_d[2] set_location_assignment PIN_AR22 -to qdriib_d[3] set_location_assignment PIN_BB20 -to qdriib_d[4] set_location_assignment PIN_AU22 -to qdriib_d[5] set_location_assignment PIN_BA21 -to qdriib_d[6] set_location_assignment PIN_AY21 -to qdriib_d[7] set_location_assignment PIN_AW21 -to qdriib_d[8] set_location_assignment PIN_AT21 -to qdriib_d[9] set_location_assignment PIN_AR21 -to qdriib_d[10] set_location_assignment PIN_AP21 -to qdriib_d[11] set_location_assignment PIN_BD22 -to qdriib_d[12] set_location_assignment PIN_BC22 -to qdriib_d[13] set_location_assignment PIN_BA22 -to qdriib_d[14] set_location_assignment PIN_AV22 -to qdriib_d[15] set_location_assignment PIN_AY22 -to qdriib_d[16] set_location_assignment PIN_AW22 -to qdriib_d[17] set_location_assignment PIN_AH19 -to qdriib_doff_n set_location_assignment PIN_AT20 -to qdriib_k_n set_location_assignment PIN_AR20 -to qdriib_k_p set_location_assignment PIN_AH18 -to qdriib_odt set_location_assignment PIN_AR19 -to qdriib_q[0] set_location_assignment PIN_AM19 -to qdriib_q[1] set_location_assignment PIN_AL19 -to qdriib_q[2] set_location_assignment PIN_AM17 -to qdriib_q[3] set_location_assignment PIN_AL18 -to qdriib_q[4] set_location_assignment PIN_AN19 -to qdriib_q[5] set_location_assignment PIN_AU18 -to qdriib_q[6] set_location_assignment PIN_AK17 -to qdriib_q[7] set_location_assignment PIN_AL17 -to qdriib_q[8] set_location_assignment PIN_AG17 -to qdriib_q[9] set_location_assignment PIN_AJ18 -to qdriib_q[10] set_location_assignment PIN_AJ17 -to qdriib_q[11] set_location_assignment PIN_AG18 -to qdriib_q[12] set_location_assignment PIN_AU19 -to qdriib_q[13] set_location_assignment PIN_AW19 -to qdriib_q[14] set_location_assignment PIN_AV19 -to qdriib_q[15] set_location_assignment PIN_AP19 -to qdriib_q[16] set_location_assignment PIN_AN20 -to qdriib_q[17] set_location_assignment PIN_AJ16 -to qdriib_qvld set_location_assignment PIN_AW20 -to qdriib_rps_n set_location_assignment PIN_AU20 -to qdriib_wps_n set_location_assignment PIN_AV16 -to qdriic_a[0] set_location_assignment PIN_AW16 -to qdriic_a[1] set_location_assignment PIN_AP16 -to qdriic_a[2] set_location_assignment PIN_AW9 -to qdriic_a[3] set_location_assignment PIN_BD7 -to qdriic_a[4] set_location_assignment PIN_BC7 -to qdriic_a[5] set_location_assignment PIN_AR17 -to qdriic_a[6] set_location_assignment PIN_AR18 -to qdriic_a[7] set_location_assignment PIN_AT17 -to qdriic_a[8] set_location_assignment PIN_BB9 -to qdriic_a[9] set_location_assignment PIN_AH21 -to qdriic_a[10] set_location_assignment PIN_AU17 -to qdriic_a[11] set_location_assignment PIN_AU16 -to qdriic_a[12] set_location_assignment PIN_BB8 -to qdriic_a[13] set_location_assignment PIN_AT18 -to qdriic_a[14] set_location_assignment PIN_AW17 -to qdriic_a[15] set_location_assignment PIN_AV17 -to qdriic_a[16] set_location_assignment PIN_AU8 -to qdriic_a[17] set_location_assignment PIN_AT9 -to qdriic_a[18] set_location_assignment PIN_AV8 -to qdriic_a[19] set_location_assignment PIN_AN17 -to qdriic_a[20] set_location_assignment PIN_AJ11 -to qdriic_bws_n[0] set_location_assignment PIN_AJ10 -to qdriic_bws_n[1] set_location_assignment PIN_AF13 -to qdriic_cq_n set_location_assignment PIN_BC11 -to qdriic_cq_p set_location_assignment PIN_AG9 -to qdriic_d[0] set_location_assignment PIN_AG10 -to qdriic_d[1] set_location_assignment PIN_AG12 -to qdriic_d[2] set_location_assignment PIN_AG11 -to qdriic_d[3] set_location_assignment PIN_AV10 -to qdriic_d[4] set_location_assignment PIN_AH12 -to qdriic_d[5] set_location_assignment PIN_AK12 -to qdriic_d[6] set_location_assignment PIN_AL12 -to qdriic_d[7] set_location_assignment PIN_AJ12 -to qdriic_d[8] set_location_assignment PIN_AN12 -to qdriic_d[9] set_location_assignment PIN_AM13 -to qdriic_d[10] set_location_assignment PIN_AR12 -to qdriic_d[11] set_location_assignment PIN_AR13 -to qdriic_d[12] set_location_assignment PIN_AU9 -to qdriic_d[13] set_location_assignment PIN_AU10 -to qdriic_d[14] set_location_assignment PIN_AU11 -to qdriic_d[15] set_location_assignment PIN_AV11 -to qdriic_d[16] set_location_assignment PIN_AT12 -to qdriic_d[17] set_location_assignment PIN_AE14 -to qdriic_doff_n set_location_assignment PIN_AP13 -to qdriic_k_n set_location_assignment PIN_AP12 -to qdriic_k_p set_location_assignment PIN_BD10 -to qdriic_odt set_location_assignment PIN_BA12 -to qdriic_q[0] set_location_assignment PIN_AF14 -to qdriic_q[1] set_location_assignment PIN_AE13 -to qdriic_q[2] set_location_assignment PIN_AD14 -to qdriic_q[3] set_location_assignment PIN_AE12 -to qdriic_q[4] set_location_assignment PIN_AF11 -to qdriic_q[5] set_location_assignment PIN_AE11 -to qdriic_q[6] set_location_assignment PIN_AE10 -to qdriic_q[7] set_location_assignment PIN_AE9 -to qdriic_q[8] set_location_assignment PIN_BB11 -to qdriic_q[9] set_location_assignment PIN_AW11 -to qdriic_q[10] set_location_assignment PIN_AF10 -to qdriic_q[11] set_location_assignment PIN_AY12 -to qdriic_q[12] set_location_assignment PIN_AW10 -to qdriic_q[13] set_location_assignment PIN_AY10 -to qdriic_q[14] set_location_assignment PIN_BB12 -to qdriic_q[15] set_location_assignment PIN_BC10 -to qdriic_q[16] set_location_assignment PIN_BA10 -to qdriic_q[17] set_location_assignment PIN_BD11 -to qdriic_qvld set_location_assignment PIN_AH10 -to qdriic_rps_n set_location_assignment PIN_AL11 -to qdriic_wps_n set_location_assignment PIN_N26 -to qdriid_a[0] set_location_assignment PIN_P28 -to qdriid_a[1] set_location_assignment PIN_N28 -to qdriid_a[2] set_location_assignment PIN_L26 -to qdriid_a[3] set_location_assignment PIN_K27 -to qdriid_a[4] set_location_assignment PIN_L27 -to qdriid_a[5] set_location_assignment PIN_U26 -to qdriid_a[6] set_location_assignment PIN_T26 -to qdriid_a[7] set_location_assignment PIN_T27 -to qdriid_a[8] set_location_assignment PIN_V27 -to qdriid_a[9] set_location_assignment PIN_U27 -to qdriid_a[10] set_location_assignment PIN_R27 -to qdriid_a[11] set_location_assignment PIN_P27 -to qdriid_a[12] set_location_assignment PIN_V25 -to qdriid_a[13] set_location_assignment PIN_V26 -to qdriid_a[14] set_location_assignment PIN_T25 -to qdriid_a[15] set_location_assignment PIN_P26 -to qdriid_a[16] set_location_assignment PIN_M27 -to qdriid_a[17] set_location_assignment PIN_M28 -to qdriid_a[18] set_location_assignment PIN_P29 -to qdriid_a[19] set_location_assignment PIN_D29 -to qdriid_a[20] set_location_assignment PIN_E26 -to qdriid_bws_n[0] set_location_assignment PIN_K26 -to qdriid_bws_n[1] set_location_assignment PIN_H27 -to qdriid_cq_n set_location_assignment PIN_E29 -to qdriid_cq_p set_location_assignment PIN_H25 -to qdriid_d[0] set_location_assignment PIN_H24 -to qdriid_d[1] set_location_assignment PIN_H23 -to qdriid_d[2] set_location_assignment PIN_J25 -to qdriid_d[3] set_location_assignment PIN_J24 -to qdriid_d[4] set_location_assignment PIN_K25 -to qdriid_d[5] set_location_assignment PIN_D26 -to qdriid_d[6] set_location_assignment PIN_F25 -to qdriid_d[7] set_location_assignment PIN_G25 -to qdriid_d[8] set_location_assignment PIN_N23 -to qdriid_d[9] set_location_assignment PIN_P24 -to qdriid_d[10] set_location_assignment PIN_P23 -to qdriid_d[11] set_location_assignment PIN_L24 -to qdriid_d[12] set_location_assignment PIN_R24 -to qdriid_d[13] set_location_assignment PIN_U23 -to qdriid_d[14] set_location_assignment PIN_U24 -to qdriid_d[15] set_location_assignment PIN_T24 -to qdriid_d[16] set_location_assignment PIN_T23 -to qdriid_d[17] set_location_assignment PIN_E27 -to qdriid_doff_n set_location_assignment PIN_K24 -to qdriid_k_n set_location_assignment PIN_L23 -to qdriid_k_p set_location_assignment PIN_H26 -to qdriid_odt set_location_assignment PIN_C27 -to qdriid_q[0] set_location_assignment PIN_A26 -to qdriid_q[1] set_location_assignment PIN_B26 -to qdriid_q[2] set_location_assignment PIN_F26 -to qdriid_q[3] set_location_assignment PIN_G26 -to qdriid_q[4] set_location_assignment PIN_C28 -to qdriid_q[5] set_location_assignment PIN_A29 -to qdriid_q[6] set_location_assignment PIN_A28 -to qdriid_q[7] set_location_assignment PIN_B28 -to qdriid_q[8] set_location_assignment PIN_G28 -to qdriid_q[9] set_location_assignment PIN_F28 -to qdriid_q[10] set_location_assignment PIN_D27 -to qdriid_q[11] set_location_assignment PIN_G29 -to qdriid_q[12] set_location_assignment PIN_F29 -to qdriid_q[13] set_location_assignment PIN_H28 -to qdriid_q[14] set_location_assignment PIN_K28 -to qdriid_q[15] set_location_assignment PIN_J28 -to qdriid_q[16] set_location_assignment PIN_H29 -to qdriid_q[17] set_location_assignment PIN_J27 -to qdriid_qvld set_location_assignment PIN_F24 -to qdriid_rps_n set_location_assignment PIN_M23 -to qdriid_wps_n set_location_assignment PIN_AG14 -to rs422_de set_location_assignment PIN_AE18 -to rs422_din set_location_assignment PIN_AE17 -to rs422_dout set_location_assignment PIN_AF17 -to rs422_re_n set_location_assignment PIN_AF16 -to rs422_te set_location_assignment PIN_BA36 -to rzq_0 set_location_assignment PIN_AR8 -to rzq_1 set_location_assignment PIN_H9 -to rzq_4 set_location_assignment PIN_P35 -to rzq_5 set_location_assignment PIN_AH6 -to sfp1g_refclk_p set_location_assignment PIN_F22 -to sfpa_los set_location_assignment PIN_E21 -to sfpa_mod0_prsnt_n set_location_assignment PIN_B20 -to sfpa_mod1_scl set_location_assignment PIN_A20 -to sfpa_mod2_sda set_location_assignment PIN_E20 -to sfpa_ratesel[0] set_location_assignment PIN_G22 -to sfpa_ratesel[1] set_location_assignment PIN_AK2 -to sfpa_rx_p set_location_assignment PIN_B22 -to sfpa_txdisable set_location_assignment PIN_A22 -to sfpa_txfault set_location_assignment PIN_AG4 -to sfpa_tx_p set_location_assignment PIN_R22 -to sfpb_los set_location_assignment PIN_K22 -to sfpb_mod0_prsnt_n set_location_assignment PIN_K21 -to sfpb_mod1_scl set_location_assignment PIN_K20 -to sfpb_mod2_sda set_location_assignment PIN_R21 -to sfpb_ratesel[0] set_location_assignment PIN_T22 -to sfpb_ratesel[1] set_location_assignment PIN_AP2 -to sfpb_rx_p set_location_assignment PIN_H22 -to sfpb_txdisable set_location_assignment PIN_H20 -to sfpb_txfault set_location_assignment PIN_AL4 -to sfpb_tx_p set_location_assignment PIN_L21 -to sfpc_los set_location_assignment PIN_J21 -to sfpc_mod0_prsnt_n set_location_assignment PIN_H21 -to sfpc_mod1_scl set_location_assignment PIN_G20 -to sfpc_mod2_sda set_location_assignment PIN_J22 -to sfpc_ratesel[0] set_location_assignment PIN_P21 -to sfpc_ratesel[1] set_location_assignment PIN_AW4 -to sfpc_rx_p set_location_assignment PIN_F21 -to sfpc_txdisable set_location_assignment PIN_F20 -to sfpc_txfault set_location_assignment PIN_AT6 -to sfpc_tx_p set_location_assignment PIN_N22 -to sfpd_los set_location_assignment PIN_V20 -to sfpd_mod0_prsnt_n set_location_assignment PIN_U21 -to sfpd_mod1_scl set_location_assignment PIN_V19 -to sfpd_mod2_sda set_location_assignment PIN_V21 -to sfpd_ratesel[0] set_location_assignment PIN_M22 -to sfpd_ratesel[1] set_location_assignment PIN_BB2 -to sfpd_rx_p set_location_assignment PIN_U20 -to sfpd_txdisable set_location_assignment PIN_T21 -to SFPD_TXFAULT set_location_assignment PIN_AY6 -to SFPD_TX_p set_location_assignment PIN_BB33 -to sma_clkin set_location_assignment PIN_B25 -to sw[0] set_location_assignment PIN_A25 -to sw[1] set_location_assignment PIN_B23 -to sw[2] set_location_assignment PIN_A23 -to sw[3] set_location_assignment PIN_D21 -to temp_clk set_location_assignment PIN_D20 -to temp_data set_location_assignment PIN_C21 -to temp_int_n set_location_assignment PIN_C22 -to temp_overt_n set_location_assignment PIN_AV34 -to sma_clkout set_location_assignment PIN_V39 -to sata_device_refclk_p set_location_assignment PIN_V6 -to sata_host_refclk_p set_location_assignment PIN_V5 -to "sata_host_refclk_p(n)" set_location_assignment PIN_V40 -to "sata_device_refclk_p(n)" set_location_assignment PIN_K43 -to sata_device_rx_p[0] set_location_assignment PIN_H43 -to sata_device_rx_p[1] set_location_assignment PIN_K39 -to sata_device_tx_p[0] set_location_assignment PIN_H39 -to sata_device_tx_p[1] set_location_assignment PIN_K44 -to "sata_device_rx_p[0](n)" set_location_assignment PIN_H44 -to "sata_device_rx_p[1](n)" set_location_assignment PIN_K40 -to "sata_device_tx_p[0](n)" set_location_assignment PIN_H40 -to "sata_device_tx_p[1](n)" set_location_assignment PIN_K2 -to sata_host_rx_p[0] set_location_assignment PIN_K1 -to "sata_host_rx_p[0](n)" set_location_assignment PIN_H2 -to sata_host_rx_p[1] set_location_assignment PIN_H1 -to "sata_host_rx_p[1](n)" set_location_assignment PIN_K6 -to sata_host_tx_p[0] set_location_assignment PIN_K5 -to "sata_host_tx_p[0](n)" set_location_assignment PIN_H6 -to sata_host_tx_p[1] set_location_assignment PIN_H5 -to "sata_host_tx_p[1](n)" set_location_assignment PIN_AK7 -to sfp_refclk_p #============================================================ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" set_location_assignment PIN_PIN -to NETName set_location_assignment PIN_AK39 -to "pcie_refclk_p(n)" set_instance_assignment -name IO_STANDARD HCSL -to "pcie_refclk_p(n)" set_location_assignment PIN_BB44 -to "PCIE_rx_p[0](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[0](n)" set_location_assignment PIN_BA42 -to "PCIE_rx_p[1](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[1](n)" set_location_assignment PIN_AW42 -to "PCIE_rx_p[2](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[2](n)" set_location_assignment PIN_AY44 -to "PCIE_rx_p[3](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[3](n)" set_location_assignment PIN_AT44 -to "PCIE_rx_p[4](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[4](n)" set_location_assignment PIN_AP44 -to "PCIE_rx_p[5](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[5](n)" set_location_assignment PIN_AM44 -to "PCIE_rx_p[6](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[6](n)" set_location_assignment PIN_AK44 -to "PCIE_rx_p[7](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_rx_p[7](n)" set_location_assignment PIN_AY40 -to "PCIE_tx_p[0](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[0](n)" set_location_assignment PIN_AV40 -to "PCIE_tx_p[1](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[1](n)" set_location_assignment PIN_AT40 -to "PCIE_tx_p[2](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[2](n)" set_location_assignment PIN_AU42 -to "PCIE_tx_p[3](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[3](n)" set_location_assignment PIN_AN42 -to "PCIE_tx_p[4](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[4](n)" set_location_assignment PIN_AL42 -to "PCIE_tx_p[5](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[5](n)" set_location_assignment PIN_AJ42 -to "PCIE_tx_p[6](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[6](n)" set_location_assignment PIN_AG42 -to "PCIE_tx_p[7](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "PCIE_tx_p[7](n)" set_instance_assignment -name IO_STANDARD HCSL -to "sata_device_refclk_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_device_rx_p[0](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_device_rx_p[1](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_device_tx_p[0](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_device_tx_p[1](n)" set_instance_assignment -name IO_STANDARD HCSL -to "sata_host_refclk_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_host_rx_p[0](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_host_rx_p[1](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_host_tx_p[0](n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sata_host_tx_p[1](n)" set_location_assignment PIN_AH5 -to "sfp1g_refclk_p(n)" set_instance_assignment -name IO_STANDARD HCSL -to "sfp1g_refclk_p(n)" set_location_assignment PIN_AK1 -to "sfpa_rx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpa_rx_p(n)" set_location_assignment PIN_AG3 -to "sfpa_tx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpa_tx_p(n)" set_location_assignment PIN_AP1 -to "sfpb_rx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpb_rx_p(n)" set_location_assignment PIN_AL3 -to "sfpb_tx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpb_tx_p(n)" set_location_assignment PIN_AW3 -to "sfpc_rx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpc_rx_p(n)" set_location_assignment PIN_AT5 -to "sfpc_tx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpc_tx_p(n)" set_location_assignment PIN_BB1 -to "sfpd_rx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpd_rx_p(n)" set_location_assignment PIN_AY5 -to "sfpd_tx_p(n)" set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to "sfpd_tx_p(n)" set_location_assignment PIN_AK7 -to sfp_refclk_p set_instance_assignment -name IO_STANDARD HCSL -to sfp_refclk_p set_location_assignment PIN_AK6 -to "sfp_refclk_p(n)" set_instance_assignment -name IO_STANDARD HCSL -to "sfp_refclk_p(n)" set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top ================================================ FILE: constraints/altera/de5.sdc ================================================ #************************************************************** # Create Clock #************************************************************** create_clock -period 10 [get_ports pcie_refclk_p] create_clock -period 1.552 [get_ports sfp_refclk] create_clock -period 20 [get_ports osc_50_b3b] create_clock -period 20 [get_ports osc_50_b3d] create_clock -period 20 [get_ports osc_50_b4d] create_clock -period 20 [get_ports osc_50_b4a] create_clock -period 20 [get_ports osc_50_b7a] create_clock -period 20 [get_ports osc_50_b7d] create_clock -period 20 [get_ports osc_50_b8d] create_clock -period 20 [get_ports osc_50_b8a] set_clock_groups -exclusive -group [get_clocks { *central_clk_div0* }] -group [get_clocks { *_hssi_pcie_hip* }] set_clock_groups -exclusive -group [get_clocks { refclk*clkout }] -group [get_clocks { *div0*coreclkout }] #************************************************************** # Create Generated Clock #************************************************************** derive_pll_clocks #************************************************************** # Set Clock Latency #************************************************************** #************************************************************** # Set Clock Uncertainty #************************************************************** derive_clock_uncertainty #************************************************************** # Set Input Delay #************************************************************** #************************************************************** # Set Output Delay #************************************************************** #************************************************************** # Set Clock Groups #************************************************************** #************************************************************** # Set False Path #************************************************************** #************************************************************** # Set Multicycle Path #************************************************************** #************************************************************** # Set Maximum Delay #************************************************************** #************************************************************** # Set Minimum Delay #************************************************************** #************************************************************** # Set Input Transition #************************************************************** #************************************************************** # Set Load #************************************************************** #Constraining JTAG interface #TCK port create_clock -name altera_reserved_tck -period 100 [get_ports altera_reserved_tck] #cut all paths to and from tck set_clock_groups -exclusive -group [get_clocks altera_reserved_tck] #constrain the TDI port set_input_delay -clock altera_reserved_tck 20 [get_ports altera_reserved_tdi] #constrain the TMS port set_input_delay -clock altera_reserved_tck 20 [get_ports altera_reserved_tms] #constrain the TDO port set_output_delay -clock altera_reserved_tck 20 [get_ports altera_reserved_tdo] ================================================ FILE: constraints/altera/htg4.qsf ================================================ set_instance_assignment -name IO_STANDARD "DIFFERENTIAL LVPECL" -to refclk set_instance_assignment -name IO_STANDARD "2.5 V" -to local_rstn_ext set_instance_assignment -name IO_STANDARD "2.5 V" -to pcie_rstn set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in0 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in1 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in2 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in3 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in4 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in5 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in6 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_in7 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out0 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out1 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out2 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out3 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out4 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out5 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out6 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_out7 set_instance_assignment -name IO_STANDARD "2.5 V" -to lane_active_led[0] set_instance_assignment -name IO_STANDARD "2.5 V" -to lane_active_led[1] set_instance_assignment -name IO_STANDARD "2.5 V" -to lane_active_led[2] set_instance_assignment -name IO_STANDARD "2.5 V" -to lane_active_led[3] set_instance_assignment -name IO_STANDARD "2.5 V" -to L0_led set_instance_assignment -name IO_STANDARD "2.5 V" -to alive_led set_instance_assignment -name IO_STANDARD "2.5 V" -to comp_led set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_serial_data_1 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to tx_serial_data_0 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_serial_data_1 set_instance_assignment -name IO_STANDARD "1.4-V PCML" -to rx_serial_data_0 set_instance_assignment -name GLOBAL_SIGNAL "GLOBAL CLOCK" -to core_clk_out set_instance_assignment -name IO_STANDARD "DIFFERENTIAL LVPECL" -to clk_644MHz set_instance_assignment -name IO_STANDARD LVDS -to clk_200MHz set_location_assignment PIN_G33 -to local_rstn_ext set_location_assignment PIN_AG24 -to pcie_rstn set_location_assignment PIN_AA38 -to refclk set_location_assignment PIN_AU38 -to rx_in0 set_location_assignment PIN_AR38 -to rx_in1 set_location_assignment PIN_AJ38 -to rx_in2 set_location_assignment PIN_AG38 -to rx_in3 set_location_assignment PIN_AE38 -to rx_in4 set_location_assignment PIN_AC38 -to rx_in5 set_location_assignment PIN_U38 -to rx_in6 set_location_assignment PIN_R38 -to rx_in7 set_location_assignment PIN_AT36 -to tx_out0 set_location_assignment PIN_AP36 -to tx_out1 set_location_assignment PIN_AH36 -to tx_out2 set_location_assignment PIN_AF36 -to tx_out3 set_location_assignment PIN_AD36 -to tx_out4 set_location_assignment PIN_AB36 -to tx_out5 set_location_assignment PIN_T36 -to tx_out6 set_location_assignment PIN_P36 -to tx_out7 set_location_assignment PIN_E34 -to gen2_led set_location_assignment PIN_N28 -to L0_led set_location_assignment PIN_F34 -to alive_led set_location_assignment PIN_R27 -to comp_led set_location_assignment PIN_D33 -to lane_active_led[0] set_location_assignment PIN_M28 -to lane_active_led[2] set_location_assignment PIN_D34 -to lane_active_led[3] set_location_assignment PIN_C34 -to lane_active_led[1] set_location_assignment PIN_A19 -to free_100MHz set_instance_assignment -name VIRTUAL_PIN ON -to app_int_sts set_instance_assignment -name VIRTUAL_PIN ON -to app_msi_num set_instance_assignment -name VIRTUAL_PIN ON -to app_msi_req set_instance_assignment -name VIRTUAL_PIN ON -to app_msi_tc set_instance_assignment -name VIRTUAL_PIN ON -to busy_altgxb_reconfig set_instance_assignment -name VIRTUAL_PIN ON -to cal_blk_clk set_instance_assignment -name VIRTUAL_PIN ON -to cpl_err set_instance_assignment -name VIRTUAL_PIN ON -to cpl_pending set_instance_assignment -name VIRTUAL_PIN ON -to crst set_instance_assignment -name VIRTUAL_PIN ON -to fixedclk_serdes set_instance_assignment -name VIRTUAL_PIN ON -to gxb_powerdown set_instance_assignment -name VIRTUAL_PIN ON -to hpg_ctrler set_instance_assignment -name VIRTUAL_PIN ON -to lmi_addr set_instance_assignment -name VIRTUAL_PIN ON -to lmi_din set_instance_assignment -name VIRTUAL_PIN ON -to lmi_rden set_instance_assignment -name VIRTUAL_PIN ON -to lmi_wren set_instance_assignment -name VIRTUAL_PIN ON -to pclk_in set_instance_assignment -name VIRTUAL_PIN ON -to pex_msi_num set_instance_assignment -name VIRTUAL_PIN ON -to phystatus_ext set_instance_assignment -name VIRTUAL_PIN ON -to pld_clk set_instance_assignment -name VIRTUAL_PIN ON -to pll_powerdown set_instance_assignment -name VIRTUAL_PIN ON -to pm_auxpwr set_instance_assignment -name VIRTUAL_PIN ON -to pm_data set_instance_assignment -name VIRTUAL_PIN ON -to pm_event set_instance_assignment -name VIRTUAL_PIN ON -to pme_to_cr set_instance_assignment -name VIRTUAL_PIN ON -to reconfig_clk set_instance_assignment -name VIRTUAL_PIN ON -to reconfig_togxb set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_mask0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_ready0 set_instance_assignment -name VIRTUAL_PIN ON -to rxdata0_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata1_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata2_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata3_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata4_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata5_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata6_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdata7_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak0_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak1_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak2_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak3_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak4_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak5_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak6_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxdatak7_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle0_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle1_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle2_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle3_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle4_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle5_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle6_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxelecidle7_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus0_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus1_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus2_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus3_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus4_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus5_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus6_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxstatus7_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid0_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid1_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid2_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid3_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid4_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid5_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid6_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxvalid7_ext set_instance_assignment -name VIRTUAL_PIN ON -to srst set_instance_assignment -name VIRTUAL_PIN ON -to test_in set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_data0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_empty0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_eop0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_err0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_sop0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_valid0 set_instance_assignment -name VIRTUAL_PIN ON -to app_int_ack set_instance_assignment -name VIRTUAL_PIN ON -to app_msi_ack set_instance_assignment -name VIRTUAL_PIN ON -to clk250_out set_instance_assignment -name VIRTUAL_PIN ON -to clk500_out set_instance_assignment -name VIRTUAL_PIN ON -to derr_cor_ext_rcv0 set_instance_assignment -name VIRTUAL_PIN ON -to derr_cor_ext_rpl set_instance_assignment -name VIRTUAL_PIN ON -to derr_rpl set_instance_assignment -name VIRTUAL_PIN ON -to dlup_exit set_instance_assignment -name VIRTUAL_PIN ON -to hotrst_exit set_instance_assignment -name VIRTUAL_PIN ON -to ko_cpl_spc_vc0 set_instance_assignment -name VIRTUAL_PIN ON -to l2_exit set_instance_assignment -name VIRTUAL_PIN ON -to lane_act set_instance_assignment -name VIRTUAL_PIN ON -to lmi_ack set_instance_assignment -name VIRTUAL_PIN ON -to lmi_dout set_instance_assignment -name VIRTUAL_PIN ON -to ltssm set_instance_assignment -name VIRTUAL_PIN ON -to npd_alloc_1cred_vc0 set_instance_assignment -name VIRTUAL_PIN ON -to npd_cred_vio_vc0 set_instance_assignment -name VIRTUAL_PIN ON -to nph_alloc_1cred_vc0 set_instance_assignment -name VIRTUAL_PIN ON -to nph_cred_vio_vc0 set_instance_assignment -name VIRTUAL_PIN ON -to pme_to_sr set_instance_assignment -name VIRTUAL_PIN ON -to powerdown_ext set_instance_assignment -name VIRTUAL_PIN ON -to r2c_err0 set_instance_assignment -name VIRTUAL_PIN ON -to rate_ext set_instance_assignment -name VIRTUAL_PIN ON -to rc_pll_locked set_instance_assignment -name VIRTUAL_PIN ON -to rc_rx_digitalreset set_instance_assignment -name VIRTUAL_PIN ON -to reconfig_fromgxb set_instance_assignment -name VIRTUAL_PIN ON -to reset_status set_instance_assignment -name VIRTUAL_PIN ON -to rx_fifo_empty0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_fifo_full0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_bardec0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_be0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_data0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_empty0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_eop0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_err0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_sop0 set_instance_assignment -name VIRTUAL_PIN ON -to rx_st_valid0 set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity0_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity1_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity2_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity3_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity4_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity5_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity6_ext set_instance_assignment -name VIRTUAL_PIN ON -to rxpolarity7_ext set_instance_assignment -name VIRTUAL_PIN ON -to suc_spd_neg set_instance_assignment -name VIRTUAL_PIN ON -to test_out set_instance_assignment -name VIRTUAL_PIN ON -to tl_cfg_add set_instance_assignment -name VIRTUAL_PIN ON -to tl_cfg_ctl set_instance_assignment -name VIRTUAL_PIN ON -to tl_cfg_ctl_wr set_instance_assignment -name VIRTUAL_PIN ON -to tl_cfg_sts set_instance_assignment -name VIRTUAL_PIN ON -to tl_cfg_sts_wr set_instance_assignment -name VIRTUAL_PIN ON -to tx_cred0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_fifo_empty0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_fifo_full0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_fifo_rdptr0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_fifo_wrptr0 set_instance_assignment -name VIRTUAL_PIN ON -to tx_st_ready0 set_instance_assignment -name VIRTUAL_PIN ON -to txcompl0_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl1_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl2_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl3_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl4_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl5_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl6_ext set_instance_assignment -name VIRTUAL_PIN ON -to txcompl7_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata0_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata1_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata2_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata3_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata4_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata5_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata6_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdata7_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak0_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak1_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak2_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak3_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak4_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak5_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak6_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdatak7_ext set_instance_assignment -name VIRTUAL_PIN ON -to txdetectrx_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle0_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle1_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle2_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle3_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle4_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle5_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle6_ext set_instance_assignment -name VIRTUAL_PIN ON -to txelecidle7_ext set_instance_assignment -name INPUT_TERMINATION OFF -to refclk set_location_assignment PIN_K34 -to clk_200MHz set_location_assignment PIN_AK25 -to mdc_from_the_mdio set_location_assignment PIN_AM26 -to mdio_in_out_from_the_mdio set_location_assignment PIN_AN26 -to lane2_prwdn set_location_assignment PIN_AP27 -to lane1_prwdn set_location_assignment PIN_AT27 -to sfp1_mod set_location_assignment PIN_AU27 -to sfp1_rate_sel set_location_assignment PIN_AW30 -to sfp1_tx_disable set_location_assignment PIN_AW32 -to sfp2_mod set_location_assignment PIN_AW33 -to sfp2_rate_sel set_location_assignment PIN_AW28 -to sfp2_tx_disable set_location_assignment PIN_AW31 -to sfp2_tx_fault set_location_assignment PIN_AW27 -to sfp1_tx_fault set_location_assignment PIN_AK26 -to phy_reset_n set_location_assignment PIN_K4 -to tx_serial_data_1 set_location_assignment PIN_L2 -to rx_serial_data_1 set_location_assignment PIN_M4 -to tx_serial_data_0 set_location_assignment PIN_N2 -to rx_serial_data_0 set_location_assignment PIN_J2 -to clk_644MHz set_location_assignment PIN_N30 -to usr_sw[7] set_location_assignment PIN_N29 -to usr_sw[6] set_location_assignment PIN_M31 -to usr_sw[5] set_location_assignment PIN_L31 -to usr_sw[4] set_location_assignment PIN_K32 -to usr_sw[3] set_location_assignment PIN_J33 -to usr_sw[2] set_location_assignment PIN_H34 -to usr_sw[1] set_location_assignment PIN_T27 -to usr_sw[0] set_location_assignment PIN_V29 -to req_compliance_push_button_n set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top ================================================ FILE: constraints/altera/htg4.sdc ================================================ #************************************************************** # Create Clock #************************************************************** #create_clock -period 10 [get_ports pcie_refclk_p] #create_clock -period 10 [get_ports sfp_refclk] #create_clock -period 20 [get_ports osc_50_b3b] #create_clock -period 20 [get_ports osc_50_b3d] #create_clock -period 20 [get_ports osc_50_b4d] #create_clock -period 20 [get_ports osc_50_b4a] #create_clock -period 20 [get_ports osc_50_b7a] #create_clock -period 20 [get_ports osc_50_b7d] #create_clock -period 20 [get_ports osc_50_b8d] #create_clock -period 20 [get_ports osc_50_b8a] # set_clock_groups -exclusive -group [get_clocks { *central_clk_div0* }] -group [get_clocks { *_hssi_pcie_hip* }] set_clock_groups -exclusive -group [get_clocks { refclk*clkout }] -group [get_clocks { *div0*coreclkout }] #************************************************************** # Create Generated Clock #************************************************************** derive_pll_clocks #************************************************************** # Set Clock Latency #************************************************************** #************************************************************** # Set Clock Uncertainty #************************************************************** derive_clock_uncertainty #************************************************************** # Set Input Delay #************************************************************** #************************************************************** # Set Output Delay #************************************************************** #************************************************************** # Set Clock Groups #************************************************************** #************************************************************** # Set False Path #************************************************************** #************************************************************** # Set Multicycle Path #************************************************************** #************************************************************** # Set Maximum Delay #************************************************************** #************************************************************** # Set Minimum Delay #************************************************************** #************************************************************** # Set Input Transition #************************************************************** #************************************************************** # Set Load #************************************************************** ================================================ FILE: constraints/xilinx/Readme.md ================================================ Procedure for creating part constraint files Start Vivado Create new project In New Vivado Project window click Next In Project Name window click next (but note the name, or change it) In Project Type window select RTL Project click next In Add Sources select Target language Verilog click next In Add Existing IP click next In Add Constraints click next In Default Part If the board type is known to Vivado, select board and choose the right board otherwise Specify Parts Search for desired part click next In New Project Summary click finish In Flow Navigator, Create Block Design In Block Design Add IP search for Processing System, add that Click Run Block Automation, to make DDR and Fixed_IO connections Add IP search for GPIO, add that Run connection automation use drop down box to select GPIO AXI This will add the reset logic and other basic stuff Ctrl-S or Save Block Design In Hierarch winddow, select Sources tab Right click Design top level Select Generate HDL wrapper In Flow navigator Run Synthesis (The file you need should be there now) Run Implementation Run Generate Bitstream Exit Vivado Go to project directory tree Search for xdc files: find .|grep .xdc There should be one named something like In part area, search for and select desired part ./project_6.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_0/design_1_processing_system7_0_0.xdc Copy this file to .../connectal/constraints/xilinx/.xdc Check this file into git, then edit it to add a comment about where it came from and to comment out the create_clock and set_jitter lines near the top ================================================ FILE: constraints/xilinx/ac701.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: artix7 ## FPGA: xc7a200tfbg676 ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC M26 [get_ports {GPIO_leds[0]}] set_property LOC T24 [get_ports {GPIO_leds[1]}] set_property LOC T25 [get_ports {GPIO_leds[2]}] set_property LOC R26 [get_ports {GPIO_leds[3]}] set_property LOC U4 [get_ports {RST_cpu_reset}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_leds[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_leds[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_leds[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_leds[3]}] set_property IOSTANDARD LVCMOS15 [get_ports {RST_cpu_reset}] set_property SLEW SLOW [get_ports GPIO_leds] set_property DRIVE 12 [get_ports GPIO_leds] set_property LOC F11 [get_ports { CLK_pci_sys_clk_p }] set_property LOC E11 [get_ports { CLK_pci_sys_clk_n }] set_property LOC M20 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC R3 [get_ports { CLK_sys_clk_p }] set_property LOC P3 [get_ports { CLK_sys_clk_n }] # set_property LOC M21 [get_ports { CLK_user_clk_p }] # set_property LOC M22 [get_ports { CLK_user_clk_n }] set_property LOC D12 [get_ports { PCIE_rxp_i[0] }] set_property LOC B13 [get_ports { PCIE_rxp_i[1] }] set_property LOC D14 [get_ports { PCIE_rxp_i[2] }] set_property LOC B11 [get_ports { PCIE_rxp_i[3] }] set_property LOC C12 [get_ports { PCIE_rxn_i[0] }] set_property LOC A13 [get_ports { PCIE_rxn_i[1] }] set_property LOC C14 [get_ports { PCIE_rxn_i[2] }] set_property LOC A11 [get_ports { PCIE_rxn_i[3] }] set_property LOC D10 [get_ports { PCIE_txp[0] }] set_property LOC B9 [get_ports { PCIE_txp[1] }] set_property LOC D8 [get_ports { PCIE_txp[2] }] set_property LOC B7 [get_ports { PCIE_txp[3] }] set_property LOC C10 [get_ports { PCIE_txn[0] }] set_property LOC A9 [get_ports { PCIE_txn[1] }] set_property LOC C8 [get_ports { PCIE_txn[2] }] set_property LOC A7 [get_ports { PCIE_txn[3] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD LVCMOS33 [get_ports { GPIO_leds[*] }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] # set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_user_clk_* }] set_property IOSTANDARD LVCMOS33 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # set_property LOC IBUFDS_GTE2_X0Y2 [get_cells { *pci_clk_100mhz_buf }] #set_property LOC MMCME2_ADV_X1Y1 [get_cells -hier -filter { NAME =~ *clk_gen_pll }] # # PCI Express Block placement. This constraint selects the PCI Express # Block to be used. # set_property LOC PCIE_X0Y0 [get_cells -hierarchical -regexp {.*pcie_7x_i/pcie_block_i}] set_property LOC MMCME2_ADV_X0Y4 [get_cells *clkgen_pll] set_property LOC MMCME2_ADV_X0Y3 [get_cells *_ep/ext_clk.pipe_clock_i/mmcm_i] # # BlockRAM placement # set_property LOC RAMB36_X1Y46 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[3].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y45 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[2].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y44 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[1].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y43 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[0].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y42 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[0].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y41 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[1].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y40 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[2].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ set_property LOC RAMB36_X1Y39 [get_cells {*\/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[3].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] */ ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/awsf1.xdc ================================================ # TBD ================================================ FILE: constraints/xilinx/bluesim.xdc ================================================ this file intentionally left blank ================================================ FILE: constraints/xilinx/bluesim_pcie.xdc ================================================ this file intentionally left blank ================================================ FILE: constraints/xilinx/cdc.tcl ================================================ ## ## set properties to help out clock domain crossing analysis ## # set ASYNC_REG property on SyncReset and SyncFifo variants foreach pat {"reset_hold_reg[*]" "sGEnqPtr*_reg[*]" "dGDeqPtr*_reg[*]" "sSyncReg*_reg[*]" "dSyncReg*_reg[*]"} { set cells [get_cells -hier $pat] if {[llength $cells] > 0} { puts "ASYNC_REG $cells" set_property ASYNC_REG 1 $cells } } ================================================ FILE: constraints/xilinx/kc160g2.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: kintex7 ## FPGA: xc7k325t-2ffg900 ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_pci_sys_clk_* }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] #set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_user_clk_* }] set_property IOSTANDARD LVCMOS25 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # ##set_property LOC IBUFDS_GTE2_X0Y1 [get_cells { *pci_clk_100mhz_buf }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/kc705-3.0.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: kintex7 ## FPGA: xc7k325t-2ffg900 ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AB8 [get_ports { GPIO_leds[0] }] set_property LOC AA8 [get_ports { GPIO_leds[1] }] set_property LOC AC9 [get_ports { GPIO_leds[2] }] set_property LOC AB9 [get_ports { GPIO_leds[3] }] set_property LOC AE26 [get_ports { GPIO_leds[4] }] set_property LOC G19 [get_ports { GPIO_leds[5] }] set_property LOC E18 [get_ports { GPIO_leds[6] }] set_property LOC F16 [get_ports { GPIO_leds[7] }] # set_property LOC Y28 [get_ports { DIP_3_gpio }] # set_property LOC AA28 [get_ports { DIP_2_gpio }] # set_property LOC W29 [get_ports { DIP_1_gpio }] # set_property LOC Y29 [get_ports { DIP_0_gpio }] #set_property LOC G12 [get_ports { BUTTON_0_gpio }] #set_property LOC AC6 [get_ports { BUTTON_1_gpio }] #set_property LOC AB12 [get_ports { BUTTON_2_gpio }] #set_property LOC AG5 [get_ports { BUTTON_3_gpio }] #set_property LOC AA12 [get_ports { BUTTON_4_gpio }] # set_property LOC AA21 [get_ports { BUTTON_0_gpio }] # set_property LOC AB22 [get_ports { BUTTON_1_gpio }] # set_property LOC AB23 [get_ports { BUTTON_2_gpio }] # set_property LOC AA22 [get_ports { BUTTON_3_gpio }] # set_property LOC AA23 [get_ports { BUTTON_4_gpio }] # set_property LOC Y10 [get_ports { LCD_db[3] }] # set_property LOC AA11 [get_ports { LCD_db[2] }] # set_property LOC AA10 [get_ports { LCD_db[1] }] # set_property LOC AA13 [get_ports { LCD_db[0] }] # set_property LOC AB10 [get_ports { LCD_e }] # set_property LOC Y11 [get_ports { LCD_rs }] # set_property LOC AB13 [get_ports { LCD_rw }] set_property LOC U8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC U7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC G25 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC AD12 [get_ports { CLK_sys_clk_p }] set_property LOC AD11 [get_ports { CLK_sys_clk_n }] set_property LOC K28 [get_ports { CLK_user_clk_p }] set_property LOC K29 [get_ports { CLK_user_clk_n }] set_property LOC M6 [get_ports { PCIE_rxp_i[0] }] set_property LOC P6 [get_ports { PCIE_rxp_i[1] }] set_property LOC R4 [get_ports { PCIE_rxp_i[2] }] set_property LOC T6 [get_ports { PCIE_rxp_i[3] }] set_property LOC V6 [get_ports { PCIE_rxp_i[4] }] set_property LOC W4 [get_ports { PCIE_rxp_i[5] }] set_property LOC Y6 [get_ports { PCIE_rxp_i[6] }] set_property LOC AA4 [get_ports { PCIE_rxp_i[7] }] set_property LOC M5 [get_ports { PCIE_rxn_i[0] }] set_property LOC P5 [get_ports { PCIE_rxn_i[1] }] set_property LOC R3 [get_ports { PCIE_rxn_i[2] }] set_property LOC T5 [get_ports { PCIE_rxn_i[3] }] set_property LOC V5 [get_ports { PCIE_rxn_i[4] }] set_property LOC W3 [get_ports { PCIE_rxn_i[5] }] set_property LOC Y5 [get_ports { PCIE_rxn_i[6] }] set_property LOC AA3 [get_ports { PCIE_rxn_i[7] }] set_property LOC L4 [get_ports { PCIE_txp[0] }] set_property LOC M2 [get_ports { PCIE_txp[1] }] set_property LOC N4 [get_ports { PCIE_txp[2] }] set_property LOC P2 [get_ports { PCIE_txp[3] }] set_property LOC T2 [get_ports { PCIE_txp[4] }] set_property LOC U4 [get_ports { PCIE_txp[5] }] set_property LOC V2 [get_ports { PCIE_txp[6] }] set_property LOC Y2 [get_ports { PCIE_txp[7] }] set_property LOC L3 [get_ports { PCIE_txn[0] }] set_property LOC M1 [get_ports { PCIE_txn[1] }] set_property LOC N3 [get_ports { PCIE_txn[2] }] set_property LOC P1 [get_ports { PCIE_txn[3] }] set_property LOC T1 [get_ports { PCIE_txn[4] }] set_property LOC U3 [get_ports { PCIE_txn[5] }] set_property LOC V1 [get_ports { PCIE_txn[6] }] set_property LOC Y1 [get_ports { PCIE_txn[7] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD LVCMOS15 [get_ports { GPIO_leds[*] }] # set_property IOSTANDARD LVCMOS15 [get_ports { DIP_*_gpio }] # set_property IOSTANDARD LVCMOS25 [get_ports { BUTTON_*_gpio }] # set_property IOSTANDARD LVCMOS15 [get_ports { LCD_* }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_user_clk_* }] set_property IOSTANDARD LVCMOS25 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # set_property LOC IBUFDS_GTE2_X0Y1 [get_cells { *pci_clk_100mhz_buf }] set_property LOC MMCME2_ADV_X1Y1 [get_cells -hier -filter { NAME =~ *clk_gen_pll }] # # Transceiver instance placement. This constraint selects the # transceivers to be used, which also dictates the pinout for the # transmit and receive differential pairs. Please refer to the # Virtex-7 GT Transceiver User Guide (UG) for more information. # # PCIe Lane 0 set_property LOC GTXE2_CHANNEL_X0Y7 [get_cells -hierarchical -regexp {.*pipe_lane\[0\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 1 set_property LOC GTXE2_CHANNEL_X0Y6 [get_cells -hierarchical -regexp {.*pipe_lane\[1\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 2 set_property LOC GTXE2_CHANNEL_X0Y5 [get_cells -hierarchical -regexp {.*pipe_lane\[2\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 3 set_property LOC GTXE2_CHANNEL_X0Y4 [get_cells -hierarchical -regexp {.*pipe_lane\[3\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 4 set_property LOC GTXE2_CHANNEL_X0Y3 [get_cells -hierarchical -regexp {.*pipe_lane\[4\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 5 set_property LOC GTXE2_CHANNEL_X0Y2 [get_cells -hierarchical -regexp {.*pipe_lane\[5\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 6 set_property LOC GTXE2_CHANNEL_X0Y1 [get_cells -hierarchical -regexp {.*pipe_lane\[6\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # PCIe Lane 7 set_property LOC GTXE2_CHANNEL_X0Y0 [get_cells -hierarchical -regexp {.*pipe_lane\[7\].gt_wrapper_i/gtx_channel.gtxe2_channel_i}] # # PCI Express Block placement. This constraint selects the PCI Express # Block to be used. # set_property LOC PCIE_X0Y0 [get_cells -hierarchical -regexp {.*pcie_7x_i/pcie_block_i}] # # BlockRAM placement # set_property LOC RAMB36_X4Y35 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[3].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y34 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[2].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y33 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[1].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y32 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[0].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y31 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[0].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y30 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[1].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y29 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[2].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] set_property LOC RAMB36_X4Y28 [get_cells {*/pcie_7x_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[3].ram/use_tdp.ramb36/genblk*.bram36_tdp_bl.bram36_tdp_bl}] ###################################################################################################### # AREA GROUPS ###################################################################################################### ## startgroup ## create_pblock pblock_pcie0 ## resize_pblock pblock_pcie0 -add {SLICE_X70Y139:SLICE_X147Y299 DSP48_X3Y56:DSP48_X5Y119 RAMB18_X3Y56:RAMB18_X6Y119 RAMB36_X3Y28:RAMB36_X6Y59} ## add_cells_to_pblock pblock_pcie0 [get_cells [list *_pcie_*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *_outFifo*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *_inFifo*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *_fifoTxData_*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *_fifoRxData_*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *\/pbb*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *fS1OutPort*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *fS1MsgOut*]] ## add_cells_to_pblock pblock_pcie0 [get_cells [list *fS2MsgOut*]] ## endgroup ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### # # clocks create_clock -name bscan_refclk -period 20 [get_pins -hier -filter {NAME=~"*pcieBscanBram_bscan/TCK"}] create_clock -name pci_refclk -period 10 [get_pins *pci_clk_100mhz_buf/O] create_clock -name sys_clk -period 5 [get_pins *sys_clk_200mhz/O] create_clock -name pci_extclk -period 10 [get_pins *ep7/pcie_ep/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtxe2_channel_i/TXOUTCLK] # # False Paths # set_false_path -from [get_ports { RST_N_pci_sys_reset_n }] set_false_path -through [get_pins -hierarchical {*pcie_block_i/PLPHYLNKUPN*}] set_false_path -through [get_pins -hierarchical {*pcie_block_i/PLRECEIVEDHOTRST*}] #set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/user_resetdone*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[0].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[1].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[2].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[3].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[4].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[5].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[6].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_nets {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[7].pipe_rate.pipe_rate_i/*}] set_false_path -through [get_cells {*/pcie_7x_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_reset.pipe_reset_i/cpllreset_reg*}] set_false_path -through [get_nets {*/ext_clk.pipe_clock_i/pclk_sel*}] set_case_analysis 1 [get_pins {*/ext_clk.pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/S0}] set_case_analysis 0 [get_pins {*/ext_clk.pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/S1}] set_clock_groups -name ___clk_groups_generated_0_1_0_0_0 -physically_exclusive -group [get_clocks clk_125mhz] -group [get_clocks clk_250mhz] set_clock_groups -name async_sysclk_coreclk -asynchronous -group [get_clocks -include_generated_clocks sys_clk] -group [get_clocks -include_generated_clocks user_clk] -group [get_clocks -include_generated_clocks pci_refclk] set_max_delay -from [get_clocks noc_clk] -to [get_clocks clk_userclk2] 8.000 -datapath_only set_max_delay -from [get_clocks clk_userclk2] -to [get_clocks noc_clk] 8.000 -datapath_only set_max_delay -from [get_clocks cclock] -to [get_clocks core_clock] 20.000 -datapath_only set_max_delay -from [get_clocks uclock] -to [get_clocks core_clock] 20.000 -datapath_only set_max_delay -from [get_clocks core_clock] -to [get_clocks cclock] 20.000 -datapath_only set_max_delay -from [get_clocks core_clock] -to [get_clocks uclock] 20.000 -datapath_only ================================================ FILE: constraints/xilinx/kc705-ddr3.prj ================================================ ddr3 1 1 OFF 1024 ON Enabled xc7k325t-2ffg900/-2 2.0 No Buffer No Buffer ACTIVE LOW FALSE 0 50 Ohms 0 DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 1250 2.0V 4:1 800 0 1.000 1 1 1 1 64 1 1 Disabled Normal FALSE 14 10 3 1.5V BANK_ROW_COLUMN 8 - Fixed Sequential 11 Normal No Slow Exit Enable RZQ/7 Disable Enable RZQ/4 0 Disabled Enabled Output Buffer Enabled Full Array 8 Enabled Normal Dynamic ODT off NATIVE ================================================ FILE: constraints/xilinx/kc705.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: kintex7 ## FPGA: xc7k325t-2ffg900 ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC U8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC U7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC G25 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC AD12 [get_ports { CLK_sys_clk_p }] set_property LOC AD11 [get_ports { CLK_sys_clk_n }] #set_property LOC K28 [get_ports { CLK_user_clk_p }] #set_property LOC K29 [get_ports { CLK_user_clk_n }] set_property LOC G25 [get_ports { RST_cpu_reset }] set_property LOC M6 [get_ports { PCIE_rxp_v[0] }] set_property LOC P6 [get_ports { PCIE_rxp_v[1] }] set_property LOC R4 [get_ports { PCIE_rxp_v[2] }] set_property LOC T6 [get_ports { PCIE_rxp_v[3] }] set_property LOC V6 [get_ports { PCIE_rxp_v[4] }] set_property LOC W4 [get_ports { PCIE_rxp_v[5] }] set_property LOC Y6 [get_ports { PCIE_rxp_v[6] }] set_property LOC AA4 [get_ports { PCIE_rxp_v[7] }] set_property LOC M5 [get_ports { PCIE_rxn_v[0] }] set_property LOC P5 [get_ports { PCIE_rxn_v[1] }] set_property LOC R3 [get_ports { PCIE_rxn_v[2] }] set_property LOC T5 [get_ports { PCIE_rxn_v[3] }] set_property LOC V5 [get_ports { PCIE_rxn_v[4] }] set_property LOC W3 [get_ports { PCIE_rxn_v[5] }] set_property LOC Y5 [get_ports { PCIE_rxn_v[6] }] set_property LOC AA3 [get_ports { PCIE_rxn_v[7] }] set_property LOC L4 [get_ports { PCIE_txp[0] }] set_property LOC M2 [get_ports { PCIE_txp[1] }] set_property LOC N4 [get_ports { PCIE_txp[2] }] set_property LOC P2 [get_ports { PCIE_txp[3] }] set_property LOC T2 [get_ports { PCIE_txp[4] }] set_property LOC U4 [get_ports { PCIE_txp[5] }] set_property LOC V2 [get_ports { PCIE_txp[6] }] set_property LOC Y2 [get_ports { PCIE_txp[7] }] set_property LOC L3 [get_ports { PCIE_txn[0] }] set_property LOC M1 [get_ports { PCIE_txn[1] }] set_property LOC N3 [get_ports { PCIE_txn[2] }] set_property LOC P1 [get_ports { PCIE_txn[3] }] set_property LOC T1 [get_ports { PCIE_txn[4] }] set_property LOC U3 [get_ports { PCIE_txn[5] }] set_property LOC V1 [get_ports { PCIE_txn[6] }] set_property LOC Y1 [get_ports { PCIE_txn[7] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_pci_sys_clk_* }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] #set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_user_clk_* }] set_property IOSTANDARD LVCMOS25 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] set_property IOSTANDARD LVCMOS15 [get_ports { RST_cpu_reset }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # set_property LOC IBUFDS_GTE2_X0Y1 [get_cells { *pci_clk_100mhz_buf }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc # ignore this timing violation set_false_path -from [get_pins host_ep7/pclk_sel_reg/C] ================================================ FILE: constraints/xilinx/kc705g2.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: kintex7 ## FPGA: xc7k325t-2ffg900 ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC U8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC U7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC G25 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC AD12 [get_ports { CLK_sys_clk_p }] set_property LOC AD11 [get_ports { CLK_sys_clk_n }] #set_property LOC K28 [get_ports { CLK_user_clk_p }] #set_property LOC K29 [get_ports { CLK_user_clk_n }] set_property LOC M6 [get_ports { PCIE_rxp_v[0] }] set_property LOC P6 [get_ports { PCIE_rxp_v[1] }] set_property LOC R4 [get_ports { PCIE_rxp_v[2] }] set_property LOC T6 [get_ports { PCIE_rxp_v[3] }] set_property LOC V6 [get_ports { PCIE_rxp_v[4] }] set_property LOC W4 [get_ports { PCIE_rxp_v[5] }] set_property LOC Y6 [get_ports { PCIE_rxp_v[6] }] set_property LOC AA4 [get_ports { PCIE_rxp_v[7] }] set_property LOC M5 [get_ports { PCIE_rxn_v[0] }] set_property LOC P5 [get_ports { PCIE_rxn_v[1] }] set_property LOC R3 [get_ports { PCIE_rxn_v[2] }] set_property LOC T5 [get_ports { PCIE_rxn_v[3] }] set_property LOC V5 [get_ports { PCIE_rxn_v[4] }] set_property LOC W3 [get_ports { PCIE_rxn_v[5] }] set_property LOC Y5 [get_ports { PCIE_rxn_v[6] }] set_property LOC AA3 [get_ports { PCIE_rxn_v[7] }] set_property LOC L4 [get_ports { PCIE_txp[0] }] set_property LOC M2 [get_ports { PCIE_txp[1] }] set_property LOC N4 [get_ports { PCIE_txp[2] }] set_property LOC P2 [get_ports { PCIE_txp[3] }] set_property LOC T2 [get_ports { PCIE_txp[4] }] set_property LOC U4 [get_ports { PCIE_txp[5] }] set_property LOC V2 [get_ports { PCIE_txp[6] }] set_property LOC Y2 [get_ports { PCIE_txp[7] }] set_property LOC L3 [get_ports { PCIE_txn[0] }] set_property LOC M1 [get_ports { PCIE_txn[1] }] set_property LOC N3 [get_ports { PCIE_txn[2] }] set_property LOC P1 [get_ports { PCIE_txn[3] }] set_property LOC T1 [get_ports { PCIE_txn[4] }] set_property LOC U3 [get_ports { PCIE_txn[5] }] set_property LOC V1 [get_ports { PCIE_txn[6] }] set_property LOC Y1 [get_ports { PCIE_txn[7] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_pci_sys_clk_* }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] #set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_user_clk_* }] set_property IOSTANDARD LVCMOS25 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # set_property LOC IBUFDS_GTE2_X0Y1 [get_cells { *pci_clk_100mhz_buf }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/kcu105.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: virtex7 ## FPGA: xc7vx690t-3ffg1761C ## Speedgrade: -3 ## ###################################################################################################### ##The following two properties should be set for every design set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AB6 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AB5 [get_ports { CLK_pci_sys_clk_p }] set_property LOC K225 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC AK17 [get_ports { CLK_sys_clk_p }] // 300MHz SYSCLK set_property LOC AK16 [get_ports { CLK_sys_clk_n }] // 300MHz SYSCLK ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD LVCMOS18 [get_ports { leds_leds[*] }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk_* }] set_property IOSTANDARD LVCMOS18 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/miniitx100-axiddr3.prj ================================================ mig_7series_0 1 1 OFF 1024 ON Enabled xc7z100-ffg900/-2 4.0 No Buffer Use System Clock ACTIVE LOW FALSE 0 50 Ohms 0 7z/xc7z045-ffg900 DDR3_SDRAM/Components/MT41K256M16XX-125 1250 2.0V 4:1 200 0 800 1.000 1 1 1 1 32 1 1 Disabled Normal FALSE 15 10 3 1.5V BANK_ROW_COLUMN 8 - Fixed Sequential 11 Normal No Slow Exit Enable RZQ/7 Disable Enable RZQ/4 0 Disabled Enabled Output Buffer Enabled Full Array 8 Enabled Normal Dynamic ODT off AXI RD_PRI_REG 30 256 4 0 ================================================ FILE: constraints/xilinx/miniitx100.xdc ================================================ # Avnet Mini-ITX Zynq100 set_property LOC H9 [get_ports { CLK_sys_clk_p }] set_property LOC G9 [get_ports { CLK_sys_clk_n }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[0]"] set_property PACKAGE_PIN "C6" [get_ports "GPIO_leds[0]"] set_property slew "SLOW" [get_ports "GPIO_leds[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[0]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[1]"] set_property PACKAGE_PIN "B6" [get_ports "GPIO_leds[1]"] set_property slew "SLOW" [get_ports "GPIO_leds[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[1]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[2]"] set_property PACKAGE_PIN "L9" [get_ports "GPIO_leds[2]"] set_property slew "SLOW" [get_ports "GPIO_leds[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[2]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[3]"] set_property PACKAGE_PIN "L10" [get_ports "GPIO_leds[3]"] set_property slew "SLOW" [get_ports "GPIO_leds[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[3]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[4]"] set_property PACKAGE_PIN "K10" [get_ports "GPIO_leds[4]"] set_property slew "SLOW" [get_ports "GPIO_leds[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[4]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[5]"] set_property PACKAGE_PIN "K11" [get_ports "GPIO_leds[5]"] set_property slew "SLOW" [get_ports "GPIO_leds[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[5]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[6]"] set_property PACKAGE_PIN "L12" [get_ports "GPIO_leds[6]"] set_property slew "SLOW" [get_ports "GPIO_leds[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[6]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[7]"] set_property PACKAGE_PIN "K12" [get_ports "GPIO_leds[7]"] set_property slew "SLOW" [get_ports "GPIO_leds[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[7]"] ================================================ FILE: constraints/xilinx/nfsume-axiddr3.prj ================================================ nfsume_ddr3a 1 1 OFF 1024 ON Enabled xc7vx690t-ffg1761/-3 2.4 No Buffer Use System Clock ACTIVE LOW FALSE 0 50 Ohms 0 DDR3_SDRAM/SODIMMs/MT8KTF51264HZ-1G9 1250 1.8V 4:1 200 0 800 1.000 1 1 1 1 64 1 1 Disabled Normal FALSE 16 10 3 1.5V BANK_ROW_COLUMN 8 - Fixed Sequential 11 Normal No Slow Exit Enable RZQ/7 Disable Enable RZQ/6 0 Disabled Enabled Output Buffer Enabled Full Array 8 Enabled Normal Dynamic ODT off AXI RD_PRI_REG 32 512 4 0 ================================================ FILE: constraints/xilinx/nfsume.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: virtex7 ## FPGA: xc7vx690t-3ffg1761C ## Speedgrade: -3 ## ###################################################################################################### ##The following two properties should be set for every design set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AR22 [get_ports { leds[0] }] set_property LOC AR23 [get_ports { leds[1] }] set_property LOC AB7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AB8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC AY35 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC H19 [get_ports { CLK_sys_clk_p }] set_property LOC G18 [get_ports { CLK_sys_clk_n }] # set_property LOC W2 [get_ports { PCIE_rxp_v[0] }] # set_property LOC AA2 [get_ports { PCIE_rxp_v[1] }] # set_property LOC AC2 [get_ports { PCIE_rxp_v[2] }] # set_property LOC AE2 [get_ports { PCIE_rxp_v[3] }] # set_property LOC AG2 [get_ports { PCIE_rxp_v[4] }] # set_property LOC AH4 [get_ports { PCIE_rxp_v[5] }] # set_property LOC AJ2 [get_ports { PCIE_rxp_v[6] }] # set_property LOC AK4 [get_ports { PCIE_rxp_v[7] }] # set_property LOC W1 [get_ports { PCIE_rxn_v[0] }] # set_property LOC AA1 [get_ports { PCIE_rxn_v[1] }] # set_property LOC AC1 [get_ports { PCIE_rxn_v[2] }] # set_property LOC AE1 [get_ports { PCIE_rxn_v[3] }] # set_property LOC AG1 [get_ports { PCIE_rxn_v[4] }] # set_property LOC AH3 [get_ports { PCIE_rxn_v[5] }] # set_property LOC AJ1 [get_ports { PCIE_rxn_v[6] }] # set_property LOC AK3 [get_ports { PCIE_rxn_v[7] }] # set_property LOC Y4 [get_ports { PCIE_txp[0] }] # set_property LOC AA6 [get_ports { PCIE_txp[1] }] # set_property LOC AB4 [get_ports { PCIE_txp[2] }] # set_property LOC AC6 [get_ports { PCIE_txp[3] }] # set_property LOC AD4 [get_ports { PCIE_txp[4] }] # set_property LOC AE6 [get_ports { PCIE_txp[5] }] # set_property LOC AF4 [get_ports { PCIE_txp[6] }] # set_property LOC AG6 [get_ports { PCIE_txp[7] }] # set_property LOC Y3 [get_ports { PCIE_txn[0] }] # set_property LOC AA5 [get_ports { PCIE_txn[1] }] # set_property LOC AB3 [get_ports { PCIE_txn[2] }] # set_property LOC AC5 [get_ports { PCIE_txn[3] }] # set_property LOC AD3 [get_ports { PCIE_txn[4] }] # set_property LOC AE5 [get_ports { PCIE_txn[5] }] # set_property LOC AF3 [get_ports { PCIE_txn[6] }] # set_property LOC AG5 [get_ports { PCIE_txn[7] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD LVCMOS15 [get_ports { leds[*] }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] set_property IOSTANDARD LVCMOS18 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # #set_property LOC IBUFDS_GTE2_X1Y5 [get_cells { *pci_clk_100mhz_buf }] #set_property LOC bogus [get_cells -hier -filter { NAME =~ */ext_clk.pipe_clock_i/mmcm_i }] #set_property LOC bogus [get_cells -hier -filter { NAME =~ *clkgen_pll }] #set_property LOC bogus [get_cells -hier -filter { NAME =~ *clk_gen_pll }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/ok/zc7z010clg400.xdc ================================================ ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z020clg484-1 ## Device Size: xc7z020 ## Package: clg484 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ create_clock -name clk_fpga_0 -period "10" [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 0.6 set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "M5" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_VRP"] set_property PACKAGE_PIN "H5" [get_ports "DDR_VRP"] set_property slew "FAST" [get_ports "DDR_VRP"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_VRP"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_VRN"] set_property PACKAGE_PIN "G5" [get_ports "DDR_VRN"] set_property slew "FAST" [get_ports "DDR_VRN"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_VRN"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "P4" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "N5" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "B4" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS[3]"] set_property PACKAGE_PIN "W5" [get_ports "DDR_DQS[3]"] set_property slew "FAST" [get_ports "DDR_DQS[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS[2]"] set_property PACKAGE_PIN "R2" [get_ports "DDR_DQS[2]"] set_property slew "FAST" [get_ports "DDR_DQS[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS[1]"] set_property PACKAGE_PIN "G2" [get_ports "DDR_DQS[1]"] set_property slew "FAST" [get_ports "DDR_DQS[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS[0]"] set_property PACKAGE_PIN "C2" [get_ports "DDR_DQS[0]"] set_property slew "FAST" [get_ports "DDR_DQS[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "W4" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "T2" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "F2" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B2" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "E3" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "E2" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "E1" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "C1" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "D1" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "D3" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "A4" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "V3" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "V2" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "A2" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "W3" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "Y2" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "Y4" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "W1" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "Y3" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "V1" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "U3" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "U2" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "U4" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "T4" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "B3" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "R1" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "R3" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "P3" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "P1" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "J1" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "H1" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "H2" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "J3" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "H3" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "G3" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "C3" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "Y1" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "T1" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "F1" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "A1" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N1" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "N3" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk"] set_property PACKAGE_PIN "L2" [get_ports "DDR_Clk"] set_property slew "FAST" [get_ports "DDR_Clk"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Clk"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "M2" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "P5" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "J5" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "R4" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "L5" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J4" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "K1" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K4" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "L4" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "L1" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "M4" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "K3" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "M3" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K2" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "F4" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "D4" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "E4" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "G4" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "F5" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "N2" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/ok/zc7z020clg400.xdc ================================================ ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z020clg484-1 ## Device Size: xc7z020 ## Package: clg484 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ create_clock -name clk_fpga_0 -period "10" [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 0.6 set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "R4" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "R5" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "P5" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F3" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "V2" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "N2" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "H2" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C2" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "W2" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "P2" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "J2" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "D2" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "G1" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "G2" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "F1" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "F2" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "E1" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "E3" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "D3" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "Y1" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "W3" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "B2" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "Y3" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "W1" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "U2" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "AA1" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "U1" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "AA3" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "R1" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "M2" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "T2" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "R3" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "C3" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "T1" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "N3" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "T3" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "M1" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "K3" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "J1" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "K1" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "L3" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "L2" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "L1" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "D1" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "AA2" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "P1" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "H3" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "B1" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "P6" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "V3" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "N4" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "N5" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "P3" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M6" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "L6" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "L7" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "H5" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "J5" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "J6" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "J7" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "K5" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "K6" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "L4" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "K4" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "M5" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "G4" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "F4" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "H4" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "G5" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "J3" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "M4" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/ok/zc7z020clg484.xdc ================================================ ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z020clg484-1 ## Device Size: xc7z020 ## Package: clg484 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ create_clock -name clk_fpga_0 -period "10" [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 0.6 set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "R4" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "R5" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "P5" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F3" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "V2" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "N2" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "H2" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C2" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "W2" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "P2" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "J2" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "D2" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "G1" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "G2" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "F1" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "F2" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "E1" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "E3" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "D3" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "Y1" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "W3" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "B2" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "Y3" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "W1" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "U2" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "AA1" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "U1" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "AA3" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "R1" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "M2" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "T2" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "R3" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "C3" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "T1" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "N3" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "T3" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "M1" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "K3" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "J1" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "K1" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "L3" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "L2" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "L1" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "D1" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "AA2" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "P1" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "H3" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "B1" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "P6" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "V3" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "N4" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "N5" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "P3" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M6" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "L6" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "L7" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "H5" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "J5" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "J6" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "J7" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "K5" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "K6" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "L4" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "K4" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "M5" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "G4" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "F4" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "H4" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "G5" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "J3" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "M4" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/ok/zc7z045ffg900.xdc ================================================ ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z045ffg900-2 ## Device Size: xc7z045 ## Package: ffg900 ## Speedgrade: -2 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ create_clock -name clk_fpga_0 -period "5" [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 0.6 set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "N23" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "N24" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "L23" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F25" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "L28" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "G29" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "C29" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C26" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "L29" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "F29" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "B29" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B26" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "A28" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "A27" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "B27" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "D25" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "B25" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "D26" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "E25" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "M30" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "L30" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "E27" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "M29" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "K30" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "J29" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "J28" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "J30" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "K27" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "F30" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "G30" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "F28" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "E30" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "A25" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "E28" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "H28" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "G27" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "H27" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "D28" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "D29" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "A30" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "D30" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "C28" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "A29" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "E26" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "K28" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "H29" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "B30" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "C27" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N22" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "M22" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "K25" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "J25" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "M24" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M25" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "M26" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "M27" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J23" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "F27" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K22" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "H26" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "G24" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "J26" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "G25" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "L27" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K26" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "J24" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "H23" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "K23" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "H24" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "G26" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "L25" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/ok/zc7z100ffg900.xdc ================================================ ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z045ffg900-2 ## Device Size: xc7z045 ## Package: ffg900 ## Speedgrade: -2 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ create_clock -name clk_fpga_0 -period "5" [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 0.6 set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "N23" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "N24" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "L23" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F25" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "L28" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "G29" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "C29" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C26" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "L29" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "F29" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "B29" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B26" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "A28" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "A27" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "B27" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "D25" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "B25" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "D26" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "E25" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "M30" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "L30" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "E27" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "M29" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "K30" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "J29" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "J28" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "J30" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "K27" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "F30" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "G30" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "F28" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "E30" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "A25" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "E28" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "H28" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "G27" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "H27" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "D28" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "D29" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "A30" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "D30" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "C28" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "A29" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "E26" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "K28" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "H29" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "B30" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "C27" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N22" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "M22" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "K25" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "J25" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "M24" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M25" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "M26" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "M27" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J23" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "F27" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K22" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "H26" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "G24" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "J26" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "G25" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "L27" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K26" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "J24" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "H23" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "K23" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "H24" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "G26" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "L25" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/parallella.xdc ================================================ # Nothing here, until the standard Parallella stuff gets defined ================================================ FILE: constraints/xilinx/pcie-clocks.xdc ================================================ #create_clock -name bscan_refclk -period 20 [get_pins host_pciehost_bscan_bscan/TCK] create_clock -name pci_refclk -period 10 [get_ports CLK_pci_sys_clk_p] create_clock -name sys_clk -period 5 [get_ports CLK_sys_clk_p] create_clock -name sys_clk1_300 -period 3.333 [get_ports CLK_sys_clk1_300_p] create_clock -name sys_clk2_300 -period 3.333 [get_ports CLK_sys_clk2_300_p] create_clock -name sys_clk_300 -period 3.333 [get_ports CLK_sys_clk_300_p] create_clock -name sys_clk1_250 -period 4.0 [get_ports CLK_sys_clk1_250_p] create_clock -name sys_clk2_250 -period 4.0 [get_ports CLK_sys_clk2_250_p] set_max_delay -from [get_clocks {clkgen_pll_CLKOUT0}] -to [get_clocks {userclk2}] [get_property PERIOD [get_clocks {userclk2}]] -datapath_only set_max_delay -to [get_clocks {clkgen_pll_CLKOUT0}] -from [get_clocks {userclk2}] [get_property PERIOD [get_clocks {userclk2}]] -datapath_only set_max_delay -from [get_clocks {clkgen_pll_CLKOUT1}] -to [get_clocks {userclk2}] [get_property PERIOD [get_clocks {userclk2}]] -datapath_only set_max_delay -to [get_clocks {clkgen_pll_CLKOUT1}] -from [get_clocks {userclk2}] [get_property PERIOD [get_clocks {userclk2}]] -datapath_only set_max_delay -from [get_clocks {clkgen_pll_CLKOUT2}] -to [get_clocks {userclk2}] [get_property PERIOD [get_clocks {userclk2}]] -datapath_only set_max_delay -to [get_clocks {clkgen_pll_CLKOUT2}] -from [get_clocks {userclk2}] [get_property PERIOD [get_clocks {userclk2}]] -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {sys_clk}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {sys_clk}] 4.0 -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {clk_pll_i}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {clk_pll_i}] 4.0 -datapath_only ================================================ FILE: constraints/xilinx/v2000t.xdc ================================================ # constraints TBD ================================================ FILE: constraints/xilinx/vc707-axiddr3.prj ================================================ mig_7series_0 1 1 OFF 1024 ON Enabled xc7vx485t-ffg1761/-2 2.3 No Buffer Use System Clock ACTIVE LOW FALSE 0 50 Ohms 0 DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 1250 2.0V 4:1 200 0 800 1.000 1 1 1 1 64 1 1 Disabled Normal FALSE 14 10 3 1.5V BANK_ROW_COLUMN 8 - Fixed Sequential 11 Normal No Slow Exit Enable RZQ/7 Disable Enable RZQ/4 0 Disabled Enabled Output Buffer Enabled Full Array 8 Enabled Normal Dynamic ODT off AXI RD_PRI_REG 30 512 6 0 ================================================ FILE: constraints/xilinx/vc707-portal-pblock.xdc ================================================ startgroup create_pblock pblock_portalTop resize_pblock pblock_portalTop -add {SLICE_X0Y0:SLICE_X105Y199 DSP48_X0Y0:DSP48_X8Y79 PCIE_X0Y0:PCIE_X0Y0 RAMB18_X0Y0:RAMB18_X6Y79 RAMB36_X0Y0:RAMB36_X6Y39} add_cells_to_pblock pblock_portalTop [get_cells top_portalTop] endgroup ================================================ FILE: constraints/xilinx/vc707.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: virtex7 ## FPGA: xc7vx485t-2ffg1761C ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AD8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC AD7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AV35 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC E19 [get_ports { CLK_sys_clk_p }] set_property LOC E18 [get_ports { CLK_sys_clk_n }] set_property LOC Y4 [get_ports { PCIE_rxp_v[0] }] set_property LOC AA6 [get_ports { PCIE_rxp_v[1] }] set_property LOC AB4 [get_ports { PCIE_rxp_v[2] }] set_property LOC AC6 [get_ports { PCIE_rxp_v[3] }] set_property LOC AD4 [get_ports { PCIE_rxp_v[4] }] set_property LOC AE6 [get_ports { PCIE_rxp_v[5] }] set_property LOC AF4 [get_ports { PCIE_rxp_v[6] }] set_property LOC AG6 [get_ports { PCIE_rxp_v[7] }] set_property LOC Y3 [get_ports { PCIE_rxn_v[0] }] set_property LOC AA5 [get_ports { PCIE_rxn_v[1] }] set_property LOC AB3 [get_ports { PCIE_rxn_v[2] }] set_property LOC AC5 [get_ports { PCIE_rxn_v[3] }] set_property LOC AD3 [get_ports { PCIE_rxn_v[4] }] set_property LOC AE5 [get_ports { PCIE_rxn_v[5] }] set_property LOC AF3 [get_ports { PCIE_rxn_v[6] }] set_property LOC AG5 [get_ports { PCIE_rxn_v[7] }] set_property LOC W2 [get_ports { PCIE_txp[0] }] set_property LOC AA2 [get_ports { PCIE_txp[1] }] set_property LOC AC2 [get_ports { PCIE_txp[2] }] set_property LOC AE2 [get_ports { PCIE_txp[3] }] set_property LOC AG2 [get_ports { PCIE_txp[4] }] set_property LOC AH4 [get_ports { PCIE_txp[5] }] set_property LOC AJ2 [get_ports { PCIE_txp[6] }] set_property LOC AK4 [get_ports { PCIE_txp[7] }] set_property LOC W1 [get_ports { PCIE_txn[0] }] set_property LOC AA1 [get_ports { PCIE_txn[1] }] set_property LOC AC1 [get_ports { PCIE_txn[2] }] set_property LOC AE1 [get_ports { PCIE_txn[3] }] set_property LOC AG1 [get_ports { PCIE_txn[4] }] set_property LOC AH3 [get_ports { PCIE_txn[5] }] set_property LOC AJ1 [get_ports { PCIE_txn[6] }] set_property LOC AK3 [get_ports { PCIE_txn[7] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] set_property IOSTANDARD LVCMOS15 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # set_property LOC IBUFDS_GTE2_X1Y5 [get_cells { host_pcieHostTop_clockGen }] set_property LOC MMCME2_ADV_X1Y2 [get_cells -hier -filter { NAME =~ */ext_clk.pipe_clock_i/mmcm_i }] set_property LOC MMCME2_ADV_X1Y1 [get_cells -hier -filter { NAME =~ *clkgen_pll }] set_property LOC MMCME2_ADV_X1Y5 [get_cells -hier -filter { NAME =~ *clk_gen_pll }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc # ignore this timing violation set_false_path -from [get_pins host_ep7/pclk_sel_reg/C] ================================================ FILE: constraints/xilinx/vc707_aurora.xdc ================================================ ################################################################################## ## ## Project: Aurora 64B/66B ## Company: Xilinx ## ## ## ## (c) Copyright 2012 - 2013 Xilinx, Inc. All rights reserved. ## ## This file contains confidential and proprietary information ## of Xilinx, Inc. and is protected under U.S. and ## international copyright and other intellectual property ## laws. ## ## DISCLAIMER ## This disclaimer is not a license and does not grant any ## rights to the materials distributed herewith. Except as ## otherwise provided in a valid license issued to you by ## Xilinx, and to the maximum extent permitted by applicable ## law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND ## WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES ## AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING ## BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- ## INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and ## (2) Xilinx shall not be liable (whether in contract or tort, ## including negligence, or under any other theory of ## liability) for any loss or damage of any kind or nature ## related to, arising under or in connection with these ## materials, including for any direct, or any indirect, ## special, incidental, or consequential loss or damage ## (including loss of data, profits, goodwill, or any type of ## loss or damage suffered as a result of any action brought ## by a third party) even if such damage or loss was ## reasonably foreseeable or Xilinx had been advised of the ## possibility of the same. ## ## CRITICAL APPLICATIONS ## Xilinx products are not designed or intended to be fail- ## safe, or for use in any application requiring fail-safe ## performance, such as life-support or safety devices or ## systems, Class III medical devices, nuclear facilities, ## applications related to the deployment of airbags, or any ## other applications that could lead to death, personal ## injury, or severe property or environmental damage ## (individually and collectively, "Critical ## Applications"). Customer assumes the sole risk and ## liability of any use of Xilinx products in Critical ## Applications, subject only to applicable laws and ## regulations governing limitations on product liability. ## ## THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS ## PART OF THIS FILE AT ALL TIMES. ## ################################################################################# ## ## aurora_64b66b_0 ## ## ## Description: This is the design constraints file for a 1 lane Aurora ## core. ## ## ## ################################ CLOCK CONSTRAINTS ############################## set_false_path -to [get_pins -hier *data_fifo*/RST] set_false_path -to [get_pins -hier *rxrecclk_bufg_i*/CE] create_clock -period 3.200 [get_pins -hier -filter {name=~*AURORA_64B66B_0_GTX_INST/gtxe2_i/TXOUTCLK}] ## create_clock -period 3.200 [get_pins -hier -filter {name=~aurora_64b66b_0_wrapper_i*aurora_64b66b_0_multi_gt_i*AURORA_64B66B_0_GTX_INST/gtxe2_i/TXOUTCLK}] ## create_clock -period 3.200 [get_pins -hier -filter {name=~*aurora_64b66b_0_wrapper_i*aurora_64b66b_0_multi_gt_i*AURORA_64B66B_0_GTX_INST/gtxe2_i/TXOUTCLK}] ## create_clock -period 3.200 [get_pins */top_auroraImport0/auroraImport/aurora_64b66b_0_block_i/aurora_64b66b_0_i/inst/aurora_64b66b_0_wrapper_i/aurora_64b66b_0_multi_gt_i/AURORA_64B66B_0_GTX_INST/gtxe2_i/TXOUTCLK] create_clock -period 3.200 [get_pins -hier -filter {name=~*AURORA_64B66B_0_GTX_INST/gtxe2_i/RXOUTCLK}] ## create_clock -period 3.200 [get_pins -hier -filter {name=~aurora_64b66b_0_wrapper_i*aurora_64b66b_0_multi_gt_i*AURORA_64B66B_0_GTX_INST/gtxe2_i/RXOUTCLK}] ## create_clock -period 3.200 [get_pins -hier -filter {name=~top_auroraImport1_0*aurora_64b66b_0_wrapper_i*aurora_64b66b_0_multi_gt_i*AURORA_64B66B_0_GTX_INST/gtxe2_i/RXOUTCLK}] ## create_clock -period 3.200 [get_pins */top_auroraImport0/auroraImport/aurora_64b66b_0_block_i/aurora_64b66b_0_i/inst/aurora_64b66b_0_wrapper_i/aurora_64b66b_0_multi_gt_i/AURORA_64B66B_0_GTX_INST/gtxe2_i/RXOUTCLK] set_false_path -to [get_pins -hier *aurora_64b66b_0_cdc_to*/D] ## create_clock -name TS_sync_clk_i -period 3.200 [get_pins */aurora_64b66b_0_block_i/clock_module_i/sync_clock_net_i/O] create_clock -name TS_sync_clk_i_0 -period 3.200 [get_pins */top_auroraImport0/auroraImport/aurora_64b66b_0_block_i/clock_module_i/sync_clock_net_i/O] ## create_clock -name TS_sync_clk_i_1_0 -period 3.200 [get_pins */top_auroraImport1_0/auroraImport/aurora_64b66b_0_block_i/clock_module_i/sync_clock_net_i/O] ## port 0 create_clock -name GTXQ0_left_i_p -period 8.000 [get_ports CLK_gtx_clk_0_p] create_clock -name GTXQ0_left_i_n -period 8.000 [get_ports CLK_gtx_clk_0_n] set_property LOC AH8 [get_ports CLK_gtx_clk_0_p] set_property LOC AH7 [get_ports CLK_gtx_clk_0_n] set_property LOC GTXE2_CHANNEL_X1Y0 [get_cells */top_auroraImport0/auroraImport/aurora_64b66b_0_block_i/aurora_64b66b_0_i/inst/aurora_64b66b_0_wrapper_i/aurora_64b66b_0_multi_gt_i/AURORA_64B66B_0_GTX_INST/gtxe2_i] set_property LOC AP4 [get_ports { pins_aurora0_TXP }] set_property LOC AP3 [get_ports { pins_aurora0_TXN }] set_property LOC AN6 [get_ports { pins_aurora0_rxp_i }] set_property LOC AN5 [get_ports { pins_aurora0_rxn_i }] ## fmc 1 port 0 ## create_clock -name GTXQ1_0_left_i_p -period 8.000 [get_ports CLK_gtx_clk_1_0_p] ## create_clock -name GTXQ1_0_left_i_n -period 8.000 [get_ports CLK_gtx_clk_1_0_n] ## set_property LOC E10 [get_ports CLK_gtx_clk_1_0_p] ## set_property LOC E9 [get_ports CLK_gtx_clk_1_0_n] ## ## set_property LOC GTXE2_CHANNEL_X1Y24 [get_cells */top_auroraImport1_0/auroraImport/aurora_64b66b_0_block_i/aurora_64b66b_0_i/inst/aurora_64b66b_0_wrapper_i/aurora_64b66b_0_multi_gt_i/AURORA_64B66B_0_GTX_INST/gtxe2_i] ## ## ## set_property LOC E2 [get_ports { pins_aurora1_0_TXP }] ## set_property LOC E1 [get_ports { pins_aurora1_0_TXN }] ## set_property LOC D8 [get_ports { pins_aurora1_0_rxp_i }] ## set_property LOC D7 [get_ports { pins_aurora1_0_rxn_i }] ================================================ FILE: constraints/xilinx/vc707_ddr3.xdc ================================================ ###################################################################################################### ## DDR3 Constraints ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### # PadFunction: IO_L23N_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[0]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[0]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[0]}] set_property LOC N14 [get_ports {pins_ddr3_DQ[0]}] # PadFunction: IO_L22P_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[1]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[1]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[1]}] set_property LOC N13 [get_ports {pins_ddr3_DQ[1]}] # PadFunction: IO_L20N_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[2]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[2]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[2]}] set_property LOC L14 [get_ports {pins_ddr3_DQ[2]}] # PadFunction: IO_L20P_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[3]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[3]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[3]}] set_property LOC M14 [get_ports {pins_ddr3_DQ[3]}] # PadFunction: IO_L24P_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[4]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[4]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[4]}] set_property LOC M12 [get_ports {pins_ddr3_DQ[4]}] # PadFunction: IO_L23P_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[5]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[5]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[5]}] set_property LOC N15 [get_ports {pins_ddr3_DQ[5]}] # PadFunction: IO_L24N_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[6]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[6]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[6]}] set_property LOC M11 [get_ports {pins_ddr3_DQ[6]}] # PadFunction: IO_L19P_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[7]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[7]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[7]}] set_property LOC L12 [get_ports {pins_ddr3_DQ[7]}] # PadFunction: IO_L17P_T2_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[8]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[8]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[8]}] set_property LOC K14 [get_ports {pins_ddr3_DQ[8]}] # PadFunction: IO_L17N_T2_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[9]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[9]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[9]}] set_property LOC K13 [get_ports {pins_ddr3_DQ[9]}] # PadFunction: IO_L14N_T2_SRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[10]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[10]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[10]}] set_property LOC H13 [get_ports {pins_ddr3_DQ[10]}] # PadFunction: IO_L14P_T2_SRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[11]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[11]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[11]}] set_property LOC J13 [get_ports {pins_ddr3_DQ[11]}] # PadFunction: IO_L18P_T2_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[12]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[12]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[12]}] set_property LOC L16 [get_ports {pins_ddr3_DQ[12]}] # PadFunction: IO_L18N_T2_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[13]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[13]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[13]}] set_property LOC L15 [get_ports {pins_ddr3_DQ[13]}] # PadFunction: IO_L13N_T2_MRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[14]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[14]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[14]}] set_property LOC H14 [get_ports {pins_ddr3_DQ[14]}] # PadFunction: IO_L16N_T2_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[15]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[15]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[15]}] set_property LOC J15 [get_ports {pins_ddr3_DQ[15]}] # PadFunction: IO_L7N_T1_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[16]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[16]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[16]}] set_property LOC E15 [get_ports {pins_ddr3_DQ[16]}] # PadFunction: IO_L8N_T1_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[17]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[17]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[17]}] set_property LOC E13 [get_ports {pins_ddr3_DQ[17]}] # PadFunction: IO_L11P_T1_SRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[18]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[18]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[18]}] set_property LOC F15 [get_ports {pins_ddr3_DQ[18]}] # PadFunction: IO_L8P_T1_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[19]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[19]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[19]}] set_property LOC E14 [get_ports {pins_ddr3_DQ[19]}] # PadFunction: IO_L12N_T1_MRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[20]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[20]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[20]}] set_property LOC G13 [get_ports {pins_ddr3_DQ[20]}] # PadFunction: IO_L10P_T1_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[21]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[21]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[21]}] set_property LOC G12 [get_ports {pins_ddr3_DQ[21]}] # PadFunction: IO_L11N_T1_SRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[22]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[22]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[22]}] set_property LOC F14 [get_ports {pins_ddr3_DQ[22]}] # PadFunction: IO_L12P_T1_MRCC_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[23]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[23]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[23]}] set_property LOC G14 [get_ports {pins_ddr3_DQ[23]}] # PadFunction: IO_L2P_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[24]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[24]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[24]}] set_property LOC B14 [get_ports {pins_ddr3_DQ[24]}] # PadFunction: IO_L4N_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[25]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[25]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[25]}] set_property LOC C13 [get_ports {pins_ddr3_DQ[25]}] # PadFunction: IO_L1N_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[26]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[26]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[26]}] set_property LOC B16 [get_ports {pins_ddr3_DQ[26]}] # PadFunction: IO_L5N_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[27]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[27]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[27]}] set_property LOC D15 [get_ports {pins_ddr3_DQ[27]}] # PadFunction: IO_L4P_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[28]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[28]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[28]}] set_property LOC D13 [get_ports {pins_ddr3_DQ[28]}] # PadFunction: IO_L6P_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[29]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[29]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[29]}] set_property LOC E12 [get_ports {pins_ddr3_DQ[29]}] # PadFunction: IO_L1P_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[30]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[30]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[30]}] set_property LOC C16 [get_ports {pins_ddr3_DQ[30]}] # PadFunction: IO_L5P_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[31]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[31]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[31]}] set_property LOC D16 [get_ports {pins_ddr3_DQ[31]}] # PadFunction: IO_L1P_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[32]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[32]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[32]}] set_property LOC A24 [get_ports {pins_ddr3_DQ[32]}] # PadFunction: IO_L4N_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[33]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[33]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[33]}] set_property LOC B23 [get_ports {pins_ddr3_DQ[33]}] # PadFunction: IO_L5N_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[34]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[34]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[34]}] set_property LOC B27 [get_ports {pins_ddr3_DQ[34]}] # PadFunction: IO_L5P_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[35]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[35]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[35]}] set_property LOC B26 [get_ports {pins_ddr3_DQ[35]}] # PadFunction: IO_L2N_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[36]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[36]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[36]}] set_property LOC A22 [get_ports {pins_ddr3_DQ[36]}] # PadFunction: IO_L2P_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[37]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[37]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[37]}] set_property LOC B22 [get_ports {pins_ddr3_DQ[37]}] # PadFunction: IO_L1N_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[38]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[38]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[38]}] set_property LOC A25 [get_ports {pins_ddr3_DQ[38]}] # PadFunction: IO_L6P_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[39]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[39]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[39]}] set_property LOC C24 [get_ports {pins_ddr3_DQ[39]}] # PadFunction: IO_L7N_T1_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[40]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[40]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[40]}] set_property LOC E24 [get_ports {pins_ddr3_DQ[40]}] # PadFunction: IO_L10N_T1_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[41]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[41]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[41]}] set_property LOC D23 [get_ports {pins_ddr3_DQ[41]}] # PadFunction: IO_L11N_T1_SRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[42]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[42]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[42]}] set_property LOC D26 [get_ports {pins_ddr3_DQ[42]}] # PadFunction: IO_L12P_T1_MRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[43]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[43]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[43]}] set_property LOC C25 [get_ports {pins_ddr3_DQ[43]}] # PadFunction: IO_L7P_T1_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[44]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[44]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[44]}] set_property LOC E23 [get_ports {pins_ddr3_DQ[44]}] # PadFunction: IO_L10P_T1_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[45]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[45]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[45]}] set_property LOC D22 [get_ports {pins_ddr3_DQ[45]}] # PadFunction: IO_L8P_T1_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[46]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[46]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[46]}] set_property LOC F22 [get_ports {pins_ddr3_DQ[46]}] # PadFunction: IO_L8N_T1_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[47]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[47]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[47]}] set_property LOC E22 [get_ports {pins_ddr3_DQ[47]}] # PadFunction: IO_L17N_T2_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[48]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[48]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[48]}] set_property LOC A30 [get_ports {pins_ddr3_DQ[48]}] # PadFunction: IO_L13P_T2_MRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[49]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[49]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[49]}] set_property LOC D27 [get_ports {pins_ddr3_DQ[49]}] # PadFunction: IO_L17P_T2_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[50]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[50]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[50]}] set_property LOC A29 [get_ports {pins_ddr3_DQ[50]}] # PadFunction: IO_L14P_T2_SRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[51]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[51]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[51]}] set_property LOC C28 [get_ports {pins_ddr3_DQ[51]}] # PadFunction: IO_L13N_T2_MRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[52]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[52]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[52]}] set_property LOC D28 [get_ports {pins_ddr3_DQ[52]}] # PadFunction: IO_L18N_T2_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[53]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[53]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[53]}] set_property LOC B31 [get_ports {pins_ddr3_DQ[53]}] # PadFunction: IO_L16P_T2_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[54]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[54]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[54]}] set_property LOC A31 [get_ports {pins_ddr3_DQ[54]}] # PadFunction: IO_L16N_T2_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[55]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[55]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[55]}] set_property LOC A32 [get_ports {pins_ddr3_DQ[55]}] # PadFunction: IO_L19P_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[56]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[56]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[56]}] set_property LOC E30 [get_ports {pins_ddr3_DQ[56]}] # PadFunction: IO_L22P_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[57]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[57]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[57]}] set_property LOC F29 [get_ports {pins_ddr3_DQ[57]}] # PadFunction: IO_L24P_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[58]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[58]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[58]}] set_property LOC F30 [get_ports {pins_ddr3_DQ[58]}] # PadFunction: IO_L23N_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[59]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[59]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[59]}] set_property LOC F27 [get_ports {pins_ddr3_DQ[59]}] # PadFunction: IO_L20N_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[60]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[60]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[60]}] set_property LOC C30 [get_ports {pins_ddr3_DQ[60]}] # PadFunction: IO_L22N_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[61]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[61]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[61]}] set_property LOC E29 [get_ports {pins_ddr3_DQ[61]}] # PadFunction: IO_L23P_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[62]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[62]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[62]}] set_property LOC F26 [get_ports {pins_ddr3_DQ[62]}] # PadFunction: IO_L20P_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQ[63]}] set_property SLEW FAST [get_ports {pins_ddr3_DQ[63]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {pins_ddr3_DQ[63]}] set_property LOC D30 [get_ports {pins_ddr3_DQ[63]}] #set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[15]}] #set_property SLEW FAST [get_ports {pins_ddr3_A[15]}] #set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[15]}] #set_property LOC E17 [get_ports {pins_ddr3_A[15]}] set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[14]}] set_property SLEW FAST [get_ports {pins_ddr3_A[14]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[14]}] set_property LOC F17 [get_ports {pins_ddr3_A[14]}] # PadFunction: IO_L5N_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[13]}] set_property SLEW FAST [get_ports {pins_ddr3_A[13]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[13]}] set_property LOC A21 [get_ports {pins_ddr3_A[13]}] # PadFunction: IO_L2N_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[12]}] set_property SLEW FAST [get_ports {pins_ddr3_A[12]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[12]}] set_property LOC A15 [get_ports {pins_ddr3_A[12]}] # PadFunction: IO_L4P_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[11]}] set_property SLEW FAST [get_ports {pins_ddr3_A[11]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[11]}] set_property LOC B17 [get_ports {pins_ddr3_A[11]}] # PadFunction: IO_L5P_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[10]}] set_property SLEW FAST [get_ports {pins_ddr3_A[10]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[10]}] set_property LOC B21 [get_ports {pins_ddr3_A[10]}] # PadFunction: IO_L1P_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[9]}] set_property SLEW FAST [get_ports {pins_ddr3_A[9]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[9]}] set_property LOC C19 [get_ports {pins_ddr3_A[9]}] # PadFunction: IO_L10N_T1_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[8]}] set_property SLEW FAST [get_ports {pins_ddr3_A[8]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[8]}] set_property LOC D17 [get_ports {pins_ddr3_A[8]}] # PadFunction: IO_L6P_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[7]}] set_property SLEW FAST [get_ports {pins_ddr3_A[7]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[7]}] set_property LOC C18 [get_ports {pins_ddr3_A[7]}] # PadFunction: IO_L7P_T1_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[6]}] set_property SLEW FAST [get_ports {pins_ddr3_A[6]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[6]}] set_property LOC D20 [get_ports {pins_ddr3_A[6]}] # PadFunction: IO_L2P_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[5]}] set_property SLEW FAST [get_ports {pins_ddr3_A[5]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[5]}] set_property LOC A16 [get_ports {pins_ddr3_A[5]}] # PadFunction: IO_L4N_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[4]}] set_property SLEW FAST [get_ports {pins_ddr3_A[4]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[4]}] set_property LOC A17 [get_ports {pins_ddr3_A[4]}] # PadFunction: IO_L3N_T0_DQS_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[3]}] set_property SLEW FAST [get_ports {pins_ddr3_A[3]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[3]}] set_property LOC A19 [get_ports {pins_ddr3_A[3]}] # PadFunction: IO_L7N_T1_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[2]}] set_property SLEW FAST [get_ports {pins_ddr3_A[2]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[2]}] set_property LOC C20 [get_ports {pins_ddr3_A[2]}] # PadFunction: IO_L1N_T0_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[1]}] set_property SLEW FAST [get_ports {pins_ddr3_A[1]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[1]}] set_property LOC B19 [get_ports {pins_ddr3_A[1]}] # PadFunction: IO_L3P_T0_DQS_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_A[0]}] set_property SLEW FAST [get_ports {pins_ddr3_A[0]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_A[0]}] set_property LOC A20 [get_ports {pins_ddr3_A[0]}] # PadFunction: IO_L10P_T1_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_BA[2]}] set_property SLEW FAST [get_ports {pins_ddr3_BA[2]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_BA[2]}] set_property LOC D18 [get_ports {pins_ddr3_BA[2]}] # PadFunction: IO_L9N_T1_DQS_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_BA[1]}] set_property SLEW FAST [get_ports {pins_ddr3_BA[1]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_BA[1]}] set_property LOC C21 [get_ports {pins_ddr3_BA[1]}] # PadFunction: IO_L9P_T1_DQS_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_BA[0]}] set_property SLEW FAST [get_ports {pins_ddr3_BA[0]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_BA[0]}] set_property LOC D21 [get_ports {pins_ddr3_BA[0]}] # PadFunction: IO_L15N_T2_DQS_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_RAS_N}] set_property SLEW FAST [get_ports {pins_ddr3_RAS_N}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_RAS_N}] set_property LOC E20 [get_ports {pins_ddr3_RAS_N}] # PadFunction: IO_L16P_T2_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_CAS_N}] set_property SLEW FAST [get_ports {pins_ddr3_CAS_N}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_CAS_N}] set_property LOC K17 [get_ports {pins_ddr3_CAS_N}] # PadFunction: IO_L15P_T2_DQS_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_WE_N}] set_property SLEW FAST [get_ports {pins_ddr3_WE_N}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_WE_N}] set_property LOC F20 [get_ports {pins_ddr3_WE_N}] # PadFunction: IO_L14N_T2_SRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_RESET_N}] set_property SLEW FAST [get_ports {pins_ddr3_RESET_N}] set_property IOSTANDARD LVCMOS15 [get_ports {pins_ddr3_RESET_N}] set_property LOC C29 [get_ports {pins_ddr3_RESET_N}] # PadFunction: IO_L14P_T2_SRCC_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_CKE}] set_property SLEW FAST [get_ports {pins_ddr3_CKE}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_CKE}] set_property LOC K19 [get_ports {pins_ddr3_CKE}] # PadFunction: IO_L17N_T2_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_ODT}] set_property SLEW FAST [get_ports {pins_ddr3_ODT}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_ODT}] set_property LOC H20 [get_ports {pins_ddr3_ODT}] # PadFunction: IO_L16N_T2_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_CS_N}] set_property SLEW FAST [get_ports {pins_ddr3_CS_N}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_CS_N}] set_property LOC J17 [get_ports {pins_ddr3_CS_N}] # PadFunction: IO_L22N_T3_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[0]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[0]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[0]}] set_property LOC M13 [get_ports {pins_ddr3_DM[0]}] # PadFunction: IO_L16P_T2_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[1]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[1]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[1]}] set_property LOC K15 [get_ports {pins_ddr3_DM[1]}] # PadFunction: IO_L10N_T1_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[2]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[2]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[2]}] set_property LOC F12 [get_ports {pins_ddr3_DM[2]}] # PadFunction: IO_L2N_T0_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[3]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[3]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[3]}] set_property LOC A14 [get_ports {pins_ddr3_DM[3]}] # PadFunction: IO_L4P_T0_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[4]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[4]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[4]}] set_property LOC C23 [get_ports {pins_ddr3_DM[4]}] # PadFunction: IO_L11P_T1_SRCC_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[5]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[5]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[5]}] set_property LOC D25 [get_ports {pins_ddr3_DM[5]}] # PadFunction: IO_L18P_T2_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[6]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[6]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[6]}] set_property LOC C31 [get_ports {pins_ddr3_DM[6]}] # PadFunction: IO_L24N_T3_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DM[7]}] set_property SLEW FAST [get_ports {pins_ddr3_DM[7]}] set_property IOSTANDARD SSTL15 [get_ports {pins_ddr3_DM[7]}] set_property LOC F31 [get_ports {pins_ddr3_DM[7]}] # PadFunction: IO_L21P_T3_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[0]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[0]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[0]}] set_property LOC N16 [get_ports {pins_ddr3_DQS_P[0]}] # PadFunction: IO_L21N_T3_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[0]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[0]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[0]}] set_property LOC M16 [get_ports {pins_ddr3_DQS_N[0]}] # PadFunction: IO_L15P_T2_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[1]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[1]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[1]}] set_property LOC K12 [get_ports {pins_ddr3_DQS_P[1]}] # PadFunction: IO_L15N_T2_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[1]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[1]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[1]}] set_property LOC J12 [get_ports {pins_ddr3_DQS_N[1]}] # PadFunction: IO_L9P_T1_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[2]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[2]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[2]}] set_property LOC H16 [get_ports {pins_ddr3_DQS_P[2]}] # PadFunction: IO_L9N_T1_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[2]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[2]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[2]}] set_property LOC G16 [get_ports {pins_ddr3_DQS_N[2]}] # PadFunction: IO_L3P_T0_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[3]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[3]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[3]}] set_property LOC C15 [get_ports {pins_ddr3_DQS_P[3]}] # PadFunction: IO_L3N_T0_DQS_39 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[3]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[3]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[3]}] set_property LOC C14 [get_ports {pins_ddr3_DQS_N[3]}] # PadFunction: IO_L3P_T0_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[4]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[4]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[4]}] set_property LOC A26 [get_ports {pins_ddr3_DQS_P[4]}] # PadFunction: IO_L3N_T0_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[4]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[4]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[4]}] set_property LOC A27 [get_ports {pins_ddr3_DQS_N[4]}] # PadFunction: IO_L9P_T1_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[5]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[5]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[5]}] set_property LOC F25 [get_ports {pins_ddr3_DQS_P[5]}] # PadFunction: IO_L9N_T1_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[5]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[5]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[5]}] set_property LOC E25 [get_ports {pins_ddr3_DQS_N[5]}] # PadFunction: IO_L15P_T2_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[6]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[6]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[6]}] set_property LOC B28 [get_ports {pins_ddr3_DQS_P[6]}] # PadFunction: IO_L15N_T2_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[6]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[6]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[6]}] set_property LOC B29 [get_ports {pins_ddr3_DQS_N[6]}] # PadFunction: IO_L21P_T3_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_P[7]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_P[7]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_P[7]}] set_property LOC E27 [get_ports {pins_ddr3_DQS_P[7]}] # PadFunction: IO_L21N_T3_DQS_37 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_DQS_N[7]}] set_property SLEW FAST [get_ports {pins_ddr3_DQS_N[7]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {pins_ddr3_DQS_N[7]}] set_property LOC E28 [get_ports {pins_ddr3_DQS_N[7]}] # PadFunction: IO_L13P_T2_MRCC_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_CLK_P}] set_property SLEW FAST [get_ports {pins_ddr3_CLK_P}] set_property IOSTANDARD DIFF_SSTL15 [get_ports {pins_ddr3_CLK_P}] set_property LOC H19 [get_ports {pins_ddr3_CLK_P}] # PadFunction: IO_L13N_T2_MRCC_38 set_property VCCAUX_IO NORMAL [get_ports {pins_ddr3_CLK_N}] set_property SLEW FAST [get_ports {pins_ddr3_CLK_N}] set_property IOSTANDARD DIFF_SSTL15 [get_ports {pins_ddr3_CLK_N}] set_property LOC G18 [get_ports {pins_ddr3_CLK_N}] set_property LOC PHASER_OUT_PHY_X1Y19 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y18 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y17 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y16 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y23 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y22 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y21 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y27 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y26 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y25 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/phaser_out}] set_property LOC PHASER_OUT_PHY_X1Y24 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/phaser_out}] set_property LOC PHASER_IN_PHY_X1Y19 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y18 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y17 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y16 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/phaser_in_gen.phaser_in}] ## set_property LOC PHASER_IN_PHY_X1Y23 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/phaser_in_gen.phaser_in}] ## set_property LOC PHASER_IN_PHY_X1Y22 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/phaser_in_gen.phaser_in}] ## set_property LOC PHASER_IN_PHY_X1Y21 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y27 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y26 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y25 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/phaser_in_gen.phaser_in}] set_property LOC PHASER_IN_PHY_X1Y24 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/phaser_in_gen.phaser_in}] set_property LOC OUT_FIFO_X1Y19 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/out_fifo}] set_property LOC OUT_FIFO_X1Y18 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/out_fifo}] set_property LOC OUT_FIFO_X1Y17 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/out_fifo}] set_property LOC OUT_FIFO_X1Y16 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/out_fifo}] set_property LOC OUT_FIFO_X1Y23 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/out_fifo}] set_property LOC OUT_FIFO_X1Y22 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/out_fifo}] set_property LOC OUT_FIFO_X1Y21 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/out_fifo}] set_property LOC OUT_FIFO_X1Y27 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/out_fifo}] set_property LOC OUT_FIFO_X1Y26 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/out_fifo}] set_property LOC OUT_FIFO_X1Y25 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/out_fifo}] set_property LOC OUT_FIFO_X1Y24 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/out_fifo}] set_property LOC IN_FIFO_X1Y19 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y18 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y17 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y16 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y27 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y26 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y25 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/in_fifo_gen.in_fifo}] set_property LOC IN_FIFO_X1Y24 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/in_fifo_gen.in_fifo}] set_property LOC PHY_CONTROL_X1Y4 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/phy_control_i}] set_property LOC PHY_CONTROL_X1Y5 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/phy_control_i}] set_property LOC PHY_CONTROL_X1Y6 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/phy_control_i}] set_property LOC PHASER_REF_X1Y4 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/phaser_ref_i}] set_property LOC PHASER_REF_X1Y5 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_1.u_ddr_phy_4lanes/phaser_ref_i}] set_property LOC PHASER_REF_X1Y6 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/phaser_ref_i}] set_property LOC OLOGIC_X1Y243 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y231 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y219 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y207 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_2.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y343 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_D.ddr_byte_lane_D/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y331 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_C.ddr_byte_lane_C/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y319 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_B.ddr_byte_lane_B/ddr_byte_group_io/*slave_ts}] set_property LOC OLOGIC_X1Y307 [get_cells -hier -filter {NAME =~ */ddr_phy_4lanes_0.u_ddr_phy_4lanes/ddr_byte_lane_A.ddr_byte_lane_A/ddr_byte_group_io/*slave_ts}] set_property LOC PLLE2_ADV_X1Y5 [get_cells -hier -filter { NAME =~ */u_ddr3_infrastructure/plle2_i }] set_property LOC MMCME2_ADV_X1Y6 [get_cells -hier -filter { NAME =~ */u_ddr3_infrastructure/mmcm_i }] ###################################################################################################### # AREA GROUPS ###################################################################################################### startgroup create_pblock pblock_ddr3 resize_pblock pblock_ddr3 -add { SLICE_X120Y200:SLICE_X220Y360 DSP48_X13Y82:DSP48_X19Y137 RAMB18_X9Y82:RAMB18_X13Y137 RAMB36_X9Y41:RAMB36_X13Y68 } #resize_pblock pblock_ddr3 -add { SLICE_X146Y201:SLICE_X205Y348 DSP48_X13Y82:DSP48_X19Y137 RAMB18_X9Y82:RAMB18_X13Y137 RAMB36_X9Y41:RAMB36_X13Y68 } add_cells_to_pblock pblock_ddr3 [get_cells [list */top_ddr3* ]] #add_cells_to_pblock pblock_ddr3 [get_cells [list */top_dramController* ]] #add_cells_to_pblock pblock_ddr3 [get_cells [list ddr3* ]] endgroup ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### create_clock -name top_x7pcie_sys_clk_200mhz -period 5 [get_pins *sys_clk_200mhz/O] create_generated_clock -name ddr3_refclk -source [get_pins *sys_clk_200mhz_buf/O] -divide_by 1 [get_pins */top_clk_gen_pll/CLKOUT1] create_generated_clock -name ddr3_usrclk -source [get_pins *sys_clk_200mhz_buf/O] -multiply_by 5 -divide_by 10 [get_pins */top_clk_gen_pll/CLKOUT0] #create_generated_clock -name ddr3_refclk -source [get_pins sys_clk/O] -divide_by 1 [get_pins clk_gen_pll/CLKOUT1] set_multicycle_path -from [get_cells -hier -filter {NAME =~ */mc0/mc_read_idle_r_reg}] \ -to [get_cells -hier -filter {NAME =~ */input_[?].iserdes_dq_.iserdesdq}] \ -setup 6 set_multicycle_path -from [get_cells -hier -filter {NAME =~ */mc0/mc_read_idle_r_reg}] \ -to [get_cells -hier -filter {NAME =~ */input_[?].iserdes_dq_.iserdesdq}] \ -hold 5 set_false_path -through [get_pins -filter {NAME =~ */DQSFOUND} -of [get_cells -hier -filter {REF_NAME == PHASER_IN_PHY}]] set_multicycle_path -through [get_pins -filter {NAME =~ */OSERDESRST} -of [get_cells -hier -filter {REF_NAME == PHASER_OUT_PHY}]] -setup 2 -start set_multicycle_path -through [get_pins -filter {NAME =~ */OSERDESRST} -of [get_cells -hier -filter {REF_NAME == PHASER_OUT_PHY}]] -hold 1 -start set_multicycle_path -to [get_cells -hier -filter {NAME =~ */temp_mon_enabled.u_mig_7series_v1_7_tempmon/device_temp_sync_r1*}] \ -setup 12 -end set_multicycle_path -to [get_cells -hier -filter {NAME =~ */temp_mon_enabled.u_mig_7series_v1_7_tempmon/device_temp_sync_r1*}] \ -hold 11 -end set_multicycle_path -to [get_cells -hier -filter {NAME =~ */temp_mon_enabled.u_mig_7series_v1_7_tempmon/rst_r1*}] \ -setup 2 -end set_multicycle_path -to [get_cells -hier -filter {NAME =~ */temp_mon_enabled.u_mig_7series_v1_7_tempmon/rst_r1*}] \ -hold 1 -end #set_max_delay -from [get_clocks uclock] -to [get_clocks clk_pll_i] 20.000 -datapath_only #set_max_delay -from [get_clocks uclock] -to [get_clocks clk_pll_i_1] 20.000 -datapath_only ================================================ FILE: constraints/xilinx/vc707_ddr3_pins.xdc ================================================ ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### # PadFunction: IO_L23N_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[0]}] set_property SLEW FAST [get_ports {ddr3_dq[0]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[0]}] set_property LOC N14 [get_ports {ddr3_dq[0]}] # PadFunction: IO_L22P_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[1]}] set_property SLEW FAST [get_ports {ddr3_dq[1]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[1]}] set_property LOC N13 [get_ports {ddr3_dq[1]}] # PadFunction: IO_L20N_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[2]}] set_property SLEW FAST [get_ports {ddr3_dq[2]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[2]}] set_property LOC L14 [get_ports {ddr3_dq[2]}] # PadFunction: IO_L20P_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[3]}] set_property SLEW FAST [get_ports {ddr3_dq[3]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[3]}] set_property LOC M14 [get_ports {ddr3_dq[3]}] # PadFunction: IO_L24P_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[4]}] set_property SLEW FAST [get_ports {ddr3_dq[4]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[4]}] set_property LOC M12 [get_ports {ddr3_dq[4]}] # PadFunction: IO_L23P_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[5]}] set_property SLEW FAST [get_ports {ddr3_dq[5]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[5]}] set_property LOC N15 [get_ports {ddr3_dq[5]}] # PadFunction: IO_L24N_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[6]}] set_property SLEW FAST [get_ports {ddr3_dq[6]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[6]}] set_property LOC M11 [get_ports {ddr3_dq[6]}] # PadFunction: IO_L19P_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[7]}] set_property SLEW FAST [get_ports {ddr3_dq[7]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[7]}] set_property LOC L12 [get_ports {ddr3_dq[7]}] # PadFunction: IO_L17P_T2_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[8]}] set_property SLEW FAST [get_ports {ddr3_dq[8]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[8]}] set_property LOC K14 [get_ports {ddr3_dq[8]}] # PadFunction: IO_L17N_T2_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[9]}] set_property SLEW FAST [get_ports {ddr3_dq[9]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[9]}] set_property LOC K13 [get_ports {ddr3_dq[9]}] # PadFunction: IO_L14N_T2_SRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[10]}] set_property SLEW FAST [get_ports {ddr3_dq[10]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[10]}] set_property LOC H13 [get_ports {ddr3_dq[10]}] # PadFunction: IO_L14P_T2_SRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[11]}] set_property SLEW FAST [get_ports {ddr3_dq[11]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[11]}] set_property LOC J13 [get_ports {ddr3_dq[11]}] # PadFunction: IO_L18P_T2_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[12]}] set_property SLEW FAST [get_ports {ddr3_dq[12]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[12]}] set_property LOC L16 [get_ports {ddr3_dq[12]}] # PadFunction: IO_L18N_T2_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[13]}] set_property SLEW FAST [get_ports {ddr3_dq[13]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[13]}] set_property LOC L15 [get_ports {ddr3_dq[13]}] # PadFunction: IO_L13N_T2_MRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[14]}] set_property SLEW FAST [get_ports {ddr3_dq[14]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[14]}] set_property LOC H14 [get_ports {ddr3_dq[14]}] # PadFunction: IO_L16N_T2_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[15]}] set_property SLEW FAST [get_ports {ddr3_dq[15]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[15]}] set_property LOC J15 [get_ports {ddr3_dq[15]}] # PadFunction: IO_L7N_T1_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[16]}] set_property SLEW FAST [get_ports {ddr3_dq[16]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[16]}] set_property LOC E15 [get_ports {ddr3_dq[16]}] # PadFunction: IO_L8N_T1_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[17]}] set_property SLEW FAST [get_ports {ddr3_dq[17]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[17]}] set_property LOC E13 [get_ports {ddr3_dq[17]}] # PadFunction: IO_L11P_T1_SRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[18]}] set_property SLEW FAST [get_ports {ddr3_dq[18]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[18]}] set_property LOC F15 [get_ports {ddr3_dq[18]}] # PadFunction: IO_L8P_T1_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[19]}] set_property SLEW FAST [get_ports {ddr3_dq[19]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[19]}] set_property LOC E14 [get_ports {ddr3_dq[19]}] # PadFunction: IO_L12N_T1_MRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[20]}] set_property SLEW FAST [get_ports {ddr3_dq[20]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[20]}] set_property LOC G13 [get_ports {ddr3_dq[20]}] # PadFunction: IO_L10P_T1_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[21]}] set_property SLEW FAST [get_ports {ddr3_dq[21]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[21]}] set_property LOC G12 [get_ports {ddr3_dq[21]}] # PadFunction: IO_L11N_T1_SRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[22]}] set_property SLEW FAST [get_ports {ddr3_dq[22]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[22]}] set_property LOC F14 [get_ports {ddr3_dq[22]}] # PadFunction: IO_L12P_T1_MRCC_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[23]}] set_property SLEW FAST [get_ports {ddr3_dq[23]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[23]}] set_property LOC G14 [get_ports {ddr3_dq[23]}] # PadFunction: IO_L2P_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[24]}] set_property SLEW FAST [get_ports {ddr3_dq[24]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[24]}] set_property LOC B14 [get_ports {ddr3_dq[24]}] # PadFunction: IO_L4N_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[25]}] set_property SLEW FAST [get_ports {ddr3_dq[25]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[25]}] set_property LOC C13 [get_ports {ddr3_dq[25]}] # PadFunction: IO_L1N_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[26]}] set_property SLEW FAST [get_ports {ddr3_dq[26]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[26]}] set_property LOC B16 [get_ports {ddr3_dq[26]}] # PadFunction: IO_L5N_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[27]}] set_property SLEW FAST [get_ports {ddr3_dq[27]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[27]}] set_property LOC D15 [get_ports {ddr3_dq[27]}] # PadFunction: IO_L4P_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[28]}] set_property SLEW FAST [get_ports {ddr3_dq[28]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[28]}] set_property LOC D13 [get_ports {ddr3_dq[28]}] # PadFunction: IO_L6P_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[29]}] set_property SLEW FAST [get_ports {ddr3_dq[29]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[29]}] set_property LOC E12 [get_ports {ddr3_dq[29]}] # PadFunction: IO_L1P_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[30]}] set_property SLEW FAST [get_ports {ddr3_dq[30]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[30]}] set_property LOC C16 [get_ports {ddr3_dq[30]}] # PadFunction: IO_L5P_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[31]}] set_property SLEW FAST [get_ports {ddr3_dq[31]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[31]}] set_property LOC D16 [get_ports {ddr3_dq[31]}] # PadFunction: IO_L1P_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[32]}] set_property SLEW FAST [get_ports {ddr3_dq[32]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[32]}] set_property LOC A24 [get_ports {ddr3_dq[32]}] # PadFunction: IO_L4N_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[33]}] set_property SLEW FAST [get_ports {ddr3_dq[33]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[33]}] set_property LOC B23 [get_ports {ddr3_dq[33]}] # PadFunction: IO_L5N_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[34]}] set_property SLEW FAST [get_ports {ddr3_dq[34]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[34]}] set_property LOC B27 [get_ports {ddr3_dq[34]}] # PadFunction: IO_L5P_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[35]}] set_property SLEW FAST [get_ports {ddr3_dq[35]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[35]}] set_property LOC B26 [get_ports {ddr3_dq[35]}] # PadFunction: IO_L2N_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[36]}] set_property SLEW FAST [get_ports {ddr3_dq[36]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[36]}] set_property LOC A22 [get_ports {ddr3_dq[36]}] # PadFunction: IO_L2P_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[37]}] set_property SLEW FAST [get_ports {ddr3_dq[37]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[37]}] set_property LOC B22 [get_ports {ddr3_dq[37]}] # PadFunction: IO_L1N_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[38]}] set_property SLEW FAST [get_ports {ddr3_dq[38]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[38]}] set_property LOC A25 [get_ports {ddr3_dq[38]}] # PadFunction: IO_L6P_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[39]}] set_property SLEW FAST [get_ports {ddr3_dq[39]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[39]}] set_property LOC C24 [get_ports {ddr3_dq[39]}] # PadFunction: IO_L7N_T1_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[40]}] set_property SLEW FAST [get_ports {ddr3_dq[40]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[40]}] set_property LOC E24 [get_ports {ddr3_dq[40]}] # PadFunction: IO_L10N_T1_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[41]}] set_property SLEW FAST [get_ports {ddr3_dq[41]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[41]}] set_property LOC D23 [get_ports {ddr3_dq[41]}] # PadFunction: IO_L11N_T1_SRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[42]}] set_property SLEW FAST [get_ports {ddr3_dq[42]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[42]}] set_property LOC D26 [get_ports {ddr3_dq[42]}] # PadFunction: IO_L12P_T1_MRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[43]}] set_property SLEW FAST [get_ports {ddr3_dq[43]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[43]}] set_property LOC C25 [get_ports {ddr3_dq[43]}] # PadFunction: IO_L7P_T1_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[44]}] set_property SLEW FAST [get_ports {ddr3_dq[44]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[44]}] set_property LOC E23 [get_ports {ddr3_dq[44]}] # PadFunction: IO_L10P_T1_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[45]}] set_property SLEW FAST [get_ports {ddr3_dq[45]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[45]}] set_property LOC D22 [get_ports {ddr3_dq[45]}] # PadFunction: IO_L8P_T1_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[46]}] set_property SLEW FAST [get_ports {ddr3_dq[46]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[46]}] set_property LOC F22 [get_ports {ddr3_dq[46]}] # PadFunction: IO_L8N_T1_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[47]}] set_property SLEW FAST [get_ports {ddr3_dq[47]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[47]}] set_property LOC E22 [get_ports {ddr3_dq[47]}] # PadFunction: IO_L17N_T2_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[48]}] set_property SLEW FAST [get_ports {ddr3_dq[48]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[48]}] set_property LOC A30 [get_ports {ddr3_dq[48]}] # PadFunction: IO_L13P_T2_MRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[49]}] set_property SLEW FAST [get_ports {ddr3_dq[49]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[49]}] set_property LOC D27 [get_ports {ddr3_dq[49]}] # PadFunction: IO_L17P_T2_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[50]}] set_property SLEW FAST [get_ports {ddr3_dq[50]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[50]}] set_property LOC A29 [get_ports {ddr3_dq[50]}] # PadFunction: IO_L14P_T2_SRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[51]}] set_property SLEW FAST [get_ports {ddr3_dq[51]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[51]}] set_property LOC C28 [get_ports {ddr3_dq[51]}] # PadFunction: IO_L13N_T2_MRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[52]}] set_property SLEW FAST [get_ports {ddr3_dq[52]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[52]}] set_property LOC D28 [get_ports {ddr3_dq[52]}] # PadFunction: IO_L18N_T2_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[53]}] set_property SLEW FAST [get_ports {ddr3_dq[53]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[53]}] set_property LOC B31 [get_ports {ddr3_dq[53]}] # PadFunction: IO_L16P_T2_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[54]}] set_property SLEW FAST [get_ports {ddr3_dq[54]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[54]}] set_property LOC A31 [get_ports {ddr3_dq[54]}] # PadFunction: IO_L16N_T2_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[55]}] set_property SLEW FAST [get_ports {ddr3_dq[55]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[55]}] set_property LOC A32 [get_ports {ddr3_dq[55]}] # PadFunction: IO_L19P_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[56]}] set_property SLEW FAST [get_ports {ddr3_dq[56]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[56]}] set_property LOC E30 [get_ports {ddr3_dq[56]}] # PadFunction: IO_L22P_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[57]}] set_property SLEW FAST [get_ports {ddr3_dq[57]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[57]}] set_property LOC F29 [get_ports {ddr3_dq[57]}] # PadFunction: IO_L24P_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[58]}] set_property SLEW FAST [get_ports {ddr3_dq[58]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[58]}] set_property LOC F30 [get_ports {ddr3_dq[58]}] # PadFunction: IO_L23N_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[59]}] set_property SLEW FAST [get_ports {ddr3_dq[59]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[59]}] set_property LOC F27 [get_ports {ddr3_dq[59]}] # PadFunction: IO_L20N_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[60]}] set_property SLEW FAST [get_ports {ddr3_dq[60]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[60]}] set_property LOC C30 [get_ports {ddr3_dq[60]}] # PadFunction: IO_L22N_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[61]}] set_property SLEW FAST [get_ports {ddr3_dq[61]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[61]}] set_property LOC E29 [get_ports {ddr3_dq[61]}] # PadFunction: IO_L23P_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[62]}] set_property SLEW FAST [get_ports {ddr3_dq[62]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[62]}] set_property LOC F26 [get_ports {ddr3_dq[62]}] # PadFunction: IO_L20P_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[63]}] set_property SLEW FAST [get_ports {ddr3_dq[63]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[63]}] set_property LOC D30 [get_ports {ddr3_dq[63]}] #set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[15]}] #set_property SLEW FAST [get_ports {ddr3_addr[15]}] #set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[15]}] #set_property LOC E17 [get_ports {ddr3_addr[15]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[14]}] set_property SLEW FAST [get_ports {ddr3_addr[14]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[14]}] set_property LOC F17 [get_ports {ddr3_addr[14]}] # PadFunction: IO_L5N_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[13]}] set_property SLEW FAST [get_ports {ddr3_addr[13]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[13]}] set_property LOC A21 [get_ports {ddr3_addr[13]}] # PadFunction: IO_L2N_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[12]}] set_property SLEW FAST [get_ports {ddr3_addr[12]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[12]}] set_property LOC A15 [get_ports {ddr3_addr[12]}] # PadFunction: IO_L4P_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[11]}] set_property SLEW FAST [get_ports {ddr3_addr[11]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[11]}] set_property LOC B17 [get_ports {ddr3_addr[11]}] # PadFunction: IO_L5P_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[10]}] set_property SLEW FAST [get_ports {ddr3_addr[10]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[10]}] set_property LOC B21 [get_ports {ddr3_addr[10]}] # PadFunction: IO_L1P_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[9]}] set_property SLEW FAST [get_ports {ddr3_addr[9]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[9]}] set_property LOC C19 [get_ports {ddr3_addr[9]}] # PadFunction: IO_L10N_T1_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[8]}] set_property SLEW FAST [get_ports {ddr3_addr[8]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[8]}] set_property LOC D17 [get_ports {ddr3_addr[8]}] # PadFunction: IO_L6P_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[7]}] set_property SLEW FAST [get_ports {ddr3_addr[7]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[7]}] set_property LOC C18 [get_ports {ddr3_addr[7]}] # PadFunction: IO_L7P_T1_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[6]}] set_property SLEW FAST [get_ports {ddr3_addr[6]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[6]}] set_property LOC D20 [get_ports {ddr3_addr[6]}] # PadFunction: IO_L2P_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[5]}] set_property SLEW FAST [get_ports {ddr3_addr[5]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[5]}] set_property LOC A16 [get_ports {ddr3_addr[5]}] # PadFunction: IO_L4N_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[4]}] set_property SLEW FAST [get_ports {ddr3_addr[4]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[4]}] set_property LOC A17 [get_ports {ddr3_addr[4]}] # PadFunction: IO_L3N_T0_DQS_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[3]}] set_property SLEW FAST [get_ports {ddr3_addr[3]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[3]}] set_property LOC A19 [get_ports {ddr3_addr[3]}] # PadFunction: IO_L7N_T1_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[2]}] set_property SLEW FAST [get_ports {ddr3_addr[2]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[2]}] set_property LOC C20 [get_ports {ddr3_addr[2]}] # PadFunction: IO_L1N_T0_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[1]}] set_property SLEW FAST [get_ports {ddr3_addr[1]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[1]}] set_property LOC B19 [get_ports {ddr3_addr[1]}] # PadFunction: IO_L3P_T0_DQS_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[0]}] set_property SLEW FAST [get_ports {ddr3_addr[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[0]}] set_property LOC A20 [get_ports {ddr3_addr[0]}] # PadFunction: IO_L10P_T1_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_ba[2]}] set_property SLEW FAST [get_ports {ddr3_ba[2]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[2]}] set_property LOC D18 [get_ports {ddr3_ba[2]}] # PadFunction: IO_L9N_T1_DQS_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_ba[1]}] set_property SLEW FAST [get_ports {ddr3_ba[1]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[1]}] set_property LOC C21 [get_ports {ddr3_ba[1]}] # PadFunction: IO_L9P_T1_DQS_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_ba[0]}] set_property SLEW FAST [get_ports {ddr3_ba[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[0]}] set_property LOC D21 [get_ports {ddr3_ba[0]}] # PadFunction: IO_L15N_T2_DQS_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_ras_n}] set_property SLEW FAST [get_ports {ddr3_ras_n}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ras_n}] set_property LOC E20 [get_ports {ddr3_ras_n}] # PadFunction: IO_L16P_T2_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_cas_n}] set_property SLEW FAST [get_ports {ddr3_cas_n}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_cas_n}] set_property LOC K17 [get_ports {ddr3_cas_n}] # PadFunction: IO_L15P_T2_DQS_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_we_n}] set_property SLEW FAST [get_ports {ddr3_we_n}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_we_n}] set_property LOC F20 [get_ports {ddr3_we_n}] # PadFunction: IO_L14N_T2_SRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_reset_n}] set_property SLEW FAST [get_ports {ddr3_reset_n}] set_property IOSTANDARD LVCMOS15 [get_ports {ddr3_reset_n}] set_property LOC C29 [get_ports {ddr3_reset_n}] # PadFunction: IO_L14P_T2_SRCC_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_cke[0]}] set_property SLEW FAST [get_ports {ddr3_cke[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_cke[0]}] set_property LOC K19 [get_ports {ddr3_cke[0]}] # PadFunction: IO_L17N_T2_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_odt[0]}] set_property SLEW FAST [get_ports {ddr3_odt[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_odt[0]}] set_property LOC H20 [get_ports {ddr3_odt[0]}] # PadFunction: IO_L16N_T2_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_cs_n[0]}] set_property SLEW FAST [get_ports {ddr3_cs_n[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_cs_n[0]}] set_property LOC J17 [get_ports {ddr3_cs_n[0]}] # PadFunction: IO_L22N_T3_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[0]}] set_property SLEW FAST [get_ports {ddr3_dm[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[0]}] set_property LOC M13 [get_ports {ddr3_dm[0]}] # PadFunction: IO_L16P_T2_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[1]}] set_property SLEW FAST [get_ports {ddr3_dm[1]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[1]}] set_property LOC K15 [get_ports {ddr3_dm[1]}] # PadFunction: IO_L10N_T1_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[2]}] set_property SLEW FAST [get_ports {ddr3_dm[2]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[2]}] set_property LOC F12 [get_ports {ddr3_dm[2]}] # PadFunction: IO_L2N_T0_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[3]}] set_property SLEW FAST [get_ports {ddr3_dm[3]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[3]}] set_property LOC A14 [get_ports {ddr3_dm[3]}] # PadFunction: IO_L4P_T0_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[4]}] set_property SLEW FAST [get_ports {ddr3_dm[4]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[4]}] set_property LOC C23 [get_ports {ddr3_dm[4]}] # PadFunction: IO_L11P_T1_SRCC_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[5]}] set_property SLEW FAST [get_ports {ddr3_dm[5]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[5]}] set_property LOC D25 [get_ports {ddr3_dm[5]}] # PadFunction: IO_L18P_T2_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[6]}] set_property SLEW FAST [get_ports {ddr3_dm[6]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[6]}] set_property LOC C31 [get_ports {ddr3_dm[6]}] # PadFunction: IO_L24N_T3_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[7]}] set_property SLEW FAST [get_ports {ddr3_dm[7]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[7]}] set_property LOC F31 [get_ports {ddr3_dm[7]}] # PadFunction: IO_L21P_T3_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[0]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[0]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[0]}] set_property LOC N16 [get_ports {ddr3_dqs_p[0]}] # PadFunction: IO_L21N_T3_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[0]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[0]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[0]}] set_property LOC M16 [get_ports {ddr3_dqs_n[0]}] # PadFunction: IO_L15P_T2_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[1]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[1]}] set_property LOC K12 [get_ports {ddr3_dqs_p[1]}] # PadFunction: IO_L15N_T2_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[1]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[1]}] set_property LOC J12 [get_ports {ddr3_dqs_n[1]}] # PadFunction: IO_L9P_T1_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[2]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[2]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[2]}] set_property LOC H16 [get_ports {ddr3_dqs_p[2]}] # PadFunction: IO_L9N_T1_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[2]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[2]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[2]}] set_property LOC G16 [get_ports {ddr3_dqs_n[2]}] # PadFunction: IO_L3P_T0_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[3]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[3]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[3]}] set_property LOC C15 [get_ports {ddr3_dqs_p[3]}] # PadFunction: IO_L3N_T0_DQS_39 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[3]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[3]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[3]}] set_property LOC C14 [get_ports {ddr3_dqs_n[3]}] # PadFunction: IO_L3P_T0_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[4]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[4]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[4]}] set_property LOC A26 [get_ports {ddr3_dqs_p[4]}] # PadFunction: IO_L3N_T0_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[4]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[4]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[4]}] set_property LOC A27 [get_ports {ddr3_dqs_n[4]}] # PadFunction: IO_L9P_T1_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[5]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[5]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[5]}] set_property LOC F25 [get_ports {ddr3_dqs_p[5]}] # PadFunction: IO_L9N_T1_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[5]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[5]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[5]}] set_property LOC E25 [get_ports {ddr3_dqs_n[5]}] # PadFunction: IO_L15P_T2_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[6]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[6]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[6]}] set_property LOC B28 [get_ports {ddr3_dqs_p[6]}] # PadFunction: IO_L15N_T2_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[6]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[6]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[6]}] set_property LOC B29 [get_ports {ddr3_dqs_n[6]}] # PadFunction: IO_L21P_T3_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[7]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[7]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[7]}] set_property LOC E27 [get_ports {ddr3_dqs_p[7]}] # PadFunction: IO_L21N_T3_DQS_37 set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[7]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[7]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[7]}] set_property LOC E28 [get_ports {ddr3_dqs_n[7]}] # PadFunction: IO_L13P_T2_MRCC_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_ck_p[0]}] set_property SLEW FAST [get_ports {ddr3_ck_p[0]}] set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_ck_p[0]}] set_property LOC H19 [get_ports {ddr3_ck_p[0]}] # PadFunction: IO_L13N_T2_MRCC_38 set_property VCCAUX_IO HIGH [get_ports {ddr3_ck_n[0]}] set_property SLEW FAST [get_ports {ddr3_ck_n[0]}] set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_ck_n[0]}] set_property LOC G18 [get_ports {ddr3_ck_n[0]}] ================================================ FILE: constraints/xilinx/vc707g2-axiddr3.prj ================================================ mig_7series_0 1 1 OFF 1024 ON Enabled xc7vx485t-ffg1761/-2 2.3 No Buffer Use System Clock ACTIVE LOW FALSE 0 50 Ohms 0 DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 1250 2.0V 4:1 200 0 800 1.000 1 1 1 1 64 1 1 Disabled Normal FALSE 14 10 3 1.5V BANK_ROW_COLUMN 8 - Fixed Sequential 11 Normal No Slow Exit Enable RZQ/7 Disable Enable RZQ/4 0 Disabled Enabled Output Buffer Enabled Full Array 8 Enabled Normal Dynamic ODT off AXI RD_PRI_REG 30 512 6 0 ================================================ FILE: constraints/xilinx/vc707g2.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: virtex7 ## FPGA: xc7vx485t-2ffg1761C ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AD8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC AD7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AV35 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC E19 [get_ports { CLK_sys_clk_p }] set_property LOC E18 [get_ports { CLK_sys_clk_n }] set_property LOC Y4 [get_ports { PCIE_rxp_v[0] }] set_property LOC AA6 [get_ports { PCIE_rxp_v[1] }] set_property LOC AB4 [get_ports { PCIE_rxp_v[2] }] set_property LOC AC6 [get_ports { PCIE_rxp_v[3] }] set_property LOC AD4 [get_ports { PCIE_rxp_v[4] }] set_property LOC AE6 [get_ports { PCIE_rxp_v[5] }] set_property LOC AF4 [get_ports { PCIE_rxp_v[6] }] set_property LOC AG6 [get_ports { PCIE_rxp_v[7] }] set_property LOC Y3 [get_ports { PCIE_rxn_v[0] }] set_property LOC AA5 [get_ports { PCIE_rxn_v[1] }] set_property LOC AB3 [get_ports { PCIE_rxn_v[2] }] set_property LOC AC5 [get_ports { PCIE_rxn_v[3] }] set_property LOC AD3 [get_ports { PCIE_rxn_v[4] }] set_property LOC AE5 [get_ports { PCIE_rxn_v[5] }] set_property LOC AF3 [get_ports { PCIE_rxn_v[6] }] set_property LOC AG5 [get_ports { PCIE_rxn_v[7] }] set_property LOC W2 [get_ports { PCIE_txp[0] }] set_property LOC AA2 [get_ports { PCIE_txp[1] }] set_property LOC AC2 [get_ports { PCIE_txp[2] }] set_property LOC AE2 [get_ports { PCIE_txp[3] }] set_property LOC AG2 [get_ports { PCIE_txp[4] }] set_property LOC AH4 [get_ports { PCIE_txp[5] }] set_property LOC AJ2 [get_ports { PCIE_txp[6] }] set_property LOC AK4 [get_ports { PCIE_txp[7] }] set_property LOC W1 [get_ports { PCIE_txn[0] }] set_property LOC AA1 [get_ports { PCIE_txn[1] }] set_property LOC AC1 [get_ports { PCIE_txn[2] }] set_property LOC AE1 [get_ports { PCIE_txn[3] }] set_property LOC AG1 [get_ports { PCIE_txn[4] }] set_property LOC AH3 [get_ports { PCIE_txn[5] }] set_property LOC AJ1 [get_ports { PCIE_txn[6] }] set_property LOC AK3 [get_ports { PCIE_txn[7] }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] set_property IOSTANDARD LVCMOS18 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # CELL LOCATIONS ###################################################################################################### # # SYS clock 100 MHz (input) signal. The sys_clk_p and sys_clk_n # signals are the PCI Express reference clock. Virtex-7 GT # Transceiver architecture requires the use of a dedicated clock # resources (FPGA input pins) associated with each GT Transceiver. # To use these pins an IBUFDS primitive (refclk_ibuf) is # instantiated in user's design. # Please refer to the Virtex-7 GT Transceiver User Guide # (UG) for guidelines regarding clock resource selection. # set_property LOC IBUFDS_GTE2_X1Y5 [get_cells { host_pcieHostTop_clockGen }] set_property LOC MMCME2_ADV_X1Y1 [get_cells -hier -filter { NAME =~ *clkgen_pll }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/vc709.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: virtex7 ## FPGA: xc7vx690t-3ffg1761C ## Speedgrade: -3 ## ###################################################################################################### ##The following two properties should be set for every design set_property CFGBVS GND [current_design] set_property CONFIG_VOLTAGE 1.8 [current_design] ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AB7 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AB8 [get_ports { CLK_pci_sys_clk_p }] set_property LOC AV35 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC H19 [get_ports { CLK_sys_clk_p }] set_property LOC G18 [get_ports { CLK_sys_clk_n }] ###################################################################################################### # I/O STANDARDS ###################################################################################################### set_property IOSTANDARD LVCMOS15 [get_ports { leds_leds[*] }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] set_property IOSTANDARD LVCMOS18 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ###################################################################################################### # TIMING CONSTRAINTS ###################################################################################################### ## in pcie-clocks.xdc ================================================ FILE: constraints/xilinx/vcu108.xdc ================================================ ###################################################################################################### ## File name : default.xdc ## ## Details : Constraints file ## FPGA family: virtex7 ## FPGA: xc7vx485t-2ffg1761C ## Speedgrade: -2 ## ###################################################################################################### ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property LOC AL9 [get_ports { CLK_pci_sys_clk_p }] set_property LOC AL8 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AM17 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC G31 [get_ports { CLK_sys_clk1_300_p }] set_property LOC F31 [get_ports { CLK_sys_clk1_300_n }] set_property LOC G22 [get_ports { CLK_sys_clk2_300_p }] set_property LOC G21 [get_ports { CLK_sys_clk2_300_n }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk1_300_p }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk1_300_n }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk2_300_p }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk2_300_n }] set_property IOSTANDARD LVCMOS18 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ================================================ FILE: constraints/xilinx/vcu118.xdc ================================================ ###################################################################################################### ## File name : vcu118.xdc ## ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### #set_property LOC AL9 [get_ports { CLK_pci_sys_clk_p }] #set_property LOC AL8 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AC9 [get_ports { CLK_pci_sys_clk_p }] set_property LOC AC8 [get_ports { CLK_pci_sys_clk_n }] set_property LOC AM17 [get_ports { RST_N_pci_sys_reset_n }] set_property LOC G31 [get_ports { CLK_sys_clk_300_p }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk_300_p }] set_property LOC F31 [get_ports { CLK_sys_clk_300_n }] set_property IOSTANDARD DIFF_SSTL12 [get_ports { CLK_sys_clk_300_n }] set_property PACKAGE_PIN E12 [ get_ports { CLK_sys_clk1_250_p } ] set_property IOSTANDARD DIFF_SSTL12 [ get_ports { CLK_sys_clk1_250_p } ] set_property PACKAGE_PIN D12 [ get_ports { CLK_sys_clk1_250_n } ] set_property IOSTANDARD DIFF_SSTL12 [ get_ports { CLK_sys_clk1_250_n } ] set_property PACKAGE_PIN AW26 [ get_ports { CLK_sys_clk2_250_p } ] set_property IOSTANDARD DIFF_SSTL12 [ get_ports { CLK_sys_clk2_250_p } ] set_property PACKAGE_PIN AW27 [ get_ports { CLK_sys_clk2_250_n } ] set_property IOSTANDARD DIFF_SSTL12 [ get_ports { CLK_sys_clk2_250_n } ] set_property IOSTANDARD LVCMOS18 [get_ports { RST_N_pci_sys_reset_n }] set_property PULLUP true [get_ports { RST_N_pci_sys_reset_n }] ================================================ FILE: constraints/xilinx/verilator.xdc ================================================ this file intentionally left blank ================================================ FILE: constraints/xilinx/xc7z010clg400.xdc ================================================ #created using vivado from microzed board type # create_clock manually commented out ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z010clg400-1 ## Device Size: xc7z010 ## Package: clg400 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ ## get the period from the clock generator cell create_clock -name clk_fpga_0 -period [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]] [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 [expr 0.3 * [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]]] set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ # Enet 0 / mdio / MIO[53] set_property iostandard "LVCMOS18" [get_ports "MIO[53]"] set_property PACKAGE_PIN "C11" [get_ports "MIO[53]"] set_property slew "slow" [get_ports "MIO[53]"] set_property drive "8" [get_ports "MIO[53]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[53]"] # Enet 0 / mdc / MIO[52] set_property iostandard "LVCMOS18" [get_ports "MIO[52]"] set_property PACKAGE_PIN "C10" [get_ports "MIO[52]"] set_property slew "slow" [get_ports "MIO[52]"] set_property drive "8" [get_ports "MIO[52]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[52]"] # GPIO / gpio[51] / MIO[51] set_property iostandard "LVCMOS18" [get_ports "MIO[51]"] set_property PACKAGE_PIN "B9" [get_ports "MIO[51]"] set_property slew "slow" [get_ports "MIO[51]"] set_property drive "8" [get_ports "MIO[51]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[51]"] # SD 0 / wp / MIO[50] set_property iostandard "LVCMOS18" [get_ports "MIO[50]"] set_property PACKAGE_PIN "B13" [get_ports "MIO[50]"] set_property slew "slow" [get_ports "MIO[50]"] set_property drive "8" [get_ports "MIO[50]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[50]"] # UART 1 / rx / MIO[49] set_property iostandard "LVCMOS18" [get_ports "MIO[49]"] set_property PACKAGE_PIN "C12" [get_ports "MIO[49]"] set_property slew "slow" [get_ports "MIO[49]"] set_property drive "8" [get_ports "MIO[49]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[49]"] # UART 1 / tx / MIO[48] set_property iostandard "LVCMOS18" [get_ports "MIO[48]"] set_property PACKAGE_PIN "B12" [get_ports "MIO[48]"] set_property slew "slow" [get_ports "MIO[48]"] set_property drive "8" [get_ports "MIO[48]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[48]"] # GPIO / gpio[47] / MIO[47] set_property iostandard "LVCMOS18" [get_ports "MIO[47]"] set_property PACKAGE_PIN "B14" [get_ports "MIO[47]"] set_property slew "slow" [get_ports "MIO[47]"] set_property drive "8" [get_ports "MIO[47]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[47]"] # SD 0 / cd / MIO[46] set_property iostandard "LVCMOS18" [get_ports "MIO[46]"] set_property PACKAGE_PIN "D16" [get_ports "MIO[46]"] set_property slew "slow" [get_ports "MIO[46]"] set_property drive "8" [get_ports "MIO[46]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[46]"] # SD 0 / data[3] / MIO[45] set_property iostandard "LVCMOS18" [get_ports "MIO[45]"] set_property PACKAGE_PIN "B15" [get_ports "MIO[45]"] set_property slew "slow" [get_ports "MIO[45]"] set_property drive "8" [get_ports "MIO[45]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[45]"] # SD 0 / data[2] / MIO[44] set_property iostandard "LVCMOS18" [get_ports "MIO[44]"] set_property PACKAGE_PIN "F13" [get_ports "MIO[44]"] set_property slew "slow" [get_ports "MIO[44]"] set_property drive "8" [get_ports "MIO[44]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[44]"] # SD 0 / data[1] / MIO[43] set_property iostandard "LVCMOS18" [get_ports "MIO[43]"] set_property PACKAGE_PIN "A9" [get_ports "MIO[43]"] set_property slew "slow" [get_ports "MIO[43]"] set_property drive "8" [get_ports "MIO[43]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[43]"] # SD 0 / data[0] / MIO[42] set_property iostandard "LVCMOS18" [get_ports "MIO[42]"] set_property PACKAGE_PIN "E12" [get_ports "MIO[42]"] set_property slew "slow" [get_ports "MIO[42]"] set_property drive "8" [get_ports "MIO[42]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[42]"] # SD 0 / cmd / MIO[41] set_property iostandard "LVCMOS18" [get_ports "MIO[41]"] set_property PACKAGE_PIN "C17" [get_ports "MIO[41]"] set_property slew "slow" [get_ports "MIO[41]"] set_property drive "8" [get_ports "MIO[41]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[41]"] # SD 0 / clk / MIO[40] set_property iostandard "LVCMOS18" [get_ports "MIO[40]"] set_property PACKAGE_PIN "D14" [get_ports "MIO[40]"] set_property slew "slow" [get_ports "MIO[40]"] set_property drive "8" [get_ports "MIO[40]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[40]"] # USB 0 / data[7] / MIO[39] set_property iostandard "LVCMOS18" [get_ports "MIO[39]"] set_property PACKAGE_PIN "C18" [get_ports "MIO[39]"] set_property slew "slow" [get_ports "MIO[39]"] set_property drive "8" [get_ports "MIO[39]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[39]"] # USB 0 / data[6] / MIO[38] set_property iostandard "LVCMOS18" [get_ports "MIO[38]"] set_property PACKAGE_PIN "E13" [get_ports "MIO[38]"] set_property slew "slow" [get_ports "MIO[38]"] set_property drive "8" [get_ports "MIO[38]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[38]"] # USB 0 / data[5] / MIO[37] set_property iostandard "LVCMOS18" [get_ports "MIO[37]"] set_property PACKAGE_PIN "A10" [get_ports "MIO[37]"] set_property slew "slow" [get_ports "MIO[37]"] set_property drive "8" [get_ports "MIO[37]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[37]"] # USB 0 / clk / MIO[36] set_property iostandard "LVCMOS18" [get_ports "MIO[36]"] set_property PACKAGE_PIN "A11" [get_ports "MIO[36]"] set_property slew "slow" [get_ports "MIO[36]"] set_property drive "8" [get_ports "MIO[36]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[36]"] # USB 0 / data[3] / MIO[35] set_property iostandard "LVCMOS18" [get_ports "MIO[35]"] set_property PACKAGE_PIN "F12" [get_ports "MIO[35]"] set_property slew "slow" [get_ports "MIO[35]"] set_property drive "8" [get_ports "MIO[35]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[35]"] # USB 0 / data[2] / MIO[34] set_property iostandard "LVCMOS18" [get_ports "MIO[34]"] set_property PACKAGE_PIN "A12" [get_ports "MIO[34]"] set_property slew "slow" [get_ports "MIO[34]"] set_property drive "8" [get_ports "MIO[34]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[34]"] # USB 0 / data[1] / MIO[33] set_property iostandard "LVCMOS18" [get_ports "MIO[33]"] set_property PACKAGE_PIN "D15" [get_ports "MIO[33]"] set_property slew "slow" [get_ports "MIO[33]"] set_property drive "8" [get_ports "MIO[33]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[33]"] # USB 0 / data[0] / MIO[32] set_property iostandard "LVCMOS18" [get_ports "MIO[32]"] set_property PACKAGE_PIN "A14" [get_ports "MIO[32]"] set_property slew "slow" [get_ports "MIO[32]"] set_property drive "8" [get_ports "MIO[32]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[32]"] # USB 0 / nxt / MIO[31] set_property iostandard "LVCMOS18" [get_ports "MIO[31]"] set_property PACKAGE_PIN "E16" [get_ports "MIO[31]"] set_property slew "slow" [get_ports "MIO[31]"] set_property drive "8" [get_ports "MIO[31]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[31]"] # USB 0 / stp / MIO[30] set_property iostandard "LVCMOS18" [get_ports "MIO[30]"] set_property PACKAGE_PIN "C15" [get_ports "MIO[30]"] set_property slew "slow" [get_ports "MIO[30]"] set_property drive "8" [get_ports "MIO[30]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[30]"] # USB 0 / dir / MIO[29] set_property iostandard "LVCMOS18" [get_ports "MIO[29]"] set_property PACKAGE_PIN "C13" [get_ports "MIO[29]"] set_property slew "slow" [get_ports "MIO[29]"] set_property drive "8" [get_ports "MIO[29]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[29]"] # USB 0 / data[4] / MIO[28] set_property iostandard "LVCMOS18" [get_ports "MIO[28]"] set_property PACKAGE_PIN "C16" [get_ports "MIO[28]"] set_property slew "slow" [get_ports "MIO[28]"] set_property drive "8" [get_ports "MIO[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[28]"] # Enet 0 / rx_ctl / MIO[27] set_property iostandard "LVCMOS18" [get_ports "MIO[27]"] set_property PACKAGE_PIN "D13" [get_ports "MIO[27]"] set_property slew "slow" [get_ports "MIO[27]"] set_property drive "8" [get_ports "MIO[27]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[27]"] # Enet 0 / rxd[3] / MIO[26] set_property iostandard "LVCMOS18" [get_ports "MIO[26]"] set_property PACKAGE_PIN "A15" [get_ports "MIO[26]"] set_property slew "slow" [get_ports "MIO[26]"] set_property drive "8" [get_ports "MIO[26]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[26]"] # Enet 0 / rxd[2] / MIO[25] set_property iostandard "LVCMOS18" [get_ports "MIO[25]"] set_property PACKAGE_PIN "F15" [get_ports "MIO[25]"] set_property slew "slow" [get_ports "MIO[25]"] set_property drive "8" [get_ports "MIO[25]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[25]"] # Enet 0 / rxd[1] / MIO[24] set_property iostandard "LVCMOS18" [get_ports "MIO[24]"] set_property PACKAGE_PIN "A16" [get_ports "MIO[24]"] set_property slew "slow" [get_ports "MIO[24]"] set_property drive "8" [get_ports "MIO[24]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[24]"] # Enet 0 / rxd[0] / MIO[23] set_property iostandard "LVCMOS18" [get_ports "MIO[23]"] set_property PACKAGE_PIN "D11" [get_ports "MIO[23]"] set_property slew "slow" [get_ports "MIO[23]"] set_property drive "8" [get_ports "MIO[23]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[23]"] # Enet 0 / rx_clk / MIO[22] set_property iostandard "LVCMOS18" [get_ports "MIO[22]"] set_property PACKAGE_PIN "B17" [get_ports "MIO[22]"] set_property slew "slow" [get_ports "MIO[22]"] set_property drive "8" [get_ports "MIO[22]"] set_property PIO_DIRECTION "INPUT" [get_ports "MIO[22]"] # Enet 0 / tx_ctl / MIO[21] set_property iostandard "LVCMOS18" [get_ports "MIO[21]"] set_property PACKAGE_PIN "F14" [get_ports "MIO[21]"] set_property slew "slow" [get_ports "MIO[21]"] set_property drive "8" [get_ports "MIO[21]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[21]"] # Enet 0 / txd[3] / MIO[20] set_property iostandard "LVCMOS18" [get_ports "MIO[20]"] set_property PACKAGE_PIN "A17" [get_ports "MIO[20]"] set_property slew "slow" [get_ports "MIO[20]"] set_property drive "8" [get_ports "MIO[20]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[20]"] # Enet 0 / txd[2] / MIO[19] set_property iostandard "LVCMOS18" [get_ports "MIO[19]"] set_property PACKAGE_PIN "D10" [get_ports "MIO[19]"] set_property slew "slow" [get_ports "MIO[19]"] set_property drive "8" [get_ports "MIO[19]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[19]"] # Enet 0 / txd[1] / MIO[18] set_property iostandard "LVCMOS18" [get_ports "MIO[18]"] set_property PACKAGE_PIN "B18" [get_ports "MIO[18]"] set_property slew "slow" [get_ports "MIO[18]"] set_property drive "8" [get_ports "MIO[18]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[18]"] # Enet 0 / txd[0] / MIO[17] set_property iostandard "LVCMOS18" [get_ports "MIO[17]"] set_property PACKAGE_PIN "E14" [get_ports "MIO[17]"] set_property slew "slow" [get_ports "MIO[17]"] set_property drive "8" [get_ports "MIO[17]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[17]"] # Enet 0 / tx_clk / MIO[16] set_property iostandard "LVCMOS18" [get_ports "MIO[16]"] set_property PACKAGE_PIN "A19" [get_ports "MIO[16]"] set_property slew "slow" [get_ports "MIO[16]"] set_property drive "8" [get_ports "MIO[16]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[16]"] # GPIO / gpio[15] / MIO[15] set_property iostandard "LVCMOS33" [get_ports "MIO[15]"] set_property PACKAGE_PIN "C8" [get_ports "MIO[15]"] set_property slew "slow" [get_ports "MIO[15]"] set_property drive "8" [get_ports "MIO[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[15]"] # GPIO / gpio[14] / MIO[14] set_property iostandard "LVCMOS33" [get_ports "MIO[14]"] set_property PACKAGE_PIN "C5" [get_ports "MIO[14]"] set_property slew "slow" [get_ports "MIO[14]"] set_property drive "8" [get_ports "MIO[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[14]"] # GPIO / gpio[13] / MIO[13] set_property iostandard "LVCMOS33" [get_ports "MIO[13]"] set_property PACKAGE_PIN "E8" [get_ports "MIO[13]"] set_property slew "slow" [get_ports "MIO[13]"] set_property drive "8" [get_ports "MIO[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[13]"] # GPIO / gpio[12] / MIO[12] set_property iostandard "LVCMOS33" [get_ports "MIO[12]"] set_property PACKAGE_PIN "D9" [get_ports "MIO[12]"] set_property slew "slow" [get_ports "MIO[12]"] set_property drive "8" [get_ports "MIO[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[12]"] # GPIO / gpio[11] / MIO[11] set_property iostandard "LVCMOS33" [get_ports "MIO[11]"] set_property PACKAGE_PIN "C6" [get_ports "MIO[11]"] set_property slew "slow" [get_ports "MIO[11]"] set_property drive "8" [get_ports "MIO[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[11]"] # GPIO / gpio[10] / MIO[10] set_property iostandard "LVCMOS33" [get_ports "MIO[10]"] set_property PACKAGE_PIN "E9" [get_ports "MIO[10]"] set_property slew "slow" [get_ports "MIO[10]"] set_property drive "8" [get_ports "MIO[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[10]"] # GPIO / gpio[9] / MIO[9] set_property iostandard "LVCMOS33" [get_ports "MIO[9]"] set_property PACKAGE_PIN "B5" [get_ports "MIO[9]"] set_property slew "slow" [get_ports "MIO[9]"] set_property drive "8" [get_ports "MIO[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[9]"] # Quad SPI Flash / qspi_fbclk / MIO[8] set_property iostandard "LVCMOS33" [get_ports "MIO[8]"] set_property PACKAGE_PIN "D5" [get_ports "MIO[8]"] set_property slew "slow" [get_ports "MIO[8]"] set_property drive "8" [get_ports "MIO[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[8]"] # USB Reset / reset / MIO[7] set_property iostandard "LVCMOS33" [get_ports "MIO[7]"] set_property PACKAGE_PIN "D8" [get_ports "MIO[7]"] set_property slew "slow" [get_ports "MIO[7]"] set_property drive "8" [get_ports "MIO[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[7]"] # Quad SPI Flash / qspi0_sclk / MIO[6] set_property iostandard "LVCMOS33" [get_ports "MIO[6]"] set_property PACKAGE_PIN "A5" [get_ports "MIO[6]"] set_property slew "slow" [get_ports "MIO[6]"] set_property drive "8" [get_ports "MIO[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[6]"] # Quad SPI Flash / qspi0_io[3] / MIO[5] set_property iostandard "LVCMOS33" [get_ports "MIO[5]"] set_property PACKAGE_PIN "A6" [get_ports "MIO[5]"] set_property slew "slow" [get_ports "MIO[5]"] set_property drive "8" [get_ports "MIO[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[5]"] # Quad SPI Flash / qspi0_io[2] / MIO[4] set_property iostandard "LVCMOS33" [get_ports "MIO[4]"] set_property PACKAGE_PIN "B7" [get_ports "MIO[4]"] set_property slew "slow" [get_ports "MIO[4]"] set_property drive "8" [get_ports "MIO[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[4]"] # Quad SPI Flash / qspi0_io[1] / MIO[3] set_property iostandard "LVCMOS33" [get_ports "MIO[3]"] set_property PACKAGE_PIN "D6" [get_ports "MIO[3]"] set_property slew "slow" [get_ports "MIO[3]"] set_property drive "8" [get_ports "MIO[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[3]"] # Quad SPI Flash / qspi0_io[0] / MIO[2] set_property iostandard "LVCMOS33" [get_ports "MIO[2]"] set_property PACKAGE_PIN "B8" [get_ports "MIO[2]"] set_property slew "slow" [get_ports "MIO[2]"] set_property drive "8" [get_ports "MIO[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[2]"] # Quad SPI Flash / qspi0_ss_b / MIO[1] set_property iostandard "LVCMOS33" [get_ports "MIO[1]"] set_property PACKAGE_PIN "A7" [get_ports "MIO[1]"] set_property slew "slow" [get_ports "MIO[1]"] set_property drive "8" [get_ports "MIO[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "MIO[1]"] # GPIO / gpio[0] / MIO[0] set_property iostandard "LVCMOS33" [get_ports "MIO[0]"] set_property PACKAGE_PIN "E6" [get_ports "MIO[0]"] set_property slew "slow" [get_ports "MIO[0]"] set_property drive "8" [get_ports "MIO[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "MIO[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrp"] set_property PACKAGE_PIN "H5" [get_ports "FIXED_IO_ddr_vrp"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrp"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrp"] set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrn"] set_property PACKAGE_PIN "G5" [get_ports "FIXED_IO_ddr_vrn"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrn"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrn"] set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "M5" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "P4" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "N5" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "B4" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "W5" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "R2" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "G2" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C2" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "W4" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "T2" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "F2" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B2" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "E3" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "E2" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "E1" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "C1" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "D1" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "D3" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "A4" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "V3" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "V2" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "A2" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "W3" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "Y2" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "Y4" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "W1" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "Y3" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "V1" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "U3" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "U2" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "U4" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "T4" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "B3" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "R1" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "R3" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "P3" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "P1" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "J1" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "H1" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "H2" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "J3" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "H3" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "G3" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "C3" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "Y1" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "T1" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "F1" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "A1" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N1" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "N3" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "L2" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "M2" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "P5" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "J5" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "R4" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "L5" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J4" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "K1" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K4" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "L4" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "L1" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "M4" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "K3" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "M3" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K2" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "F4" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "D4" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "E4" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "G4" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "F5" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "N2" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] set_property iostandard "LVCMOS33" [get_ports "PS_PORB"] set_property PACKAGE_PIN "C7" [get_ports "PS_PORB"] set_property slew "slow" [get_ports "PS_PORB"] set_property drive "8" [get_ports "PS_PORB"] set_property iostandard "LVCMOS33" [get_ports "PS_SRSTB"] set_property PACKAGE_PIN "B10" [get_ports "PS_SRSTB"] set_property slew "slow" [get_ports "PS_SRSTB"] set_property drive "8" [get_ports "PS_SRSTB"] set_property iostandard "LVCMOS33" [get_ports "PS_CLK"] set_property PACKAGE_PIN "E7" [get_ports "PS_CLK"] set_property slew "slow" [get_ports "PS_CLK"] set_property drive "8" [get_ports "PS_CLK"] ================================================ FILE: constraints/xilinx/xc7z045ffg900.xdc ================================================ #created using vivado, see instructions in Readme.md #create clock manually commented out ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z045ffg900-1 ## Device Size: xc7z045 ## Package: ffg900 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ ## get the period from the clock generator cell create_clock -name clk_fpga_0 -period [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]] [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 [expr 0.03 * [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]]] set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrp"] set_property PACKAGE_PIN "M21" [get_ports "FIXED_IO_ddr_vrp"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrp"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrp"] set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrn"] set_property PACKAGE_PIN "N21" [get_ports "FIXED_IO_ddr_vrn"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrn"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrn"] set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "N23" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "N24" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "L23" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F25" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "L28" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "G29" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "C29" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C26" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "L29" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "F29" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "B29" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B26" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "A27" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "A29" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "E27" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "D26" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "E26" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "B25" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "D25" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "M30" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "L30" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "B27" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "M29" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "K30" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "J28" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "J30" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "K27" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "J29" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "F30" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "G30" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "F28" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "E30" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "E25" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "E28" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "H28" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "G27" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "H27" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "D29" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "D28" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "D30" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "C28" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "A28" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "A30" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "A25" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "K28" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "H29" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "B30" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "C27" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N22" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "M22" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "K25" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "J25" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "M24" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M25" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "M26" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "M27" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J23" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "F27" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K22" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "H26" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "G24" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "J26" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "G25" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "L27" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K26" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "J24" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "H23" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "K23" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "H24" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "G26" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "L25" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/xc7z100ffg900.xdc ================================================ #created using vivado see readme.md # create_clock manually commented out ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z100ffg900-1 ## Device Size: xc7z100 ## Package: ffg900 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ ## get the period from the clock generator cell create_clock -name clk_fpga_0 -period [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]] [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 [expr 0.3 * [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]]] set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrp"] set_property PACKAGE_PIN "M21" [get_ports "FIXED_IO_ddr_vrp"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrp"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrp"] set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrn"] set_property PACKAGE_PIN "N21" [get_ports "FIXED_IO_ddr_vrn"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrn"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrn"] set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "N23" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "N24" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "L23" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F25" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "L28" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "G29" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "C29" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C26" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "L29" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "F29" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "B29" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B26" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "A27" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "A29" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "E27" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "D26" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "E26" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "B25" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "D25" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "M30" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "L30" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "B27" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "M29" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "K30" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "J28" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "J30" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "K27" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "J29" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "F30" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "G30" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "F28" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "E30" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "E25" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "E28" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "H28" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "G27" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "H27" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "D29" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "D28" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "D30" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "C28" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "A28" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "A30" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "A25" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "K28" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "H29" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "B30" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "C27" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N22" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "M22" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "K25" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "J25" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "M24" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M25" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "M26" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "M27" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J23" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "F27" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K22" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "H26" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "G24" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "J26" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "G25" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "L27" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K26" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "J24" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "H23" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "K23" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "H24" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "G26" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "L25" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/zc706-axiddr3.prj ================================================ axiddr3 1 1 OFF 1024 ON Enabled xc7z045-ffg900/-2 2.3 No Buffer Use System Clock ACTIVE LOW FALSE 0 50 Ohms 0 DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 1250 2.0V 4:1 200 0 800 1.000 1 1 1 1 64 1 1 Disabled Normal FALSE 14 10 3 1.5V BANK_ROW_COLUMN 8 - Fixed Sequential 11 Normal No Slow Exit Enable RZQ/7 Disable Enable RZQ/4 0 Disabled Enabled Output Buffer Enabled Full Array 8 Enabled Normal Dynamic ODT off AXI RD_PRI_REG 30 512 6 0 ================================================ FILE: constraints/xilinx/zc706.xdc ================================================ set_property LOC H9 [get_ports { CLK_sys_clk_p }] set_property LOC G9 [get_ports { CLK_sys_clk_n }] set_property IOSTANDARD DIFF_SSTL15 [get_ports { CLK_sys_clk_* }] create_clock -name sys_clk -period 5 [get_ports CLK_sys_clk_p] # set_property iostandard "LVCMOS15" [get_ports "GPIO_leds[0]"] # set_property PACKAGE_PIN "A17" [get_ports "GPIO_leds[0]"] # set_property slew "SLOW" [get_ports "GPIO_leds[0]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[0]"] # set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[1]"] # set_property PACKAGE_PIN "W21" [get_ports "GPIO_leds[1]"] # set_property slew "SLOW" [get_ports "GPIO_leds[1]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[1]"] # set_property iostandard "LVCMOS15" [get_ports "GPIO_leds[2]"] # set_property PACKAGE_PIN "G2" [get_ports "GPIO_leds[2]"] # set_property slew "SLOW" [get_ports "GPIO_leds[2]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[2]"] # set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[3]"] # set_property PACKAGE_PIN "Y21" [get_ports "GPIO_leds[3]"] # set_property slew "SLOW" [get_ports "GPIO_leds[3]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[3]"] # set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[0]"] # set_property PACKAGE_PIN "H14" [get_ports "XADC_gpio[0]"] # set_property slew "SLOW" [get_ports "XADC_gpio[0]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[0]"] # set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[1]"] # set_property PACKAGE_PIN "J15" [get_ports "XADC_gpio[1]"] # set_property slew "SLOW" [get_ports "XADC_gpio[1]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[1]"] # set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[2]"] # set_property PACKAGE_PIN "J16" [get_ports "XADC_gpio[2]"] # set_property slew "SLOW" [get_ports "XADC_gpio[2]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[2]"] # set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[3]"] # set_property PACKAGE_PIN "J14" [get_ports "XADC_gpio[3]"] # set_property slew "SLOW" [get_ports "XADC_gpio[3]"] # set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[3]"] # PS_MIO50 set_property PACKAGE_PIN "A19" [get_ports "I2C0_scl"] # PS_MIO51 set_property PACKAGE_PIN "F19" [get_ports "I2C0_sda"] ================================================ FILE: constraints/xilinx/zc706_pl_ddr3_pins.xdc ================================================ ###################################################################################################### # PIN ASSIGNMENTS ###################################################################################################### set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[0]}] set_property SLEW FAST [get_ports {ddr3_dq[0]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[0]}] set_property LOC L1 [get_ports {ddr3_dq[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[1]}] set_property SLEW FAST [get_ports {ddr3_dq[1]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[1]}] set_property LOC L2 [get_ports {ddr3_dq[1]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[2]}] set_property SLEW FAST [get_ports {ddr3_dq[2]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[2]}] set_property LOC K5 [get_ports {ddr3_dq[2]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[3]}] set_property SLEW FAST [get_ports {ddr3_dq[3]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[3]}] set_property LOC J4 [get_ports {ddr3_dq[3]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[4]}] set_property SLEW FAST [get_ports {ddr3_dq[4]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[4]}] set_property LOC K1 [get_ports {ddr3_dq[4]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[5]}] set_property SLEW FAST [get_ports {ddr3_dq[5]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[5]}] set_property LOC L3 [get_ports {ddr3_dq[5]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[6]}] set_property SLEW FAST [get_ports {ddr3_dq[6]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[6]}] set_property LOC J5 [get_ports {ddr3_dq[6]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[7]}] set_property SLEW FAST [get_ports {ddr3_dq[7]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[7]}] set_property LOC K6 [get_ports {ddr3_dq[7]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[8]}] set_property SLEW FAST [get_ports {ddr3_dq[8]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[8]}] set_property LOC G6 [get_ports {ddr3_dq[8]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[9]}] set_property SLEW FAST [get_ports {ddr3_dq[9]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[9]}] set_property LOC H4 [get_ports {ddr3_dq[9]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[10]}] set_property SLEW FAST [get_ports {ddr3_dq[10]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[10]}] set_property LOC H6 [get_ports {ddr3_dq[10]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[11]}] set_property SLEW FAST [get_ports {ddr3_dq[11]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[11]}] set_property LOC H3 [get_ports {ddr3_dq[11]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[12]}] set_property SLEW FAST [get_ports {ddr3_dq[12]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[12]}] set_property LOC G1 [get_ports {ddr3_dq[12]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[13]}] set_property SLEW FAST [get_ports {ddr3_dq[13]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[13]}] set_property LOC H2 [get_ports {ddr3_dq[13]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[14]}] set_property SLEW FAST [get_ports {ddr3_dq[14]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[14]}] set_property LOC G5 [get_ports {ddr3_dq[14]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[15]}] set_property SLEW FAST [get_ports {ddr3_dq[15]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[15]}] set_property LOC G4 [get_ports {ddr3_dq[15]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[16]}] set_property SLEW FAST [get_ports {ddr3_dq[16]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[16]}] set_property LOC E2 [get_ports {ddr3_dq[16]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[17]}] set_property SLEW FAST [get_ports {ddr3_dq[17]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[17]}] set_property LOC E3 [get_ports {ddr3_dq[17]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[18]}] set_property SLEW FAST [get_ports {ddr3_dq[18]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[18]}] set_property LOC D4 [get_ports {ddr3_dq[18]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[19]}] set_property SLEW FAST [get_ports {ddr3_dq[19]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[19]}] set_property LOC E5 [get_ports {ddr3_dq[19]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[20]}] set_property SLEW FAST [get_ports {ddr3_dq[20]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[20]}] set_property LOC F4 [get_ports {ddr3_dq[20]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[21]}] set_property SLEW FAST [get_ports {ddr3_dq[21]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[21]}] set_property LOC F3 [get_ports {ddr3_dq[21]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[22]}] set_property SLEW FAST [get_ports {ddr3_dq[22]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[22]}] set_property LOC D1 [get_ports {ddr3_dq[22]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[23]}] set_property SLEW FAST [get_ports {ddr3_dq[23]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[23]}] set_property LOC D3 [get_ports {ddr3_dq[23]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[24]}] set_property SLEW FAST [get_ports {ddr3_dq[24]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[24]}] set_property LOC A2 [get_ports {ddr3_dq[24]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[25]}] set_property SLEW FAST [get_ports {ddr3_dq[25]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[25]}] set_property LOC B2 [get_ports {ddr3_dq[25]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[26]}] set_property SLEW FAST [get_ports {ddr3_dq[26]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[26]}] set_property LOC B4 [get_ports {ddr3_dq[26]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[27]}] set_property SLEW FAST [get_ports {ddr3_dq[27]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[27]}] set_property LOC B5 [get_ports {ddr3_dq[27]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[28]}] set_property SLEW FAST [get_ports {ddr3_dq[28]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[28]}] set_property LOC A3 [get_ports {ddr3_dq[28]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[29]}] set_property SLEW FAST [get_ports {ddr3_dq[29]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[29]}] set_property LOC B1 [get_ports {ddr3_dq[29]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[30]}] set_property SLEW FAST [get_ports {ddr3_dq[30]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[30]}] set_property LOC C1 [get_ports {ddr3_dq[30]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[31]}] set_property SLEW FAST [get_ports {ddr3_dq[31]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[31]}] set_property LOC C4 [get_ports {ddr3_dq[31]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[32]}] set_property SLEW FAST [get_ports {ddr3_dq[32]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[32]}] set_property LOC K10 [get_ports {ddr3_dq[32]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[33]}] set_property SLEW FAST [get_ports {ddr3_dq[33]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[33]}] set_property LOC L9 [get_ports {ddr3_dq[33]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[34]}] set_property SLEW FAST [get_ports {ddr3_dq[34]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[34]}] set_property LOC K12 [get_ports {ddr3_dq[34]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[35]}] set_property SLEW FAST [get_ports {ddr3_dq[35]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[35]}] set_property LOC J9 [get_ports {ddr3_dq[35]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[36]}] set_property SLEW FAST [get_ports {ddr3_dq[36]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[36]}] set_property LOC K11 [get_ports {ddr3_dq[36]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[37]}] set_property SLEW FAST [get_ports {ddr3_dq[37]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[37]}] set_property LOC L10 [get_ports {ddr3_dq[37]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[38]}] set_property SLEW FAST [get_ports {ddr3_dq[38]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[38]}] set_property LOC J10 [get_ports {ddr3_dq[38]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[39]}] set_property SLEW FAST [get_ports {ddr3_dq[39]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[39]}] set_property LOC L7 [get_ports {ddr3_dq[39]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[40]}] set_property SLEW FAST [get_ports {ddr3_dq[40]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[40]}] set_property LOC F14 [get_ports {ddr3_dq[40]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[41]}] set_property SLEW FAST [get_ports {ddr3_dq[41]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[41]}] set_property LOC F15 [get_ports {ddr3_dq[41]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[42]}] set_property SLEW FAST [get_ports {ddr3_dq[42]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[42]}] set_property LOC F13 [get_ports {ddr3_dq[42]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[43]}] set_property SLEW FAST [get_ports {ddr3_dq[43]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[43]}] set_property LOC G16 [get_ports {ddr3_dq[43]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[44]}] set_property SLEW FAST [get_ports {ddr3_dq[44]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[44]}] set_property LOC G15 [get_ports {ddr3_dq[44]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[45]}] set_property SLEW FAST [get_ports {ddr3_dq[45]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[45]}] set_property LOC E12 [get_ports {ddr3_dq[45]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[46]}] set_property SLEW FAST [get_ports {ddr3_dq[46]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[46]}] set_property LOC D13 [get_ports {ddr3_dq[46]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[47]}] set_property SLEW FAST [get_ports {ddr3_dq[47]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[47]}] set_property LOC E13 [get_ports {ddr3_dq[47]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[48]}] set_property SLEW FAST [get_ports {ddr3_dq[48]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[48]}] set_property LOC D15 [get_ports {ddr3_dq[48]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[49]}] set_property SLEW FAST [get_ports {ddr3_dq[49]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[49]}] set_property LOC E15 [get_ports {ddr3_dq[49]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[50]}] set_property SLEW FAST [get_ports {ddr3_dq[50]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[50]}] set_property LOC D16 [get_ports {ddr3_dq[50]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[51]}] set_property SLEW FAST [get_ports {ddr3_dq[51]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[51]}] set_property LOC E16 [get_ports {ddr3_dq[51]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[52]}] set_property SLEW FAST [get_ports {ddr3_dq[52]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[52]}] set_property LOC C17 [get_ports {ddr3_dq[52]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[53]}] set_property SLEW FAST [get_ports {ddr3_dq[53]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[53]}] set_property LOC B16 [get_ports {ddr3_dq[53]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[54]}] set_property SLEW FAST [get_ports {ddr3_dq[54]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[54]}] set_property LOC D14 [get_ports {ddr3_dq[54]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[55]}] set_property SLEW FAST [get_ports {ddr3_dq[55]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[55]}] set_property LOC B17 [get_ports {ddr3_dq[55]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[56]}] set_property SLEW FAST [get_ports {ddr3_dq[56]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[56]}] set_property LOC B12 [get_ports {ddr3_dq[56]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[57]}] set_property SLEW FAST [get_ports {ddr3_dq[57]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[57]}] set_property LOC C12 [get_ports {ddr3_dq[57]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[58]}] set_property SLEW FAST [get_ports {ddr3_dq[58]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[58]}] set_property LOC A12 [get_ports {ddr3_dq[58]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[59]}] set_property SLEW FAST [get_ports {ddr3_dq[59]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[59]}] set_property LOC A14 [get_ports {ddr3_dq[59]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[60]}] set_property SLEW FAST [get_ports {ddr3_dq[60]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[60]}] set_property LOC A13 [get_ports {ddr3_dq[60]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[61]}] set_property SLEW FAST [get_ports {ddr3_dq[61]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[61]}] set_property LOC B11 [get_ports {ddr3_dq[61]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[62]}] set_property SLEW FAST [get_ports {ddr3_dq[62]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[62]}] set_property LOC C14 [get_ports {ddr3_dq[62]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dq[63]}] set_property SLEW FAST [get_ports {ddr3_dq[63]}] set_property IOSTANDARD SSTL15_T_DCI [get_ports {ddr3_dq[63]}] set_property LOC B14 [get_ports {ddr3_dq[63]}] #set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[15]}] #set_property SLEW FAST [get_ports {ddr3_addr[15]}] #set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[15]}] #set_property LOC C6 [get_ports {ddr3_addr[15]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[14]}] set_property SLEW FAST [get_ports {ddr3_addr[14]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[14]}] set_property LOC G11 [get_ports {ddr3_addr[14]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[13]}] set_property SLEW FAST [get_ports {ddr3_addr[13]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[13]}] set_property LOC A10 [get_ports {ddr3_addr[13]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[12]}] set_property SLEW FAST [get_ports {ddr3_addr[12]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[12]}] set_property LOC H12 [get_ports {ddr3_addr[12]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[11]}] set_property SLEW FAST [get_ports {ddr3_addr[11]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[11]}] set_property LOC B7 [get_ports {ddr3_addr[11]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[10]}] set_property SLEW FAST [get_ports {ddr3_addr[10]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[10]}] set_property LOC D6 [get_ports {ddr3_addr[10]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[9]}] set_property SLEW FAST [get_ports {ddr3_addr[9]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[9]}] set_property LOC J8 [get_ports {ddr3_addr[9]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[8]}] set_property SLEW FAST [get_ports {ddr3_addr[8]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[8]}] set_property LOC B10 [get_ports {ddr3_addr[8]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[7]}] set_property SLEW FAST [get_ports {ddr3_addr[7]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[7]}] set_property LOC E8 [get_ports {ddr3_addr[7]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[6]}] set_property SLEW FAST [get_ports {ddr3_addr[6]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[6]}] set_property LOC F9 [get_ports {ddr3_addr[6]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[5]}] set_property SLEW FAST [get_ports {ddr3_addr[5]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[5]}] set_property LOC B6 [get_ports {ddr3_addr[5]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[4]}] set_property SLEW FAST [get_ports {ddr3_addr[4]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[4]}] set_property LOC D11 [get_ports {ddr3_addr[4]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[3]}] set_property SLEW FAST [get_ports {ddr3_addr[3]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[3]}] set_property LOC A9 [get_ports {ddr3_addr[3]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[2]}] set_property SLEW FAST [get_ports {ddr3_addr[2]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[2]}] set_property LOC E11 [get_ports {ddr3_addr[2]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[1]}] set_property SLEW FAST [get_ports {ddr3_addr[1]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[1]}] set_property LOC B9 [get_ports {ddr3_addr[1]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_addr[0]}] set_property SLEW FAST [get_ports {ddr3_addr[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_addr[0]}] set_property LOC E10 [get_ports {ddr3_addr[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_ba[2]}] set_property SLEW FAST [get_ports {ddr3_ba[2]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[2]}] set_property LOC A7 [get_ports {ddr3_ba[2]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_ba[1]}] set_property SLEW FAST [get_ports {ddr3_ba[1]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[1]}] set_property LOC H7 [get_ports {ddr3_ba[1]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_ba[0]}] set_property SLEW FAST [get_ports {ddr3_ba[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ba[0]}] set_property LOC F8 [get_ports {ddr3_ba[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_ras_n}] set_property SLEW FAST [get_ports {ddr3_ras_n}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_ras_n}] set_property LOC H11 [get_ports {ddr3_ras_n}] set_property VCCAUX_IO HIGH [get_ports {ddr3_cas_n}] set_property SLEW FAST [get_ports {ddr3_cas_n}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_cas_n}] set_property LOC E7 [get_ports {ddr3_cas_n}] set_property VCCAUX_IO HIGH [get_ports {ddr3_we_n}] set_property SLEW FAST [get_ports {ddr3_we_n}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_we_n}] set_property LOC F7 [get_ports {ddr3_we_n}] set_property VCCAUX_IO HIGH [get_ports {ddr3_reset_n}] set_property SLEW FAST [get_ports {ddr3_reset_n}] set_property IOSTANDARD LVCMOS15 [get_ports {ddr3_reset_n}] set_property LOC G17 [get_ports {ddr3_reset_n}] set_property VCCAUX_IO HIGH [get_ports {ddr3_cke[0]}] set_property SLEW FAST [get_ports {ddr3_cke[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_cke[0]}] set_property LOC D10 [get_ports {ddr3_cke[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_odt[0]}] set_property SLEW FAST [get_ports {ddr3_odt[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_odt[0]}] set_property LOC G7 [get_ports {ddr3_odt[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_cs_n[0]}] set_property SLEW FAST [get_ports {ddr3_cs_n[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_cs_n[0]}] set_property LOC J11 [get_ports {ddr3_cs_n[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[0]}] set_property SLEW FAST [get_ports {ddr3_dm[0]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[0]}] set_property LOC J3 [get_ports {ddr3_dm[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[1]}] set_property SLEW FAST [get_ports {ddr3_dm[1]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[1]}] set_property LOC F2 [get_ports {ddr3_dm[1]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[2]}] set_property SLEW FAST [get_ports {ddr3_dm[2]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[2]}] set_property LOC E1 [get_ports {ddr3_dm[2]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[3]}] set_property SLEW FAST [get_ports {ddr3_dm[3]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[3]}] set_property LOC C2 [get_ports {ddr3_dm[3]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[4]}] set_property SLEW FAST [get_ports {ddr3_dm[4]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[4]}] set_property LOC L12 [get_ports {ddr3_dm[4]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[5]}] set_property SLEW FAST [get_ports {ddr3_dm[5]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[5]}] set_property LOC G14 [get_ports {ddr3_dm[5]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[6]}] set_property SLEW FAST [get_ports {ddr3_dm[6]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[6]}] set_property LOC C16 [get_ports {ddr3_dm[6]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dm[7]}] set_property SLEW FAST [get_ports {ddr3_dm[7]}] set_property IOSTANDARD SSTL15 [get_ports {ddr3_dm[7]}] set_property LOC C11 [get_ports {ddr3_dm[7]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[0]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[0]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[0]}] set_property LOC K3 [get_ports {ddr3_dqs_p[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[0]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[0]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[0]}] set_property LOC K2 [get_ports {ddr3_dqs_n[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[1]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[1]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[1]}] set_property LOC J1 [get_ports {ddr3_dqs_p[1]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[1]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[1]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[1]}] set_property LOC H1 [get_ports {ddr3_dqs_n[1]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[2]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[2]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[2]}] set_property LOC E6 [get_ports {ddr3_dqs_p[2]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[2]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[2]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[2]}] set_property LOC D5 [get_ports {ddr3_dqs_n[2]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[3]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[3]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[3]}] set_property LOC A5 [get_ports {ddr3_dqs_p[3]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[3]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[3]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[3]}] set_property LOC A4 [get_ports {ddr3_dqs_n[3]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[4]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[4]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[4]}] set_property LOC L8 [get_ports {ddr3_dqs_p[4]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[4]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[4]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[4]}] set_property LOC K8 [get_ports {ddr3_dqs_n[4]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[5]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[5]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[5]}] set_property LOC G12 [get_ports {ddr3_dqs_p[5]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[5]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[5]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[5]}] set_property LOC F12 [get_ports {ddr3_dqs_n[5]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[6]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[6]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[6]}] set_property LOC F17 [get_ports {ddr3_dqs_p[6]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[6]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[6]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[6]}] set_property LOC E17 [get_ports {ddr3_dqs_n[6]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_p[7]}] set_property SLEW FAST [get_ports {ddr3_dqs_p[7]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_p[7]}] set_property LOC B15 [get_ports {ddr3_dqs_p[7]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_dqs_n[7]}] set_property SLEW FAST [get_ports {ddr3_dqs_n[7]}] set_property IOSTANDARD DIFF_SSTL15_T_DCI [get_ports {ddr3_dqs_n[7]}] set_property LOC A15 [get_ports {ddr3_dqs_n[7]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_ck_p[0]}] set_property SLEW FAST [get_ports {ddr3_ck_p[0]}] set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_ck_p[0]}] set_property LOC G10 [get_ports {ddr3_ck_p[0]}] set_property VCCAUX_IO HIGH [get_ports {ddr3_ck_n[0]}] set_property SLEW FAST [get_ports {ddr3_ck_n[0]}] set_property IOSTANDARD DIFF_SSTL15 [get_ports {ddr3_ck_n[0]}] set_property LOC F10 [get_ports {ddr3_ck_n[0]}] ================================================ FILE: constraints/xilinx/zc7z020clg400.xdc ================================================ # This file pulled from a Vidado manual run of a minimal design # using PS7. It was named # project/project_srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_0/design_1_processing_system7_0_0.xdc # clocking manually commented out ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z020clg400-1 ## Device Size: xc7z020 ## Package: clg400 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ ## get the period from the clock generator cell create_clock -name clk_fpga_0 -period [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]] [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 [expr 0.3 * [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]]] set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} create_clock -name bscan_refclk -period 20 [get_pins -hier -filter {NAME=~"*/bscan_mytck/O"}] ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrp"] set_property PACKAGE_PIN "H5" [get_ports "FIXED_IO_ddr_vrp"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrp"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrp"] set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrn"] set_property PACKAGE_PIN "G5" [get_ports "FIXED_IO_ddr_vrn"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrn"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrn"] set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "M5" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "P4" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "N5" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "B4" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "W5" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "R2" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "G2" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C2" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "W4" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "T2" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "F2" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "B2" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "E3" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "E2" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "E1" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "C1" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "D1" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "D3" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "A4" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "V3" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "V2" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "A2" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "W3" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "Y2" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "Y4" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "W1" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "Y3" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "V1" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "U3" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "U2" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "U4" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "T4" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "B3" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "R1" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "R3" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "P3" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "P1" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "J1" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "H1" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "H2" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "J3" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "H3" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "G3" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "C3" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "Y1" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "T1" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "F1" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "A1" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "N1" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "N3" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "L2" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "M2" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "P5" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "J5" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "R4" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "L5" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "J4" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "K1" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "K4" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "L4" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "L1" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "M4" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "K3" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "M3" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "K2" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "F4" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "D4" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "E4" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "G4" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "F5" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "N2" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/zc7z020clg484.xdc ================================================ # This file pulled from a Vidado manual run of a minimal design # using PS7. It was named # project/project_srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_0/design_1_processing_system7_0_0.xdc # clocking manually commented out here ############################################################################ ## ## Xilinx, Inc. 2006 www.xilinx.com ############################################################################ ## File name : ps7_constraints.xdc ## ## Details : Constraints file ## FPGA family: zynq ## FPGA: xc7z020clg484-1 ## Device Size: xc7z020 ## Package: clg484 ## Speedgrade: -1 ## ## ############################################################################ ############################################################################ ############################################################################ # Clock constraints # ############################################################################ ## get the period from the clock generator cell create_clock -name clk_fpga_0 -period [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]] [get_pins "*ps7_foo/FCLKCLK[0]"] set_input_jitter clk_fpga_0 [expr 0.3 * [get_property CLKIN1_PERIOD [get_cells -hierarchical ps7_clockGen_pll]]] set_clock_groups -asynchronous -group {clk_fpga_0} create_clock -name clk_fpga_1 -period "6" [get_pins "*ps7_foo/FCLKCLK[1]"] set_input_jitter clk_fpga_1 0.6 set_clock_groups -asynchronous -group {clk_fpga_1} create_clock -name clk_fpga_3 -period "5" [get_pins "*ps7_foo/FCLKCLK[3]"] set_input_jitter clk_fpga_3 0.6 set_clock_groups -asynchronous -group {clk_fpga_3} create_clock -name bscan_refclk -period 20 [get_pins -hier -filter {NAME=~"*/bscan_mytck/O"}] ############################################################################ # I/O STANDARDS and Location Constraints # ############################################################################ set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrp"] set_property PACKAGE_PIN "N7" [get_ports "FIXED_IO_ddr_vrp"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrp"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrp"] set_property iostandard "SSTL15_T_DCI" [get_ports "FIXED_IO_ddr_vrn"] set_property PACKAGE_PIN "M7" [get_ports "FIXED_IO_ddr_vrn"] set_property slew "FAST" [get_ports "FIXED_IO_ddr_vrn"] set_property PIO_DIRECTION "BIDIR" [get_ports "FIXED_IO_ddr_vrn"] set_property iostandard "SSTL15" [get_ports "DDR_WEB"] set_property PACKAGE_PIN "R4" [get_ports "DDR_WEB"] set_property slew "SLOW" [get_ports "DDR_WEB"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_WEB"] set_property iostandard "SSTL15" [get_ports "DDR_RAS_n"] set_property PACKAGE_PIN "R5" [get_ports "DDR_RAS_n"] set_property slew "SLOW" [get_ports "DDR_RAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_RAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_ODT"] set_property PACKAGE_PIN "P5" [get_ports "DDR_ODT"] set_property slew "SLOW" [get_ports "DDR_ODT"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_ODT"] set_property iostandard "SSTL15" [get_ports "DDR_DRSTB"] set_property PACKAGE_PIN "F3" [get_ports "DDR_DRSTB"] set_property slew "FAST" [get_ports "DDR_DRSTB"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DRSTB"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[3]"] set_property PACKAGE_PIN "V2" [get_ports "DDR_DQS_p[3]"] set_property slew "FAST" [get_ports "DDR_DQS_p[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[2]"] set_property PACKAGE_PIN "N2" [get_ports "DDR_DQS_p[2]"] set_property slew "FAST" [get_ports "DDR_DQS_p[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[1]"] set_property PACKAGE_PIN "H2" [get_ports "DDR_DQS_p[1]"] set_property slew "FAST" [get_ports "DDR_DQS_p[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_p[0]"] set_property PACKAGE_PIN "C2" [get_ports "DDR_DQS_p[0]"] set_property slew "FAST" [get_ports "DDR_DQS_p[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_p[0]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[3]"] set_property PACKAGE_PIN "W2" [get_ports "DDR_DQS_n[3]"] set_property slew "FAST" [get_ports "DDR_DQS_n[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[3]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[2]"] set_property PACKAGE_PIN "P2" [get_ports "DDR_DQS_n[2]"] set_property slew "FAST" [get_ports "DDR_DQS_n[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[2]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[1]"] set_property PACKAGE_PIN "J2" [get_ports "DDR_DQS_n[1]"] set_property slew "FAST" [get_ports "DDR_DQS_n[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[1]"] set_property iostandard "DIFF_SSTL15_T_DCI" [get_ports "DDR_DQS_n[0]"] set_property PACKAGE_PIN "D2" [get_ports "DDR_DQS_n[0]"] set_property slew "FAST" [get_ports "DDR_DQS_n[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQS_n[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[9]"] set_property PACKAGE_PIN "G1" [get_ports "DDR_DQ[9]"] set_property slew "FAST" [get_ports "DDR_DQ[9]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[9]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[8]"] set_property PACKAGE_PIN "G2" [get_ports "DDR_DQ[8]"] set_property slew "FAST" [get_ports "DDR_DQ[8]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[8]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[7]"] set_property PACKAGE_PIN "F1" [get_ports "DDR_DQ[7]"] set_property slew "FAST" [get_ports "DDR_DQ[7]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[7]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[6]"] set_property PACKAGE_PIN "F2" [get_ports "DDR_DQ[6]"] set_property slew "FAST" [get_ports "DDR_DQ[6]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[6]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[5]"] set_property PACKAGE_PIN "E1" [get_ports "DDR_DQ[5]"] set_property slew "FAST" [get_ports "DDR_DQ[5]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[5]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[4]"] set_property PACKAGE_PIN "E3" [get_ports "DDR_DQ[4]"] set_property slew "FAST" [get_ports "DDR_DQ[4]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[4]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[3]"] set_property PACKAGE_PIN "D3" [get_ports "DDR_DQ[3]"] set_property slew "FAST" [get_ports "DDR_DQ[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[31]"] set_property PACKAGE_PIN "Y1" [get_ports "DDR_DQ[31]"] set_property slew "FAST" [get_ports "DDR_DQ[31]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[31]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[30]"] set_property PACKAGE_PIN "W3" [get_ports "DDR_DQ[30]"] set_property slew "FAST" [get_ports "DDR_DQ[30]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[30]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[2]"] set_property PACKAGE_PIN "B2" [get_ports "DDR_DQ[2]"] set_property slew "FAST" [get_ports "DDR_DQ[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[29]"] set_property PACKAGE_PIN "Y3" [get_ports "DDR_DQ[29]"] set_property slew "FAST" [get_ports "DDR_DQ[29]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[29]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[28]"] set_property PACKAGE_PIN "W1" [get_ports "DDR_DQ[28]"] set_property slew "FAST" [get_ports "DDR_DQ[28]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[28]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[27]"] set_property PACKAGE_PIN "U2" [get_ports "DDR_DQ[27]"] set_property slew "FAST" [get_ports "DDR_DQ[27]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[27]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[26]"] set_property PACKAGE_PIN "AA1" [get_ports "DDR_DQ[26]"] set_property slew "FAST" [get_ports "DDR_DQ[26]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[26]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[25]"] set_property PACKAGE_PIN "U1" [get_ports "DDR_DQ[25]"] set_property slew "FAST" [get_ports "DDR_DQ[25]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[25]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[24]"] set_property PACKAGE_PIN "AA3" [get_ports "DDR_DQ[24]"] set_property slew "FAST" [get_ports "DDR_DQ[24]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[24]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[23]"] set_property PACKAGE_PIN "R1" [get_ports "DDR_DQ[23]"] set_property slew "FAST" [get_ports "DDR_DQ[23]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[23]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[22]"] set_property PACKAGE_PIN "M2" [get_ports "DDR_DQ[22]"] set_property slew "FAST" [get_ports "DDR_DQ[22]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[22]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[21]"] set_property PACKAGE_PIN "T2" [get_ports "DDR_DQ[21]"] set_property slew "FAST" [get_ports "DDR_DQ[21]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[21]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[20]"] set_property PACKAGE_PIN "R3" [get_ports "DDR_DQ[20]"] set_property slew "FAST" [get_ports "DDR_DQ[20]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[20]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[1]"] set_property PACKAGE_PIN "C3" [get_ports "DDR_DQ[1]"] set_property slew "FAST" [get_ports "DDR_DQ[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[19]"] set_property PACKAGE_PIN "T1" [get_ports "DDR_DQ[19]"] set_property slew "FAST" [get_ports "DDR_DQ[19]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[19]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[18]"] set_property PACKAGE_PIN "N3" [get_ports "DDR_DQ[18]"] set_property slew "FAST" [get_ports "DDR_DQ[18]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[18]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[17]"] set_property PACKAGE_PIN "T3" [get_ports "DDR_DQ[17]"] set_property slew "FAST" [get_ports "DDR_DQ[17]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[17]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[16]"] set_property PACKAGE_PIN "M1" [get_ports "DDR_DQ[16]"] set_property slew "FAST" [get_ports "DDR_DQ[16]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[16]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[15]"] set_property PACKAGE_PIN "K3" [get_ports "DDR_DQ[15]"] set_property slew "FAST" [get_ports "DDR_DQ[15]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[15]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[14]"] set_property PACKAGE_PIN "J1" [get_ports "DDR_DQ[14]"] set_property slew "FAST" [get_ports "DDR_DQ[14]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[14]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[13]"] set_property PACKAGE_PIN "K1" [get_ports "DDR_DQ[13]"] set_property slew "FAST" [get_ports "DDR_DQ[13]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[13]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[12]"] set_property PACKAGE_PIN "L3" [get_ports "DDR_DQ[12]"] set_property slew "FAST" [get_ports "DDR_DQ[12]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[12]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[11]"] set_property PACKAGE_PIN "L2" [get_ports "DDR_DQ[11]"] set_property slew "FAST" [get_ports "DDR_DQ[11]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[11]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[10]"] set_property PACKAGE_PIN "L1" [get_ports "DDR_DQ[10]"] set_property slew "FAST" [get_ports "DDR_DQ[10]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[10]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DQ[0]"] set_property PACKAGE_PIN "D1" [get_ports "DDR_DQ[0]"] set_property slew "FAST" [get_ports "DDR_DQ[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DQ[0]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[3]"] set_property PACKAGE_PIN "AA2" [get_ports "DDR_DM[3]"] set_property slew "FAST" [get_ports "DDR_DM[3]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[3]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[2]"] set_property PACKAGE_PIN "P1" [get_ports "DDR_DM[2]"] set_property slew "FAST" [get_ports "DDR_DM[2]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[2]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[1]"] set_property PACKAGE_PIN "H3" [get_ports "DDR_DM[1]"] set_property slew "FAST" [get_ports "DDR_DM[1]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[1]"] set_property iostandard "SSTL15_T_DCI" [get_ports "DDR_DM[0]"] set_property PACKAGE_PIN "B1" [get_ports "DDR_DM[0]"] set_property slew "FAST" [get_ports "DDR_DM[0]"] set_property PIO_DIRECTION "BIDIR" [get_ports "DDR_DM[0]"] set_property iostandard "SSTL15" [get_ports "DDR_CS_n"] set_property PACKAGE_PIN "P6" [get_ports "DDR_CS_n"] set_property slew "SLOW" [get_ports "DDR_CS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CS_n"] set_property iostandard "SSTL15" [get_ports "DDR_CKE"] set_property PACKAGE_PIN "V3" [get_ports "DDR_CKE"] set_property slew "SLOW" [get_ports "DDR_CKE"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CKE"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_p"] set_property PACKAGE_PIN "N4" [get_ports "DDR_Clk_p"] set_property slew "FAST" [get_ports "DDR_Clk_p"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_p"] set_property iostandard "DIFF_SSTL15" [get_ports "DDR_Clk_n"] set_property PACKAGE_PIN "N5" [get_ports "DDR_Clk_n"] set_property slew "FAST" [get_ports "DDR_Clk_n"] set_property PIO_DIRECTION "INPUT" [get_ports "DDR_Clk_n"] set_property iostandard "SSTL15" [get_ports "DDR_CAS_n"] set_property PACKAGE_PIN "P3" [get_ports "DDR_CAS_n"] set_property slew "SLOW" [get_ports "DDR_CAS_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_CAS_n"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[2]"] set_property PACKAGE_PIN "M6" [get_ports "DDR_BankAddr[2]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[1]"] set_property PACKAGE_PIN "L6" [get_ports "DDR_BankAddr[1]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_BankAddr[0]"] set_property PACKAGE_PIN "L7" [get_ports "DDR_BankAddr[0]"] set_property slew "SLOW" [get_ports "DDR_BankAddr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_BankAddr[0]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[9]"] set_property PACKAGE_PIN "H5" [get_ports "DDR_Addr[9]"] set_property slew "SLOW" [get_ports "DDR_Addr[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[9]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[8]"] set_property PACKAGE_PIN "J5" [get_ports "DDR_Addr[8]"] set_property slew "SLOW" [get_ports "DDR_Addr[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[8]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[7]"] set_property PACKAGE_PIN "J6" [get_ports "DDR_Addr[7]"] set_property slew "SLOW" [get_ports "DDR_Addr[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[7]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[6]"] set_property PACKAGE_PIN "J7" [get_ports "DDR_Addr[6]"] set_property slew "SLOW" [get_ports "DDR_Addr[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[6]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[5]"] set_property PACKAGE_PIN "K5" [get_ports "DDR_Addr[5]"] set_property slew "SLOW" [get_ports "DDR_Addr[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[5]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[4]"] set_property PACKAGE_PIN "K6" [get_ports "DDR_Addr[4]"] set_property slew "SLOW" [get_ports "DDR_Addr[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[4]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[3]"] set_property PACKAGE_PIN "L4" [get_ports "DDR_Addr[3]"] set_property slew "SLOW" [get_ports "DDR_Addr[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[3]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[2]"] set_property PACKAGE_PIN "K4" [get_ports "DDR_Addr[2]"] set_property slew "SLOW" [get_ports "DDR_Addr[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[2]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[1]"] set_property PACKAGE_PIN "M5" [get_ports "DDR_Addr[1]"] set_property slew "SLOW" [get_ports "DDR_Addr[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[1]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[14]"] set_property PACKAGE_PIN "G4" [get_ports "DDR_Addr[14]"] set_property slew "SLOW" [get_ports "DDR_Addr[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[14]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[13]"] set_property PACKAGE_PIN "F4" [get_ports "DDR_Addr[13]"] set_property slew "SLOW" [get_ports "DDR_Addr[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[13]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[12]"] set_property PACKAGE_PIN "H4" [get_ports "DDR_Addr[12]"] set_property slew "SLOW" [get_ports "DDR_Addr[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[12]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[11]"] set_property PACKAGE_PIN "G5" [get_ports "DDR_Addr[11]"] set_property slew "SLOW" [get_ports "DDR_Addr[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[11]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[10]"] set_property PACKAGE_PIN "J3" [get_ports "DDR_Addr[10]"] set_property slew "SLOW" [get_ports "DDR_Addr[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[10]"] set_property iostandard "SSTL15" [get_ports "DDR_Addr[0]"] set_property PACKAGE_PIN "M4" [get_ports "DDR_Addr[0]"] set_property slew "SLOW" [get_ports "DDR_Addr[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "DDR_Addr[0]"] ================================================ FILE: constraints/xilinx/zcu102.xdc ================================================ ## TBD ================================================ FILE: constraints/xilinx/zcu111.xdc ================================================ ## TBD ================================================ FILE: constraints/xilinx/zybo.xdc ================================================ set_property iostandard "LVCMOS25" [get_ports "GPIO_leds[0]"] set_property PACKAGE_PIN "M14" [get_ports "GPIO_leds[0]"] set_property slew "SLOW" [get_ports "GPIO_leds[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[0]"] set_property iostandard "LVCMOS25" [get_ports "GPIO_leds[1]"] set_property PACKAGE_PIN "M15" [get_ports "GPIO_leds[1]"] set_property slew "SLOW" [get_ports "GPIO_leds[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[1]"] set_property iostandard "LVCMOS25" [get_ports "GPIO_leds[2]"] set_property PACKAGE_PIN "G14" [get_ports "GPIO_leds[2]"] set_property slew "SLOW" [get_ports "GPIO_leds[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[2]"] set_property iostandard "LVCMOS25" [get_ports "GPIO_leds[3]"] set_property PACKAGE_PIN "D18" [get_ports "GPIO_leds[3]"] set_property slew "SLOW" [get_ports "GPIO_leds[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[3]"] ================================================ FILE: constraints/xilinx/zynq100.xdc ================================================ set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[0]"] set_property PACKAGE_PIN "A17" [get_ports "GPIO_leds[0]"] set_property slew "SLOW" [get_ports "GPIO_leds[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[0]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[1]"] set_property PACKAGE_PIN "W21" [get_ports "GPIO_leds[1]"] set_property slew "SLOW" [get_ports "GPIO_leds[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[1]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[2]"] set_property PACKAGE_PIN "G2" [get_ports "GPIO_leds[2]"] set_property slew "SLOW" [get_ports "GPIO_leds[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[2]"] set_property iostandard "LVCMOS18" [get_ports "GPIO_leds[3]"] set_property PACKAGE_PIN "Y21" [get_ports "GPIO_leds[3]"] set_property slew "SLOW" [get_ports "GPIO_leds[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "GPIO_leds[3]"] set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[0]"] set_property PACKAGE_PIN "H14" [get_ports "XADC_gpio[0]"] set_property slew "SLOW" [get_ports "XADC_gpio[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[0]"] set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[1]"] set_property PACKAGE_PIN "J15" [get_ports "XADC_gpio[1]"] set_property slew "SLOW" [get_ports "XADC_gpio[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[1]"] set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[2]"] set_property PACKAGE_PIN "J16" [get_ports "XADC_gpio[2]"] set_property slew "SLOW" [get_ports "XADC_gpio[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[2]"] set_property iostandard "LVCMOS18" [get_ports "XADC_gpio[3]"] set_property PACKAGE_PIN "J14" [get_ports "XADC_gpio[3]"] set_property slew "SLOW" [get_ports "XADC_gpio[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "XADC_gpio[3]"] # PS_MIO50 set_property PACKAGE_PIN "A19" [get_ports "I2C0_scl"] # PS_MIO51 set_property PACKAGE_PIN "F19" [get_ports "I2C0_sda"] ================================================ FILE: contrib/bluescope/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = MemcpyRequest BlueScopeRequest MemcpyIndication BlueScopeIndication MemServerIndication BSVFILES = Memcpy.bsv $(CONNECTALDIR)/lib/bsv/BlueScope.bsv Top.bsv CPPFILES=testbluescope.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/bluescope/Memcpy.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFOF::*; import GetPut::*; import FIFO::*; import Connectable::*; import ClientServer::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import BlueScope::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; interface MemcpyRequest; method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface MemcpyIndication; method Action started(); method Action done(); endinterface interface Memcpy; interface MemcpyRequest request; interface MemReadClient#(64) readClient; interface MemWriteClient#(64) writeClient; endinterface module mkMemcpyRequest#(MemcpyIndication indication, BlueScope#(64) bs)(Memcpy); MemReadEngine#(64,64,1,1) re <- mkMemReadEngine; MemWriteEngine#(64,64,1,1) we <- mkMemWriteEngine; Reg#(Bit#(32)) iterCnt <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(SGLId) rdPointer <- mkReg(0); Reg#(SGLId) wrPointer <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); FIFO#(void) doneFifo <- mkFIFO; rule start(iterCnt > 0); re.readServers[0].request.put(MemengineCmd{sglId:rdPointer, base:0, len:numWords*4, burstLen:truncate(burstLen*4)}); we.writeServers[0].request.put(MemengineCmd{sglId:wrPointer, base:0, len:numWords*4, burstLen:truncate(burstLen*4)}); iterCnt <= iterCnt-1; endrule rule finish; doneFifo.deq; let rv1 <- we.writeServers[0].done.get; if(iterCnt==0) begin indication.done; end endrule rule xfer; let v <- toGet(re.readServers[0].data).get; we.writeServers[0].data.enq(v.data); bs.dataIn(v.data,v.data); if (v.last) doneFifo.enq(?); endrule interface MemcpyRequest request; method Action startCopy(Bit#(32) wp, Bit#(32) rp, Bit#(32) nw, Bit#(32) bl); $display("startCopy wrPointer=%d rdPointer=%d numWords=%h burstLen=%d", wp, rp, nw, bl); indication.started; // initialized wrPointer <= wp; rdPointer <= rp; numWords <= nw; iterCnt <= 1; burstLen <= bl; endmethod endinterface interface readClient = re.dmaClient; interface writeClient = we.dmaClient; endmodule ================================================ FILE: contrib/bluescope/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import BlueScope::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import MemcpyRequest::*; import BlueScopeRequest::*; import MemServerRequest::*; import MMURequest::*; import MemcpyIndication::*; import BlueScopeIndication::*; import MemServerIndication::*; import MMUIndication::*; import Memcpy::*; `define BluescopeSampleLength 8 typedef enum {IfcNames_MemcpyIndication, IfcNames_MemcpyRequest, IfcNames_HostMemServerIndication, IfcNames_HostMemServerRequest, IfcNames_HostMMURequest, IfcNames_HostMMUIndication, IfcNames_BluescopeIndication, IfcNames_BluescopeRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalDmaTop#(PhysAddrWidth)); BlueScopeIndicationProxy blueScopeIndicationProxy <- mkBlueScopeIndicationProxy(IfcNames_BluescopeIndication); BlueScope#(64) bs <- mkBlueScope(`BluescopeSampleLength, blueScopeIndicationProxy.ifc); BlueScopeRequestWrapper blueScopeRequestWrapper <- mkBlueScopeRequestWrapper(IfcNames_BluescopeRequest,bs.requestIfc); MemcpyIndicationProxy memcpyIndicationProxy <- mkMemcpyIndicationProxy(IfcNames_MemcpyIndication); Memcpy memcpy <- mkMemcpyRequest(memcpyIndicationProxy.ifc, bs); MemcpyRequestWrapper memcpyRequestWrapper <- mkMemcpyRequestWrapper(IfcNames_MemcpyRequest,memcpy.request); Vector#(1, MemReadClient#(64)) readClients = newVector(); readClients[0] = memcpy.readClient; Vector#(2, MemWriteClient#(64)) writeClients = newVector(); writeClients[0] = bs.writeClient; writeClients[1] = memcpy.writeClient; MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_HostMMUIndication); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_HostMMURequest, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_HostMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(readClients, writeClients, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_HostMemServerRequest, dma.request); Vector#(8,StdPortal) portals; portals[0] = memcpyRequestWrapper.portalIfc; portals[1] = memcpyIndicationProxy.portalIfc; portals[2] = blueScopeRequestWrapper.portalIfc; portals[3] = blueScopeIndicationProxy.portalIfc; portals[4] = hostMemServerRequestWrapper.portalIfc; portals[5] = hostMemServerIndicationProxy.portalIfc; portals[6] = hostMMURequestWrapper.portalIfc; portals[7] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: contrib/bluescope/testbluescope.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "dmaManager.h" #include "BlueScopeIndication.h" #include "BlueScopeRequest.h" #include "MemcpyIndication.h" #include "MemcpyRequest.h" sem_t done_sem; int srcAlloc; int dstAlloc; int bsAlloc; unsigned int *srcBuffer = 0; unsigned int *dstBuffer = 0; unsigned int *bsBuffer = 0; int numWords = 128; //16 << 10; size_t alloc_sz = numWords*sizeof(unsigned int); bool trigger_fired = false; bool finished = false; bool memcmp_fail = false; unsigned int memcmp_count = 0; static void memdump(void *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) fprintf(stderr, "\n"); fprintf(stderr, "%s: ",title); } fprintf(stderr, "%02x ", *(unsigned char *)p); p = (unsigned char *)p + 1; i++; len--; } fprintf(stderr, "\n"); } void exit_test() { fprintf(stderr, "testmemcpy finished count=%d memcmp_fail=%d, trigger_fired=%d\n", memcmp_count, memcmp_fail, trigger_fired); exit(memcmp_fail || !trigger_fired); } class MemcpyIndication : public MemcpyIndicationWrapper { public: MemcpyIndication(unsigned int id) : MemcpyIndicationWrapper(id){} virtual void started(){ fprintf(stderr, "started"); } virtual void done() { sem_post(&done_sem); finished = true; unsigned int mcf = memcmp(srcBuffer, dstBuffer, numWords*sizeof(unsigned int)); memcmp_fail |= mcf; fprintf(stderr, "memcpy done:\n"); fprintf(stderr, "(%d) memcmp src=%lx dst=%lx success=%s\n", memcmp_count, (long)srcBuffer, (long)dstBuffer, mcf == 0 ? "pass" : "fail"); memdump(srcBuffer, 128, "src"); memdump(dstBuffer, 128, "dst"); memdump(bsBuffer, 128, "dbg"); } }; class BlueScopeIndication : public BlueScopeIndicationWrapper { public: BlueScopeIndication(unsigned int id) : BlueScopeIndicationWrapper(id){} virtual void done( ){ fprintf(stderr, "BlueScope::done\n"); } virtual void triggerFired( ){ fprintf(stderr, "BlueScope::triggerFired\n"); trigger_fired = true; } virtual void reportStateDbg(uint64_t mask, uint64_t value){ fprintf(stderr, "BlueScope::reportStateDbg mask=%" PRIu64 ", value=%" PRIu64 "\n", mask, value); } }; // we can use the data synchronization barrier instead of flushing the // cache only because the ps7 is configured to run in buffered-write mode // // an opc2 of '4' and CRm of 'c10' encodes "CP15DSB, Data Synchronization Barrier // operation". this is a legal instruction to execute in non-privileged mode (mdk) // // #define DATA_SYNC_BARRIER __asm __volatile( "MCR p15, 0, %0, c7, c10, 4" :: "r" (0) ); int main(int argc, const char **argv) { MemcpyRequestProxy *device = 0; BlueScopeRequestProxy *bluescope = 0; MemcpyIndication *deviceIndication = 0; BlueScopeIndication *bluescopeIndication = 0; if(sem_init(&done_sem, 1, 0)){ fprintf(stderr, "failed to init done_sem\n"); exit(1); } fprintf(stderr, "%s %s\n", __DATE__, __TIME__); device = new MemcpyRequestProxy(IfcNames_MemcpyRequest); bluescope = new BlueScopeRequestProxy(IfcNames_BluescopeRequest); DmaManager *dma = platformInit(); deviceIndication = new MemcpyIndication(IfcNames_MemcpyIndication); bluescopeIndication = new BlueScopeIndication(IfcNames_BluescopeIndication); fprintf(stderr, "Main::allocating memory of size=%d...\n", (int)alloc_sz); srcAlloc = portalAlloc(alloc_sz, 0); dstAlloc = portalAlloc(alloc_sz, 0); bsAlloc = portalAlloc(alloc_sz, 0); // for(int i = 0; i < srcAlloc->header.numEntries; i++) // fprintf(stderr, "%lx %lx\n", srcAlloc->entries[i].dma_address, srcAlloc->entries[i].length); // for(int i = 0; i < dstAlloc->header.numEntries; i++) // fprintf(stderr, "%lx %lx\n", dstAlloc->entries[i].dma_address, dstAlloc->entries[i].length); // for(int i = 0; i < bsAlloc->header.numEntries; i++) // fprintf(stderr, "%lx %lx\n", bsAlloc->entries[i].dma_address, bsAlloc->entries[i].length); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); bsBuffer = (unsigned int *)portalMmap(bsAlloc, alloc_sz); for (int i = 0; i < numWords; i++){ srcBuffer[i] = i; dstBuffer[i] = 0x5a5abeef; bsBuffer[i] = 0x5a5abeef; } portalCacheFlush(bsAlloc, bsBuffer, alloc_sz, 1); portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); unsigned int ref_dstAlloc = dma->reference(dstAlloc); unsigned int ref_bsAlloc = dma->reference(bsAlloc); bluescope->reset(); bluescope->setTriggerMask (0xFFFFFFFF); bluescope->setTriggerValue(0x00000008); bluescope->start(ref_bsAlloc, alloc_sz); sleep(1); //hostMemServerRequest->addrRequest(ref_srcAlloc, 1*sizeof(unsigned int)); sleep(1); //hostMemServerRequest->addrRequest(ref_dstAlloc, 2*sizeof(unsigned int)); sleep(1); //hostMemServerRequest->addrRequest(ref_bsAlloc, 3*sizeof(unsigned int)); sleep(1); fprintf(stderr, "Main::starting mempcy numWords:%d\n", numWords); int burstLen = 16; device->startCopy(ref_dstAlloc, ref_srcAlloc, numWords, burstLen); sem_wait(&done_sem); sleep(2); exit_test(); } ================================================ FILE: contrib/bluescopeevent/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SignalGenRequest SignalGenIndication \ BlueScopeEventRequest BlueScopeEventIndication BSVFILES = ../../lib/bsv/BlueScopeEvent.bsv SignalGen.bsv Top.bsv CPPFILES=testbluescopeevent.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/bluescopeevent/SignalGen.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BlueScopeEvent::*; interface SignalGenIndication; method Action ack1(Bit#(32) d1); method Action ack2(Bit#(32) d1, Bit#(32) d2); endinterface interface SignalGenRequest; method Action send1(Bit#(32) d1); endinterface module mkSignalGen#(BlueScopeEvent#(32) bse, SignalGenIndication indication)(SignalGenRequest); method Action send1(Bit#(32) d1); bse.dataIn(d1); indication.ack1(d1); endmethod endmodule ================================================ FILE: contrib/bluescopeevent/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import BlueScopeEvent::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import SignalGen::*; import BlueScopeEventRequest::*; import BlueScopeEventIndication::*; import MemServerRequest::*; import MemServerIndication::*; import MMURequest::*; import MMUIndication::*; import SignalGenRequest::*; import SignalGenIndication::*; `define BlueScopeEventSampleLength 512 typedef enum {IfcNames_HostMemServerIndication, IfcNames_HostMemServerRequest, IfcNames_HostMMURequest, IfcNames_HostMMUIndication, IfcNames_BlueScopeEventIndication, IfcNames_BlueScopeEventRequest, IfcNames_SignalGenIndication, IfcNames_SignalGenRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); BlueScopeEventIndicationProxy blueScopeEventIndicationProxy <- mkBlueScopeEventIndicationProxy(IfcNames_BlueScopeEventIndication); BlueScopeEventControl#(32) bs <- mkBlueScopeEvent(`BlueScopeEventSampleLength, blueScopeEventIndicationProxy.ifc); BlueScopeEventRequestWrapper blueScopeEventRequestWrapper <- mkBlueScopeEventRequestWrapper(IfcNames_BlueScopeEventRequest,bs.requestIfc); SignalGenIndicationProxy signalGenIndicationProxy <- mkSignalGenIndicationProxy(IfcNames_SignalGenIndication); SignalGenRequest sg <- mkSignalGen(bs.bse, signalGenIndicationProxy.ifc); SignalGenRequestWrapper signalGenRequestWrapper <- mkSignalGenRequestWrapper(IfcNames_SignalGenRequest,sg); Vector#(1, MemWriteClient#(DataBusWidth)) writeClients = newVector(); writeClients[0] = bs.writeClient; MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_HostMMUIndication); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_HostMMURequest, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_HostMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(nil, writeClients, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_HostMemServerRequest, dma.request); Vector#(8,StdPortal) portals; portals[0] = signalGenRequestWrapper.portalIfc; portals[1] = signalGenIndicationProxy.portalIfc; portals[2] = blueScopeEventRequestWrapper.portalIfc; portals[3] = blueScopeEventIndicationProxy.portalIfc; portals[4] = hostMemServerRequestWrapper.portalIfc; portals[5] = hostMemServerIndicationProxy.portalIfc; portals[6] = hostMMURequestWrapper.portalIfc; portals[7] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: contrib/bluescopeevent/testbluescopeevent.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "dmaManager.h" #include "BlueScopeEventIndication.h" #include "BlueScopeEventRequest.h" #include "SignalGenIndication.h" #include "SignalGenRequest.h" sem_t done_sem; sem_t cv_sem; unsigned int counter_value = 0; int bsAlloc; uint64_t *bsBuffer = 0; int numWords = 512; //16 << 10; size_t alloc_sz = numWords*sizeof(uint64_t); bool finished = false; void exit_test() { fprintf(stderr, "test finished\n"); exit(0); } class BlueScopeEventIndication : public BlueScopeEventIndicationWrapper { public: BlueScopeEventIndication(unsigned int id) : BlueScopeEventIndicationWrapper(id){} virtual void dmaDone( ){ sem_post(&done_sem); finished = true; fprintf(stderr, "BlueScopeEvent::dmaDone\n"); } virtual void counterValue(uint32_t v){ counter_value = v; sem_post(&cv_sem); fprintf(stderr, "BlueScopeEvent::counterValue value=%u\n", v); } }; class SignalGenIndication : public SignalGenIndicationWrapper { public: SignalGenIndication(unsigned int id) : SignalGenIndicationWrapper(id){} virtual void ack1(unsigned int d1 ){ fprintf(stderr, "SignalGen::ack1(%d)\n", d1); } virtual void ack2(unsigned int d1, unsigned int d2){ fprintf(stderr, "SignalGen::ack2(%d, %d)\n", d1, d2); } }; // we can use the data synchronization barrier instead of flushing the // cache only because the ps7 is configured to run in buffered-write mode // // an opc2 of '4' and CRm of 'c10' encodes "CP15DSB, Data Synchronization Barrier // operation". this is a legal instruction to execute in non-privileged mode (mdk) // // #define DATA_SYNC_BARRIER __asm __volatile( "MCR p15, 0, %0, c7, c10, 4" :: "r" (0) ); int main(int argc, const char **argv) { BlueScopeEventRequestProxy *bluescope = 0; BlueScopeEventIndication *bluescopeIndication = 0; SignalGenRequestProxy *signalgen = 0; SignalGenIndication *signalgenIndication = 0; int i; if(sem_init(&done_sem, 1, 0)){ fprintf(stderr, "failed to init done_sem\n"); exit(1); } if(sem_init(&cv_sem, 1, 0)){ fprintf(stderr, "failed to init cv_sem\n"); exit(1); } fprintf(stderr, "%s %s\n", __DATE__, __TIME__); bluescope = new BlueScopeEventRequestProxy(IfcNames_BlueScopeEventRequest); DmaManager *dma = platformInit(); bluescopeIndication = new BlueScopeEventIndication(IfcNames_BlueScopeEventIndication); signalgen = new SignalGenRequestProxy(IfcNames_SignalGenRequest); signalgenIndication = new SignalGenIndication(IfcNames_SignalGenIndication); fprintf(stderr, "Main::allocating memory of size=%d...\n", (int)alloc_sz); bsAlloc = portalAlloc(alloc_sz, 0); bsBuffer = (uint64_t *)portalMmap(bsAlloc, alloc_sz); portalCacheFlush(bsAlloc, bsBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); unsigned int ref_bsAlloc = dma->reference(bsAlloc); bluescope->doReset(); bluescope->setTriggerMask (0xFFFFFFFF); bluescope->getCounterValue(); sem_wait(&cv_sem); fprintf(stderr, "Main::initial BlueScopeEvent counterValue: %d\n", counter_value); sleep(1); signalgen->send1(0x1); fprintf(stderr, "Main::send1\n"); signalgen->send1(0x2); fprintf(stderr, "Main::send1\n"); signalgen->send1(0x3); fprintf(stderr, "Main::send1\n"); signalgen->send1(0x4); fprintf(stderr, "Main::send1\n"); bluescope->getCounterValue(); fprintf(stderr, "Main::getCounter\n"); sem_wait(&cv_sem); fprintf(stderr, "Main::final BlueScopeEvent counterValue: %d\n", counter_value); // test here if (counter_value != 4) counter_value = 4; bluescope->startDma(ref_bsAlloc, counter_value * sizeof(uint64_t)); sem_wait(&done_sem); for (i = 0; i < 5; i += 1) { fprintf(stderr, "event %3d: %08lx\n", i, bsBuffer[i]); } // XXX print event buffer sleep(2); exit_test(); } ================================================ FILE: contrib/bluescopeeventpio/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SignalGenRequest SignalGenIndication \ BlueScopeEventPIORequest BlueScopeEventPIOIndication BSVFILES = ../../lib/bsv/BlueScopeEventPIO.bsv SignalGen.bsv Top.bsv CPPFILES=testbluescopeeventpio.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/bluescopeeventpio/SignalGen.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BlueScopeEventPIO::*; interface SignalGenIndication; method Action ack1(Bit#(32) d1); endinterface interface SignalGenRequest; method Action send1(Bit#(32) d1); endinterface module mkSignalGen#(BlueScopeEventPIO#(32) bse, SignalGenIndication indication)(SignalGenRequest); method Action send1(Bit#(32) d1); bse.dataIn(d1); indication.ack1(d1); endmethod endmodule ================================================ FILE: contrib/bluescopeeventpio/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import BlueScopeEventPIO::*; import SignalGen::*; import BlueScopeEventPIORequest::*; import BlueScopeEventPIOIndication::*; import SignalGenRequest::*; import SignalGenIndication::*; `define BlueScopeEventPIOSampleLength 512 typedef enum {IfcNames_BlueScopeEventPIOIndication, IfcNames_BlueScopeEventPIORequest, IfcNames_SignalGenIndication, IfcNames_SignalGenRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); BlueScopeEventPIOIndicationProxy blueScopeEventPIOIndicationProxy <- mkBlueScopeEventPIOIndicationProxy(IfcNames_BlueScopeEventPIOIndication); BlueScopeEventPIOControl#(32) bs <- mkBlueScopeEventPIO(`BlueScopeEventPIOSampleLength, blueScopeEventPIOIndicationProxy.ifc); BlueScopeEventPIORequestWrapper blueScopeEventPIORequestWrapper <- mkBlueScopeEventPIORequestWrapper(IfcNames_BlueScopeEventPIORequest,bs.requestIfc); SignalGenIndicationProxy signalGenIndicationProxy <- mkSignalGenIndicationProxy(IfcNames_SignalGenIndication); SignalGenRequest sg <- mkSignalGen(bs.bse, signalGenIndicationProxy.ifc); SignalGenRequestWrapper signalGenRequestWrapper <- mkSignalGenRequestWrapper(IfcNames_SignalGenRequest,sg); Vector#(4,StdPortal) portals; portals[0] = signalGenRequestWrapper.portalIfc; portals[1] = signalGenIndicationProxy.portalIfc; portals[2] = blueScopeEventPIORequestWrapper.portalIfc; portals[3] = blueScopeEventPIOIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule ================================================ FILE: contrib/bluescopeeventpio/testbluescopeeventpio.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include "BlueScopeEventPIOIndication.h" #include "BlueScopeEventPIORequest.h" #include "SignalGenIndication.h" #include "SignalGenRequest.h" sem_t done_sem; sem_t cv_sem; unsigned int counter_value = 0; bool finished = false; void exit_test() { fprintf(stderr, "test finished\n"); exit(0); } class BlueScopeEventPIOIndication : public BlueScopeEventPIOIndicationWrapper { public: BlueScopeEventPIOIndication(unsigned int id) : BlueScopeEventPIOIndicationWrapper(id){} virtual void reportEvent(uint32_t v, uint32_t timestamp ){ fprintf(stderr, "BlueScopeEventPIO::reportEvent(%08x, %08x)\n", v, timestamp); } virtual void counterValue(uint32_t v){ counter_value = v; sem_post(&cv_sem); fprintf(stderr, "BlueScopeEventPIO::counterValue value=%u\n", v); } }; class SignalGenIndication : public SignalGenIndicationWrapper { public: SignalGenIndication(unsigned int id) : SignalGenIndicationWrapper(id){} virtual void ack1(unsigned int d1 ){ fprintf(stderr, "SignalGen::ack1(%d)\n", d1); } }; // we can use the data synchronization barrier instead of flushing the // cache only because the ps7 is configured to run in buffered-write mode // // an opc2 of '4' and CRm of 'c10' encodes "CP15DSB, Data Synchronization Barrier // operation". this is a legal instruction to execute in non-privileged mode (mdk) // // #define DATA_SYNC_BARRIER __asm __volatile( "MCR p15, 0, %0, c7, c10, 4" :: "r" (0) ); int main(int argc, const char **argv) { BlueScopeEventPIORequestProxy *bluescope = 0; BlueScopeEventPIOIndication *bluescopeIndication = 0; SignalGenRequestProxy *signalgen = 0; SignalGenIndication *signalgenIndication = 0; int i; if(sem_init(&done_sem, 1, 0)){ fprintf(stderr, "failed to init done_sem\n"); exit(1); } if(sem_init(&cv_sem, 1, 0)){ fprintf(stderr, "failed to init cv_sem\n"); exit(1); } fprintf(stderr, "%s %s\n", __DATE__, __TIME__); bluescope = new BlueScopeEventPIORequestProxy(IfcNames_BlueScopeEventPIORequest); bluescopeIndication = new BlueScopeEventPIOIndication(IfcNames_BlueScopeEventPIOIndication); signalgen = new SignalGenRequestProxy(IfcNames_SignalGenRequest); signalgenIndication = new SignalGenIndication(IfcNames_SignalGenIndication); bluescope->doReset(); bluescope->setTriggerMask (0xFFFFFFFF); bluescope->getCounterValue(); bluescope->enableIndications(1); sem_wait(&cv_sem); fprintf(stderr, "Main::initial BlueScopeEventPIO counterValue: %d\n", counter_value); sleep(1); signalgen->send1(0x1); fprintf(stderr, "Main::send1\n"); signalgen->send1(0x2); fprintf(stderr, "Main::send1\n"); signalgen->send1(0x3); fprintf(stderr, "Main::send1\n"); signalgen->send1(0x4); fprintf(stderr, "Main::send1\n"); bluescope->getCounterValue(); fprintf(stderr, "Main::getCounter\n"); sem_wait(&cv_sem); fprintf(stderr, "Main::final BlueScopeEventPIO counterValue: %d\n", counter_value); // test here // XXX print event buffer sleep(2); exit_test(); } ================================================ FILE: contrib/channelselect/ChannelSelect.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Complex::*; import FixedPoint::*; import SDRTypes::*; import FPCMult::*; import Gearbox::*; import Pipe::*; import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import BRAM::*; import BRAMFIFO::*; import Vector::*; import Clocks::*; import DefaultValue::*; import DDS::*; /* note rf signal is 64 bits wide, 2 sample of complex fixed point(0,16) */ (* always_enabled *) interface ChannelSelect; interface PipeIn#(Vector#(2, Complex#(Signal))) rfreq; interface PipeOut#(Complex#(Signal)) ifreq; method Action setCoeff(Bit#(11) addr, Complex#(FixedPoint#(2,23)) value); endinterface module mkChannelSelect#(Bit#(10) decimation, DDS dds)(ChannelSelect); BRAM_Configure cfg = defaultValue; cfg.memorySize = 1024; BRAM2Port#(Bit#(10), Complex#(FixedPoint#(2,23))) coeffRam0 <- mkBRAM2Server(cfg); BRAM2Port#(Bit#(10), Complex#(FixedPoint#(2,23))) coeffRam1 <- mkBRAM2Server(cfg); Reg#(Bit#(10)) filterPhase <- mkReg(0); FIFO#(Bit#(1)) delayFilterPhase <- mkSizedFIFO(3); // length > bram read latency FIFOF#(Vector#(2, Complex#(Signal))) infifo <- mkFIFOF(); FIFOF#(Complex#(Signal)) outfifo <- mkFIFOF(); Vector#(2, FPCMult) mul <- replicateM(mkFPCMult()); Vector#(2, Reg#(Complex#(Product))) accum <- replicateM(mkReg(?)); Vector#(2, FIFO#(Complex#(Product))) accumout <- replicateM(mkFIFO()); FIFO#(Complex#(Product)) ycombined <- mkFIFO(); FPCMult lo <- mkFPCMult(); /* could do this with mkForkVector() but we don't need the extra FIFOs since everything is ready every cycle */ rule duplicateSignal; let v = infifo.first; infifo.deq(); mul[0].x.enq(v[0]); mul[1].x.enq(v[1]); endrule rule filter_phase; $display("filter_phase %d dec %d\n", filterPhase, decimation ); if (filterPhase == (decimation - 1)) begin filterPhase <= 0; delayFilterPhase.enq(1); end else begin filterPhase <= filterPhase + 1; delayFilterPhase.enq(0); end coeffRam0.portB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: filterPhase, datain: ?}); coeffRam1.portB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: filterPhase, datain: ?}); endrule rule mulin; let c0 <- coeffRam0.portB.response.get(); let c1 <- coeffRam1.portB.response.get(); Bit#(1) phase = delayFilterPhase.first(); $write("mulin ph %d c0 ", phase); $write(fshow(c0)); $write(" c1 "); $write(fshow(c1)); $write("\n"); delayFilterPhase.deq(); mul[0].a.enq(CoeffData{a: c0, filterPhase: phase}); mul[1].a.enq(CoeffData{a: c1, filterPhase: phase}); endrule rule muloutaccumin0; ProductData m = mul[0].y.first(); mul[0].y.deq(); if (m.filterPhase == 1) begin accum[0] <= m.y; $write("muloutaccumin0 ph 1 "); $display(fshow(m.y)); accumout[0].enq(accum[0]); end else begin $write("muloutaccumin0 ph 0 "); $display(fshow(m.y)); accum[0] <= accum[0] + m.y; end endrule rule muloutaccumin1; ProductData m = mul[1].y.first(); mul[1].y.deq(); if (m.filterPhase == 1) begin $write("muloutaccumin1 ph 1 "); $display(fshow(m.y)); accum[1] <= m.y; accumout[1].enq(accum[1]); end else begin $write("muloutaccumin0 ph 0 "); $display(fshow(m.y)); accum[1] <= accum[1] + m.y; end endrule rule accumoutcombinein; Complex#(Product) a0 = accumout[0].first(); Complex#(Product) a1 = accumout[1].first(); ycombined.enq(a0 + a1); accumout[0].deq(); accumout[1].deq(); endrule rule combineoutloin; Complex#(Product) yin = ycombined.first(); FixedPoint#(2,16) yrel = fxptTruncate(yin.rel); FixedPoint#(2,16) yimg = fxptTruncate(yin.img); DDSOutType loin = dds.osc.first(); dds.osc.deq(); ycombined.deq(); lo.x.enq(Complex{rel: yrel, img: yimg}); lo.a.enq(CoeffData{a: loin, filterPhase: 0}); $write("combineoutloin x "); $write(fshow(Complex{rel: yrel, img: yimg})); $write(" loin "); $display(fshow(loin)); endrule rule loout; Complex#(Product) ifc = lo.y.first().y; FixedPoint#(2,16) ifrel = fxptTruncate(ifc.rel); FixedPoint#(2,16) ifimg = fxptTruncate(ifc.img); outfifo.enq(Complex{rel: ifrel, img: ifimg}); lo.y.deq(); $write("loout "); $display(fshow(Complex{rel: ifrel, img: ifimg})); endrule interface PipeIn rfreq = toPipeIn(infifo); method Action setCoeff(Bit#(11) addr, Complex#(FixedPoint#(2,23)) value); Bit#(1) idx = addr[0]; if (idx == 0) coeffRam0.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: addr[10:1], datain: value}); else coeffRam1.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: addr[10:1], datain: value}); endmethod interface PipeOut ifreq = toPipeOut(outfifo); endmodule ================================================ FILE: contrib/channelselect/ChannelSelectTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import DDS::*; import Gearbox::*; import ChannelSelect::*; import Complex::*; import SDRTypes::*; import FPCMult::*; import FixedPoint::*; import Pipe::*; import Vector::*; import ChannelSelectTestInterfaces::*; module mkChannelSelectTestRequest#(ChannelSelectTestIndication indication) (ChannelSelectTestRequest) provisos(Bits#(CoeffData, a__), Bits#(ProductData, b__), Bits#(MulData, c__)); Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; Gearbox#(1, 2, Complex#(Signal)) gb <- mk1toNGearbox(clk, rst, clk, rst); DDS dds <- mkDDS(); ChannelSelect cs <- mkChannelSelect(4, dds); rule processRF; let data = gb.first(); gb.deq(); cs.rfreq.enq(data); endrule rule processIF; let data = cs.ifreq.first(); cs.ifreq.deq(); indication.ifreqData(zeroExtend(pack(data.rel)), zeroExtend(pack(data.img))); endrule method Action rfreqDataWrite(Bit#(32) dataRe, Bit#(32) dataIm); Signal re = unpack(truncate(dataRe)); Signal im = unpack(truncate(dataIm)); Vector#(1, Complex#(Signal)) x = newVector(); x[0] = Complex{rel: re, img: im}; gb.enq(x); indication.setDataResp(); endmethod method Action setCoeff(Bit#(11) addr, Bit#(32) valueRe, Bit#(32) valueIm); FixedPoint#(2, 23) re = unpack(pack(truncate(valueRe))); FixedPoint#(2, 23) im = unpack(pack(truncate(valueIm))); cs.setCoeff(addr, Complex{rel: re, img:im}); indication.setConfigResp(); endmethod method Action setPhaseAdvance(Bit#(32) i, Bit#(32) f); dds.setPhaseAdvance(PhaseType{i: truncate(i), f: truncate(f)}); indication.setConfigResp(); endmethod endmodule ================================================ FILE: contrib/channelselect/ChannelSelectTestInterfaces.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. /* rfreqDataWrite data is FixedPoint(2,14) */ /* setCoeff data is FixedPoint(2, 23) */ interface ChannelSelectTestRequest; method Action rfreqDataWrite(Bit#(32) dataRe, Bit#(32) dataIm); method Action setCoeff(Bit#(11) addr, Bit#(32) valueRe, Bit#(32) valueIm); method Action setPhaseAdvance(Bit#(32) i, Bit#(32) f); endinterface /* rfreqDataWrite data is FixedPoint(2,14) */ interface ChannelSelectTestIndication; method Action ifreqData(Bit#(32) dataRe, Bit#(32) dataIm); method Action setDataResp(); method Action setConfigResp(); endinterface ================================================ FILE: contrib/channelselect/DDS.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Complex::*; import FixedPoint::*; //import StmtFSM::*; import BRAM::*; import FIFOF::*; import Pipe::*; import Vector::*; typedef Complex#(FixedPoint#(2,23)) DDSOutType; typedef FixedPoint#(10,23) PhaseType; interface DDS; method Action setPhaseAdvance(PhaseType v); method PhaseType getPhase(); interface PipeOut#(DDSOutType) osc; endinterface module mkDDS(DDS); BRAM_Configure cfg = defaultValue; cfg.memorySize = 1024; cfg.loadFormat = tagged Binary "sine.bin"; BRAM1Port#(Bit#(10), DDSOutType) ram <-mkBRAM1Server(cfg); FIFOF#(DDSOutType) ddsout <- mkFIFOF(); Reg#(PhaseType) phase <- mkReg(0); Reg#(PhaseType) phaseAdvance <- mkReg(0); /* Reg#(UInt#(12)) idx <- mkReg(0); Stmt dumpRam = seq for (idx <= 0; idx < 1024; idx <= idx + 1) seq ram.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: truncate(pack(idx)), datain: ?}); action let v <- ram.portA.response.get(); $display("adr %d", idx); $write( "re " ) ; fxptWrite( 10, v.rel ) ; $display("" ) ; $write( "im " ) ; fxptWrite( 10, v.img ) ; $display("" ) ; endaction endseq endseq; mkAutoFSM (dumpRam); */ rule filter_phase; Bit#(10) addr; phase <= phase + phaseAdvance; addr = phase.i; ram.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: addr, datain: ?}); // $display("dds addr %x\n", addr); endrule rule ddsoutrule; let v <- ram.portA.response.get(); // $write("ddsout ph %d " , phase); // $display(fshow(v)); ddsout.enq(v); endrule method Action setPhaseAdvance(PhaseType v); // $write("setphase advance "); $display(fshow(v)); phaseAdvance <= v; endmethod method PhaseType getPhase(); return(phase); endmethod interface PipeOut osc = toPipeOut(ddsout); endmodule ================================================ FILE: contrib/channelselect/DDSTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import DDS::*; import FixedPoint::*; import Complex::*; import Pipe::*; import DDSTestInterfaces::*; module mkDDSTestRequest#(DDSTestIndication indication) (DDSTestRequest); DDS dds <- mkDDS(); method Action setPhaseAdvance(Bit#(32) i, Bit#(32) f); dds.setPhaseAdvance(PhaseType{i: truncate(i), f: truncate(f)}); indication.setConfigResp(); endmethod method Action getData(); PhaseType p = dds.getPhase(); DDSOutType d = dds.osc.first(); dds.osc.deq(); indication.ddsData(zeroExtend(p.i), zeroExtend(pack(d.rel)), zeroExtend(pack(d.img))); endmethod endmodule ================================================ FILE: contrib/channelselect/DDSTestInterfaces.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. /* setPhaseAdvance data is FixedPoint(10, 23) */ interface DDSTestRequest; method Action setPhaseAdvance(Bit#(32) i, Bit#(32) f); method Action getData(); endinterface /* ddsData is Complex#(FixedPoint(2,23)) */ interface DDSTestIndication; method Action setConfigResp(); method Action ddsData(Bit#(32) phase, Bit#(32) dataRe, Bit#(32) dataIm); endinterface ================================================ FILE: contrib/channelselect/FPCMult.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This module implements a fixed point complex multiplication // that is intended to map smoothly onto the DSP slices in Xilinx // FPGAs. To this end, the signal path is 18 bits (2 bits of integer // and 16 bits of fraction), the coefficient path is 25 bits (2 bits // of integer and 23 bits of fraction), and the product is 43 bits // 4 bits of integer and 39 bits of fraction). The multiplier // in a DSP slice is actually 18 x 25 -> 45 bits. The additional two // product bits are for overflow, since the complex multipler adds // four intermediate results. // Signal inputs and outputs are Pipe datatypes, to provide flow control. // The module is intended for use in environments where there may be // one result per cycle, but at slow signal rates, clock cycles may // be skipped. Because the logic is pipelined, there are valid // bits that follow the signal path. The signal is assumed to be provided // intermittently, while the coefficients are provided on demand up to // one per cycle. // Because one intended application is a Channel Select filter with // downconversion, the coefficient path supplies a "filter phase" boolean // which indicates the start of a new sample period at the output // intermediate frequency. import FIFOF::*; import SpecialFIFOs::*; import Complex::*; import FixedPoint::*; import Pipe::*; import FIFOF::*; import SpecialFIFOs::*; import SDRTypes::*; typedef struct { Complex#(Coeff) a; Bit#(1) filterPhase; } CoeffData deriving(Bits); typedef struct { Complex#(Product) y; Bit#(1) filterPhase; } ProductData deriving(Bits); typedef struct { Product arxr; Product arxi; Product aixr; Product aixi; Bit#(1) filterPhase; } MulData deriving(Bits); interface FPCMult; interface PipeIn#(Complex#(Signal)) x; interface PipeIn#(CoeffData) a; interface PipeOut#(ProductData) y; endinterface module mkFPCMult(FPCMult) provisos(Bits#(CoeffData, a__), Bits#(ProductData, b__), Bits#(MulData, c__)); /* input registers */ FIFOF#(CoeffData) ain <- mkPipelineFIFOF(); FIFOF#(Complex#(Signal)) xin <- mkPipelineFIFOF(); /* pipeline registers at output of multipliers */ Reg#(MulData) ax <- mkReg(?); /* result registers */ FIFOF#(ProductData) yout <- mkPipelineFIFOF(); rule work; /* compute multiplies */ Product arxr = fxptMult(ain.first().a.rel, xin.first.rel); Product aixi = fxptMult(ain.first().a.img, xin.first.img); Product arxi = fxptMult(ain.first().a.rel, xin.first.img); Product aixr = fxptMult(ain.first().a.img, xin.first.rel); ain.deq(); xin.deq(); ax <= MulData{arxr: arxr, aixi: aixi, arxi: arxi, aixr: aixr, filterPhase: ain.first().filterPhase}; /* pipeline and combine into outputs */ yout.enq(ProductData{y: Complex{rel: ax.arxr - ax.aixi, img: ax.arxi + ax.aixr}, filterPhase: ax.filterPhase}); endrule interface PipeOut y = toPipeOut(yout); interface PipeIn x = toPipeIn(xin); interface PipeIn a = toPipeIn(ain); endmodule ================================================ FILE: contrib/channelselect/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = ChannelSelectTestRequest DDSTestRequest ChannelSelectTestIndication DDSTestIndication BSVFILES = ChannelSelectTestInterfaces.bsv DDSTestInterfaces.bsv Top.bsv CPPFILES=testchannelselecttest.cpp gentarget:: sine.bin sine.bin: sinetable mkdir -p bluesim ./sinetable >sine.bin cp sine.bin bluesim sinetable: sinetable.c cc -o sinetable sinetable.c -lm include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/channelselect/Readme.md ================================================ ## ChannelSelectTest L. Stewart August 21, 2014 This example is part of the front end of a software defined radio. Digital samples at the RF sample rate come in, are filtered by a finite impulse response digital filter, and multiplied by a digital local oscillator signal. The output is at the IF sample rate. Due to the high expected RF sample rate, the input is two samples per cycle at half the RF rate. Output is one sample per cycle at the IF rate. This example is a test harness for the signal processing logic located in examples/fmcomms1 The test software loads filter coefficients one by one, then feeds RF samples one at a time to the hardware. Occasionally, the hardware sends IF sample back, using the indications interface. The hardware is supposed to map onto MAC units in the Xilinx. What it does The hardware under test accepts two-at-a-time complex valued RF samples. Real and imaginary parts of the signal are 16 bits, with 2 integer bits and 14 fraction bits. An FIR filter is applied to the RF filter, and the result is multiplied by a local oscillator. The result is decimated and delivered as Complex valued IF samples. The trick of Vanu and Welborn is used, so that the FIR filter only computes results at the IF sampling rate, and the local oscillator also runs at the IF sample rate ================================================ FILE: contrib/channelselect/SDRTypes.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Complex::*; import FixedPoint::*; typedef FixedPoint#(2,16) Signal; typedef FixedPoint#(2,23) Coeff; typedef FixedPoint#(4,39) Product; ================================================ FILE: contrib/channelselect/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import GetPut::*; import Connectable :: *; import FIFO::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import MemServer::*; import DDSTestInterfaces::*; import DDSTest::*; import ChannelSelectTestInterfaces::*; import ChannelSelectTest::*; import ChannelSelectTestRequest::*; import ChannelSelectTestIndication::*; import DDSTestRequest::*; import DDSTestIndication::*; typedef enum { IfcNames_ChannelSelectTestIndication, IfcNames_ChannelSelectTestRequest, IfcNames_DDSTestIndication, IfcNames_DDSTestRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); ChannelSelectTestIndicationProxy channelSelectTestIndicationProxy <- mkChannelSelectTestIndicationProxy(IfcNames_ChannelSelectTestIndication); ChannelSelectTestRequest channelSelectTestRequest <- mkChannelSelectTestRequest(channelSelectTestIndicationProxy.ifc); ChannelSelectTestRequestWrapper channelSelectTestRequestWrapper <- mkChannelSelectTestRequestWrapper(IfcNames_ChannelSelectTestRequest, channelSelectTestRequest); DDSTestIndicationProxy ddsTestIndicationProxy <- mkDDSTestIndicationProxy(IfcNames_DDSTestIndication); DDSTestRequest ddsTestRequest <- mkDDSTestRequest(ddsTestIndicationProxy.ifc); DDSTestRequestWrapper ddsTestRequestWrapper <- mkDDSTestRequestWrapper(IfcNames_DDSTestRequest, ddsTestRequest); Vector#(4,StdPortal) portals; portals[0] = channelSelectTestRequestWrapper.portalIfc; portals[1] = channelSelectTestIndicationProxy.portalIfc; portals[2] = ddsTestRequestWrapper.portalIfc; portals[3] = ddsTestIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/channelselect/sinetable.c ================================================ /* create hex file to load BRAM with sine and cosine tables * for the direct digital synthesizer */ /* Copyright (c) 2014 Quanta Research Cambridge, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include int main(int argc, char *argv[]) { double s, c; double phase; int i, j; unsigned long c_frac, s_frac; for (i = 0; i < 1024; i += 1) { c = cos(((double) i / 1024.0) * 2.0 * M_PI); s = sin(((double) i / 1024.0) * 2.0 * M_PI); c_frac = c * (double) (1L << 23); s_frac = s * (double) (1L << 23); for (j = 24; j >= 0; j -= 1) printf("%1lx", (c_frac >> j) & 0x1); for (j = 24; j >= 0; j -= 1) printf("%1lx", (s_frac >> j) & 0x1); printf("\n"); } return(0); } ================================================ FILE: contrib/channelselect/testchannelselecttest.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "ChannelSelectTestRequest.h" #include "ChannelSelectTestIndication.h" #include "DDSTestRequest.h" #include "DDSTestIndication.h" #include "GeneratedTypes.h" sem_t data_sem; sem_t config_sem; class ChannelSelectTestIndication : public ChannelSelectTestIndicationWrapper { public: ChannelSelectTestIndication(unsigned int id) : ChannelSelectTestIndicationWrapper(id){} virtual void ifreqData(unsigned dataRe, unsigned dataIm){ fprintf(stdout, "read %x %x\n", dataRe, dataIm); } virtual void setDataResp(){ fprintf(stdout, "setDataResp\n"); sem_post(&data_sem); } virtual void setConfigResp(){ fprintf(stdout, "setDataResp\n"); sem_post(&config_sem); } }; class DDSTestIndication : public DDSTestIndicationWrapper { public: DDSTestIndication(unsigned int id) : DDSTestIndicationWrapper(id){} virtual void ddsData(unsigned phase, unsigned dataRe, unsigned dataIm){ fprintf(stdout, "data %d %X %x\n", phase, dataRe, dataIm); sem_post(&data_sem); } virtual void setConfigResp(){ fprintf(stdout, "dds.setDataResp\n"); sem_post(&config_sem); } }; int main(int argc, const char **argv) { ChannelSelectTestRequestProxy *ctdevice = 0; ChannelSelectTestIndication *ctindication = 0; DDSTestRequestProxy *ddsdevice = 0; DDSTestIndication *ddsindication = 0; sem_init(&data_sem, 0, 0); sem_init(&config_sem, 0, 0); fprintf(stdout, "Main::%s %s\n", __DATE__, __TIME__); ctdevice = new ChannelSelectTestRequestProxy(IfcNames_ChannelSelectTestRequest); ctindication = new ChannelSelectTestIndication(IfcNames_ChannelSelectTestIndication); ddsdevice = new DDSTestRequestProxy(IfcNames_DDSTestRequest); ddsindication = new DDSTestIndication(IfcNames_DDSTestIndication); fprintf(stdout, "DDSTest\n"); ddsdevice->setPhaseAdvance(1, 0); for (int i = 0; i < 2048; i += 1) { ddsdevice->getData(); sem_wait(&data_sem); } fprintf(stdout, "Main::starting\n"); ctdevice->setCoeff(0, 1<<21, 0); sem_wait(&config_sem); ctdevice->setCoeff(1, 1<<21, 0); sem_wait(&config_sem); ctdevice->setCoeff(2, 1<<21, 0); sem_wait(&config_sem); ctdevice->setCoeff(3, 1<<21, 0); sem_wait(&config_sem); ctdevice->setPhaseAdvance(0, 1 << 21); sem_wait(&config_sem); int i; for (i = 0; i < 128; i += 1) { ctdevice->rfreqDataWrite(1<<16, 0); // should be re=1, im=0 sem_wait(&data_sem); } fprintf(stdout, "Main::stopping\n"); exit(0); } ================================================ FILE: contrib/fib/Fib.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StackReg::*; import StmtFSM::*; interface FibIndication; method Action fibresult(Bit#(32) v); endinterface interface FibRequest; method Action fib(Bit#(32) v); endinterface interface Fib; interface FibRequest request; endinterface typedef enum {FIBSTATEIDLE, FIBSTATE1, FIBSTATE2, FIBSTATE3, FIBSTATECOMPLETE} FSState deriving (Bits,Eq); module mkFib#(FibIndication indication)(Fib); /* pc, args, vars */ StackReg#(128, FSState, Bit#(16), Bit#(16)) frame <- mkStackReg(128, FIBSTATEIDLE); /* function variables that do not need to be saved or restored * in the pseudocode below, this is tmp2 */ Reg#(Bit#(16)) fibretval <- mkReg(0); /* experiment: recursive fibonnaci * fib(n): * int tmp1, tmp2; * if n == 0 return 0 // fibstate1 * if n == 1 return 1 * tmp1 = fib(n-1) * tmp2 = fib(n-2) // fibstate2 * return tmp1 + tmp2 // fibstate3 */ rule fib1 (frame.pc == FIBSTATE1); //$display("FIBSTATE1 %d", frame.args); if (frame.args == 0) begin fibretval <= 0; frame.doreturn(); end else if (frame.args == 1) begin fibretval <= 1; frame.doreturn(); end else // call FIBSTATE1 and return to FIBSTATE2 // call with argument frame.args -1 and tmp2 = 0 frame.docall(FIBSTATE1, FIBSTATE2, frame.args - 1, 0); endrule rule fib2 (frame.pc == FIBSTATE2); //$display("FIBSTATE2 (retval %d)", fibretval); // frame.vars <= fibretval; subsumed in docall frame.docall(FIBSTATE1, FIBSTATE3, frame.args - 2, fibretval); endrule rule fib3 (frame.pc == FIBSTATE3); //$display("FIBSTATE3 tmp1 %d fibretval %d return %d", frame.vars, fibretval, frame.vars + fibretval); fibretval <= frame.vars + fibretval; frame.doreturn(); endrule rule fibcomplete (frame.pc == FIBSTATECOMPLETE); //$display("FIBSTATECOMPLETE %d %d", frame.args, fibretval); indication.fibresult(zeroExtend(fibretval)); // our work here is done frame.nextpc(FIBSTATEIDLE); endrule interface FibRequest request; method Action fib(Bit#(32) v); //$display("request fib %d", v); // call FIBSTATE1 and return to FIBSTATECOMPLETE // with argument v frame.docall(FIBSTATE1, FIBSTATECOMPLETE, truncate(v), 0); endmethod endinterface endmodule ================================================ FILE: contrib/fib/FibNarrow.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Stack::*; import StmtFSM::*; interface FibIndication; method Action fibresult(Bit#(32) v); method Action fibnote(Bit#(32) v); endinterface interface FibRequest; method Action fib(Bit#(32) v); endinterface typedef enum {FIBSTATEIDLE, FIBSTATE1, FIBSTATE2, FIBSTATE3, FIBSTATECOMPLETE, FIBCALLING, FIBRETURNING} FSState deriving (Bits,Eq); module mkFibRequest#(FibIndication indication)(FibRequest); // provisos(Literal#(FSState)); /* stack frame */ Reg#(Bit#(16)) fibn <- mkReg(0); Reg#(Bit#(16)) fibtmp1 <- mkReg(0); Reg#(FSState) fibstate <- mkReg(FIBSTATEIDLE); /* function variables that do not need to be saved or restored */ Reg#(Bit#(16)) fibretval <- mkReg(0); /* offsets in stack frame */ Bit#(2) fsoffsetn = 0; Bit#(2) fsoffsettmp1 = 1; Bit#(2) fsoffsetnext = 2; Stack#(128, 3, Bit#(16)) stack <- mkStack(128 ,3); /* experiment: recursive fibonnaci * fib(n): * int tmp1, tmp2; * if n == 0 return 1 // fibstate1 * if n == 1 return 1 * tmp1 = fib(n-1) * tmp2 = fib(n-2 // fibstate2 * return tmp1 + tmp2 // fibstate3 * * with explicit stack: * struct fsf { * int level; * int tmp1; * int n; * int next_state; * } stack[N] * */ Reg#(Bit#(16)) fibcallarg <- mkReg(0); Reg#(FSState) fibcallreturnto <- mkReg(FIBSTATEIDLE); Stmt callfibstmt = seq // $display("FIBCALL"); stack.store(fsoffsetn, fibn); stack.store(fsoffsettmp1, fibtmp1); stack.store(fsoffsetnext, zeroExtend(pack(fibcallreturnto))); // par stack.push(); fibn <= fibcallarg; fibstate <= FIBSTATE1; // endpar endseq; FSM callFibFSM <- mkFSM(callfibstmt); Stmt fibreturnstmt = seq // $display("FIBRETURN"); stack.pop(); // $display("FIBRETURN pop"); stack.loadstart(fsoffsetn); action let t <- stack.loadfinish(); stack.loadstart(fsoffsettmp1); fibn <= t; endaction // $display("FIBRETURN n"); action let t <- stack.loadfinish(); stack.loadstart(fsoffsetnext); fibtmp1 <= t; endaction // $display("FIBRETURN tmp1"); action let t <- stack.loadfinish(); // $display("FIBRETURN set state %d", t); fibstate <= unpack(truncate(t)); endaction endseq; FSM fibreturnFSM <- mkFSM(fibreturnstmt); function Action callfib(Bit#(16) arg, FSState returnto); return action fibstate <= FIBCALLING; fibcallarg <= arg; fibcallreturnto <= returnto; callFibFSM.start(); endaction; endfunction function Action fibreturn(Bit#(16) returnval); return action fibstate <= FIBRETURNING; fibretval <= returnval; fibreturnFSM.start(); endaction; endfunction rule fib1 (fibstate == FIBSTATE1); // $display("FIBSTATE1"); if (fibn == 0) fibreturn(0); else if (fibn == 1) fibreturn(1); else callfib(fibn - 1, FIBSTATE2); endrule rule fib2 (fibstate == FIBSTATE2); // $display("FIBSTATE2"); fibtmp1 <= fibretval; callfib(fibn - 2, FIBSTATE3); endrule rule fib3 (fibstate == FIBSTATE3); // $display("FIBSTATE3 fibtmp1 %d fibretval %d return %d", fibtmp1, fibretval, fibtmp1 + fibretval); fibreturn(fibtmp1 + fibretval); endrule rule fibcomplete (fibstate == FIBSTATECOMPLETE); // $display("FIBSTATECOMPLETE %d %d", fibn, fibretval); indication.fibresult(zeroExtend(fibretval)); fibstate <= FIBSTATEIDLE; endrule method Action fib(Bit#(32) v); $display("request fib %d", v); fibn <= truncate(v); indication.fibnote(8); callfib(truncate(v), FIBSTATECOMPLETE); endmethod endmodule ================================================ FILE: contrib/fib/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = FibRequest:Fib.request H2S_INTERFACES = Fib:FibIndication BSVFILES = Fib.bsv CPPFILES=testfib.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/fib/Readme.md ================================================ Larry Stewart Fib is an example of a stylized way to construct recursive algorithms in hardware. The main algorithm is constructed as a state machine. In the case of fibonacci, the pseudo code is fib(n): int tmp1, tmp2; if n == 0 return 0 if n == 1 return 1 tmp1 = fib(n-1) tmp2 = fib(n-2) return tmp1 + tmp2 Except for the recursion, this could be implemented in the StmtFSM language, but StmtFSM leaves the state machinery hidden, so there is no way to save and restore the "program counter" as would be needed to resume execution in the middle of an FSM after a return. Likewise, FSM server doesn't help, because you cannot call yourself. Instead, Fib is implemented using an FSM constructed out of individual rules which fire according to a state variable. Fib takes three rules: rule fib1 (fibstate == FIBSTATE1); if (fibn == 0) fibreturn(0); else if (fibn == 1) fibreturn(1); else callfib(fibn - 1, FIBSTATE2); endrule rule fib2 (fibstate == FIBSTATE2); fibtmp1 <= fibretval; callfib(fibn - 2, FIBSTATE3); endrule rule fib3 (fibstate == FIBSTATE3); fibreturn(fibtmp1 + fibretval); endrule In accordance with bluespec, each rule takes exactly one cycle to run, once its guards are satisfied. The newest version of thisfib is in the module FibWide.bsv, which uses the library module lib/bsv/StackReg.bsv The idea of StackReg is that it stores the entire "local frame" on a stack. The local frame includes the program counter, the function arguments, and any local variables. These are all stored in parallel, so it takes three BRAMs of the appropriate widths. Additional registers are used for the "top of stack" and a bypass register that permits single cycle returns. To use the StackReg library, you instantiate a StackReg, with parameters for stack depth, types for the PC, arguments, and locals, and a parameter for the initial value of the PC. Thereafter, you can use the docall and doreturn methods to implement recursive algorithms. The original version of thisFib is in the module Fib.bsv, which uses the library module lib/bsv/Stack.bsv Stack uses a single 16 bit wide BRAM to store all the stack data in the local frame. This is a multicycle operation, and requires the caller to implement the FSMs to do the save and restore. It uses less hardware, more time, and is messy to code. The original caller of this FSM uses "callfib" to start the run. The first argument to callfib is the argument to this invocation of fib, and the second argument is the "state" to return to. In effect this is the program counter value to push on the stack. The state machine returns from a call by using "fibreturn" with a return value. method Action fib(Bit#(32) v); fibn <= truncate(v); callfib(truncate(v), FIBSTATECOMPLETE); endmethod rule fibcomplete (fibstate == FIBSTATECOMPLETE); indication.fibresult(zeroExtend(fibretval)); fibstate <= FIBSTATEIDLE; endrule Call and return are a bit more complicated function Action callfib(Bit#(16) arg, FSState returnto); return action fibstate <= FIBCALLING; fibcallarg <= arg; fibcallreturnto <= returnto; callFibFSM.start(); endaction; endfunction Because it is a multicycle process to push the current state onto the stack and start the recursive call, the callfib function saves its arguments in registers, changes the FSM state to FIBCALLING and launches the callFibFSM. Stmt callfibstmt = seq stack.store(fsoffsetn, fibn); stack.store(fsoffsettmp1, fibtmp1); stack.store(fsoffsetnext, zeroExtend(pack(fibcallreturnto))); par stack.push(); fibn <= fibcallarg; fibstate <= FIBSTATE1; endpar endseq; This state machine pushes local variables onto the stack, increments the stack pointer, and changes the working register for the new call. It then sets the state to FIBSTATE1, the state for the first chunk of code in fib. When an invocation is finished, it calls "fibreturn" with a return value. function Action fibreturn(Bit#(16) returnval); return action fibstate <= FIBRETURNING; fibretval <= returnval; fibreturnFSM.start(); endaction; endfunction Similar to callfib, the process of popping the previous state off the stack is multicycle, so it is relegated to a StmtFSM. While that FSM runs, the main machine state is set to FIBRETURNING Stmt fibreturnstmt = seq stack.pop(); stack.loadstart(fsoffsetn); action let t <- stack.loadfinish(); stack.loadstart(fsoffsettmp1); fibn <= t; endaction action let t <- stack.loadfinish(); stack.loadstart(fsoffsetnext); fibtmp1 <= t; endaction action let t <- stack.loadfinish(); fibstate <= unpack(truncate(t)); endaction endseq; This FSM decrements the frame pointer, then restores the local variables to their previous values. The final step is restoring the "pc" which causes the original state machine to resume execution in its previous context. ================================================ FILE: contrib/fib/testfib.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "FibIndication.h" #include "FibRequest.h" #include "GeneratedTypes.h" sem_t test_sem; class FibIndication : public FibIndicationWrapper { public: virtual void fibresult(uint32_t v) { fprintf(stderr, "fibresult: %d\n", v); sem_post(&test_sem); } FibIndication(unsigned int id) : FibIndicationWrapper(id) {} }; static FibRequestProxy *fibRequestProxy = 0; FibIndication *fibIndication; int main(int argc, const char **argv) { int i; // these use the default poller fibIndication = new FibIndication(IfcNames_FibIndicationH2S); fibRequestProxy = new FibRequestProxy(IfcNames_FibRequestS2H); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } for (i = 0; i < 20; i += 1) { fprintf(stderr, "fib(%d)\n", i); fibRequestProxy->fib(i); sem_wait(&test_sem); } return 0; } ================================================ FILE: contrib/flowcontrol/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SinkRequest SinkIndication BSVFILES = Sink.bsv Top.bsv CPPFILES=test.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/flowcontrol/Sink.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; interface SinkIndication; method Action returnTokens(Bit#(32) v); endinterface interface SinkRequest; method Action init(Bit#(32) v); method Action put(Bit#(32) v); endinterface module mkSinkRequest#(SinkIndication indication)(SinkRequest); Bit#(32) threshold = 4; Bit#(32) capacity = 24; Reg#(Bit#(32)) count <- mkReg(0); rule consume (count >= threshold); indication.returnTokens(count); count <= 0; endrule method Action init(Bit#(32) v); indication.returnTokens(capacity); endmethod method Action put(Bit#(32) v) if (count < capacity); count <= count+1; endmethod endmodule ================================================ FILE: contrib/flowcontrol/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import SinkIndication::*; import SinkRequest::*; import Sink::*; typedef enum {IfcNames_SinkIndication, IfcNames_SinkRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); // instantiate user portals SinkIndicationProxy sinkIndicationProxy <- mkSinkIndicationProxy(IfcNames_SinkIndication); SinkRequest sinkRequest <- mkSinkRequest(sinkIndicationProxy.ifc); SinkRequestWrapper sinkRequestWrapper <- mkSinkRequestWrapper(IfcNames_SinkRequest,sinkRequest); Vector#(2,StdPortal) portals; portals[0] = sinkIndicationProxy.portalIfc; portals[1] = sinkRequestWrapper.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/flowcontrol/test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include "SinkIndication.h" #include "SinkRequest.h" #include "GeneratedTypes.h" #include #include pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER; int count = 0; class SinkIndication : public SinkIndicationWrapper { public: virtual void returnTokens(uint32_t v) { // Lock mutex and update the count variable pthread_mutex_lock( &count_mutex ); count += v; // Signal to main() thread that more tokens have been // returned from the SinkRequest hardware and unlock mutex pthread_cond_signal( &condition_var ); pthread_mutex_unlock( &count_mutex ); } SinkIndication(unsigned int id) : SinkIndicationWrapper(id){} }; int main(int argc, const char **argv) { int tokens = 0; SinkIndication *sinkIndication = new SinkIndication(IfcNames_SinkIndication); SinkRequestProxy *sinkRequestProxy = new SinkRequestProxy(IfcNames_SinkRequest); fprintf(stderr, "Main::creating exec thread\n"); sinkRequestProxy->init(0); while(tokens < 32){ // Lock mutex and then wait for signal to relase mutex pthread_mutex_lock( &count_mutex ); // Wait while SinkIndication::returnTokens updates count // mutex unlocked if condition varialbe is signaled. pthread_cond_wait( &condition_var, &count_mutex ); // consume the credit int local_count = count; count = 0; // Unlock the mutex so SinkIndication::returnTokens can // accept more tokens from the SinkRequest hardware pthread_mutex_unlock( &count_mutex ); while(local_count){ fprintf(stderr, "main() count:%d\n", local_count--); sinkRequestProxy->put(tokens++); } } return 0; } ================================================ FILE: contrib/importverilog/.gitignore ================================================ RegFile.bsv ================================================ FILE: contrib/importverilog/Main.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import RegFile::*; import Clocks::*; import DefaultValue::*; import StmtFSM::*; interface MainRequest; method Action write_rf(Bit#(16) address, Bit#(16) data); method Action read_rf(Bit#(16) address, Bit#(16) data); endinterface interface Main; interface MainRequest request; endinterface typedef struct{ Bit#(2) address; Bit#(8) data; } RFItem deriving (Bits); module mkMain#(MainRequest indication)(Main); let verbose = False; Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); RegFile rf <- mkRegFile(defaultClock, defaultReset, defaultReset); FIFOF#(RFItem) read_item <- mkSizedFIFOF(2); // The purpose of this state machine is to read Stmt handleRead = seq while(True) seq if (read_item.notEmpty()) seq rf.read.address(zeroExtend(read_item.first().address)); action read_item.deq(); indication.read_rf(zeroExtend(read_item.first().address), zeroExtend(rf.read.data())); endaction endseq endseq endseq; mkAutoFSM(handleRead); interface MainRequest request; method Action write_rf(Bit#(16) address, Bit#(16) data); if (verbose) $display("mkMain::write_rf"); rf.write.address(truncate(address)); rf.write.data(truncate(data)); rf.write.en(1); indication.write_rf(address, data); endmethod method Action read_rf(Bit#(16) address, Bit#(16) data); if (verbose) $display("mkMain::read_rf"); read_item.enq(RFItem{address:truncate(address), data:0}); endmethod endinterface endmodule ================================================ FILE: contrib/importverilog/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MainRequest:Main.request H2S_INTERFACES = Main:MainRequest BSVFILES = Main.bsv RegFile.bsv CPPFILES=testmain.cpp RegFile.bsv: regfile.v $(CONNECTALDIR)/generated/scripts/importbvi.py -o RegFile.bsv -I RegFile -P RF -c clock -r reset_n \ regfile.v include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/importverilog/Readme.md ================================================ This example shows how to integrate a verilog module with Bluespec code. In the Makefile there is a target to build RefFile.bsv automatically from regfile.v. This creates a Bluespec wrapper for the verilog, allowing Bluespec code to send signals into the verilog and to get results back into Bluespec. ================================================ FILE: contrib/importverilog/regfile.v ================================================ // simple verilog example of a 2 port register file with 4 registers module regfile (clock, reset_n, write_address, write_data, write_en, read_address, read_data); input clock; input reset_n; input [1:0] write_address; input [7:0] write_data; input write_en; input [1:0] read_address; output [7:0] read_data; reg [7:0] reg0; reg [7:0] reg1; reg [7:0] reg2; reg [7:0] reg3; reg [1:0] ra; wire [7:0] read_data; assign read_data = (ra == 0) ? reg0 : (ra == 1) ? reg1 : (ra == 2) ? reg2 : (ra == 3) ? reg3 : 0; always @ (posedge clock) ra <= read_address; always @ (posedge clock) if (reset_n == 0) begin reg0 <= 0; reg1 <= 0; reg2 <= 0; reg3 <= 0; end else begin if (write_en) begin case(write_address) 0: reg0 <= write_data; 1: reg1 <= write_data; 2: reg2 <= write_data; 3: reg3 <= write_data; endcase // case (write_address) end end // else: !if(rst) endmodule ================================================ FILE: contrib/importverilog/regfile_tb.v ================================================ module regfile_tb; reg clock; reg reset; reg [1:0] read_address; reg [1:0] write_address; reg [7:0] write_data; reg write_en; wire [7:0] read_data; initial begin $monitor ("we=%b, wa=%b, wd=%b, ra=%b, rd=%b", write_en, write_address, write_data, read_address, read_data); clock=0; reset=0; write_address=0; write_data=0; write_en=0; read_address=0; #20 reset = 1; #20 reset = 0; #20 read_address = 2'b00; #20 read_address = 2'b01; #20 read_address = 2'b10; #20 read_address = 2'b11; #20 write_address = 2'b00; #1 write_data = 8'b00010000; #20 write_en = 1; #20 write_address = 2'b01; #1 write_data = 8'b00010001; #20 write_address = 2'b10; #1 write_data = 8'b00010010; #20 write_address = 2'b11; #1 write_data = 8'b00010011; #20 write_en = 0; #20 read_address = 2'b00; #20 read_address = 2'b01; #20 read_address = 2'b10; #20 read_address = 2'b11; $finish; end // initial begin always begin #5 clock = !clock; end regfile U0 ( .clock (clock), .reset (reset), .write_address (write_address), .write_data (write_data), .write_en (write_en), .read_address (read_address), .read_data (read_data) ); endmodule // regfile_tb ================================================ FILE: contrib/importverilog/testmain.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "MainRequest.h" #define NUMBER_OF_TESTS 8 class Main : public MainRequestWrapper { public: uint32_t cnt; void incr_cnt(){ if (++cnt == NUMBER_OF_TESTS) exit(0); } virtual void write_rf(uint16_t address, uint16_t data) { fprintf(stderr, "write_rf(%d 0x%02x)\n", address, data); incr_cnt(); } virtual void read_rf(uint16_t address, uint16_t data) { fprintf(stderr, "read_rf(%d 0x%02x)\n", address, data); incr_cnt(); } Main(unsigned int id) : MainRequestWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { Main *indication = new Main(IfcNames_MainRequestH2S); MainRequestProxy *device = new MainRequestProxy(IfcNames_MainRequestS2H); device->pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ fprintf(stderr, "Main::calling write_rf(11, 22, 33, 44)\n"); device->write_rf(0, 0x11); device->write_rf(1, 0x22); device->write_rf(2, 0x33); device->write_rf(3, 0x44); fprintf(stderr, "Main::calling read_rf(0, 1, 2, 3)\n"); device->read_rf(0,0); device->read_rf(1,0); device->read_rf(2,0); device->read_rf(3,0); fprintf(stderr, "Main::about to go to sleep\n"); while(true){sleep(2);} } ================================================ FILE: contrib/maxcommonsubseq/HirschA.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StmtFSM::*; import BRAM::*; import MCSAlgorithm::*; module mkHirschA#(BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strA, BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strB, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) matL)(MCSAlgorithm) provisos(Add#(0, 14, strIndexWidth), Add#(0, 14, lIndexWidth)); Reg#(Bit#(14)) aStartReg <- mkReg(0); Reg#(Bit#(14)) bStartReg <- mkReg(0); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) rLenReg <- mkReg(0); Reg#(Bit#(14)) ii <- mkReg(0); Reg#(Bit#(14)) jj <- mkReg(0); Reg#(Bit#(8)) aData <- mkReg(0); Reg#(Bit#(8)) bData <- mkReg(0); Reg#(Bit#(16)) lim1jm1 <- mkReg(0); Reg#(Bit#(16)) lim1j <- mkReg(0); Reg#(Bit#(16)) lijm1 <- mkReg(0); Stmt hirschA = seq // $display("hirschA running alen %d blen %d", aLenReg, bLenReg); for (ii<= 0; ii < aLenReg; ii <= ii + 1) seq matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {ii[6:0],0}, datain: 0}); endseq for (ii<= 0; ii < aLenReg; ii <= ii + 1) seq matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {0,ii[6:0]}, datain: 0}); endseq for (ii<= 1; ii <= aLenReg; ii <= ii + 1) for (jj<= 1; jj <= bLenReg; jj <= jj + 1) seq strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: aStartReg + ii-1, datain: 0}); strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: bStartReg + jj-1, datain: 0}); action let ta <- strA.response.get(); let tb <- strB.response.get(); aData <= ta; bData <= tb; endaction if (aData == bData) seq matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {ii[6:0]-1,jj[6:0]-1}, datain: 0}); action let temp <- matL.response.get(); lim1jm1 <= temp; endaction matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {ii[6:0],jj[6:0]}, datain: lim1jm1+1}); endseq else seq matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {ii[6:0],jj[6:0]-1}, datain: 0}); action let tlijm1 <- matL.response.get(); lijm1 <= tlijm1; endaction matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {ii[6:0]-1,jj[6:0]}, datain: 0}); action let tlim1j <- matL.response.get(); lim1j <= tlim1j; endaction matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {ii[6:0],jj[6:0]}, datain: max(lijm1,lim1j)}); endseq endseq endseq; FSM hA <- mkFSM(hirschA); method Action setupA(Bit#(14) start, Bit#(14) length); aStartReg <= start; aLenReg <= length; endmethod method Action setupB(Bit#(14) start, Bit#(14) length); bStartReg <= start; bLenReg <= length; endmethod method Action setupL(Bit#(14) start); endmethod method Bit#(14) result(); return(zeroExtend(aLenReg) * zeroExtend(bLenReg)); endmethod interface FSM fsm = hA; endmodule ================================================ FILE: contrib/maxcommonsubseq/HirschB.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StmtFSM::*; import BRAM::*; import MCSAlgorithm::*; module mkHirschB#(BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strA, BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strB, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) matL, int dir)(MCSAlgorithm) provisos(Add#(0, 14, strIndexWidth), Add#(0, 14, lIndexWidth)); Reg#(Bit#(14)) aStartReg <- mkReg(0); Reg#(Bit#(14)) bStartReg <- mkReg(0); Reg#(Bit#(14)) rStartReg <- mkReg(0); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) ii <- mkReg(0); Reg#(Bit#(14)) jj <- mkReg(0); Reg#(Bit#(8)) aData <- mkReg(0); Reg#(Bit#(8)) bData <- mkReg(0); Reg#(Bit#(16)) k1j <- mkReg(0); Reg#(Bit#(16)) k1jm1 <- mkReg(0); Reg#(Bit#(16)) k0j <- mkReg(0); Reg#(Bit#(16)) k0jm1 <- mkReg(0); BRAM1Port#(Bit#(lIndexWidth), Bit#(16)) k0 <- mkBRAM1Server(defaultValue); /* The original algorithm B uses two vectors K0 and K1 to store two rows of the full L * matrix from algoritm A. For any particular iteration, K[0][j-1] K[0][j] * and K[1][j-1] are used to compute K[1][j] * * Each cycle, K[1] is copied to K[0], and then a new K[1] is computed. First, the * the previous K[0][j] is copied to K[0][j-1] and the previous K[1][j] is copied to * K[1][j-1]. Then a new K[1][j] is computed. * * In the revised version, a single vector is used, plus auxiliary registers. * First the old K[0][j] auxiliary is copied to K[0][j-1] and the K[1][j] auxiliary * is copied to K[1][j-1]. Then K[0][j] is read. Then K[1][j] is computed to * K[0][j]. When the row is finished, K[0] is effectively K[1] * */ Stmt hirschB = seq jj <= 17; // one cycle delay to permit the control registers to get set //$display("hirschB running %d %d %d %d dir %d", // aStartReg, aLenReg, bStartReg, bLenReg, dir); /* initialize K1 (stored in lMat) of temporary storage */ for (jj <= 0; jj <= bLenReg; jj <= jj + 1) seq matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: rStartReg + zeroExtend(jj), datain: 0}); endseq /* Loop through string a */ for (ii <= 1; ii <= aLenReg; ii <= ii + 1) seq //$display("hirschB ii = %d", ii); par /* initialize pipelining */ jj <= 1; k0j <= 0; k1j <= 0; action let idx = ?; if (dir == 1) idx = aStartReg + ii - 1; // 0 to aLen - 1 else idx = aStartReg + aLenReg - ii; // aLen-1 downto 0 strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: idx, datain: ?}); endaction /* Read b[j] */ action let idx = ?; if (dir == 1) idx = bStartReg; else idx = bStartReg + bLenReg - 1; strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: idx, datain: ?}); endaction /* start read of k0j */ matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: rStartReg + 1, datain: ?}); endpar action let ta <- strA.response.get(); /* read a[i] */ aData <= ta; endaction /* Loop through string B */ while (jj <= bLenReg) seq //$display("hirschB jj = %d", jj); action let tb <- strB.response.get(); let tk <- matL.response.get(); k0jm1 <= k0j; /* pipeline from previous cycle */ k1jm1 <= k1j; bData <= tb; /* read b[j] from bram */ k0j <= tk; /* read k[0][j] from bram */ matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: rStartReg + zeroExtend(jj-1), datain: k1j}); endaction //$display("hirschB ii %d jj %d A %h B %h k1j", ii, jj, aData, bData, k1j); action let tmp = ?; /* Read b[j] */ /* if backwards B[bStartReg + bLenReg - jj] */ action let idx = ?; if (dir == 1) idx = bStartReg + jj; else idx = bStartReg + bLenReg - jj - 1; strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: idx, datain: ?}); endaction if (aData == bData) tmp = k0jm1 + 1; else tmp = max(k0j,k1jm1); k1j <= tmp; jj <= jj + 1; /* start read of k0j */ matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: rStartReg + zeroExtend(jj+1), datain: ?}); endaction //$display(" L[%d][%d] = %d ", ii, jj, k1j); endseq action let tb <- strB.response.get(); let tk <- matL.response.get(); matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: rStartReg + zeroExtend(jj-1), datain: k1j}); endaction endseq endseq; FSM hB <- mkFSM(hirschB); method Action setupA(Bit#(14) start, Bit#(14) length); aStartReg <= start; aLenReg <= length; endmethod method Action setupB(Bit#(14) start, Bit#(14) length); bStartReg <= start; bLenReg <= length; endmethod method Action setupL(Bit#(14) start); rStartReg <= start; endmethod method Bit#(14) result(); return(zeroExtend(bLenReg)); endmethod interface FSM fsm = hB; endmodule ================================================ FILE: contrib/maxcommonsubseq/HirschC.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StmtFSM::*; import BRAM::*; import MCSAlgorithm::*; import StackReg::*; /* frame arguments */ typedef struct { Bit#(14) aStart; Bit#(14) bStart; Bit#(14) aLen; Bit#(14) bLen; } CArgs deriving(Bits); typedef struct { Bit#(14) midi; Bit#(14) maxj; } CVars deriving(Bits); typedef enum {HCSIdle, HCS1, HCS2, HCS3, HCS4, HCS5, HCS6, HCSComplete} HCState deriving (Bits, Eq); /* Strings A and B are passed in as BRAMs, they are loaded in * the caller * matL is a bram for the output. It is Bit#(16) here but it should * be Bit#(8) like the strings * The forward and backwards Hirsch algorithm B modules are passed in. * They share access to the strings, but have their own result matrixes. * used here (l0 and l1). */ module mkHirschC#(BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strA, BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strB, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) matL, MCSAlgorithm chirschB0, MCSAlgorithm chirschB1, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) l0, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) l1)(MCSAlgorithm) provisos(Add#(0, 14, strIndexWidth), Add#(0, 14, lIndexWidth)); /* pc, args, vars */ StackReg#(128, HCState, CArgs, CVars) fr <- mkStackReg(128, HCSIdle); Reg#(Bit#(14)) aStartReg <- mkReg(0); Reg#(Bit#(14)) bStartReg <- mkReg(0); Reg#(Bit#(14)) rStartReg <- mkReg(0); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) ii <- mkReg(0); Reg#(Bit#(14)) jj <- mkReg(0); Reg#(Bit#(8)) aData <- mkReg(0); Reg#(Bit#(8)) bData <- mkReg(0); Reg#(Bit#(14)) outcounter <- mkReg(0); Reg#(Bit#(16)) maxjvalue <- mkReg(0); /* * HirschC(Astart, Alen, Bstart, Blen, output fifo) * implicit A storage, B storage * */ // This FSM searches string B looking for the first char of string A Stmt hirschC2Stmt = seq //$display("hirschC2Stmt running "); // read A[0] strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fr.args.aStart, datain: ?}); action let tmp <- strA.response.get(); aData <= tmp; endaction // scan for it in B for (jj <= 0; jj < fr.args.bLen; jj <= jj + 1) seq strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fr.args.bStart + jj, datain: ?}); action let tmp <- strB.response.get(); bData <= tmp; endaction if (aData == bData) seq //$display("output %d", aData); matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: outcounter, datain: zeroExtend(aData)}); outcounter <= outcounter + 1; break; endseq endseq fr.doreturn(); endseq; FSM hC2fsm <- mkFSM(hirschC2Stmt); // AlgC step 1, 2, and 3 rule hc1 (fr.pc == HCS1); //$display("HCS1 aStart %d aLen %d bStart %d bLen %d", fr.args.aStart, fr.args.aLen, fr.args.bStart, fr.args.bLen); if (fr.args.bLen == 0) fr.doreturn(); else if (fr.args.aLen == 1) begin hC2fsm.start(); fr.nextpc(HCS2); end else action let midi = fr.args.aLen >> 1; fr.vars.midi <= midi; chirschB1.setupA(fr.args.aStart, midi); chirschB1.setupB(fr.args.bStart, fr.args.bLen); chirschB0.setupA(fr.args.aStart+midi, fr.args.aLen - midi); chirschB0.setupB(fr.args.bStart, fr.args.bLen); chirschB0.fsm.start(); chirschB1.fsm.start(); fr.nextpc(HCS3); endaction endrule // This FSM searches the results of the two calls to HirschB Stmt hirschC4Stmt = seq //$display ("hirschC4A stmt running"); maxjvalue <= 0; fr.vars.maxj <= 0; for (jj <= 0; jj <= fr.args.bLen; jj <= jj + 1) seq l0.request.put(BRAMRequest{write: False, responseOnWrite: False, address: zeroExtend(jj), datain: ?}); l1.request.put(BRAMRequest{write: False, responseOnWrite: False, address: zeroExtend(fr.args.bLen - jj), datain: ?}); action let t1 <- l0.response.get(); let t2 <- l1.response.get(); //$display(" j %d l0 %d l1 %d, sum %d oldmax %d", // jj, t1, t2, t1 + t2, maxjvalue); if ((t1 + t2) > maxjvalue) action maxjvalue <= t1 + t2; fr.vars.maxj <= jj; endaction endaction endseq //$display ("midi %d maxj %d", fr.vars.midi, fr.vars.maxj); fr.docall(HCS1, HCS5, CArgs {aStart: fr.args.aStart, aLen: fr.vars.midi, bStart: fr.args.bStart, bLen: fr.vars.maxj}, fr.vars); endseq; FSM hc4fsm <- mkFSM(hirschC4Stmt); rule hc3 (fr.pc == HCS3 && chirschB0.fsm.done() && chirschB1.fsm.done()); //$display("HSC3"); hc4fsm.start(); fr.nextpc(HCS4); endrule rule hc5 (fr.pc == HCS5); //$display("HSC5 aStart %d aLen %d bStart %d bLen %d midi %d maxj %d", // fr.args.aStart, fr.args.aLen, fr.args.bStart, fr.args.bLen, // fr.vars.midi, fr.vars.maxj); fr.docall(HCS1, HCS6, CArgs{aStart: fr.args.aStart + fr.vars.midi, aLen: fr.args.aLen - fr.vars.midi, bStart: fr.args.bStart + fr.vars.maxj, bLen: fr.args.bLen - fr.vars.maxj}, fr.vars); endrule rule hc6 (fr.pc == HCS6); //$display("HSC6"); fr.doreturn(); endrule rule hccomplete (fr.pc == HCSComplete); $display("HSCComplete, result size %d", outcounter); fr.nextpc(HCSIdle); endrule method Action setupA(Bit#(14) start, Bit#(14) length); $display("HirschC setupA %d %d", start, length); aStartReg <= start; aLenReg <= length; endmethod method Action setupB(Bit#(14) start, Bit#(14) length); $display("HirschC setupB %d %d", start, length); bStartReg <= start; bLenReg <= length; endmethod method Action setupL(Bit#(14) start); rStartReg <= start; endmethod method Bit#(14) result(); return(outcounter); endmethod interface FSM fsm; method Action start(); $display("HirschC running aLen %d bLen %d", aLenReg, bLenReg); fr.docall(HCS1, HCSComplete, CArgs{aStart: 0, aLen: aLenReg, bStart: 0, bLen: bLenReg}, CVars {midi: 0, maxj: 0}); endmethod method Bool done(); return(fr.pc == HCSIdle); endmethod method Action waitTillDone(); endmethod method Action abort(); endmethod endinterface: fsm endmodule ================================================ FILE: contrib/maxcommonsubseq/MCSAlgorithm.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StmtFSM::*; interface MCSAlgorithm; method Action setupA (Bit#(14) start, Bit#(14) length); method Action setupB (Bit#(14) start, Bit#(14) length); method Action setupL (Bit#(14) start); method Bit#(14) result(); interface FSM fsm; endinterface ================================================ FILE: contrib/maxcommonsubseq/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = MaxcommonsubseqRequest MaxcommonsubseqIndication BSVFILES = Maxcommonsubseq.bsv Top.bsv $(CONNECTALDIR)/lib/deprecated/DmaUtils.bsv CPPFILES=testmaxcommonsubseq.cpp CONNECTALFLAGS += -I $(CONNECTALDIR)/lib/strstr/cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/maxcommonsubseq/Maxcommonsubseq.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import StmtFSM::*; import BRAM::*; import Connectable::*; import MCSAlgorithm::*; import ConnectalMemTypes::*; import DmaUtils::*; import Dma2BRAM::*; // algorithm import HirschA::*; import HirschB::*; import HirschC::*; /* This module solves the maximum common subsequence problem. * It finds the longest subsequence of characters present in both input strings * the subsequence does not have to be contiguous and the characters can have different locations * and offsets in the two strings, just so long as they occur in the same order * * To initialize, load string A with request setupA, and wait for indication setup complete * Then load string B with request setupB, and wait for indication setup complete * To start the unit, signal start, and wait for searchResult, which will tell you the length * To retreive the result, use fetch and wait for fetchComplete */ /* First pass implements Hirschberg Algorithm A and the fetch call returns the L matrix */ interface MaxcommonsubseqRequest; method Action setupA(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); method Action setupB(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); method Action fetch(Bit#(32) strPointer, Bit#(32) dest, Bit#(32) src, Bit#(32) strLen); method Action start(Bit#(32) alg); endinterface interface MaxcommonsubseqIndication; method Action searchResult(Bit#(32) v); method Action setupAComplete(); method Action setupBComplete(); method Action fetchComplete(); endinterface typedef Bit#(64) DWord; typedef Bit#(32) Word; typedef 16384 MaxStringLen; typedef 16384 MaxFetchLen; typedef TLog#(MaxStringLen) StringIdxWidth; typedef Bit#(StringIdxWidth) StringIdx; typedef TLog#(MaxFetchLen) LIdxWidth; typedef Bit#(LIdxWidth) LIdx; module mkMaxcommonsubseqRequest#(MaxcommonsubseqIndication indication, MemReadServer#(busWidth) setupA_read_server, MemReadServer#(busWidth) setupB_read_server, MemWriteServer#(busWidth) fetch_write_server )(MaxcommonsubseqRequest) provisos(Add#(a__, 8, busWidth), Div#(busWidth,8,nc), Mul#(nc,8,busWidth), Add#(1, b__, nc), Add#(c__, 32, busWidth), Add#(1, d__, TDiv#(busWidth, 32)), Mul#(TDiv#(busWidth, 32), 32, busWidth), Mul#(TDiv#(busWidth, 16), 16, busWidth), Add#(1, e__, TDiv#(busWidth, 16)), Add#(1, f__, TMul#(2, TDiv#(busWidth, 16))), Add#(1, h__, busWidth), Add#(TDiv#(busWidth, 16), g__, TMul#(2, TDiv#(busWidth, 16)))); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) rLenReg <- mkReg(0); BRAM2Port#(StringIdx, Bit#(8)) strA <- mkBRAM2Server(defaultValue); BRAM2Port#(StringIdx, Bit#(8)) strB <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) matL0 <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) matL1 <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) matL <- mkBRAM2Server(defaultValue); BRAMReadClient#(StringIdxWidth,busWidth) n2a <- mkBRAMReadClient(strA.portB); mkConnection(n2a.dmaClient, setupA_read_server); BRAMReadClient#(StringIdxWidth,busWidth) n2b <- mkBRAMReadClient(strB.portB); mkConnection(n2b.dmaClient, setupB_read_server); BRAMWriteClient#(LIdxWidth, busWidth) l2n <- mkBRAMWriteClient(matL.portB); mkConnection(l2n.dmaClient, fetch_write_server); Reg#(Bool) hirschARunning <- mkReg(False); Reg#(Bool) hirschB0Running <- mkReg(False); Reg#(Bool) hirschB1Running <- mkReg(False); Reg#(Bool) hirschCRunning <- mkReg(False); MCSAlgorithm hirschA <- mkHirschA(strA.portA, strB.portA, matL.portA); MCSAlgorithm hirschB1 <- mkHirschB(strA.portA, strB.portA, matL.portA, 1); MCSAlgorithm hirschB0 <- mkHirschB(strA.portA, strB.portA, matL.portA, 0); MCSAlgorithm chirschB1 <- mkHirschB(strA.portA, strB.portA, matL0.portA, 1); MCSAlgorithm chirschB0 <- mkHirschB(strA.portA, strB.portA, matL1.portA, 0); MCSAlgorithm hirschC <- mkHirschC(strA.portA, strB.portA, matL.portA, chirschB0, chirschB1, matL0.portB, matL1.portB); // create BRAM Write client for matL rule finish_setupA; $display("finish setupA"); let x <- n2a.finish; indication.setupAComplete(); endrule rule finish_setupB; $display("finish setupB"); let x <- n2b.finish; indication.setupBComplete(); endrule rule finish_fetch; $display("finish fetch"); let x <- l2n.finish; indication.fetchComplete(); endrule rule hirschA_completion (hirschARunning && hirschA.fsm.done); hirschARunning <= False; indication.searchResult(pack(zeroExtend(hirschA.result()))); endrule rule hirschB0_completion (hirschB0Running && hirschB0.fsm.done); hirschB0Running <= False; indication.searchResult(pack(zeroExtend(hirschB0.result()))); endrule rule hirschB1_completion (hirschB1Running && hirschB1.fsm.done); hirschB1Running <= False; indication.searchResult(pack(zeroExtend(hirschB1.result()))); endrule rule hirschC_completion (hirschCRunning && hirschC.fsm.done); hirschCRunning <= False; indication.searchResult(pack(zeroExtend(hirschC.result()))); endrule method Action setupA(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); aLenReg <= truncate(strLen); $display("setupA %h %h %d", strPointer, strOffset, strLen); n2a.start(strPointer, 0, pack(truncate(strOffset)), pack(truncate(strOffset + strLen-1))); hirschA.setupA(truncate(strOffset), pack(truncate(strLen))); hirschB0.setupA(truncate(strOffset), pack(truncate(strLen))); hirschB1.setupA(truncate(strOffset), pack(truncate(strLen))); hirschC.setupA(truncate(strOffset), pack(truncate(strLen))); endmethod method Action setupB(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); bLenReg <= truncate(strLen); $display("setupB %h %h %d", strPointer, strOffset, strLen); n2b.start(strPointer, 0, pack(truncate(strOffset)), pack(truncate(strOffset + strLen-1))); hirschA.setupB(truncate(strOffset), pack(truncate(strLen))); hirschB0.setupB(truncate(strOffset), pack(truncate(strLen))); hirschB1.setupB(truncate(strOffset), pack(truncate(strLen))); hirschC.setupB(truncate(strOffset), pack(truncate(strLen))); endmethod method Action fetch(Bit#(32) strPointer, Bit#(32) dest, Bit#(32) src, Bit#(32) strLen); //rLenReg <= truncate(strLen); $display("fetch %h %h %h %h", strPointer, dest, src, strLen); let bram_start_idx = pack(truncate(src)); let bram_finish_idx = bram_start_idx+pack(truncate(strLen-1)); l2n.start(strPointer, zeroExtend(dest), bram_start_idx, bram_finish_idx); endmethod method Action start(Bit#(32) alg); $display ("start %d", alg); case (alg) 0: begin hirschA.setupL(0); hirschA.fsm.start(); hirschARunning <= True; end 1: begin hirschB1.fsm.start(); hirschB1.setupL(0); hirschB1Running <= True; end 2: begin hirschB0.fsm.start(); hirschB0.setupL(0); hirschB0Running <= True; end 3: begin hirschC.setupL(0); hirschC.fsm.start(); hirschCRunning <= True; end endcase endmethod endmodule ================================================ FILE: contrib/maxcommonsubseq/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import BlueScope::*; import ConnectalMemory::*; import DmaUtils::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import MaxcommonsubseqRequest::*; import MemServerRequest::*; import MMURequest::*; import MaxcommonsubseqIndication::*; import MemServerIndication::*; import MMUIndication::*; import Maxcommonsubseq::*; typedef enum {IfcNames_MaxcommonsubseqIndication, IfcNames_MaxcommonsubseqRequest, IfcNames_HostMemServerIndication, IfcNames_HostMemServerRequest, IfcNames_HostMMURequest, IfcNames_HostMMUIndication} IfcNames deriving (Eq,Bits); typedef 1 DegPar; module mkConnectalTop(StdConnectalDmaTop#(PhysAddrWidth)); DmaReadBuffer#(64,1) setupA_read_chan <- mkDmaReadBuffer(); DmaReadBuffer#(64,1) setupB_read_chan <- mkDmaReadBuffer(); DmaWriteBuffer#(64,1) fetch_write_chan <- mkDmaWriteBuffer(); MemReadClient#(64) setupA_read_client = setupA_read_chan.dmaClient; MemReadClient#(64) setupB_read_client = setupB_read_chan.dmaClient; MemWriteClient#(64) fetch_write_client = fetch_write_chan.dmaClient; Vector#(2, MemReadClient#(64)) readClients; readClients[0] = setupA_read_client; readClients[1] = setupB_read_client; Vector#(1, MemWriteClient#(64)) writeClients; writeClients[0] = fetch_write_client; MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_HostMMUIndication); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_HostMMURequest, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_HostMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(readClients, writeClients, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_HostMemServerRequest, dma.request); MaxcommonsubseqIndicationProxy maxcommonsubseqIndicationProxy <- mkMaxcommonsubseqIndicationProxy(IfcNames_MaxcommonsubseqIndication); MaxcommonsubseqRequest maxcommonsubseqRequest <- mkMaxcommonsubseqRequest(maxcommonsubseqIndicationProxy.ifc, setupA_read_chan.dmaServer, setupB_read_chan.dmaServer, fetch_write_chan.dmaServer); MaxcommonsubseqRequestWrapper maxcommonsubseqRequestWrapper <- mkMaxcommonsubseqRequestWrapper(IfcNames_MaxcommonsubseqRequest,maxcommonsubseqRequest); Vector#(6,StdPortal) portals; portals[0] = maxcommonsubseqRequestWrapper.portalIfc; portals[1] = maxcommonsubseqIndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = hostMemServerIndicationProxy.portalIfc; portals[4] = hostMMURequestWrapper.portalIfc; portals[5] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: contrib/maxcommonsubseq/hirschberg.py ================================================ # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # # ASIC project # This code implements Hirschberg's longest common subsequence algorithm from # CACM June 1975 # Given strings A and B of lengths m and n, this runs in O(mn) time and O(m + n) space # with recursion depth O(lg n) from __future__ import print_function try: xrange except NameError: xrange = range # Python 3 compatibility # compute maximal length subsequence of A and B # returns a full matrix L, where L[i][j] is the longest common subsequence in # the prefixes A[:i] B[:j] up to L[m][n] which is the answer # uses O(mn) time and O(mn) space def hirschbergalga(A, B): m = len(A) n = len(B) L = [[0 for j in xrange(n+1)] for i in xrange(m+1)] for i in xrange(1, m+1): L[i][0] = 0 for j in xrange(1, n+1): L[0][j] = 0 for i in xrange(1, m+1): for j in xrange(1, n+1): if A[i-1]==B[j-1]: L[i][j] = L[i-1][j-1] + 1 else: L[i][j] = max(L[i][j-1], L[i-1][j]) return L # should be 2 hirschbergalga(" a b c ", "xxbsscee") # compute the length of the longest common subsequence # returns the last row of the L matrix above, namely L[m][j] for j in [0..m] # uses O(mn) time and O(n) space. # It is prudent to pass B as the shorter argument def hirschbergalgb(A, B): m = len(A) n = len(B) K = [[0 for j in xrange(n+1)] for i in xrange(2)] for i in xrange(1,m+1): for j in xrange(1,n+1): K[0][j] = K[1][j] for j in xrange(1, n+1): if A[i-1]==B[j-1]: K[1][j] = K[0][j-1] + 1 else: K[1][j] = max(K[1][j-1], K[0][j]) LL = [K[1][j] for j in xrange(n+1)] return(LL) # returns the actual longest common subsequence, as a string # The natural order of execution will return the parts of the answer so the results # could be pushed into a stream or fifo def hirschbergalgc(A, B): print("algC ", A, B) m = len(A) n = len(B) if n == 0: return "" if m == 1: if A[0] in B: return A else: return "" i = m / 2 # solve the forward problem, using string prefixes L1 = hirschbergalgb(A[0:i], B) print("algB ", " A ", A[0:i], " B ", B, " L1 ", L1) # solve the reverse problem, using string suffixes L2 = hirschbergalgb(A[i:][::-1], B[::-1]) print("algB ", " A ", A[i:][::-1], " B ", B, " L2 ", L2) # find k, the j at which m is maximized m = -1 for j in xrange(n+1): t = L1[j] + L2[n-j]; if t > m: m = t k = j # given break points i and k, solve the two subproblems recursively C1 = hirschbergalgc(A[0:i],B[0:k]) C2 = hirschbergalgc(A[i:], B[k:]) return C1 + C2 def hirschbergalgc2(sa, sb, A, B): m = len(A) n = len(B) print("algC ", "sa ", sa, " la ", m, " sb ", sb, " lb ", n, A, B) if n == 0: return "" if m == 1: if A[0] in B: return A else: return "" i = m / 2 print("m= ", m, " i = ", i) # solve the forward problem, using string prefixes L1 = hirschbergalgb(A[0:i], B) print("algB ", " A ", A[0:i], " B ", B, " L1 ", L1) # solve the reverse problem, using string suffixes L2 = hirschbergalgb(A[i:][::-1], B[::-1]) print("algB ", " A ", A[i:][::-1], " B ", B, " L2 ", L2) # find k, the j at which m is maximized m = -1 for j in xrange(n+1): t = L1[j] + L2[n-j]; if t > m: m = t k = j # given break points i and k, solve the two subproblems recursively C1 = hirschbergalgc2(sa, sb, A[0:i],B[0:k]) C2 = hirschbergalgc2(sa +i, sb + k, A[i:], B[k:]) return C1 + C2 strA = "___a_____b______c____" strB = "..a........b.c...."; strA = "012a45678b012345c7890"; strB = "ABaDEFGHIJKbMcOPQR"; hirschbergalgc2(0, 0, strA, strB) ================================================ FILE: contrib/maxcommonsubseq/testmaxcommonsubseq.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include "dmaManager.h" #include #include #include "MaxcommonsubseqIndication.h" #include "MaxcommonsubseqRequest.h" sem_t test_sem; int result_length; class MaxcommonsubseqIndication : public MaxcommonsubseqIndicationWrapper { public: MaxcommonsubseqIndication(unsigned int id) : MaxcommonsubseqIndicationWrapper(id){}; virtual void setupAComplete() { fprintf(stderr, "setupAComplete\n"); sem_post(&test_sem); } virtual void setupBComplete() { fprintf(stderr, "setupBComplete\n"); sem_post(&test_sem); } virtual void fetchComplete() { fprintf(stderr, "fetchComplete\n"); sem_post(&test_sem); } virtual void searchResult (uint32_t v){ result_length = v; fprintf(stderr, "searchResult = %d\n", v); sem_post(&test_sem); } }; int main(int argc, const char **argv) { MaxcommonsubseqRequestProxy *device = 0; MaxcommonsubseqIndication *deviceIndication = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); device = new MaxcommonsubseqRequestProxy(IfcNames_MaxcommonsubseqRequest); DmaManager *dma = platformInit(); deviceIndication = new MaxcommonsubseqIndication(IfcNames_MaxcommonsubseqIndication); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } fprintf(stderr, "simple tests\n"); int strAAlloc; int strBAlloc; int fetchAlloc; unsigned int alloc_len = 128; unsigned int fetch_len = alloc_len * alloc_len; int rcA, rcB, rcFetch; struct stat statAbuf, statBbuf, statFetchbuf; fetchAlloc = portalAlloc(fetch_len*sizeof(uint16_t), 0); rcFetch = fstat(fetchAlloc, &statFetchbuf); if (rcA < 0) perror("fstatFetch"); int *fetch = (int *)portalMmap(fetchAlloc, fetch_len * sizeof(uint16_t)); if (fetch == MAP_FAILED) perror("fetch mmap failed"); assert(fetch != MAP_FAILED); strAAlloc = portalAlloc(alloc_len, 0); rcA = fstat(strAAlloc, &statAbuf); if (rcA < 0) perror("fstatA"); char *strA = (char *)portalMmap(strAAlloc, alloc_len); if (strA == MAP_FAILED) perror("strA mmap failed"); assert(strA != MAP_FAILED); strBAlloc = portalAlloc(alloc_len, 0); rcB = fstat(strBAlloc, &statBbuf); if (rcA < 0) perror("fstatB"); char *strB = (char *)portalMmap(strBAlloc, alloc_len); if (strB == MAP_FAILED) perror("strB mmap failed"); assert(strB != MAP_FAILED); /* const char *strA_text = "___a_____b______c____"; const char *strB_text = "..a........b.c...."; */ const char *strA_text = "012a45678b012345c7890"; const char *strB_text = "ABaDEFGHIJKbMcOPQR"; assert(strlen(strA_text) < alloc_len); assert(strlen(strB_text) < alloc_len); strncpy(strA, strA_text, alloc_len); strncpy(strB, strB_text, alloc_len); int strA_len = strlen(strA); int strB_len = strlen(strB); uint16_t swFetch[fetch_len]; portalTimerInit(); portalTimerStart(0); fprintf(stderr, "elapsed time (hw cycles): %lld\n", (long long)portalTimerLap(0)); portalCacheFlush(strAAlloc, strA, alloc_len, 1); portalCacheFlush(strBAlloc, strB, alloc_len, 1); portalCacheFlush(fetchAlloc, fetch, fetch_len*sizeof(uint16_t), 1); unsigned int ref_strAAlloc = dma->reference(strAAlloc); unsigned int ref_strBAlloc = dma->reference(strBAlloc); unsigned int ref_fetchAlloc = dma->reference(fetchAlloc); device->setupA(ref_strAAlloc, 0, strA_len); sem_wait(&test_sem); device->setupB(ref_strBAlloc, 0, strB_len); sem_wait(&test_sem); uint64_t cycles; uint64_t beats; fprintf(stderr, "starting algorithm A\n"); portalTimerInit(); portalTimerStart(0); device->start(0); sem_wait(&test_sem); cycles = portalTimerLap(0); beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); fprintf(stderr, "hw cycles: %f\n", (float)cycles); device->fetch(ref_fetchAlloc, 0, 0, fetch_len / 2); sem_wait(&test_sem); printf("fetch 1 finished \n"); device->fetch(ref_fetchAlloc, fetch_len, fetch_len / 2, fetch_len / 2); sem_wait(&test_sem); printf("fetch 2 finished \n"); memcpy(swFetch, fetch, fetch_len * sizeof(uint16_t)); printf(" "); for (int j = 0; j <= strB_len; j += 1) { printf("%4d", j); } printf("\n"); printf(" "); for (int j = 0; j <= strB_len; j += 1) { printf("%4c", strB[j-1]); } printf("\n"); for (int i = 0; i <= strA_len; i += 1) { printf("%4c%4d", strA[i-1], i); for (int j = 0; j <= strB_len; j += 1) { printf("%4d", swFetch[(i << 7) + j] & 0xff); } printf("\n"); } fprintf(stderr, "starting algorithm B, forward\n"); portalTimerInit(); portalTimerStart(0); device->start(1); sem_wait(&test_sem); cycles = portalTimerLap(0); fprintf(stderr, "hw cycles: %f\n", (float)cycles); device->fetch(ref_fetchAlloc, 0, 0, fetch_len / 2); sem_wait(&test_sem); memcpy(swFetch, fetch, fetch_len * sizeof(uint16_t)); printf(" "); for (int j = 0; j <= strB_len; j += 1) { printf("%4d", j); } printf("\n"); printf(" "); for (int j = 0; j <= strB_len; j += 1) { printf("%4c", strB[j-1]); } printf("\n"); for (int i = 0; i < 1; i += 1) { printf("%4c%4d", strA[i-1], i); for (int j = 0; j <= strB_len; j += 1) { printf("%4d", swFetch[(i << 7) + j] & 0xff); } printf("\n"); } /* reverse argument strings */ for (int i = 0; i < strA_len; i += 1) { strA[i] = strA_text[strA_len - i - 1]; } for (int i = 0; i < strB_len; i += 1) { strB[i] = strB_text[strB_len - i - 1]; } device->setupA(ref_strAAlloc, 0, strA_len); sem_wait(&test_sem); device->setupB(ref_strBAlloc, 0, strB_len); sem_wait(&test_sem); fprintf(stderr, "starting algorithm B, backward\n"); portalTimerInit(); portalTimerStart(0); device->start(2); sem_wait(&test_sem); cycles = portalTimerLap(0); fprintf(stderr, "hw cycles: %f\n", (float)cycles); device->fetch(ref_fetchAlloc, 0, 0, fetch_len / 2); sem_wait(&test_sem); memcpy(swFetch, fetch, fetch_len * sizeof(uint16_t)); printf(" "); for (int j = 0; j <= strB_len; j += 1) { printf("%4d", j); } printf("\n"); printf(" "); for (int j = 0; j <= strB_len; j += 1) { printf("%4c", strB[j-1]); } printf("\n"); for (int i = 0; i < 1; i += 1) { printf("%4c%4d", strA[i-1], i); for (int j = 0; j <= strB_len; j += 1) { printf("%4d", swFetch[(i << 7) + j] & 0xff); } printf("\n"); } /* forward argument strings */ for (int i = 0; i < strA_len; i += 1) { strA[i] = strA_text[i]; } for (int i = 0; i < strB_len; i += 1) { strB[i] = strB_text[i]; } device->setupA(ref_strAAlloc, 0, strA_len); sem_wait(&test_sem); device->setupB(ref_strBAlloc, 0, strB_len); sem_wait(&test_sem); fprintf(stderr, "starting algorithm C\n"); portalTimerInit(); portalTimerStart(0); device->start(3); sem_wait(&test_sem); cycles = portalTimerLap(0); fprintf(stderr, "hw cycles: %f\n", (float)cycles); device->fetch(ref_fetchAlloc, 0, 0, fetch_len / 2); sem_wait(&test_sem); memcpy(swFetch, fetch, fetch_len * sizeof(uint16_t)); if (result_length > strB_len) result_length = strB_len; printf("Algorithm C results\n"); for (int j = 0; j < result_length; j += 1) { char c = swFetch[j] & 0xff; printf(" %02x (%c)", 0xff & c, (isalnum(c) ? c: '_')); } printf("\n"); close(strAAlloc); close(strBAlloc); close(fetchAlloc); } ================================================ FILE: contrib/noc/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = NocRequest NocIndication BSVFILES = Noc.bsv Top.bsv CPPFILES=testnoc.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/noc/Noc.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import SerialFIFO::*; import NocNode::*; import Connectable::*; import StmtFSM::*; import Vector::*; import FIFOF::*; import Pipe::*; interface NocIndication; method Action ack(Bit#(4) recvnode, Bit#(4) to, Bit#(32) message); endinterface interface NocRequest; method Action send(Bit#(4) sendnode, Bit#(4) to, Bit#(32) message); endinterface module mkNocRequest#(NocIndication indication)(NocRequest); SerialFIFO#(DataMessage) xxx <- mkSerialFIFO(); Vector#(5, SerialFIFO#(DataMessage)) we <- replicateM( mkSerialFIFO ); Vector#(5, SerialFIFO#(DataMessage)) ew <- replicateM( mkSerialFIFO ); // discard traffic from loose ends rule discardeast; $display("we[4] discard %x", we[4].out.first); we[4].out.deq(); endrule rule discardwest; $display("ew[0] discard %x", ew[0].out.first); ew[0].out.deq(); endrule Vector#(4, SerialFIFO#(DataMessage)) node; for (Bit#(4) i = 0; i < 4; i = i + 1) begin node[i] <- mkNocNode(unpack(i), SerialFIFO {in: ew[i+0].in, out: we[i+0].out}, SerialFIFO {in: we[i+1].in, out: ew[i+1].out}); end // fsm to read from host ports and generate indications Reg#(Bit#(4)) id <- mkReg(0); Stmt readindications = seq while(True) seq for(id <= 0; id < 4; id <= id + 1) if (node[id].out.notEmpty()) seq $display("recv at %d to %d m %x", id, node[id].out.first.address, node[id].out.first.payload); indication.ack(id, node[id].out.first.address, node[id].out.first.payload); node[id].out.deq(); endseq endseq endseq; mkAutoFSM(readindications); method Action send(Bit#(4) sendnode, Bit#(4) to, Bit#(32) message); $display("send f %d t %d m %x", sendnode, to, message); node[sendnode].in.enq(DataMessage{address: to, payload: message}); endmethod endmodule ================================================ FILE: contrib/noc/NocNode.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; import SerialFIFO::*; import FIFOF::*; import Vector::*; import Pipe::*; import Arbiter::*; typedef struct { Bit#(4) address; Bit#(32) payload; } DataMessage deriving(Bits); function Action move(PipeOut#(DataMessage) from, PipeIn#(DataMessage) to); return action $display("move %x", from.first); to.enq(from.first); from.deq(); endaction; endfunction module mkNocArbitrate#(Bit#(4) id, String name, Vector#(n, PipeOut#(a)) in, PipeIn#(a) out)(Empty); Arbiter_IFC#(n) arb <- mkArbiter(False); for (Integer i = 0; i < valueOf(n); i = i + 1) rule send_request (out.notFull && in[i].notEmpty); arb.clients[i].request(); endrule rule move; if (out.notFull && in[arb.grant_id].notEmpty) action $display("%s id %d from %d", name, id, arb.grant_id); out.enq(in[arb.grant_id].first()); in[arb.grant_id].deq(); endaction endrule endmodule module mkNocNode#(Bit#(4) id, SerialFIFO#(DataMessage) west, SerialFIFO#(DataMessage) east)(SerialFIFO#(DataMessage)); // host Links FIFOF#(DataMessage) fifofromhost <- mkSizedFIFOF(4); FIFOF#(DataMessage) fifotohost <- mkSizedFIFOF(4); SerialFIFO#(DataMessage) host = SerialFIFO{in: toPipeIn(fifotohost), out: toPipeOut(fifofromhost)}; // buffers for crossbar switch FIFOF#(DataMessage) he <- mkSizedFIFOF(4); FIFOF#(DataMessage) hw <- mkSizedFIFOF(4); FIFOF#(DataMessage) hh <- mkSizedFIFOF(4); FIFOF#(DataMessage) ew <- mkSizedFIFOF(4); FIFOF#(DataMessage) we <- mkSizedFIFOF(4); FIFOF#(DataMessage) eh <- mkSizedFIFOF(4); FIFOF#(DataMessage) wh <- mkSizedFIFOF(4); // collate for inputs to host, east, west Vector#(3,PipeOut#(DataMessage)) vToHost = newVector; Vector#(2,PipeOut#(DataMessage)) vToEast = newVector; Vector#(2,PipeOut#(DataMessage)) vToWest = newVector; vToHost[0] = toPipeOut(hh); vToHost[1] = toPipeOut(eh); vToHost[2] = toPipeOut(wh); vToEast[0] = toPipeOut(he); vToEast[1] = toPipeOut(we); vToWest[0] = toPipeOut(hw); vToWest[1] = toPipeOut(ew); mkNocArbitrate(id, "toHost", vToHost, host.in); mkNocArbitrate(id, "toEast", vToEast, east.in); mkNocArbitrate(id, "toWest", vToWest, west.in); // sort host messages to proper queue rule fromhost (host.out.notEmpty); if (host.out.first.address < id) begin $display("id %d host to west", id); move(host.out, toPipeIn(hw)); end else if (host.out.first.address == id) begin $display("id %d host to host", id); move(host.out, toPipeIn(hh)); end else begin $display("id %d host to east", id); move(host.out, toPipeIn(he)); end endrule // Handle arriving messages from East rule fromeast (east.out.notEmpty); if (east.out.first.address == id) begin $display("fromeast %d to host v %x", id, east.out.first); move(east.out, toPipeIn(eh)); end else begin $display("fromeast %d to west v %x", id, east.out.first); move(east.out, toPipeIn(ew)); end endrule // Handle arriving messages from West rule fromwest (west.out.notEmpty); if (west.out.first.address == id) begin $display("fromwest %d to host v %x", id, west.out.first); move(west.out, toPipeIn(wh)); end else begin $display("fromwest %d to east v %x", id, west.out.first); move(west.out, toPipeIn(we)); end endrule // interface wiring interface PipeIn in = toPipeIn(fifofromhost); interface PipeOut out = toPipeOut(fifotohost); endmodule ================================================ FILE: contrib/noc/Readme.md ================================================ Network on Chip This example is an extension of the serialconfig scheme to make more of an on-chip network. The network is composed of nodes, each of which can send or receive messages. Point to point links between the nodes complete the design. Stage 1: 1-D mesh Each node has two links, called East and West, and an address which is its coordinate. Each node therefore has inputs from East, West, and Local. plus three outputs to East, West, and Local. The local link is called "host" The switch is a 3x3 crossbar, implemented with three three input muxes. (In the alternative, we could choose not to support loopback traffic, simplifying the switch by 1 leg on the muxes.) The Each swith input is a FIFOF. Each output (row) is a round-robin arbiter that selects the next message to send from the various inputs. Each input link has a distributor switch column) rule that routes an arriving message to the proper swith FIFO. Each link is a SerialFIFO, which is two back-to-back Gearbox modules, so the node ends of a link have the DataMessage type, while the "middle" of the link is serial (a 1-bit wide FIFO, really). Test Program The test program sends a message from each node to each other node ================================================ FILE: contrib/noc/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import NocIndication::*; import NocRequest::*; import Noc::*; typedef enum {IfcNames_NocIndication, IfcNames_NocRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); // instantiate user portals NocIndicationProxy nocIndicationProxy <- mkNocIndicationProxy(IfcNames_NocIndication); NocRequest nocRequest <- mkNocRequest(nocIndicationProxy.ifc); NocRequestWrapper nocRequestWrapper <- mkNocRequestWrapper(IfcNames_NocRequest,nocRequest); Vector#(2,StdPortal) portals; portals[0] = nocRequestWrapper.portalIfc; portals[1] = nocIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/noc/testnoc.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include "NocIndication.h" #include "NocRequest.h" #include "GeneratedTypes.h" sem_t test_sem; uint32_t lastheardby; uint32_t lastto; uint32_t lastmsg; NocRequestProxy *dev = 0; class NocIndication : public NocIndicationWrapper { public: NocIndication(unsigned int id) : NocIndicationWrapper(id){}; virtual void ack(uint32_t heardby, uint32_t to, uint32_t msg) { fprintf(stderr, "ack h %d t %d msg %08x\n", heardby, to, msg); lastheardby = heardby; lastto = to; lastmsg = msg; sem_post(&test_sem); } }; void lastheardbyshouldbe(uint32_t heardby) { if (lastheardby != heardby) printf("error, expected data %08x got %08x\n", heardby, lastheardby); } void lastmsgshouldbe(uint32_t msg) { if (lastmsg != msg) printf("error, expected data %08x got %08x\n", msg, lastmsg); } void lasttoshouldbe(uint32_t to) { if (lastto != to) printf("error, expected to address %08x got %08x\n", to, lastto); } void dosend(uint32_t from, uint32_t to, uint32_t msg) { dev->send(from, to, msg); sem_wait(&test_sem); lastheardbyshouldbe(to); lasttoshouldbe(to); lastmsgshouldbe(msg); } void dotest() { uint32_t from, to, msg; for (from = 0; from < 4; from += 1) { for (to = 0; to < 4; to += 1) { printf("send from %d to %d v %08x\n", from, to, (from << 16) + to); dosend(from, to, (from << 16) + to); } } } int main(int argc, const char **argv) { NocIndication *deviceIndication = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); dev = new NocRequestProxy(IfcNames_NocRequest); deviceIndication = new NocIndication(IfcNames_NocIndication); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } fprintf(stderr, "simple tests\n"); dotest(); } ================================================ FILE: contrib/noc2d/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = NocRequest NocIndication BSVFILES = Noc2d.bsv Top.bsv CPPFILES=testnoc2d.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/noc2d/Noc2d.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import SerialFIFO::*; import NocNode::*; import Connectable::*; import StmtFSM::*; import Vector::*; import FIFOF::*; import Pipe::*; interface NocIndication; method Action ack(Bit#(8) recvnode, Bit#(8) to, Bit#(32) message); endinterface interface NocRequest; method Action send(Bit#(8) sendnode, Bit#(8) to, Bit#(32) message); endinterface module mkPipeOutDiscard#(PipeOut#(Bit#(1)) x)(Empty); rule toss; x.deq(); endrule endmodule module mkNocRequest#(NocIndication indication)(NocRequest); Vector#(4, Vector#(4, NocNode#(2))) node = replicate(newVector); for (Bit#(4) x = 0; x < 4; x = x + 1) for (Bit#(4) y = 0; y < 4; y = y + 1) begin Vector#(2, Bit#(4)) id = newVector; id[0] = x; id[1] = y; node[x][y] <- mkNocNode(id); end // wire up the links in the x direction Vector#(3, Integer) indexes3 = genVector(); Vector#(4, Integer) indexes4 = genVector(); module mkXLinks#(Integer x)(Empty); module mkXLink#(Integer x, Integer y)(Empty); mkConnection(node[x][y].linkupout[0], node[x+1][y].linkdownin[0]); mkConnection(node[x+1][y].linkdownout[0], node[x][y].linkupin[0]); endmodule mapM_(mkXLink(x), indexes4); endmodule mapM_(mkXLinks, indexes3); // wire up the links in the y direction module mkYLinks#(Integer y)(Empty); module mkYLink#(Integer y, Integer x)(Empty); mkConnection(node[x][y].linkupout[1], node[x][y+1].linkdownin[1]); mkConnection(node[x][y+1].linkdownout[1], node[x][y].linkupin[1]); endmodule mapM_(mkYLink(y), indexes4); endmodule mapM_(mkYLinks, indexes3); // discard traffic from loose ends in y direction for (Bit#(4) x = 0; x < 4; x = x + 1) begin mkPipeOutDiscard(node[x][0].linkdownout[1]); mkPipeOutDiscard(node[x][3].linkupout[1]); end // discard traffic from loose ends in x direction for (Bit#(4) y = 0; y < 4; y = y + 1) begin mkPipeOutDiscard(node[0][y].linkdownout[0]); mkPipeOutDiscard(node[3][y].linkupout[0]); end // fsm to read from host ports and generate indications Reg#(Bit#(4)) idx <- mkReg(0); Reg#(Bit#(4)) idy <- mkReg(0); Stmt readindications = seq while(True) seq for(idx <= 0; idx < 4; idx <= idx + 1) for(idy <= 0; idy < 4; idy <= idy + 1) if (node[idx][idy].nodetohost.notEmpty()) seq $display("recv at [%d,%d] to [%d,%d] m %x", idx,idy, node[idx][idy].nodetohost.first.address[0], node[idx][idy].nodetohost.first.address[1], node[idx][idy].nodetohost.first.payload); indication.ack((zeroExtend(idx)<<4) + zeroExtend(idy), (zeroExtend(node[idx][idy].nodetohost.first.address[0])<<4)+ zeroExtend(node[idx][idy].nodetohost.first.address[1]), node[idx][idy].nodetohost.first.payload); node[idx][idy].nodetohost.deq(); endseq endseq endseq; mkAutoFSM(readindications); method Action send(Bit#(8) sendnode, Bit#(8) to, Bit#(32) message); Vector#(2,Bit#(4)) id = newVector; Vector#(2,Bit#(4)) dest = newVector; id[0] = sendnode[7:4]; id[1] = sendnode[3:0]; dest[0] = to[7:4]; dest[1] = to[3:0]; $display("send f %x t %x m %x", sendnode, to, message); node[id[0]][id[1]].hosttonode.enq(DataMessage{address: dest, payload: message}); endmethod endmodule ================================================ FILE: contrib/noc2d/NocNode.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; import SerialFIFO::*; import FIFOF::*; import Vector::*; import Pipe::*; import Arbiter::*; typedef struct { Vector#(2, Bit#(4)) address; Bit#(32) payload; } DataMessage deriving(Bits); interface NocNode#(numeric type dim); interface PipeIn#(DataMessage) hosttonode; interface PipeOut#(DataMessage) nodetohost; interface Vector#(dim, PipeIn#(Bit#(1))) linkupin; interface Vector#(dim, PipeOut#(Bit#(1))) linkupout; interface Vector#(dim, PipeIn#(Bit#(1))) linkdownin; interface Vector#(dim, PipeOut#(Bit#(1))) linkdownout; endinterface function PipeOut#(Bit#(1)) selectoutput(SerialFIFOTX#(DataMessage) x); return x.out; endfunction function PipeIn#(Bit#(1)) selectinput(SerialFIFORX#(DataMessage) x); return x.in; endfunction function Action move(PipeOut#(DataMessage) from, PipeIn#(DataMessage) to); return action $display("move %x", from.first); to.enq(from.first); from.deq(); endaction; endfunction module mkNocArbitrate#(Vector#(n, Bit#(4)) id, Bit#(4) outlink, Vector#(r, PipeOut#(a)) in, PipeIn#(a) out)(Empty) /* provisos( Add#(0,n,2), Add#(0,r,5) ) */ ; Arbiter_IFC#(r) arb <- mkArbiter(False); for (Integer i = 0; i < valueOf(r); i = i + 1) rule send_request (out.notFull && in[i].notEmpty); arb.clients[i].request(); endrule rule move; if (out.notFull && in[arb.grant_id].notEmpty) action $display("arb id [%d,%d] link %d from %d", id[0], id[1], outlink, arb.grant_id); out.enq(in[arb.grant_id].first()); in[arb.grant_id].deq(); endaction endrule endmodule module mkDistributor#(Vector#(n, Bit#(4)) id, PipeOut#(DataMessage) in, Vector#(r, PipeIn#(DataMessage)) out)(Empty) /* provisos( Add#(0,n,2), Add#(0,r,5) ) */ ; rule move; $display("distrib [%d,%d] to [%d,%d] v %x", id[0], id[1], in.first.address[0], in.first.address[1], in.first.payload); if (in.first.address[0] < id[0]) begin $display(" to link 1"); move(in, out[1]); end else if (in.first.address[0] > id[0]) begin $display(" to link 0"); move(in, out[0]); end else /* in.first.address[0] == id[0] */ begin if (in.first.address[1] < id[1]) begin $display(" to link 3"); move (in, out[3]); end else if (in.first.address[1] > id[1]) begin $display(" to link 2"); move (in, out[2]); end else begin $display(" to link 4"); move(in, out[4]); end end endrule endmodule // This makes a FIFO which throws away data and is never ready to read module mkDiscard(FIFOF#(DataMessage)); method Action enq(DataMessage d); endmethod method Bool notFull; return True; endmethod method DataMessage first() = ?; method Bool notEmpty(); return False; endmethod method Action deq; if (False) noAction; endmethod method Action clear = ?; endmodule typedef 2 NumDims; (* synthesize *) module mkNocNode#(Vector#(NumDims, Bit#(4)) id)(NocNode#(NumDims)); Integer radix = (valueOf(NumDims) * 2) + 1; // host Links FIFOF#(DataMessage) fifofromhost <- mkSizedFIFOF(4); FIFOF#(DataMessage) fifotohost <- mkSizedFIFOF(4); PipeIn#(DataMessage) tohost = toPipeIn(fifotohost); PipeOut#(DataMessage) fromhost = toPipeOut(fifofromhost); Vector#(NumDims, SerialFIFOTX#(DataMessage)) txup <- replicateM(mkSerialFIFOTX); Vector#(NumDims, SerialFIFORX#(DataMessage)) rxup <- replicateM(mkSerialFIFORX); Vector#(NumDims, SerialFIFOTX#(DataMessage)) txdown <- replicateM(mkSerialFIFOTX); Vector#(NumDims, SerialFIFORX#(DataMessage)) rxdown <- replicateM(mkSerialFIFORX); // sources Vector#(TAdd#(TMul#(NumDims, 2), 1), PipeOut#(DataMessage)) switchin = newVector; Vector#(TAdd#(TMul#(NumDims, 2), 1), PipeIn#(DataMessage)) switchout = newVector; // buffers for crossbar switch Vector#(TAdd#(TMul#(NumDims, 2), 1), Vector#(TAdd#(TMul#(NumDims, 2), 1), FIFOF#(DataMessage))) xp = replicate(newVector); // temps for building switch Vector#(TAdd#(TMul#(NumDims, 2), 1), PipeIn#(DataMessage)) tmpin = newVector; Vector#(TAdd#(TMul#(NumDims, 2), 1), PipeOut#(DataMessage)) tmpout = newVector; for (Integer i = 0; i < valueOf(NumDims); i = i + 1) begin switchin[(2*i) + 0] = rxup[i].out; switchin[(2*i) + 1] = rxdown[i].out; switchout[(2*i) + 0] = txup[i].in; switchout[(2*i) + 1] = txdown[i].in; end switchin[radix - 1] = fromhost; switchout[radix - 1] = tohost; for (Integer x = 0; x < radix; x = x + 1) for (Integer y = 0; y < radix; y = y + 1) if (x != y) xp[x][y] <- mkSizedFIFOF(4); for (Integer x = 0; x < (radix - 1); x = x + 1) xp[x][x] <- mkDiscard(); xp[radix - 1][radix - 1] <- mkSizedFIFOF(4); // create distributors for (Integer x = 0; x < radix; x = x + 1) begin for (Integer y = 0; y < radix; y = y + 1) tmpin[y] = toPipeIn(xp[x][y]); mkDistributor(id, switchin[x], tmpin); end // create arbiters for (Integer y = 0; y < radix; y = y + 1) begin for (Integer x = 0; x < radix; x = x + 1) tmpout[x] = toPipeOut(xp[x][y]); mkNocArbitrate(id, fromInteger(y), tmpout, switchout[y]); end // interface wiring interface PipeIn hosttonode = toPipeIn(fifofromhost); interface PipeOut nodetohost = toPipeOut(fifotohost); interface Vector linkupin = map(selectinput, rxup); interface Vector linkupout = map(selectoutput, txup); interface Vector linkdownin = map(selectinput, rxdown); interface Vector linkdownout = map(selectoutput, txdown); endmodule ================================================ FILE: contrib/noc2d/Readme.md ================================================ Network on Chip This is a two dimensional mesh network with 16 nodes. Each node has four links to adjacent nodes, plus a link to the local "host". Each node has a crossbar switch for routing. Messages are a compiled-in datatype, plus a message address which is the coordinates of the destination host in the X and Y directions. Links are SerialFIFOs, from the connectal library. The link "transmitter" is a GearBox from the message datatype to a Bit#(1) serial datatype. The link "receiver" is a Gearbox from Bit#(1) back to the message datatype. The crossbar switch consists of a matrix of FIFOF. A particular FIFO accepts messages from a particular input link which are routed to a particular output link. The four input links, plus a FIFO from the host, feed distributors. Each distributor examines the address of a message and copies the message to the correct crosspoint FIFO. A "row" in the crossbar consists of all the FIFOs which accept traffic from a particular link plus a row for messages from the host. A "column" in the crossbar consists of all the FIFOs which send traffic to a particular link, plus a column for traffic to the host. Each output link has an arbiter, which merges traffic from the associated FIFOs. In order to avoid deadlock, the network uses dimension order routing. A message traverses links in the X direction until it reaches the correct X coordinate, and then traverses links in the Y direction until the Y coordinates match. The message is then delivered to the host. A message can never be routed back to the node from which it just arrived, so there are no FIFOs needed on the diagonal of the switch matrix. There is a crosspoint to route host messages back to the local host. ================================================ FILE: contrib/noc2d/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import NocIndication::*; import NocRequest::*; import Noc2d::*; typedef enum {IfcNames_NocIndication, IfcNames_NocRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); NocIndicationProxy nocIndicationProxy <- mkNocIndicationProxy(IfcNames_NocIndication); NocRequest nocRequest <- mkNocRequest(nocIndicationProxy.ifc); NocRequestWrapper nocRequestWrapper <- mkNocRequestWrapper(IfcNames_NocRequest,nocRequest); Vector#(2,StdPortal) portals; portals[0] = nocRequestWrapper.portalIfc; portals[1] = nocIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/noc2d/testnoc2d.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include "NocIndication.h" #include "NocRequest.h" #include "GeneratedTypes.h" sem_t test_sem; uint32_t lastheardby; uint32_t lastto; uint32_t lastmsg; NocRequestProxy *dev = 0; class NocIndication : public NocIndicationWrapper { public: NocIndication(unsigned int id) : NocIndicationWrapper(id){}; virtual void ack(uint32_t heardby, uint32_t to, uint32_t msg) { fprintf(stderr, "ack h [%d.%d] t [%d.%d] msg %08x\n", (heardby >> 4) & 0x0f, heardby & 0xf, (to >> 4) & 0xf, to & 0xf, msg); lastheardby = heardby; lastto = to; lastmsg = msg; sem_post(&test_sem); } }; void lastheardbyshouldbe(uint32_t heardby) { if (lastheardby != heardby) printf("error, expected data %08x got %08x\n", heardby, lastheardby); } void lastmsgshouldbe(uint32_t msg) { if (lastmsg != msg) printf("error, expected data %08x got %08x\n", msg, lastmsg); } void lasttoshouldbe(uint32_t to) { if (lastto != to) printf("error, expected to address %08x got %08x\n", to, lastto); } void dosend(uint32_t from, uint32_t to, uint32_t msg) { dev->send(from, to, msg); sem_wait(&test_sem); lastheardbyshouldbe(to); lasttoshouldbe(to); lastmsgshouldbe(msg); } void dotest() { uint32_t fromx, fromy, tox, toy, msg; for (fromx = 0; fromx < 4; fromx += 1) { for (fromy = 0; fromy < 4; fromy += 1) { for (tox = 0; tox < 4; tox += 1) { for (toy = 0; toy < 4; toy += 1) { printf("send from [%d.%d] to [%d.%d] v %08x\n", fromx, fromy, tox, toy, (fromx << 20) + (fromy << 16) + (tox << 4) + toy); dosend((fromx << 4) + fromy, (tox << 4) + toy, (fromx << 20) + (fromy << 16) + (tox << 4) + toy); } } } } } int main(int argc, const char **argv) { NocIndication *deviceIndication = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); dev = new NocRequestProxy(IfcNames_NocRequest); deviceIndication = new NocIndication(IfcNames_NocIndication); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } fprintf(stderr, "simple tests\n"); dotest(); } ================================================ FILE: contrib/parallella/ELink.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This file is a hand-generated file that we hope will someday be // generated automatically by connectal/generated/scripts/importbvi.py // // Created by copying the style of connectal/generated/xilinx/PPS7LIB.bsv import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; // The name of this interface is a prefix "Par_" plus the common // prefix of the signals "tx" // Hopefully this is what importbvi.py would do (* always_ready, always_enabled *) interface Par_tx; method Action data_p(Bit#(8) v); method Action data_n(Bit#(8) v); method Action frame_p(Bit#(1) v); method Action frame_n(Bit#(1) v); method Action lclk_p(Bit#(1) v); method Action lclk_n(Bit#(1) v); method Bit#(1) wr_wait_p(); method Bit#(1) wr_wait_n(); method Bit#(1) rd_wait_p(); method Bit#(1) rd_wait_n(); endinterface (* always_ready, always_enabled *) interface Par_rx; method Bit#(8) data_p(); method Bit#(8) data_n(); method Bit#(1) frame_p(); method Bit#(1) frame_n(); method Bit#(1) lclk_p(); method Bit#(1) lclk_n(); method Action wr_wait_p(Bit#(1) v); method Action wr_wait_n(Bit#(1) v); method Action rd_wait_p(Bit#(1) v); method Action rd_wait_n(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Par_misc; method Bit#(1) csysack(); method Bit#(1) cactive(); method Action csysreq(Bit#(1) v); method Bit#(1) reset_chip(); method Bit#(1) reset_fpga(); method Action cclk_p(Bit#(1) v); method Action cclk_n(Bit#(1) v); endinterface typedef AxiMasterBits#(32,64,6,Empty) ParSaxiHp; typedef AxiSlaveBits#(32,32,12,Empty) ParMaxiGp; (* always_ready, always_enabled *) interface ELink; interface Par_tx tx; interface Par_rx rx; interface ParMaxiGp maxi; // this will connect to a master interface ParSaxiHp saxi; // this will connect to a slave interface Par_misc misc; endinterface import "BVI" elink = module mkELink#(Clock maxiclk, Clock saxiclk, Reset maxiclk_reset, Reset saxiclk_reset, Reset maxireset, Reset saxireset, Reset reset_chip, Reset reset_fpga)(ELink); // default_clock clk(); // default_reset rst(); input_clock maxiclk(emaxi_aclk) = maxiclk; // assigns the verilog emaxi_aclk input_clock saxiclk(s_axi_aclk) = saxiclk; // assigns the verilog s_axi_aclk input_reset maxiclk_reset() = maxiclk_reset; /* from clock*/ input_reset saxiclk_reset() = saxiclk_reset; /* from clock*/ input_reset maxireset() = maxireset; input_reset saxireset() = saxireset; interface Par_misc misc; method csysack csysack(); method cactive cactive(); method reset_chip reset_chip(); method reset_fpga reset_fpga(); method csysreq(csysreq) enable((*inhigh*) EN_csysreq); method cclk_p(cclk_p) enable((*inhigh*) EN_cclk_p); method cclk_n(cclk_n) enable((*inhigh*) EN_cclk_n); endinterface interface Par_tx tx; method data_p(tx_data_p) enable((*inhigh*) EN_tx_data_p); method data_n(tx_data_n) enable((*inhigh*) EN_tx_data_n); method frame_p(tx_frame_p) enable((*inhigh*) EN_tx_frame_p); method frame_n(tx_frame_n) enable((*inhigh*) EN_tx_frame_n); method lclk_p(tx_lclk_p) enable((*inhigh*) EN_tx_lclk_p); method lclk_n(tx_lclk_n) enable((*inhigh*) EN_tx_lclk_n); method tx_wr_wait_p wr_wait_p(); method tx_wr_wait_n wr_wait_n(); method tx_rd_wait_p rd_wait_p(); method tx_rd_wait_n rd_wait_n(); endinterface interface Par_rx rx; method rx_data_p data_p(); method rx_data_n data_n(); method rx_frame_p frame_p(); method rx_frame_n frame_n(); method rx_lclk_p lclk_p(); method rx_lclk_n lclk_n(); method wr_wait_p(rx_wr_wait_p) enable((*inhigh*) EN_rx_wr_wait_p); method wr_wait_n(rx_wr_wait_n) enable((*inhigh*) EN_rx_wr_wait_n); method rd_wait_p(rx_rd_wait_p) enable((*inhigh*) EN_rx_rd_wait_p); method rd_wait_n(rx_rd_wait_n) enable((*inhigh*) EN_rx_rd_wait_n); endinterface interface ParSaxiHp saxi; method m_axi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset); method m_axi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arid arid() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset); method arready(m_axi_arready) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_arready); method m_axi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset); method m_axi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awid awid() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset); method awready(m_axi_awready) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_awready); method m_axi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset); method m_axi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset); method bid(m_axi_bid) enable((*inhigh*) EN_m_axi_bid); method m_axi_bready bready() clocked_by (saxiclk) reset_by(saxireset); method bresp(m_axi_bresp) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_bresp); method bvalid(m_axi_bvalid) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_bvalid); method rdata(m_axi_rdata) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rdata); method rid(m_axi_rid) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rid); method rlast(m_axi_rlast) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rlast); method m_axi_rready rready() clocked_by (saxiclk) reset_by(saxireset); method rresp(m_axi_rresp) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rresp); method rvalid(m_axi_rvalid) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rvalid); method m_axi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset); method m_axi_wid wid() clocked_by (saxiclk) reset_by(saxireset); method m_axi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset); method wready(m_axi_wready) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_wready); method m_axi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset); method m_axi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset); endinterface interface ParMaxiGp maxi; method araddr(s_axi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_araddr); method arburst(s_axi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arburst); method arcache(s_axi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arcache); method s_axi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset); method arid(s_axi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arid); method arlen(s_axi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arlen); method arlock(s_axi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arlock); method arprot(s_axi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arprot); method arqos(s_axi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arqos); method s_axi_arready arready() clocked_by(maxiclk) reset_by(maxireset); method arsize(s_axi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arsize); method arvalid(s_axi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arvalid); method awaddr(s_axi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awaddr); method awburst(s_axi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awburst); method awcache(s_axi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awcache); method awid(s_axi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awid); method awlen(s_axi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awlen); method awlock(s_axi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awlock); method awprot(s_axi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awprot); method awqos(s_axi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awqos); method s_axi_awready awready() clocked_by(maxiclk) reset_by(maxireset); method awsize(s_axi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awsize); method awvalid(s_axi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awvalid); method s_axi_bid bid() clocked_by(maxiclk) reset_by(maxireset); method bready(s_axi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_bready); method s_axi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset); method s_axi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset); method s_axi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset); method s_axi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset); method rready(s_axi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_rready); method s_axi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset); method s_axi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset); method wdata(s_axi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wdata); method wid(s_axi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wid); method wlast(s_axi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wlast); method s_axi_wready wready() clocked_by(maxiclk) reset_by(maxireset); method wstrb(s_axi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wstrb); method wvalid(s_axi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wvalid); method s_axi_rid rid() clocked_by(maxiclk) reset_by(maxireset); endinterface schedule ( misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, tx.data_p, tx.data_n, tx.frame_p, tx.frame_n, tx.lclk_p, tx.lclk_n, rx.wr_wait_p, rx.wr_wait_n, rx.rd_wait_p, rx.rd_wait_n, misc.cclk_p, misc.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize, maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot, maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb, maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid, saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen, maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache, maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready, saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid, maxi.awqos, maxi.arqos, // Inputs // clkin_100, saxi.aclk, maxi.aclk, reset, saxi.aresetn, maxi.aresetn, misc.csysreq, rx.data_p, rx.data_n, rx.frame_p, rx.frame_n, rx.lclk_p, rx.lclk_n, tx.wr_wait_p, tx.wr_wait_n, tx.rd_wait_p, tx.rd_wait_n, maxi.awready, saxi.awid, saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst, saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid, maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast, saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready, maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize, saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot, saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast, maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos ) CF ( misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, tx.data_p, tx.data_n, tx.frame_p, tx.frame_n, tx.lclk_p, tx.lclk_n, rx.wr_wait_p, rx.wr_wait_n, rx.rd_wait_p, rx.rd_wait_n, misc.cclk_p, misc.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize, maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot, maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb, maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid, saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen, maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache, maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready, saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid, maxi.awqos, maxi.arqos, // Inputs // clkin_100, saxi.aclk, maxi.aclk, reset, saxi.aresetn, maxi.aresetn, misc.csysreq, rx.data_p, rx.data_n, rx.frame_p, rx.frame_n, rx.lclk_p, rx.lclk_n, tx.wr_wait_p, tx.wr_wait_n, tx.rd_wait_p, tx.rd_wait_n, maxi.awready, saxi.awid, saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst, saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid, maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast, saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready, maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize, saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot, saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast, maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos ); endmodule ================================================ FILE: contrib/parallella/Makefile ================================================ CONNECTALDIR?=../.. #S2H_INTERFACES = MainRequest:Main.request #H2S_INTERFACES = Main:MainRequest BSVFILES = ELink.bsv ParallellaLibDefs.bsv CPPFILES=testmain.cpp PARDIR=/scratch/stewart/parallella/parallella-hw/fpga/src PIN_TYPE = ParallellaLibDefs::ParallellaPins PIN_TYPE_INCLUDE = ParallellaLibDefs # CONNECTALFLAGS = -C /scratch/stewart/parallella/parallella-hw/boards/parallella-I/constraints/parallella_z70x0_loc.xdc CONNECTALFLAGS += \ --verilog $(PARDIR)/elink/hdl/elink_regmap.v \ --verilog $(PARDIR)/constants/hdl \ --verilog $(PARDIR)/elink/hdl \ --verilog $(PARDIR)/embox/hdl \ --verilog $(PARDIR)/emmu/hdl \ --verilog $(PARDIR)/gpio/hdl \ --verilog $(PARDIR)/i2c/hdl \ --verilog $(PARDIR)/memory/hdl \ --verilog $(PARDIR)/stubs/hdl CONNECTALFLAGS += -D IMPORT_HOSTIF Parallella.bsv: parallella.v $(CONNECTALDIR)/generated/scripts/importbvi.py -o Parallella.bsv -I Parallella -P PP --factor esaxi --factor emaxi --factor rx --factor tx -c clkin_100 -r reset \ -p SIDW:12 \ -p SAW:32 \ -p SDW:32 \ -p MIDW:6 \ -p MAW:32 \ -p MDW:64 \ -p STW:8 \ -p LW:8 \ -p AW:32 \ -p DW:32 \ parallella.v include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/parallella/PParallellaLIB.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This file is a hand-generated file that we hope will someday be // generated automatically by connectal/generated/scripts/importbvi.py // // Created by copying the style of connectal/generated/xilinx/PPS7LIB.bsv import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; // The name of this interface is a prefix "Par_" plus the common prefix of the signals "txo" // Hopefully this is what importbvi.py would do (* always_ready, always_enabled *) interface Par_txo; method Action data_p(Bit#(8) v); method Action data_n(Bit#(8) v); method Action frame_p(Bit#(1) v); method Action frame_n(Bit#(1) v); method Action lclk_p(Bit#(1) v); method Action lclk_n(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Par_txi; method Bit#(1) wr_wait_p(); method Bit#(1) wr_wait_n(); method Bit#(1) rd_wait_p(); method Bit#(1) rd_wait_n(); endinterface (* always_ready, always_enabled *) interface Par_rxi; method Bit#(8) data_p(); method Bit#(8) data_n(); method Bit#(1) frame_p(); method Bit#(1) frame_n(); method Bit#(1) lclk_p(); method Bit#(1) lclk_n(); method Action cclk_p(Bit#(1) v); method Action cclk_n(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Par_rxo; method Action wr_wait_p(Bit#(1) v); method Action wr_wait_n(Bit#(1) v); method Action rd_wait_p(Bit#(1) v); method Action rd_wait_n(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Par_misc; method Bit#(1) csysack(); method Bit#(1) cactive(); method Action csysreq(Bit#(1) v); method Bit#(1) reset_chip(); method Bit#(1) reset_fpga(); endinterface typedef AxiMasterBits#(32,64,6,Empty) ParSaxiHp; typedef AxiSlaveBits#(32,32,12,Empty) ParMaxiGp; (* always_ready, always_enabled *) interface PParallellaLIB; interface Par_txo txo; interface Par_txi txi; interface Par_rxo rxo; interface Par_rxi rxi; interface ParMaxiGp maxi; // this will connect to a master interface ParSaxiHp saxi; // this will connect to a slave interface Par_misc misc; endinterface import "BVI" parallella = module mkPParallellaLIB#(Clock maxiclk, Clock saxiclk, Reset maxiclk_reset, Reset saxiclk_reset, Reset maxireset, Reset saxireset, Reset reset_chip, Reset reset_fpga)(PParallellaLIB); // default_clock clk(); // default_reset rst(); input_clock maxiclk(emaxi_aclk) = maxiclk; // assigns the verilog emaxi_aclk input_clock saxiclk(esaxi_aclk) = saxiclk; // assigns the verilog esaxi_aclk input_reset maxiclk_reset() = maxiclk_reset; /* from clock*/ input_reset saxiclk_reset() = saxiclk_reset; /* from clock*/ input_reset maxireset() = maxireset; input_reset saxireset() = saxireset; interface Par_misc misc; method csysack csysack(); method cactive cactive(); method reset_chip reset_chip(); method reset_fpga reset_fpga(); method csysreq(csysreq) enable((*inhigh*) EN_csysreq); endinterface interface Par_txo txo; method data_p(txo_data_p) enable((*inhigh*) EN_txo_data_p); method data_n(txo_data_n) enable((*inhigh*) EN_txo_data_n); method frame_p(txo_frame_p) enable((*inhigh*) EN_txo_frame_p); method frame_n(txo_frame_n) enable((*inhigh*) EN_txo_frame_n); method lclk_p(txo_lclk_p) enable((*inhigh*) EN_txo_lclk_p); method lclk_n(txo_lclk_n) enable((*inhigh*) EN_txo_lclk_n); endinterface interface Par_txi txi; method txo_wr_wait_p wr_wait_p(); method txo_wr_wait_n wr_wait_n(); method txo_rd_wait_p rd_wait_p(); method txo_rd_wait_n rd_wait_n(); endinterface interface Par_rxi rxi; method rxi_data_p data_p(); method rxi_data_n data_n(); method rxi_frame_p frame_p(); method rxi_frame_n frame_n(); method rxi_lclk_p lclk_p(); method rxi_lclk_n lclk_n(); method cclk_p(rxi_cclk_p) enable((*inhigh*) EN_rxi_cclk_p); method cclk_n(rxi_cclk_n) enable((*inhigh*) EN_rxi_cclk_n); endinterface interface Par_rxo rxo; method wr_wait_p(rxo_wr_wait_p) enable((*inhigh*) EN_rxo_wr_wait_p); method wr_wait_n(rxo_wr_wait_n) enable((*inhigh*) EN_rxo_wr_wait_n); method rd_wait_p(rxo_rd_wait_p) enable((*inhigh*) EN_rxo_rd_wait_p); method rd_wait_n(rxo_rd_wait_n) enable((*inhigh*) EN_rxo_rd_wait_n); endinterface interface ParSaxiHp saxi; method esaxi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset); method esaxi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arid arid() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset); method arready(esaxi_arready) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_arready); method esaxi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset); method esaxi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awid awid() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset); method awready(esaxi_awready) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_awready); method esaxi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset); method esaxi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset); method bid(esaxi_bid) enable((*inhigh*) EN_esaxi_bid); method esaxi_bready bready() clocked_by (saxiclk) reset_by(saxireset); method bresp(esaxi_bresp) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_bresp); method bvalid(esaxi_bvalid) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_bvalid); method rdata(esaxi_rdata) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rdata); method rid(esaxi_rid) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rid); method rlast(esaxi_rlast) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rlast); method esaxi_rready rready() clocked_by (saxiclk) reset_by(saxireset); method rresp(esaxi_rresp) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rresp); method rvalid(esaxi_rvalid) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rvalid); method esaxi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset); method esaxi_wid wid() clocked_by (saxiclk) reset_by(saxireset); method esaxi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset); method wready(esaxi_wready) clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_wready); method esaxi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset); method esaxi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset); endinterface interface ParMaxiGp maxi; method araddr(emaxi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_araddr); method arburst(emaxi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arburst); method arcache(emaxi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arcache); method emaxi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset); method arid(emaxi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arid); method arlen(emaxi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arlen); method arlock(emaxi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arlock); method arprot(emaxi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arprot); method arqos(emaxi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arqos); method emaxi_arready arready() clocked_by(maxiclk) reset_by(maxireset); method arsize(emaxi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arsize); method arvalid(emaxi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arvalid); method awaddr(emaxi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awaddr); method awburst(emaxi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awburst); method awcache(emaxi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awcache); method awid(emaxi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awid); method awlen(emaxi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awlen); method awlock(emaxi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awlock); method awprot(emaxi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awprot); method awqos(emaxi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awqos); method emaxi_awready awready() clocked_by(maxiclk) reset_by(maxireset); method awsize(emaxi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awsize); method awvalid(emaxi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awvalid); method emaxi_bid bid() clocked_by(maxiclk) reset_by(maxireset); method bready(emaxi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_bready); method emaxi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset); method emaxi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset); method emaxi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset); method emaxi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset); method rready(emaxi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_rready); method emaxi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset); method emaxi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset); method wdata(emaxi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wdata); method wid(emaxi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wid); method wlast(emaxi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wlast); method emaxi_wready wready() clocked_by(maxiclk) reset_by(maxireset); method wstrb(emaxi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wstrb); method wvalid(emaxi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wvalid); method emaxi_rid rid() clocked_by(maxiclk) reset_by(maxireset); endinterface schedule ( misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, txo.data_p, txo.data_n, txo.frame_p, txo.frame_n, txo.lclk_p, txo.lclk_n, rxo.wr_wait_p, rxo.wr_wait_n, rxo.rd_wait_p, rxo.rd_wait_n, rxi.cclk_p, rxi.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize, maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot, maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb, maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid, saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen, maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache, maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready, saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid, maxi.awqos, maxi.arqos, // Inputs // clkin_100, saxi.aclk, maxi.aclk, reset, saxi.aresetn, maxi.aresetn, misc.csysreq, rxi.data_p, rxi.data_n, rxi.frame_p, rxi.frame_n, rxi.lclk_p, rxi.lclk_n, txi.wr_wait_p, txi.wr_wait_n, txi.rd_wait_p, txi.rd_wait_n, maxi.awready, saxi.awid, saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst, saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid, maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast, saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready, maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize, saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot, saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast, maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos ) CF ( misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, txo.data_p, txo.data_n, txo.frame_p, txo.frame_n, txo.lclk_p, txo.lclk_n, rxo.wr_wait_p, rxo.wr_wait_n, rxo.rd_wait_p, rxo.rd_wait_n, rxi.cclk_p, rxi.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize, maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot, maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb, maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid, saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen, maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache, maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready, saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid, maxi.awqos, maxi.arqos, // Inputs // clkin_100, saxi.aclk, maxi.aclk, reset, saxi.aresetn, maxi.aresetn, misc.csysreq, rxi.data_p, rxi.data_n, rxi.frame_p, rxi.frame_n, rxi.lclk_p, rxi.lclk_n, txi.wr_wait_p, txi.wr_wait_n, txi.rd_wait_p, txi.rd_wait_n, maxi.awready, saxi.awid, saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst, saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid, maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast, saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready, maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize, saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot, saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast, maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos ); endmodule ================================================ FILE: contrib/parallella/ParallellaLib.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import DefaultValue::*; import GetPut::*; import Connectable::*; import ConnectableWithTrace::*; import Bscan::*; import Vector::*; import ELink::*; import Portal::*; import AxiMasterSlave::*; import AxiDma::*; import XilinxCells::*; import ConnectalXilinxCells::*; import ConnectalClocks::*; import AxiBits::*; import AxiGather::*; import ParallellaLibDefs::*; module mkParallellaLib#(Clock axi_clock, Reset axi_reset)(ParallellaLib); ELink foo <- mkELink( axi_clock, axi_clock, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset, axi_reset ); AxiSlaveCommon#(32,32,12,Empty) vtopm_axi_gp; AxiMasterCommon#(32,64,6) vtops_axi_hp; vtopm_axi_gp <- mkAxi3SlaveGather(foo.maxi, clocked_by axi_clock, reset_by axi_reset); vtops_axi_hp <- mkAxi3MasterGather(foo.saxi, clocked_by axi_clock, reset_by axi_reset); interface maxi = vtopm_axi_gp; interface saxi = vtops_axi_hp; interface ParallellaPins pins; interface tx = foo.tx; interface rx = foo.rx; endinterface interface misc = foo.misc; endmodule ================================================ FILE: contrib/parallella/ParallellaLibDefs.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ELink::*; import AxiMasterSlave::*; import AxiBits::*; import AxiGather::*; interface ParallellaPins; interface Par_tx tx; interface Par_rx rx; endinterface interface ParallellaLib; interface ParallellaPins pins; interface AxiSlaveCommon#(32,32,12,Empty) maxi; // this will connect to a master interface AxiMasterCommon#(32,64,6) saxi; // this will connect to a slave interface Par_misc misc; endinterface ================================================ FILE: contrib/parallella/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import GetPut::*; import Connectable :: *; import Clocks :: *; import FIFO::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import PS7LIB::*; import PPS7LIB::*; import ConnectalClocks::*; import BlueScopeEventPIO::*; import ParallellaLibDefs::*; import ParallellaLib::*; import PParallellaLIB::*; import AxiMasterSlave::*; import AxiGather::*; import AxiDma::*; module mkConnectalTop#(HostInterface host)(ConnectalTop); Clock oneTrueClock <- exposeCurrentClock; Reset oneTrueReset <- exposeCurrentReset; ParallellaLib plib <- mkParallellaLib(oneTrueClock, oneTrueReset); mkConnection(host.ps7.m_axi_gp[1].client, plib.maxi.server); mkConnection(plib.saxi.client, host.ps7.s_axi_hp[3].server); interface ParallellaPins pins = plib.pins; endmodule : mkConnectalTop export mkConnectalTop; export ParallellaLibDefs::*; export PParallellaLIB::*; ================================================ FILE: contrib/parallella/notes.txt ================================================ In parallella-hw I'm getting width differences between various axi bus signals in elink.v and the corresponding signals on the PS7. From Table 5-9 in the Zynq TRM ug585-Zynq-7000-TRM.pdf, I think elink.v has the wrong values. Why is elink.v like this? Is there a module that actually wires up the ps7 to elink.v somewhere? WARNING: [Synth 8-689] width (6) of port connection 'm_axi_bid' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1539] WARNING: [Synth 8-689] width (6) of port connection 'm_axi_rid' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1543] WARNING: [Synth 8-689] width (6) of port connection 'm_axi_arid' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1603] WARNING: [Synth 8-689] width (6) of port connection 'm_axi_awid' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1613] WARNING: [Synth 8-689] width (4) of port connection 'm_axi_arlen' does not match port width (8) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1604] WARNING: [Synth 8-689] width (4) of port connection 'm_axi_awlen' does not match port width (8) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1614] WARNING: [Synth 8-689] width (2) of port connection 'm_axi_arlock' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1605] WARNING: [Synth 8-689] width (2) of port connection 'm_axi_awlock' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1615] WARNING: [Synth 8-689] width (2) of port connection 'm_axi_arsize' does not match port width (3) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1608] WARNING: [Synth 8-689] width (2) of port connection 'm_axi_awsize' does not match port width (3) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1618] WARNING: [Synth 8-689] width (32) of port connection 's_axi_araddr' does not match port width (30) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1552] WARNING: [Synth 8-689] width (32) of port connection 's_axi_awaddr' does not match port width (30) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1562] WARNING: [Synth 8-689] width (4) of port connection 's_axi_arlen' does not match port width (8) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1556] WARNING: [Synth 8-689] width (4) of port connection 's_axi_awlen' does not match port width (8) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1566] WARNING: [Synth 8-689] width (2) of port connection 's_axi_arlock' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1557] WARNING: [Synth 8-689] width (2) of port connection 's_axi_awlock' does not match port width (1) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1567] WARNING: [Synth 8-689] width (2) of port connection 's_axi_arsize' does not match port width (3) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1560] WARNING: [Synth 8-689] width (2) of port connection 's_axi_awsize' does not match port width (3) of module 'elink' [/scratch/stewart/connectal/contrib/parallella/zedboard/verilog/mkZynqTop.v:1570] ================================================ FILE: contrib/parallella/parallella.v ================================================ /* File: parallella.v This file is part of the Parallella FPGA Reference Design. Copyright (C) 2013 Adapteva, Inc. Contributed by Roman Trogan This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program (see the file COPYING). If not, see . */ module parallella (/*AUTOARG*/ // Outputs csysack, cactive, reset_chip, reset_fpga, txo_data_p, txo_data_n, txo_frame_p, txo_frame_n, txo_lclk_p, txo_lclk_n, rxo_wr_wait_p, rxo_wr_wait_n, rxo_rd_wait_p, rxo_rd_wait_n, rxi_cclk_p, rxi_cclk_n, emaxi_awid, emaxi_awaddr, emaxi_awlen, emaxi_awsize, emaxi_awburst, emaxi_awlock, emaxi_awcache, emaxi_awprot, emaxi_awvalid, esaxi_awready, emaxi_wid, emaxi_wdata, emaxi_wstrb, emaxi_wlast, emaxi_wvalid, esaxi_wready, emaxi_bready, esaxi_bid, esaxi_bresp, esaxi_bvalid, emaxi_arid, emaxi_araddr, emaxi_arlen, emaxi_arsize, emaxi_arburst, emaxi_arlock, emaxi_arcache, emaxi_arprot, emaxi_arvalid, esaxi_arready, emaxi_rready, esaxi_rid, esaxi_rdata, esaxi_rresp, esaxi_rlast, esaxi_rvalid, emaxi_awqos, emaxi_arqos, // Inputs clkin_100, esaxi_aclk, emaxi_aclk, reset, esaxi_aresetn, emaxi_aresetn, csysreq, rxi_data_p, rxi_data_n, rxi_frame_p, rxi_frame_n, rxi_lclk_p, rxi_lclk_n, txi_wr_wait_p, txi_wr_wait_n, txi_rd_wait_p, txi_rd_wait_n, emaxi_awready, esaxi_awid, esaxi_awaddr, esaxi_awlen, esaxi_awsize, esaxi_awburst, esaxi_awlock, esaxi_awcache, esaxi_awprot, esaxi_awvalid, emaxi_wready, esaxi_wid, esaxi_wdata, esaxi_wstrb, esaxi_wlast, esaxi_wvalid, emaxi_bid, emaxi_bresp, emaxi_bvalid, esaxi_bready, emaxi_arready, esaxi_arid, esaxi_araddr, esaxi_arlen, esaxi_arsize, esaxi_arburst, esaxi_arlock, esaxi_arcache, esaxi_arprot, esaxi_arvalid, emaxi_rid, emaxi_rdata, emaxi_rresp, emaxi_rlast, emaxi_rvalid, esaxi_rready, esaxi_awqos, esaxi_arqos ); parameter SIDW = 12; //ID Width parameter SAW = 32; //Address Bus Width parameter SDW = 32; //Data Bus Width parameter MIDW = 6; //ID Width parameter MAW = 32; //Address Bus Width parameter MDW = 64; //Data Bus Width parameter STW = 8; //Number of strobes parameter LW = 8; parameter AW = 32; //Address Bus Width parameter DW = 32; //Data Bus Width //######### //# Inputs //######### // global signals input clkin_100; // 100MHz input clock input esaxi_aclk; // clock source of the axi bus for slave port input emaxi_aclk; // clock source of the axi bus for master port input reset; // system reset input esaxi_aresetn; // reset of axi bus for slave port input emaxi_aresetn; // reset of axi bus for master port input csysreq; // system exit low-power state request // LVDS FMC Port input [7:0] rxi_data_p; input [7:0] rxi_data_n; input rxi_frame_p; input rxi_frame_n; input rxi_lclk_p; input rxi_lclk_n; input txi_wr_wait_p; input txi_wr_wait_n; input txi_rd_wait_p; input txi_rd_wait_n; //######################## //# Write address channel //######################## // Master Port input emaxi_awready; //write address ready // Slave Port input [SIDW-1:0] esaxi_awid; //write address ID input [MAW-1:0] esaxi_awaddr; //write address input [3:0] esaxi_awlen; //burst lenght (the number of data transfers) input [2:0] esaxi_awsize; //burst size (the size of each transfer) input [1:0] esaxi_awburst; //burst type input [1:0] esaxi_awlock; //lock type (atomic characteristics) input [3:0] esaxi_awcache; //memory type input [2:0] esaxi_awprot; //protection type input esaxi_awvalid; //write address valid //######################## //# Write data channel //######################## // Master Port input emaxi_wready;//write ready // Slave Port input [SIDW-1:0] esaxi_wid; //write ID tag (supported only in AXI3) input [SDW-1:0] esaxi_wdata; //write data input [3:0] esaxi_wstrb; //write strobes input esaxi_wlast; //write last. Indicates last transfer in burst input esaxi_wvalid;//write valid //######################## // Write response channel //######################## // Master Port input [MIDW-1:0] emaxi_bid; //response ID tag input [1:0] emaxi_bresp; //write response input emaxi_bvalid;//write response valid // Slave Port input esaxi_bready;//response ready //######################## //# Read address channel //######################## // Master Port input emaxi_arready;//read address ready // Slave Port input [SIDW-1:0] esaxi_arid; //read address ID input [MAW-1:0] esaxi_araddr; //read address input [3:0] esaxi_arlen; //burst lenght (the number of data transfers) input [2:0] esaxi_arsize; //burst size (the size of each transfer) input [1:0] esaxi_arburst; //burst type input [1:0] esaxi_arlock; //lock type (atomic characteristics) input [3:0] esaxi_arcache; //memory type input [2:0] esaxi_arprot; //protection type input esaxi_arvalid; //write address valid //######################## //# Read data channel //######################## // Master Port input [MIDW-1:0] emaxi_rid; //read ID tag input [MDW-1:0] emaxi_rdata; //read data input [1:0] emaxi_rresp; //read response input emaxi_rlast; //read last, indicates last transfer in burst input emaxi_rvalid;//read valid // Slave Port input esaxi_rready; //read ready //########## //# Outputs //########## // global signals output csysack;//exit low-power state acknowledgement output cactive;//clock active output reset_chip; output reset_fpga; // LVDS FMC Port output [7:0] txo_data_p; output [7:0] txo_data_n; output txo_frame_p; output txo_frame_n; output txo_lclk_p; output txo_lclk_n; output rxo_wr_wait_p; output rxo_wr_wait_n; output rxo_rd_wait_p; output rxo_rd_wait_n; output rxi_cclk_p; output rxi_cclk_n; //######################## //# Write address channel //######################## // Master Port output [MIDW-1:0] emaxi_awid; //write address ID output [MAW-1:0] emaxi_awaddr; //write address output [3:0] emaxi_awlen; //burst length (number of data transfers) output [2:0] emaxi_awsize; //burst size (the size of each transfer) output [1:0] emaxi_awburst; //burst type output [1:0] emaxi_awlock; //lock type (atomic characteristics) output [3:0] emaxi_awcache; //memory type output [2:0] emaxi_awprot; //protection type output emaxi_awvalid; //write address valid // Slave Port output esaxi_awready; //write address ready //######################## //# Write data channel //######################## // Master Port output [MIDW-1:0] emaxi_wid; //write ID tag (supported only in AXI3) output [MDW-1:0] emaxi_wdata; //write data output [STW-1:0] emaxi_wstrb; //write strobes output emaxi_wlast; //write last, indicates last transfer in burst output emaxi_wvalid;//write valid // Slave Port output esaxi_wready;//write ready //######################## // Write response channel //######################## // Master Port output emaxi_bready;//response ready // Slave Port output [SIDW-1:0] esaxi_bid; //response ID tag output [1:0] esaxi_bresp; //write response output esaxi_bvalid;//write response valid //######################## //# Read address channel //######################## // Master Port output [MIDW-1:0] emaxi_arid; //read address ID output [MAW-1:0] emaxi_araddr; //read address output [3:0] emaxi_arlen; //burst lenght (number of data transfers) output [2:0] emaxi_arsize; //burst size (the size of each transfer) output [1:0] emaxi_arburst; //burst type output [1:0] emaxi_arlock; //lock type (atomic characteristics) output [3:0] emaxi_arcache; //memory type output [2:0] emaxi_arprot; //protection type output emaxi_arvalid; //write address valid // Slave Port output esaxi_arready; //read address ready //######################## //# Read data channel //######################## // Master Port output emaxi_rready; //read ready // Slave Port output [SIDW-1:0] esaxi_rid; //read ID tag (must match arid of transaction) output [SDW-1:0] esaxi_rdata; //read data output [1:0] esaxi_rresp; //read response output esaxi_rlast; //read last, indicates last transfer in burst output esaxi_rvalid;//read valid //####################################################################### //# The following features are not supported (AXI4 only) //# If un-commented, those signals have to be driven with default values //####################################################################### // input emaxi_buser; //user signal // input emaxi_ruser; //user signal output [3:0] emaxi_awqos; //quality of service default 4'b0000 // output [3:0] emaxi_awregion;//region identifier // output emaxi_awuser; //user signal // output emaxi_wuser; //user signal output [3:0] emaxi_arqos; //quality of service default 4'b0000 // output [3:0] emaxi_arregion;//region identifier // output emaxi_aruser; //user signal input [3:0] esaxi_awqos; //Quality of Service default 4'b0000 // input [3:0] awregion; //region identifier // input awuser; //user signal // input wuser; //user signal input [3:0] esaxi_arqos; //quality of service default 4'b0000 // input [3:0] arregion; //region identifier (AXI4 only) // input aruser; //user signal (AXI4 only) // output buser; //user signal (AXI4 only) // output ruser; //user signal (AXI4 only) /*AUTOINPUT*/ /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire elink_access_inb; // From ewrapper_link_top of ewrapper_link_top.v wire elink_access_outb; // From axi_elink_if of axi_elink_if.v wire elink_cclk_enb; // From axi_elink_if of axi_elink_if.v wire [1:0] elink_clk_div; // From axi_elink_if of axi_elink_if.v wire [3:0] elink_ctrlmode_inb; // From ewrapper_link_top of ewrapper_link_top.v wire [3:0] elink_ctrlmode_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] elink_data_inb; // From ewrapper_link_top of ewrapper_link_top.v wire [31:0] elink_data_outb; // From axi_elink_if of axi_elink_if.v wire [1:0] elink_datamode_inb; // From ewrapper_link_top of ewrapper_link_top.v wire [1:0] elink_datamode_outb; // From axi_elink_if of axi_elink_if.v wire elink_disable; // From axi_elink_if of axi_elink_if.v wire [31:0] elink_dstaddr_outb; // From axi_elink_if of axi_elink_if.v wire elink_rd_wait_inb; // From ewrapper_link_top of ewrapper_link_top.v wire elink_rd_wait_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] elink_srcaddr_inb; // From ewrapper_link_top of ewrapper_link_top.v wire [31:0] elink_srcaddr_outb; // From axi_elink_if of axi_elink_if.v wire elink_wr_wait_inb; // From ewrapper_link_top of ewrapper_link_top.v wire elink_wr_wait_outb; // From axi_elink_if of axi_elink_if.v wire elink_write_inb; // From ewrapper_link_top of ewrapper_link_top.v wire elink_write_outb; // From axi_elink_if of axi_elink_if.v wire emaxi_access_inb; // From axi_master of axi_master.v wire emaxi_access_outb; // From axi_elink_if of axi_elink_if.v wire [3:0] emaxi_ctrlmode_inb; // From axi_master of axi_master.v wire [3:0] emaxi_ctrlmode_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] emaxi_data_inb; // From axi_master of axi_master.v wire [31:0] emaxi_data_outb; // From axi_elink_if of axi_elink_if.v wire [1:0] emaxi_datamode_inb; // From axi_master of axi_master.v wire [1:0] emaxi_datamode_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] emaxi_dstaddr_inb; // From axi_master of axi_master.v wire [31:0] emaxi_dstaddr_outb; // From axi_elink_if of axi_elink_if.v wire emaxi_rd_wait_inb; // From axi_master of axi_master.v wire [31:0] emaxi_srcaddr_inb; // From axi_master of axi_master.v wire [31:0] emaxi_srcaddr_outb; // From axi_elink_if of axi_elink_if.v wire emaxi_wr_wait_inb; // From axi_master of axi_master.v wire emaxi_wr_wait_outb; // From axi_elink_if of axi_elink_if.v wire emaxi_write_inb; // From axi_master of axi_master.v wire emaxi_write_outb; // From axi_elink_if of axi_elink_if.v wire esaxi_access_inb; // From axi_slave of axi_slave.v wire esaxi_access_outb; // From axi_elink_if of axi_elink_if.v wire [3:0] esaxi_ctrlmode_inb; // From axi_slave of axi_slave.v wire [3:0] esaxi_ctrlmode_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] esaxi_data_inb; // From axi_slave of axi_slave.v wire [31:0] esaxi_data_outb; // From axi_elink_if of axi_elink_if.v wire [1:0] esaxi_datamode_inb; // From axi_slave of axi_slave.v wire [1:0] esaxi_datamode_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] esaxi_dstaddr_inb; // From axi_slave of axi_slave.v wire [31:0] esaxi_dstaddr_outb; // From axi_elink_if of axi_elink_if.v wire esaxi_rd_wait_inb; // From axi_slave of axi_slave.v wire esaxi_rd_wait_outb; // From axi_elink_if of axi_elink_if.v wire [31:0] esaxi_srcaddr_inb; // From axi_slave of axi_slave.v wire [31:0] esaxi_srcaddr_outb; // From axi_elink_if of axi_elink_if.v wire esaxi_wr_wait_inb; // From axi_slave of axi_slave.v wire esaxi_wr_wait_outb; // From axi_elink_if of axi_elink_if.v wire esaxi_write_inb; // From axi_slave of axi_slave.v wire esaxi_write_outb; // From axi_elink_if of axi_elink_if.v // End of automatics //######### //# Regs //######### //######### //# Wires //######### wire emaxi_reset; wire esaxi_reset; wire rxi_eclk; wire [31:0] elink_dstaddr_inb; wire [31:0] elink_dstaddr_tmp; wire ext_mem_access; //################# //# global signals //################# assign emaxi_reset = ~emaxi_aresetn; assign esaxi_reset = ~esaxi_aresetn; //################################## //# AXI Slave Port Instantiation //################################## /*axi_slave AUTO_TEMPLATE(.eclk (rxi_eclk), .reset (esaxi_reset), .aclk (esaxi_aclk), .aw\(.*\) (esaxi_aw\1[]), .w\(.*\) (esaxi_w\1[]), .b\(.*\) (esaxi_b\1[]), .ar\(.*\) (esaxi_ar\1[]), .r\(.*\) (esaxi_r\1[]), .emesh_\(.*\) (esaxi_\1[]), ); */ axi_slave axi_slave(/*AUTOINST*/ // Outputs .csysack (csysack), .cactive (cactive), .awready (esaxi_awready), // Templated .wready (esaxi_wready), // Templated .bid (esaxi_bid[SIDW-1:0]), // Templated .bresp (esaxi_bresp[1:0]), // Templated .bvalid (esaxi_bvalid), // Templated .arready (esaxi_arready), // Templated .rid (esaxi_rid[SIDW-1:0]), // Templated .rdata (esaxi_rdata[SDW-1:0]), // Templated .rresp (esaxi_rresp[1:0]), // Templated .rlast (esaxi_rlast), // Templated .rvalid (esaxi_rvalid), // Templated .emesh_access_inb(esaxi_access_inb), // Templated .emesh_write_inb (esaxi_write_inb), // Templated .emesh_datamode_inb(esaxi_datamode_inb[1:0]), // Templated .emesh_ctrlmode_inb(esaxi_ctrlmode_inb[3:0]), // Templated .emesh_dstaddr_inb(esaxi_dstaddr_inb[31:0]), // Templated .emesh_srcaddr_inb(esaxi_srcaddr_inb[31:0]), // Templated .emesh_data_inb (esaxi_data_inb[31:0]), // Templated .emesh_wr_wait_inb(esaxi_wr_wait_inb), // Templated .emesh_rd_wait_inb(esaxi_rd_wait_inb), // Templated // Inputs .aclk (esaxi_aclk), // Templated .eclk (rxi_eclk), // Templated .reset (esaxi_reset), // Templated .csysreq (csysreq), .awid (esaxi_awid[SIDW-1:0]), // Templated .awaddr (esaxi_awaddr[SAW-1:0]), // Templated .awlen (esaxi_awlen[3:0]), // Templated .awsize (esaxi_awsize[2:0]), // Templated .awburst (esaxi_awburst[1:0]), // Templated .awlock (esaxi_awlock[1:0]), // Templated .awcache (esaxi_awcache[3:0]), // Templated .awprot (esaxi_awprot[2:0]), // Templated .awvalid (esaxi_awvalid), // Templated .wid (esaxi_wid[SIDW-1:0]), // Templated .wdata (esaxi_wdata[SDW-1:0]), // Templated .wstrb (esaxi_wstrb[3:0]), // Templated .wlast (esaxi_wlast), // Templated .wvalid (esaxi_wvalid), // Templated .bready (esaxi_bready), // Templated .arid (esaxi_arid[SIDW-1:0]), // Templated .araddr (esaxi_araddr[SAW-1:0]), // Templated .arlen (esaxi_arlen[3:0]), // Templated .arsize (esaxi_arsize[2:0]), // Templated .arburst (esaxi_arburst[1:0]), // Templated .arlock (esaxi_arlock[1:0]), // Templated .arcache (esaxi_arcache[3:0]), // Templated .arprot (esaxi_arprot[2:0]), // Templated .arvalid (esaxi_arvalid), // Templated .rready (esaxi_rready), // Templated .emesh_access_outb(esaxi_access_outb), // Templated .emesh_write_outb(esaxi_write_outb), // Templated .emesh_datamode_outb(esaxi_datamode_outb[1:0]), // Templated .emesh_ctrlmode_outb(esaxi_ctrlmode_outb[3:0]), // Templated .emesh_dstaddr_outb(esaxi_dstaddr_outb[31:0]), // Templated .emesh_srcaddr_outb(esaxi_srcaddr_outb[31:0]), // Templated .emesh_data_outb (esaxi_data_outb[31:0]), // Templated .emesh_wr_wait_outb(esaxi_wr_wait_outb), // Templated .emesh_rd_wait_outb(esaxi_rd_wait_outb), // Templated .awqos (esaxi_awqos[3:0]), // Templated .arqos (esaxi_arqos[3:0])); // Templated //################################## //# AXI Master Port Instantiation //################################## /*axi_master AUTO_TEMPLATE(.eclk (rxi_eclk), .reset (emaxi_reset), .aclk (emaxi_aclk), .aw\(.*\) (emaxi_aw\1[]), .w\(.*\) (emaxi_w\1[]), .b\(.*\) (emaxi_b\1[]), .ar\(.*\) (emaxi_ar\1[]), .r\(.*\) (emaxi_r\1[]), .emesh_\(.*\) (emaxi_\1[]), ); */ axi_master axi_master(/*AUTOINST*/ // Outputs .awid (emaxi_awid[MIDW-1:0]), // Templated .awaddr (emaxi_awaddr[MAW-1:0]), // Templated .awlen (emaxi_awlen[3:0]), // Templated .awsize (emaxi_awsize[2:0]), // Templated .awburst (emaxi_awburst[1:0]), // Templated .awlock (emaxi_awlock[1:0]), // Templated .awcache (emaxi_awcache[3:0]), // Templated .awprot (emaxi_awprot[2:0]), // Templated .awvalid (emaxi_awvalid), // Templated .wid (emaxi_wid[MIDW-1:0]), // Templated .wdata (emaxi_wdata[MDW-1:0]), // Templated .wstrb (emaxi_wstrb[STW-1:0]), // Templated .wlast (emaxi_wlast), // Templated .wvalid (emaxi_wvalid), // Templated .bready (emaxi_bready), // Templated .arid (emaxi_arid[MIDW-1:0]), // Templated .araddr (emaxi_araddr[MAW-1:0]), // Templated .arlen (emaxi_arlen[3:0]), // Templated .arsize (emaxi_arsize[2:0]), // Templated .arburst (emaxi_arburst[1:0]), // Templated .arlock (emaxi_arlock[1:0]), // Templated .arcache (emaxi_arcache[3:0]), // Templated .arprot (emaxi_arprot[2:0]), // Templated .arvalid (emaxi_arvalid), // Templated .rready (emaxi_rready), // Templated .emesh_access_inb (emaxi_access_inb), // Templated .emesh_write_inb (emaxi_write_inb), // Templated .emesh_datamode_inb (emaxi_datamode_inb[1:0]), // Templated .emesh_ctrlmode_inb (emaxi_ctrlmode_inb[3:0]), // Templated .emesh_dstaddr_inb (emaxi_dstaddr_inb[31:0]), // Templated .emesh_srcaddr_inb (emaxi_srcaddr_inb[31:0]), // Templated .emesh_data_inb (emaxi_data_inb[31:0]), // Templated .emesh_wr_wait_inb (emaxi_wr_wait_inb), // Templated .emesh_rd_wait_inb (emaxi_rd_wait_inb), // Templated .awqos (emaxi_awqos[3:0]), // Templated .arqos (emaxi_arqos[3:0]), // Templated // Inputs .aclk (emaxi_aclk), // Templated .eclk (rxi_eclk), // Templated .reset (emaxi_reset), // Templated .awready (emaxi_awready), // Templated .wready (emaxi_wready), // Templated .bid (emaxi_bid[MIDW-1:0]), // Templated .bresp (emaxi_bresp[1:0]), // Templated .bvalid (emaxi_bvalid), // Templated .arready (emaxi_arready), // Templated .rid (emaxi_rid[MIDW-1:0]), // Templated .rdata (emaxi_rdata[MDW-1:0]), // Templated .rresp (emaxi_rresp[1:0]), // Templated .rlast (emaxi_rlast), // Templated .rvalid (emaxi_rvalid), // Templated .emesh_access_outb (emaxi_access_outb), // Templated .emesh_write_outb (emaxi_write_outb), // Templated .emesh_datamode_outb (emaxi_datamode_outb[1:0]), // Templated .emesh_ctrlmode_outb (emaxi_ctrlmode_outb[3:0]), // Templated .emesh_dstaddr_outb (emaxi_dstaddr_outb[31:0]), // Templated .emesh_srcaddr_outb (emaxi_srcaddr_outb[31:0]), // Templated .emesh_data_outb (emaxi_data_outb[31:0]), // Templated .emesh_wr_wait_outb (emaxi_wr_wait_outb)); // Templated //##################################### //# ELINK (CHIP Port) Instantiation //##################################### //# "manual remapping" of external memory address seen by the chips assign ext_mem_access = (elink_dstaddr_tmp[31:28] == `VIRT_EXT_MEM) & ~(elink_dstaddr_tmp[31:20] == `AXI_COORD); assign elink_dstaddr_inb[31:28] = ext_mem_access ? `PHYS_EXT_MEM : elink_dstaddr_tmp[31:28]; assign elink_dstaddr_inb[27:0] = elink_dstaddr_tmp[27:0]; /*ewrapper_link_top AUTO_TEMPLATE(.emesh_clk_inb (rxi_eclk), .burst_en (1'b1), .emesh_dstaddr_inb(elink_dstaddr_tmp[31:0]), .emesh_\(.*\) (elink_\1[]), ); */ ewrapper_link_top ewrapper_link_top (/*AUTOINST*/ // Outputs .emesh_clk_inb (rxi_eclk), // Templated .emesh_access_inb (elink_access_inb), // Templated .emesh_write_inb (elink_write_inb), // Templated .emesh_datamode_inb (elink_datamode_inb[1:0]), // Templated .emesh_ctrlmode_inb (elink_ctrlmode_inb[3:0]), // Templated .emesh_dstaddr_inb (elink_dstaddr_tmp[31:0]), // Templated .emesh_srcaddr_inb (elink_srcaddr_inb[31:0]), // Templated .emesh_data_inb (elink_data_inb[31:0]), // Templated .emesh_wr_wait_inb (elink_wr_wait_inb), // Templated .emesh_rd_wait_inb (elink_rd_wait_inb), // Templated .txo_data_p (txo_data_p[7:0]), .txo_data_n (txo_data_n[7:0]), .txo_frame_p (txo_frame_p), .txo_frame_n (txo_frame_n), .txo_lclk_p (txo_lclk_p), .txo_lclk_n (txo_lclk_n), .rxo_wr_wait_p (rxo_wr_wait_p), .rxo_wr_wait_n (rxo_wr_wait_n), .rxo_rd_wait_p (rxo_rd_wait_p), .rxo_rd_wait_n (rxo_rd_wait_n), .rxi_cclk_p (rxi_cclk_p), .rxi_cclk_n (rxi_cclk_n), // Inputs .reset (reset), .clkin_100 (clkin_100), .elink_disable (elink_disable), .elink_cclk_enb (elink_cclk_enb), .elink_clk_div (elink_clk_div[1:0]), .emesh_access_outb (elink_access_outb), // Templated .emesh_write_outb (elink_write_outb), // Templated .emesh_datamode_outb (elink_datamode_outb[1:0]), // Templated .emesh_ctrlmode_outb (elink_ctrlmode_outb[3:0]), // Templated .emesh_dstaddr_outb (elink_dstaddr_outb[31:0]), // Templated .emesh_srcaddr_outb (elink_srcaddr_outb[31:0]), // Templated .emesh_data_outb (elink_data_outb[31:0]), // Templated .emesh_wr_wait_outb (elink_wr_wait_outb), // Templated .emesh_rd_wait_outb (elink_rd_wait_outb), // Templated .rxi_data_p (rxi_data_p[7:0]), .rxi_data_n (rxi_data_n[7:0]), .rxi_frame_p (rxi_frame_p), .rxi_frame_n (rxi_frame_n), .rxi_lclk_p (rxi_lclk_p), .rxi_lclk_n (rxi_lclk_n), .txi_wr_wait_p (txi_wr_wait_p), .txi_wr_wait_n (txi_wr_wait_n), .txi_rd_wait_p (txi_rd_wait_p), .txi_rd_wait_n (txi_rd_wait_n), .burst_en (1'b1)); // Templated //#################################### //# AXI-ELINK Interface Instantiation //#################################### /*axi_elink_if AUTO_TEMPLATE(.eclk (rxi_eclk), .aclk (esaxi_aclk), ); */ axi_elink_if axi_elink_if (/*AUTOINST*/ // Outputs .reset_chip (reset_chip), .reset_fpga (reset_fpga), .emaxi_access_outb (emaxi_access_outb), .emaxi_write_outb (emaxi_write_outb), .emaxi_datamode_outb (emaxi_datamode_outb[1:0]), .emaxi_ctrlmode_outb (emaxi_ctrlmode_outb[3:0]), .emaxi_dstaddr_outb (emaxi_dstaddr_outb[31:0]), .emaxi_srcaddr_outb (emaxi_srcaddr_outb[31:0]), .emaxi_data_outb (emaxi_data_outb[31:0]), .emaxi_wr_wait_outb (emaxi_wr_wait_outb), .esaxi_access_outb (esaxi_access_outb), .esaxi_write_outb (esaxi_write_outb), .esaxi_datamode_outb (esaxi_datamode_outb[1:0]), .esaxi_ctrlmode_outb (esaxi_ctrlmode_outb[3:0]), .esaxi_dstaddr_outb (esaxi_dstaddr_outb[31:0]), .esaxi_srcaddr_outb (esaxi_srcaddr_outb[31:0]), .esaxi_data_outb (esaxi_data_outb[31:0]), .esaxi_wr_wait_outb (esaxi_wr_wait_outb), .esaxi_rd_wait_outb (esaxi_rd_wait_outb), .elink_access_outb (elink_access_outb), .elink_write_outb (elink_write_outb), .elink_datamode_outb (elink_datamode_outb[1:0]), .elink_ctrlmode_outb (elink_ctrlmode_outb[3:0]), .elink_dstaddr_outb (elink_dstaddr_outb[31:0]), .elink_srcaddr_outb (elink_srcaddr_outb[31:0]), .elink_data_outb (elink_data_outb[31:0]), .elink_wr_wait_outb (elink_wr_wait_outb), .elink_rd_wait_outb (elink_rd_wait_outb), .elink_disable (elink_disable), .elink_cclk_enb (elink_cclk_enb), .elink_clk_div (elink_clk_div[1:0]), // Inputs .eclk (rxi_eclk), // Templated .aclk (esaxi_aclk), // Templated .reset (reset), .emaxi_access_inb (emaxi_access_inb), .emaxi_write_inb (emaxi_write_inb), .emaxi_datamode_inb (emaxi_datamode_inb[1:0]), .emaxi_ctrlmode_inb (emaxi_ctrlmode_inb[3:0]), .emaxi_dstaddr_inb (emaxi_dstaddr_inb[31:0]), .emaxi_srcaddr_inb (emaxi_srcaddr_inb[31:0]), .emaxi_data_inb (emaxi_data_inb[31:0]), .emaxi_wr_wait_inb (emaxi_wr_wait_inb), .emaxi_rd_wait_inb (emaxi_rd_wait_inb), .esaxi_access_inb (esaxi_access_inb), .esaxi_write_inb (esaxi_write_inb), .esaxi_datamode_inb (esaxi_datamode_inb[1:0]), .esaxi_ctrlmode_inb (esaxi_ctrlmode_inb[3:0]), .esaxi_dstaddr_inb (esaxi_dstaddr_inb[31:0]), .esaxi_srcaddr_inb (esaxi_srcaddr_inb[31:0]), .esaxi_data_inb (esaxi_data_inb[31:0]), .esaxi_wr_wait_inb (esaxi_wr_wait_inb), .esaxi_rd_wait_inb (esaxi_rd_wait_inb), .elink_access_inb (elink_access_inb), .elink_write_inb (elink_write_inb), .elink_datamode_inb (elink_datamode_inb[1:0]), .elink_ctrlmode_inb (elink_ctrlmode_inb[3:0]), .elink_dstaddr_inb (elink_dstaddr_inb[31:0]), .elink_srcaddr_inb (elink_srcaddr_inb[31:0]), .elink_data_inb (elink_data_inb[31:0]), .elink_wr_wait_inb (elink_wr_wait_inb), .elink_rd_wait_inb (elink_rd_wait_inb)); endmodule // parallella // Local Variables: // verilog-library-directories:("." "../elink" "../axi") // End: ================================================ FILE: contrib/parallella/testmain.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include int main(int argc, const char **argv) { printf( "Hello world\n"); } ================================================ FILE: contrib/perf/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = PerfRequest PerfIndication BSVFILES = Perf.bsv Top.bsv $(CONNECTALDIR)/lib/deprecated/DmaUtils.bsv CPPFILES=testperf.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/perf/Perf.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFOF::*; import GetPut::*; import ConnectalMemory::*; import ConnectalMemTypes::*; interface PerfRequest; method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords, Bit#(32) repeatCount); method Action readWord(); method Action getStateDbg(); endinterface interface PerfIndication; method Action started(Bit#(32) numWords); method Action readWordResult(Bit#(32) v); method Action done(Bit#(32) dataMismatch); method Action rData(Bit#(64) v); method Action readReq(Bit#(32) v); method Action writeReq(Bit#(32) v); method Action writeAck(Bit#(32) v); method Action reportStateDbg(Bit#(32) srcGen, Bit#(32) streamRdCnt, Bit#(32) streamWrCnt, Bit#(32) writeInProg, Bit#(32) dataMismatch); endinterface module mkPerfRequest#(PerfIndication indication, MemReadServer#(busWidth) dma_stream_read_server, MemWriteServer#(busWidth) dma_stream_write_server, MemReadServer#(busWidth) dma_word_read_server) (PerfRequest) provisos (Div#(busWidth,8,busWidthBytes), Add#(a__,32,busWidth)); let busWidthBytes = valueOf(busWidthBytes); let busWidthWords = busWidthBytes/4; Reg#(Bit#(32)) srcGen <- mkReg(0); Reg#(Bit#(32)) byteCnt <- mkReg(0); Reg#(Bit#(32)) streamRdCnt <- mkReg(0); Reg#(Bit#(32)) streamWrCnt <- mkReg(0); Reg#(Bit#(32)) streamAckCnt <- mkReg(0); Reg#(Bit#(32)) repeatCnt <- mkReg(0); Reg#(Bit#(MemOffsetSize)) streamRdOff <- mkReg(0); Reg#(Bit#(MemOffsetSize)) streamWrOff <- mkReg(0); Reg#(SGLId) streamRdPointer <- mkReg(0); Reg#(SGLId) streamWrPointer <- mkReg(0); Reg#(Bool) writeInProg <- mkReg(False); Reg#(Bool) iterInProg <- mkReg(False); Reg#(Bool) dataMismatch <- mkReg(False); Reg#(Bit#(8)) burstLen <- mkReg(8*fromInteger(busWidthBytes)); Reg#(Bit#(MemOffsetSize)) deltaOffset <- mkReg(8*fromInteger(busWidthBytes)); rule readReq(streamRdCnt > 0); streamRdCnt <= streamRdCnt - extend(burstLen); streamRdOff <= streamRdOff + deltaOffset; //$display("readReq.put pointer=%h address=%h, burstlen=%h", streamRdPointer, streamRdOff, burstLen); dma_stream_read_server.readReq.put(MemRequest {sglId: streamRdPointer, offset: streamRdOff, burstLen: extend(burstLen), tag: truncate(streamRdOff>>5)}); //indication.readReq(streamRdCnt); endrule rule writeReq(streamWrCnt > 0 && !writeInProg); writeInProg <= True; streamWrCnt <= streamWrCnt-extend(burstLen); streamWrOff <= streamWrOff + deltaOffset; //$display("writeReq.put pointer=%h address=%h", streamWrPointer, streamWrOff); dma_stream_write_server.writeReq.put(MemRequest {sglId: streamWrPointer, offset: streamWrOff, burstLen: extend(burstLen), tag: truncate(streamWrOff>>5)}); //indication.writeReq(streamWrCnt); endrule rule writeAck(writeInProg); writeInProg <= False; let tag <- dma_stream_write_server.writeDone.get(); //$display("writeAck: tag=%d", tag); streamAckCnt <= streamAckCnt-extend(burstLen); //indication.writeAck(streamAckCnt); if(streamAckCnt==extend(burstLen)) begin if (repeatCnt == 0) indication.done(0); iterInProg <= False; end endrule rule loopback; let tagdata <- dma_stream_read_server.readData.get(); let v = tagdata.data; Bool mismatch = False; //for (Integer i = 0; i < busWidthWords; i = i+1) // mismatch = mismatch || (v[31+i*32:i*32] != (srcGen + fromInteger(i))); //dataMismatch <= dataMismatch || mismatch; dma_stream_write_server.writeData.put(tagdata); srcGen <= srcGen+fromInteger(busWidthWords); //$display("loopback %h", tagdata.data); // indication.rData(v); endrule rule readWordResp; let tagdata <- dma_word_read_server.readData.get; indication.readWordResult(truncate(tagdata.data)); endrule rule startIteration((iterInProg == False) && (repeatCnt > 0)); streamRdOff <= 0; streamWrOff <= 0; streamRdCnt <= byteCnt; streamWrCnt <= byteCnt; streamAckCnt <= byteCnt; iterInProg <= True; repeatCnt <= repeatCnt - 1; endrule method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords, Bit#(32) repeatCount) if (streamRdCnt == 0 && streamWrCnt == 0); //$display("startCopy wrPointer=%h rdPointer=%h numWords=%d", wrPointer, rdPointer, numWords); streamWrPointer <= wrPointer; streamRdPointer <= rdPointer; byteCnt <= numWords << 2; repeatCnt <= repeatCount; indication.started(numWords); endmethod method Action readWord(); dma_word_read_server.readReq.put(MemRequest {sglId: streamWrPointer, offset: 0, burstLen: fromInteger(busWidthBytes), tag: 1}); endmethod method Action getStateDbg(); indication.reportStateDbg(srcGen, streamRdCnt, streamWrCnt, writeInProg ? 32'd1 : 32'd0, dataMismatch ? 32'd1 : 32'd0); endmethod endmodule ================================================ FILE: contrib/perf/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import ConnectalMemory::*; import DmaUtils::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import PerfRequest::*; import MemServerRequest::*; import MMURequest::*; import PerfIndication::*; import MemServerIndication::*; import MMUIndication::*; import Perf::*; typedef enum {IfcNames_PerfIndication, IfcNames_PerfRequest, IfcNames_HostMemServerIndication, IfcNames_HostMemServerRequest, IfcNames_HostMMURequest, IfcNames_HostMMUIndication} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalDmaTop#(PhysAddrWidth)); DmaReadBuffer#(64,8) dma_stream_read_chan <- mkDmaReadBuffer(); DmaWriteBuffer#(64,8) dma_stream_write_chan <- mkDmaWriteBuffer(); DmaReadBuffer#(64,8) dma_word_read_chan <- mkDmaReadBuffer(); DmaWriteBuffer#(64,8) dma_debug_write_chan <- mkDmaWriteBuffer(); Vector#(2, MemReadClient#(64)) readClients = newVector(); readClients[0] = dma_stream_read_chan.dmaClient; readClients[1] = dma_word_read_chan.dmaClient; Vector#(2, MemWriteClient#(64)) writeClients = newVector(); writeClients[0] = dma_stream_write_chan.dmaClient; writeClients[1] = dma_debug_write_chan.dmaClient; MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_HostMMUIndication); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_HostMMURequest, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_HostMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(readClients, writeClients, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_HostMemServerRequest, dma.request); PerfIndicationProxy perfIndicationProxy <- mkPerfIndicationProxy(IfcNames_PerfIndication); PerfRequest perfRequest <- mkPerfRequest(perfIndicationProxy.ifc, dma_stream_read_chan.dmaServer, dma_stream_write_chan.dmaServer, dma_word_read_chan.dmaServer); PerfRequestWrapper perfRequestWrapper <- mkPerfRequestWrapper(IfcNames_PerfRequest,perfRequest); Vector#(6,StdPortal) portals; portals[0] = perfRequestWrapper.portalIfc; portals[1] = perfIndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = hostMemServerIndicationProxy.portalIfc; portals[4] = hostMMURequestWrapper.portalIfc; portals[5] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: contrib/perf/testperf.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "dmaManager.h" #include "PerfIndication.h" #include "PerfRequest.h" sem_t copy_sem; PerfRequestProxy *device = 0; MMURequestProxy *dmap = 0; int srcAlloc; int dstAlloc; unsigned int *srcBuffer = 0; unsigned int *dstBuffer = 0; int numWords; size_t test_sz = (1 << 20) *sizeof(unsigned int); size_t alloc_sz = test_sz; unsigned int finishedCount; unsigned int ref_srcAlloc; unsigned int ref_dstAlloc; bool memcmp_fail = false; unsigned int memcmp_count = 0; unsigned int start_count = 0; unsigned int copy_size = 0; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (int i = 0; i < len ; i++) { fprintf(stderr, "%02x", (unsigned char)buf[i]); if (i % 32 == 31) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } class PerfIndication : public PerfIndicationWrapper { public: PerfIndication(unsigned int id) : PerfIndicationWrapper(id){} virtual void started(uint32_t words){ // fprintf(stderr, "started: words=%ld\n", words); start_count += 1; if (copy_size == 0) sem_post(©_sem); } virtual void readWordResult ( uint32_t v ){ dump("readWordResult: ", (char*)&v, sizeof(v)); } virtual void done(uint32_t v) { finishedCount += 1; sem_post(©_sem); } virtual void rData ( uint64_t v ){ dump("rData: ", (char*)&v, sizeof(v)); } virtual void readReq(uint32_t v){ //fprintf(stderr, "readReq %lx\n", v); } virtual void writeReq(uint32_t v){ //fprintf(stderr, "writeReq %lx\n", v); } virtual void writeAck(uint32_t v){ //fprintf(stderr, "writeAck %lx\n", v); } virtual void reportStateDbg(uint32_t srcGen, uint32_t streamRdCnt, uint32_t streamWrCnt, uint32_t writeInProg, uint32_t dataMismatch){ fprintf(stderr, "Perf::reportStateDbg: srcGen=%d, streamRdCnt=%d, streamWrCnt=%d, writeInProg=%d, dataMismatch=%d\n", srcGen, streamRdCnt, streamWrCnt, writeInProg, dataMismatch); } }; PerfIndication *deviceIndication = 0; // we can use the data synchronization barrier instead of flushing the // cache only because the ps7 is configured to run in buffered-write mode // // an opc2 of '4' and CRm of 'c10' encodes "CP15DSB, Data Synchronization Barrier // operation". this is a legal instruction to execute in non-privileged mode (mdk) // // #define DATA_SYNC_BARRIER __asm __volatile( "MCR p15, 0, %0, c7, c10, 4" :: "r" (0) ); long long deltatime( struct timeval start, struct timeval stop) { long long diff = ((long long) (stop.tv_sec - start.tv_sec)) * 1000000; diff = diff + ((long long) (stop.tv_usec - start.tv_usec)); return (diff); } int dotest(unsigned size, unsigned repeatCount) { struct timeval start, stop; unsigned loops = 1; unsigned int i; long long interval; fprintf(stderr, "repeat %d size %d loop ", repeatCount, size); for(;;) { finishedCount = 0; copy_size = size; fprintf(stderr, " %d", loops); gettimeofday(&start, NULL); for (i = 0; i < loops; i += 1) { device->startCopy(ref_dstAlloc, ref_srcAlloc, numWords, repeatCount); sem_wait(©_sem); } gettimeofday(&stop, NULL); interval = deltatime(start, stop); if (interval >= 500000) break; loops <<= 1; } fprintf(stderr, "\n block size %d microseconds %lld\n", size*16, interval / loops); } int main(int argc, const char **argv) { unsigned int srcGen = 0; unsigned repeatCount = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); DmaManager *dma = platformInit(); device = new PerfRequestProxy(IfcNames_PerfRequest); deviceIndication = new PerfIndication(IfcNames_PerfIndication); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); dstAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); ref_srcAlloc = dma->reference(srcAlloc); ref_dstAlloc = dma->reference(dstAlloc); fprintf(stderr, "ref_srcAlloc %d\n", ref_srcAlloc); fprintf(stderr, "ref_dstAlloc %d\n", ref_dstAlloc); //fprintf(stderr, "Main::starting mempcy numWords:%d\n", 0); //dotest(0); for (repeatCount = 1; repeatCount <= 16; repeatCount <<= 1) { fprintf(stderr, "Main::starting mempcy repeatCount:%d\n", repeatCount); for (numWords = 16; numWords < (1 << 16); numWords <<= 1){ //fprintf(stderr, "Main::starting mempcy numWords:%d\n", numWords); dotest(numWords, repeatCount); } } device->getStateDbg(); fprintf(stderr, "Main::exiting\n"); } ================================================ FILE: contrib/pipe_mul/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = PipeMulRequest PipeMulIndication BSVFILES = PipeMulTB.bsv Top.bsv CPPFILES=testpipe_mul.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/pipe_mul/PipeMulTB.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import PipeMul::*; interface PipeMulIndication; method Action res(Bit#(32) v); endinterface interface PipeMulRequest; method Action mul(Bit#(32) x, Bit#(32) y); endinterface interface PipeMulTB; interface PipeMulRequest ifc; endinterface module mkPipeMulTB#(PipeMulIndication indication)(PipeMulTB); PipeMul#(1,16,void) multiplier <- mkPipeMul; rule res; match {.rv, .*} <- multiplier.get; indication.res(pack(extend(rv))); endrule interface PipeMulRequest ifc; method Action mul(Bit#(32) a, Bit#(32) b); multiplier.put(unpack(truncate(a)),unpack(truncate(b)),?); endmethod endinterface endmodule ================================================ FILE: contrib/pipe_mul/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import PipeMulIndication::*; import PipeMulRequest::*; import PipeMulTB::*; typedef enum {IfcNames_PipeMulIndication, IfcNames_PipeMulRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); PipeMulIndicationProxy indProxy <- mkPipeMulIndicationProxy(IfcNames_PipeMulIndication); PipeMulTB pmTB <- mkPipeMulTB(indProxy.ifc); PipeMulRequestWrapper reqWrapper <- mkPipeMulRequestWrapper(IfcNames_PipeMulRequest,pmTB.ifc); Vector#(2,StdPortal) portals; portals[0] = indProxy.portalIfc; portals[1] = reqWrapper.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/pipe_mul/testpipe_mul.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "PipeMulIndication.h" #include "PipeMulRequest.h" #include "GeneratedTypes.h" class PipeMulIndication : public PipeMulIndicationWrapper { public: virtual void res(uint32_t v) { fprintf(stderr, "res: %d\n", v); exit(0); } PipeMulIndication(unsigned int id) : PipeMulIndicationWrapper(id) {} }; int main(int argc, const char **argv) { PipeMulIndication *indication = new PipeMulIndication(IfcNames_PipeMulIndication); PipeMulRequestProxy *device = new PipeMulRequestProxy(IfcNames_PipeMulRequest); device->mul(3,4); while(true); } ================================================ FILE: contrib/pipe_mul2/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = PipeMulRequest PipeMulIndication BSVFILES = PipeMulTB.bsv Top.bsv CPPFILES=testpipe_mul.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/pipe_mul2/PipeMulTB.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import PipeMul::*; interface PipeMulIndication; method Action res(Bit#(64) v); endinterface interface PipeMulRequest; method Action mul(Bit#(32) x, Bit#(32) y); endinterface interface PipeMulTB; interface PipeMulRequest ifc; endinterface (* synthesize *) module mkPipeMul2Synth(PipeMul2#(2,24,void)); let pm <- mkPipeMul2(); return pm; endmodule module mkPipeMulTB#(PipeMulIndication indication)(PipeMulTB); PipeMul2#(2,24,void) multiplier <- mkPipeMul2Synth; rule res; match {.rv, .*} <- multiplier.get; indication.res(extend(pack(rv))); endrule interface PipeMulRequest ifc; method Action mul(Bit#(32) a, Bit#(32) b); multiplier.put(unpack(truncate(a)),unpack(truncate(b)),?); endmethod endinterface endmodule ================================================ FILE: contrib/pipe_mul2/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import PipeMulIndication::*; import PipeMulRequest::*; import PipeMulTB::*; typedef enum {IfcNames_PipeMulIndication, IfcNames_PipeMulRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); PipeMulIndicationProxy indProxy <- mkPipeMulIndicationProxy(IfcNames_PipeMulIndication); PipeMulTB pmTB <- mkPipeMulTB(indProxy.ifc); PipeMulRequestWrapper reqWrapper <- mkPipeMulRequestWrapper(IfcNames_PipeMulRequest,pmTB.ifc); Vector#(2,StdPortal) portals; portals[0] = indProxy.portalIfc; portals[1] = reqWrapper.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/pipe_mul2/testpipe_mul.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "PipeMulIndication.h" #include "PipeMulRequest.h" #include "GeneratedTypes.h" class PipeMulIndication : public PipeMulIndicationWrapper { public: virtual void res(uint64_t v) { fprintf(stderr, "res: %lld\n", (long long)v); exit(0); } PipeMulIndication(unsigned int id) : PipeMulIndicationWrapper(id) {} }; int main(int argc, const char **argv) { PipeMulIndication *indication = new PipeMulIndication(IfcNames_PipeMulIndication); PipeMulRequestProxy *device = new PipeMulRequestProxy(IfcNames_PipeMulRequest); device->mul(3,4); while(true); } ================================================ FILE: contrib/portalperf/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = PortalPerfRequest PortalPerfIndication BSVFILES = Repeat.bsv PortalPerf.bsv Top.bsv CPPFILES=testportalperf.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/portalperf/PortalPerf.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Repeat::*; import Vector::*; interface PortalPerfRequest; method Action swallow(); method Action swallowl(Bit#(32) v1); method Action swallowll(Bit#(32) v1, Bit#(32) v2); method Action swallowlll(Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); method Action swallowllll(Bit#(32) v1, Bit#(32) v2, Bit#(32) v3, Bit#(32) v4); method Action swallowd(Bit#(64) v1); method Action swallowdd(Bit#(64) v1, Bit#(64) v2); method Action swallowddd(Bit#(64) v1, Bit#(64) v2, Bit#(64) v3); method Action swallowdddd(Bit#(64) v1, Bit#(64) v2, Bit#(64) v3, Bit#(64) v4); method Action startspit(Bit#(16) spitType, Bit#(16) loops); endinterface interface PortalPerfIndication; method Action spit(); method Action spitl(Bit#(32) v1); method Action spitll(Bit#(32) v1, Bit#(32) v2); method Action spitlll(Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); method Action spitllll(Bit#(32) v1, Bit#(32) v2, Bit#(32) v3, Bit#(32) v4); method Action spitd(Bit#(64) v1); method Action spitdd(Bit#(64) v1, Bit#(64) v2); method Action spitddd(Bit#(64) v1, Bit#(64) v2, Bit#(64) v3); method Action spitdddd(Bit#(64) v1, Bit#(64) v2, Bit#(64) v3, Bit#(64) v4); endinterface module mkPortalPerfRequest#(PortalPerfIndication indication) (PortalPerfRequest); Reg#(Bit#(32)) sinkl1 <- mkReg(0); Reg#(Bit#(32)) sinkll1 <- mkReg(0); Reg#(Bit#(32)) sinkll2 <- mkReg(0); Reg#(Bit#(32)) sinklll1 <- mkReg(0); Reg#(Bit#(32)) sinklll2 <- mkReg(0); Reg#(Bit#(32)) sinklll3 <- mkReg(0); Reg#(Bit#(32)) sinkllll1 <- mkReg(0); Reg#(Bit#(32)) sinkllll2 <- mkReg(0); Reg#(Bit#(32)) sinkllll3 <- mkReg(0); Reg#(Bit#(32)) sinkllll4 <- mkReg(0); Reg#(Bit#(64)) sinkd1 <- mkReg(0); Reg#(Bit#(64)) sinkdd1 <- mkReg(0); Reg#(Bit#(64)) sinkdd2 <- mkReg(0); Reg#(Bit#(64)) sinkddd1 <- mkReg(0); Reg#(Bit#(64)) sinkddd2 <- mkReg(0); Reg#(Bit#(64)) sinkddd3 <- mkReg(0); Reg#(Bit#(64)) sinkdddd1 <- mkReg(0); Reg#(Bit#(64)) sinkdddd2 <- mkReg(0); Reg#(Bit#(64)) sinkdddd3 <- mkReg(0); Reg#(Bit#(64)) sinkdddd4 <- mkReg(0); function Action dospit(); return action indication.spit(); endaction ; endfunction function Action dospitl(); return ( action indication.spitl(sinkl1); endaction ); endfunction function Action dospitll(); return ( action indication.spitll(sinkll1, sinkll2); endaction ); endfunction function Action dospitlll(); return ( action indication.spitlll(sinklll1, sinklll2, sinklll3); endaction ); endfunction function Action dospitllll(); return ( action indication.spitllll(sinkllll1, sinkllll2, sinkllll3, sinkllll4); endaction ); endfunction function Action dospitd(); return ( action indication.spitd(sinkd1); endaction ); endfunction function Action dospitdd(); return ( action indication.spitdd(sinkdd1, sinkdd2); endaction ); endfunction function Action dospitddd(); return ( action indication.spitddd(sinkddd1, sinkddd2, sinkddd3); endaction ); endfunction function Action dospitdddd(); return ( action indication.spitdddd(sinkdddd1, sinkdddd2, sinkdddd3, sinkdddd4); endaction ); endfunction Vector#(9, Repeat) rfns = ?; rfns[0] <- mkRepeat(dospit); rfns[1] <- mkRepeat(dospitl); rfns[2] <- mkRepeat(dospitll); rfns[3] <- mkRepeat(dospitlll); rfns[4] <- mkRepeat(dospitllll); rfns[5] <- mkRepeat(dospitd); rfns[6] <- mkRepeat(dospitdd); rfns[7] <- mkRepeat(dospitddd); rfns[8] <- mkRepeat(dospitdddd); method Action swallowl(Bit#(32) v1); sinkl1 <= v1; endmethod method Action swallow(); endmethod method Action swallowll(Bit#(32) v1, Bit#(32) v2); sinkll1 <= v1; sinkll2 <= v2; endmethod method Action swallowlll(Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); sinklll1 <= v1; sinklll2 <= v2; sinklll3 <= v3; endmethod method Action swallowllll(Bit#(32) v1, Bit#(32) v2, Bit#(32) v3, Bit#(32) v4); sinkllll1 <= v1; sinkllll2 <= v2; sinkllll3 <= v3; sinkllll4 <= v4; endmethod method Action swallowd(Bit#(64) v1); sinkd1 <= v1; endmethod method Action swallowdd(Bit#(64) v1, Bit#(64) v2); sinkdd1 <= v1; sinkdd2 <= v2; endmethod method Action swallowddd(Bit#(64) v1, Bit#(64) v2, Bit#(64) v3); sinkddd1 <= v1; sinkddd2 <= v2; sinkddd3 <= v3; endmethod method Action swallowdddd(Bit#(64) v1, Bit#(64) v2, Bit#(64) v3, Bit#(64) v4 ); sinkdddd1 <= v1; sinkdddd2 <= v2; sinkdddd3 <= v3; sinkdddd4 <= v4; endmethod method Action startspit(Bit#(16) spitType, Bit#(16) loops); rfns[spitType].start(loops); endmethod endmodule ================================================ FILE: contrib/portalperf/Repeat.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface Repeat; method Action start(Bit#(16) loops); endinterface module mkRepeat#(function Action tocall)(Repeat); Reg#(Bit#(16)) loopcount <- mkReg(0); rule doonce (loopcount > 0); tocall(); loopcount <= loopcount - 1; endrule method Action start(Bit#(16) loops); loopcount <= loops; endmethod endmodule ================================================ FILE: contrib/portalperf/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import HostInterface::*; import CtrlMux::*; import PortalPerfIndication::*; import PortalPerfRequest::*; import PortalPerf::*; typedef enum {IfcNames_PortalPerfIndication, IfcNames_PortalPerfRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); PortalPerfIndicationProxy portalPerfIndicationProxy <- mkPortalPerfIndicationProxy(IfcNames_PortalPerfIndication); PortalPerfRequest portalPerfRequest <- mkPortalPerfRequest(portalPerfIndicationProxy.ifc); PortalPerfRequestWrapper portalPerfRequestWrapper <- mkPortalPerfRequestWrapper(IfcNames_PortalPerfRequest, portalPerfRequest); Vector#(2,StdPortal) portals; portals[0] = portalPerfIndicationProxy.portalIfc; portals[1] = portalPerfRequestWrapper.portalIfc; let ctrl_mux <- mkSlaveMuxDbg(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: contrib/portalperf/testportalperf.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include "PortalPerfIndication.h" #include "PortalPerfRequest.h" //#define DEBUG 1 #ifdef DEBUG #define DEBUGWHERE() \ fprintf(stderr, "at %s, %s:%d\n", __FUNCTION__, __FILE__, __LINE__) #else #define DEBUGWHERE() #endif #define LOOP_COUNT 10000 PortalPerfRequestProxy *portalPerfRequestProxy = 0; int heard_count; static void *wait_for(int n) { void *rc = NULL; while ((heard_count != n) && !rc) { rc = defaultPoller->pollFn(0); if ((long)rc >= 0) rc = defaultPoller->event(); } return rc; } uint32_t vrl1, vrl2, vrl3, vrl4; uint64_t vrd1, vrd2, vrd3, vrd4; class PortalPerfIndication : public PortalPerfIndicationWrapper { public: virtual void spit() { DEBUGWHERE(); heard_count++; } virtual void spitl(uint32_t v1) { DEBUGWHERE(); heard_count++; vrl1 = v1; } virtual void spitll(uint32_t v1, uint32_t v2) { DEBUGWHERE(); heard_count++; vrl1 = v1; vrl2 = v2; } virtual void spitlll(uint32_t v1, uint32_t v2, uint32_t v3) { DEBUGWHERE(); heard_count++; vrl1 = v1; vrl2 = v2; vrl3 = v3; } virtual void spitllll(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t v4) { DEBUGWHERE(); heard_count++; vrl1 = v1; vrl2 = v2; vrl3 = v3; vrl4 = v4; } virtual void spitd(uint64_t v1) { DEBUGWHERE(); heard_count++; vrd1 = v1; } virtual void spitdd(uint64_t v1, uint64_t v2) { DEBUGWHERE(); heard_count++; vrd1 = v1; vrd2 = v2; } virtual void spitddd(uint64_t v1, uint64_t v2, uint64_t v3) { DEBUGWHERE(); heard_count++; vrd1 = v1; vrd2 = v2; vrd3 = v3; } virtual void spitdddd(uint64_t v1, uint64_t v2, uint64_t v3, uint64_t v4) { DEBUGWHERE(); heard_count++; vrd1 = v1; vrd2 = v2; vrd3 = v3; vrd4 = v4; } PortalPerfIndication(unsigned int id) : PortalPerfIndicationWrapper(id) {} }; uint32_t vl1, vl2, vl3, vl4; uint64_t vd1, vd2, vd3, vd4; void call_swallow(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallow(); portalTimerCatch(19); } void call_swallowl(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowl(vl1); portalTimerCatch(19); } void call_swallowll(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowll(vl1, vl2); portalTimerCatch(19); } void call_swallowlll(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowlll(vl1, vl2, vl3); portalTimerCatch(19); } void call_swallowllll(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowllll(vl1, vl2, vl3, vl4); portalTimerCatch(19); } void call_swallowd(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowd(vd1); portalTimerCatch(19); } void call_swallowdd(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowdd(vd1, vd2); portalTimerCatch(19); } void call_swallowddd(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowddd(vd1, vd2, vd3); portalTimerCatch(19); } void call_swallowdddd(void) { DEBUGWHERE(); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->swallowdddd(vd1, vd2, vd3, vd4); portalTimerCatch(19); } void dotestout(const char *testname, void (*testfn)(void)) { uint64_t elapsed; portalTimerInit(); portalTimerStart(1); for (int i = 0; i < LOOP_COUNT; i++) { testfn(); } elapsed = portalTimerLap(1); printf("test %s: elapsed %g average %g\n", testname, (double) elapsed, (double) elapsed/ (double) LOOP_COUNT); portalTimerPrint(LOOP_COUNT); } void dotestin(const char *testname, int which) { uint64_t elapsed; heard_count = 0; printf("starting test %s, which %d\n", testname, which); portalTimerInit(); portalTimerStart(1); portalTimerStart(0); portalTimerCatch(0); portalPerfRequestProxy->startspit(which, LOOP_COUNT); portalTimerCatch(19); wait_for(LOOP_COUNT); portalTimerCatch(21); elapsed = portalTimerLap(1); printf("test %s: heard %d elapsed %g average %g\n", testname, heard_count, (double) elapsed, (double) elapsed/ (double) LOOP_COUNT); portalTimerPrint(1); } int main(int argc, const char **argv) { PortalPerfIndication *portalPerfIndication = new PortalPerfIndication(IfcNames_PortalPerfIndication); portalPerfRequestProxy = new PortalPerfRequestProxy(IfcNames_PortalPerfRequest); printf("Timer tests\n"); portalTimerInit(); for (int i = 0; i < 1000; i++) { portalTimerStart(0); portalTimerCatch(1); portalTimerCatch(2); portalTimerCatch(3); portalTimerCatch(4); portalTimerCatch(5); portalTimerCatch(6); portalTimerCatch(7); portalTimerCatch(8); } printf("Each line 1-8 is one more call to portalTimerCatch()\n"); portalTimerPrint(1000); vl1 = 0xfeed000000000011; vl2 = 0xface000000000012; vl3 = 0xdead000000000013; vl4 = 0xbeef000000000014; vd1 = 0xfeed0000000000000021LL; vd2 = 0xface0000000000000022LL; vd3 = 0xdead0000000000000023LL; vd4 = 0xbeef0000000000000024LL; dotestout("swallow", call_swallow); dotestout("swallowl", call_swallowl); dotestout("swallowll", call_swallowll); dotestout("swallowlll", call_swallowlll); dotestout("swallowllll", call_swallowllll); dotestout("swallowd", call_swallowd); dotestout("swallowdd", call_swallowdd); dotestout("swallowddd", call_swallowddd); dotestout("swallowdddd", call_swallowdddd); dotestin("spitl", 1); dotestin("spit", 0); dotestin("spitll", 2); dotestin("spitlll", 3); dotestin("spitllll", 4); dotestin("spitd", 5); dotestin("spitdd", 6); dotestin("spitddd", 7); dotestin("spitdddd", 8); return 0; } ================================================ FILE: contrib/ptest/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = PTestRequest PTestIndication BSVFILES = PTest.bsv include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/ptest/PTest.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ typedef struct { Bit#(16) a; Bit#(16) b; } Rec; typedef Bit#(16) Signal; interface PTestRequest; method Action func2(Rec data); method Action func1(Signal data); endinterface interface PTestIndication; method Action func3(Signal data); endinterface ================================================ FILE: contrib/ptest/PTest.bsv.bad ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ typedef struct { Bit#(16) a; Bit#(16) b; } Rec; typedef Bit#(16) Signal; interface PTestRequest; method Action func2(Rec data); method Action func1(Signal data); endinterface interface PTestIndication; method Action func3(Signal data); endinterface ================================================ FILE: contrib/ptest/PTest.bsv.good ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ typedef Bit#(16) Signal; interface PTestRequest; method Action func1(Bit#(16) data); endinterface interface PTestIndication; method Action fun2(Bit#(16) data); endinterface ================================================ FILE: contrib/serialconfig/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = SerialconfigRequest:Serialconfig.request H2S_INTERFACES = Serialconfig:SerialconfigIndication BSVFILES = Serialconfig.bsv CPPFILES=testserialconfig.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/serialconfig/Readme.md ================================================ # Serial Configuration Register L. Stewart, Quanta Research Cambridge, stewart@qrclab.com In many designs, there is a need for configuration control registers that do not have high bandwidth requirements. They are used to configure a piece of hardware, to contain near constants, etc. There is also a need to read the contents of registers in the design. The straightforward way to specify configuration registers using portals leads to wide parallel busses to each register. Serial Configuration Registers are intended to solve these problems. The example defines two modules, an SpiReg and an SpiRoot. An SpiReg creates a Register for a user defined type, and also an SpiTap to read and write the register over a serial bus. This is much like a JTAG scannable register, but with simpler SPI type serial protocol. Each SpiReg has an address and up to 32 bits of data. The SpiRoot module provides a parallel, FIFO interface to a collection of Spi Registers. The Registers are connected in a serial chain. To perform a write to an SpiReg, the client writes register address and data into the FIFO. Returning read data (and acks for write data) show up at the output of the FIFO. ================================================ FILE: contrib/serialconfig/Serialconfig.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import SpiTap::*; import SpiRoot::*; import Connectable::*; interface SerialconfigIndication; method Action ack(Bit#(32) a, Bit#(32) d); endinterface interface SerialconfigRequest; method Action send(Bit#(32) a, Bit#(32) d); endinterface interface Serialconfig; interface SerialconfigRequest request; endinterface module mkSerialconfig#(SerialconfigIndication indication)(Serialconfig); SpiReg#(Bit#(32)) tap1 <- mkSpiReg('h11110000); SpiReg#(Bit#(24)) tap2 <- mkSpiReg('h22220000); SpiReg#(Bit#(16)) tap3 <- mkSpiReg('h33330000); SpiReg#(Bit#(8)) tap4 <- mkSpiReg('h44440000); mkConnection(tap1.tap.out, tap2.tap.in); mkConnection(tap2.tap.out, tap3.tap.in); mkConnection(tap3.tap.out, tap4.tap.in); FIFO#(SpiItem) spi <- mkSpiRoot(SpiTap{in: tap1.tap.in, out: tap4.tap.out}); rule getresults; indication.ack(spi.first().a, spi.first().d); spi.deq(); endrule interface SerialconfigRequest request; method Action send(Bit#(32) a, Bit#(32) d); spi.enq(SpiItem{a: a, d: d}); endmethod endinterface endmodule ================================================ FILE: contrib/serialconfig/testserialconfig.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include "SerialconfigIndication.h" #include "SerialconfigRequest.h" #include "GeneratedTypes.h" sem_t test_sem; uint32_t lasta; uint32_t lastd; static SerialconfigRequestProxy *serialconfigRequestProxy = 0; class SerialconfigIndication : public SerialconfigIndicationWrapper { public: SerialconfigIndication(unsigned int id) : SerialconfigIndicationWrapper(id){}; virtual void ack(uint32_t a, uint32_t d) { fprintf(stderr, "ack a %x d %x\n", a, d); lasta = a; lastd = d; sem_post(&test_sem); } }; void lastdshouldbe(uint32_t v) { if (lastd != v) printf("error, expected data %08x got %08x\n", v, lastd); } void lastashouldbe(uint32_t a) { if ((lasta & ~1) != a) printf("error, expected address %08x got %08x\n", a, lasta & ~1); } void doread(uint32_t a, uint32_t expect) { serialconfigRequestProxy->send(a & ~1, 0xfeedface); sem_wait(&test_sem); lastashouldbe(a); lastdshouldbe(expect); } void dowrite(uint32_t a, uint32_t d) { serialconfigRequestProxy->send(a | 1, d); sem_wait(&test_sem); lastashouldbe(a); lastdshouldbe(d); } void dotest() { dowrite(0x0, 0xf00f00); dowrite(0x11110000, 0x00000000); dowrite(0x22220000, 0x00000000); dowrite(0x33330000, 0x00000000); dowrite(0x44440000, 0x00000000); doread(0x11110000, 0x00000000); doread(0x22220000, 0x00000000); doread(0x33330000, 0x00000000); doread(0x44440000, 0x00000000); dowrite(0x11110000, 0x11111111); dowrite(0x22220000, 0x22222222); dowrite(0x33330000, 0x33333333); dowrite(0x44440000, 0x44444444); doread(0x11110000, 0x11111111); doread(0x22220000, 0x00222222); doread(0x33330000, 0x00003333); doread(0x44440000, 0x00000044); dowrite(0x0, 0xdeadbeef); doread(0x0, 0xfeedface); } int main(int argc, const char **argv) { SerialconfigIndication serialconfigIndication(IfcNames_SerialconfigIndicationH2S); fprintf(stderr, "%s %s\n", __DATE__, __TIME__); serialconfigRequestProxy = new SerialconfigRequestProxy(IfcNames_SerialconfigRequestS2H); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } fprintf(stderr, "simple tests\n"); dotest(); } ================================================ FILE: contrib/smithwaterman/GotohB.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StmtFSM::*; import BRAM::*; interface GotohAlgorithm; method Action setupA (Bit#(14) start, Bit#(14) length); method Action setupB (Bit#(14) start, Bit#(14) length); method Action setupG (Bit#(16) g); method Action setupCC (Bit#(14) start); method Action setupDD (Bit#(14) start); method Bit#(14) result(); interface FSM fsm; endinterface module mkGotohB#(BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strA, BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strB, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) matCC, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) matDD, int dir)(GotohAlgorithm) provisos(Add#(0, 14, strIndexWidth), Add#(0, 14, lIndexWidth)); Bit#(16) initialH = 1; Bit#(16) initialG = 4; Reg#(Bit#(14)) aStartReg <- mkReg(0); Reg#(Bit#(14)) bStartReg <- mkReg(0); Reg#(Bit#(14)) ccStartReg <- mkReg(0); Reg#(Bit#(14)) ddStartReg <- mkReg(0); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) ii <- mkReg(0); Reg#(Bit#(14)) jj <- mkReg(0); Reg#(Bit#(8)) aData <- mkReg(0); Reg#(Bit#(8)) bData <- mkReg(0); Reg#(Bit#(16)) vd <- mkReg(0); Reg#(Bit#(16)) vc <- mkReg(0); Reg#(Bit#(16)) ve <- mkReg(0); Reg#(Bit#(16)) vs <- mkReg(0); Reg#(Bit#(16)) vt <- mkReg(0); Reg#(Bit#(16)) ccData <- mkReg(0); Reg#(Bit#(16)) ddData <- mkReg(0); Reg#(Bit#(16)) wdata <- mkReg(0); Reg#(Bit#(16)) argt <- mkReg(0); Stmt gotohB = seq $display("gotohB running %d %d %d %d dir %d", aStartReg, aLenReg, bStartReg, bLenReg, dir); /* initialize arrays */ vt <= initialG + initialH; jj<= 1; while (jj <= bLenReg) seq action matCC.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ccStartReg + zeroExtend(jj), datain: vt}); matDD.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ddStartReg + zeroExtend(jj), datain: vt + initialG}); vt <= vt + initialH; jj <= jj + 1; endaction endseq action ve <= 0; vc <= 0; vs <= 0; matCC.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ccStartReg, datain: 0}); matDD.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ddStartReg, datain: 0}); endaction vt <= argt; /* Use passed-in value here */ /* Loop through string a */ ii <= 1; while (ii <= aLenReg) seq $display("gotohB ii = %d", ii); /* read string A */ action let idx = ?; if (dir == 1) idx = aStartReg + ii - 1; // 0 to aLen - 1 else idx = aStartReg + aLenReg - ii; // aLen-1 downto 0 strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: idx, datain: ?}); endaction action let tmp <- strA.response.get(); /* read a[i] */ aData <= tmp; endaction /* s = CC[0] */ matCC.request.put(BRAMRequest{write: False, responseOnWrite: False, address: ccStartReg + 0, datain: ?}); action let tmp <- matCC.response.get(); vs <= tmp; endaction action let newt = vt + initialH; vc <= newt; /* c = t + i * h */ vt <= newt; matCC.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ccStartReg + 0, datain: newt}); /* CC[0] = c */ matDD.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ddStartReg + 0, datain: newt}); /* DD[0] = CC[0] */ ve <= newt + initialG; jj <= 1; endaction /* Loop through string B */ while (jj <= bLenReg) seq $display("gotohB jj = %d", jj); ve <= min (ve, vc + initialG) + initialH; /* read CC[j] and DD[j] */ matCC.request.put(BRAMRequest{write: False, responseOnWrite: False, address: ccStartReg + jj, datain: ?}); matDD.request.put(BRAMRequest{write: False, responseOnWrite: False, address: ddStartReg + jj, datain: ?}); action let tmpcc <- matCC.response.get(); let tmpdd <- matDD.response.get(); ccData <= tmpcc; ddData <= tmpdd; endaction /* read bData */ action let idx = ?; if (dir == 1) idx = bStartReg + jj - 1; /* b[0] tp b[m-1] */ else idx = bStartReg + bLenReg - jj; /* b[m-1] downto b[0] */ strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: idx, datain: ?}); endaction action let tmp <- strB.response.get(); bData <= tmp; endaction if (aData == bData) wdata <= 0; else wdata <= 2; action let newdd = min(ddData, ccData + initialG) + initialH; matDD.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ddStartReg + jj, datain: newdd}); vc <= min(newdd, min(ve, vs + wdata)); endaction vs <= ccData; matCC.request.put(BRAMRequest{write: True, responseOnWrite: False, address: ccStartReg + jj, datain: vc}); jj <= jj + 1; endseq ii <= ii + 1; endseq endseq; FSM hB <- mkFSM(gotohB); method Action setupA(Bit#(14) start, Bit#(14) length); aStartReg <= start; aLenReg <= length; endmethod method Action setupB(Bit#(14) start, Bit#(14) length); bStartReg <= start; bLenReg <= length; endmethod method Action setupG(Bit#(16) g); argt <= g; endmethod method Action setupCC(Bit#(14) start); ccStartReg <= start; endmethod method Action setupDD(Bit#(14) start); ddStartReg <= start; endmethod method Bit#(14) result(); return(zeroExtend(bLenReg)); endmethod interface FSM fsm = hB; endmodule ================================================ FILE: contrib/smithwaterman/GotohC.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import StmtFSM::*; import BRAM::*; import GotohB::*; import StackReg::*; interface SWAlgorithm; method Action setupA (Bit#(14) start, Bit#(14) length); method Action setupB (Bit#(14) start, Bit#(14) length); method Bit#(14) result(); interface FSM fsm; endinterface /* frame arguments */ typedef struct { Bit#(14) aStart; Bit#(14) bStart; Bit#(14) aLen; Bit#(14) bLen; Bit#(16) tb; /* tb, te only need to be 1 bit, to represent 0 or g */ Bit#(16) te; } CArgs deriving(Bits); typedef struct { Bit#(14) midi; Bit#(14) minj; Bit#(2) mintype; } CVars deriving(Bits); typedef enum {GCSIdle, GCS1, GCS2, GCS3, GCS4, GCS5, GCS6, GCSComplete} GCState deriving (Bits, Eq); module mkGotohC#( BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strA, BRAMServer#(Bit#(strIndexWidth), Bit#(8)) strB, GotohAlgorithm cgotohB0, GotohAlgorithm cgotohB1, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) cc, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) dd, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) rr, BRAMServer#(Bit#(lIndexWidth), Bit#(16)) ss)(SWAlgorithm) provisos(Add#(0, 14, strIndexWidth), Add#(0, 14, lIndexWidth)); Bit#(16) initialH = 1; Bit#(16) initialG = 4; /* pc, args, vars */ StackReg#(128, GCState, CArgs, CVars) fr <- mkStackReg(128, GCSIdle); Reg#(Bit#(14)) aStartReg <- mkReg(0); Reg#(Bit#(14)) bStartReg <- mkReg(0); Reg#(Bit#(14)) rStartReg <- mkReg(0); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) ii <- mkReg(0); Reg#(Bit#(14)) jj <- mkReg(0); Reg#(Bit#(8)) aData <- mkReg(0); Reg#(Bit#(8)) bData <- mkReg(0); Reg#(Bit#(14)) outcounter <- mkReg(0); Reg#(Bit#(16)) alt1 <- mkReg(0); Reg#(Bit#(16)) alt2 <- mkReg(0); Reg#(Bit#(16)) minsofar <- mkReg(0); Reg#(Bit#(1)) minfound <- mkReg(0); /* * GotohC(Astart, Alen, Bstart, Blen, tb, te, output fifo) * implicit A storage, B storage * */ function Bit#(16) gap (Bit#(16) i); if (i == 0) gap = 0; else gap = (initialG + (initialH * i)); endfunction: gap // This FSM searches string B looking for the first char of string A Stmt gotohC2Stmt = seq $display("gotohC2Stmt running "); // read A[0] strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fr.args.aStart, datain: ?}); action let tmp <- strA.response.get(); aData <= tmp; endaction alt1 <= min(fr.args.tb, fr.args.te) + initialH + gap(zeroExtend(fr.args.bLen)); minsofar <= alt1; fr.vars <= CVars{midi: 0, minj: 1, mintype: 1}; // scan B for (jj <= 1; jj <= fr.args.bLen; jj <= jj + 1) seq strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fr.args.bStart + jj - 1, datain: ?}); action let tmp <- strB.response.get(); bData <= tmp; endaction if (aData == bData) alt2 <= 0; else alt2 <= 2; alt2 <= alt2 + gap(zeroExtend(jj - 1)) + gap(zeroExtend(fr.args.bLen - jj)); if (min(alt1, alt2) < minsofar) par minsofar <= min(alt1, alt2); fr.vars <= CVars{midi: 0, minj: jj, mintype: 1}; endpar endseq if (fr.vars.minj > 1) $display("delete B[%d] through B[%d]", fr.args.bStart, fr.args.bStart + fr.vars.minj - 1); $display("convert A[%d] (%s) to B[%d] (%s)", fr.args.aStart, aData, fr.args.bStart + fr.vars.minj - 1, bData); if (fr.vars.minj < fr.args.bLen) $display("delete B[%d] through B[%d]", fr.args.bStart + fr.vars.minj, fr.args.bStart + fr.args.bLen - 1); $display("notes fr.vars.minj %f fr.args.bLen %d", fr.vars.minj, fr.args.bLen); fr.doreturn(); endseq; FSM gC2fsm <- mkFSM(gotohC2Stmt); // AlgC step 1, 2, and 3 rule gc1 (fr.pc == GCS1); $display("GCS1 aStart %d aLen %d bStart %d bLen %d", fr.args.aStart, fr.args.aLen, fr.args.bStart, fr.args.bLen); if (fr.args.bLen == 0) begin if (fr.args.aLen > 0) $display("delete A[%d] through A[%d]", fr.args.aStart, fr.args.aStart + fr.args.aLen - 1); fr.doreturn(); end else if (fr.args.aLen == 0) begin $display("insert B[%d] through B[%d]", fr.args.bStart, fr.args.bStart + fr.args.bLen - 1); end else if (fr.args.aLen == 1) begin gC2fsm.start(); fr.nextpc(GCS2); end else action let midi = fr.args.aLen >> 1; fr.vars.midi <= midi; cgotohB1.setupA(fr.args.aStart, midi); cgotohB1.setupB(fr.args.bStart, fr.args.bLen); cgotohB1.setupG(fr.args.tb); cgotohB0.setupA(fr.args.aStart+midi, fr.args.aLen - midi); cgotohB0.setupB(fr.args.bStart, fr.args.bLen); cgotohB0.setupG(fr.args.te); cgotohB0.fsm.start(); cgotohB1.fsm.start(); fr.nextpc(GCS3); endaction endrule // This FSM searches the results of the two calls to GotohB Stmt gotohC4Stmt = seq $display ("gotohC4A stmt running"); action minfound <= 0; minsofar <= 0; fr.vars.minj <= 0; endaction for (jj <= 0; jj <= fr.args.bLen; jj <= jj + 1) seq action cc.request.put(BRAMRequest{write: False, responseOnWrite: False, address: zeroExtend(jj), datain: ?}); rr.request.put(BRAMRequest{write: False, responseOnWrite: False, address: zeroExtend(fr.args.bLen - jj), datain: ?}); dd.request.put(BRAMRequest{write: False, responseOnWrite: False, address: zeroExtend(jj), datain: ?}); ss.request.put(BRAMRequest{write: False, responseOnWrite: False, address: zeroExtend(fr.args.bLen - jj), datain: ?}); endaction action let tc <- cc.response.get(); let td <- dd.response.get(); let tr <- rr.response.get(); let ts <- ss.response.get(); let t1 = tc + tr; let t2 = td + ts - initialG; $display(" j %d cc %d dd %d rr %d ss %d", jj, tc, td, tr, ts); if ((minfound == 0) || (t1 < minsofar) || (t2 < minsofar)) action if (t1 < t2) action fr.vars <= CVars{midi: fr.vars.midi, minj: jj, mintype: 1}; minsofar <= t1; endaction else action fr.vars <= CVars{midi: fr.vars.midi, minj: jj, mintype: 2}; minsofar <= t2; endaction endaction minfound <= 1; endaction endseq $display ("midi %d minj %d fr.vars.mintype %d", fr.vars.midi, fr.vars.minj, fr.vars.mintype); if (fr.vars.mintype == 1) action fr.docall(GCS1, GCS5, CArgs {aStart: fr.args.aStart, aLen: fr.vars.midi, bStart: fr.args.bStart, bLen: fr.vars.minj, tb: fr.args.tb, te: initialG}, fr.vars); endaction else /* fr.vars.mintype == 2 */ action fr.docall(GCS1, GCS5, CArgs {aStart: fr.args.aStart, aLen: fr.vars.midi - 1, bStart: fr.args.bStart, bLen: fr.vars.minj, tb: fr.args.tb, te: 0}, fr.vars); endaction endseq; FSM gc4fsm <- mkFSM(gotohC4Stmt); rule gc3 (fr.pc == GCS3 && cgotohB0.fsm.done() && cgotohB1.fsm.done()); //$display("HSC3"); gc4fsm.start(); fr.nextpc(GCS4); endrule rule gc5 (fr.pc == GCS5); $display("GCC5 aStart %d aLen %d bStart %d bLen %d midi %d maj %d", fr.args.aStart, fr.args.aLen, fr.args.bStart, fr.args.bLen, fr.vars.midi, fr.vars.minj); if (fr.vars.mintype == 1) action fr.docall(GCS1, GCS6, CArgs{aStart: fr.args.aStart + fr.vars.midi, aLen: fr.args.aLen - fr.vars.midi, bStart: fr.args.bStart + fr.vars.minj, bLen: fr.args.bLen - fr.vars.minj, tb: initialG, te: fr.args.te}, fr.vars); endaction else action $display("delete A[%d] and A[%d]", fr.args.aStart + fr.vars.midi, fr.args.aStart + fr.vars.midi + 1); fr.docall(GCS1, GCS6, CArgs{aStart: fr.args.aStart + fr.vars.midi + 1, aLen: fr.args.aLen - fr.vars.midi- 1, bStart: fr.args.bStart + fr.vars.minj, bLen: fr.args.bLen - fr.vars.minj, tb: 0, te: fr.args.te}, fr.vars); endaction endrule rule gc6 (fr.pc == GCS6); $display("GSC6"); fr.doreturn(); endrule rule hccomplete (fr.pc == GCSComplete); $display("GSCComplete, result size %d", outcounter); fr.nextpc(GCSIdle); endrule method Action setupA(Bit#(14) start, Bit#(14) length); $display("GotohC setupA %d %d", start, length); aStartReg <= start; aLenReg <= length; endmethod method Action setupB(Bit#(14) start, Bit#(14) length); $display("GotohC setupB %d %d", start, length); bStartReg <= start; bLenReg <= length; endmethod method Bit#(14) result(); return(outcounter); endmethod interface FSM fsm; method Action start(); $display("GotohC running aLen %d bLen %d", aLenReg, bLenReg); fr.docall(GCS1, GCSComplete, CArgs{aStart: 0, aLen: aLenReg, bStart: 0, bLen: bLenReg, tb: initialG, te: initialG}, CVars {midi: 0, minj: 0, mintype: 1}); endmethod method Bool done(); return(fr.pc == GCSIdle); endmethod method Action waitTillDone(); endmethod method Action abort(); endmethod endinterface: fsm endmodule ================================================ FILE: contrib/smithwaterman/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SmithwatermanRequest SmithwatermanIndication BSVFILES = Smithwaterman.bsv Top.bsv $(CONNECTALDIR)/lib/deprecated/DmaUtils.bsv CPPFILES=testsmithwaterman.cpp CONNECTALFLAGS += -I $(CONNECTALDIR)/lib/strstr/cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/smithwaterman/Readme.md ================================================ ## Smith-Waterman L. Stewart March17, 2014 See connectal/doc/SmithWaterman.md ================================================ FILE: contrib/smithwaterman/Smithwaterman.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import StmtFSM::*; import BRAM::*; import Connectable::*; import ConnectalMemTypes::*; import DmaUtils::*; import Dma2BRAM::*; // algorithm import GotohB::*; import GotohC::*; interface SmithwatermanRequest; method Action setupA(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); method Action setupB(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); method Action start(Bit#(32) alg); endinterface interface SmithwatermanIndication; method Action searchResult(Bit#(32) v); method Action setupAComplete(); method Action setupBComplete(); endinterface typedef Bit#(64) DWord; typedef Bit#(32) Word; typedef 16384 MaxStringLen; typedef 16384 MaxFetchLen; typedef TLog#(MaxStringLen) StringIdxWidth; typedef Bit#(StringIdxWidth) StringIdx; typedef TLog#(MaxFetchLen) LIdxWidth; typedef Bit#(LIdxWidth) LIdx; module mkSmithwatermanRequest#(SmithwatermanIndication indication, MemReadServer#(busWidth) setupA_read_server, MemReadServer#(busWidth) setupB_read_server)(SmithwatermanRequest) provisos(Add#(a__, 8, busWidth), Div#(busWidth,8,nc), Mul#(nc,8,busWidth), Add#(1, b__, nc), Add#(c__, 32, busWidth), Add#(1, d__, TDiv#(busWidth, 32)), Mul#(TDiv#(busWidth, 32), 32, busWidth), Mul#(TDiv#(busWidth, 16), 16, busWidth), Add#(1, e__, TDiv#(busWidth, 16)), Add#(1, f__, TMul#(2, TDiv#(busWidth, 16))), Add#(TDiv#(busWidth, 16), g__, TMul#(2, TDiv#(busWidth, 16)))); Reg#(Bit#(14)) aLenReg <- mkReg(0); Reg#(Bit#(14)) bLenReg <- mkReg(0); Reg#(Bit#(14)) rLenReg <- mkReg(0); BRAM2Port#(StringIdx, Bit#(8)) strA <- mkBRAM2Server(defaultValue); BRAM2Port#(StringIdx, Bit#(8)) strB <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) cc <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) dd <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) rr <- mkBRAM2Server(defaultValue); BRAM2Port#(LIdx, Bit#(16)) ss <- mkBRAM2Server(defaultValue); BRAMReadClient#(StringIdxWidth,busWidth) n2a <- mkBRAMReadClient(strA.portB); mkConnection(n2a.dmaClient, setupA_read_server); BRAMReadClient#(StringIdxWidth,busWidth) n2b <- mkBRAMReadClient(strB.portB); mkConnection(n2b.dmaClient, setupB_read_server); Reg#(Bool) gotohCRunning <- mkReg(False); GotohAlgorithm cgotohB1 <- mkGotohB(strA.portA, strB.portA, cc.portA, dd.portA, 1); GotohAlgorithm cgotohB0 <- mkGotohB(strA.portA, strB.portA, rr.portA, ss.portA, 0); SWAlgorithm gotohC <- mkGotohC(strA.portA, strB.portA, cgotohB0, cgotohB1, cc.portB, dd.portB, rr.portB, ss.portB); // create BRAM Write client for matL rule finish_setupA; $display("finish setupA"); let x <- n2a.finish; indication.setupAComplete(); endrule rule finish_setupB; $display("finish setupB"); let x <- n2b.finish; indication.setupBComplete(); endrule rule gotohC_completion (gotohCRunning && gotohC.fsm.done); gotohCRunning <= False; indication.searchResult(pack(zeroExtend(gotohC.result()))); endrule method Action setupA(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); aLenReg <= truncate(strLen); $display("setupA %h %h %d", strPointer, strOffset, strLen); n2a.start(strPointer, 0, pack(truncate(strOffset)), pack(truncate(strOffset + strLen-1))); gotohC.setupA(truncate(strOffset), pack(truncate(strLen))); endmethod method Action setupB(Bit#(32) strPointer, Bit#(32) strOffset, Bit#(32) strLen); bLenReg <= truncate(strLen); $display("setupB %h %h %d", strPointer, strOffset, strLen); n2b.start(strPointer, 0, pack(truncate(strOffset)), pack(truncate(strOffset + strLen-1))); gotohC.setupB(truncate(strOffset), pack(truncate(strLen))); endmethod method Action start(Bit#(32) alg); $display ("start %d", alg); case (alg) 3: begin gotohC.fsm.start(); gotohCRunning <= True; end endcase endmethod endmodule ================================================ FILE: contrib/smithwaterman/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import BlueScope::*; import ConnectalMemory::*; import DmaUtils::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import SmithwatermanRequest::*; import MemServerRequest::*; import MMURequest::*; import SmithwatermanIndication::*; import MemServerIndication::*; import MMUIndication::*; import Smithwaterman::*; typedef enum {IfcNames_SmithwatermanIndication, IfcNames_SmithwatermanRequest, IfcNames_HostMemServerIndication, IfcNames_HostMemServerRequest, IfcNames_HostMMURequest, IfcNames_HostMMUIndication} IfcNames deriving (Eq,Bits); typedef 1 DegPar; module mkConnectalTop(StdConnectalDmaTop#(PhysAddrWidth)); DmaReadBuffer#(64,1) setupA_read_chan <- mkDmaReadBuffer(); DmaReadBuffer#(64,1) setupB_read_chan <- mkDmaReadBuffer(); MemReadClient#(64) setupA_read_client = setupA_read_chan.dmaClient; MemReadClient#(64) setupB_read_client = setupB_read_chan.dmaClient; Vector#(2, MemReadClient#(64)) readClients; readClients[0] = setupA_read_client; readClients[1] = setupB_read_client; MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_HostMMUIndication); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_HostMMURequest, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_HostMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(readClients, nil, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_HostMemServerRequest, dma.request); SmithwatermanIndicationProxy smithwatermanIndicationProxy <- mkSmithwatermanIndicationProxy(IfcNames_SmithwatermanIndication); SmithwatermanRequest smithwatermanRequest <- mkSmithwatermanRequest(smithwatermanIndicationProxy.ifc, setupA_read_chan.dmaServer, setupB_read_chan.dmaServer); SmithwatermanRequestWrapper smithwatermanRequestWrapper <- mkSmithwatermanRequestWrapper(IfcNames_SmithwatermanRequest,smithwatermanRequest); Vector#(6,StdPortal) portals; portals[0] = smithwatermanRequestWrapper.portalIfc; portals[1] = smithwatermanIndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = hostMemServerIndicationProxy.portalIfc; portals[4] = hostMMURequestWrapper.portalIfc; portals[5] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: contrib/smithwaterman/sw.py ================================================ from __future__ import print_function try: xrange except NameError: xrange = range # Python 3 compatibility def printmatrix(m): print("%s\n" * len (m) % tuple(m)) # Step 1 is Gotoh's algorithm] # arrays C[0..m, 0..n], D[0..m, 0..n] I[0..M, 0..N] # scalar t # paramters w(a, b), g, h # where w(a,b) is the cost of converting a to b # and cost of a gap is g + hk where k is the length ofthe gap # C(i,j) is the minimum cost of converting A(0..i) to B(0..j) # D(i,j) is the minimum cost of converting A(0..i) to B(0..j) when ai is deleted # C(i,j) is the minimum cost of converting A(0..i) to B(0..j) when bj is inserted # def w(a, b): if (a == b): return 0.0 else: return 1.0 g = 2.0 h = 0.5 def gap(k): return g + (k * h) def gotoh(A, B): m = len(A) n = len(B) C = [[0 for j in xrange(n+1)] for i in xrange(m+1)] D = [[0 for j in xrange(n+1)] for i in xrange(m+1)] I = [[0 for j in xrange(n+1)] for i in xrange(m+1)] C[0][0] = 0 for j in xrange(1,n+1): C[0][j] = gap(j) D[0][j] = C[0][j] + g for i in xrange(1,m+1): C[i][0] = gap(i) I[i][0] = C[i][0] + g for j in xrange(1,n+1): I[i][j] = min(I[i][j-1], C[i][j-1] + g) + h D[i][j] = min(D[i-1][j], C[i-1][j] + g) + h C[i][j] = min(D[i][j], I[i][j], C[i-1][j-1] + w(A[i-1], B[j-1])) print("String A %s String B %s" % (A, B)) print("Matrix C") printmatrix(C) print("Matrix D") printmatrix(D) print("Matrix I") printmatrix(I) return(C[m][n]) A = "agtac" B = "aag" gotoh(A, B) # The recurrances in Gotoh only depend on the previous row, so # in a manner analagous to the conversion from Hirschberg algorithm A # to Hirschberg algorithm B we can write algorithm gotohb that uses # only two row vectors CC and DD def gotohb(A, B): m = len(A) n = len(B) e = 0 c = 0 s = 0 CC = [0 for j in xrange(n+1)] DD = [0 for j in xrange(n+1)] CC[0] = 0 for j in xrange(1,n+1): CC[j] = gap(j) DD[j] = CC[j] + g # print 0, CC, DD, e, c, s for i in xrange(1,m+1): s = CC[0] c = gap(i) CC[0] = c e = c + g for j in xrange(1, n+1): e = min(e, c + g) + h DD[j] = min(DD[j], CC[j] + g) + h c = min(DD[j], e, s+w(A[i-1], B[j-1])) s = CC[j] CC[j] = c return([CC, DD]) print("Calling gotohb(%s, %s)" % (A, B)) regular = gotohb(A, B) print(regular) def gotohb2(A, B, t): m = len(A) n = len(B) e = 0 c = 0 s = 0 CC = [0 for j in xrange(n+1)] DD = [0 for j in xrange(n+1)] CC[0] = 0 for j in xrange(1,n+1): CC[j] = gap(j) DD[j] = CC[j] + g for i in xrange(1,m+1): s = CC[0] c = t + i * h CC[0] = c e = c + g for j in xrange(1, n+1): e = min(e, c + g) + h DD[j] = min(DD[j], CC[j] + g) + h c = min(DD[j], e, s+w(A[i-1], B[j-1])) s = CC[j] CC[j] = c DD[0] = CC[0] return([CC, DD]) print("Calling gotohb2 (%s, %s) " % ( A, B)) alternate = gotohb2(A, B, g) print(alternate) # # # def gotohc(A, B, sa, sb, m, n, tb, te): # m = len(A) - sa # n = len(B) - sb print("in gotohc", A, B, sa, sb, m, n, tb, te) if n == 0: if m > 0: print("delete A[%d] through A[%d]" % (sa, sa + m - 1)) elif m == 0: print("insert B[%d] through B[%d]" % (sb, sb + n - 1)) elif m == 1: alt1 = min(tb, te) + h + gap(n) minsofar = alt1; jsofar = 1; for j in xrange(1, n+1): alt2 = gap(j-1) + w(A[sa + 0], B[sb + j-1]) + gap(n-j) if (min(alt1, alt2) < minsofar): minsofar = min(alt1, alt2) jsofar = j if (jsofar > 1): print("delete B[%d] through B[%d]" % (sb, sb + jsofar -1)) print("convert A[%d] (%s) to B[%d] (%s) " % (sa, A[sa], sb + jsofar - 1, B[sb + jsofar - 1])) if jsofar < n: print("delete B[%d] through B[%d]" % (sb + jsofar, sb + n - 1)) else: i = m >> 1 # print "fwd rev", A, sa, i, B, sb, n fwd = gotohb2(A[sa : sa + i], B[sb:sb+n], tb) rev = gotohb2(A[sa + i:sa + m][::-1],B[sb:sb+n][::-1], te) minfound = 0 minsofar = 0 print("CC ", fwd[0], " DD ", fwd[1]) print("RR ", rev[0], " SS ", rev[1]) for j in xrange(0,n+1): t1 = fwd[0][j] + rev[0][n-j] t2 = fwd[1][j] + rev[1][n-j] - g if (minfound == 0) or (t1 < minsofar): mintype = 1 minsofar = t1 minj = j if (t2 < minsofar): mintype = 2 minsofar = t2 minj = j minfound = 1 # minj minsofar and mintype are set if mintype == 1: print("type 1 midpoint at %d,%d" % (i, minj)) gotohc(A,B, sa, sb, i, minj, tb, g) gotohc(A,B, sa+i, sb+minj, m-i, n-minj, g, te) else: print("type 2 midpoint at %d,%d" % (i, minj)) gotohc(A,B, sa, sb, i - 1, minj, tb, 0) print("delete a[", sa + i, "] and a[", sa + i + 1, "]") gotohc(A,B, sa + i + 1, sb + minj, m - i - 1, n - minj, 0, te) print("calling gotohc(%s, %s)" %(A, B)) gotohc(A, B, 0, 0, len(A), len(B), g, g) ================================================ FILE: contrib/smithwaterman/testsmithwaterman.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "dmaManager.h" #include #include #include "SmithwatermanIndication.h" #include "SmithwatermanRequest.h" sem_t test_sem; int result_length; class SmithwatermanIndication : public SmithwatermanIndicationWrapper { public: SmithwatermanIndication(unsigned int id) : SmithwatermanIndicationWrapper(id){}; virtual void setupAComplete() { fprintf(stderr, "setupAComplete\n"); sem_post(&test_sem); } virtual void setupBComplete() { fprintf(stderr, "setupBComplete\n"); sem_post(&test_sem); } virtual void searchResult (uint32_t v){ result_length = v; fprintf(stderr, "searchResult = %d\n", v); sem_post(&test_sem); } }; int main(int argc, const char **argv) { SmithwatermanRequestProxy *device = 0; SmithwatermanIndication *deviceIndication = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); device = new SmithwatermanRequestProxy(IfcNames_SmithwatermanRequest); deviceIndication = new SmithwatermanIndication(IfcNames_SmithwatermanIndication); DmaManager *dma = platformInit(); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } fprintf(stderr, "simple tests\n"); int strAAlloc; int strBAlloc; unsigned int alloc_len = 128; int rcA, rcB; struct stat statAbuf, statBbuf; strAAlloc = portalAlloc(alloc_len, 0); rcA = fstat(strAAlloc, &statAbuf); if (rcA < 0) perror("fstatA"); char *strA = (char *)portalMmap(strAAlloc, alloc_len); if (strA == MAP_FAILED) perror("strA mmap failed"); assert(strA != MAP_FAILED); strBAlloc = portalAlloc(alloc_len, 0); rcB = fstat(strBAlloc, &statBbuf); if (rcA < 0) perror("fstatB"); char *strB = (char *)portalMmap(strBAlloc, alloc_len); if (strB == MAP_FAILED) perror("strB mmap failed"); assert(strB != MAP_FAILED); const char *strA_text = "agtac"; const char *strB_text = "aag"; assert(strlen(strA_text) < alloc_len); assert(strlen(strB_text) < alloc_len); strncpy(strA, strA_text, alloc_len); strncpy(strB, strB_text, alloc_len); int strA_len = strlen(strA); int strB_len = strlen(strB); portalTimerInit(); portalTimerStart(0); fprintf(stderr, "elapsed time (hw cycles): %lld\n", (long long)portalTimerLap(0)); portalCacheFlush(strAAlloc, strA, alloc_len, 1); portalCacheFlush(strBAlloc, strB, alloc_len, 1); unsigned int ref_strAAlloc = dma->reference(strAAlloc); unsigned int ref_strBAlloc = dma->reference(strBAlloc); device->setupA(ref_strAAlloc, 0, strA_len); sem_wait(&test_sem); device->setupB(ref_strBAlloc, 0, strB_len); sem_wait(&test_sem); uint64_t cycles; uint64_t beats; fprintf(stderr, "starting algorithm C\n"); portalTimerInit(); portalTimerStart(0); device->start(3); sem_wait(&test_sem); cycles = portalTimerLap(0); fprintf(stderr, "hw cycles: %f\n", (float)cycles); sem_wait(&test_sem); printf("Algorithm C results\n"); printf("\n"); close(strAAlloc); close(strBAlloc); } ================================================ FILE: contrib/splice/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SpliceRequest SpliceIndication BSVFILES = Splice.bsv Top.bsv $(CONNECTALDIR)/lib/deprecated/DmaUtils.bsv CPPFILES=testsplice.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: contrib/splice/Splice.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import StmtFSM::*; import BRAM::*; import Connectable::*; import ConnectalMemTypes::*; import DmaUtils::*; import Dma2BRAM::*; /* This module solves the maximum common subsequence problem. * It finds the longest subsequence of characters present in both input strings * the subsequence does not have to be contiguous and the characters can have different locations * and offsets in the two strings, just so long as they occur in the same order * * To initialize, load string A with request setupA, and wait for indication setup complete * Then load string B with request setupB, and wait for indication setup complete * To start the unit, signal start, and wait for searchResult, which will tell you the length * To retreive the result, use fetch and wait for fetchComplete */ /* First pass implements Hirschberg Algorithm A and the fetch call returns the L matrix */ interface SpliceRequest; method Action setupA(Bit#(32) strPointer, Bit#(32) strLen); method Action setupB(Bit#(32) strPointer, Bit#(32) strLen); method Action fetch(Bit#(32) strPointer, Bit#(32) strLen); method Action start(); endinterface interface SpliceIndication; method Action searchResult(Int#(32) v); method Action setupAComplete(); method Action setupBComplete(); method Action fetchComplete(); endinterface typedef Bit#(8) Char; typedef Bit#(64) DWord; typedef Bit#(32) Word; typedef 128 MaxStringLen; typedef 16384 MaxFetchLen; typedef TLog#(MaxStringLen) StringIdx; typedef TLog#(MaxFetchLen) LIdx; module mkSpliceRequest#(SpliceIndication indication, MemReadServer#(busWidth) setupA_read_server, MemReadServer#(busWidth) setupB_read_server, MemWriteServer#(busWidth) fetch_write_server )(SpliceRequest) provisos(Add#(a__, 8, busWidth), Div#(busWidth,8,nc), Mul#(nc,8,busWidth), Add#(1, b__, nc), Add#(c__, 32, busWidth), Add#(1, d__, TDiv#(busWidth, 32)), Mul#(TDiv#(busWidth, 32), 32, busWidth), Mul#(TDiv#(busWidth, 16), 16, busWidth), Add#(1, e__, TDiv#(busWidth, 16)), Add#(1, f__, TMul#(2, TDiv#(busWidth, 16))), Add#(1, h__, busWidth), Add#(TDiv#(busWidth, 16), g__, TMul#(2, TDiv#(busWidth, 16)))); Reg#(Bit#(32)) aLenReg <- mkReg(0); Reg#(Bit#(32)) bLenReg <- mkReg(0); Reg#(Bit#(32)) rLenReg <- mkReg(0); Reg#(Bit#(32)) ii <- mkReg(0); Reg#(Char) aData <- mkReg(0); Reg#(Char) bData <- mkReg(0); BRAM2Port#(Bit#(StringIdx), Char) strA <- mkBRAM2Server(defaultValue); BRAM2Port#(Bit#(StringIdx), Char) strB <- mkBRAM2Server(defaultValue); BRAM2Port#(Bit#(LIdx), Bit#(16)) matL <- mkBRAM2Server(defaultValue); BRAMReadClient#(StringIdx,busWidth) n2a <- mkBRAMReadClient(strA.portB); mkConnection(n2a.dmaClient, setupA_read_server); BRAMReadClient#(StringIdx,busWidth) n2b <- mkBRAMReadClient(strB.portB); mkConnection(n2b.dmaClient, setupB_read_server); BRAMWriteClient#(LIdx, busWidth) l2n <- mkBRAMWriteClient(matL.portB); mkConnection(l2n.dmaClient, fetch_write_server); FIFOF#(void) aReady <- mkFIFOF; FIFOF#(void) bReady <- mkFIFOF; FIFOF#(void) mReady <- mkFIFOF; Stmt splice = seq while(True) seq action let ra <- aReady.deq(); $display("Splice A Ready"); endaction action let rb <- bReady.deq(); $display("Splice B Ready"); endaction if (aLenReg > bLenReg) rLenReg <= aLenReg; else rLenReg <= bLenReg; for (ii <= 0; ii < rLenReg; ii <= ii + 1) seq $display("Splice ii %d ", ii); strA.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: truncate(ii), datain: 0}); strB.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: truncate(ii), datain: 0}); action let left <- strA.portA.response.get(); let right <- strB.portA.response.get(); aData <= left; bData <= right; endaction $display("aData %h bData %h", aData, bData); matL.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: truncate(ii), datain: {aData, bData}}); endseq indication.searchResult(unpack(rLenReg)); endseq endseq; // create BRAM Write client for matL rule finish_setupA; $display("finish setupA"); let x <- n2a.finish; aReady.enq(?); indication.setupAComplete(); endrule rule finish_setupB; $display("finish setupB"); let x <- n2b.finish; bReady.enq(?); indication.setupBComplete(); endrule rule finish_fetch; $display("finish fetch"); let x <- l2n.finish; indication.fetchComplete(); endrule mkAutoFSM(splice); method Action setupA(Bit#(32) strPointer, Bit#(32) strLen); aLenReg <= strLen; $display("setupA %h %d", strPointer, strLen); n2a.start(strPointer, 0, 0, truncate(strLen - 1)); endmethod method Action setupB(Bit#(32) strPointer, Bit#(32) strLen); bLenReg <= strLen; $display("setupB %h %d", strPointer, strLen); n2b.start(strPointer, 0, 0, truncate(strLen - 1)); endmethod method Action fetch(Bit#(32) strPointer, Bit#(32) strLen); rLenReg <= strLen; $display("fetch %h %d", strPointer, strLen); l2n.start(strPointer, 0, 0, truncate(strLen - 1)); endmethod method Action start(); endmethod endmodule ================================================ FILE: contrib/splice/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import BlueScope::*; import ConnectalMemory::*; import DmaUtils::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import SpliceRequest::*; import MemServerRequest::*; import MMURequest::*; import SpliceIndication::*; import MemServerIndication::*; import MMUIndication::*; import Splice::*; typedef enum {IfcNames_SpliceIndication, IfcNames_SpliceRequest, IfcNames_HostMemServerIndication, IfcNames_HostMemServerRequest, IfcNames_HostMMURequest, IfcNames_HostMMUIndication} IfcNames deriving (Eq,Bits); typedef 1 DegPar; module mkConnectalTop(StdConnectalDmaTop#(PhysAddrWidth)); DmaReadBuffer#(64,1) setupA_read_chan <- mkDmaReadBuffer(); DmaReadBuffer#(64,1) setupB_read_chan <- mkDmaReadBuffer(); DmaWriteBuffer#(64,1) fetch_write_chan <- mkDmaWriteBuffer(); MemReadClient#(64) setupA_read_client = setupA_read_chan.dmaClient; MemReadClient#(64) setupB_read_client = setupB_read_chan.dmaClient; MemWriteClient#(64) fetch_write_client = fetch_write_chan.dmaClient; Vector#(2, MemReadClient#(64)) readClients; readClients[0] = setupA_read_client; readClients[1] = setupB_read_client; Vector#(1, MemWriteClient#(64)) writeClients; writeClients[0] = fetch_write_client; MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_HostMMUIndication); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_HostMMURequest, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_HostMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(readClients, writeClients, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_HostMemServerRequest, dma.request); SpliceIndicationProxy spliceIndicationProxy <- mkSpliceIndicationProxy(IfcNames_SpliceIndication); SpliceRequest spliceRequest <- mkSpliceRequest(spliceIndicationProxy.ifc, setupA_read_chan.dmaServer, setupB_read_chan.dmaServer, fetch_write_chan.dmaServer); SpliceRequestWrapper spliceRequestWrapper <- mkSpliceRequestWrapper(IfcNames_SpliceRequest,spliceRequest); Vector#(6,StdPortal) portals; portals[0] = spliceRequestWrapper.portalIfc; portals[1] = spliceIndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = hostMemServerIndicationProxy.portalIfc; portals[4] = hostMMURequestWrapper.portalIfc; portals[5] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: contrib/splice/testsplice.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "dmaManager.h" #include "SpliceIndication.h" #include "SpliceRequest.h" sem_t test_sem; sem_t setup_sem; int sw_match_cnt = 0; int hw_match_cnt = 0; unsigned result_len = 0; class SpliceIndication : public SpliceIndicationWrapper { public: SpliceIndication(unsigned int id) : SpliceIndicationWrapper(id){}; virtual void setupAComplete() { fprintf(stderr, "setupAComplete\n"); sem_post(&setup_sem); } virtual void setupBComplete() { fprintf(stderr, "setupBComplete\n"); sem_post(&setup_sem); } virtual void fetchComplete() { fprintf(stderr, "fetchComplete\n"); sem_post(&setup_sem); } virtual void searchResult (int v){ fprintf(stderr, "searchResult = %d\n", v); result_len = v; sem_post(&test_sem); } }; int main(int argc, const char **argv) { SpliceRequestProxy *device = 0; SpliceIndication *deviceIndication = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); device = new SpliceRequestProxy(IfcNames_SpliceRequest); deviceIndication = new SpliceIndication(IfcNames_SpliceIndication); DmaManager *dma = platformInit(); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } if(sem_init(&setup_sem, 1, 0)){ fprintf(stderr, "failed to init setup_sem\n"); return -1; } fprintf(stderr, "simple tests\n"); int strAAlloc; int strBAlloc; int fetchAlloc; unsigned int alloc_len = 128; unsigned int fetch_len = alloc_len * alloc_len; strAAlloc = portalAlloc(alloc_len, 0); strBAlloc = portalAlloc(alloc_len, 0); fetchAlloc = portalAlloc(fetch_len, 0); char *strA = (char *)portalMmap(strAAlloc, alloc_len); char *strB = (char *)portalMmap(strBAlloc, alloc_len); int *fetch = (int *)portalMmap(fetchAlloc, fetch_len); const char *strA_text = " a b c "; const char *strB_text = "..a........b......"; assert(strlen(strA_text) < alloc_len); assert(strlen(strB_text) < alloc_len); strncpy(strA, strA_text, alloc_len); strncpy(strB, strB_text, alloc_len); int strA_len = strlen(strA); int strB_len = strlen(strB); uint16_t swFetch[fetch_len]; for (int i = 0; i < alloc_len; i += 1) { strA[i] = i; strB[i] = 255 - i; } portalTimerStart(0); fprintf(stderr, "elapsed time (hw cycles): %lld\n", (long long)portalTimerLap(0)); portalCacheFlush(strAAlloc, strA, alloc_len, 1); portalCacheFlush(strBAlloc, strB, alloc_len, 1); portalCacheFlush(fetchAlloc, fetch, fetch_len, 1); unsigned int ref_strAAlloc = dma->reference(strAAlloc); unsigned int ref_strBAlloc = dma->reference(strBAlloc); unsigned int ref_fetchAlloc = dma->reference(fetchAlloc); device->setupA(ref_strAAlloc, strA_len); sem_wait(&setup_sem); device->setupB(ref_strBAlloc, strB_len); sem_wait(&setup_sem); portalTimerStart(0); device->start(); sem_wait(&test_sem); uint64_t cycles = portalTimerLap(0); uint64_t beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); fprintf(stderr, "hw cycles: %f\n", (float)cycles); assert(result_len < alloc_len * alloc_len); // device->fetch(ref_fetchAlloc, (result_len+7)& ~7); device->fetch(ref_fetchAlloc, 32); printf("fetch called %d\n", result_len); sem_wait(&setup_sem); printf("fetch finished \n"); memcpy(swFetch, fetch, result_len * sizeof(uint16_t)); for (int i = 0; i < result_len; i += 1) { if ((swFetch[i] & 0xffff) != ((strA[i] << 8) & 0xff00 | (strB[i] & 0xff))) printf("mismatch i %d A %02x B %02x R %04x\n", i, strA[i], strB[i], swFetch[i]); } close(strAAlloc); close(strBAlloc); close(fetchAlloc); } ================================================ FILE: cpp/BsimDma.cpp ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include "sock_utils.h" #define MAX_DMA_PORTS 4 #define MAX_DMA_IDS 32 typedef struct { int fd; unsigned char *buffer; uint32_t buffer_len; int size_accum; } DMAINFO[MAX_DMA_IDS]; static DMAINFO dma_info[MAX_DMA_PORTS]; static int dma_trace ;//= 1; #define BUFFER_CHECK \ if (!dma_info[id][pref].buffer || offset >= dma_info[id][pref].buffer_len) { \ fprintf(stderr, "BsimDma [%s:%d]: Error: offset %d too large for buffer %p len %d; reference id %d pref %d\n", __FUNCTION__, __LINE__, offset, dma_info[id][pref].buffer, dma_info[id][pref].buffer_len, id, pref); \ exit(-1); \ } extern "C" void write_simDma32(uint32_t pref, uint32_t offset, unsigned int data, uint8_t byteEnable) { uint32_t id = pref>>5; pref -= id<<5; if (dma_trace) fprintf(stderr, "%s: %d [%d:%d] = %x\n", __FUNCTION__, id, pref, offset, data); BUFFER_CHECK if (byteEnable != 0xF) { uint32_t old_data = *(unsigned int *)&dma_info[id][pref].buffer[offset]; uint32_t mask = 0; for (int i = 0; i < 4; i++) { if (byteEnable & (1 << i)) mask |= (0xFF << (i*8)); } //fprintf(stderr, "write_simDma32 mask=%08x data=%08x old_data=%08x\n", mask, data, old_data); data &= mask; old_data &= ~mask; //fprintf(stderr, "write_simDma32 mask=%08x data=%08x old_data=%08x\n", mask, data, old_data); data = data | old_data; } *(unsigned int *)&dma_info[id][pref].buffer[offset] = data; } extern "C" unsigned int read_simDma32(uint32_t pref, uint32_t offset) { uint32_t id = pref>>5; unsigned int ret; pref -= id<<5; BUFFER_CHECK ret = *(unsigned int *)&dma_info[id][pref].buffer[offset]; if (dma_trace) fprintf(stderr, "%s: %d [%d:%d] = %x\n", __FUNCTION__, id, pref, offset, ret); return ret; } extern "C" void write_simDma64(uint32_t pref, uint32_t offset, uint64_t data, uint8_t byteEnable) { uint32_t id = pref>>5; pref -= id<<5; if (dma_trace) fprintf(stderr, "%s: %d [%d:%d] = %llx\n", __FUNCTION__, id, pref, offset, (long long)data); BUFFER_CHECK if (byteEnable != 0xFF) { uint64_t old_data = *(uint64_t *)&dma_info[id][pref].buffer[offset]; uint64_t mask = 0; for (int i = 0; i < 8; i++) { if (byteEnable & (1 << i)) mask |= (0xFF << (i*8)); } data &= mask; old_data &= ~mask; data = data | old_data; } *(uint64_t *)&dma_info[id][pref].buffer[offset] = data; } extern "C" uint64_t read_simDma64(uint32_t pref, uint32_t offset) { uint32_t id = pref>>5; uint64_t ret; pref -= id<<5; BUFFER_CHECK ret = *(uint64_t *)&dma_info[id][pref].buffer[offset]; if (dma_trace) fprintf(stderr, "%s: %d [%d:%d] = %llx\n", __FUNCTION__, id, pref, offset, (long long)ret); return ret; } extern "C" void simDma_initfd(uint32_t aid, uint32_t fd) { uint32_t id = aid >> 16; uint32_t pref = aid & 0xffff; if (dma_trace) fprintf(stderr, "%s: id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, fd); assert(pref < MAX_DMA_IDS); dma_info[id][pref].fd = fd; assert(dma_info[id][pref].size_accum == 0); } extern "C" void simDma_init(uint32_t id, uint32_t pref, uint32_t size) { if (dma_trace) fprintf(stderr, "simDma_init: id=%d pref=%d, size=%08x size_accum=%08x\n", id, pref, size, dma_info[id][pref].size_accum); assert(pref < MAX_DMA_IDS); dma_info[id][pref].size_accum += size; if(size == 0){ if (dma_trace) fprintf(stderr, "%s: id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, dma_info[id][pref].fd); dma_info[id][pref].buffer = (unsigned char *)mmap(0, dma_info[id][pref].size_accum, PROT_WRITE|PROT_WRITE|PROT_EXEC, MAP_SHARED, dma_info[id][pref].fd, 0); if (dma_info[id][pref].buffer == MAP_FAILED) { fprintf(stderr, "simDma_init Error: mmap failed fd %x buffer %p size %x errno %d\n", dma_info[id][pref].fd, dma_info[id][pref].buffer, size, errno); exit(-1); } dma_info[id][pref].buffer_len = dma_info[id][pref].size_accum; } if (dma_trace) fprintf(stderr, "simDma_init: done\n"); } extern "C" void simDma_idreturn(uint32_t aid) { uint32_t id = aid >> 16; uint32_t pref = aid & 0xffff; if (dma_trace) fprintf(stderr, "simDma_idreturn: aid=%08x id=%d pref=%d size=%08x\n", aid, id, pref, dma_info[id][pref].size_accum); assert(pref < MAX_DMA_IDS); int unmapped = munmap(dma_info[id][pref].buffer, dma_info[id][pref].size_accum); if (unmapped != 0) fprintf(stderr, "%s: failed to unmap id=%d pref=%d fd=%d\n", __FUNCTION__, id, pref, dma_info[id][pref].fd); memset(&dma_info[id][pref], 0, sizeof(dma_info[id][pref])); } ================================================ FILE: cpp/DmaBuffer.cpp ================================================ /* Copyright (c) 2016 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "DmaBuffer.h" DmaManager *DmaBuffer::mgr; void DmaBuffer::initDmaManager() { if (!mgr) mgr = platformInit(); } DmaBuffer::DmaBuffer(int size, bool cached) : size(size), cached(cached), ref(-1) { fd = portalAlloc(size, cached); buf = (char *)portalMmap(fd, size); if (1) { cacheInvalidate(size, 0); } } DmaBuffer::~DmaBuffer() { dereference(); portalMunmap(buf, size); close(fd); } uint32_t DmaBuffer::reference() { initDmaManager(); if (ref == -1) ref = mgr->reference(fd); return ref; } void DmaBuffer::dereference() { if (ref != -1 && mgr) mgr->dereference(ref); ref = -1; } void DmaBuffer::cacheInvalidate(int size, int flush) { #ifndef USE_ACP if (size == 0) size = this->size; if (cached) { portalCacheFlush(fd, buf, size, flush); } #else //fprintf(stderr, "cacheInvalidate skipped due to use of ACP\n"); #endif } ================================================ FILE: cpp/DmaBuffer.h ================================================ /* Copyright (c) 2016 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef _DMA_BUFFER_H_ #define _DMA_BUFFER_H_ #include "dmaManager.h" class DmaBuffer { const int size; const bool cached; int fd; char *buf; int ref; static DmaManager *mgr; static void initDmaManager(); public: // Allocates a portal memory object of specified size and maps it into user process DmaBuffer(int size, bool cached=true); // Dereferences and deallocates the portal memory object // if destructor is not called, the object is automatically // unreferenced and freed when the process exits ~DmaBuffer(); // returns the address of the mapped buffer char *buffer() { return buf; } // returns the reference to the object // // Sends the address translation table to hardware MMU if necessary. uint32_t reference(); // Removes the address translation table from the hardware MMU void dereference(); // invalidate and optionally flush from the dcache void cacheInvalidate(int size=0, int flush=0); }; #endif // _DMA_BUFFER_H_ ================================================ FILE: cpp/MMUServer.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "MMURequest.h" #include "MMUIndication.h" #define MAX_SERVER_AREAS 20 static int trace_mmuserver;// = 1; class MMUServer : public MMURequestWrapper { struct { int fd; void *ptr; int len; } memoryAreas[MAX_SERVER_AREAS]; int memoryAreasIndex; PortalInternal *ifcarr[MAX_SERVER_AREAS]; MMUIndicationProxy *mIndicationProxy; public: void sglist (const uint32_t sglId, const uint32_t sglIndex, const uint64_t addr, const uint32_t len ) { if (trace_mmuserver) fprintf(stderr, "daemon[%s:%d](%x, %x, %lx, %x)\n", __FUNCTION__, __LINE__, sglId, sglIndex, addr, len); memoryAreas[sglId].len += len; } void region (const uint32_t sglId, const uint64_t barr12, const uint32_t index12, const uint64_t barr8, const uint32_t index8, const uint64_t barr4, const uint32_t index4, const uint64_t barr0, const uint32_t index0 ) { memoryAreas[sglId].ptr = portalMmap(memoryAreas[sglId].fd, memoryAreas[sglId].len); //if (trace_mmuserver) fprintf(stderr, "daemon[%s:%d] fd %d ptr %p len %x\n", __FUNCTION__, __LINE__, memoryAreas[sglId].fd, memoryAreas[sglId].ptr, memoryAreas[sglId].len); mIndicationProxy->configResp(0); } void idRequest(SpecialTypeForSendingFd fd) { memoryAreas[memoryAreasIndex].fd = fd; memoryAreas[memoryAreasIndex].ptr = NULL; memoryAreas[memoryAreasIndex].len = 0; //if (trace_mmuserver) fprintf(stderr, "daemon[%s:%d] fd %d\n", __FUNCTION__, __LINE__, fd); if (fd <= 0) { fprintf(stderr, "[%s:%d] bogus fd value %d\n", __FUNCTION__, __LINE__, fd); exit(1); } mIndicationProxy->idResponse(memoryAreasIndex++); } void setInterface(uint32_t interfaceId, uint32_t sglId) { if (trace_mmuserver) fprintf(stderr, "[%s:%d] ifc %d sgl %d\n", __FUNCTION__, __LINE__, interfaceId, sglId); ifcarr[interfaceId]->map_base = (volatile unsigned int *)memoryAreas[sglId].ptr; } void idReturn (const uint32_t sglId ) { if (trace_mmuserver) fprintf(stderr, "daemon[%s:%d] sglId %d\n", __FUNCTION__, __LINE__, sglId); } void *getPtr (const uint32_t sglId ) { return memoryAreas[sglId].ptr; } void registerInterface(uint32_t interfaceId, PortalInternal *p) { ifcarr[interfaceId] = p; } MMUServer(unsigned int id, MMUIndicationProxy *mind, PortalTransportFunctions *transport, void *param) : MMURequestWrapper(id, transport, param), memoryAreasIndex(1), mIndicationProxy(mind) {} }; ================================================ FILE: cpp/TlpReplay.cpp ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include #include #include #include #include static bool loaded = false; uint8_t *tlp_packets = NULL; uint8_t cvt(char c) { if (c >= 'a') return c-'a'+0xA; if (c >= 'A') return c-'A'+0xA; return c-'0'; } void load_tlp() { if(!loaded){ fprintf(stderr, "about to load tlp.log\n"); int tlp_file = open("tlp.log", O_RDONLY); struct stat fileStat; assert(fstat(tlp_file,&fileStat) >= 0); tlp_packets = (uint8_t*)malloc(fileStat.st_size); std::ifstream infile("tlp.log"); std::string line; unsigned char *tlpp = tlp_packets; // skip over the first 8 characters in each // line as they correspond to the timestamp while (std::getline(infile, line)){ for(int i = 0; i < 40; i+=2) { uint8_t high = cvt(line[8+i+0]); uint8_t low = cvt(line[8+i+1]); *tlpp = (high<<4)|low; tlpp++; } } loaded = true; fprintf(stderr, "loaded tlp.log successfully\n"); } } uint8_t portnum() { return *tlp_packets >> 1; } extern "C" { bool can_put_tlp() { load_tlp(); return portnum() == 8; } bool can_get_tlp() { load_tlp(); return portnum() == 4; } void put_tlp(unsigned int* tlp) { assert(loaded); tlp_packets += 20; } void get_tlp(unsigned int* tlp) { assert(loaded); // fprintf(stderr, " "); // for(int i = i; i < 20; i++) // fprintf(stderr, "%02x", tlp_packets[i]); // fprintf(stderr, "\n"); // byte-swapping for bsim compatability for(int i = 0; i < 20; i++){ ((uint8_t*)tlp)[19-i] = tlp_packets[i]; } tlp_packets += 20; } } ================================================ FILE: cpp/XsimTop.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include static int trace_xsimtop; // = 1; class XsimMsgRequest : public XsimMsgRequestWrapper { pthread_mutex_t mutex; std::queue sinkbeats[16]; public: XsimMsgRequest(int id, PortalTransportFunctions *item, void *param, PortalPoller *poller = 0):XsimMsgRequestWrapper(id, item, param, poller){ pthread_mutex_init(&mutex, 0); } ~XsimMsgRequest() { pthread_mutex_destroy(&mutex); } void msgSink ( const uint32_t portal, const uint32_t data ) { if (trace_xsimtop) fprintf(stderr, "XsimRX: portal %d data=%08x\n", portal, data); pthread_mutex_lock(&mutex); sinkbeats[portal].push(data); pthread_mutex_unlock(&mutex); } void msgSinkFd ( const uint32_t portal, const uint32_t data ) { if (trace_xsimtop) fprintf(stderr, "XsimRXFD: portal %d data=%08x\n", portal, data); pthread_mutex_lock(&mutex); sinkbeats[portal].push(data); pthread_mutex_unlock(&mutex); } bool notEmpty(int portal) { pthread_mutex_lock(&mutex); bool notEmpty = sinkbeats[portal].size() > 0; pthread_mutex_unlock(&mutex); return notEmpty; } uint32_t get(int portal) { pthread_mutex_lock(&mutex); uint32_t data = sinkbeats[portal].front(); sinkbeats[portal].pop(); pthread_mutex_unlock(&mutex); return data; } }; static Portal *mcommon; static XsimMsgIndicationProxy *xsimIndicationProxy; static XsimMsgRequest *xsimRequest; static int finish = 0; static int xsim_disconnect(struct PortalInternal *pint) { fprintf(stderr, "%s:%d pint=%p calling $finish\n", __FUNCTION__, __LINE__, pint); finish = 1; return 0; } static PortalHandlerTemplate xsim_handler = { xsim_disconnect }; long cycleCount; extern "C" int dpi_cycle() { cycleCount++; return finish; } double sc_time_stamp() { return (double)cycleCount; } extern "C" void dpi_init() { if (trace_xsimtop) fprintf(stderr, "%s:%d &xsim_handler=%p\n", __FUNCTION__, __LINE__, &xsim_handler); #ifdef POLL_IN_DPI_POLL defaultPoller->stop(); #endif mcommon = new Portal(0, 0, sizeof(uint32_t), portal_mux_handler, &xsim_handler, &transportSocketResp, NULL, NULL); PortalMuxParam param = {}; param.pint = &mcommon->pint; xsimIndicationProxy = new XsimMsgIndicationProxy(XsimIfcNames_XsimMsgIndication, &transportMux, ¶m); xsimRequest = new XsimMsgRequest(XsimIfcNames_XsimMsgRequest, &transportMux, ¶m); if (trace_xsimtop) fprintf(stderr, "%s: end\n", __FUNCTION__); } #ifdef POLL_IN_DPI_POLL extern "C" void dpi_poll() { void *rc = defaultPoller->pollFn(1); //fprintf(stderr, "%s:%d: rc=%ld\n", __FUNCTION__, __LINE__, (long)rc); if ((long)rc > 0) defaultPoller->event(); } #endif extern "C" long long dpi_msgSink_beat(int portal) { long long result = 0xbadad7a; //if (trace_xsimtop) fprintf(stderr, "%s: portal %d rdy %d\n", __FUNCTION__, portal, (int)xsimRequest->sinkbeats[portal].size()); if (xsimRequest->notEmpty(portal)) { uint32_t beat = xsimRequest->get(portal); if (trace_xsimtop) fprintf(stderr, "%s: portal %d beat %08x\n", __FUNCTION__, portal, beat); result = (1ll << 32) | beat; } return result; } extern "C" void dpi_msgSource_beat(int portal, int beat) { if (trace_xsimtop) fprintf(stderr, "dpi_msgSource_beat: portal %d beat=%08x\n", portal, beat); xsimIndicationProxy->msgSource(portal, beat); } ================================================ FILE: cpp/XsimTop.h ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef _XsimTop_h #define _XsimTop_h extern "C" void dpi_init(); extern "C" int dpi_cycle(); #endif ================================================ FILE: cpp/bluesim_main.cxx ================================================ // Copyright (c) 2016 Bluespec, Inc. All Rights Reserved. // This is a boilerplate 'main' to drive a Bluesim executable without // using the BlueTcl top-level that bsc normally generates. // Example: // Suppose your top-level BSV file is Foo.bsv, with top-level module mkFoo // Compile and link the top-level BSV as usual, e.g.,: // bsc -sim -u Foo.bsv // bsc -sim -e mkFoo // This will produce the usual Bluetcl-based executable (a.out and a.out.so) // but it will also produce: // mkFoo.{h,cxx,o} // model_mkFoo.{h,cxx,o} // (and of course similar files for any other imported BSV modules) // Then, compile and link this file with those .o's, like this Makefile target // // CXXFAMILY=g++4 // for 32-bit platforms // CXXFAMILY=g++4_64 // for 64-bit platforms // // $(EXE): model_$(TOPMOD).o $(TOPMOD).o // c++ -O3 \ // bluesim_main.cxx \ // This file // -o $@ \ // Your final executable // -I. \ // bsc-generated .h files, project .h files // -I$(BLUESPECDIR)/Bluesim \ // Dir for Bluespec release .h files // -L$(BLUESPECDIR)/Bluesim/$(CXXFAMILY) \ // Dir Bluespec release libs // $^ \ // all your .o's // -lbskernel -lbsprim -lpthread // libs #include #include #include #include #include "bluesim_kernel_api.h" // #include MODEL_MKFOO_H #include "model_mkXsimTop.h" // ================================================================ // Process command line args static char default_vcd_filename [] = "dump.vcd"; static char *vcd_filename = NULL; // Valid if not NULL static tUInt64 count = 0; // Valid if positive static void process_command_line_args (int argc, char *argv []) { // Check for -h (help) for (int j = 0; j < argc; j++) { if (strcmp (argv [j], "-h") == 0) { fprintf (stderr, "Usage: %s [opts]\n", argv [0]); fprintf (stderr, "Options:\n"); fprintf (stderr, " -h = print help and exit\n"); fprintf (stderr, " -m = execute for N cycles\n"); fprintf (stderr, " -V [] = dump waveforms to VCD file (default: dump.vcd)\n"); fprintf (stderr, "\n"); fprintf (stderr, "Examples:\n"); fprintf (stderr, " %s\n", argv [0]); fprintf (stderr, " %s -m 3000\n", argv [0]); fprintf (stderr, " %s -V sim.vcd\n", argv [0]); exit (1); } } // Check for -V or -V vcd_filename in command-line args for (int j = 0; j < argc; j++) { if (strcmp (argv [j], "-V") == 0) { if (j == (argc - 1)) vcd_filename = & (default_vcd_filename [0]); else if (argv [j+1][0] != '-') vcd_filename = argv [j+1]; break; } } // Check for -m flag (execute for N cycles) long int n = -1; for (int j = 0; j < argc; j++) { if (strcmp (argv [j], "-m") == 0) { if (j == (argc - 1)) { fprintf (stderr, "Command-line error: -m flag must be followed by a positive integer\n"); exit (1); } errno = 0; n = strtol (argv [j+1], NULL, 0); if ((errno != 0) || (n < 1)) { fprintf (stderr, "Command-line error: -m flag must be followed by a positive integer\n"); exit (1); } count = n; break; } } } // ================================================================ int main (int argc, char *argv[]) { process_command_line_args (argc, argv); // tModel model = NEW_MODEL_MKFOO (); tModel model = new_MODEL_mkXsimTop(); #ifdef BSC_OBSOLETE tSimStateHdl sim = bk_init (model, true, false); #else tSimStateHdl sim = bk_init (model, true); #endif if (vcd_filename != NULL) { tStatus status = bk_set_VCD_file (sim, vcd_filename); if (status == BK_ERROR) { fprintf (stderr, "Error: Could not open file for VCD output: %s\n", vcd_filename); exit (1); } tBool b = bk_enable_VCD_dumping (sim); if (b == 0) { fprintf (stderr, "Error: Could not enable VCD dumping in file: %s\n", vcd_filename); exit (1); } fprintf (stdout, "Enabled VCD dumping to file %s\n", vcd_filename); } if (count > 0) { tClock clk = 0; tEdgeDirection dir = POSEDGE; bk_quit_after_edge (sim, clk, dir, count); fprintf (stdout, "Will stop after %0lld clocks\n", count); } bk_advance (sim, false); bk_shutdown (sim); if (count > 0) { fprintf (stdout, "Stopped after %0lld clocks\n", count); } } ================================================ FILE: cpp/bsim_relay.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include "sock_utils.h" #include "portal.h" static void memdump(unsigned char *p, int len, char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) fprintf(stderr, "\n"); fprintf(stderr, "%s: ",title); } fprintf(stderr, "%02x ", *p++); i++; len--; } fprintf(stderr, "\n"); } static char devicename[1000]; int main(int argc, char *argv[]) { struct memrequest req; static PortalInternal pint; int rc; char *bashpid = getenv("CONNECTAL_MODULE_NAME"); if (!bashpid) { fprintf(stderr, "bsim_relay: define environment variable CONNECTAL_MODULE_NAME\n"); return -1; } sprintf(devicename, "/dev/%s", bashpid); int fd = open(devicename, O_RDWR); if (fd == -1) { fprintf(stderr, "bsimhost: '%s' not found\n", devicename); return -1; } fprintf(stderr, "[%s:%d] trying to connect to bsim\n", __FUNCTION__, __LINE__); connect_to_bsim(); fprintf(stderr, "[%s:%d] opened bsim\n", __FUNCTION__, __LINE__); while ((rc = read(fd, &req, sizeof(req)))) { struct memresponse rv; if (rc == -1) { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000; select(0, NULL, NULL, NULL, &timeout); continue; } if (rc != sizeof(req)) { fprintf(stderr, "[%s:%d] rc = %d.\n", __FUNCTION__, __LINE__, rc); memdump((unsigned char *)&req, sizeof(req), "RX"); } rv.portal = req.portal; pint.fpga_number = req.portal; if (req.portal == MAGIC_PORTAL_FOR_SENDING_FD) { fprintf(stderr, "[%s:%d] sending fd %d\n", __FUNCTION__, __LINE__, req.data_or_tag); transportBsim.writefd(&pint, &req.addr, req.data_or_tag); rv.data = 0xdead; write(fd, &rv, sizeof(rv)); } else if (req.write_flag) transportBsim.write(&pint, &req.addr, req.data_or_tag); else { rv.data = transportBsim.read(&pint, &req.addr); write(fd, &rv, sizeof(rv)); } } return 0; } ================================================ FILE: cpp/dmaManager.c ================================================ // Copyright (c) 2013,2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "dmaManager.h" #ifndef __KERNEL__ #include #include #include #ifdef ZYNQ #include "drivers/zynqportal/zynqportal.h" #else #include "drivers/pcieportal/pcieportal.h" #endif #endif #if defined(SIMULATION) #include "dmaSendFd.h" #endif #include "GeneratedTypes.h" #ifndef __KERNEL__ static pthread_mutex_t dma_mutex; pthread_once_t mutex_once = PTHREAD_ONCE_INIT; static void dmaManagerOnce(void) { fprintf(stderr, "[%s:%d]\n", __FUNCTION__, __LINE__); pthread_mutex_init(&dma_mutex, 0); } #endif void DmaManager_init(DmaManagerPrivate *priv, PortalInternal *sglDevice) { memset(priv, 0, sizeof(*priv)); priv->sglDevice = sglDevice; #ifndef __KERNEL__ pthread_once(&mutex_once, dmaManagerOnce); #endif initPortalMemory(); if (sem_init(&priv->sglIdSem, 0, 0)){ PORTAL_PRINTF("failed to init sglIdSem\n"); } if (sem_init(&priv->confSem, 0, 0)){ PORTAL_PRINTF("failed to init confSem\n"); } } void DmaManager_dereference(DmaManagerPrivate *priv, int ref) { #if !defined(SIMULATION) && !defined(__KERNEL__) pthread_mutex_lock(&dma_mutex); #ifdef ZYNQ int rc = ioctl(priv->sglDevice->fpga_fd, PORTAL_DEREFERENCE, ref); #else int rc = ioctl(priv->sglDevice->fpga_fd, PCIE_DEREFERENCE, ref); #endif pthread_mutex_unlock(&dma_mutex); if (rc != 0) fprintf(stderr, "[%s:%d] dereference ioctl error %d\n", __FUNCTION__, __LINE__, errno); #else MMURequest_idReturn(priv->sglDevice, ref); #endif } int DmaManager_reference(DmaManagerPrivate *priv, int fd) { int id = 0; int rc = 0; pthread_mutex_lock(&dma_mutex); initPortalMemory(); MMURequest_idRequest(priv->sglDevice, (SpecialTypeForSendingFd)fd); if (priv->poll) { int rc = priv->poll(priv->shared_mmu_indication, &priv->sglId); fprintf(stderr, "[%s:%d] return after idrequest %d %d\n", __FUNCTION__, __LINE__, rc, priv->sglId); } else sem_wait(&priv->sglIdSem); id = priv->sglId; #if !defined(SIMULATION) && !defined(__KERNEL__) #ifdef ZYNQ PortalSendFd sendFd; sendFd.fd = fd; sendFd.id = id; rc = ioctl(priv->sglDevice->fpga_fd, PORTAL_SEND_FD, &sendFd); #else tSendFd sendFd; sendFd.fd = fd; sendFd.id = id; rc = ioctl(priv->sglDevice->fpga_fd, PCIE_SEND_FD, &sendFd); #endif if (!rc) { if (priv->poll) { uint32_t ret; int rc = priv->poll(priv->shared_mmu_indication, &ret); fprintf(stderr, "[%s:%d] return after ioctl %d %d\n", __FUNCTION__, __LINE__, rc, ret); } else sem_wait(&priv->confSem); } rc = id; #else // defined(SIMULATION) || defined(__KERNEL__) rc = send_fd_to_portal(priv->sglDevice, fd, id, global_pa_fd); if (rc >= 0) { //PORTAL_PRINTF("%s:%d sem_wait\n", __FUNCTION__, __LINE__); if (priv->poll) { uint32_t ret; int rc = priv->poll(priv->shared_mmu_indication, &ret); fprintf(stderr, "[%s:%d] return after sendfd %d %d\n", __FUNCTION__, __LINE__, rc, ret); } else sem_wait(&priv->confSem); } #endif // defined(SIMULATION) || defined(__KERNEL__) pthread_mutex_unlock(&dma_mutex); return rc; } void DmaManager_idresp(DmaManagerPrivate *priv, uint32_t sglId) { priv->sglId = sglId; #ifndef __KERNEL__ sem_post(&priv->sglIdSem); #endif } void DmaManager_confresp(DmaManagerPrivate *priv, uint32_t channelId) { #ifndef __KERNEL__ //fprintf(stderr, "configResp %d\n", channelId); sem_post(&priv->confSem); #endif } ================================================ FILE: cpp/dmaManager.h ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef _PORTAL_MEMORY_H_ #define _PORTAL_MEMORY_H_ #include "ConnectalProjectConfig.h" #ifdef __KERNEL__ #include #include #include #define sem_wait(A) down_interruptible(A) #define sem_post(A) up(A) #define sem_init(A, B, C) (sema_init ((A), (C)), 0) typedef struct semaphore sem_t; #include #include #define PORTAL_MALLOC(A) vmalloc(A) #define PORTAL_FREE(A) vfree(A) #else #include #include #include #define PORTAL_MALLOC(A) malloc(A) #define PORTAL_FREE(A) free(A) #endif #include "portal.h" typedef struct { sem_t confSem; sem_t sglIdSem; #ifndef __KERNEL__ pthread_mutex_t mutex; #endif uint32_t sglId; PortalInternal *sglDevice; int pa_fd; SHARED_MMUINDICATION_POLL poll; PortalInternal *shared_mmu_indication; } DmaManagerPrivate; #ifdef __cplusplus extern "C" { #endif void DmaManager_init(DmaManagerPrivate *priv, PortalInternal *sglDevice); int DmaManager_reference(DmaManagerPrivate *priv, int fd); void DmaManager_dereference(DmaManagerPrivate *priv, int ref); void DmaManager_idresp(DmaManagerPrivate *priv, uint32_t sglId); void DmaManager_confresp(DmaManagerPrivate *priv, uint32_t channelId); #ifdef __cplusplus } #endif #ifndef NO_CPP_PORTAL_CODE #ifdef __cplusplus #include "GeneratedTypes.h" //ChannelType!! class DmaManager { public: DmaManagerPrivate priv; DmaManager(Portal *sglDevice) { DmaManager_init(&priv, &sglDevice->pint); }; int reference(int fd) { return DmaManager_reference(&priv, fd); }; void dereference(int ref){ DmaManager_dereference(&priv, ref); } void sglIdResp(uint32_t sglId) { DmaManager_idresp(&priv, sglId); } void confResp(uint32_t channelId) { DmaManager_confresp(&priv, channelId); }; }; extern "C" DmaManager *platformInit(void); extern "C" void platformStatistics(void); #else struct DmaManager { DmaManagerPrivate priv; }; typedef struct DmaManager DmaManager; DmaManager *platformInit(void); void platformStatistics(void); #endif #endif #endif // _PORTAL_MEMORY_H_ ================================================ FILE: cpp/dmaSendFd.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #define PAGE_SHIFT0 12 #define PAGE_SHIFT4 16 #define PAGE_SHIFT8 20 #define PAGE_SHIFT12 24 #define NUM_SHIFTS 4 static int shifts[NUM_SHIFTS+1] = {PAGE_SHIFT12, PAGE_SHIFT8, PAGE_SHIFT4, PAGE_SHIFT0, 0 /* needed for border computation */}; #include "drivers/portalmem/portalmem.h" // PortalAlloc #ifdef CONNECTAL_DRIVER_CODE #define NO_WRAPPER_FUNCTIONS #include "MMURequest.c" #endif static int trace_memory = 0; #include "GeneratedTypes.h" // generated in project directory #ifdef SIMULATION // indexed by fd extern int portalmem_sizes[1024]; #endif int send_fd_to_portal(PortalInternal *device, int fd, int id, int pa_fd) { int rc = 0; int i, j; uint32_t regions[4] = {0,0,0,0}; uint64_t border = 0; unsigned char entryCount = 0; uint64_t borderVal[4]; uint32_t indexVal[4]; unsigned char idxOffset; #if defined(SIMULATION) int size_accum = 0; #endif #ifdef __KERNEL__ struct scatterlist *sg; struct file *fmem; struct sg_table *sgtable; fmem = fget(fd); sgtable = ((struct pa_buffer *)((struct dma_buf *)fmem->private_data)->priv)->sg_table; #elif !defined(SIMULATION) #error #endif rc = id; #ifdef __KERNEL__ for_each_sg(sgtable->sgl, sg, sgtable->nents, i) { long addr = sg_phys(sg); long len = sg->length; #elif defined(SIMULATION) long object_len = portalmem_sizes[fd]; object_len = ((object_len + 4095) & ~4095l); for (i = 0; object_len > 0; i++) { long addr = size_accum; long len = object_len; if ((unsigned int)fd > sizeof(portalmem_sizes)/sizeof(portalmem_sizes[0])) goto retlab; if (!len) break; for (j = 0; (unsigned)j < NUM_SHIFTS; j++) { long size = 1 << shifts[j]; if (object_len >= size) { len = size; break; } } //fprintf(stderr, "%s:%d i=%d fd=%d object_len=%ld len=%ld\n", __FUNCTION__, __LINE__, i, fd, object_len, len); size_accum += len; object_len -= len; addr |= ((long)id) << 32; //[39:32] = truncate(pref); #elif !defined(SIMULATION) #error #endif for(j = 0; j < NUM_SHIFTS; j++) if (len == 1<>= shifts[j]; break; } if (j >= 4) PORTAL_PRINTF("DmaManager:unsupported sglist size %lx\n", len); if (trace_memory) PORTAL_PRINTF("DmaManager:sglist(id=%08x, i=%d dma_addr=%08lx, len=%08lx)\n", id, i, (long)addr, len); MMURequest_sglist(device, id, i, addr, len); } // balance } #ifdef __KERNEL__ fput(fmem); #endif // HW interprets zeros as end of sglist if (trace_memory) PORTAL_PRINTF("DmaManager:sglist(id=%08x, i=%d end of list)\n", id, i); MMURequest_sglist(device, id, i, 0, 0); // end list for(i = 0; i < 4; i++){ idxOffset = entryCount - border; entryCount += regions[i]; border += regions[i]; borderVal[i] = border; indexVal[i] = idxOffset; border <<= (shifts[i] - shifts[i+1]); } if (trace_memory) { PORTAL_PRINTF("regions %d (%x %x %x %x)\n", id, regions[0], regions[1], regions[2], regions[3]); PORTAL_PRINTF("borders %d (%" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 ")\n", id,borderVal[0], borderVal[1], borderVal[2], borderVal[3]); } MMURequest_region(device, id, borderVal[0], indexVal[0], borderVal[1], indexVal[1], borderVal[2], indexVal[2], borderVal[3], indexVal[3]); /* ifdefs here to supress warning during kernel build */ #ifndef __KERNEL__ retlab: #endif return rc; } ================================================ FILE: cpp/kernel_module.c ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. /* * This is a test harness for running connectal test programs as kernel modules. * * After the module is loaded, it calls 'main(0, NULL)' to start the program. */ #include #include #include #include #include #include "portal.h" // pthread_t extern int main(int argc, char *argv[]); int bsim_relay_running; struct semaphore bsim_start; DECLARE_COMPLETION(main_completion); int pthread_create(pthread_t *thread, void *attr, void *(*start_routine) (void *), void *arg) { if (!(*thread = kthread_run ((int (*)(void *))start_routine, arg, "pthread_worker"))) { printk ("pthread_create: kthread_run failed"); } return 0; } void memdump(unsigned char *p, int len, char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printk("\n"); printk("%s: ",title); } printk("%02x ", *p++); i++; len--; } printk("\n"); } /* in sock_utils.c */ ssize_t connectal_kernel_read (struct file *f, char __user *arg, size_t len, loff_t *data); ssize_t connectal_kernel_write (struct file *f, const char __user *arg, size_t len, loff_t *data); int main_program_finished = 0; static struct file_operations pa_fops = { .owner = THIS_MODULE, #if defined(SIMULATION) .read = connectal_kernel_read, .write = connectal_kernel_write, #endif }; static struct miscdevice miscdev = { .minor = MISC_DYNAMIC_MINOR, // Must be < 256! .name = "connectal_unknown", .fops = &pa_fops, .mode = S_IRUGO | S_IWUGO, }; void *main_start(void *arg) { main(0, NULL); /* start the test program */ printk("TestProgram::main program finished\n"); complete(&main_completion); main_program_finished = 1; return NULL; } static int __init pa_init(void) { pthread_t pid; printk("TestProgram::pa_init minor %d thisname %s\n", miscdev.minor, THIS_MODULE->name); miscdev.name = THIS_MODULE->name; misc_register(&miscdev); sema_init (&bsim_start, 0); pthread_create(&pid, NULL, main_start, NULL); return 0; } static void __exit pa_exit(void) { printk("TestProgram::pa_exit %s\n", THIS_MODULE->name); #ifdef SIMULATION if (!bsim_relay_running) { printk("TestProgram::pa_exit terminate main program\n"); main_program_finished = 1; up(&bsim_start); // in case host never starts } else #endif wait_for_completion(&main_completion); misc_deregister(&miscdev); } module_init(pa_init); module_exit(pa_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("connectal test program"); MODULE_VERSION("0.1"); ================================================ FILE: cpp/manualMMUIndication.h ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "dmaManager.h" #include "MMUIndication.h" static int return_code; static uint32_t return_id; enum {ManualMMU_None, ManualMMU_IdResponse, ManualMMU_ConfigResp, ManualMMU_Error}; static int manualDisconnect(struct PortalInternal *p) { return 0; } static int manualIdResponse(struct PortalInternal *p, const uint32_t sglId ) { return_id = sglId; return_code = ManualMMU_IdResponse; return 0; } static int manualConfigResp(struct PortalInternal *p, const uint32_t sglId ) { return_id = sglId; return_code = ManualMMU_ConfigResp; return 0; } static int manualError(struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ) { return_code = ManualMMU_Error; return 0; } static MMUIndicationCb manualMMU_Cb = {manualDisconnect, manualIdResponse, manualConfigResp, manualError}; static int manualWaitForResp(PortalInternal *p, uint32_t *arg_id) { return_code = ManualMMU_None; printf("[%s:%d]\n", __FUNCTION__, __LINE__); while(return_code == ManualMMU_None) { p->transport->event(p); } printf("[%s:%d]\n", __FUNCTION__, __LINE__); *arg_id = return_id; return return_code; } ================================================ FILE: cpp/monkit.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef _MONKIT_H_ #define _MONKIT_H_ #include #include #include // strerrror class MonkitFile { public: MonkitFile(const char *name) : name(name), hw_cycles(1), sw_cycles(0), hw_read_bw_util(0), hw_write_bw_util(0) {} ~MonkitFile() {} MonkitFile &setHwCycles(float cycles) { this->hw_cycles = cycles; return *this; } MonkitFile &setSwCycles(float cycles) { this->sw_cycles = cycles; return *this; } MonkitFile &setReadBwUtil(float u) { this->hw_read_bw_util = u; return *this; } MonkitFile &setWriteBwUtil(float u) { this->hw_write_bw_util = u; return *this; } void writeFile(); private: const char *name; float hw_cycles; float sw_cycles; float hw_read_bw_util; float hw_write_bw_util; }; #define monkit "\n\ \n\ \n\ \n\ %f\n\ %f\n\ \n\ \n\ \n\ \n\ \n\ %f\n\ %f\n\ \n\ \n\ \n\ \n\ %f\n\ \n\ \n\ \n" void MonkitFile::writeFile() { float hw_speedup = sw_cycles/hw_cycles; FILE *out = fopen(name, "w"); if (out) { fprintf(out, monkit, hw_cycles, sw_cycles, hw_read_bw_util, hw_write_bw_util, hw_speedup); fclose(out); } else { fprintf(stderr, "Failed to open MonkitFile %s errno=%d:%s\n", name, errno, strerror(errno)); } } #endif ================================================ FILE: cpp/platformMemory.cpp ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include "dmaManager.h" #include "MMURequest.h" #include "MMUIndication.h" #include "MemServerRequest.h" #include "MemServerIndication.h" #define PLATFORM_TILE 0 class PortalPoller; int mmu_error_limit = 20; int mem_error_limit = 20; const char *dmaErrors[] = { "None", "SGL Id out of range for read", "SGL Id out of range for write", "MMU out of range for read", "MMU out of range for write", "Offset out of range", "SGL Id invalid", "Tile tag out of range" }; class MMUIndication : public MMUIndicationWrapper { DmaManager *portalMemory; public: MMUIndication(DmaManager *pm, unsigned int id, int tile=PLATFORM_TILE) : MMUIndicationWrapper(id,tile), portalMemory(pm) {} MMUIndication(DmaManager *pm, unsigned int id, PortalTransportFunctions *item, void *param) : MMUIndicationWrapper(id, item, param), portalMemory(pm) {} virtual void configResp(uint32_t pointer){ portalMemory->confResp(pointer); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MMUIndication::error(code=0x%x:%s, pointer=0x%x, offset=0x%" PRIx64 " extra=0x%" PRIx64 "\n", code, dmaErrors[code], pointer, offset, extra); if (--mmu_error_limit < 0) exit(-1); } virtual void idResponse(uint32_t sglId){ portalMemory->sglIdResp(sglId); } }; class MemServerIndication : public MemServerIndicationWrapper { MemServerRequestProxy *memServerRequestProxy; sem_t mtSem; uint64_t mtCnt; void init(){ if (sem_init(&mtSem, 0, 0)) PORTAL_PRINTF("MemServerIndication::init failed to init mtSem\n"); } public: MemServerIndication(unsigned int id, int tile=PLATFORM_TILE) : MemServerIndicationWrapper(id,tile), memServerRequestProxy(NULL) {init();} MemServerIndication(MemServerRequestProxy *p, unsigned int id, int tile=PLATFORM_TILE) : MemServerIndicationWrapper(id,tile), memServerRequestProxy(p) {init();} virtual void addrResponse(uint64_t physAddr){ fprintf(stderr, "DmaIndication::addrResponse(physAddr=%" PRIx64 ")\n", physAddr); } virtual void reportStateDbg(const DmaDbgRec rec){ fprintf(stderr, "MemServerIndication::reportStateDbg: {x:%08x y:%08x z:%08x w:%08x}\n", rec.x,rec.y,rec.z,rec.w); } virtual void reportMemoryTraffic(uint64_t words){ //fprintf(stderr, "reportMemoryTraffic: words=%" PRIx64 "\n", words); mtCnt = words; sem_post(&mtSem); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MemServerIndication::error(code=%x:%s, pointer=%x, offset=%" PRIx64 " extra=%" PRIx64 "\n", code, dmaErrors[code], pointer, offset, extra); if (--mem_error_limit < 0) exit(-1); } uint64_t receiveMemoryTraffic(){ sem_wait(&mtSem); return mtCnt; } uint64_t getMemoryTraffic(const ChannelType rc){ assert(memServerRequestProxy); memServerRequestProxy->memoryTraffic(rc); return receiveMemoryTraffic(); } }; static MemServerRequestProxy *hostMemServerRequest; static MemServerIndication *hostMemServerIndication; static MMUIndication *mmuIndication; static DmaManager *dma; static pthread_once_t once_control = PTHREAD_ONCE_INIT; void platformInitOnce(void) { hostMemServerRequest = new MemServerRequestProxy(PlatformIfcNames_MemServerRequestS2H, PLATFORM_TILE); MMURequestProxy *dmap = new MMURequestProxy(PlatformIfcNames_MMURequestS2H, PLATFORM_TILE); dma = new DmaManager(dmap); hostMemServerIndication = new MemServerIndication(hostMemServerRequest, PlatformIfcNames_MemServerIndicationH2S, PLATFORM_TILE); mmuIndication = new MMUIndication(dma, PlatformIfcNames_MMUIndicationH2S, PLATFORM_TILE); #ifdef MainClockPeriod long req_freq = (long)(1e9 / MainClockPeriod); long freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); #endif } DmaManager *platformInit(void) { pthread_once(&once_control, platformInitOnce); return dma; } void platformStatistics(void) { uint64_t cycles = portalTimerLap(0); hostMemServerRequest->memoryTraffic(ChannelType_Read); uint64_t read_beats = hostMemServerIndication->receiveMemoryTraffic(); float read_util = (float)read_beats/(float)cycles; hostMemServerRequest->memoryTraffic(ChannelType_Write); uint64_t write_beats = hostMemServerIndication->receiveMemoryTraffic(); float write_util = (float)write_beats/(float)cycles; fprintf(stderr, " read_beats: %lld\n", (long long)read_beats); fprintf(stderr, " write_beats: %lld\n", (long long)write_beats); fprintf(stderr, " cycles: %lld\n", (long long)cycles); fprintf(stderr, "memory utilization (beats/cycle): read %f write %f\n", read_util, write_util); } ================================================ FILE: cpp/poller.cpp ================================================ // Copyright (c) 2012 Nokia, Inc. // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #include "sock_utils.h" #include #include #include #include #include static int trace_poller;//=1; #ifndef NO_CPP_PORTAL_CODE PortalPoller *defaultPoller = new PortalPoller(); uint64_t poll_enter_time, poll_return_time; // for performance measurement PortalPoller::PortalPoller(int autostart) : startThread(autostart), numWrappers(0), numFds(0), inPoll(0), stopping(0) { memset(portal_fds, 0, sizeof(portal_fds)); memset(portal_wrappers, 0, sizeof(portal_wrappers)); int rc = pipe(pipefd); if (rc != 0) fprintf(stderr, "[%s:%d] pipe error %d:%s\n", __FUNCTION__, __LINE__, errno, strerror(errno)); sem_init(&sem_startup, 0, 0); pthread_mutex_init(&mutex, NULL); fcntl(pipefd[0], F_SETFL, O_NONBLOCK); addFd(pipefd[0]); timeout = -1; // wait for interrupt #if defined(SIMULATION) timeout = 100; #endif if (getenv("PORTAL_TIMEOUT") != 0) { timeout = strtoul(getenv("PORTAL_TIMEOUT"), 0, 0); } } int PortalPoller::unregisterInstance(Portal *portal) { int i = 0; pthread_mutex_lock(&mutex); while(i < numWrappers){ if(portal_wrappers[i]->pint.fpga_number == portal->pint.fpga_number) { //fprintf(stderr, "PortalPoller::unregisterInstance %d %d\n", i, portal->pint.fpga_number); break; } i++; } while(i < numWrappers-1){ portal_wrappers[i] = portal_wrappers[i+1]; i++; } numWrappers--; i = 0; while(i < numFds){ if(portal_fds[i].fd == portal->pint.fpga_fd) break; i++; } while(i < numFds-1){ portal_fds[i] = portal_fds[i+1]; i++; } numFds--; pthread_mutex_unlock(&mutex); return 0; } void PortalPoller::addFd(int fd) { /* this internal function assumes mutex locked by caller. * since it can be called from addFdToPoller(), which was called under mutex lock * event(). */ numFds++; struct pollfd *pollfd = &portal_fds[numFds-1]; memset(pollfd, 0, sizeof(struct pollfd)); pollfd->fd = fd; pollfd->events = POLLIN; } int PortalPoller::registerInstance(Portal *portal) { uint8_t ch = 0; pthread_mutex_lock(&mutex); int rc = write(pipefd[1], &ch, 1); // get poll to return, so that it will try again with the new file descriptor if (rc < 0) fprintf(stderr, "[%s:%d] write error %d\n", __FUNCTION__, __LINE__, errno); numWrappers++; if (trace_poller) fprintf(stderr, "Poller: registerInstance fpga%d fd %d clients %d\n", portal->pint.fpga_number, portal->pint.fpga_fd, portal->pint.client_fd_number); while(inPoll) usleep(1000); portal_wrappers[numWrappers-1] = portal; if (portal->pint.fpga_fd != -1) addFd(portal->pint.fpga_fd); for (int i = 0; i < portal->pint.client_fd_number; i++) addFd(portal->pint.client_fd[i]); portal->pint.transport->enableint(&portal->pint, 1); pthread_mutex_unlock(&mutex); start(); return 0; } void* PortalPoller::init(void) { #ifdef SIMULATION if (global_sockfd != -1) { pthread_mutex_lock(&mutex); addFd(global_sockfd); pthread_mutex_unlock(&mutex); } #endif //fprintf(stderr, "Poller: about to enter loop, numFds=%d\n", numFds); return NULL; } void PortalPoller::stop(void) { uint8_t ch = 0; int rc; stopping = 1; startThread = 0; rc = write(pipefd[1], &ch, 1); if (rc < 0) fprintf(stderr, "[%s:%d] write error %d\n", __FUNCTION__, __LINE__, errno); } void PortalPoller::end(void) { stopping = 1; fprintf(stderr, "%s: don't disable interrupts when stopping\n", __FUNCTION__); return; pthread_mutex_lock(&mutex); for (int i = 0; i < numWrappers; i++) { Portal *instance = portal_wrappers[i]; fprintf(stderr, "Poller::disabling interrupts portal %d fpga%d\n", i, instance->pint.fpga_number); instance->pint.transport->enableint(&instance->pint, 0); } pthread_mutex_unlock(&mutex); } void* PortalPoller::pollFn(int timeout) { long rc = 0; //printf("[%s:%d] before poll %d numFds %d\n", __FUNCTION__, __LINE__, timeout, numFds); //for (int i = 0; i < numFds; i++) //printf("%s: fd %d events %x\n", __FUNCTION__, portal_fds[i].fd, portal_fds[i].events); inPoll = 1; if (timeout != 0) rc = poll(portal_fds, numFds, timeout); inPoll = 0; if(rc < 0) { // return only in error case fprintf(stderr, "Poller: poll returned rc=%ld errno=%d:%s\n", rc, errno, strerror(errno)); } return (void*)rc; } void* PortalPoller::event(void) { uint8_t ch; pthread_mutex_lock(&mutex); size_t rc = read(pipefd[0], &ch, 1); if (rc < 0) fprintf(stderr, "[%s:%d] read error %d\n", __FUNCTION__, __LINE__, errno); for (int i = 0; i < numWrappers; i++) { if (!portal_wrappers) fprintf(stderr, "Poller: No portal_instances revents=%d\n", portal_fds[i].revents); Portal *instance = portal_wrappers[i]; if (trace_poller) fprintf(stderr, "Poller: event tile %d fpga%d fd %d handler %p parent %p\n", instance->pint.fpga_tile, instance->pint.fpga_number, instance->pint.fpga_fd, instance->pint.handler, instance->pint.parent); instance->pint.transport->event(&instance->pint); if (instance->pint.handler) { // re-enable interrupt which was disabled by portal_isr instance->pint.transport->enableint(&instance->pint, 1); } } pthread_mutex_unlock(&mutex); return NULL; } extern "C" void addFdToPoller(struct PortalPoller *poller, int fd) { poller->addFd(fd); } void* PortalPoller::threadFn(void* __x) { void *rc = init(); sem_post(&sem_startup); while (!rc && !stopping) { rc = pollFn(timeout); if ((long) rc >= 0) rc = event(); } end(); fprintf(stderr, "[%s] thread ending\n", __FUNCTION__); return rc; } static void *pthread_worker(void *__x) { ((PortalPoller *)__x)->threadFn(__x); return 0; } void PortalPoller::start() { pthread_t threaddata; pthread_mutex_lock(&mutex); if (!startThread) { pthread_mutex_unlock(&mutex); return; } startThread = 0; pthread_mutex_unlock(&mutex); pthread_create(&threaddata, NULL, &pthread_worker, (void *)this); sem_wait(&sem_startup); } #endif // NO_CPP_PORTAL_CODE ================================================ FILE: cpp/portal.c ================================================ // Copyright (c) 2012 Nokia, Inc. // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "ConnectalProjectConfig.h" #include "portal.h" #include "sock_utils.h" #ifdef __KERNEL__ #include "linux/delay.h" #include "linux/file.h" #include "linux/dma-buf.h" #else #include #include #include #include #include #include #include #include // ctime #include // for portal_printf #include #include #include // dirname #include #endif #ifdef __APPLE__ // hack for debugging #include #else #include "drivers/portalmem/portalmem.h" // PA_MALLOC #if defined(ZYNQ) || defined(__riscv__) #include "drivers/zynqportal/zynqportal.h" #else #include "drivers/pcieportal/pcieportal.h" // BNOC_TRACE #endif #endif // !__APPLE__ int simulator_dump_vcd = 0; const char *simulator_vcd_name = "dump.vcd"; // set this to 1 to suppress call to fpgajtag #ifndef DEFAULT_NOPROGRAM #define DEFAULT_NOPROGRAM 0 #endif int noprogram = DEFAULT_NOPROGRAM; static int trace_portal;//= 1; int global_pa_fd = -1; PortalInternal *utility_portal = 0x0; void (*connectalPrintfHandler)(struct PortalInternal *p, unsigned int header); #ifdef __KERNEL__ static tBoard* tboard; #endif /* * Initialize control data structure for portal */ void init_portal_internal(PortalInternal *pint, int id, int tile, PORTAL_INDFUNC handler, void *cb, PortalTransportFunctions *transport, void *param, void *parent, uint32_t reqinfo) { int rc; memset(pint, 0, sizeof(*pint)); if(!utility_portal) utility_portal = pint; pint->board_number = 0; pint->fpga_number = id; pint->fpga_tile = tile; pint->fpga_fd = -1; pint->muxid = -1; pint->handler = handler; pint->cb = (PortalHandlerTemplate *)cb; pint->parent = parent; pint->reqinfo = reqinfo; pint->busyType = BUSY_SPIN; if (getenv("FPGA_NUMBER") != 0) pint->board_number = strtoul(getenv("FPGA_NUMBER"), 0, 0); if(trace_portal) PORTAL_PRINTF("%s: **initialize portal_b%dt%dp%d handler %p cb %p parent %p\n", __FUNCTION__, pint->board_number, pint->fpga_tile, pint->fpga_number, handler, cb, parent); if (!transport) { // Use defaults for transport handling methods #if defined(SIMULATION) && !defined(__ATOMICC__) transport = &transportXsim; #else transport = &transportHardware; #endif } pint->transport = transport; rc = pint->transport->init(pint, param); if (rc != 0) { PORTAL_PRINTF("%s: failed to initialize Portal portal_b%dt%dp%d\n", __FUNCTION__, pint->board_number, pint->fpga_tile, pint->fpga_number); #ifndef __KERNEL__ exit(1); #endif } } int portal_disconnect(struct PortalInternal *pint) { if(trace_portal) PORTAL_PRINTF("[%s:%d] fpgafd %d num %d cli %d\n", __FUNCTION__, __LINE__, pint->fpga_fd, pint->client_fd_number, pint->client_fd[0], pint->client_fd[1]); close(pint->fpga_fd); if (pint->client_fd_number > 0) close(pint->client_fd[--pint->client_fd_number]); return 0; } int portal_event(struct PortalInternal *pint) { #if defined(SIMULATION) && !defined(__ATOMICC__) return event_xsim(pint); #else return event_hardware(pint); #endif } char *getExecutionFilename(char *buf, int buflen) { int rc, fd; #ifdef __APPLE__ // hack for debugging static char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; rc = proc_pidpath (getpid(), pathbuf, sizeof(pathbuf)); return pathbuf; #endif char *filename = 0; buf[0] = 0; fd = open("/proc/self/maps", O_RDONLY); while ((rc = read(fd, buf, buflen-1)) > 0) { buf[rc] = 0; rc = 0; while(buf[rc]) { char *endptr; unsigned long addr = strtoul(&buf[rc], &endptr, 16); if (endptr && *endptr == '-') { char *endptr2; unsigned long addr2 = strtoul(endptr+1, &endptr2, 16); if (addr <= (unsigned long)&initPortalHardware && (unsigned long)&initPortalHardware <= addr2) { filename = strstr(endptr2, " "); while (*filename == ' ') filename++; endptr2 = strstr(filename, "\n"); if (endptr2) *endptr2 = 0; fprintf(stderr, "buffer %s\n", filename); goto endloop; } } while(buf[rc] && buf[rc] != '\n') rc++; if (buf[rc]) rc++; } } endloop: if (!filename) { fprintf(stderr, "[%s:%d] could not find execution filename\n", __FUNCTION__, __LINE__); return 0; } return filename; } /* * One time initialization of portal framework */ static pthread_once_t once_control; static void initPortalHardwareOnce(void) { #ifdef __KERNEL__ tboard = get_pcie_portal_descriptor(); #else /* * fork/exec 'fpgajtag' to download bits to hardware * (the FPGA bits are stored as an extra ELF segment in the executable file) */ int pid = fork(); if (pid == -1) { fprintf(stderr, "[%s:%d] fork error\n", __FUNCTION__, __LINE__); exit(-1); } else if (pid) { #ifndef SIMULATION int status; waitpid(pid, &status, 0); fprintf(stderr, "subprocess pid %d completed status=%x %d\n", pid, status, WEXITSTATUS(status)); #ifndef BOARD_de5 if (WEXITSTATUS(status) != 0) exit(-1); #endif { int fd = -1; ssize_t len; int attempt; for (attempt = 0; attempt < 10; attempt++) { struct stat statbuf; int rc = stat("/dev/connectal", &statbuf); /* wait for driver to load */ if (rc == -1) continue; fd = open("/dev/connectal", O_RDONLY); /* scan the fpga directory */ if (fd < 0) { fprintf(stderr, "[%s:%d] waiting for '/dev/connectal'\n", __FUNCTION__, __LINE__); sleep(1); continue; } len = read(fd, &status, sizeof(status)); if (len < (ssize_t)sizeof(status)) fprintf(stderr, "[%s:%d] fd %d len %lu\n", __FUNCTION__, __LINE__, fd, (unsigned long)len); close(fd); break; } if (fd == -1) { PORTAL_PRINTF("Error: %s: failed to open /dev/connectal, exiting\n", __FUNCTION__); exit(-1); } } #endif // !defined(SIMULATION) } else { #define MAX_PATH 2000 static char buf[400000]; char *filename = NULL; char *argv[] = { (char *)"fpgajtag", NULL, NULL, NULL, NULL, NULL, NULL, NULL}; int ind = 1; if (noprogram || getenv("NOFPGAJTAG") || getenv("NOPROGRAM")) exit(0); #ifndef SIMULATOR_USE_PATH filename = getExecutionFilename(buf, sizeof(buf)); #endif #ifdef SIMULATION char *bindir = (filename) ? dirname(filename) : 0; static char exename[MAX_PATH]; char *library_path = 0; if (getenv("DUMP_VCD")) { simulator_dump_vcd = 1; simulator_vcd_name = getenv("DUMP_VCD"); } #if defined(BOARD_bluesim) const char *exetype = "bsim"; argv[ind++] = (char*)"-w"; // wait for license if (simulator_dump_vcd) { argv[ind++] = (char*)"-V"; argv[ind++] = (char*)simulator_vcd_name; } #endif #if defined(BOARD_ncverilog) const char *exetype = "ncverilog"; bindir = 0; // the simulation driver is found in $PATH //FIXME ARGS #endif #if defined(BOARD_verilator) const char *exetype = "vlsim"; if (simulator_dump_vcd) { argv[ind++] = (char*)"-t"; argv[ind++] = (char*)simulator_vcd_name; } #endif #if defined(BOARD_cvc) const char *exetype = "cvcsim"; if (simulator_dump_vcd) { //argv[ind++] = (char*)"-t"; //argv[ind++] = (char*)simulator_vcd_name; } #endif #if defined(BOARD_xsim) const char *exetype = "xsim"; bindir = 0; // the simulation driver is found in $PATH argv[ind++] = (char *)"-R"; argv[ind++] = (char *)"work.xsimtop"; #endif #if defined(BOARD_vcs) const char *exetype = "simv"; argv[ind++] = (char *)"+verbose=1"; argv[ind++] = (char *)"-assert"; argv[ind++] = (char *)"verbose+success"; if (simulator_dump_vcd) { //argv[ind++] = (char*)"-t"; //argv[ind++] = (char*)simulator_vcd_name; } #endif #if defined(BOARD_vsim) const char *exetype = "vsim"; bindir = 0; // the simulation driver is found in $PATH argv[ind++] = (char *)"-c"; argv[ind++] = (char *)"-sv_lib"; argv[ind++] = (char *)"xsimtop"; argv[ind++] = (char *)"work.xsimtop"; argv[ind++] = (char *)"-do"; argv[ind++] = (char *)"run -all; quit -f"; #endif if (bindir) sprintf(exename, "%s/%s", bindir, exetype); else sprintf(exename, "%s", exetype); argv[0] = exename; if (trace_portal) fprintf(stderr, "[%s:%d] %s %s *******\n", __FUNCTION__, __LINE__, exetype, exename); argv[ind++] = NULL; if (bindir) { const char *old_library_path = getenv("LD_LIBRARY_PATH"); int library_path_len = strlen(bindir); if (old_library_path) library_path_len += strlen(old_library_path); library_path = (char *)malloc(library_path_len + 2); if (old_library_path) snprintf(library_path, library_path_len+2, "%s:%s", bindir, old_library_path); else snprintf(library_path, library_path_len+1, "%s", bindir); setenv("LD_LIBRARY_PATH", library_path, 1); if (trace_portal) fprintf(stderr, "[%s:%d] LD_LIBRARY_PATH %s *******\n", __FUNCTION__, __LINE__, library_path); } execvp (exename, argv); fprintf(stderr, "[%s:%d] exec(%s) failed errno=%d:%s\n", __FUNCTION__, __LINE__, exename, errno, strerror(errno)); #else // !defined(SIMULATION) char *serial = getenv("SERIALNO"); if (serial) { argv[ind++] = (char *)"-s"; argv[ind++] = strdup(serial); } { #ifdef __ANDROID__ // on zynq android, fpgajtag is in the initramdisk in the root directory const char *fpgajtag = "/fpgajtag"; #else const char *fpgajtag = "fpgajtag"; #endif // !__arm__ #ifdef __arm__ argv[ind++] = (char *)"-x"; // program via /dev/xdevcfg #endif #ifdef __aarch64__ argv[ind++] = (char *)"-m"; // program via fpga manager #endif argv[ind++] = filename; errno = 0; if (filename) // only run fpgajtag if filename was found execvp (fpgajtag, argv); fprintf(stderr, "[%s:%d] exec(%s) failed errno=%d:%s\n", __FUNCTION__, __LINE__, fpgajtag, errno, strerror(errno)); } #endif // !SIMULATION exit(-1); } #endif // !__KERNEL__ } void initPortalHardware(void) { pthread_once(&once_control, initPortalHardwareOnce); } /* * Utility functions for alloc/mmap/cache for shared memory */ void initPortalMemory(void) { #ifndef __KERNEL__ if (global_pa_fd == -1) #ifndef SIMULATION global_pa_fd = open("/dev/portalmem", O_RDWR); if (global_pa_fd < 0){ PORTAL_PRINTF("Failed to open /dev/portalmem pa_fd=%d errno=%d:%s\n", global_pa_fd, errno, strerror(errno)); exit(ENODEV); } #else global_pa_fd = -1; #endif #endif } int portalmem_sizes[1024]; int portalAlloc(size_t size, int cached) { int fd; initPortalMemory(); #ifdef __KERNEL__ fd = portalmem_dmabuffer_create(size); #else #ifndef SIMULATION { struct PortalAlloc portalAlloc; portalAlloc.len = size; portalAlloc.cached = cached; fd = ioctl(global_pa_fd, PA_MALLOC, &portalAlloc); } #else { #define FNAME_BUF_SIZE 128 static int portalmem_number = 0; char fname[FNAME_BUF_SIZE]; snprintf(fname, sizeof(fname), "/tmp/portalmem-%d-%d.bin", getpid(), portalmem_number++); fd = open(fname, O_RDWR|O_CREAT, 0600); if (fd < 0) fprintf(stderr, "ERROR %s:%d fname=%s fd=%d\n", __FUNCTION__, __LINE__, fname, fd); unlink(fname); lseek(fd, size, SEEK_SET); size_t bytesWritten = write(fd, (void*)fname, FNAME_BUF_SIZE); if (bytesWritten != FNAME_BUF_SIZE) fprintf(stderr, "ERROR %s:%d fname=%s fd=%d wrote %ld bytes\n", __FUNCTION__, __LINE__, fname, fd, (long)bytesWritten); portalmem_sizes[fd] = size; } #endif #endif if(trace_portal) PORTAL_PRINTF("alloc size=%ld fd=%d\n", (unsigned long)size, fd); if (fd == -1) { PORTAL_PRINTF("portalAllocCached: alloc failed size=%ld errno=%d\n", (unsigned long)size, errno); exit(-1); } return fd; } void *portalMmap(int fd, size_t size) { #ifdef __KERNEL__ struct file *fmem = fget(fd); void *retptr = dma_buf_vmap(fmem->private_data); fput(fmem); return retptr; #else ///////////////////////// userspace version void *mapped = mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0); if (mapped == MAP_FAILED) fprintf(stderr, "ERROR: portalMmap fd=%d size=%ld mapped=%p\n", fd, (long)size, mapped); return mapped; #endif } int portalMunmap(void *addr, size_t size) { #ifdef __KERNEL__ fprintf(stderr, "UNIMPLEMENTED: portalMunmap addr=%p size=%d\n", addr, size); #else ///////////////////////// userspace version return munmap(addr, size); #endif } int portalCacheFlush(int fd, void *__p, long size, int flush) { #if defined(__arm__) || defined (__riscv__) #ifdef __KERNEL__ int i; struct scatterlist *sg; struct file *fmem = fget(fd); struct sg_table *sgtable = ((struct pa_buffer *)((struct dma_buf *)fmem->private_data)->priv)->sg_table; printk("[%s:%d] flush %d\n", __FUNCTION__, __LINE__, fd); for_each_sg(sgtable->sgl, sg, sgtable->nents, i) { unsigned int length = sg->length; dma_addr_t start_addr = sg_phys(sg), end_addr = start_addr+length; printk("[%s:%d] start %lx end %lx len %x\n", __FUNCTION__, __LINE__, (long)start_addr, (long)end_addr, length); if(flush) outer_clean_range(start_addr, end_addr); outer_inv_range(start_addr, end_addr); } fput(fmem); #else int rc; if (utility_portal){ PortalCacheRequest req; req.fd = fd; req.base = __p; req.len = size; if(flush) rc = ioctl(utility_portal->fpga_fd, PORTAL_DCACHE_FLUSH_INVAL, &req); else rc = ioctl(utility_portal->fpga_fd, PORTAL_DCACHE_INVAL, &req); } else rc = -1; if (rc){ PORTAL_PRINTF("portal dcache flush failed rc=%d errno=%d:%s\n", rc, errno, strerror(errno)); return rc; } #endif #elif defined(__i386__) || defined(__x86_64__) { int i; // not sure any of this is necessary (mdk) for(i = 0; i < size; i++){ char foo = *(((volatile char *)__p)+i); asm volatile("clflush %0" :: "m" (foo)); } asm volatile("mfence"); } #elif defined(__aarch64__) // TBD #else #error("portalCacheFlush not defined for unspecified architecture") #endif if(trace_portal) PORTAL_PRINTF("dcache flush\n"); return 0; } /* * Miscellaneous utility functions */ int setClockFrequency(int clkNum, long requestedFrequency, long *actualFrequency) { int status = -1; initPortalHardware(); #ifdef ZYNQ PortalClockRequest request; request.clknum = clkNum; request.requested_rate = requestedFrequency; if (utility_portal){ status = ioctl(utility_portal->fpga_fd, PORTAL_SET_FCLK_RATE, (long)&request); if (status == 0 && actualFrequency) *actualFrequency = request.actual_rate; if (status < 0) status = errno; } else { fprintf(stderr, "[%s:%d] no utility portal\n", __FUNCTION__, __LINE__); status = -1; } #endif return status; } ================================================ FILE: cpp/portal.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef __PORTAL_OFFSETS_H__ #define __PORTAL_OFFSETS_H__ #ifdef __KERNEL__ #include // has same typedefs as stdint.h #include #include typedef struct task_struct *pthread_t; int pthread_create(pthread_t *thread, void *attr, void *(*start_routine) (void *), void *arg); #define PRIu64 "llx" #define PRIx64 "llx" #define PORTAL_PRINTF printk #else #include #include #include // for send()/recv() #include // memcpy #include // printf() #include // exit() #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS #endif #include #ifdef __cplusplus #include #include #include // pthread_mutex_t #include #endif #include "ConnectalProjectConfig.h" extern int simulator_dump_vcd; extern const char *simulator_vcd_name; extern int noprogram; #define PORTAL_PRINTF portal_printf #endif // Other constants #define MAX_TIMERS 50 #define MAX_CLIENT_FD 10 #ifdef __ATOMICC__ #define DEFAULT_TILE 0 #else #define DEFAULT_TILE 1 #endif /* * Function vector for portal transport primitives used in generated C code */ struct PortalInternal; typedef int (*ITEMINIT)(struct PortalInternal *pint, void *param); typedef unsigned int (*READWORD)(struct PortalInternal *pint, volatile unsigned int **addr); typedef void (*WRITEWORD)(struct PortalInternal *pint, volatile unsigned int **addr, unsigned int v); typedef void (*WRITEFDWORD)(struct PortalInternal *pint, volatile unsigned int **addr, unsigned int v); typedef volatile unsigned int *(*MAPCHANNELIND)(struct PortalInternal *pint, unsigned int v); typedef volatile unsigned int *(*MAPCHANNELREQ)(struct PortalInternal *pint, unsigned int v, unsigned int size); typedef void (*SENDMSG)(struct PortalInternal *pint, volatile unsigned int *buffer, unsigned int hdr, int sendFd); typedef int (*RECVMSG)(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd); typedef int (*BUSYWAIT)(struct PortalInternal *pint, unsigned int v, const char *str); typedef void (*ENABLEINT)(struct PortalInternal *pint, int val); typedef int (*EVENT)(struct PortalInternal *pint); typedef int (*NOTFULL)(struct PortalInternal *pint, unsigned int v); typedef struct { ITEMINIT init; READWORD read; WRITEWORD write; WRITEFDWORD writefd; MAPCHANNELIND mapchannelInd; MAPCHANNELREQ mapchannelReq; SENDMSG send; RECVMSG recv; BUSYWAIT busywait; ENABLEINT enableint; EVENT event; NOTFULL notFull; } PortalTransportFunctions; /* * Indication function vector for method invocations from HW->SW */ typedef int (*PORTAL_INDFUNC)(struct PortalInternal *p, unsigned int channel, int messageFd); /* * Disconnect indications from sockets */ typedef int (*PORTAL_DISCONNECT)(struct PortalInternal *pint); typedef struct { PORTAL_DISCONNECT disconnect; } PortalHandlerTemplate; /* * Main data structure used for managing Portal info at runtime */ typedef struct PortalInternal { struct PortalPoller *poller; int fpga_fd; uint32_t fpga_number; uint32_t fpga_tile; uint32_t board_number; volatile unsigned int *map_base; void *parent; PORTAL_INDFUNC handler; uint32_t reqinfo; int accept_finished; PortalTransportFunctions *transport; PortalHandlerTemplate *cb; struct PortalInternal *mux; int muxid; int busyType; #define BUSY_TIMEWAIT 0 #define BUSY_SPIN 1 #define BUSY_EXIT 2 #define BUSY_ERROR 3 uint32_t sharedMem; int indication_index; int request_index; int client_fd_number; int client_fd[MAX_CLIENT_FD]; int mux_ports_number; struct PortalMuxHandler *mux_ports; void *websock; void *websock_context; void *websock_wsi; void *shared_dma; struct PortalInternal *shared_cfg; int poller_register; int json_arg_vector; } PortalInternal; typedef struct PortalMuxHandler { PortalInternal *pint; } PortalMuxHandler; /* * Struct definitions for optional parameter when initializing transport for portal */ typedef int (*SHARED_CONFIG_SETSGLID)(struct PortalInternal *, const uint32_t sglId); typedef int (*SHARED_MMUINDICATION_POLL)(PortalInternal *p, uint32_t *arg_id); typedef struct { struct { struct DmaManager *manager; uint32_t reqport; uint32_t reqinfo; uint32_t indport; uint32_t indinfo; PORTAL_INDFUNC handler; void *callbackFunctions; SHARED_MMUINDICATION_POLL poll; } dma; uint32_t size; struct { uint32_t port; uint32_t reqinfo; SHARED_CONFIG_SETSGLID setSglId; } hardware; struct { int serial_fd; } serial; } PortalSharedParam; /* for ITEMINIT function */ typedef struct { PortalInternal *pint; void *socketParam; } PortalMuxParam; typedef struct { const char *name; int offset; int itype; } ConnectalParamJsonInfo; typedef struct { const char *name; ConnectalParamJsonInfo *param; } ConnectalMethodJsonInfo; enum {ITYPE_other, ITYPE_int, ITYPE_uint8_t, ITYPE_uint16_t, ITYPE_uint32_t, ITYPE_uint64_t, ITYPE_int8_t, ITYPE_int16_t, ITYPE_int32_t, ITYPE_int64_t, ITYPE_SpecialTypeForSendingFd, ITYPE_ChannelType, ITYPE_DmaDbgRec}; typedef int Bool; /* for GeneratedTypes.h */ typedef uint32_t fixed32; /* for GeneratedTypes.h from protobuf */ #define SHARED_DMA(REQPORTALNAME, INDPORTALNAME) {NULL, (REQPORTALNAME), MMURequest_reqinfo, (INDPORTALNAME), MMUIndication_reqinfo, MMUIndication_handleMessage, (void *)&manualMMU_Cb, manualWaitForResp} #define SHARED_HARDWARE(PORTALNAME) {(PORTALNAME), SharedMemoryPortalConfig_reqinfo, SharedMemoryPortalConfig_setSglId} #define Connectaloffsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER) /* * Address constants for portal memory mapped registers */ /* Divide up 20 bits of physical address space into Tile:Portal:Method selectors */ #define ADDRESS_TILE_SELECTOR 2 #define ADDRESS_PORTAL_SELECTOR 6 #define ADDRESS_METHOD_SELECTOR 7 #define ADDRESS_METHOD_SIZE 5 /* Offset of each /dev/fpgaxxx device in the address space */ #define PORTAL_BASE_OFFSET (1 << (ADDRESS_METHOD_SIZE+ADDRESS_METHOD_SELECTOR)) #define TILE_BASE_OFFSET (PORTAL_BASE_OFFSET << ADDRESS_PORTAL_SELECTOR) /* Offsets of mapped registers within an /dev/fpgaxxx device */ #define PORTAL_FIFO(A) ( (((A)+1) << ADDRESS_METHOD_SIZE) / sizeof(uint32_t) ) // PortalCtrl offsets #define PORTAL_CTRL_INTERRUPT_STATUS 0 #define PORTAL_CTRL_INTERRUPT_ENABLE 1 #define PORTAL_CTRL_NUM_TILES 2 #define PORTAL_CTRL_IND_QUEUE_STATUS 3 #define PORTAL_CTRL_PORTAL_ID 4 #define PORTAL_CTRL_NUM_PORTALS 5 #define PORTAL_CTRL_COUNTER_MSB 6 #define PORTAL_CTRL_COUNTER_LSB 7 #define PORTAL_CTRL_SIZE (8 * sizeof(uint32_t)) /* * Constants used in shared memory transport for portals */ #define SHARED_LIMIT 0 #define SHARED_WRITE 1 #define SHARED_READ 2 #define SHARED_START 4 // Since PortalCtrl fields appear as 'method 0', we need to be sure we have // enough memory allocated to 'read' them on simulation #define REQINFO_SIZE(A) (((A) & 0xffff) > PORTAL_CTRL_SIZE ? ((A) & 0xffff) : PORTAL_CTRL_SIZE) #define REQINFO_COUNT(A) (((A) >> 16) & 0xffff) #ifdef __cplusplus extern "C" { #endif // Initialize portal control structure. (called by constructor when creating a portal at runtime) void init_portal_internal(PortalInternal *pint, int id, int tile, PORTAL_INDFUNC handler, void *cb, PortalTransportFunctions *transport, void *param, void *parent, uint32_t reqinfo); int portal_disconnect(struct PortalInternal *p); // Shared memory functions void initPortalMemory(void); int portalAlloc(size_t size, int cached); void *portalMmap(int fd, size_t size); int portalMunmap(void *addr, size_t size); int portalCacheFlush(int fd, void *__p, long size, int flush); // Timer functions uint64_t portalCycleCount(void); void portalTimerStart(unsigned int i); uint64_t portalTimerLap(unsigned int i); void portalTimerInit(void); uint64_t portalTimerCatch(unsigned int i); void portalTimerPrint(int loops); // Functions shared across several portal transports void enableint_portal_null(struct PortalInternal *pint, int val); int busy_portal_null(struct PortalInternal *pint, unsigned int v, const char *str); int notfull_null(PortalInternal *pint, unsigned int v); void send_portal_null(struct PortalInternal *pint, volatile unsigned int *buffer, unsigned int hdr, int sendFd); int recv_portal_null(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd); int event_null(struct PortalInternal *pint); volatile unsigned int *mapchannel_req_generic(struct PortalInternal *pint, unsigned int v, unsigned int size); unsigned int read_portal_memory(PortalInternal *pint, volatile unsigned int **addr); void write_portal_memory(PortalInternal *pint, volatile unsigned int **addr, unsigned int v); void write_fd_portal_memory(PortalInternal *pint, volatile unsigned int **addr, unsigned int v); void enableint_hardware(struct PortalInternal *pint, int val); int busy_hardware(struct PortalInternal *pint, unsigned int v, const char *str); int notfull_hardware(PortalInternal *pint, unsigned int v); int event_hardware(struct PortalInternal *pint); int event_xsim(struct PortalInternal *pint); int portal_event(struct PortalInternal *pint); volatile unsigned int *mapchannel_hardware(struct PortalInternal *pint, unsigned int v); volatile unsigned int *mapchannel_socket(struct PortalInternal *pint, unsigned int v); int portal_mux_handler(struct PortalInternal *p, unsigned int channel, int messageFd); int portal_serialmux_handler(struct PortalInternal *p, unsigned int channel, int messageFd); // Json encode/decode functions called from generated code void connectalJsonEncode(char *json, void *data, ConnectalMethodJsonInfo *info, int json_arg_vector); void connectalJsonEncodeAndSend(PortalInternal *pint, void *data, ConnectalMethodJsonInfo *info); void connectalJsonSend(PortalInternal *pint, const char *jsonp, int methodNumber); const char *connectalJsonReceive(PortalInternal *pint); // Primitive used to send/recv data across a socket. void portalSendFd(int fd, void *data, int len, int sendFd); int portalRecvFd(int fd, void *data, int len, int *recvFd); unsigned int bsim_poll_interrupt(void); unsigned int read_pareff32(uint32_t pref, uint32_t offset); unsigned int read_pareff64(uint64_t pref, uint64_t offset); int setClockFrequency(int clkNum, long requestedFrequency, long *actualFrequency); void initPortalHardware(void); void addFdToPoller(struct PortalPoller *poller, int fd); #ifndef __KERNEL__ int portal_printf(const char *format, ...); // outputs to stderr #endif extern int global_sockfd, global_pa_fd; extern PortalInternal *utility_portal; #define CONNECTAL_PRINTF_PORT 0x7fff extern void (*connectalPrintfHandler)(struct PortalInternal *p, unsigned int header); // Portal transport variants extern PortalTransportFunctions transportBsim, // Transport for bsim transportHardware, // Memory-mapped register transport for hardware transportSocketInit, // Linux socket transport (Unix sockets and TCP); Initiator side // (the 'connect()' call is on Initiator side; Responder does 'listen()' transportSocketResp, // Linux socket transport (Unix sockets and TCP); Responder side transportSerial, // Serial port transport transportSerialMux, // Serial port mux transportShared, // Shared memory transport transportMux, // Multiplex transport (to use 1 transport for all methods or multiple portals) transportTrace, // Trace transport tee transportXsim, // Xilinx xsim transport transportWebSocketInit, // Websocket transport; Initiator side transportWebSocketResp, // Websocket transport; Responder side transportPortal; #ifdef __cplusplus } #endif /* * C++ class definitions used in application software */ #ifdef __cplusplus class Portal; class PortalPoller { private: Portal *portal_wrappers[32]; struct pollfd portal_fds[32]; // 16 portals + pipefd[0] + extra pthread_mutex_t mutex; int pipefd[2]; int startThread; int numWrappers; int numFds; int inPoll; public: PortalPoller(int autostart=1); int registerInstance(Portal *portal); int unregisterInstance(Portal *portal); void *init(void); void *pollFn(int timeout); void *event(void); void end(void); void start(); void stop(); void addFd(int fd); int timeout; int stopping; sem_t sem_startup; void* threadFn(void* __x); }; extern PortalPoller *defaultPoller; class Portal { void initPortal() { if (pint.handler || pint.poller_register) { if (pint.poller == 0) pint.poller = defaultPoller; pint.poller->registerInstance(this); } } public: Portal(int id, int tile, uint32_t reqinfo, PORTAL_INDFUNC handler, void *cb, void *parent, PortalPoller *poller = 0) { init_portal_internal(&pint, id, tile, handler, cb, NULL, NULL, parent, reqinfo); pint.poller = poller; initPortal(); }; Portal(int id, int tile, uint32_t reqinfo, PORTAL_INDFUNC handler, void *cb, PortalTransportFunctions *transport, void *param, void *parent, PortalPoller *poller = 0) { init_portal_internal(&pint, id, tile, handler, cb, transport, param, parent, reqinfo); pint.poller = poller; initPortal(); }; ~Portal() { if (pint.handler) pint.poller->unregisterInstance(this); if (pint.fpga_fd > 0) { ::close(pint.fpga_fd); pint.fpga_fd = -1; } }; PortalInternal pint; }; extern uint64_t poll_enter_time, poll_return_time; // for performance measurement extern int mmu_error_limit, mem_error_limit; // portalMemory extern const char *dmaErrors[]; // portalMemory #endif // __cplusplus #endif /* __PORTAL_OFFSETS_H__ */ ================================================ FILE: cpp/portalJson.c ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include "portal.h" // extern "C" because some of the makefiles use g++ to compile this file #ifdef __cplusplus extern "C" { #endif static int trace_json;// = 1; void connectalJsonEncode(char *datap, void *binarydata, ConnectalMethodJsonInfo *info, int json_arg_vector) { ConnectalParamJsonInfo *iparam = info->param; char *data = (char *)datap; if (!json_arg_vector) data += sprintf(data, "{\"name\":\"%s\"", info->name); else data += sprintf(data, "[\"%s\"", info->name); while(iparam->name) { uint8_t tmp8; uint16_t tmp16; uint32_t tmp32; uint64_t tmp64; int8_t stmp8; int16_t stmp16; int32_t stmp32; int64_t stmp64; int tmpint; if (!json_arg_vector) data += sprintf(data, ",\"%s\":", iparam->name); else data += sprintf(data, ", "); switch(iparam->itype) { case ITYPE_int8_t: stmp8 = *(int8_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", stmp8); break; case ITYPE_int16_t: stmp16 = *(int16_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", stmp16); break; case ITYPE_int: case ITYPE_int32_t: stmp32 = *(int32_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", stmp32); break; case ITYPE_int64_t: stmp64 = *(int64_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%lld", (long long)stmp64); break; case ITYPE_uint8_t: tmp8 = *(uint8_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", tmp8); break; case ITYPE_uint16_t: tmp16 = *(uint16_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", tmp16); break; case ITYPE_uint32_t: tmp32 = *(uint32_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", tmp32); break; case ITYPE_uint64_t: tmp64 = *(uint64_t *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%lld", (unsigned long long)tmp64); break; case ITYPE_SpecialTypeForSendingFd: tmpint = *(int *)((unsigned long)binarydata + iparam->offset); data += sprintf(data, "%d", tmpint); break; default: fprintf(stderr, "%x type %d\n", *(uint32_t *)((unsigned long)binarydata + iparam->offset), iparam->itype); } iparam++; } if (!json_arg_vector) data += sprintf(data, "}"); else data += sprintf(data, "]"); if (trace_json) fprintf(stderr, "[%s] num %d message '%s'\n", __FUNCTION__, iparam->offset, (char *)datap); int slength = strlen(datap); int rounded_size = (slength + sizeof(uint32_t) - 1) / sizeof(uint32_t); while (slength++ < (int)(rounded_size*sizeof(uint32_t))) *data++ = ' '; *data++ = 0; } void connectalJsonEncodeAndSend(PortalInternal *pint, void *binarydata, ConnectalMethodJsonInfo *info) { ConnectalParamJsonInfo *iparam = info->param; char *jsonp = (char *)pint->transport->mapchannelInd(pint, 0); if (pint->json_arg_vector) jsonp = (char *)pint->parent; connectalJsonEncode(jsonp, binarydata, info, pint->json_arg_vector); if (!pint->json_arg_vector) { int rounded_size = strlen(jsonp); pint->transport->send(pint, (volatile unsigned int*)jsonp, (iparam->offset << 16) | (1 + rounded_size), -1); } } void connectalJsonSend(PortalInternal *pint, const char *jsonp, int methodNumber) { //fprintf(stderr, "%s:%d jsonp=%s\n", __FUNCTION__, __LINE__, jsonp); if (pint->json_arg_vector) { //FIXME strncpy strcpy((char *)pint->parent, jsonp); } if (!pint->json_arg_vector) { int rounded_size = strlen(jsonp); pint->transport->send(pint, (volatile unsigned int*)jsonp, (methodNumber << 16) | (1 + rounded_size), -1); } } const char *connectalJsonReceive(PortalInternal *pint) { uint32_t header = *(uint32_t *)pint->map_base; char *datap = (char *)pint->transport->mapchannelInd(pint, 0); int tmpfd; int len = (header & 0xffff)-1; int rc = pint->transport->recv(pint, (volatile unsigned int*)datap, len, &tmpfd); if (rc != len) fprintf(stderr, "[%s:%d] short read %d\n", __FUNCTION__, __LINE__, rc); datap[len*sizeof(uint32_t)] = 0; if (trace_json) fprintf(stderr, "[%s] message '%s'\n", __FUNCTION__, (char *)datap); return datap; } int connectalJsonDecode(PortalInternal *pint, int _unused_channel, void *binarydata, ConnectalMethodJsonInfo *infoa) { int channel = 0; ConnectalMethodJsonInfo *info = NULL; //&infoa[channel]; uint32_t header = *(uint32_t *)pint->map_base; char *datap = (char *)pint->transport->mapchannelInd(pint, 0); char ch, *attr = NULL, *val = NULL; int tmpfd; int len = (header & 0xffff)-1; int rc = pint->transport->recv(pint, (volatile unsigned int*)datap, len, &tmpfd); if (rc != len) fprintf(stderr, "[%s:%d] short read %d\n", __FUNCTION__, __LINE__, rc); datap[len*sizeof(uint32_t)] = 0; if (trace_json) fprintf(stderr, "[%s] message '%s'\n", __FUNCTION__, (char *)datap); while ((ch = *datap++)) { if (ch == '\"') { if (!attr) attr = datap; else if (!val) *(datap - 1) = 0; } else if (ch == ':') val = datap; else if ((ch == ',' || ch == '}') && attr && val) { *(datap - 1) = 0; if (!strcmp(attr, "name")) { info = infoa; val++; /* skip leading '"' */ val[strlen(val) - 1] = 0; /* delete trailing '"' */ while (info->name && strcmp(info->name, val)){ info++; channel++; } if (!info->name) { fprintf(stderr, "[%s:%d] unknown method name '%s'\n", __FUNCTION__, __LINE__, val); exit(1); } } ConnectalParamJsonInfo *iparam = info->param; while (iparam->name) { if (!strcmp(iparam->name, attr)) { char *endptr; if (trace_json) fprintf(stderr, "[%s] attr '%s' val '%s'\n", __FUNCTION__, attr, val); uint64_t tmp64 = strtol(val, &endptr, 0); if (endptr != &val[strlen(val)]) fprintf(stderr, "[%s:%d] strtol didn't use all characters %p != %p\n", __FUNCTION__, __LINE__, endptr, val+strlen(val)); switch(iparam->itype) { case ITYPE_int16_t: *(int16_t *)((unsigned long)binarydata + iparam->offset) = tmp64; break; case ITYPE_uint16_t: *(uint16_t *)((unsigned long)binarydata + iparam->offset) = tmp64; break; case ITYPE_uint32_t: *(uint32_t *)((unsigned long)binarydata + iparam->offset) = tmp64; break; case ITYPE_uint64_t: *(uint64_t *)((unsigned long)binarydata + iparam->offset) = tmp64; break; case ITYPE_SpecialTypeForSendingFd: *(int *)((unsigned long)binarydata + iparam->offset) = tmp64; break; default: fprintf(stderr, "%x type %d\n", *(uint32_t *)((unsigned long)binarydata + iparam->offset), iparam->itype); } break; } iparam++; } attr = NULL; val = NULL; } } return channel; } #ifdef __cplusplus } #endif ================================================ FILE: cpp/portalKernel.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. void send_portal_null(struct PortalInternal *pint, volatile unsigned int *buffer, unsigned int hdr, int sendFd) { } int recv_portal_null(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) { return 0; } volatile unsigned int *mapchannel_portal_kernel_ind(struct PortalInternal *pint, unsigned int v) { return &pint->map_base[PORTAL_FIFO(v)]; } volatile unsigned int *mapchannel_portal_kernel_req(struct PortalInternal *pint, unsigned int v, unsigned int size) { return pint->transport->mapchannelInd(pint, v); } int notfull_kernel(PortalInternal *pint, unsigned int v) { volatile unsigned int *tempp = pint->transport->mapchannelInd(pint, v) + 1; return pint->transport->read(pint, &tempp); } int busy_portal_kernel(struct PortalInternal *pint, unsigned int v, const char *str) { int count = 50; while (!pint->transport->notFull(pint, v) && count-- > 0) ; /* busy wait a bit on 'fifo not full' */ if (count <= 0){ PORTAL_PRINTF("putFailed: %s\n", str); return 1; } return 0; } void enableint_portal_kernel(struct PortalInternal *pint, int val) { volatile unsigned int *enp = &(pint->map_base[PORTAL_CTRL_INTERRUPT_ENABLE]); pint->transport->write(pint, &enp, val); } int event_portal_kernel(struct PortalInternal *pint) { // handle all messasges from this portal instance //event_hardware(pint); return -1; } static int init_portal_kernel(struct PortalInternal *pint, void *param) { //pint->map_base = (volatile unsigned int*)(tboard->bar2io + pint->fpga_number * PORTAL_BASE_OFFSET); return 0; } static unsigned int read_portal_kernel(PortalInternal *pint, volatile unsigned int **addr) { return **addr; } static void write_portal_kernel(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { **addr = v; } static void write_fd_portal_kernel(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { **addr = v; } PortalTransportFunctions kernelfunc = { init_portal_kernel, read_portal_kernel, write_portal_kernel, write_fd_portal_kernel, mapchannel_portal_kernel_ind, mapchannel_portal_kernel_req, send_portal_null, recv_portal_null, busy_portal_kernel, enableint_portal_kernel, event_portal_kernel, notfull_kernel}; ================================================ FILE: cpp/portalPrintf.c ================================================ // Copyright (c) 2013-2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #ifndef __KERNEL__ #ifdef __cplusplus extern "C" #endif int portal_printf(const char *format, ...) { va_list ap; va_start(ap, format); return vfprintf(stderr, format, ap); } #endif ================================================ FILE: cpp/portalPython.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * Copyright (c) 2016 ConnectalProject * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "GeneratedTypes.h" #include static int tracePython;// = 1; static PortalInternal pythonTransport; #define STUB \ { \ fprintf(stderr, "[%s:%d]\n", __FUNCTION__, __LINE__); \ exit(-1); \ } static volatile unsigned int *pythonTransportMAPCHANNELIND(struct PortalInternal *pint, unsigned int v) { return &pythonTransport.map_base[0]; } static volatile unsigned int *pythonTransportMAPCHANNELREQ(struct PortalInternal *pint, unsigned int v, unsigned int size) { return &pythonTransport.map_base[0]; } static void pythonTransportSENDMSG(struct PortalInternal *pint, volatile unsigned int *buffer, unsigned int hdr, int sendFd) { if (tracePython) fprintf(stderr, "%s:%d %s\n", __FUNCTION__, __LINE__, (const char *)buffer); } static int pythonTransportTRANSPORTINIT(struct PortalInternal *pint, void *param) STUB static unsigned int pythonTransportREADWORD(struct PortalInternal *pint, volatile unsigned int **addr) STUB static void pythonTransportWRITEWORD(struct PortalInternal *pint, volatile unsigned int **addr, unsigned int v) STUB static void pythonTransportWRITEFDWORD(struct PortalInternal *pint, volatile unsigned int **addr, unsigned int v) STUB static int pythonTransportRECVMSG(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) STUB static int pythonTransportBUSYWAIT(struct PortalInternal *pint, unsigned int v, const char *str) STUB static void pythonTransportENABLEINT(struct PortalInternal *pint, int val) STUB static int pythonTransportEVENT(struct PortalInternal *pint) STUB static int pythonTransportNOTFULL(struct PortalInternal *pint, unsigned int v) STUB PortalTransportFunctions callbackTransport = { pythonTransportTRANSPORTINIT, pythonTransportREADWORD, pythonTransportWRITEWORD, pythonTransportWRITEFDWORD, pythonTransportMAPCHANNELIND, pythonTransportMAPCHANNELREQ, pythonTransportSENDMSG, pythonTransportRECVMSG, pythonTransportBUSYWAIT, pythonTransportENABLEINT, pythonTransportEVENT, pythonTransportNOTFULL}; extern "C" { typedef int (*HandleMessage)(struct PortalInternal *pint, unsigned int channel, int messageFd); struct PortalPython { struct PortalInternal pint; HandleMessage handleMessage; PyObject *callbackFunction; }; static int handleIndicationMessage(struct PortalInternal *pint, unsigned int channel, int messageFd) { struct PortalPython *ppython = (struct PortalPython *)pint; HandleMessage handleMessage = ppython->handleMessage; pint->json_arg_vector = 1; int value = handleMessage(pint, channel, messageFd); PyGILState_STATE gstate = PyGILState_Ensure(); const char *jsonp = (const char *)pint->parent; if (tracePython) fprintf(stderr, "handleIndicationMessage: json=%s\n", jsonp); if (ppython->callbackFunction) { PyEval_CallMethod(ppython->callbackFunction, "callback", "(s)", jsonp, NULL); } else { fprintf(stderr, "%s:%d no callback for portal\n", __FUNCTION__, __LINE__); } PyGILState_Release(gstate); return value; } void set_callback(struct PortalPython *ppython, PyObject *param) { Py_INCREF(param); ppython->callbackFunction = param; pythonTransport.transport = &callbackTransport; pythonTransport.map_base = (volatile unsigned int *)malloc(1000); } void *newRequestPortal(int ifcname, int reqinfo) { struct PortalInternal *pint = (struct PortalInternal *)calloc(1, sizeof(struct PortalInternal)); void *parent = NULL;; if (tracePython) fprintf(stderr, "%s:%d ifcname=%x reqinfo=%08x pint=%p\n", __FUNCTION__, __LINE__, ifcname, reqinfo, pint); init_portal_internal(pint, ifcname, DEFAULT_TILE, NULL, NULL, NULL, NULL, parent, reqinfo); return pint; } void *newIndicationPortal(int ifcname, int reqinfo, HandleMessage handleMessage, void *proxyreq) { void *parent = malloc(4096); struct PortalPython *ppython = (struct PortalPython *)calloc(1, sizeof(struct PortalPython)); ppython->handleMessage = handleMessage; if (tracePython) fprintf(stderr, "%s:%d ifcname=%x reqinfo=%08x handleMessage=%p proxyreq=%p pint=%p\n", __FUNCTION__, __LINE__, ifcname, reqinfo, handleMessage, proxyreq, ppython); init_portal_internal(&ppython->pint, ifcname, DEFAULT_TILE, (PORTAL_INDFUNC) handleIndicationMessage, proxyreq, NULL, NULL, parent, reqinfo); // encode message as vector ["methodname", arg0, arg1, ...] pythonTransport.json_arg_vector = 1; return ppython; } } // extern "C" ================================================ FILE: cpp/runpython.cpp ================================================ #include #include #include #include #include #include #include #include #include #define STR_VALUE_(arg) #arg #define STR_VALUE(arg) STR_VALUE_(arg) int main(int argc, char * const *argv) { const char *exename = "../test.py"; char library_path[4096]; struct utsname utsname; struct stat statbuf; const char *libdir = "./bin"; int statok = 0; fprintf(stderr, "runpython args: "); for (int i = 0; i < argc; i++) fprintf(stderr, " %s", argv[i]); fprintf(stderr, "\n"); if (argc > 1) { exename = argv[1]; // What? dirname modifies its argument? libdir = dirname(strdup(argv[1])); } statok = stat("/usr/bin/python", &statbuf); uname(&utsname); if ((statok != 0) && strcmp(utsname.machine, "armv7l") == 0) { strncpy(library_path, "./bin:../lib:.", sizeof(library_path)); exename = "../bin/python"; } else { strncpy(library_path, libdir, sizeof(library_path)); strncat(library_path, ":./bin", sizeof(library_path)-strlen(":./bin")-1); } if (getenv("LD_LIBRARY_PATH") != 0) { strncat(library_path, ":", sizeof(library_path)-strlen(library_path)-1); strncat(library_path, getenv("LD_LIBRARY_PATH"), sizeof(library_path)-strlen(library_path)-1); } fprintf(stderr, "LD_LIBRARY_PATH: %s\n", library_path); setenv("LD_LIBRARY_PATH", library_path, 1); #ifdef PYTHONPATH fprintf(stderr, "PYTHONPATH=%s\n", PYTHONPATH); fprintf(stderr, "CONNECTALDIR=%s\n", CONNECTALDIR); static char pythonpath[1024]; snprintf(pythonpath, sizeof(pythonpath), "%s:%s/scripts", PYTHONPATH, CONNECTALDIR); fprintf(stderr, "using PYTHONPATH=%s\n", pythonpath); setenv("PYTHONPATH", pythonpath, 1); #endif fprintf(stderr, "%s: execv(%s)\n", argv[0], exename); return execv(exename, argv); } ================================================ FILE: cpp/sock_utils.c ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #include "sock_utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static int trace_socket ;//= 1; const char *bluesimSocketName() { char *name = getenv("BLUESIM_SOCKET_NAME"); return name ? name : "socket_for_bluesim"; } int init_listening(const char *arg_name, PortalSocketParam *param) { int listening_socket; struct sockaddr_un sa = {0}; sa.sun_family = AF_UNIX; strcpy(sa.sun_path, arg_name); struct addrinfo addrinfo = { 0, AF_UNIX, SOCK_STREAM, 0}; addrinfo.ai_addrlen = #ifdef __APPLE__ SUN_LEN(&sa); #else sizeof(sa.sun_family) + strlen(sa.sun_path); #endif addrinfo.ai_addr = (struct sockaddr *)&sa; struct addrinfo *addr = &addrinfo; if (trace_socket) fprintf(stderr, "[%s:%d] listenName %s\n", __FUNCTION__, __LINE__, arg_name); if (param && param->addr) { fprintf(stderr, "[%s:%d] TCP\n", __FUNCTION__, __LINE__); addr = param->addr; // added these for android addr->ai_socktype = SOCK_STREAM; addr->ai_protocol = 0; } else unlink(sa.sun_path); listening_socket = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); int tmp = 1; setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); if (listening_socket == -1 || bind(listening_socket, addr->ai_addr, addr->ai_addrlen) == -1) { fprintf(stderr, "%s[%d]: bind error %s\n",__FUNCTION__, listening_socket, strerror(errno)); exit(1); } if (listen(listening_socket, 5) == -1) { fprintf(stderr, "%s[%d]: listen error %s\n",__FUNCTION__, listening_socket, strerror(errno)); exit(1); } if (trace_socket) fprintf(stderr, "%s: listen(%d)\n", __FUNCTION__, listening_socket); return listening_socket; } int accept_socket(int arg_listening) { int sockfd = accept(arg_listening, NULL, NULL); if (sockfd == -1) { if (errno == EAGAIN) return -1; fprintf(stderr, "%s[%d]: accept error %s\n",__FUNCTION__, arg_listening, strerror(errno)); exit(1); } if (trace_socket) fprintf(stderr, "%s: accept(%d) = %d\n", __FUNCTION__, arg_listening, sockfd); return sockfd; } int init_connecting(const char *arg_name, PortalSocketParam *param) { int connect_attempts = 0; int sockfd; struct sockaddr_un sa = {0}; struct addrinfo addrinfo = { 0, AF_UNIX, SOCK_STREAM, 0}; struct addrinfo *addr = &addrinfo; sa.sun_family = AF_UNIX; strcpy(sa.sun_path, arg_name); addrinfo.ai_addrlen = #ifdef __APPLE__ SUN_LEN(&sa); #else sizeof(sa.sun_family) + strlen(sa.sun_path); #endif addrinfo.ai_addr = (struct sockaddr *)&sa; if (param && param->addr) { if (trace_socket) fprintf(stderr, "[%s:%d] TCP\n", __FUNCTION__, __LINE__); addr = param->addr; } if ((sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol)) == -1) { PORTAL_PRINTF( "%s[%d]: socket error %s\n",__FUNCTION__, sockfd, strerror(errno)); return -1; } if (trace_socket) PORTAL_PRINTF( "%s (%s) trying to connect...\n",__FUNCTION__, arg_name); while (connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1) { if(connect_attempts++ > 16){ PORTAL_PRINTF( "%s (%s) connect error %s\n",__FUNCTION__, arg_name, strerror(errno)); return -1; } if (trace_socket) PORTAL_PRINTF( "%s (%s) retrying connection\n",__FUNCTION__, arg_name); sleep(1); } if (trace_socket) PORTAL_PRINTF( "%s (%s) connected. Attempts %d\n",__FUNCTION__, arg_name, connect_attempts); return sockfd; } // Taken from: UNIX Network Programming, Richard Stevens // http://www.kohala.com/start/unpv12e.html ssize_t sock_fd_write(int sockfd, void *ptr, size_t nbytes, int sendfd) { struct msghdr msg; struct iovec iov[1]; union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; struct cmsghdr *cmptr; msg.msg_control = control_un.control; msg.msg_controllen = 0; if (sendfd >= 0) { memset(&control_un, 0, sizeof(control_un)); msg.msg_controllen = sizeof(control_un.control); cmptr = CMSG_FIRSTHDR(&msg); cmptr->cmsg_len = CMSG_LEN(sizeof(int)); cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; int *foo = (int *)CMSG_DATA(cmptr); *foo = sendfd; } msg.msg_name = NULL; msg.msg_namelen = 0; iov[0].iov_base = ptr; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; #ifdef __APPLE__ ssize_t bytesSent = send(sockfd, ptr, nbytes, 0); #else ssize_t bytesSent = sendmsg(sockfd, &msg, 0); #endif if (bytesSent != (ssize_t)nbytes) { fprintf(stderr, "[%s:%d] error in sendmsg %ld %d\n", __FUNCTION__, __LINE__, (long)bytesSent, errno); exit(1); } return bytesSent; } ssize_t sock_fd_read(int sockfd, void *ptr, size_t nbytes, int *recvfd) { struct msghdr msg; struct iovec iov[1]; ssize_t n; union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; struct cmsghdr *cmptr; //if (trace_socket) // printf("[%s:%d] sock %d\n", __FUNCTION__, __LINE__, sockfd); msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); msg.msg_name = NULL; msg.msg_namelen = 0; iov[0].iov_base = ptr; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; *recvfd = -1; /* descriptor was not passed */ if ((n = recvmsg(sockfd, &msg, MSG_DONTWAIT)) <= 0) return n; if ((cmptr = CMSG_FIRSTHDR(&msg)) && cmptr->cmsg_len == CMSG_LEN(sizeof(int))) { if (cmptr->cmsg_level != SOL_SOCKET || cmptr->cmsg_type != SCM_RIGHTS) { fprintf(stderr, "%s failed\n", __FUNCTION__); exit(1); } int *datap = (int *)CMSG_DATA(cmptr); *recvfd = *datap; if (trace_socket) fprintf(stderr, "[%s:%d] got fd %d\n", __FUNCTION__, __LINE__, *datap); } if (n != (ssize_t)nbytes) { iov[0].iov_base = (void *)((unsigned long)iov[0].iov_base + n); iov[0].iov_len -= n; if ((n = recvmsg(sockfd, &msg, 0)) <= 0) return n; } return n; } void portalSendFd(int fd, void *data, int len, int sendFd) { int rc; if (trace_socket) fprintf(stderr, "%s: fd %d data %p len %d\n", __FUNCTION__, fd, data, len); if ((rc = sock_fd_write(fd, data, len, sendFd)) != len) { fprintf(stderr, "%s: send len %d error %d\n",__FUNCTION__, rc, errno); exit(1); } } int portalRecvFd(int fd, void *data, int len, int *recvFd) { int rc = sock_fd_read(fd, data, len, recvFd); if (trace_socket && rc && rc != -1) fprintf(stderr, "%s: fd %d data %p len %d rc %d\n", __FUNCTION__, fd, data, len, rc); return rc; } ================================================ FILE: cpp/sock_utils.h ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef _SOCK_UTILS_H_ #define _SOCK_UTILS_H_ #include "portal.h" // ssize_t and uint32_t #define MAX_SIMULATOR_PORTAL_ID 128 #define MAGIC_PORTAL_FOR_SENDING_FD 666 #define MAGIC_PORTAL_FOR_SENDING_INTERRUPT 999 #define SOCKET_NAME bluesimSocketName() typedef struct PortalSocketParam { struct addrinfo *addr; } PortalSocketParam; /* for ITEMINIT function */ struct memrequest{ uint32_t portal; int write_flag; volatile unsigned int *addr; unsigned int data_or_tag; }; struct memresponse{ uint32_t portal; unsigned int data; unsigned int tag; }; #ifdef __cplusplus extern "C" { #endif const char *bluesimSocketName(); void connect_to_bsim(void); ssize_t sock_fd_write(int sockfd, void *ptr, size_t nbytes, int sendfd); ssize_t sock_fd_read(int sockfd, void *ptr, size_t nbytes, int *recvfd); int pareff_fd(int *fd); void init_pareff(void); int init_connecting(const char *arg_name, struct PortalSocketParam *param); int init_listening(const char *arg_name, struct PortalSocketParam *param); int accept_socket(int arg_listening); #ifdef __cplusplus } #endif #endif //_SOCK_UTILS_H_ ================================================ FILE: cpp/timer.c ================================================ // Copyright (c) 2012 Nokia, Inc. // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #define MAX_TIMER_COUNT 16 typedef struct { uint64_t total, min, max, over; } PORTAL_TIMETYPE; static uint64_t c_start[MAX_TIMER_COUNT]; static uint64_t lap_timer_temp; static PORTAL_TIMETYPE timers[MAX_TIMERS]; uint64_t portalCycleCount() { uint64_t high_bits, low_bits; volatile unsigned int *msb, *lsb; initPortalHardware(); if(!utility_portal) return 0; msb = &utility_portal->map_base[PORTAL_CTRL_COUNTER_MSB]; lsb = &utility_portal->map_base[PORTAL_CTRL_COUNTER_LSB]; high_bits = utility_portal->transport->read(utility_portal, &msb); low_bits = utility_portal->transport->read(utility_portal, &lsb); return (high_bits << 32) | low_bits; } void portalTimerStart(unsigned int i) { if (i < MAX_TIMER_COUNT) c_start[i] = portalCycleCount(); } uint64_t portalTimerLap(unsigned int i) { uint64_t temp = portalCycleCount(); if (i >= MAX_TIMER_COUNT) return 0; lap_timer_temp = temp; return temp - c_start[i]; } void portalTimerInit(void) { int i; memset(timers, 0, sizeof(timers)); for (i = 0; i < MAX_TIMERS; i++) timers[i].min = 1LLU << 63; } uint64_t portalTimerCatch(unsigned int i) { uint64_t val = portalTimerLap(0); if (i >= MAX_TIMERS) return 0; if (val > timers[i].max) timers[i].max = val; if (val < timers[i].min) timers[i].min = val; if (val == 000000) timers[i].over++; timers[i].total += val; return lap_timer_temp; } void portalTimerPrint(int loops) { int i; for (i = 0; i < MAX_TIMERS; i++) { if (timers[i].min != (1LLU << 63)) PORTAL_PRINTF("[%d]: avg %" PRIx64 " min %" PRIx64 " max %" PRIx64 " over %" PRIx64 "\n", i, timers[i].total/loops, timers[i].min, timers[i].max, timers[i].over); } } ================================================ FILE: cpp/transportHardware.c ================================================ // Copyright (c) 2012 Nokia, Inc. // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #ifdef __KERNEL__ //#include "linux/delay.h" //#include "linux/file.h" //#include "linux/dma-buf.h" #else #include #include #include #include #endif static int trace_hardware;//=1; void send_portal_null(struct PortalInternal *pint, volatile unsigned int *buffer, unsigned int hdr, int sendFd) { } int recv_portal_null(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) { return 0; } int notfull_null(PortalInternal *pint, unsigned int v) { return 0; } int busy_portal_null(struct PortalInternal *pint, unsigned int v, const char *str) { return 0; } void enableint_portal_null(struct PortalInternal *pint, int val) { } int event_null(struct PortalInternal *pint) { return -1; } unsigned int read_portal_memory(PortalInternal *pint, volatile unsigned int **addr) { unsigned int rc = **addr; *addr += 1; return rc; } void write_portal_memory(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { **addr = v; *addr += 1; } void write_fd_portal_memory(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { **addr = v; *addr += 1; } volatile unsigned int *mapchannel_req_generic(struct PortalInternal *pint, unsigned int v, unsigned int size) { return pint->transport->mapchannelInd(pint, v); } volatile unsigned int *mapchannel_hardware(struct PortalInternal *pint, unsigned int v) { return &pint->map_base[PORTAL_FIFO(v)]; } int notfull_hardware(PortalInternal *pint, unsigned int v) { volatile unsigned int *tempp = pint->transport->mapchannelInd(pint, v) + 1; return pint->transport->read(pint, &tempp); } int busy_hardware(struct PortalInternal *pint, unsigned int v, const char *str) { int count = 50; while (!pint->transport->notFull(pint, v) && ((pint->busyType == BUSY_SPIN) || count-- > 0)) ; /* busy wait a bit on 'fifo not full' */ if (count <= 0) { if (0 && pint->busyType == BUSY_TIMEWAIT) while (!pint->transport->notFull(pint, v)) { #ifndef __KERNEL__ struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000; select(0, NULL, NULL, NULL, &timeout); #endif } else { /* PORTAL_PRINTF("putFailed: %s\n", str); */ #ifndef __KERNEL__ if (pint->busyType == BUSY_EXIT) exit(1); #endif return 1; } } return 0; } void enableint_hardware(struct PortalInternal *pint, int val) { volatile unsigned int *enp = &(pint->map_base[PORTAL_CTRL_INTERRUPT_ENABLE]); pint->transport->write(pint, &enp, val); } int event_hardware(struct PortalInternal *pint) { // handle all messasges from this portal instance volatile unsigned int *map_base = pint->map_base; // sanity check, to see the status of interrupt source and enable unsigned int queue_status; volatile unsigned int *statp = &map_base[PORTAL_CTRL_IND_QUEUE_STATUS]; volatile unsigned int *srcp = &map_base[PORTAL_CTRL_INTERRUPT_STATUS]; volatile unsigned int *enp = &map_base[PORTAL_CTRL_INTERRUPT_ENABLE]; while ((queue_status = pint->transport->read(pint, &statp))) { if(trace_hardware) { unsigned int int_src = pint->transport->read(pint, &srcp); unsigned int int_en = pint->transport->read(pint, &enp); PORTAL_PRINTF( "%s: (fpga%d) about to receive messages int=%08x en=%08x qs=%08x handler %p parent %p\n", __FUNCTION__, pint->fpga_number, int_src, int_en, queue_status, pint->handler, pint->parent); } if (pint->handler) pint->handler(pint, queue_status-1, 0); else { unsigned int int_src = pint->transport->read(pint, &srcp); unsigned int int_en = pint->transport->read(pint, &enp); PORTAL_PRINTF( "%s: (fpga%d) no handler receive int=%08x en=%08x qs=%08x handler %p parent %p\n", __FUNCTION__, pint->fpga_number, int_src, int_en, queue_status, pint->handler, pint->parent); exit(-1); } } return -1; } static int init_hardware(struct PortalInternal *pint, void *param) { initPortalHardware(); #if defined(__KERNEL__) int i; pint->map_base = NULL; for (i = 0; i < MAX_NUM_PORTALS; i++) { if (tboard->portal[i].device_name == pint->fpga_number) { pint->map_base = (volatile unsigned int*)(tboard->bar2io + i * PORTAL_BASE_OFFSET); break; } } if (!pint->map_base) { PORTAL_PRINTF("init_hardware: portal not found %d.\n", pint->fpga_number); return -1; } #else char oldname[128]; char newname[128]; int i; snprintf(oldname, sizeof(oldname), "/dev/portal_%d_%d", pint->fpga_tile, pint->fpga_number); snprintf(newname, sizeof(newname), "/dev/portal_b%dt%dp%d", pint->board_number, pint->fpga_tile, pint->fpga_number); //FIXME: race condition on Zynq between cat /dev/connectal and here for (i = 0; i < 5; i++) { // try old style name pint->fpga_fd = open(oldname, O_RDWR); if (pint->fpga_fd >= 0) break; // try new style name pint->fpga_fd = open(newname, O_RDWR); if (pint->fpga_fd >= 0) break; // retry if EACCESS if (errno == EACCES && i != 4) { sleep(1); continue; } // else fail PORTAL_PRINTF("Failed to open %s fd=%d errno=%d:%s\n", oldname, pint->fpga_fd, errno, strerror(errno)); return -errno; } pint->map_base = (volatile unsigned int*)portalMmap(pint->fpga_fd, PORTAL_BASE_OFFSET); if (pint->map_base == MAP_FAILED) { PORTAL_PRINTF("Failed to mmap PortalHWRegs from fd=%d errno=%d\n", pint->fpga_fd, errno); return -errno; } #endif return 0; } static unsigned int read_hardware(PortalInternal *pint, volatile unsigned int **addr) { return **addr; } static void write_hardware(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { **addr = v; } static void write_fd_hardware(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { **addr = v; } PortalTransportFunctions transportHardware = { init_hardware, read_hardware, write_hardware, write_fd_hardware, mapchannel_hardware, mapchannel_req_generic, send_portal_null, recv_portal_null, busy_hardware, enableint_hardware, event_hardware, notfull_hardware}; ================================================ FILE: cpp/transportPortal.c ================================================ // Copyright (c) 2018, The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #include #include #include #include static int trace_portal=0; static void enableint_portal(struct PortalInternal *pint, int val) { pint->map_base[PORTAL_CTRL_INTERRUPT_ENABLE] = val; } static int event_portal(struct PortalInternal *pint) { // handle all messasges from this portal instance volatile unsigned int *map_base = pint->map_base, len; while ((len = map_base[PORTAL_CTRL_IND_QUEUE_STATUS])) { if(trace_portal) PORTAL_PRINTF( "%s: (fpga%d) about to receive messages int=%08x en=%08x qs=%08x handler %p parent %p\n", __FUNCTION__, pint->fpga_number, 0, 0, 0, pint->handler, pint->parent); if (pint->handler) pint->handler(pint, 5/*portal number ATOMICC */, 0); else { PORTAL_PRINTF( "%s: (fpga%d) no handler receive int=%08x en=%08x qs=%08x handler %p parent %p\n", __FUNCTION__, pint->fpga_number, 0, 0, 0, pint->handler, pint->parent); exit(-1); } } return -1; } static volatile unsigned int *portalPtr; static int init_portal(struct PortalInternal *pint, void *param) { initPortalHardware(); char oldname[128]; int i; snprintf(oldname, sizeof(oldname), "/dev/portal_%d_%d", pint->fpga_tile, pint->fpga_number); //FIXME: race condition on Zynq between cat /dev/connectal and here for (i = 0; i < 5; i++) { // try old style name pint->fpga_fd = open(oldname, O_RDWR); if (pint->fpga_fd >= 0) break; // retry if EACCESS if (errno == EACCES && i != 4) { sleep(1); continue; } // else fail PORTAL_PRINTF("Failed to open %s fd=%d errno=%d:%s\n", oldname, pint->fpga_fd, errno, strerror(errno)); return -errno; } pint->map_base = (volatile unsigned int*)portalMmap(pint->fpga_fd, PORTAL_BASE_OFFSET); if (pint->map_base == MAP_FAILED) { PORTAL_PRINTF("Failed to mmap PortalHWRegs from fd=%d errno=%d\n", pint->fpga_fd, errno); return -errno; } portalPtr = &pint->map_base[PORTAL_FIFO(0)]; return 0; } static void send_portal(struct PortalInternal *pint, volatile unsigned int *data, unsigned int hdr, int sendFd) { volatile unsigned int *buffer = data-1; //if(trace_portal) fprintf(stderr, "[%s:%d] hdr %x fpga %x num %d\n", __FUNCTION__, __LINE__, hdr, pint->fpga_number, pint->client_fd_number); buffer[0] = hdr; if (!portalPtr[1]) { printf("[%s:%d] ERROR: queue full\n", __FUNCTION__, __LINE__); return; } int i = (hdr & 0xffff) - 2; for (; i > 0; i--) { printf("[SEND] data[%d] = %x\n", i, data[i]); portalPtr[0] = data[i]; } printf("[SEND] Ldata[%d] = %x\n", 0, data[0]); portalPtr[1] = data[0]; } static int recv_portal(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) { int i; for (i = 0; i < len; i++) { buffer[i] = portalPtr[0]; printf("[RECV] data[%d] = %x\n", i, buffer[i]); } return 0; } PortalTransportFunctions transportPortal = { init_portal, NULL, NULL, NULL, NULL, NULL, send_portal, recv_portal, NULL, enableint_portal, event_portal, NULL}; ================================================ FILE: cpp/transportSerial.c ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include "portal.h" #include "dmaManager.h" #include "sock_utils.h" #ifdef __KERNEL__ #include "linux/delay.h" #include "linux/file.h" #include "linux/dma-buf.h" #define assert(A) #else #include #include #include #include #include #include #include #include #include // ctime #endif #include "drivers/portalmem/portalmem.h" // PA_MALLOC #define PLATFORM_TILE 0 static int init_serial(struct PortalInternal *pint, void *aparam) { PortalSharedParam *param = (PortalSharedParam *)aparam; if (param) { int serial_fd = param->serial.serial_fd; pint->map_base = (volatile unsigned int *)malloc(4096); pint->client_fd[0] = serial_fd; pint->client_fd_number = 1; fprintf(stderr, "init_serial param=%p pint=%p serial_fd=%d map_base=%p\n", param, pint, param->serial.serial_fd, pint->map_base); if (0) { struct termios terminfo; int rc; tcflush(serial_fd, TCIOFLUSH); tcgetattr(serial_fd, &terminfo); terminfo.c_cflag = CS8 | CLOCAL | CREAD | PARENB; terminfo.c_cflag &= ~CRTSCTS; // needed for /dev/tty.SLAB_USBtoUART terminfo.c_iflag = IGNCR; terminfo.c_lflag = ICANON; cfsetspeed(&terminfo, B115200); rc = tcsetattr(serial_fd, TCSANOW, &terminfo); if (rc != 0) { fprintf(stderr, "tcsetattr %d errno %d:%s\n", rc, errno, strerror(errno)); } } } return 0; } static volatile unsigned int *mapchannel_serialInd(struct PortalInternal *pint, unsigned int v) { return &pint->map_base[128+1]; } static volatile unsigned int *mapchannel_serialReq(struct PortalInternal *pint, unsigned int v, unsigned int size) { return &pint->map_base[0+1]; } static int busywait_serial(struct PortalInternal *pint, unsigned int v, const char *str) { return 0; } static void send_serial(struct PortalInternal *pint, volatile unsigned int *buffer, unsigned int hdr, int sendFd) { int reqwords = hdr & 0xffff; int i; fprintf(stderr, "send_serial head=%d hdr=%08x reqwords=%d buffer=%p buffer[1]=%08x buffer[2]=%08x\n", buffer[0], hdr, reqwords, buffer, buffer[1], buffer[2]); buffer[0] = hdr; if (0) for (i = 0; i < reqwords+1; i++) buffer[i] = htonl(buffer[i]); int nbytes = write(pint->client_fd[0], (void*)buffer, 4*reqwords); if (nbytes != 4*reqwords) { fprintf(stderr, "%s:%x pint=%p fd=%d nbytes=%d errno=%d:%s\n", __FUNCTION__, __LINE__, pint, pint->client_fd[0], nbytes, errno, strerror(errno)); } buffer[0] = 0; //tcdrain(pint->client_fd[0]); } static int event_serial(struct PortalInternal *pint) { if (0) fprintf(stderr, "%s:%d serial_fd=%d\n", __FUNCTION__, __LINE__, pint->client_fd[0]); int nbytes; int i = 0; char *base = (char *)&pint->map_base[128]; int tries = 0; do { nbytes = read(pint->client_fd[0], (void*)(base + i), 4); if (nbytes > 0) i += nbytes; if (0) fprintf(stderr, "%s:%d i=%d nbytes=%d hdr=%#08x\n", __FUNCTION__, __LINE__, i, nbytes, pint->map_base[128]); if (i >= 4) { int reqwords = pint->map_base[128] & 0xFFFF; int msg_num = pint->map_base[128] >> 16; if (reqwords > 1) { nbytes = read(pint->client_fd[0], (void*)&pint->map_base[129], 4*(reqwords-1)); if (nbytes < 4*(reqwords-1)) fprintf(stderr, "SHORT READ %s:%d i=%d nbytes=%d buffer=%p msgbody[0]=%08x\n", __FUNCTION__, __LINE__, i, nbytes, &pint->map_base[128], pint->map_base[128+1]); } if (msg_num != 0xFFFF && pint->handler) pint->handler(pint, msg_num, 0); i = 0; } } while (nbytes > 0 || tries-- > 0); return -1; } PortalTransportFunctions transportSerial = { init_serial, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_serialInd, mapchannel_serialReq, send_serial, recv_portal_null, busywait_serial, enableint_portal_null, event_serial, notfull_null}; static int init_serialmux(struct PortalInternal *pint, void *aparam) { PortalMuxParam *param = (PortalMuxParam *)aparam; fprintf(stderr, "%s:%d pint=%p client_fd=%d\n", __FUNCTION__, __LINE__, pint, pint->client_fd[0]); pint->mux = param->pint; pint->map_base = ((volatile unsigned int*)malloc(REQINFO_SIZE(pint->reqinfo) + sizeof(uint32_t))) + 1; memset((void *)(pint->map_base-1), 0, REQINFO_SIZE(pint->reqinfo) + sizeof(uint32_t)); // for valgrind pint->mux->map_base[0] = -1; pint->mux->mux_ports_number++; pint->mux->mux_ports = (PortalMuxHandler *)realloc(pint->mux->mux_ports, pint->mux->mux_ports_number * sizeof(PortalMuxHandler)); pint->mux->mux_ports[pint->mux->mux_ports_number-1].pint = pint; return 0; } static void send_serialmux(struct PortalInternal *pint, volatile unsigned int *data, unsigned int hdr, int sendFd) { volatile unsigned int *buffer = data-1; buffer[0] = hdr; fprintf(stderr, "%s:%d pint=%p mux=%p map_base=%p mux->map_base=%p buffer=%p\n", __FUNCTION__, __LINE__, pint, pint->mux, pint->map_base, pint->mux->map_base, buffer); pint->mux->request_index = pint->request_index; pint->mux->transport->send(pint->mux, buffer, (pint->fpga_number << 24) | hdr, sendFd); } static int recv_serialmux(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) { return pint->mux->transport->recv(pint->mux, buffer, len, recvfd); } int portal_serialmux_handler(struct PortalInternal *pint, unsigned int channel, int messageFd) { int i; unsigned int fpga_number = (channel >> 8) & 0xFF; unsigned int msg_number = (channel >> 0) & 0xFF; fprintf(stderr, "%s:%d channel=%x\n", __FUNCTION__, __LINE__, channel); for (i = 0; i < pint->mux_ports_number; i++) { PortalInternal *p = pint->mux_ports[i].pint; int hdr = pint->map_base[128]; int reqwords = hdr & 0xffff; memcpy((void *)&p->map_base[128], (void *)&pint->map_base[128], 4*reqwords); if (fpga_number == p->fpga_number && p->handler) { p->handler(p, msg_number, messageFd); } } return -1; } PortalTransportFunctions transportSerialMux = { init_serialmux, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_serialInd, mapchannel_req_generic, send_serialmux, recv_serialmux, busy_portal_null, enableint_portal_null, event_null, notfull_null}; ================================================ FILE: cpp/transportShared.c ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #include "dmaManager.h" #include "sock_utils.h" #ifdef __KERNEL__ #include "linux/delay.h" #include "linux/file.h" #include "linux/dma-buf.h" #define assert(A) #else #include #include #include #include #include #include #include #include // ctime #endif #include "drivers/portalmem/portalmem.h" // PA_MALLOC #define PLATFORM_TILE 0 static int init_shared(struct PortalInternal *pint, void *aparam) { PortalSharedParam *param = (PortalSharedParam *)aparam; if (param) { int fd = portalAlloc(param->size, 1); pint->map_base = (volatile unsigned int *)portalMmap(fd, param->size); pint->map_base[SHARED_LIMIT] = param->size/sizeof(uint32_t); pint->map_base[SHARED_WRITE] = SHARED_START; pint->map_base[SHARED_READ] = SHARED_START; pint->map_base[SHARED_START] = 0; if (param->dma.manager) pint->shared_dma = ¶m->dma.manager->priv; else if (param->dma.reqinfo) { PortalInternal *psgl = (PortalInternal *)malloc(sizeof(PortalInternal)); init_portal_internal(psgl, param->dma.reqport, PLATFORM_TILE, NULL, NULL, NULL, NULL, NULL, param->dma.reqinfo); DmaManagerPrivate *p = (DmaManagerPrivate *)malloc(sizeof(DmaManagerPrivate)); pint->shared_dma = p; DmaManager_init(p, psgl); p->poll = param->dma.poll; p->shared_mmu_indication = (PortalInternal *)malloc(sizeof(PortalInternal)); init_portal_internal(p->shared_mmu_indication, param->dma.indport, PLATFORM_TILE, param->dma.handler, param->dma.callbackFunctions, NULL, NULL, NULL, param->dma.indinfo); } DmaManagerPrivate *p = (DmaManagerPrivate *)pint->shared_dma; if (p) { pint->sharedMem = DmaManager_reference(p, fd); MMURequest_setInterface(p->sglDevice, pint->fpga_number, pint->sharedMem); } if (param->hardware.setSglId) { PortalInternal *p = (PortalInternal *)malloc(sizeof(PortalInternal)); pint->shared_cfg = p; init_portal_internal(p, param->hardware.port, pint->fpga_tile, NULL, NULL, NULL, NULL, NULL, param->hardware.reqinfo); param->hardware.setSglId(p, pint->sharedMem); } } return 0; } static volatile unsigned int *mapchannel_sharedInd(struct PortalInternal *pint, unsigned int v) { return &pint->map_base[pint->map_base[SHARED_READ]+1]; } static volatile unsigned int *mapchannel_sharedReq(struct PortalInternal *pint, unsigned int v, unsigned int size) { return &pint->map_base[pint->map_base[SHARED_WRITE]+1]; } static int busywait_shared(struct PortalInternal *pint, unsigned int v, const char *str) { int reqwords = REQINFO_SIZE(pint->reqinfo)/sizeof(uint32_t) + 1; reqwords = (reqwords + 1) & 0xfffe; volatile unsigned int *map_base = pint->map_base; int limit = map_base[SHARED_LIMIT]; while (1) { int write = map_base[SHARED_WRITE]; int read = map_base[SHARED_READ]; int avail; if (write >= read) { avail = limit - (write - read) - 4; } else { avail = read - write; } int enqready = (avail > 2*reqwords); // might have to wrap //fprintf(stderr, "busywait_shared limit=%d write=%d read=%d avail=%d enqready=%d\n", limit, write, read, avail, enqready); if (avail < reqwords) fprintf(stderr, "****\n not enough space available \n****\n"); if (enqready) return 0; } return 0; } static inline unsigned int increment_shared(PortalInternal *pint, unsigned int newp) { int reqwords = REQINFO_SIZE(pint->reqinfo)/sizeof(uint32_t) + 1; reqwords = (reqwords + 1) & 0xfffe; if (newp + reqwords >= pint->map_base[SHARED_LIMIT]) newp = SHARED_START; return newp; } static void send_shared(struct PortalInternal *pint, volatile unsigned int *buff, unsigned int hdr, int sendFd) { int reqwords = hdr & 0xffff; int needs_padding = (reqwords & 1); pint->map_base[pint->map_base[SHARED_WRITE]] = hdr; if (needs_padding) { // pad req pint->map_base[pint->map_base[SHARED_WRITE] + reqwords] = 0xffff0001; reqwords = (reqwords + 1) & 0xfffe; } pint->map_base[SHARED_WRITE] = increment_shared(pint, pint->map_base[SHARED_WRITE] + reqwords); //fprintf(stderr, "send_shared head=%d padded=%d hdr=%08x\n", pint->map_base[SHARED_WRITE], needs_padding, hdr); pint->map_base[pint->map_base[SHARED_WRITE]] = 0; } static int event_shared(struct PortalInternal *pint) { if (pint->map_base && pint->map_base[SHARED_READ] != pint->map_base[SHARED_WRITE]) { unsigned int hdr = pint->map_base[pint->map_base[SHARED_READ]]; unsigned short msg_num = hdr >> 16; unsigned short msg_words = hdr & 0xffff; msg_words = (msg_words + 1) & 0xfffe; if (msg_num != 0xffff && pint->handler) pint->handler(pint, msg_num, 0); pint->map_base[SHARED_READ] = increment_shared(pint, pint->map_base[SHARED_READ] + msg_words); } return -1; } PortalTransportFunctions transportShared = { init_shared, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_sharedInd, mapchannel_sharedReq, send_shared, recv_portal_null, busywait_shared, enableint_portal_null, event_shared, notfull_null}; static volatile unsigned int *mapchannel_traceInd(struct PortalInternal *pint, unsigned int v) { return &pint->map_base[pint->map_base[SHARED_READ]]; } static volatile unsigned int *mapchannel_traceReq(struct PortalInternal *pint, unsigned int v, unsigned int size) { return &pint->map_base[pint->map_base[SHARED_WRITE]]; } extern void memdump(uint8_t *p, int len, const char *title); static void send_trace(struct PortalInternal *pint, volatile unsigned int *buff, unsigned int hdr, int sendFd) { int reqwords = hdr & 0xffff; pint->map_base[pint->map_base[SHARED_WRITE]+reqwords-1] = hdr; pint->map_base[SHARED_WRITE] = increment_shared(pint, pint->map_base[SHARED_WRITE] + reqwords); //fprintf(stderr, "send_shared head=%d padded=%d hdr=%08x\n", pint->map_base[SHARED_WRITE], needs_padding, hdr); pint->map_base[pint->map_base[SHARED_WRITE]] = 0; } PortalTransportFunctions transportTrace = { init_shared, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_traceInd, mapchannel_traceReq, send_trace, recv_portal_null, busywait_shared, enableint_portal_null, event_shared, notfull_null}; ================================================ FILE: cpp/transportSocket.c ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "portal.h" #include "sock_utils.h" #include static int trace_socket; // = 1; #ifndef __KERNEL__ #include #include #include #include #include #include // FIONBIO #include #include #include #include #include #include void memdump(unsigned char *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) fprintf(stderr, "\n"); fprintf(stderr, "%s: ",title); } fprintf(stderr, "%02x ", *p++); i++; len--; } fprintf(stderr, "\n"); } static pthread_mutex_t socket_mutex; int global_sockfd = -1; static int init_socketResp(struct PortalInternal *pint, void *aparam) { //initPortalHardware(); PortalSocketParam *param = (PortalSocketParam *)aparam; char buff[128]; int on = 1; const char *name = getenv("SOFTWARE_SOCKET_NAME"); if (!name) name = "SWSOCK"; sprintf(buff, "%s%d", name, pint->fpga_number); pint->fpga_fd = init_listening(buff, param); ioctl(pint->fpga_fd, FIONBIO, &on); pint->map_base = (volatile unsigned int*)malloc(REQINFO_SIZE(pint->reqinfo)); memset((void *)pint->map_base, 0, REQINFO_SIZE(pint->reqinfo)); // for valgrind pint->poller_register = 1; return 0; } static int init_socketInit(struct PortalInternal *pint, void *aparam) { #if defined(SIMULATION) || !defined(__ATOMICC__) initPortalHardware(); #endif PortalSocketParam *param = (PortalSocketParam *)aparam; char buff[128]; const char *name = getenv("SOFTWARE_SOCKET_NAME"); if (!name) name = "SWSOCK"; sprintf(buff, "%s%d", name, pint->fpga_number); pint->client_fd[pint->client_fd_number++] = init_connecting(buff, param); pint->accept_finished = 1; pint->map_base = (volatile unsigned int*)malloc(REQINFO_SIZE(pint->reqinfo)); memset((void *)pint->map_base, 0, REQINFO_SIZE(pint->reqinfo)); // for valgrind pint->poller_register = 1; return 0; } volatile unsigned int *mapchannel_socket(struct PortalInternal *pint, unsigned int v) { return &pint->map_base[1]; } static int recv_socket(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) { int rc = portalRecvFd(pint->client_fd[pint->indication_index], (void *)buffer, len * sizeof(uint32_t), recvfd); if(trace_socket) { fprintf(stderr, "[%s:%d] len %d fd %d rc %d\n", __FUNCTION__, __LINE__, len, pint->client_fd[pint->indication_index], rc); if (rc > 0) { char bname[100]; sprintf(bname,"RECV%d.%d", getpid(), pint->client_fd[pint->indication_index]); memdump((uint8_t*)buffer, rc, bname); } } return rc; } static int event_socket(struct PortalInternal *pint) { int i, j, event_socket_fd; for (i = 0; i < pint->client_fd_number;) { int len = portalRecvFd(pint->client_fd[i], (void *)pint->map_base, sizeof(uint32_t), &event_socket_fd); if (len==sizeof(uint32_t) && trace_socket) fprintf(stderr, "[%s:%d] %d\n", __FUNCTION__, __LINE__, pint->map_base[0]); if (len == 0) { /* EOF */ close(pint->client_fd[i]); pint->client_fd_number--; for (j = i; j < pint->client_fd_number; j++) pint->client_fd[j] = pint->client_fd[j+1]; if (pint->cb) pint->cb->disconnect(pint); } else if (len == -1 && errno == EAGAIN) { i++; continue; } else if (len == -1) { PORTAL_PRINTF( "%s[%d]: read error %d\n",__FUNCTION__, pint->client_fd[i], errno); exit(1); } pint->indication_index = i; if (pint->handler) pint->handler(pint, *pint->map_base >> 16, event_socket_fd); break; } if (pint->fpga_fd != -1) { int sockfd = accept_socket(pint->fpga_fd); if (sockfd != -1) { if (trace_socket) fprintf(stderr, "[%s:%d]afteracc %p accfd %d fd %d\n", __FUNCTION__, __LINE__, pint, pint->fpga_fd, sockfd); pint->client_fd[pint->client_fd_number++] = sockfd; pint->accept_finished = 1; #ifndef NO_CPP_PORTAL_CODE #ifndef NO_POLLER_SUPPORT if (pint->poller) addFdToPoller(pint->poller, sockfd); #endif #endif //return sockfd; } } return -1; } static void send_socket(struct PortalInternal *pint, volatile unsigned int *data, unsigned int hdr, int sendFd) { volatile unsigned int *buffer = data-1; if(trace_socket) fprintf(stderr, "[%s:%d] hdr %x fpga %x num %d\n", __FUNCTION__, __LINE__, hdr, pint->fpga_number, pint->client_fd_number); buffer[0] = hdr; while (pint->client_fd_number == 0) event_socket(pint); if(trace_socket) { char bname[100]; sprintf(bname,"SEND%d.%d", getpid(), pint->client_fd[pint->request_index]); memdump((uint8_t*)buffer, (hdr & 0xffff) * sizeof(uint32_t), bname); } portalSendFd(pint->client_fd[pint->request_index], (void *)buffer, (hdr & 0xffff) * sizeof(uint32_t), sendFd); } PortalTransportFunctions transportSocketResp = { init_socketResp, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_socket, mapchannel_req_generic, send_socket, recv_socket, busy_portal_null, enableint_portal_null, event_socket, notfull_null}; PortalTransportFunctions transportSocketInit = { init_socketInit, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_socket, mapchannel_req_generic, send_socket, recv_socket, busy_portal_null, enableint_portal_null, event_socket, notfull_null}; static int init_mux(struct PortalInternal *pint, void *aparam) { //initPortalHardware(); PortalMuxParam *param = (PortalMuxParam *)aparam; if(trace_socket) fprintf(stderr, "[%s:%d]\n", __FUNCTION__, __LINE__); pint->mux = param->pint; pint->map_base = ((volatile unsigned int*)malloc(REQINFO_SIZE(pint->reqinfo) + sizeof(uint32_t))) + 1; memset((void *)(pint->map_base-1), 0, REQINFO_SIZE(pint->reqinfo) + sizeof(uint32_t)); // for valgrind pint->mux->map_base[0] = -1; pint->mux->mux_ports_number++; pint->mux->mux_ports = (PortalMuxHandler *)realloc(pint->mux->mux_ports, pint->mux->mux_ports_number * sizeof(PortalMuxHandler)); pint->mux->mux_ports[pint->mux->mux_ports_number-1].pint = pint; return 0; } static void send_mux(struct PortalInternal *pint, volatile unsigned int *data, unsigned int hdr, int sendFd) { volatile unsigned int *buffer = data-1; if(trace_socket) fprintf(stderr, "[%s:%d] hdr %x fpga %x\n", __FUNCTION__, __LINE__, hdr, pint->fpga_number); buffer[0] = hdr; pint->mux->request_index = pint->request_index; pint->mux->transport->send(pint->mux, buffer, (pint->fpga_number << 16) | ((hdr + 1) & 0xffff), sendFd); } static int recv_mux(struct PortalInternal *pint, volatile unsigned int *buffer, int len, int *recvfd) { return pint->mux->transport->recv(pint->mux, buffer, len, recvfd); } int portal_mux_handler(struct PortalInternal *pint, unsigned int channel, int messageFd) { int i, dummy; for (i = 0; i < pint->mux_ports_number; i++) { PortalInternal *p = pint->mux_ports[i].pint; if (channel == p->fpga_number && p->handler) { p->transport->recv(p, p->map_base, 1, &dummy); if (connectalPrintfHandler && (*p->map_base >> 16) == CONNECTAL_PRINTF_PORT) connectalPrintfHandler(p, *p->map_base); else p->handler(p, *p->map_base >> 16, messageFd); } } return -1; } PortalTransportFunctions transportMux = { init_mux, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_socket, mapchannel_req_generic, send_mux, recv_mux, busy_portal_null, enableint_portal_null, event_null, notfull_null}; /* * BOARD_bluesim */ static struct memresponse shared_response; static int shared_response_valid; static uint32_t interrupt_value; int poll_response(uint32_t id) { int recvFd; if (!shared_response_valid) { if (portalRecvFd(global_sockfd, &shared_response, sizeof(shared_response), &recvFd) == sizeof(shared_response)) { if (shared_response.portal == MAGIC_PORTAL_FOR_SENDING_INTERRUPT) interrupt_value = shared_response.data; else shared_response_valid = 1; } } return shared_response_valid && shared_response.portal == id; } unsigned int bsim_poll_interrupt(void) { if (global_sockfd == -1) return 0; pthread_mutex_lock(&socket_mutex); poll_response(-1); pthread_mutex_unlock(&socket_mutex); return interrupt_value; } #else // __KERNEL__ /* * Used when running application in kernel and BOARD_bluesim in userspace */ #include #include // copy_to/from_user #include #include #include #include extern struct semaphore bsim_start; static struct semaphore bsim_avail; static struct semaphore bsim_have_response; void memdump(unsigned char *p, int len, char *title); static int have_request; static struct memrequest upreq; static struct memresponse downresp; extern int bsim_relay_running; extern int main_program_finished; ssize_t connectal_kernel_read (struct file *f, char __user *arg, size_t len, loff_t *data) { int err; if (!bsim_relay_running) up(&bsim_start); bsim_relay_running = 1; if (main_program_finished) return 0; // all done! if (!have_request) return -EAGAIN; if (len > sizeof(upreq)) len = sizeof(upreq); if (upreq.write_flag == MAGIC_PORTAL_FOR_SENDING_FD) // part of sock_fd_write() processing upreq.addr = (void *)(long)dma_buf_fd((struct dma_buf *)upreq.addr, O_CLOEXEC); /* get an fd in user process!! */ err = copy_to_user((void __user *) arg, &upreq, len); have_request = 0; up(&bsim_avail); return len; } ssize_t connectal_kernel_write (struct file *f, const char __user *arg, size_t len, loff_t *data) { int err; if (len > sizeof(downresp)) len = sizeof(downresp); err = copy_from_user(&downresp, (void __user *) arg, len); if (!err) up(&bsim_have_response); return len; } void connect_to_bsim(void) { printk("[%s:%d]\n", __FUNCTION__, __LINE__); if (bsim_relay_running) return; sema_init (&bsim_avail, 1); sema_init (&bsim_have_response, 0); initialize_bsim_map(); printk("[%s:%d]\n", __FUNCTION__, __LINE__); down_interruptible(&bsim_start); } static struct memresponse shared_response; static int shared_response_valid; static uint32_t interrupt_value; static int poll_response(int id) { //int recvFd; if (!shared_response_valid) { #if 0 if (portalRecvFd(global_sockfd, &shared_response, sizeof(shared_response), &recvFd) == sizeof(shared_response)) { if (shared_response.portal == MAGIC_PORTAL_FOR_SENDING_INTERRUPT) interrupt_value = shared_response.data; else shared_response_valid = 1; } #endif } return shared_response_valid && shared_response.portal == id; } #endif ================================================ FILE: cpp/transportWebSocket.c ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include "portal.h" #include "sock_utils.h" #include "libwebsockets.h" #define MAX_ZEDBOARD_PAYLOAD 4096 struct per_session_data_connectal { }; #define WEB(P) ((struct per_session_data_connectal *)(P)->websock) static int connect_proceed; static int websock_trace ;//= 1; static int callback_connectal(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { PortalInternal *pint = (PortalInternal *)libwebsocket_context_user(context); switch (reason) { case LWS_CALLBACK_CLIENT_ESTABLISHED: connect_proceed = 1; case LWS_CALLBACK_ESTABLISHED: if (websock_trace) fprintf(stderr, "LWS/ESTABLISHED %d context %p pint %p wsi %p user %p in %p len %ld fd %d\n", reason, context, pint, wsi, user, in, (long)len, libwebsocket_get_socket_fd(wsi)); pint->websock = user; pint->websock_wsi = wsi; if (pint->poller) addFdToPoller(pint->poller, libwebsocket_get_socket_fd(wsi)); else pint->fpga_fd = libwebsocket_get_socket_fd(wsi); break; case LWS_CALLBACK_ADD_POLL_FD: if (websock_trace) fprintf(stderr, "LWS_CALLBACK_ADD_POLL_FD %p wsi %p poller %p fd %d.\n", context, wsi, pint->poller, libwebsocket_get_socket_fd(wsi)); if (pint->poller) addFdToPoller(pint->poller, libwebsocket_get_socket_fd(wsi)); else pint->fpga_fd = libwebsocket_get_socket_fd(wsi); break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: fprintf(stderr, "LWS_CALLBACK_CLIENT_CONNECTION_ERROR context %p wsi %p user %p in %p len %ld\n", context, wsi, user, in, (long)len); pint->websock = user; pint->websock_wsi = wsi; break; case LWS_CALLBACK_CLOSED: fprintf(stderr, "LWS_CALLBACK_CLOSED context %p pint %p\n", context, pint); pint->websock = user; pint->websock_wsi = wsi; break; case LWS_CALLBACK_RECEIVE: case LWS_CALLBACK_CLIENT_RECEIVE: { if (websock_trace) fprintf(stderr, "LWS_CALLBACK_RECEIVE context %p pint %p user %p len %ld\n", context, pint, user, (long)len); if (pint->handler) { pint->map_base[0] = len+1; memcpy((void *)&pint->map_base[1], in, len); pint->handler(pint, 0, 0); memset((void *)pint->map_base, 0, 16); } break; } case LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: case LWS_CALLBACK_SERVER_WRITEABLE: case LWS_CALLBACK_CLIENT_WRITEABLE: case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: case LWS_CALLBACK_PROTOCOL_INIT: case LWS_CALLBACK_WSI_CREATE: case LWS_CALLBACK_WSI_DESTROY: case LWS_CALLBACK_CLOSED_HTTP: case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: case LWS_CALLBACK_GET_THREAD_ID: case LWS_CALLBACK_LOCK_POLL: case LWS_CALLBACK_UNLOCK_POLL: case LWS_CALLBACK_CHANGE_MODE_POLL_FD: case LWS_CALLBACK_DEL_POLL_FD: break; default: printf("[%s:%d] reason %d\n", __FUNCTION__, __LINE__, reason); break; } return 0; } static int event_webSocket(struct PortalInternal *pint) { libwebsocket_service((struct libwebsocket_context *)pint->websock_context, 1); } #define HANDLE(A) \ static struct libwebsocket_protocols protocols ## A[] = { \ /* first protocol must always be HTTP handler */ \ { "connectal" # A, callback_connectal, sizeof(struct per_session_data_connectal) }, { NULL, NULL, 0 } }; HANDLE(0); HANDLE(1); HANDLE(2); HANDLE(3); HANDLE(4); HANDLE(5); HANDLE(6); HANDLE(7); HANDLE(8); HANDLE(9); HANDLE(10); HANDLE(11); HANDLE(12); HANDLE(13); HANDLE(14); HANDLE(15); #define NHANDLE(A) protocols ## A static struct libwebsocket_protocols *protocols[] = { NHANDLE(0), NHANDLE(1), NHANDLE(2), NHANDLE(3), NHANDLE(4), NHANDLE(5), NHANDLE(6), NHANDLE(7), NHANDLE(8), NHANDLE(9), NHANDLE(10), NHANDLE(11), NHANDLE(12), NHANDLE(13), NHANDLE(14), NHANDLE(15) }; static void get_context(PortalInternal *pint, int port) { struct lws_context_creation_info info = {0}; pint->poller_register = 1; info.port = port; info.protocols = protocols[pint->fpga_number]; info.gid = -1; info.uid = -1; info.user = pint; pint->websock_context = libwebsocket_create_context(&info); if (!pint->websock_context) { lwsl_err("libwebsocket init failed\n"); exit(-1); } } static int init_webSocketInit(struct PortalInternal *pint, void *aparam) { PortalSocketParam *param = (PortalSocketParam *)aparam; unsigned short port = 5050; char buffer[INET6_ADDRSTRLEN]; pint->map_base = (volatile unsigned int *)malloc(4+MAX_ZEDBOARD_PAYLOAD+1); memset((void *)pint->map_base, 0, 4+MAX_ZEDBOARD_PAYLOAD+1); // for valgrind if (param->addr->ai_family == AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)param->addr->ai_addr; port = htons(sa->sin_port); } else if (param->addr->ai_family == AF_INET6) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)param->addr->ai_addr; port = htons(sa->sin6_port); } if (websock_trace) fprintf(stderr, "[%s:%d] connecting addr=%p ai_family=%d port %d\n", __FUNCTION__, __LINE__, param->addr->ai_addr, param->addr->ai_family, port); get_context(pint, CONTEXT_PORT_NO_LISTEN); int err=getnameinfo(param->addr->ai_addr, param->addr->ai_addrlen, buffer, sizeof(buffer), 0, 0, NI_NUMERICHOST); connect_proceed = 0; struct libwebsocket *lsock = libwebsocket_client_connect((libwebsocket_context *)pint->websock_context, buffer, port, 0, "/", "hostname", "originname", protocols[pint->fpga_number][0].name, -1); if (websock_trace) printf("[%s:%d] pint %p = %p address %s name %s\n", __FUNCTION__, __LINE__, pint, lsock, buffer, protocols[pint->fpga_number][0].name); while(!connect_proceed) event_webSocket(pint); return 0; } static int init_webSocketResp(struct PortalInternal *pint, void *aparam) { PortalSocketParam *param = (PortalSocketParam *)aparam; unsigned short port = 5050; pint->map_base = (volatile unsigned int *)malloc(4+MAX_ZEDBOARD_PAYLOAD+1); memset((void *)pint->map_base, 0, 4+MAX_ZEDBOARD_PAYLOAD+1); // for valgrind if (param->addr->ai_family == AF_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)param->addr->ai_addr; port = htons(sa->sin_port); } else if (param->addr->ai_family == AF_INET6) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)param->addr->ai_addr; port = htons(sa->sin6_port); } if (websock_trace) fprintf(stderr, "[%s:%d] listening on addr=%p ai_family=%d port %d\n", __FUNCTION__, __LINE__, param->addr->ai_addr, param->addr->ai_family, port); get_context(pint, port); if (websock_trace) fprintf(stderr, "[%s:%d] pint %p context %p fd %d.\n", __FUNCTION__, __LINE__, pint, pint->websock_context, pint->fpga_fd); return 0; } static void send_webSocket(struct PortalInternal *pint, volatile unsigned int *data, unsigned int hdr, int sendFd) { int n; uint32_t len = (hdr & 0xffff); unsigned char txbuf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ZEDBOARD_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING]; if (websock_trace) printf("[%s:%d] pint %p websock %p len %d data %s\n", __FUNCTION__, __LINE__, pint, WEB(pint), len, (char*)data); memcpy(&txbuf[LWS_SEND_BUFFER_PRE_PADDING], (void *)data, len); n = libwebsocket_write((libwebsocket *)pint->websock_wsi, &txbuf[LWS_SEND_BUFFER_PRE_PADDING], len, LWS_WRITE_TEXT); } PortalTransportFunctions transportWebSocketInit = { init_webSocketInit, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_socket, mapchannel_req_generic, send_webSocket, recv_portal_null, busy_portal_null, enableint_portal_null, event_webSocket, notfull_null}; PortalTransportFunctions transportWebSocketResp = { init_webSocketResp, read_portal_memory, write_portal_memory, write_fd_portal_memory, mapchannel_socket, mapchannel_req_generic, send_webSocket, recv_portal_null, busy_portal_null, enableint_portal_null, event_webSocket, notfull_null}; ================================================ FILE: cpp/transportXsim.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "GeneratedTypes.h" #include #include static int trace_xsim; // = 1; static uint32_t indicationIndex[16]; static uint32_t indicationHdr[16]; static PortalInternal mcommon, indPortal, reqPortal; static int indMsgSource (PortalInternal *pint, const uint32_t portal, const uint32_t data ) { PortalInternal *clientp = pint->mux_ports[portal].pint; uint32_t index = indicationIndex[portal]++; if (index == 0) indicationHdr[portal] = data; uint32_t hdr = indicationHdr[portal]; if (clientp) clientp->map_base[index] = data; uint32_t numwords = hdr & 0xFF; if (trace_xsim) fprintf(stderr, "pid %d %s: portal=%d data=%x hdr=%08x numwords=%d pid=%d\n", getpid(), __FUNCTION__, portal, data, hdr, numwords, getpid()); if (indicationIndex[portal] >= numwords) { uint32_t methodId = (hdr >> 16) & 0xFF; if (trace_xsim) fprintf(stderr, "pid %d %s: clientp=%p srcbeats=%d methodwords=%d methodId=%d hdr=%08x\n", getpid(), __FUNCTION__, clientp, indicationIndex[portal], numwords, methodId, hdr); if (clientp && clientp->handler) clientp->handler(clientp, methodId, 0); indicationIndex[portal] = 0; } return 0; } static XsimMsgIndicationCb indHandlers = {portal_disconnect, indMsgSource}; static int init_xsim(struct PortalInternal *pint, void *init_param) { initPortalHardware(); printf("[%s:%d]\n", __FUNCTION__, __LINE__); //sleep(10); if (!indPortal.mux_ports) { init_portal_internal(&mcommon, 0, 0, portal_mux_handler, NULL, &transportSocketInit, NULL, NULL, sizeof(uint32_t)); PortalMuxParam param = {}; param.pint = &mcommon; init_portal_internal(&indPortal, XsimIfcNames_XsimMsgIndication, 0, XsimMsgIndication_handleMessage, &indHandlers, &transportMux, ¶m, NULL, XsimMsgIndication_reqinfo); init_portal_internal(&reqPortal, XsimIfcNames_XsimMsgRequest, 0, NULL, NULL, &transportMux, ¶m, NULL, XsimMsgRequest_reqinfo); indPortal.mux_ports_number = 16; indPortal.mux_ports = (PortalMuxHandler *)malloc(indPortal.mux_ports_number * sizeof(PortalMuxHandler)); } //pint->fpga_number = indPortal->fpgaNumber(pint->fpga_number); pint->map_base = ((volatile unsigned int*)malloc(REQINFO_SIZE(pint->reqinfo) + sizeof(uint32_t))) + 1; memset((void *)(pint->map_base-1), 0, REQINFO_SIZE(pint->reqinfo) + sizeof(uint32_t)); // for valgrind indPortal.mux_ports[pint->fpga_number].pint = pint; // FIXME: depends on ids < 16 pint->fpga_fd = mcommon.client_fd[0]; return 0; } void write_portal_xsim(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { if (trace_xsim) printf("%s %d sending data %d\n", __FUNCTION__, pint->fpga_number, v); XsimMsgRequest_msgSink(&reqPortal, pint->fpga_number, v); } void write_fd_portal_xsim(PortalInternal *pint, volatile unsigned int **addr, unsigned int v) { //if (trace_xsim) printf("%s: %d sending fd %d\n", __FUNCTION__, pint->fpga_number, v); XsimMsgRequest_msgSinkFd(&reqPortal, pint->fpga_number, v); } static volatile unsigned int *mapchannel_req_xsim(struct PortalInternal *pint, unsigned int v, unsigned int size) { if (trace_xsim) printf("%s: %d sending header %x\n", __FUNCTION__, pint->fpga_number, (v << 16) | size); XsimMsgRequest_msgSink(&reqPortal, pint->fpga_number, (v << 16) | size); return pint->transport->mapchannelInd(pint, v); } int event_xsim(struct PortalInternal *pint) { mcommon.transport->event(&mcommon); return -1; } PortalTransportFunctions transportXsim = { init_xsim, read_portal_memory, write_portal_xsim, write_fd_portal_xsim, mapchannel_socket, mapchannel_req_xsim, send_portal_null, recv_portal_null, busy_portal_null, enableint_portal_null, event_xsim, notfull_null}; ================================================ FILE: cpp/verilatortop.cpp ================================================ #include "vlsim.h" #include "verilated.h" #include #include #include #ifdef BSV_POSITIVE_RESET #define BSV_RESET_VALUE 1 #define BSV_RESET_EDGE 0 //posedge #else #define BSV_RESET_VALUE 0 #define BSV_RESET_EDGE 1 //negedge #endif #if VM_TRACE # include // Trace file format header #endif bool dump_vcd = false; const char *vcd_file_name = "dump.vcd"; void parseArgs(int argc, char **argv) { signed char opt; while ((opt = getopt(argc, argv, "ht:")) != -1) { switch (opt) { case 't': dump_vcd = true; vcd_file_name = optarg; break; } } } vluint64_t main_time = 0; vluint64_t derived_time = 0; int main(int argc, char **argv, char **env) { fprintf(stderr, "vlsim::main\n"); Verilated::commandArgs(argc, argv); parseArgs(argc, argv); vlsim* top = new vlsim; fprintf(stderr, "vlsim calling dpi_init\n"); dpi_init(); #if VM_TRACE // If verilator was invoked with --trace VerilatedVcdC* tfp = 0; if (dump_vcd) { Verilated::traceEverOn(true); // Verilator must compute traced signals VL_PRINTF("Enabling vcd waves to %s\n", vcd_file_name); tfp = new VerilatedVcdC; top->trace (tfp, 4); // Trace 4 levels of hierarchy tfp->open (vcd_file_name); // Open the dump file } #endif fprintf(stderr, "starting simulation\n"); top->CLK = 0; top->RST_N = BSV_RESET_VALUE; top->CLK_derivedClock = 0; top->CLK_sys_clk = 0; top->RST_N_derivedReset = BSV_RESET_VALUE; while (!Verilated::gotFinish()) { if (main_time >= 10) { if ((top->CLK == BSV_RESET_EDGE) && (top->RST_N == BSV_RESET_VALUE)) { fprintf(stderr, "time=%ld leaving reset new value %d\n", (long)main_time, !BSV_RESET_VALUE); top->RST_N = !BSV_RESET_VALUE; } } if (derived_time >= 10) { if ((top->CLK_derivedClock == BSV_RESET_EDGE) && (top->RST_N_derivedReset == BSV_RESET_VALUE)) { fprintf(stderr, "time=%ld deasserting derivedReset new value %d\n", (long)main_time, !BSV_RESET_VALUE); top->RST_N_derivedReset = !BSV_RESET_VALUE; } } if (dpi_cycle()) vl_finish(__FILE__, __LINE__, "vlsim"); top->CLK = main_time % 2; top->CLK_derivedClock = derived_time % 2; top->CLK_sys_clk = main_time % 2; top->eval(); #if VM_TRACE if (tfp) tfp->dump (main_time); // Create waveform trace for this timestamp #endif main_time++; if (main_time & 1) derived_time++; } top->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete top; exit(0); } ================================================ FILE: debian/changelog ================================================ connectal (15.08.4-1precise1) precise; urgency=medium * Fixed DMA write path through MemSlaveEngine post Altera merge -- Jamey Hicks Fri, 07 Aug 2015 14:42:17 -0400 connectal (15.08.3-1precise1) precise; urgency=medium * Fixed python location * 15.08.3 -- Jamey Hicks Tue, 04 Aug 2015 15:46:36 -0400 connectal (15.08.2-1precise1) precise; urgency=medium * Another hugetlb page size change. * 15.08.2 -- Jamey Hicks Tue, 04 Aug 2015 15:31:41 -0400 connectal (15.08.1-1precise1) precise; urgency=medium * Added hugetlb page size. * Version 15.08.1 -- Jamey Hicks Mon, 03 Aug 2015 08:11:10 -0400 connectal (15.07.4-1precise1) precise; urgency=medium * Driver fixes. -- Jamey Hicks Fri, 10 Jul 2015 09:48:19 -0400 connectal (15.07.3-1precise1) precise; urgency=medium * One more PCIE3 fix. -- Jamey Hicks Mon, 06 Jul 2015 10:02:28 -0400 connectal (15.07.2-1precise1) precise; urgency=medium * 15.07.2, fixed PCIE3 conditionalization -- Jamey Hicks Mon, 06 Jul 2015 09:31:16 -0400 connectal (15.07.1-1precise1) precise; urgency=medium * v15.07.1 -- Jamey Hicks Mon, 06 Jul 2015 09:04:37 -0400 connectal (15.06.3-1precise1) precise; urgency=medium * v15.06.3 -- Jamey Hicks Tue, 09 Jun 2015 14:47:44 -0400 connectal (15.06.2-1precise1) precise; urgency=medium * 15.06.2 -- Jamey Hicks Thu, 04 Jun 2015 09:21:24 -0400 connectal (15.06.1-3precise3) precise; urgency=medium * updated dkms build -- Jamey Hicks Mon, 01 Jun 2015 12:47:00 -0400 connectal (15.06.1-2precise2) precise; urgency=medium * fixing dkms -- Jamey Hicks Mon, 01 Jun 2015 11:09:43 -0400 connectal (15.06.1-1precise1) precise; urgency=medium * 15.06.1 -- Jamey Hicks Mon, 01 Jun 2015 10:34:18 -0400 connectal (15.05.2-1precise1) precise; urgency=medium * 15.05.2 -- Jamey Hicks Tue, 26 May 2015 09:24:41 -0400 connectal (15.05.1-1precise1) precise; urgency=medium * Updated to 15.05.1 -- Jamey Hicks Wed, 20 May 2015 15:30:20 -0400 connectal (15.04.4-2precise2) precise; urgency=medium * Fixed sed DRIVER_VERSION and DEV_VERSION for DKMS -- Jamey Hicks Wed, 29 Apr 2015 12:34:38 -0400 connectal (15.04.4-1precise1) precise; urgency=medium * 15.04.4: fixes rmmod pcieportal, etc. -- Jamey Hicks Tue, 28 Apr 2015 16:07:16 -0400 connectal (15.04.3-1precise1) precise; urgency=medium * 15.04.3: fixed make pciedrivers -- Jamey Hicks Mon, 27 Apr 2015 11:52:46 -0400 connectal (15.04.2-1precise1) precise; urgency=medium * Fixing DKMS sources -- Jamey Hicks Mon, 27 Apr 2015 11:06:34 -0400 connectal (15.04.1-1precise1) precise; urgency=medium * 15.04.1 -- Jamey Hicks Fri, 24 Apr 2015 09:41:52 -0400 connectal (15.03.12-1precise1) precise; urgency=medium * 15.03.12 -- Jamey Hicks Wed, 01 Apr 2015 16:58:40 -0400 connectal (15.03.11-1precise1) precise; urgency=medium * 15.03.11 -- Jamey Hicks Mon, 30 Mar 2015 12:59:29 -0400 connectal (15.03.10-1precise1) precise; urgency=medium * 15.03.10 -- Jamey Hicks Wed, 25 Mar 2015 15:20:34 -0400 connectal (15.03.9-1precise1ubuntu1) precise; urgency=medium * 15.03.9 -- Jamey Hicks Tue, 24 Mar 2015 13:21:43 -0400 connectal (15.03.8-1precise1) precise; urgency=medium * 15.03.8 -- Jamey Hicks Mon, 23 Mar 2015 09:12:55 -0400 connectal (15.03.7-1precise1) precise; urgency=medium * 15.03.7: reverts interface to mkMemServer, plus other fixes -- Jamey Hicks Fri, 20 Mar 2015 11:47:05 -0400 connectal (15.03.6-1precise1) precise; urgency=medium * 15.03.6: a couple of driver fixes -- Jamey Hicks Thu, 19 Mar 2015 17:04:55 -0400 connectal (15.03.5-1precise1) precise; urgency=medium * 15.03.5 -- Jamey Hicks Thu, 19 Mar 2015 16:32:38 -0400 connectal (15.03.4-1precise1) precise; urgency=medium * Updated to 15.03.4 -- Jamey Hicks Wed, 18 Mar 2015 12:51:41 -0400 connectal (15.03.2-1precise1) precise; urgency=medium * Updated to 15.03.2 -- Jamey Hicks Mon, 09 Mar 2015 15:21:08 -0400 connectal (15.03.1-1precise1) precise; urgency=medium * Updated to 15.03.1 -- Jamey Hicks Wed, 04 Mar 2015 15:30:27 -0500 connectal (15.02.5-1precise1) precise; urgency=medium * Updated to 15.02.5 -- Jamey Hicks Mon, 16 Feb 2015 20:37:45 -0500 connectal (15.02.4-1precise1) precise; urgency=medium * Updated to 15.02.4 -- Jamey Hicks Sun, 15 Feb 2015 20:37:45 -0500 connectal (15.02.3-1precise1) precise; urgency=medium * Updated to 15.02.3 -- Jamey Hicks Wed, 11 Feb 2015 11:48:40 -0500 connectal (15.02.2-2precise2) precise; urgency=medium * For Trusty -- Jamey Hicks Tue, 10 Feb 2015 10:33:22 -0500 connectal (15.02.2-1precise1) precise; urgency=medium * Fixed include string.h for zynqdrivers -- Jamey Hicks Tue, 10 Feb 2015 10:09:21 -0500 connectal (15.02.1-1precise3) precise; urgency=medium * Updated to 15.02.1 -- Jamey Hicks Tue, 10 Feb 2015 09:53:44 -0500 connectal (14.12.3-4precise1) precise; urgency=medium * Second try to add pciescan -- Jamey Hicks Wed, 10 Dec 2014 08:22:10 -0500 connectal (14.12.3-3precise1) precise; urgency=medium * Added dependence on pciescan -- Jamey Hicks Wed, 10 Dec 2014 08:03:00 -0500 connectal (14.12.3-2precise1) precise; urgency=medium * Added support for setting derivedClock frequency -- Jamey Hicks Fri, 05 Dec 2014 16:24:47 -0500 connectal (14.12.2-4precise1) precise; urgency=medium * Fix include paths for dkms -- Jamey Hicks Thu, 04 Dec 2014 13:16:48 -0500 connectal (14.12.2-2precise1) precise; urgency=medium * Bump kernel version to fix DKMS error -- Jamey Hicks Thu, 04 Dec 2014 12:59:07 -0500 connectal (14.12.2-1precise1) precise; urgency=medium * Removed zynqdrivers build and install until I find the cross arm toolchain for precise -- Jamey Hicks Thu, 04 Dec 2014 12:37:57 -0500 connectal (14.12.2-1precise1) precise; urgency=medium * Fixed Vector compilation in C -- Jamey Hicks Tue, 02 Dec 2014 09:40:36 -0500 connectal (14.12.1-1precise1) precise; urgency=medium * Added support for Vector in portal interfaces. -- Jamey Hicks Mon, 01 Dec 2014 11:48:25 -0500 connectal (14.11.6-2precise3) precise; urgency=low * Tweak install of pcieflat -- Jamey Hicks Mon, 24 Nov 2014 16:55:21 -0500 connectal (14.11.6-1precise1) precise; urgency=low * Updated to 14.11.6 -- Jamey Hicks Mon, 24 Nov 2014 15:54:34 -0500 connectal (14.11.5-1precise1) precise; urgency=low * Updated to 14.11.5 -- Jamey Hicks Tue, 18 Nov 2014 08:43:29 -0500 connectal (14.11.4-1precise1) precise; urgency=low * Updated to 14.11.4 -- Jamey Hicks Mon, 17 Nov 2014 12:00:21 -0500 connectal (14.11.3-2precise2) precise; urgency=low * Updated to 14.11.3 -- Jamey Hicks Fri, 14 Nov 2014 11:38:22 -0500 connectal (14.11.2-1precise1) precise; urgency=low * Update to 14.11.2 -- Jamey Hicks Fri, 07 Nov 2014 09:07:26 -0500 connectal (14.11.1-2precise1) precise; urgency=low * Update install-dkms -- Jamey Hicks Thu, 06 Nov 2014 13:03:40 -0500 connectal (14.11.1-1precise1) precise; urgency=low * Updated to connectal 14.11.1 -- Jamey Hicks Thu, 06 Nov 2014 11:35:05 -0500 connectal (14.10.2-7precise4) precise; urgency=medium * Specify CROSS_COMPILE and add to arm-linux-gnueabi-gcc to Build-Depends -- Jamey Hicks Mon, 27 Oct 2014 08:27:24 -0400 connectal (14.10.2-7precise2) precise; urgency=medium * Specify driver version -- Jamey Hicks Sat, 25 Oct 2014 14:34:22 -0400 connectal (14.10.2-6precise1) precise; urgency=medium * Added the build depdences on zynqdrivers and zynqdrivers-install -- Jamey Hicks Fri, 24 Oct 2014 16:19:17 -0400 connectal (14.10.2-5precise1) precise; urgency=medium * Build zynqdrivers and package in connectal-zynqdrivers -- Jamey Hicks Fri, 24 Oct 2014 13:23:21 -0400 connectal (14.10.2-4precise1) precise; urgency=medium * Depend on fpgamake, buildcache, and fpgajtag -- Jamey Hicks Thu, 23 Oct 2014 14:09:00 -0400 connectal (14.10.2-3precise1) precise; urgency=medium * Fix DKMS install -- Jamey Hicks Thu, 23 Oct 2014 12:26:54 -0400 connectal (14.10.2-2precise1) precise; urgency=high * Depends on vim for xxd -- Jamey Hicks Thu, 23 Oct 2014 11:18:06 -0400 connectal (14.10.2-1precise1) precise; urgency=high * Updated to 14.10.2 -- Jamey Hicks Thu, 23 Oct 2014 11:15:16 -0400 connectal (14.10.01-5precise1) precise; urgency=low * DKMS -- Jamey Hicks Thu, 23 Oct 2014 09:09:02 -0400 connectal (14.10.01-4precise2) precise; urgency=low * Do not build kernel modules -- Jamey Hicks Wed, 22 Oct 2014 17:43:44 -0400 connectal (14.10.01-3precise1) precise; urgency=low * Depends on python-ply -- Jamey Hicks Wed, 22 Oct 2014 17:29:22 -0400 connectal (14.10.01-2precise2) precise; urgency=low * Include the source tarball -- Jamey Hicks Wed, 22 Oct 2014 08:11:22 -0400 connectal (14.10.01-2precise1) precise; urgency=low * Missed some files -- Jamey Hicks Tue, 21 Oct 2014 16:44:23 -0400 connectal (14.10.01-1precise1) precise; urgency=low * Initial release -- Jamey Hicks Fri, 17 Oct 2014 17:10:47 -0400 ================================================ FILE: debian/compat ================================================ 8 ================================================ FILE: debian/connectal-doc.docs ================================================ #DOCS# ================================================ FILE: debian/connectal-doc.install ================================================ #DOCS# ================================================ FILE: debian/connectal-zynqdrivers.install ================================================ /usr/share/connectal-zynqdrivers/*.ko ================================================ FILE: debian/connectal.dkms ================================================ drivers/pcieportal/dkms.conf.out ================================================ FILE: debian/connectal.install ================================================ /usr/bin/pcieflat /usr/share/connectal /usr/src/ ================================================ FILE: debian/connectal.udev ================================================ # UDev rules for setting up Bluespec emulation device drivers ACTION=="add",SUBSYSTEM=="pci",ATTR{vendor}=="0x1be7", ATTR{device}="0xb100", RUN+="/sbin/modprobe -ba pcieportal portalmem" KERNEL=="portal*",MODE="666" KERNEL=="portalmem",MODE="666" KERNEL=="connectal",MODE="666" ================================================ FILE: debian/control ================================================ Source: connectal Section: devel Priority: extra Maintainer: Jamey Hicks Build-Depends: debhelper (>= 8.0.0), python3 (>= 3.7), python3-ply, python3-support (>= 0.90), dkms Standards-Version: 3.9.2 Homepage: https://github.com/cambridgehackers/connectal #Vcs-Git: git://git.debian.org/collab-maint/connectal.git #Vcs-Browser: http://git.debian.org/?p=collab-maint/connectal.git;a=summary Package: connectal Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, python3 (>= 3.7), python3-ply, python3-gmpy, python3-netifaces, python3-gflags, python3-support (>= 0.90), dkms, fpgamake, buildcache, fpgajtag, pciescan, gcc, g++, libfontconfig1, libxft2 Description: Software-driven hardware development framework Connectal provides a hardware-software interface for applications split between user mode code and custom hardware in an FPGA. Portal can automatically build the software and hardware glue for a message based interface and also provides for configuring and using shared memory between applications and hardware. Communications between hardware and software are provided by a bidirectional flow of events and regions of memory shared between hardware and software. Events from software to hardware are called requests and events from hardware to software are called indications, but in fact they are symmetric. Package: connectal-doc Section: doc Architecture: all Description: documentation for connectal More of the same description ================================================ FILE: debian/copyright ================================================ Format: http://dep.debian.net/deps/dep5 Upstream-Name: connectal Source: Files: * Copyright: 2012 Nokia, Inc. 2013-2014 Quanta Research Cambridge License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. . ================================================ FILE: debian/docs ================================================ README.md ================================================ FILE: debian/rules ================================================ #!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # # Modified to make a template file for a multi-binary package with separated # build-arch and build-indep targets by Bill Allombert 2001 # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 # This has to be exported to make some magic below work. export DH_OPTIONS %: dh $@ --with dkms ================================================ FILE: doc/Makefile ================================================ all: make -C library html latexpdf ================================================ FILE: doc/ReadmePartialReconfiguration.md ================================================ CONNECTAL Support for Partial Reconfiguration ========================================= CONNECTAL supports partial reconfiguration on pcie-based platforms (kc705 and vc707). There's not enough static logic on the zedboard to make this worthwhile at the moment. Run connectalgen as usual to create the project directory. Create proxies, wrappers, scripts, and Makefiles: cd examples/echo connectalgen -Bkc705 -p kc705 -x mkPcieTop -s2h Say -h2s Say -s test.cpp -t ../../bsv/StdPcieTop.bsv Say.bsv Compile the full bitstream: cd kc705 make verilog make partial ## generates full and partial bitstreams make program ## loads the full bitstream Now reboot to configure the PCIe endpoint sudo shutdown -r now Now you can edit the source code, recompile, and generate a new partial bitstream: ## edit the BSV make verilog make partial Load the partial bitstream: make reprogram This also calls "connectalutil reset /dev/fpga0" to reset the portals in the design. No reboot required. ================================================ FILE: doc/SmithWaterman.md ================================================ ## Smith-Waterman L. Stewart March 17, 2014 Smith-Waterman is an algorithm for determining the best alignment of two strands of DNA. It is a variant of dynamic programming, published in 1981. For strands of lengths m and n, it runs in O(mn) space and O(mn) time and returns all alignments with the best score, according to weights for mismatches, insertions, and deletions. In 1982, Gotoh found an O(mn) time but only O(shorter of m and n) space scheme that returns only a single instance of the best match. In 1986, Altschul and Erickson published a version with "affine gap costs." The original Smith-Waterman had the same weight for each step in a run of inserts or deletes, but a model in which the first insert or delete costs more than adding to an existing run models biology more accurately. In 1988, Miller, Webb, and Myers adapted a computer science algorithm by Hirshberg (1975) to the problem, leading O(smaller of m or n) space. Limiting space usage is fairly important for FPGA implementations, since while FGPAs or ASICs have a lot of internal memory units, they aren't very big each. In order to achieve a big speedup on sequencing, we have to have a lot of parallelism. Each instance can have its own memory, but not very much of it. For the Hirschberg algorithm, see connectal/examples/maxcommonsubseq. How it works The problem is to find the minimum cost of converting one string, A, into another one, B. Three things can happen: a character can be deleted from string A, a character can be inserted into string A, and combination event, in which a character in string A is changed (delete combined with insert). Parameters are needed: a substitution matrix that details the cost of converting a character to another (or itself), and a gap model, which expresses the cost of deleting or inserting a run of characters. The simplest gap model has a fixed cost for every deletion or insertion, but an "affine model" better matches what happens in biology: there is a startup cost for a run of deletions or insertions, and a typically lower, cost for extending a run. Call the substitution matrix w(a, b) def w(a, b): if (a == b): return 0.0 else: return 1.0 In other words, no cost to leave a character unchanged, and unit cost to change it. A typical gap model is g = 2.0 h = 0.5 def gap(k): return g + (k * h) The magnitudes of these costs are irrelevant, only the relative costs matter. The basic idea of Smith Waterman is dynamic programming. Suppose that m = len(A) n = len(B) Define A_i to be the subsequence A[0]..A[i]. Let's define C[i][j] as the minimum cost of a conversion from A_i to B_j. D[i][j] as the minimum cost of a conversion from A_i to B_j such that A[i] is deleted (a suffix gap in A), and that I[i][j] is the minimum cost of conversion from A_i to B_j such that b[j] is inserted (into A). D and I are only necessary to handle the gap cost model - you have to know whether the best answer up to a point has a gap at the end or not, so you can apply the gap cost model to either extend a gap or open a new one. The essence of dynamic programming is a recurrance that expresses that expresses matrix values as functions of "earlier" values. C[i][j] = min ( D[i][j], I[i][j], C[i-1][j-1] + w(a[i], b[j])) D[i][j] = min( D[i-1][j] + h, // extend an old gap C[i-1][j] + g + h) // start a new gap I[i][j] = min( I[i][j-1] + h, // extend an old gap C[i][j-1] + g + h) // start a new gap The Gotoh version of Smith-Waterman does exactly this, building the full C, D, and I matrices. From inspection of the recurrance relations, it is clear that you don't need to save the full matrices, and the algorithm Gotohb keeps only two row vectors. CC[j] represents conversion costs of A_i to B_j (for all j) and DD[j] represents conversion costs of A_i to B_j ending with a deletion, for all j. All of the above follows the lines of Hirschberg's algorithms A and B for the maximum common subsequence problem. The key insight in the Myers and Miller paper is that you can write a recursive version of Smith Waterman along the lines of Hirschberg's algorithm C. 1 Choose a midpoint i in the A string. 2 Find j such that the best overall solution passes through C[i][j] 3 Recursively solve the conversion of A_i to B_j and the solution of A_m-i to B_n-j, where A_m-i and B_n-j are the suffixes of A and B. Step 1 is straightforward, the best solution passes through A_i, although we don't know at what j. Step 2 uses Gotoh Algorithm B to find the cost of solutions which cross A_i for all values of j. This is done in two parts. The first half part is done in the forward direction by using GotohB(A_i, B_j). This produces vectors CC and DD as above. Then GotohB(A*_m-i, B*_j) is run, where A* and B* are the reversed strings A and B. A*_m-i is the reversed suffix of A, from i+1 to the end. This produces vectors RR, the conversion from A*_m-i to B*_j for all j, and SS, the conversion costs from A*_i to B*_j ending with a delete. The reverse solution finds costs for the suffixes of A and B There are two cases. In type 1 cases, the cost of the overall conversion that splits B at j is just CC[j] + RR[N-j]. This is minimized over j to find the best split point for string B. In type 2 cases, the best solution for the prefix of B ends with a delete and the best solution for the suffix begins with a delete. In this case, we have to coalesce the deletions into a single gap. min over j (CC[j] + RR[N-j], DD[j] + SS[N-j] -g) Given the split points i and j, we can run step 3, to solve the prefix and suffix problems recursively. Below the top level of the recursion, it may be necessary to coalesce gaps at either the beginning or end of the string, and for this reason, additional parameters are passed in to control this accounting. def gotohc(A, B, tb, te): ... In order to make the python version more like the eventual hardware version, we also pass in sa and sb, the starting indices in A and B, and m and n, the lengths of the active substrings in A and B. def gotohc(A, B, sa, sb, m, n, tb, te): ... For full details, see examples/smithwaterman/sw.py ================================================ FILE: doc/axi_tracing.md ================================================ ## How to trace AXI bus transactions on the Zynq platform. ### Preparation 1. Connect a usb cable to either a linux box or Mac 2. Install openocd Linux: sudo apt-get install openocd Mac using 'port': sudo port install libftdi sudo port install openocd Mac using 'brew': brew install libftdi brew install openocd --enable-ft2232_libftdi On Mac, if you get the message: 'unable to claim usb device. Make sure the default FTDI driver is not in use': Please read: http://pylibftdi.readthedocs.org/en/latest/troubleshooting.html Summarized here: OS X Mavericks OS X Mavericks includes kernel drivers which will reserve the FTDI device by default. This needs unloading before libftdi will be able to communicate with the device: sudo kextunload -bundle-id com.apple.driver.AppleUSBFTDI Similarly to reload it: sudo kextload -bundle-id com.apple.driver.AppleUSBFTDI OS X Mountain Lion and earlier Whereas Mavericks includes an FTDI driver directly, earlier versions of OS X did not, and if this issue occurred it would typically as a result of installing some other program - for example the Arduino IDE. As a result, the kernel module may have different names, but FTDIUSBSerialDriver.kext is the usual culprit. Unload the kernel driver as follows: sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext ### Compile time In the project makefile, add the line: CONNECTALFLAGS=--bscflags " -D TRACE_AXI" For getting timestamps inserted in read request data, also specify the conditional compile flag AXI_READ_TIMING. This will compile ConnectableWithTrace to trace transactions into BRAM. ### After running the test: 1. run the script connectal/jtag/run_trace.sh. 2. the trace output will be in the file trace.log. ================================================ FILE: doc/centos.md ================================================ # CentOS [CentOS](http://centos.org/) has joined forces with Red Hat, working to provide a common platform for open source community project needs. Since [RedHat](http://www.redhat.com/) is one of the preferred Linux platform for all EDA vendors, this page lists all the packages that were required to be installed on top of the typical installation to run the CONNECTAL framework. Vivado-14.1 also lists native support for CentOS in their [release notes](http://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_1/ug973-vivado-release-notes-install-license.pdf). # yum RedHat/CentOS uses [yum](http://www.ibm.com/developerworks/library/l-lpic1-v3-102-5/) to fetch packages and install RPMs whereas Ubuntu which is derived from Debian distribution uses [apt](http://www.ibm.com/developerworks/linux/library/l-lpic1-v3-102-4/) commands to install packages. All the packages installed using yum [commands](http://yum.baseurl.org/wiki/YumCommands) need sudo or root privileges. # Packages The following table lists the package name, the command used to install the package followed by a brief comment.
**package name** **installation command** **comment**
32-bit libstdc sudo yum install “Compatibility libraries” arm-xilinx-linux-gnueabi-g++ needs 32-bit libs
[LiberOffice](http://www.libreoffice.org/) sudo yum groupinstall “Office Suite and Productivity” Optional (groupinfo will list packages)
[flashplayer](http://get.adobe.com/flashplayer/) sudo yum install flash-plugin nspluginwrapper curl For several viewing video tutorials, e.g. [vivado training](http://www.xilinx.com/training/vivado/)
python-ply sudo yum install python-ply Python Lex-Yacc
python-argparse sudo yum install python-argparse Parser for command-line options, arguments and sub-commands
[graphviz](http://www.graphviz.org/Download_linux_rhel.php) sudo yum install graphviz graphviz-tcl To view dot files generated by "bsc -sched-dot"
ftp client sudo yum install ftp [needed for running out-of-the-box Linux example](http://zedboard.org/content/zedboard-setting-arm-development-environment-linux)
cable drivers   [Install Instructions](http://www.xilinx.com/support/answers/29310.htm)
[fxload](http://pkgs.org/centos-6-rhel-6/linuxtech-x86_64/fxload-2008_10_13-3.el6.x86_64.rpm.html)   Used to update the firmware of the platform cable.
ldd \`which docnav\`   Need to install "not found" libs for running Xilinx docnav
  sudo yum whatprovides libgthread-2.0.so.0 repo: glib2-2.26.1-3.el6.i686
libpng12.so.0 sudo yum install 2:libpng-1.2.49-1.el6\_2.i686 A library of functions for manipulating PNG image format files
libfontconfig.so.1 sudo yum install fontconfig-2.8.0-3.el6.i686 Font configuration and customization library
libfreetype.so.6 sudo yum install freetype-2.3.11-14.el6\_3.1.i686 A free and portable font rendering engine
libXext.so.6 sudo yum install libXext.so.6 X.Org X11 libXext runtime library
libXrender.so.q sudo yum install libXrender-0.9.7-2.el6.i686 X.Org X11 libXrender runtime library
libstdc++.so.6 sudo yum install libstdc++-4.4.7-4.el6.i686 GNU Standard C++ Library
libgthread-2.0.so.0 sudo yum install glib2-2.26.1-3.el6.i686 A library of handy utility functions
libSM.so.6 sudo yum install libSM-1.2.1-2.el6.i686 X.Org X11 SM runtime library
libICE.so.6 sudo yum install libICE-1.0.6-1.el6.i686 X.Org X11 ICE runtime library
libX11.so.6 sudo yum install libX11-1.5.0-4.el6.i686 Core X11 protocol client library
  cd //xilinx/14.7/ISE\_DS/ISE/lib/lin64 To fix 'GLIBCXX\_3.4.9' not found
  sudo mv libstdc++.so libstdc++.so.orig Do the same also in the following directories:
  sudo mv libstdc++.so.6 libstdc++.so.6.orig */xilinx/14.7/ISE\_DS/common/lib/lin64*
  sudo mv libstdc++.so.6.0.8 libstdc++.so.6.0.8.orig //xilinx/Vivado/2013.3/ids\_lite/ISE/lib/lin64
emacs 24.3   [Install instructions](http://h1de0ut.com/bl0g/article/2012/03/01/emacs24-ricty-centos6/) (for better org mode support)
================================================ FILE: doc/generated/html/portal.html ================================================ CONNECTAL

April 29, 2014

What is CONNECTAL?

CONNECTAL provides a hardware-software interface for applications split between user mode code and custom hardware in an FPGA or ASIC.

CONNECTAL can automaticaly build the software and hardware glue for a message based interface and also provides for configuring and using shared memory between applications and hardware. Communications between hardware and software are provided by a bidirectional flow of events and regions of memory shared between hardware and software. Events from software to hardware are called requests and events from hardware to software are called indications, but in fact they are symmetric.

Lexicon

connectal

The name of the project, whose goal is to ease the task of building applications composed of hardware and software components. Programmers use bsv as an IDL to specify the interface between the hardware and software components. A combination of generated code and libraries coordinate the data-flow between the program modules. Because the HW and SW stacks are customized for each application, the overheads associated with communicating across the HW/SW boundary are low.

HW/SW interface

portal

bsv

Bluespec System Verilog. bsv is a language for describing hardware that is might higher level than verilog. See BSV Documentation and Bluespec, Inc.

bluespec

Shorthand for Bluespec System Verilog (bsv)

indexterm:portal portal:: a logical request/indication pair is referred to as a portal. current tools require their specification in the IDL to be syntactically identifiable (i.e. fooRequest/fooIndication). An application can make use of multiple portals, which may be specified independently.

request interface

These methods are implemented by the application hardware to be invoked by application software. A bsv interface consisting of ‘Action’ methods. Because of the ‘Action’ type, data flow across this interface is unidirectional (SW → HW).

indication interface

The dual of a request interface, indication interfaces are ‘Action’ methods implemented by application software to be invoked by application hardware. As with request interfaces, the data flow across this interface is unidirectional, but in the opposite direction.

pcieportal/zynqportal

these two loadable kernel modules implement the minimal set of driver functionality. Specifically, they expose portal HW registers to SW through mmap, and set up interrupts to notify SW that an indication method has been invoked by HW.

portalalloc

This loadable kernel module exposes a subset of dma-buf functionality to user-space software (though a set of ioctl commands) to allocate and manage memory regions which can be shared between SW and HW processes. Maintaining coherence of the allocated buffers between processes is not automatic: ioctl commands for flush/invalidate are provided to be invoked explicitly by the users if necessary.

connectalgen

The name of the interface compiler which takes as input the bsv interface specification along with a description of a target platform and generates logic in both HW and SW to support this interface across the communication fabric.

Example setups:

A zedboard ( http://www.zedboard.org/ ), with Android running on the embedded ARM processors (the Processing System 7), an application running as a user process, and custom hardware configured into the Programmable Logic FPGA.

An x86 server, with Linux running on the host processor, an application running partly as a user process on the host and partly as hardware configured into an FPGA connected by PCI express (such as the Xilinx VC707 (http://www.xilinx.com/products/boards-and-kits/EK-V7-VC707-G.htm).

Background

When running part or all of an application in an FPGA, it is usually necessary to communicate between code running in user mode on the host and the hardware. Typically this has been accomplished by custom device drivers in the OS, or by shared memory mapped between the software and the hardware, or both. Shared memory has been particularly troublesome under Linux or Android, because devices frequently require contiguous memory, and the mechanisms for guaranteeing successful memory allocation often require reserving the maximum amount of memory at boot time.

Portal tries to provide convenient solutions to these problems in a portable way.

It is desirable to have

  • low latency for small messages

  • high bandwidth for large messages

  • notification of arriving messages

  • asynchronous replies to messages

  • support for hardware simulation by a separate user mode process

  • support for shared memory (DMA) between hardware and software

Overview

Portal is implemented as a loadable kernel module device driver for Linux/Android and a set of tools to automatically construct the hardware and software glue necessary for communications.

Short messages are handled by programmed I/O. The message interface from software to hardware (so called "requests") is defined as a bsv interface containing a number of Action methods, each with a name and typed arguments. The interface generator creates all the software and hardware glue so that software invocations of the interface stubs flow through to, and are turned into bsv invocations of the matching hardware. The machinery does not have flow control. Software is responsible for not overrunning the hardware. There is a debug mechanism which will return the request type of a failed method, but it does not tell which invocation failed. Hardware to software interfaces (so called “indications”) are likewise defined by bsv interfaces containing Action methods. Hardware invocations of these methods flow through to and cause software calls to corresponding user-supplied functions. In the current implementation there is flow control, in that the hardware will stall until there is room for a hardware to software message. There is also a mechanism for software to report a failure, and there is machinery for these failures to be returned to the hardware.

request-response-1.png

Portals do not have to be structured as request/response. Hardware can send messages to software without a prior request from software.

indication-only.png

Incoming messages can cause host interrupts, which wake up the device driver, which can wake up the user mode application by using the select(2) or poll(2) interfaces.

Most of the time, communications between hardware and software will proceed without requiring use of the OS. User code will read and write directly to memory mapped I/O space. Library code will poll for incoming messages, and [true? eventually time out and call poll(2). Only when poll(2) or select(2) are called will the device driver enable hardware interrupts. Thus interrupts are only used to wake up software after a quiet period.

The designer specifies a set of hardware functions that can be called from software, and a set of actions that the hardware can take which result in messages to software. Portal tools take this specification and build software glue modules to translate software function calls into I/O writes to hardware registers, and to report hardware events to software.

For larger memory and OS bypass (OS bypass means letting the user mode application talk directly to the hardware without using the OS except for setup), portal implements shared memory. Portal memory objects are allocated by the user mode program, and appear as Linux file descriptors. The user can mmap(2) the file to obtain user mode access to the shared memory region. Portal does not assure that the memory is physically contiguous, but does pin it to prevent the OS from reusing the memory. An FPGA DMA controller module is provided that gives the illusion of contiguous memory to application hardware, while under the covers using a translation table of scattered addresses.

The physical addresses are provided to the user code in order to initialize the dma controller, and address "handles" are provided for the application hardware to use.

The DMA controller provides Bluespec objects that support streaming access with automatic page crossings, or random access.

An Example

An application developer will typically write the hardware part of the application in Bluespec and the software part of the application in C or C++. In a short example, there will be a bsv source file for the hardware and a cpp source file for the application.

The application developer is free to specify whatever hardware-software interface makes sense.

In the examples directory, see [simple](../examples/simple/). The file [Simple.bsv](../examples/simple/Simple.bsv) defines the hardware, and testsimple.cpp supplies the software part. In this case, the software part is a test framework for the hardware.

Simple.bsv declares a few struct and enum types:

    typedef struct{
       Bit#(32) a;
       Bit#(32) b;
       } S1 deriving (Bits);

    typedef struct{
       Bit#(32) a;
       Bit#(16) b;
       Bit#(7) c;
       } S2 deriving (Bits);

    typedef enum {
       E1Choice1,
       E1Choice2,
       E1Choice3
       } E1 deriving (Bits,Eq);

    typedef struct{
       Bit#(32) a;
       E1 e1;
       } S3 deriving (Bits);

Simple.bsv defines the actions (called Requests) that software can use to cause the hardware to act, and defines the notifications (called Indications) that the hardware can use to signal the software.

    interface SimpleIndication;
        method Action heard1(Bit#(32) v);
        method Action heard2(Bit#(16) a, Bit#(16) b);
        method Action heard3(S1 v);
        method Action heard4(S2 v);
        method Action heard5(Bit#(32) a, Bit#(64) b, Bit#(32) c);
        method Action heard6(Bit#(32) a, Bit#(40) b, Bit#(32) c);
        method Action heard7(Bit#(32) a, E1 e1);
    endinterface

    interface SimpleRequest;
        method Action say1(Bit#(32) v);
        method Action say2(Bit#(16) a, Bit#(16) b);
        method Action say3(S1 v);
        method Action say4(S2 v);
        method Action say5(Bit#(32)a, Bit#(64) b, Bit#(32) c);
        method Action say6(Bit#(32)a, Bit#(40) b, Bit#(32) c);
        method Action say7(S3 v);
    endinterface

Software can start the hardware working via say, say2, … Hardware signals back to software with heard and heard2 and so fort. In the case of this example, say and say2 merely echo their arguments back to software.

The definitions in the bsv file are used by the connectal infrastructure ( a python program) to automatically create corresponding c++ interfaces.

    ../../connectalgen -Bbluesim -p bluesim -x mkBsimTop \
         -s2h SimpleRequest \
         -h2s SimpleIndication \
         -s testsimple.cpp \
         -t ../../bsv/BsimTop.bsv  Simple.bsv Top.bsv

The tools have to be told which interface records should be used for Software to Hardware messages and which should be used for Hardware to Software messages. These interfaces are given on the command line for genxpprojfrombsv

connectalgen constructs all the hardware and software modules needed to wire up portals. This is sort of like an RPC compiler for the hardware-software interface. However, unlike an RPC each method is asynchronous.

The user must also create a toplevel bsv module Top.bsv, which instantiates the user portals, the standard hardware environment, and any additional hardware modules.

Rather than constructing the connectalgen command line from scratch, the examples in connectal use include [Makefile.common](../Makefile.common) and define some make variables.

Here is the Makefile for the simple example:

    BSVDIR=../../bsv
    S2H = SimpleRequest
    H2S = SimpleIndication
    BSVFILES = Simple.bsv Top.bsv
    CPPFILES=testsimple.cpp
    Dma =
    PINS = Std

    include ../../Makefile.common

Designs using connectal may also include connectal/Makefile.common if they define CONNECTALDIR in their Makefile:

    CONNECTALDIR=/scratch/connectal
    S2H = ...
    H2S = ...
    BSVFILES = ...
    CPPFILES = ...
    include $(CONNECTALDIR)/Makefile.common

simple/Top.bsv

Each CONNECTAL design implements [Top.bsv](../examples/simple/Top.bsv) with some standard components.

It defines the IfcNames enum, for use in identifying the portals between software and hardware:

    typedef enum {SimpleIndication, SimpleRequest} IfcNames deriving (Eq,Bits);

It defines mkConnectalTop, which instantiates the wrappers, proxies, and the design itself:

    module mkConnectalTop(StdConnectalTop#(addrWidth));

StdConnectalTop is parameterized by addrWidth because Zynq and x86 have different width addressing. StdConnectalTop is a typedef:

    typedef ConnectalTop#(addrWidth,64,Empty)     StdConnectalTop#(numeric type addrWidth);

The "64" specifies the data width and Empty specifies the empty interface is exposed as pins from the design. In designs using HDMI, for example, Empty is replaced by HDMI. On some platforms, the design may be able to use different data widths, such as 128 bits on x86/PCIe.

Next, mkConnectalTop instantiates user portals:

    // instantiate user portals
       SimpleIndicationProxy simpleIndicationProxy <- mkSimpleIndicationProxy(SimpleIndication);

Instantiate the design:

       SimpleRequest simpleRequest <- mkSimpleRequest(simpleIndicationProxy.ifc);

Instantiate the wrapper for the design:

       SimpleRequestWrapper simpleRequestWrapper <- mkSimpleRequestWrapper(SimpleRequest,simpleRequest);

Collect the portals into a vector:

       Vector#(2,StdPortal) portals;
       portals[0] = simpleRequestWrapper.portalIfc;
       portals[1] = simpleIndicationProxy.portalIfc;

Create an interrupt multiplexer from the vector of portals:

       let interrupt_mux <- mkInterruptMux(portals);

Create the system directory, which is used by software to locate each portal via the IfcNames enum:

       // instantiate system directory
       StdDirectory dir <- mkStdDirectory(portals);
       let ctrl_mux <- mkAxiSlaveMux(dir,portals);

The following generic interfaces are used by the platform specific top BSV module:

       interface interrupt = interrupt_mux;
       interface ctrl = ctrl_mux;
       interface m_axi = null_axi_master;
       interface leds = echoRequestInternal.leds;

    endmodule : mkConnectalTop

simple/testsimple.cpp

CONNECTAL generates header files declaring wrappers for hardware-to-software interfaces and proxies for software-to-hardware interfaces. These will be in the "jni/" subdirectory of the project directory.

    #include "SimpleIndicationWrapper.h"
    #include "SimpleRequestProxy.h"

It also declares software equivalents for structs and enums declared in the processed BSV files:

    #include "GeneratedTypes.h"

CONNECTAL generates abstract virtual base classes for each Indication interface.

    class SimpleIndicationWrapper : public Portal {

    public:
        ...
        SimpleIndicationWrapper(int id, PortalPoller *poller = 0);
        virtual void heard1 ( const uint32_t v )= 0;
        ...
    };

Implement subclasses of the wrapper in order to define the callbacks

    class SimpleIndication : public SimpleIndicationWrapper
    {
    public:
      ...
        virtual void heard1(uint32_t a) {
          fprintf(stderr, "heard1(%d)\n", a);
          assert(a == v1a);
          incr_cnt();
        }
        ...
    };

To connect these classes to the hardware, instantiate them using the IfcNames enum identifiers. CONNECTAL prepends the name of the type because C++ does not support overloading of enum tags.

    SimpleIndication *indication = new SimpleIndication(IfcNames_SimpleIndication);
    SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequest);

Create a thread for handling notifications from hardware:

    pthread_t tid;
    if(pthread_create(&tid, NULL,  portalExec, NULL)){
      exit(1);
    }

Now the software invokes hardware methods via the proxy:

    device->say1(v1a);

    device->say2(v2a,v2b);

Simple Example Design Structure

The simple example consists of the following files:

    Simple.bsv
    Makefile
    Top.bsv
    testsimple.cpp

After running make BOARD=zedboard verilog in the simple directory, the zedboard project directory is created, populated by the generated files.

A top level Makefile is created:

    zedboard/Makefile

connectalgen generates wrappers for software-to-hardware interfaces and proxies for hardware-to-software interfaces:

    zedboard/sources/mkzynqtop/SimpleIndicationProxy.bsv
    zedboard/sources/mkzynqtop/SimpleRequestWrapper.bsv

CONNECTAL supports Android on Zynq platforms, so connectalgen generates jni/Android.mk for ndk-build.

    zedboard/jni/Android.mk
    zedboard/jni/Application.mk

CONNECTAL generates jni/Makefile to compile the software for PCIe platforms (vc707 and kc705).

    zedboard/jni/Makefile

CONNECTAL generates software proxies for software-to-hardware interfaces and software wrappers for hardware-to-software interfaces:

    zedboard/jni/SimpleIndicationWrapper.h
    zedboard/jni/SimpleIndicationWrapper.cpp
    zedboard/jni/SimpleRequestProxy.cpp
    zedboard/jni/SimpleRequestProxy.h

CONNECTAL also generates GeneratedTypes.h for struct and enum types in the processed BSV source files:

    zedboard/jni/GeneratedTypes.h

CONNECTAL copies in standard and specified constraints files:

    zedboard/constraints/design_1_processing_system7_1_0.xdc
    zedboard/constraints/zedboard.xdc

CONNECTAL generates several TCL files to run vivado.

The board.tcl file specifies partname, boardname, and connectaldir for the other TCL scripts.

    zedboard/board.tcl

To generate an FPGA bit file, run make bits. This runs vivado with the mkzynqtop-impl.tcl script.

    zedboard/mkzynqtop-impl.tcl

make verilog

Compiling to verilog results in the following verilog files:

    zedboard/verilog/top/mkSimpleIndicationProxySynth.v
    zedboard/verilog/top/mkZynqTop.v

Verilog library files referenced in the design are copied for use in synthesis.

    zedboard/verilog/top/FIFO1.v
    ...

make bits

Running make bits in the zedboard directory results in timing reports:

    zedboard/hw/mkzynqtop_post_place_timing_summary.rpt
    zedboard/hw/mkzynqtop_post_route_timing_summary.rpt
    zedboard/hw/mkzynqtop_post_route_timing.rpt

and some design checkpoints:

    zedboard/hw/mkzynqtop_post_synth.dcp
    zedboard/hw/mkzynqtop_post_place.dcp
    zedboard/hw/mkzynqtop_post_route.dcp

and the FPGA configuration file in .bit and .bin formats:

    zedboard/hw/mkZynqTop.bit
    zedboard/hw/mkZynqTop.bin

make android_exe

CONNECTAL supports Android 4.0 on Zynq platforms. It generates jni/Android.mk which is used by ndk-build to create a native Android executable.

    make android_exe

This produces the ARM elf executable:

    libs/armeabi/android_exe

make run

For Zynq platforms,

    make run

will copy the Android executable and FPGA configuration file to the target device, program the FPGA, and run the executable. See [run.android](../scripts/run.android) for details.

It uses connectal/consolable/checkip to determine the IP address of the device via a USB console connection to the device. If the target is not connected to the build machine via USB, specify the IP address of the target manually:

    make RUNPARAM=ipaddr run

For PCIe platforms, make run programs the FPGA via USB and runs the software locally.

For bluesim, make run invokes bluesim on the design and runs the software locally.

Shared Memory

Shared Memory Hardware

In order to use shared memory, the hardware design instantiates a DMA module in Top.bsv:

   AxiDmaServer#(addrWidth,64) dma <- mkAxiDmaServer(dmaIndicationProxy.ifc, readClients, writeClients);

The AxiDmaServer multiplexes read and write requests from the clients, translates DMA addresses to physical addresses, initiates bus transactions to memory, and delivers responses to the clients.

DMA requests are specified with respect to "portal" memory allocated by software and identified by a pointer.

Requests and responses are tagged in order to enable pipelining.

    typedef struct {
       SGLId pointer;
       Bit#(MemOffsetSize) offset;
       Bit#(8) burstLen;
       Bit#(6)  tag;
       } MemRequest deriving (Bits);

    typedef struct {
       Bit#(dsz) data;
       Bit#(6) tag;
       } MemData#(numeric type dsz) deriving (Bits);

Read clients implement the MemReadClient interface. On response to the read, burstLen MemData items will be put to the readData interface. The design must be ready to consume the data when it is delivered from the memory bus or the system may hang.

    interface MemReadClient#(numeric type dsz);
       interface GetF#(MemRequest)    readReq;
       interface PutF#(MemData#(dsz)) readData;
    endinterface

Write clients implement MemWriteClient. To complete the transaction, burstLen data items will be consumed from the writeData interace. Upon completion of the request, the specified tag will be put to the writeDone interface. The data must be available when the write request is issued to the memory bus or the system may hang.

    interface MemWriteClient#(numeric type dsz);
       interface GetF#(MemRequest)    writeReq;
       interface GetF#(MemData#(dsz)) writeData;
       interface PutF#(Bit#(6))       writeDone;
    endinterface

A design may implement MemReadClient and MemWriteClient interfaces directly, or it may instantiate DmaReadBuffer or DmaWriteBuffer.

 The `AxiDmaServer` is configured with physical address translations
for each region of memory identified by a `pointer`. A design using
DMA must export the `DmaConfig` and `DmaIndication` interfaces of the
DMA server.

Here are the DMA components of [memread_nobuff/Top.bsv](../examples/memread_nobuff/Top.bsv):

Instantiate the design and its interface wrappers and proxies:

    MemreadIndicationProxy memreadIndicationProxy <- mkMemreadIndicationProxy(MemreadIndication);
    Memread memread <- mkMemread(memreadIndicationProxy.ifc);
    MemreadRequestWrapper memreadRequestWrapper <- mkMemreadRequestWrapper(MemreadRequest,memread.request);

Collect the read and write clients:

    Vector#(1, MemReadClient#(64)) readClients = cons(memread.dmaClient, nil);
    Vector#(0, MemReadClient#(64)) writeClients = nil;

Instantiate the DMA server and its wrapper and proxy:

    DmaIndicationProxy dmaIndicationProxy <- mkDmaIndicationProxy(DmaIndication);
    AxiDmaServer#(addrWidth,64) dma <- mkAxiDmaServer(dmaIndicationProxy.ifc, readClients, writeClients);
    DmaConfigWrapper dmaConfigWrapper <- mkDmaConfigWrapper(DmaConfig,dma.request);

Include DmaConfig and DmaIndication in the portals of the design:

    Vector#(4,StdPortal) portals;
    portals[0] = memreadRequestWrapper.portalIfc;
    portals[1] = memreadIndicationProxy.portalIfc;
    portals[2] = dmaConfigWrapper.portalIfc;
    portals[3] = dmaIndicationProxy.portalIfc;

The code generation tools will then produce the software glue necessary for the shared memory support libraries to initialize the DMA "library module" included in the hardware.

Shared Memory Software

The software side instantiates the DmaConfig proxy and the DmaIndication wrapper:

    dma = new DmaConfigProxy(IfcNames_DmaConfig);
    dmaIndication = new DmaIndication(dma, IfcNames_DmaIndication);

Call dma->alloc() to allocate DMA memory. Each chunk of portal memory is identified by a file descriptor. Portal memory may be shared with other processes. Portal memory is reference counted according to the number of file descriptors associated with it.

    PortalAlloc *srcAlloc;
    dma->alloc(alloc_sz, &srcAlloc);

Memory map it to make it accessible to software:

    srcBuffer = (unsigned int *)mmap(0, alloc_sz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, srcAlloc->header.fd, 0);

CONNECTAL is currently using non-snooped interfaces, so the cache must be flushed and invalidated before hardware accesses portal memory:

    dma->dCacheFlushInval(srcAlloc, srcBuffer);

Call dma->reference() to get a pointer that may be passed to hardware:

    unsigned int ref_srcAlloc = dma->reference(srcAlloc);

This also transfers the DMA-to-physical address translation information to the hardware via the DmaConfig interface.

    device->startRead(ref_srcAlloc, numWords, burstLen, iterCnt);

Notes

stewart notes

Currently there are no valid bits and no protections against bursts crossing page boundaries]

There needs to be a way to synchronize Request actions and DMA reads, and to synchronize DMA writes with Indications, so that the writes complete to the coherence point before the indication is delivered to software. One could imagine an absurdly buffered memory interface and a rather direct path for I/O reads that could get out of order.

Portal Interface Structure

CONNECTAL connects software and hardware via portals, where each portal is an interface that allows one side to invoke methods on the other side.

We generally call a portal from software to hardware to be a "request" and from hardware to software to be an "indication" interface.

request-response-21.png

A portal is conceptually a FIFO, where the arguments to a method are packaged as a message. CONNECTAL generates a "proxy" that marshalls the arguments to the method into a message and a "wrapper" that unpacks the arguments and invokes the method.

Currently, connectalgen includes a library that implements portals via memory mapped hardware.

Portal Device Drivers

CONNECTAL uses a platform-specific driver to enable user-space applications to memory-map each portal used by the application and to enable the application to wait for interrupts from the hardware.

indexterm:pcieportal indexterm:zynqportal

  • pcieportal.ko

  • zynqportal.ko

CONNECTAL also uses a generic driver to enable the applications to allocate DRAM that will be shared with the hardware and to send the memory mapping of that memory to the hardware.

  • portalmem.ko

Portal Memory Map

CONNECTAL currently supports up to 15 portals connected between software and hardware, for a total of 1MB of address space. It also provides a directory.

Base address Function

0x00000

Directory that maps portal identifier to portal number

0x10000

Portal 0

0x20000

Portal 1

0x30000

Portal 2

0x40000

Portal 3

0x50000

Portal 4

0x60000

Portal 5

0x70000

Portal 6

0x80000

Portal 7

0x90000

Portal 8

0xa0000

Portal 9

0xb0000

Portal 10

0xc0000

Portal 11

0xd0000

Portal 12

0xe0000

Portal 13

0xf0000

Portal 14

Each portal uses 64KB of address space, divided equally into 4 sections:

Base address Function

0x0000

Request FIFO base

0x4000

Request register base

0x8000

Indication FIFO base

0xc000

Indication register base

Although each portal only passes messages in one direction, it supports two way communication. For "request" portals, the indication path is used to communicate that a message send failed.

Portal FIFOs

Each method is implemented as a FIFO to or from hardware. Each FIFO is allocated 256 bytes of address space.

base address Function

0x0000

Request method 0 FIFO

0x0100

Request method 1 FIFO

0x8000

Indication method 0 FIFO

0x0100

Indication method 1 FIFO

Portal Request Registers

Base address Function

0x4000

Request fired count

0x4004

Out of range write count

Portal Indication Registers

Base address Function Description

0xc000

Interrupt status register

1 if this portal has any messages ready, 0 otherwise

0xC004

Interrupt enable register

Write 1 to enable interrupts, 0 to disable

0xC008

Method count?

Number of methods implemented by this portal

0xC00C

Underflow read count reg

0xC010

Out of range read count reg

0xC014

Out of range write count reg

0xC018

Ready channel indication

channel number + 1 if message is available, 0 otherwise

Index


================================================ FILE: doc/ifdef.md ================================================ --BSC ZYNQ is defined for the following platforms: [zc702,zedboard] PCIE is defined for the following platforms: [ac701, kc705, vc707] SIMULATION is defined for the following platforms: [bsim, bsim_pcie] --CPP ZYNQ is defined for the following platforms: [zedboard, zc702] ================================================ FILE: doc/library/Makefile ================================================ # Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build include ../../Makefile.version # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 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 " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @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: images $(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/connectal.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/connectal.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/connectal" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/connectal" @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: images $(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." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @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." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 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." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." source/devguide/connectalbuild-1.png: source/devguide/connectalbuild.pdf pdftoppm -png source/devguide/connectalbuild.pdf source/devguide/connectalbuild images: source/devguide/connectalbuild-1.png make -C source/design all install: sudo apt-get install poppler-utils sudo pip install docutils sphinx sphinxcontrib-makedomain sphinx-argparse publish: sed -i "s/version = .*/version = '$(VERSION)'/" source/conf.py sed -i "s/release = .*/release = '$(VERSION)'/" source/conf.py make images html latexpdf rsync -avz build/html/* ../../../doc/current/ref rsync -av build/latex/connectal.pdf ../../../doc/current/ref ================================================ FILE: doc/library/source/bsv/addressgenerator.rst ================================================ Address Generator ================= .. bsv:package:: AddressGenerator One of the common patterns that leads to long critical paths in designs on the FPGA are counters and comparisons against counters. This package contains a module for generating the sequence of addresses used by a memory read or write burst, along with a field indicating the last beat of the burst. .. bsv:struct:: AddrBeat#(numeric type addrWidth) .. bsv:field:: Bit#(addrWidth) addr The address for this beat of the request. .. bsv:field:: Bit#(BurstLenSize) bc .. bsv:field:: Bit#(MemTagSize) tag .. bsv:field:: Bool last .. bsv:interface:: AddressGenerator#(numeric type addrWidth, numeric type dataWidth) .. bsv:subinterface:: Put#(PhysMemRequest#(addrWidth)) request The interface for requesting a sequence of addresses. .. bsv:subinterface:: Get#(AddrBeat#(addrWidth)) addrBeat The interface for getting the address beats of the burst. There is one pipeline cycle from the reuqest to the first address beat. .. bsv:module:: mkAddressGenerator#()(AddressGenerator#(addrWidth, dataWidth)) Instantiates an address generator. ================================================ FILE: doc/library/source/bsv/arith.rst ================================================ Arith Package ============= .. bsv:package:: Arith The Arith package implements some functions that correspond to infix operators. .. bsv:function:: Bool booland(Bool x1, Bool x2) Returns logical "and" of inputs. Named to avoid conflict with the Verilog keyword "and". .. bsv:function:: Bool boolor(Bool x1, Bool x2) Returns logical "or" of inputs. Named to avoid conflict with the Verilog keyword "or". .. bsv:function:: Bool eq(a x1, a x2); .. bsv:function:: a add(a x1, a x2) Returns sum of inputs. Requires Arith#(a). .. bsv:function:: a mul(a x1, a x2) Returns product of inputs. Requires Arith#(a). .. bsv:function:: Bit#(b) rshift(Bit#(b) x1, Integer i) Returns input right shifted by i bits. .. bsv:function:: Vector#(n, a) vadd(Vector#(n, a) x1, Vector#(n, a) x2) Returns sum of input vectors. .. bsv:function:: Vector#(n, a) vmul(Vector#(n, a) x1, Vector#(n, a) x2) Returns element-wise product of input vectors. .. bsv:function:: Vector#(n, Bit#(b)) vrshift(Vector#(n, Bit#(b)) x1, Integer i) Right shifts the elements of the input vector by i bits. ================================================ FILE: doc/library/source/bsv/axistream.rst ================================================ AxiStream Package ================ .. bsv:package:: AxiStream AXI Stream Interfaces --------------------- .. bsv:interface:: AxiStreamMaster#(numeric type dataWidth) AXI stream source with dataWidth data bits. .. bsv:method:: Bit#(dsz) tdata() Returns the data from this beat if tvalid is asserted, otherwise returns undefined. .. bsv:method:: Bit#(TDiv#(dsz,8)) tkeep() Returns the byte enables from this beat if tvalid is asserted, otherwise returns undefined. .. bsv:method:: Bit#(1) tlast() Indicates if this is the last data beat of this transaction tvalid is asserted, otherwise returns undefined. .. bsv:method:: Action tready(Bit#(1) v) When tvalid and tready are both asserted the current data is consumed. The value passed to tready may not depend on the output of tvalid. .. bsv:method:: Bit#(1) tvalid() Asserted when the data is valid. .. bsv:interface:: AxiStreamSlave#(numeric type dataWidth) AXI stream sink with dataWidth data bits. .. bsv:method:: Action tdata(Bit#(dsz) data) The data passed from the source if tvalid is asserted, otherwise undefined.. .. bsv:method:: Action tkeep(Bit#(TDiv#(dsz,8)) keep) The byte enables passed from the source if tvalid is asserted, otherwise undefined. .. bsv:method:: Action tlast(Bit#(1) last) Indicates if this is the last data beat of this transaction tvalid is asserted, otherwise returns undefined. .. bsv:method:: Bit#(1) tready() Return 1 if ready to receive data, 0 otherwise. When tvalid and tready are both asserted the current data is consumed. The value passed to tready may not depend on the output of tvalid. .. bsv:method:: Action tvalid(Bit#(1) v) Indicates the data from the source is valid. Connectable Type Instances -------------------------- .. bsv:instance:: Connectable#(AxiStreamMaster#(dataWidth), AxiStreamSlave#(dataWidth)) .. bsv::module:: mkConnection#(AxiStreamMaster#(dataWidth) from, AxiStreamSlave#(dataWidth) to)(Empty) Enables mkConnection(axiStreamMaster, axiStreamSlave) .. bsv:instance:: ToGetM#(AxiStreamMaster#(asz), Bit#(asz)) .. bsv:module: toGetM#(AxiStreamMaster#(asz) m)(Get#(Bit#(asz))) .. bsv:instance:: ToPutM#(AxiStreamSlave#(asz), Bit#(asz)) .. bsv:module: toPutM#(AxiStreamSlave#(asz) m)(Put#(Bit#(asz))) AXI Stream Type Classes and Instances ---------------------------------------- .. bsv:typeclass:: ToAxiStream#(type atype, type btype) .. bsv:function:: atype toAxiStream(btype b) Convert to an AXI stream interface. .. bsv:typeclass:: MkAxiStream#(type atype, type btype) .. bsv:module:: mkAxiStream#(btype b)(atype) Create a module with an AXI Stream interface. .. bsv:instance:: MkAxiStream#(AxiStreamMaster#(dsize), FIFOF#(Bit#(dsize))) .. bsv:module:: mkAxiStream#(FIFOF#(Bit#(dsize)) f)(AxiStreamMaster#(dsize)); Create an AXI Stream master from a FIFOF of bits .. bsv:instance:: MkAxiStream#(AxiStreamSlave#(dsize), FIFOF#(Bit#(dsize))) .. bsv:module:: mkAxiStream#(FIFOF#(Bit#(dsize)) f)(AxiStreamSlave#(dsize)); Create an AXI Stream slave from a FIFOF of bits .. bsv:instance:: MkAxiStream#(AxiStreamMaster#(dsize), FIFOF#(Bit#(dsize))) .. bsv:module:: mkAxiStream#(FIFOF#(Bit#(dsize)) f)(AxiStreamMaster#(dsize)); Create an AXI Stream master from a FIFOF of MemDataF .. bsv:instance:: MkAxiStream#(AxiStreamSlave#(dsize), FIFOF#(MemDataF#(dsize))) .. bsv:module:: mkAxiStream#(FIFOF#(MemDataF#(dsize)) f)(AxiStreamSlave#(dsize)); Create an AXI Stream slave from a FIFOF of MemDataF .. bsv:instance:: MkAxiStream#(AxiStreamMaster#(dsize), PipeOut#(dtype)) .. bsv:module:: mkAxiStream#(PipeOut#(dtype) f)(AxiStreamMaster#(dsize)); Create an AXI Stream master from a PipeOut#(dtype) .. bsv:instance:: MkAxiStream#(AxiStreamSlave#(dsize), FIFOF#(PipeIn#(dtype)) .. bsv:module:: mkAxiStream#(PipeIn#(dtype) f)(AxiStreamSlave#(dsize)); Create an AXI Stream slave from a PipeIn#(dtype) ================================================ FILE: doc/library/source/bsv/bsv.rst ================================================ ======================= Connectal BSV Libraries ======================= .. toctree:: :maxdepth: 2 :numbered: addressgenerator.rst arith.rst axistream.rst ctrlmux.rst hostinterface.rst leds.rst memportal.rst memreadengine.rst memtypes.rst mmu.rst pipe.rst portal.rst ================================================ FILE: doc/library/source/bsv/ctrlmux.rst ================================================ CtrlMux Package ===================== .. bsv:package:: CtrlMux .. bsv:module:: mkInterruptMux#(Vector#(numPortals,MemPortal#(aw,dataWidth)) portals)(ReadOnly#(Bool)) Used by BsimTop, PcieTop, and ZynqTop. Takes a vector of MemPortals and returns a boolean indicating whether any of the portals has indication method data available. .. bsv:module:: mkSlaveMux#(Vector#(numPortals,MemPortal#(aw,dataWidth)) portals)(PhysMemSlave#(addrWidth,dataWidth)) Takes a vector of MemPortals and returns a PhysMemSlave combining them. ================================================ FILE: doc/library/source/bsv/hostinterface.rst ================================================ HostInterface Package ===================== The HostInterface package provides host-specific typedefs and interfaces. .. bsv:package:: HostInterface Host-Specific Constants ------------------------ .. bsv:typedef:: DataBusWidth Width in bits of the data bus connected to host shared memory. .. bsv:typedef:: PhysAddrWidth Width in bits of physical addresses on the data bus connected to host shared memory. .. bsv:typedef:: NumberOfMasters Number of memory interfaces used for connecting to host shared memory. Host-Specific Interfaces ------------------------ .. bsv:interface:: BsimHost Host interface for the bluesim platform .. bsv:interface:: PcieHost Host interface for PCIe-attached FPGAs such as vc707 and kc705 .. bsv:interface:: ZynqHost Host interface for Zynq FPGAs such as zedboard, zc702, zc706, and zybo. The Zc706 is a ZynqHost even when it is plugged into a PCIe slot. Application-Specific Types -------------------------- .. bsv:typedef:: PinType Specifies the type of the application pins interface. Defined from PIN_TYPE. ================================================ FILE: doc/library/source/bsv/leds.rst ================================================ Leds Package ===================== .. bsv:package:: Leds .. bsv:interface:: LEDS .. bsv:typedef:: LedsWidth Defined to be the number of default LEDs on the FPGA board. The Zedboard has 8, Zc706 has 4, ... .. bsv:method:: Bit#(LedsWidth) leds() ================================================ FILE: doc/library/source/bsv/memportal.rst ================================================ MemPortal Package ================= .. bsv:package:: MemPortal mkMemPortal Module ------------------ .. bsv:module:: mkMemPortal#(Bit#(slaveDataWidth) ifcId, PipePortal#(numRequests, numIndications, slaveDataWidth) portal)(MemPortal#(slaveAddrWidth, slaveDataWidth)) Takes an interface identifier and a PipePortal and returns a MemPortal. ================================================ FILE: doc/library/source/bsv/memreadengine.rst ================================================ MemReadEngine Package ===================== .. bsv:package:: MemReadEngine .. bsv:module:: mkMemReadEngine(MemReadEngine#(busWidth, userWidth, cmdQDepth, numServers)) Creates a MemReadEngine with default 256 bytes of buffer per server. .. bsv:module:: mkMemReadEngineBuff#(Integer bufferSizeBytes) (MemReadEngine#(busWidth, userWidth, cmdQDepth, numServers)) Creates a MemReadEngine with the specified buffer size. ================================================ FILE: doc/library/source/bsv/memtypes.rst ================================================ MemTypes Package ================ .. bsv:package:: MemTypes Constants ------------------ .. bsv:typedef:: Bit#(32) SGLId .. bsv:typedef:: 44 MemOffsetSize .. bsv:typedef:: 6 MemTagSize .. bsv:typedef:: 8 BurstLenSize .. bsv:typedef:: 32 MemServerTags .. bsv:typedef:: TDiv#(DataBusSize,8) ByteEnableSize Data Types ---------- .. bsv:struct:: PhysMemRequest#(numeric type addrWidth, dataWidth) A memory request containing a physical memory address .. bsv:field:: Bit#(addrWidth) addr Physical address to read or write .. bsv:field:: Bit#(BurstLenSize) burstLen Length of read or write burst, in bytes. The number of beats of the request will be the burst length divided by the physical width of the memory interface. .. bsv:field:: Bit#(MemTagSize) tag .. bsv:field:: Bit#(TDiv#(dataWidth,8)) firstbe .. bsv:field:: Bit#(TDiv#(dataWidth,8)) lastbe If BYTE_ENABLESis defined as aBSV preprocessor macro,byte write enables are added to PhysMemRequest, intwo fields: firstbe and lastbe.The idea is to enable writing any number of contiguous bytes even if it is less than the width of the shared memory data bus. These have roughly the same semantics as in PCIE. The write enable in firstbe apply to the first beat of a burst request and those inlastbe apply to the last beat of a multi-beat burst request. Intervening beats of a burst request enable the write of all beats of that burst. .. bsv:struct:: MemRequest A logical memory read or write request. The linear offset of the request will be translated by an MMU according to the specified scatter-gather list. .. bsv:field:: SGLId sglId Indicates which scatter-gather list the MMU should use when translating the address .. bsv:field:: Bit#(MemOffsetSize) offset Linear byte offset to read or write. .. bsv:field:: Bit#(BurstLenSize) burstLen Length of read or write burst, in bytes. The number of beats of the request will be the burst length divided by the physical width of the memory interface. .. bsv:field:: Bit#(MemTagSize) tag .. bsv:field:: Bit#(ByteEnableSize) firstbe .. bsv:field:: Bit#(ByteEnableSize) lastbe If BYTE_ENABLESis defined as aBSV preprocessor macro,byte write enables are added to PhysMemRequest, intwo fields: firstbe and lastbe.The idea is to enable writing any number of contiguous bytes even if it is less than the width of the shared memory data bus. These have roughly the same semantics as in PCIE. The write enable in firstbe apply to the first beat of a burst request and those inlastbe apply to the last beat of a multi-beat burst request. Intervening beats of a burst request enable the write of all beats of that burst. .. bsv:struct:: MemData#(numeric type dsz) One beat of the payload of a physical or logical memory read or write request. .. bsv:field:: Bit#(dsz) data One data beat worth of data. .. bsv:field:: Bit#(MemTagSize) tag Indicates to which request this beat belongs. .. bsv:field:: Bool last Indicates that this is the last beat of a burst. .. bsv:struct:: MemDataF#(numeric type dsz) One beat of the payload of a physical or logical memory read or write request. Used by MemReadEngine and MemWriteEngine. .. bsv:field:: Bit#(dsz) data One data beat worth of data. .. bsv:field:: Bit#(MemTagSize) tag Indicates to which request this beat belongs. .. bsv:field:: Bool first Indicates that this is the first data beat of a request. .. bsv:field:: Bool last Indicates that this is the last data beat of a request. Physical Memory Clients and Servers ----------------------------------- .. bsv:interface:: PhysMemMaster#(numeric type addrWidth, numeric type dataWidth) The physical memory interface exposed by MemMaster. For example, connects via AXI to Zynq or via PCIe to x86 memory. .. bsv:subinterface:: PhysMemReadClient#(addrWidth, dataWidth) read_client .. bsv:subinterface:: PhysMemWriteClient#(addrWidth, dataWidth) write_client .. bsv:interface:: PhysMemReadClient#(numeric type asz, numeric type dsz) .. bsv:subinterface:: Get#(PhysMemRequest#(asz)) readReq .. bsv:subinterface:: Put#(MemData#(dsz)) readData .. bsv:interface:: PhysMemWriteClient#(numeric type asz, numeric type dsz) .. bsv:subinterface:: Get#(PhysMemRequest#(asz)) writeReq .. bsv:subinterface:: Get#(MemData#(dsz)) writeData .. bsv:subinterface:: Put#(Bit#(MemTagSize)) writeDone .. bsv:interface:: PhysMemSlave#(numeric type addrWidth, numeric type dataWidth) .. bsv:subinterface:: PhysMemReadServer#(addrWidth, dataWidth) read_server .. bsv:subinterface:: PhysMemWriteServer#(addrWidth, dataWidth) write_server .. bsv:interface:: PhysMemReadServer#(numeric type asz, numeric type dsz) .. bsv:subinterface:: Put#(PhysMemRequest#(asz)) readReq .. bsv:subinterface:: Get#(MemData#(dsz)) readData .. bsv:interface:: PhysMemWriteServer#(numeric type asz, numeric type dsz) .. bsv:subinterface:: Put#(PhysMemRequest#(asz)) writeReq .. bsv:subinterface:: Put#(MemData#(dsz)) writeData .. bsv:subinterface:: Get#(Bit#(MemTagSize)) writeDone Memory Clients and Servers -------------------------- These clients and servers operate on logical addresses. These are translated by an MMU before being issued to system memory. .. bsv:interface:: MemReadClient#(numeric type dsz) The system memory read interface exported by a client of MemServer, such as MemReadEngine. .. bsv:subinterface:: Get#(MemRequest) readReq .. bsv:subinterface:: Put#(MemData#(dsz)) readData .. bsv:interface:: MemWriteClient#(numeric type dsz) The system memory write interface exported by a client of MemServer, such as MemWriteEngine. .. bsv:subinterface:: Get#(MemRequest) writeReq .. bsv:subinterface:: Get#(MemData#(dsz)) writeData .. bsv:subinterface:: Put#(Bit#(MemTagSize)) writeDone .. bsv:interface:: MemReadServer#(numeric type dsz) The system memory read interface exported by MemServer. .. bsv:subinterface:: Put#(MemRequest) readReq .. bsv:subinterface:: Get#(MemData#(dsz)) readData .. bsv:interface:: MemWriteServer#(numeric type dsz) The system memory write interface exported by MemServer. .. bsv:subinterface:: Put#(MemRequest) writeReq .. bsv:subinterface:: Put#(MemData#(dsz)) writeData .. bsv:subinterface:: Get#(Bit#(MemTagSize)) writeDone Memory Engine Types ------------------- .. bsv:struct:: MemengineCmd A read or write request for a MemReadEngine or a MemWriteEngine. MemRead and MemWrite engines will issue one or more burst requests to satisfy the overall length of the request. .. bsv:field:: SGLId sglId Which memory object identifer (scatter gather list ID) the MMU should use to translate the addresses .. bsv:field:: Bit#(MemOffsetSize) base Logical base address of the request, as a byte offset .. bsv:field:: Bit#(BurstLenSize) burstLen Maximum burst length, in bytes. .. bsv:field:: Bit#(32) len Number of bytes to transfer. Must be a multiple of the data bus width. .. bsv:field:: Bit#(MemTagSize) tag Identifier for this request. Memory Engine Interfaces ------------------------ .. bsv:interface:: MemWriteEngineServer#(numeric type userWidth) The interface used by one client of a MemWriteEngine. .. bsv:subinterface:: Put#(MemengineCmd) request .. bsv:subinterface:: Get#(Bool) done .. bsv:subinterface:: PipeIn#(Bit#(userWidth)) data .. bsv:interface:: MemWriteEngine#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth, numeric type numServers) A multi-client component that supports multi-burst writes to system memory. .. bsv:subinterface:: MemWriteClient#(busWidth) dmaClient .. bsv:subinterface:: Vector#(numServers, MemWriteEngineServer#(userWidth)) writeServers .. bsv:interface:: MemReadEngineServer#(numeric type userWidth) The interface used by one client of a MemReadEngine. .. bsv:subinterface:: Put#(MemengineCmd) request .. bsv:subinterface:: PipeOut#(MemDataF#(userWidth)) data .. bsv:interface:: MemReadEngine#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth, numeric type numServers) A multi-client component that supports multi-burst reads from system memory. .. bsv:subinterface:: MemReadClient#(busWidth) dmaClient .. bsv:subinterface:: Vector#(numServers, MemReadEngineServer#(userWidth)) readServers Memory Traffic Interfaces ------------------------- .. bsv:interface:: DmaDbg .. bsv:method:: ActionValue#(Bit#(64)) getMemoryTraffic() .. bsv:method:: ActionValue#(DmaDbgRec) dbg() Connectable Instances --------------------- .. bsv:instance:: Connectable#(MemReadClient#(dsz), MemReadServer#(dsz)) .. bsv:instance:: Connectable#(MemWriteClient#(dsz), MemWriteServer#(dsz)) .. bsv:instance:: Connectable#(PhysMemMaster#(addrWidth, busWidth), PhysMemSlave#(addrWidth, busWidth)) .. bsv:instance:: Connectable#(PhysMemMaster#(32, busWidth), PhysMemSlave#(40, busWidth)) ================================================ FILE: doc/library/source/bsv/mmu.rst ================================================ MMU Package =========== .. bsv:package:: MMU .. bsv:typedef:: 32 MaxNumSGLists .. bsv:typedef:: Bit#(TLog#(MaxNumSGLists)) SGListId .. bsv:typedef:: 12 SGListPageShift0 .. bsv:typedef:: 16 SGListPageShift4 .. bsv:typedef:: 20 SGListPageShift8 .. bsv:typedef:: 24 SGListPageShift12 .. bsv:typedef:: Bit#(TLog#(MaxNumSGLists)) RegionsIdx .. bsv:typedef:: 8 IndexWidth Address Translation ------------------- .. bsv:struct:: AddrTransRequest Address translation request type .. bsv:field:: SGListId id Which object identifier to use. .. bsv:field:: Bit#(MemOffsetSize) off The address to translate. .. bsv:interface:: MMU#(numeric type addrWidth) An address translator .. bsv:subinterface:: MMURequest request The interface of the MMU that is exposed to software as a portal. .. bsv:subinterface:: Vector#(2,Server#(AddrTransRequest,Bit#(addrWidth))) addr The address translation servers .. bsv:interface:: MMURequest; The Connectal MMU maps linear offsets on objects identified by sglId to dmaAddress. It is constructed from a list of segments, where the segments are sorted by size in descending order. Each segment must be one of the supported sizes. .. bsv:method:: Action sglist(Bit#(32) sglId, Bit#(32) segmentIndex, Bit#(64) addr, Bit#(32) len); Updates the address of the segment number segmentIndex for object identified by sglId. The address has been preshifted so that the final address may be constructed by concatenating addr and offset within the segment. .. bsv:method:: Action region(Bit#(32) sglId, Bit#(64) barr12, Bit#(32) idxOffset12, Bit#(64) barr8, Bit#(32) idxOffset8, Bit#(64) barr4, Bit#(32) idxOffset4, Bit#(64) barr0, Bit#(32) idxOffset0); Updates the boundaries between the segments of different sizes for the object identified by sglId. For example, if an offset to be translated is less than barr12, then the target segment is of size SGListPageShift12 (2^24 bytes). If the offset is less than barr12, then idxOffset12 points to the first translation table entry for segments of that size pbase = offset >> segAddrSize + idxOffset segNumber = pbase + idxOffset dmaBase = translationTable[sglId,segNumber] dmaAddress = {dmaBase[physAddrSize-segAddrSize-1:0],offset[segAddrSize-1:0]} .. bsv:method:: Action idRequest(SpecialTypeForSendingFd fd); Requests a new object identifier. .. bsv:method:: Action idReturn(Bit#(32) sglId); Indicates that the designated object is no longer in use. The MMU clears the translation entries for this object. .. bsv:method:: Action setInterface(Bit#(32) interfaceId, Bit#(32) sglId); This method is only implemented in software responders. .. bsv:interface:: MMUIndication; .. bsv:method:: Action idResponse(Bit#(32) sglId); Response from idRequest indicating the new object identifier sglId. .. bsv:method:: Action configResp(Bit#(32) sglId); .. bsv:method:: Action error(Bit#(32) code, Bit#(32) sglId, Bit#(64) offset, Bit#(64) extra); Sent from the MMU when there is a translation error. .. bsv:struct:: DmaErrorType .. bsv:field:: DmaErrorNone Code 0 indicates no error. .. bsv:field:: DmaErrorSGLIdOutOfRange_r Code 1 indicates object identifier was out of range during a read request. .. bsv:field:: DmaErrorSGLIdOutOfRange_w Code 2 indicates object identifier was out of range during a read request. .. bsv:field:: DmaErrorMMUOutOfRange_r Code 3 indicates MMU identifier was out of range during a read request. .. bsv:field:: DmaErrorMMUOutOfRange_w Code 4 indicates MMU identifier was out of range during a read request. .. bsv:field:: DmaErrorOffsetOutOfRange Code 5 indicates offset was out of range for the designated object. .. bsv:field:: DmaErrorSGLIdInvalid Code 6 indicates the object identifier was out of range. .. bsv:field:: DmaErrorTileTagOutOfRange Code 7 indicates the tag was out of range for the requesting platform application tile. .. bsv:module:: mkMMU#(Integer iid, Bool hostMapped, MMUIndication mmuIndication)(MMU#(addrWidth)) Instantiates an address translator that stores a scatter-gather list to define the logical to physical address mapping. Parameter iid is the portal identifier of the MMURequest interface. Parameter hostMapped is true for simulation. .. bsv:interface:: MemServerRequest; .. bsv:method:: Action addrTrans(Bit#(32) sglId, Bit#(32) offset); Requests an address translation .. bsv:method:: Action setTileState(TileControl tc); Changes tile status .. bsv:method:: Action stateDbg(ChannelType rc) Requests debug info for the specified channel type .. bsv:method:: Action memoryTraffic(ChannelType rc); .. bsv:interface:: MemServerIndication; .. bsv:method:: Action addrResponse(Bit#(64) physAddr); .. bsv:method:: Action reportStateDbg(DmaDbgRec rec); .. bsv:method:: Action reportMemoryTraffic(Bit#(64) words); .. bsv:method:: Action error(Bit#(32) code, Bit#(32) sglId, Bit#(64) offset, Bit#(64) extra); ================================================ FILE: doc/library/source/bsv/pipe.rst ================================================ Pipe Package ============ .. bsv:package:: Pipe The Pipe package is modeled on Bluespec, Inc's PAClib package. It provides functions and modules for composing pipelines of operations. Pipe Interfaces --------------- .. bsv:interface:: PipeIn#(type a) Corresponds to the input interface of a FIFOF. .. bsv:method:: Action enq(a v) .. bsv:method:: Bool notFull() .. bsv:interface:: PipeOut#(type a) Corresponds to the output interface of a FIFOF. .. bsv:method:: a first() .. bsv:method:: Action deq() .. bsv:method:: Bool notEmpty() .. bsv:typeclass:: ToPipeIn#(type a, type b) .. bsv:function:: PipeIn#(a) toPipeIn(b in) Returns a PipeIn to the object "in" with no additional buffering. .. bsv:typeclass:: ToPipeOut#(type a, type b) .. bsv:function:: PipeOut#(a) toPipeOut(b in) Returns a PipeOut from the object "in" with no additional buffering. .. bsv:typeclass:: MkPipeIn#(type a, type b) .. bsv:module:: mkPipeIn#(b in)(PipeIn#(a)) Instantiates a module whose interface is a PipeIn to the input parameter "in". Includes a FIFO buffering stage. .. bsv:typeclass:: MkPipeOut#(type a, type b) .. bsv:module:: mkPipeOut#(b in)(PipeOut#(a)) Instantiates a module whose interface is PipeOut from the input parameter "in". Includes a FIFO buffering stage. .. bsv:instance:: ToPipeIn#(a, FIFOF#(a)) Converts a FIFOF to a PipeIn. .. bsv:instance:: ToPipeOut#(a, function a pipefn()) Converts a function to a PipeOut. .. bsv:instance:: ToPipeOut#(a, Reg#(a)) Converts a register to a PipeOut. .. bsv:instance:: ToPipeIn#(Vector#(m, a), Gearbox#(m, n, a)) Converts a Gearbox to a PipeOut. .. bsv:instance:: ToPipeOut#(a, FIFOF#(a)) Converts a FIFOF to a PipeOut. .. bsv:instance:: ToPipeOut#(Vector#(n,a), MIMO#(k,n,sz,a)) Converts a MIMO to a PipeOut. .. bsv:instance:: ToPipeOut#(Vector#(n, a), Gearbox#(m, n, a)) Converts a Gearbox to a PipeOut. .. bsv:instance:: MkPipeOut#(a, Get#(a)) Instantiates a pipelined PipeOut from a Get interface. .. bsv:instance:: MkPipeIn#(a, Put#(a)) Instantiates a pipelined PipeIn to a Put interface. Get and Put Pipes ----------------- .. bsv:instance:: ToGet #(PipeOut #(a), a) .. bsv:instance:: ToPut #(PipeIn #(a), a) Connectable Pipes ----------------- .. bsv:instance:: Connectable#(PipeOut#(a),Put#(a)) .. bsv:instance:: Connectable#(PipeOut#(a),PipeIn#(a)) Mapping over Pipes ------------------ .. bsv:function:: PipeOut#(a) toCountedPipeOut(Reg#(Bit#(n)) r, PipeOut#(a) pipe) .. bsv:function:: PipeOut#(Tuple2#(a,b)) zipPipeOut(PipeOut#(a) ina, PipeOut#(b) inb) Returns a PipeOut whose elements are 2-tuples of the elements of the input pipes. .. bsv:function:: PipeOut#(b) mapPipe(function b f(a av), PipeOut#(a) apipe) Returns a PipeOut that maps the function f to each element of the input pipes with no buffering. .. bsv:module:: mkMapPipe#(function b f(a av), PipeOut#(a) apipe)(PipeOut#(b)) Instantiates a PipeOut that maps the function f to each element of the input pipes using a FIFOF for buffering. .. bsv:function:: PipeIn#(a) mapPipeIn(function b f(a av), PipeIn#(b) apipe) Returns a PipeIn applies the function f to each value that is enqueued. Reducing Pipes -------------- .. bsv::typeclass ReducePipe#( numeric type n, type a) Instantiates a tree of logic to reduce the values of the input pipes using the combinepipe function. .. bsv:module:: mkReducePipe (CombinePipe#(Tuple2#(a,a), a) combinepipe, PipeOut#(Vector#(n,a)) inpipe, PipeOut#(a) ifc) .. bsv:module:: mkReducePipes (CombinePipe#(Tuple2#(a,a), a) combinepipe, Vector#(n,PipeOut#(a)) inpipe, PipeOut#(a) ifc) Functions on Pipes of Vectors ----------------------------- .. bsv:function:: PipeOut#(a) unvectorPipeOut(PipeOut#(Vector#(1,a)) in) Funneling and Unfunneling ------------------------- .. bsv:module:: mkFunnel#(PipeOut#(Vector#(mk,a)) in)(PipeOut#(Vector#(m, a))) Returns k Vectors of m elements for each Vector#(mk,a) element of the input pipe. .. bsv:module:: mkFunnel1#(PipeOut#(Vector#(k,a)) in)(PipeOut#(a)) Sames as mkFunnel, but returns k singleton elements for each vector element of the input pipe. .. bsv:module:: mkFunnelGB1#(Clock slowClock, Reset slowReset, Clock fastClock, Reset fastReset, PipeOut#(Vector#(k,a)) in)(PipeOut#(a)) Same as mkFunnel1, but uses a Gearbox with a 1 to k ratio. .. bsv:module:: mkUnfunnel#(PipeOut#(Vector#(m,a)) in)(PipeOut#(Vector#(mk, a))) The dual of mkFunnel. Consumes k elements from the input pipe, each of which is an m-element vector, and returns an mk-element vector. .. bsv:module:: mkUnfunnelGB#(Clock slowClock, Reset slowReset, Clock fastClock, Reset fastReset, PipeOut#(Vector#(1,a)) in)(PipeOut#(Vector#(k, a))) The same as mkUnfunnel, but uses a Gearbox with a 1-to-k. .. bsv:module:: mkRepeat#(UInt#(n) repetitions, PipeOut#(a) inpipe)(PipeOut#(a)) Returns a PipeOut which repeats each element of the input pipe the specified number of times. Fork and Join ------------- Fork and Join with limited scalability .. bsv:module:: mkForkVector#(PipeOut#(a) inpipe)(Vector#(n, PipeOut#(a))) Replicates each element of the input pipe to each of the output pipes. It uses a FIFOF per output pipe. .. bsv:module:: mkSizedForkVector#(Integer size, PipeOut#(a) inpipe)(Vector#(n, PipeOut#(a))) Used a SizedFIFOF for each of the output pipes. .. bsv:module:: mkJoin#(function c f(a av, b bv), PipeOut#(a) apipe, PipeOut#(b) bpipe)(PipeOut#(c)) Returns a PipeOut that applies the function f to the elements of the input pipes, with no buffering. .. bsv:module:: mkJoinBuffered#(function c f(a av, b bv), PipeOut#(a) apipe, PipeOut#(b) bpipe)(PipeOut#(c)) Returns a PipeOut that applies the function f to the elements of the input pipes, using a FIFOF to buffer the output. .. bsv:module:: mkJoinVector#(function b f(Vector#(n, a) av), Vector#(n, PipeOut#(a)) apipes)(PipeOut#(b)) Same as mkJoin, but operates on a vector of PipeOut as input. Funnel Pipes --------------- Fork and Join with tree-based fanout and fanin for scalability. These are used by MemReadEngine and MemWriteEngine. .. bsv:typedef:: Vector#(j,PipeOut#(a)) FunnelPipe#(numeric type j, numeric type k, type a, numeric type bitsPerCycle) .. bsv:typedef:: Vector#(k,PipeOut#(a)) UnFunnelPipe#(numeric type j, numeric type k, type a, numeric type bitsPerCycle) .. bsv:typeclass:: FunnelPipesPipelined#(numeric type j, numeric type k, type a, numeric type bpc) .. bsv:module:: mkFunnelPipesPipelined#(Vector#(k,PipeOut#(a)) in) (FunnelPipe#(j,k,a,bpc)) .. bsv:module:: mkFunnelPipesPipelinedRR#(Vector#(k,PipeOut#(a)) in, Integer c) (FunnelPipe#(j,k,a,bpc)) .. bsv:module:: mkUnFunnelPipesPipelined#(Vector#(j,PipeOut#(Tuple2#(Bit#(TLog#(k)),a))) in) (UnFunnelPipe#(j,k,a,bpc)) .. bsv:module:: mkUnFunnelPipesPipelinedRR#(Vector#(j,PipeOut#(a)) in, Integer c) (UnFunnelPipe#(j,k,a,bpc)) .. bsv:instance:: FunnelPipesPipelined#(1,1,a,bpc) .. bsv:instance:: FunnelPipesPipelined#(1,k,a,bpc) .. bsv:module:: mkUnFunnelPipesPipelinedInternal#(Vector#(1, PipeOut#(Tuple2#(Bit#(TLog#(k)),a))) in)(UnFunnelPipe#(1,k,a,bpc)) .. bsv:module:: mkFunnelPipes#(Vector#(mk, PipeOut#(a)) ins)(Vector#(m, PipeOut#(a))) .. bsv:module:: mkFunnelPipes1#(Vector#(k, PipeOut#(a)) ins)(PipeOut#(a)) .. bsv:module:: mkUnfunnelPipes#(Vector#(m, PipeOut#(a)) ins)(Vector#(mk, PipeOut#(a))) .. bsv:module:: mkPipelinedForkVector#(PipeOut#(a) inpipe, Integer id)(UnFunnelPipe#(1,k,a,bpc)) Delimited Pipes --------------- .. bsv:interface:: FirstLastPipe#(type a) A pipe whose elements two-tuples of boolean values indicating first and last in a series. The ttype a indicates the type of the counter used. .. bsv:subinterface:: PipeOut#(Tuple2#(Bool,Bool)) pipe The pipe of delimited elements .. bsv:method:: Action start(a count) Starts the series of count elements .. bsv:module:: mkFirstLastPipe#()(FirstLastPipe#(a)) Creates a FirstLastPipe. .. bsv:struct:: RangeConfig#(type a) The base, limit and step for mkRangePipeOut. .. bsv:field:: a xbase .. bsv:field:: a xlimit .. bsv:field:: a xstep .. bsv:interface:: RangePipeIfc#(type a) .. bsv:subinterface:: PipeOut#(a) pipe .. bsv:method:: Bool isFirst() .. bsv:method:: Bool isLast() .. bsv:method:: Action start(RangeConfig#(a) cfg) .. bsv:module:: mkRangePipeOut#()(RangePipeIfc#(a)) Creates a Pipe of values from xbase to xlimit by xstep. Used by MemRead. ================================================ FILE: doc/library/source/bsv/portal.rst ================================================ Portal Package ============== .. bsv:package:: Portal PipePortal Interface -------------------- .. bsv:interface:: PipePortal#(numeric type numRequests, numeric type numIndications, numeric type slaveDataWidth) .. bsv:method:: Bit#(16) messageSize(Bit#(16) methodNumber) Returns the message size of the methodNumber method of the portal. .. bsv:subinterface:: Vector#(numRequests, PipeIn#(Bit#(slaveDataWidth))) requests .. bsv:subinterface:: Vector#(numIndications, PipeOut#(Bit#(slaveDataWidth))) indications MemPortal Interface ------------------- .. bsv:interface:: MemPortal#(numeric type slaveAddrWidth, numeric type slaveDataWidth) .. bsv:subinterface:: PhysMemSlave#(slaveAddrWidth,slaveDataWidth) slave .. bsv:subinterface:: ReadOnly#(Bool) interrupt .. bsv:subinterface:: WriteOnly#(Bool) top .. bsv:function:: PhysMemSlave(_a,_d) getSlave(MemPortal#(_a,_d) p) .. bsv:function:: ReadOnly#(Bool) getInterrupt(MemPortal#(_a,_d) p) .. bsv:function:: Vector#(16,ReadOnly#(Bool)) getInterruptVector(Vector#(numPortals, MemPortal#(_a,_d)) portals) ShareMemoryPortal Interface --------------------------- .. bsv:interface:: SharedMemoryPortal#(numeric type dataBusWidth) Should be in SharedMemoryPortal.bsv .. bsv:subinterface:: MemReadClient(dataBusWidth) readClient .. bsv:subinterface:: MemWriteClient#(dataBusWidth) writeClient .. bsv:subinterface:: SharedMemoryPortalConfig cfg .. bsv:subinterface:: ReadOnly#(Bool) interrupt ConnectalTop Interface ---------------------- .. bsv:interface:: ConnectalTop#(numeric type addrWidth, numeric type dataWidth, type pins, numeric type numMasters) Interface ConnectalTop is the interface exposed by the top module of a Connectal hardware design. .. bsv:subinterface:: PhysMemSlave#(32,32) slave .. bsv:subinterface:: Vector#(numMasters,PhysMemMaster#(addrWidth, dataWidth)) masters .. bsv:subinterface:: Vector#(16,ReadOnly#(Bool)) interrupt .. bsv:subinterface:: LEDS leds .. bsv:subinterface:: pins pins StdConnectalTop Typedef ----------------------- .. bsv:typedef:: StdConnectalTop :parameter: numeric type addrWidth :returntype: ConnectalTop#(addrWidth,64,Empty,0) Type StdConnectalTop indicates a Connectal hardware design with no user defined pins and no user of host shared memory. The "pins" interface is Empty and the number of masters is 0. .. bsv:typedef:: StdConnectalDmaTop :parameter: numeric type addrWidth :returnType: ConnectalTop#(addrWidth,64,Empty,1) Type StdConnectalDmaTop indicates a Connectal hardware design with no user defined pins and a single client of host shared memory. The "pins" interface is Empty and the number of masters is 1. ================================================ FILE: doc/library/source/bsvsphinx.py ================================================ # -*- coding: utf-8 -*- """ The Bsv domain. :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. Copyright 2014 Quanta Research Cambridge. :license: BSD, see LICENSE for details. """ from __future__ import print_function import re from docutils import nodes from docutils.parsers.rst import directives from sphinx import addnodes from sphinx.roles import XRefRole from sphinx.locale import l_, _ from sphinx.domains import Domain, ObjType, Index from sphinx.directives import ObjectDescription from sphinx.util.nodes import make_refnode from sphinx.util.docutils import SphinxDirective from sphinx.util.docfields import Field, GroupedField, TypedField # REs for Bsv signatures bsv_param_re = re.compile('^\((.*)\)$') def _pseudo_parse_arglist(signode, arglist): """"Parse" a list of arguments separated by commas. Arguments can have "optional" annotations given by enclosing them in brackets. Currently, this will split at any comma, even if it's inside a string literal (e.g. default argument value). """ paramlist = addnodes.desc_parameterlist() stack = [paramlist] try: for argument in arglist.split(','): argument = argument.strip() ends_open = ends_close = 0 while argument.startswith('['): stack.append(addnodes.desc_optional()) stack[-2] += stack[-1] argument = argument[1:].strip() while argument.startswith(']'): stack.pop() argument = argument[1:].strip() while argument.endswith(']'): ends_close += 1 argument = argument[:-1].strip() while argument.endswith('['): ends_open += 1 argument = argument[:-1].strip() if argument: stack[-1] += addnodes.desc_parameter(argument, argument) while ends_open: stack.append(addnodes.desc_optional()) stack[-2] += stack[-1] ends_open -= 1 while ends_close: stack.pop() ends_close -= 1 if len(stack) != 1: raise IndexError except IndexError: # if there are too few or too many elements on the stack, just give up # and treat the whole argument list as one argument, discarding the # already partially populated paramlist node signode += addnodes.desc_parameterlist() signode[-1] += addnodes.desc_parameter(arglist, arglist) else: signode += paramlist class BsvObject(ObjectDescription): """ Description of a general Bsv object. """ option_spec = { 'noindex': directives.flag, 'package': directives.unchanged, 'annotation': directives.unchanged, 'parameter': directives.unchanged, 'returntype': directives.unchanged, } doc_field_types = [ TypedField('parameter', label=l_('Parameters'), names=('param', 'parameter', 'arg', 'argument', 'keyword', 'kwarg', 'kwparam'), typerolename='obj', typenames=('paramtype', 'type'), can_collapse=True), TypedField('variable', label=l_('Variables'), rolename='obj', names=('var', 'ivar', 'cvar'), typerolename='obj', typenames=('vartype',), can_collapse=True), GroupedField('exceptions', label=l_('Raises'), rolename='exc', names=('raises', 'raise', 'exception', 'except'), can_collapse=True), Field('returnvalue', label=l_('Returns'), has_arg=False, names=('returns', 'return')), Field('returntype', label=l_('Return type'), has_arg=False, names=('rtype',)), ] def get_signatures(self): siglines = ObjectDescription.get_signatures(self) return siglines def get_signature_prefix(self, sig): """May return a prefix to put before the object name in the signature. """ return '' def needs_arglist(self): """May return true if an empty argument list is to be generated even if the document contains none. """ return False def handle_signature(self, sig, signode): """Transform a Bsv signature into RST nodes. Return (fully qualified name of the thing, interfacename if any). If inside a interface, the current interface name is handled intelligently: * it is stripped from the displayed name if present * it is added to the full name (return value) if not present """ print('BsvObject.handle_signature', sig) name_prefix = '' name = sig arglist = '' retann = '' if self.objtype in ['interface', 'instance', 'typeclass']: split = sig.split('#', 1) name = split[0] if len(split) > 1: arglist = split[1] m = bsv_param_re.match(arglist) if m: arglist = m.group(1) elif self.objtype in ['subinterface', 'field']: split = sig.rsplit(' ', 1) print('rsplit', split) name = split[-1] if len(split) > 1: retann = split[0] elif self.objtype in ['method', 'function']: split = sig.split(' ', 1) retann = split[0] nameparams = split[1] split = nameparams.split('(', 1) name = split[0] if len(split) > 1: arglist = split[1][0:-1] elif self.objtype in ['module']: split = sig.split('#', 1) name = split[0] if len(split) > 1: depth = 0 paramreturn = split[1] #print('module', paramreturn, len(paramreturn)) for i in range(0,len(paramreturn)): c = paramreturn[i] if c == '(': depth = depth+1 elif c == ')': depth = depth-1 #print(i, c, depth) if depth==0: endofparam=i break arglist = paramreturn[1:endofparam] retann = paramreturn[endofparam+1:-1] #print(arglist) #print(endofparam, retann) # determine package and interface name (if applicable), as well as full name modname = self.options.get( 'package', self.env.temp_data.get('bsv:package')) interfacename = self.env.temp_data.get('bsv:interface') if interfacename: add_package = False if name_prefix and name_prefix.startswith(interfacename): fullname = name_prefix + name # interface name is given again in the signature name_prefix = name_prefix[len(interfacename):].lstrip('.') elif name_prefix: # interface name is given in the signature, but different # (shouldn't happen) fullname = interfacename + '.' + name_prefix + name else: # interface name is not given in the signature fullname = interfacename + '.' + name else: add_package = True if name_prefix: interfacename = name_prefix.rstrip('.') fullname = name_prefix + name else: interfacename = '' fullname = name signode['package'] = modname signode['interface'] = interfacename signode['fullname'] = fullname sig_prefix = self.get_signature_prefix(sig) if sig_prefix: signode += addnodes.desc_annotation(sig_prefix, sig_prefix) if name_prefix: signode += addnodes.desc_addname(name_prefix, name_prefix) # exceptions are a special case, since they are documented in the # 'exceptions' package. elif add_package and self.env.config.add_package_names: modname = self.options.get( 'package', self.env.temp_data.get('bsv:package')) if modname and modname != 'exceptions': nodetext = modname + '::' signode += addnodes.desc_addname(nodetext, nodetext) anno = self.options.get('annotation') signode += addnodes.desc_name(name, name) #print('arglist', arglist) if not arglist: if self.needs_arglist(): # for callables, add an empty parameter list if arglist: signode += addnodes.desc_parameterlist(text=arglist) elif self.options.get('parameter'): signode += addnodes.desc_parameterlist(text=self.options.get('parameter')) if retann: signode += addnodes.desc_returns(text=retann) elif self.options.get('returntype'): signode += addnodes.desc_returns(text=self.options.get('returntype')) if anno: signode += addnodes.desc_annotation(' ' + anno, ' ' + anno) #print('signode', signode) return fullname, name_prefix _pseudo_parse_arglist(signode, arglist) if retann: signode += addnodes.desc_returns(retann, retann) if anno: signode += addnodes.desc_annotation(' ' + anno, ' ' + anno) return fullname, name_prefix def get_index_text(self, modname, name): """Return the text for the index entry of the object.""" raise NotImplementedError('must be implemented in subinterfacees') def add_target_and_index(self, name_cls, sig, signode): modname = self.options.get( 'package', self.env.temp_data.get('bsv:package')) fullname = (modname and modname + '::' or '') + name_cls[0] # note target if fullname not in self.state.document.ids: signode['names'].append(fullname) signode['ids'].append(fullname) signode['first'] = (not self.names) self.state.document.note_explicit_target(signode) objects = self.env.domaindata['bsv']['objects'] if fullname in objects: self.state_machine.reporter.warning( 'duplicate object description of %s, ' % fullname + 'other instance in ' + self.env.doc2path(objects[fullname][0]) + ', use :noindex: for one of them', line=self.lineno) objects[fullname] = (self.env.docname, self.objtype) indextext = self.get_index_text(modname, name_cls) if indextext: self.indexnode['entries'].append(('single', indextext, fullname, '')) def before_content(self): # needed for automatic qualification of members (reset in subinterfacees) self.clsname_set = False def after_content(self): if self.clsname_set: self.env.temp_data['bsv:interface'] = None class BsvPackagelevel(BsvObject): """ Description of an object on package level (functions, data). """ def get_signature_prefix(self, sig): return self.objtype + ' ' def needs_arglist(self): return self.objtype.endswith('method') or self.objtype in ['typedef', 'function', 'interface', 'typeclass'] def get_index_text(self, modname, name_cls): if modname: return _('%s (%s in package %s)') % (name_cls[0], self.objtype, modname) else: return _('%s (%s)') % (name_cls[0], self.objtype) class BsvInterfacelike(BsvObject): """ Description of a interface-like object (interfacees). """ def get_signature_prefix(self, sig): return self.objtype + ' ' def get_index_text(self, modname, name_cls): if modname: return _('%s (%s in package %s)') % (name_cls[0], self.objtype, modname) else: return _('%s (%s)') % (name_cls[0], self.objtype) def before_content(self): BsvObject.before_content(self) if self.names: self.env.temp_data['bsv:interface'] = self.names[0][0] self.clsname_set = True class BsvInterfacemember(BsvObject): """ Description of a interface member (methods, fields). """ option_spec = { 'noindex': directives.flag, 'package': directives.unchanged, 'annotation': directives.unchanged, 'returntype': directives.unchanged_required, 'parameter': directives.unchanged_required } def needs_arglist(self): return self.objtype.endswith('method') or self.objtype in ['typedef', 'interface', 'subinterface', 'field'] def get_signature_prefix(self, sig): if self.objtype == 'staticmethod': return 'static ' elif self.objtype == 'interfacemethod': return 'interfacemethod ' return '' def get_index_text(self, modname, name_cls): name, cls = name_cls add_packages = self.env.config.add_package_names print('BsvInterfacemember.get_index_text', name, cls, modname) if self.objtype == 'method': try: clsname, methname = name.rsplit('.', 1) except ValueError: if modname: return _('%s() (in package %s)') % (name, modname) else: return '%s()' % name if modname and add_packages: return _('%s() (%s::%s method)') % (methname, modname, clsname) else: return _('%s() (%s method)') % (methname, clsname) elif self.objtype == 'staticmethod': try: clsname, methname = name.rsplit('.', 1) except ValueError: if modname: return _('%s() (in package %s)') % (name, modname) else: return '%s()' % name if modname and add_packages: return _('%s() (%s::%s static method)') % (methname, modname, clsname) else: return _('%s() (%s static method)') % (methname, clsname) elif self.objtype == 'interfacemethod': try: clsname, methname = name.rsplit('.', 1) except ValueError: if modname: return _('%s() (in package %s)') % (name, modname) else: return '%s()' % name if modname: return _('%s() (%s::%s interface method)') % (methname, modname, clsname) else: return _('%s() (%s interface method)') % (methname, clsname) elif self.objtype == 'attribute': try: clsname, attrname = name.rsplit('.', 1) except ValueError: if modname: return _('%s (in package %s)') % (name, modname) else: return name if modname and add_packages: return _('%s (%s::%s attribute)') % (attrname, modname, clsname) else: return _('%s (%s attribute)') % (attrname, clsname) else: return '' def before_content(self): BsvObject.before_content(self) lastname = self.names and self.names[-1][1] if lastname and not self.env.temp_data.get('bsv:interface'): self.env.temp_data['bsv:interface'] = lastname.strip('.') self.clsname_set = True class BsvDecoratorMixin(object): """ Mixin for decorator directives. """ def handle_signature(self, sig, signode): print('BsvDecoratorMixin.handle_signature', sig) ret = super(BsvDecoratorMixin, self).handle_signature(sig, signode) signode.insert(0, addnodes.desc_addname('@', '@')) return ret def needs_arglist(self): return False class BsvDecoratorFunction(BsvDecoratorMixin, BsvPackagelevel): """ Directive to mark functions meant to be used as decorators. """ def run(self): # a decorator function is a function after all self.name = 'bsv:function' return BsvPackagelevel.run(self) class BsvDecoratorMethod(BsvDecoratorMixin, BsvInterfacemember): """ Directive to mark methods meant to be used as decorators. """ def run(self): self.name = 'bsv:method' return BsvInterfacemember.run(self) class BsvPackage(SphinxDirective): """ Directive to mark description of a new package. """ has_content = False required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False option_spec = { 'platform': lambda x: x, 'synopsis': lambda x: x, 'noindex': directives.flag, 'deprecated': directives.flag, } def run(self): env = self.state.document.settings.env modname = self.arguments[0].strip() noindex = 'noindex' in self.options env.temp_data['bsv:package'] = modname ret = [] if not noindex: env.domaindata['bsv']['packages'][modname] = \ (env.docname, self.options.get('synopsis', ''), self.options.get('platform', ''), 'deprecated' in self.options) # make a duplicate entry in 'objects' to facilitate searching for # the package in BsvDomain.find_obj() env.domaindata['bsv']['objects'][modname] = (env.docname, 'package') targetnode = nodes.target('', '', ids=['package-' + modname], ismod=True) self.state.document.note_explicit_target(targetnode) # the platform and synopsis aren't printed; in fact, they are only # used in the pkgindex currently ret.append(targetnode) indextext = _('%s (package)') % modname inode = addnodes.index(entries=[('single', indextext, 'package-' + modname, '')]) ret.append(inode) return ret class BsvCurrentPackage(SphinxDirective): """ This directive is just to tell Sphinx that we're documenting stuff in package foo, but links to package foo won't lead here. """ has_content = False required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False option_spec = {} def run(self): env = self.state.document.settings.env modname = self.arguments[0].strip() if modname == 'None': env.temp_data['bsv:package'] = None else: env.temp_data['bsv:package'] = modname return [] class BsvXRefRole(XRefRole): def process_link(self, env, refnode, has_explicit_title, title, target): refnode['bsv:package'] = env.temp_data.get('bsv:package') refnode['bsv:interface'] = env.temp_data.get('bsv:interface') if not has_explicit_title: title = title.lstrip('.') # only has a meaning for the target target = target.lstrip('~') # only has a meaning for the title # if the first character is a tilde, don't display the package/interface # parts of the contents if title[0:1] == '~': title = title[1:] dot = title.rfind('.') if dot != -1: title = title[dot+1:] # if the first character is a dot, search more specific namespaces first # else search builtins first if target[0:1] == '.': target = target[1:] refnode['refspecific'] = True return title, target class BsvPackageIndex(Index): """ Index subinterface to provide the Bsv package index. """ name = 'pkgindex' localname = l_('Bsv Package Index') shortname = l_('bsvpkgs') def generate(self, docnames=None): content = {} # list of prefixes to ignore ignores = self.domain.env.config['pkgindex_common_prefix'] ignores = sorted(ignores, key=len, reverse=True) # list of all packages, sorted by package name packages = sorted(self.domain.data['packages'].items(), key=lambda x: x[0].lower()) # sort out collapsable packages prev_modname = '' num_toplevels = 0 for modname, (docname, synopsis, platforms, deprecated) in packages: if docnames and docname not in docnames: continue for ignore in ignores: if modname.startswith(ignore): modname = modname[len(ignore):] stripped = ignore break else: stripped = '' # we stripped the whole package name? if not modname: modname, stripped = stripped, '' entries = content.setdefault(modname[0].lower(), []) package = modname.split('.')[0] if package != modname: # it's a subpackage if prev_modname == package: # first subpackage - make parent a group head if entries: entries[-1][1] = 1 elif not prev_modname.startswith(package): # subpackage without parent in list, add dummy entry entries.append([stripped + package, 1, '', '', '', '', '']) subtype = 2 else: num_toplevels += 1 subtype = 0 qualifier = deprecated and _('Deprecated') or '' entries.append([stripped + modname, subtype, docname, 'package-' + stripped + modname, platforms, qualifier, synopsis]) prev_modname = modname # apply heuristics when to collapse pkgindex at page load: # only collapse if number of toplevel packages is larger than # number of subpackages collapse = len(packages) - num_toplevels < num_toplevels # sort by first letter content = sorted(content.items()) return content, collapse class BsvModuleIndex(Index): """ Index subinterface to provide the Bsv module index. """ name = 'bsvmodules' localname = l_('Bsv Module Index') shortname = l_('bsvmodules') def generate(self, docnames=None): content = {} # list of prefixes to ignore ignores = self.domain.env.config['pkgindex_common_prefix'] ignores = sorted(ignores, key=len, reverse=True) # list of all packages, sorted by package name modules = sorted(self.domain.data['modules'].items(), key=lambda x: x[0].lower()) # sort out collapsable modules prev_modname = '' num_toplevels = 0 for modname, (docname, synopsis, platforms, deprecated) in modules: if docnames and docname not in docnames: continue for ignore in ignores: if modname.startswith(ignore): modname = modname[len(ignore):] stripped = ignore break else: stripped = '' # we stripped the whole module name? if not modname: modname, stripped = stripped, '' entries = content.setdefault(modname[0].lower(), []) module = modname.split('.')[0] if module != modname: # it's a submodule if prev_modname == module: # first submodule - make parent a group head if entries: entries[-1][1] = 1 elif not prev_modname.startswith(module): # submodule without parent in list, add dummy entry entries.append([stripped + module, 1, '', '', '', '', '']) subtype = 2 else: num_toplevels += 1 subtype = 0 qualifier = deprecated and _('Deprecated') or '' entries.append([stripped + modname, subtype, docname, 'module-' + stripped + modname, platforms, qualifier, synopsis]) prev_modname = modname # apply heuristics when to collapse pkgindex at page load: # only collapse if number of toplevel modules is larger than # number of submodules collapse = len(modules) - num_toplevels < num_toplevels # sort by first letter content = sorted(content.items()) return content, collapse class BsvDomain(Domain): """Bsv language domain.""" name = 'bsv' label = 'Bsv' object_types = { 'function': ObjType(l_('function'), 'func', 'obj'), 'data': ObjType(l_('data'), 'data', 'obj'), 'interface': ObjType(l_('interface'), 'interface', 'exc', 'obj'), 'instance': ObjType(l_('instance'), 'instance', 'obj'), 'exception': ObjType(l_('exception'), 'exc', 'interface', 'obj'), 'method': ObjType(l_('method'), 'meth', 'obj'), 'subinterface': ObjType(l_('subinterface'), 'ifc', 'obj'), 'field': ObjType(l_('field'), 'fld', 'obj'), 'interfacemethod': ObjType(l_('interface method'), 'meth', 'obj'), 'staticmethod': ObjType(l_('static method'), 'meth', 'obj'), 'package': ObjType(l_('package'), 'pkg', 'obj'), 'module': ObjType(l_('module'), 'mod', 'obj'), 'struct': ObjType(l_('struct'), 'struct', 'obj'), 'typedef': ObjType(l_('typedef'), 'mod', 'obj'), 'typeclass': ObjType(l_('typeclass'), 'typeclass', 'obj'), } directives = { 'function': BsvPackagelevel, 'data': BsvPackagelevel, 'module': BsvPackagelevel, 'typedef': BsvPackagelevel, 'interface': BsvInterfacelike, 'typeclass': BsvInterfacelike, 'instance': BsvInterfacelike, 'struct': BsvInterfacelike, 'method': BsvInterfacemember, 'interfacemethod': BsvInterfacemember, 'staticmethod': BsvInterfacemember, 'subinterface': BsvInterfacemember, 'field': BsvInterfacemember, 'package': BsvPackage, 'currentpackage': BsvCurrentPackage, 'decorator': BsvDecoratorFunction, 'decoratormethod': BsvDecoratorMethod, } roles = { 'data': BsvXRefRole(), 'exc': BsvXRefRole(), 'func': BsvXRefRole(fix_parens=True), 'interface': BsvXRefRole(), 'const': BsvXRefRole(), 'attr': BsvXRefRole(), 'meth': BsvXRefRole(fix_parens=True), 'mod': BsvXRefRole(), 'pkg': BsvXRefRole(), 'obj': BsvXRefRole(), } initial_data = { 'objects': {}, # fullname -> docname, objtype 'packages': {}, # modname -> docname, synopsis, platform, deprecated 'modules': {}, # modname -> docname, synopsis, platform, deprecated 'labels': { # labelname -> docname, labelid, sectionname 'pkgindex': ('bsv-pkgindex', '', l_('Package Index')), }, 'anonlabels': { # labelname -> docname, labelid 'pkgindex': ('bsv-pkgindex', ''), }, } indices = [ BsvPackageIndex, BsvModuleIndex ] def clear_doc(self, docname): for fullname, (fn, _) in self.data['objects'].items(): if fn == docname: del self.data['objects'][fullname] for modname, (fn, _, _, _) in self.data['packages'].items(): if fn == docname: del self.data['packages'][modname] def find_obj(self, env, modname, interfacename, name, type, searchmode=0): """Find a Bsv object for "name", perhaps using the given package and/or interfacename. Returns a list of (name, object entry) tuples. """ # skip parens if name[-2:] == '()': name = name[:-2] if not name: return [] objects = self.data['objects'] matches = [] newname = None if searchmode == 1: objtypes = self.objtypes_for_role(type) if objtypes is not None: if modname and interfacename: fullname = modname + '::' + interfacename + '.' + name if fullname in objects and objects[fullname][1] in objtypes: newname = fullname if not newname: if modname and modname + '::' + name in objects and \ objects[modname + '::' + name][1] in objtypes: newname = modname + '::' + name elif name in objects and objects[name][1] in objtypes: newname = name else: # "fuzzy" searching mode searchname = '.' + name matches = [(oname, objects[oname]) for oname in objects if oname.endswith(searchname) and objects[oname][1] in objtypes] else: # NOTE: searching for exact match, object type is not considered if name in objects: newname = name elif type == 'mod': # only exact matches allowed for packages return [] elif interfacename and interfacename + '.' + name in objects: newname = interfacename + '.' + name elif modname and modname + '::' + name in objects: newname = modname + '::' + name elif modname and interfacename and \ modname + '::' + interfacename + '.' + name in objects: newname = modname + '::' + interfacename + '.' + name # special case: builtin exceptions have package "exceptions" set elif type == 'exc' and '.' not in name and \ 'exceptions.' + name in objects: newname = 'exceptions.' + name # special case: object methods elif type in ('func', 'meth') and '.' not in name and \ 'object.' + name in objects: newname = 'object.' + name if newname is not None: matches.append((newname, objects[newname])) return matches def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode): modname = node.get('bsv:package') clsname = node.get('bsv:interface') searchmode = node.hasattr('refspecific') and 1 or 0 matches = self.find_obj(env, modname, clsname, target, type, searchmode) if not matches: return None elif len(matches) > 1: env.warn_node( 'more than one target found for cross-reference ' '%r: %s' % (target, ', '.join(match[0] for match in matches)), node) name, obj = matches[0] if obj[1] == 'package': # get additional info for packages docname, synopsis, platform, deprecated = self.data['packages'][name] assert docname == obj[0] title = name if synopsis: title += ': ' + synopsis if deprecated: title += _(' (deprecated)') if platform: title += ' (' + platform + ')' return make_refnode(builder, fromdocname, docname, 'package-' + name, contnode, title) else: return make_refnode(builder, fromdocname, obj[0], name, contnode, name) def get_objects(self): for modname, info in self.data['packages'].items(): yield (modname, modname, 'package', info[0], 'package-' + modname, 0) for refname, (docname, type) in self.data['objects'].items(): if type != 'package': # packages are already handled yield (refname, refname, type, docname, refname, 1) def setup(app): print('sphinxbsv setup') app.add_config_value('bsv_include_bsvs', False, False) app.add_config_value('add_package_names', True, True) app.add_config_value('pkgindex_common_prefix', [], 'html') app.add_domain(BsvDomain) ================================================ FILE: doc/library/source/c/c.rst ================================================ Connectal C/C++ Libraries ========================= .. toctree:: :maxdepth: 2 :numbered: portal.rst ================================================ FILE: doc/library/source/c/portal.rst ================================================ C/C++ Portal ============ Connecting to Bluesim --------------------- .. envvar:: BLUESIM_SOCKET_NAME Controls the name of the socket used for connecting software and hardware simulated by bluesim. Connecting to Xsim and Verilator -------------------------------- .. envvar:: SOFTWARE_SOCKET_NAME Controls the name of the socket used for connecting software and hardware simulated by xsim/verilator. Automatically Programming the FPGA ---------------------------------- Connectal application executables or shared objects contain the FPGA bitstream in the "fpgadata" section of the ELF file. When the application (or library) first tries to access the hardware, the Connectal library automatically programs the FGPA with the associated bitstream, unless :c:data:`noprogram` is set to a non-zero value or environment variable :envvar:`NOPROGRAM` is nonzero. In the case of simulation hardware, the simulator is launched when the application first tries to access the hardware. This behavior is also suppressed by a nonzero value for either :c:data:`noprogram` or :envvar:`NOPROGRAM`. .. c:var:: int noprogram If :c:data:`noprogram` is set to a non-zero value, then the FPGA is not programmed automatically. Tracing Simulation ------------------ .. envvar:: DUMP_VCD If set, directs the simulator to dump a VCD trace to the $DUMP_VCD. .. c:var:: int simulator_dump_vcd The application can enable VCD tracing by setting :c:data:`simulator_dump_vcd` to 1. It takes the file name from :c:data:`simulator_vcd_name`. DUMP_VCD overrides this variable. .. c:var:: const char *simulator_vcd_name; Specifies the name of the vcd file. Defaults to "dump.vcd". DUMP_VCD overrides this variable. Zynq Clock Control ------------------ .. c:function:: void setClockFrequency(int clkNum, long requestedFrequency, long *actualFrequency) Changes the frequency of Zynq FPGA Clock clkNum to the closest frequency to requestedFrequency available from the PLL. If the actualFrequency pointer is non-null, stores the actual freqency before returning. Portal Memory ------------- .. c:function:: int portalAlloc(size_t size, int cached) Uses portalmem to allocate a region of size bytes. On platforms that support non-cache-coherent I/O (e.g., zedboard), cached=0 indicates that the programmable logic will use a port to memory that is not snooped by the CPU's caches. In this case, it is up to the allocation to flush or invalidate the CPU cache as needed, using portalCacheFlush(). Returns the file descriptor associated with the memory region. .. c:function:: void *portalMmap(int fd, size_t size) Memory maps size bytes of the portal memory region indicated by fd. Returns a pointer to memory on success or -1 on failure. .. c:function:: portalCacheFlush(int fd, void *__p, long size, int flush) PortalPoller ============ .. cpp:class:: PortalPoller Polls portals .. cpp:member:: PortalPoller::PortalPoller(int autostart = 1) If autostart is 1, then invoke :cpp:member:`start()` from :cpp:member:`registerInstance()` .. cpp:member:: void PortalPoller::start(); Starts the poller. Called automatically from :cpp:member:`registerInstance()` if :cpp:member:`autostart` is 1. .. cpp:member:: void PortalPoller::stop(); Stops the poller. .. cpp:member:: int PortalPoller::timeout The timeout value, in milliseconds, passed to :c:function:`poll()` :envvar:`PORTAL_TIMEOUT`. Overrides the default value for :cpp:member:`PortalPoller::timeout`. Deprecated Functions -------------------- .. c:function:: void *portalExec(void *__x) Polls the registered portals and invokes their callback handlers. .. c:function:: void portalExec_start() .. c:function:: void portalExec_poll() ================================================ FILE: doc/library/source/conf.py ================================================ # -*- coding: utf-8 -*- # # connectal documentation build configuration file, created by # sphinx-quickstart on Tue Nov 25 12:27:26 2014. # # 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. import sys import os # 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('.')) sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath('../../../scripts')) # -- 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.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinxcontrib.makedomain', 'sphinxarg.ext', 'bsvsphinx' ] # 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'connectal' copyright = u'2015-2020, Jamey Hicks, Myron King, John Ankcorn' googleanalytics_id = 'UA-15845210-2' googleanalytics_enabled = True # 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 = '22.05.23b' # The full version, including alpha/beta/rc tags. release = '22.05.23b' # 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 = [] # 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 = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False autosummary_generate = True autoclass_content = 'both' autodoc_default_flags = ['members', 'undoc-members', 'show-inheritance'] # -- 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 = 'connectal' # 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 = ['themes'] # 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'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # 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 = 'connectaldoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'connectal.tex', u'connectal Documentation', u'Jamey Hicks, Myron King, John Ankcorn', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # 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 # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'connectal', u'connectal Documentation', [u'Jamey Hicks, Myron King, John Ankcorn'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'connectal', u'connectal Documentation', u'Jamey Hicks, Myron King, John Ankcorn', 'connectal', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False ================================================ FILE: doc/library/source/design/Makefile ================================================ all: make -C images all ================================================ FILE: doc/library/source/design/abstract.rst ================================================ Abstract ******** The cost and complexity of hardware-centric systems can often be reduced by using software to perform tasks which don't appear on the critical path. Alternately, the performance of software can sometimes be improved by using special purpose hardware to implement tasks which *do* appear on the critical path. Whatever the motivation, most modern systems are composed of both hardware and software components. Given the importance of the connection between hardware and software in these systems, it is surprising how little automated and machine-checkable support there is for co-design space exploration. This paper presents the Connectal framework, which enables the development of hardware accelerators for software applications by generating hardware/software interface implementations from abstract Interface Design Language (IDL) specifications. `Connectal`_ generates stubs to support asynchronous remote method invocation from software to software, hardware to software, software to hardware, and hardware to hardware. For high-bandwidth communication, the Connectal framework provides comprehensive support for shared memory between hardware and software components, removing the repetitive work of processor bus interfacing from project tasks. This framework is released as open software under an MIT license, making it available for use in any projects. .. _Connectal: http://www.connectal.org/ ================================================ FILE: doc/library/source/design/bs-related-papers.bib ================================================ % ---------------------------------------------------- % Bluespec References % ---------------------------------------------------- % -------------- % PHD Theses % -------------- @PHDTHESIS{Hoe:Thesis, AUTHOR = "James C. Hoe", TITLE = {{Operation-Centric Hardware Description and Synthesis}}, SCHOOL = "MIT", YEAR = {2000}, ADDRESS = {Cambridge,~MA} } @PHDTHESIS{Shen:Thesis, AUTHOR = "Xiaowei Shen", TITLE = {{Design and Verification of Adaptive Cache Coherence Protocols}}, SCHOOL = "MIT", YEAR = {2000}, ADDRESS = {Cambridge,~MA} } @PHDTHESIS{Rosenband:Thesis, AUTHOR = "Daniel L. Rosenband", TITLE = {{A Performance Driven Approach for Hardware Synthesis of Guarded Atomic Actions}}, SCHOOL = "MIT", YEAR = {2005}, ADDRESS = {Cambridge,~MA} } % -------------- % Masters Theses % -------------- @MASTERSTHESIS{Lis:Thesis, AUTHOR = "Mieszko Lis", TITLE = {{Superscalar Processors via Automatic Microarchitecture Transformations}}, SCHOOL = "MIT", MONTH = {May}, YEAR = 2000, ADDRESS = {Cambridge,~MA} } @MASTERSTHESIS{Dave:MSThesis, AUTHOR = "Nirav Dave", TITLE = {{Designing a Processor in Bluespec }}, SCHOOL = "MIT", MONTH = {Jan}, YEAR = 2005, ADDRESS = {Cambridge,~MA} } @MASTERSTHESIS{Dave:MSThesisPutGet, AUTHOR = "Nirav Dave", TITLE = {{Designing a Processor in Bluespec }}, SCHOOL = "MIT", MONTH = {Jan}, YEAR = 2005, pages = {23}, ADDRESS = {Cambridge,~MA} } @MASTERSTHESIS{ChunChieh:MSThesis, AUTHOR = "Chun-Chieh Lin", TITLE = {{ Implementation of H.264 Decoder in Bluespec System Verilog}}, SCHOOL = "MIT", MONTH = {Feb}, YEAR = 2007, ADDRESS = {Cambridge,~MA} } % -------------- % Conference Papers % -------------- @inproceedings{DBLP:conf/iccad/KarczmarekA08, author = {Michal Karczmarek and Arvind}, title = {Synthesis from multi-cycle atomic actions as a solution to the timing closure problem}, booktitle = {ICCAD}, year = {2008}, ee = {http://doi.acm.org/10.1145/1509456.1509475}, bibsource = {DBLP, http://dblp.uni-trier.de} } @article{ArvindNikhil:ExecutingProgram, author = {Arvind and Rishiyur S. Nikhil}, title = {Executing a Program on the MIT Tagged-Token Dataflow Architecture}, journal = {IEEE Trans. Comput.}, volume = {39}, number = {3}, year = {1990}, issn = {0018-9340}, pages = {300--318}, doi = {http://dx.doi.org/10.1109/12.48862}, publisher = {IEEE Computer Society}, address = {Washington, DC, USA}, } @article{HCAA:MonsoonPerformance, author = "James Hicks and Derek Chiou and Boon Seong Ang and Arvind", title = "Performance Studies of {Id} on the {Monsoon Dataflow System}", journal = "Journal of Parallel and Distributed Computing", volume = "18", number = "3", pages = "273--300", year = "1993", url = "citeseer.ist.psu.edu/hicks94performance.html" } @INPROCEEDINGS{HoeArvind:TRS_Synthesis1, AUTHOR = "James C. Hoe and Arvind", TITLE = {{Synthesis of Operation-Centric Hardware Descriptions}}, BOOKTITLE = {{Proceedings of ICCAD'00}}, PAGES = {511--518}, YEAR = {2000}, ADDRESS = {San Jose,~CA} } @INPROCEEDINGS{Dave:ROB, AUTHOR = "Nirav Dave", TITLE = {{Designing a Reorder Buffer in Bluespec}}, BOOKTITLE = "Proceedings of MEMOCODE'04", YEAR = {2004}, ADDRESS = {San Diego,~CA} } @INPROCEEDINGS{ArvindNikhilRosenbandDave:HighLevelSynthesis, AUTHOR = "Arvind and Rishiyur S. Nikhil and Daniel L. Rosenband and Nirav Dave", TITLE = {{High-level Synthesis: An Essential Ingredient for Designing Complex ASICs}}, BOOKTITLE = "Proceedings of ICCAD'04", YEAR = {2004}, ADDRESS = {San Jose,~CA} } @INPROCEEDINGS{ANRD:HighLevelSynthesis, AUTHOR = "Arvind and Rishiyur S. Nikhil and Daniel L. Rosenband and Nirav Dave", TITLE = {{High-level Synthesis: An Essential Ingredient for Designing Complex ASICs}}, BOOKTITLE = "Proceedings of ICCAD'04", YEAR = {2004}, ADDRESS = {San Jose,~CA} } @INPROCEEDINGS{RosenbandArvind:ModularScheduling, AUTHOR = "Daniel L. Rosenband and Arvind", TITLE = {{Modular Scheduling of Guarded Atomic Actions}}, BOOKTITLE = "Proceedings of DAC'04", YEAR = 2004, ADDRESS = {San Diego,~CA} } @INPROCEEDINGS{Rosenband:PerformanceGuarantees, AUTHOR = "Daniel L. Rosenband and Arvind", TITLE = {{Hardware Synthesis from Guarded Atomic Actions with Performance Specifications}}, BOOKTITLE = "Proceedings of ICCAD'05", YEAR = 2005, ADDRESS = {San Jose,~CA} } @INPROCEEDINGS{Rosenband:EHR, AUTHOR = "Daniel L. Rosenband", TITLE = {{The Ephemeral History Register: Flexible Scheduling for Rule-Based Designs}}, BOOKTITLE = "Proceedings of MEMOCODE'04", YEAR = {2004}, ADDRESS = {San Diego,~CA} } @INPROCEEDINGS{StoyShenArvind:Proofs, AUTHOR = "Joseph E. Stoy and Xiaowei Shen and Arvind", TITLE = {{Proofs of Correctness of Cache-Coherence Protocols}}, BOOKTITLE = {{Proceedings of FME'01: Formal Methods for Increasing Software Productivity}}, YEAR = {2001}, PAGES = {47--71}, PUBLISHER = {Springer-Verlag}, ADDRESS = {London,~UK} } @inproceedings{Bluespec:MCD, author = {Ed Czeck and Ravi Nanavati and Joe Stoy}, title = {{Reliable Design with Multiple Clock Domains}}, booktitle = {Proceedings of Formal Methods and Models for Codesign (MEMOCODE)}, year = {2006} } @InProceedings{DPGA:80211, author = {Nirav Dave and Michael Pellauer and Steve Gerding and Arvind}, title = {{802.11a Transmitter: A Case Study in Microarchitectural Exploration}}, booktitle = {Proceedings of Formal Methods and Models for Codesign (MEMOCODE)}, year = {2006}, ADDRESS = {Napa,~CA} } @INPROCEEDINGS{DAP:CompositionScheduling, AUTHOR = "Nirav Dave and Arvind and Michael Pellauer", TITLE = {{Scheduling as Rule Composition}}, BOOKTITLE = "Proceedings of Formal Methods and Models for Codesign (MEMOCODE)", YEAR = {2007}, ADDRESS = {Nice,~France} } @INPROCEEDINGS{Ng:OFDM, AUTHOR = "Man Cheuk Ng and Muralidaran Vijayaraghavan and Gopal Raghavan and Nirav Dave and Jamey Hicks and Arvind", TITLE = {{From WiFI to WiMAX: Techniques for IP Reuse Across Different OFDM Protocols}}, BOOKTITLE = "Proceedings of Formal Methods and Models for Codesign (MEMOCODE)", YEAR = {2007}, ADDRESS = {Nice,~France} } @INPROCEEDINGS{MEMOCODE2011, AUTHOR = "Nirav Dave and Michael Katelman and Myron King and Jose Meseguer and Arvind", TITLE = {{Verification of Microarchitectural Refinements in Rule-based systems}}, BOOKTITLE = "MEMOCODE", YEAR = {2011}, ADDRESS = {Cambridge,~UK} } @INPROCEEDINGS{Bluespec:H264, AUTHOR = "Kermin Fleming and Chun-Chieh Lin and Nirav Dave and Gopal Raghavan and Jamey Hicks and Arvind", TITLE = {{H.264 Decoder: A Case Study in Multiple Design Points}}, BOOKTITLE = "Proceedings of Formal Methods and Models for Codesign (MEMOCODE)", YEAR = {2008}, ADDRESS = {Anaheim,~CA} } @INPROCEEDINGS{NordinHoe:SynchronousExtensions, AUTHOR = "Grace Nordin and James C. Hoe", TITLE = {{Synchronous Extensions to Operation-Centric Hardware Description Languages}}, BOOKTITLE = "Proceedings of MEMOCODE'04", YEAR = 2004, ADDRESS = {San Diego,~CA} } @inproceedings{Shen:CRF, author = {Xiaowei Shen and Arvind and Larry Rudolph}, title = {Commit-reconcile \& fences (CRF): a new memory model for architects and compiler writers}, booktitle = {Proceedings of the 26th annual international symposium on Computer architecture}, year = {1999}, isbn = {0-7695-0170-2}, pages = {150--161}, location = {Atlanta, Georgia, United States}, doi = {http://doi.acm.org/10.1145/300979.300992}, publisher = {IEEE Computer Society}, } @inproceedings{Fleming:FPGA, author = {K. Fleming and M. Adler and M. Pellauer and A. Parashar and Arvind and J. Emer}, title = {Leveraging Latency-Insensitivity to Ease Multiple FPGA Design}, booktitle = {FPGA}, month = {February}, year = {2011} } @inproceedings{DBLP:conf/memocode/VijayaraghavanA09, author = {Muralidaran Vijayaraghavan and Arvind}, title = {Bounded Dataflow Networks and Latency-Insensitive circuits}, booktitle = {MEMOCODE}, year = {2009}, pages = {171-180}, ee = {http://dx.doi.org/10.1109/MEMCOD.2009.5185393}, bibsource = {DBLP, http://dblp.uni-trier.de} } % -------------- % Journal Articles % -------------- @ARTICLE{HoeArvind:TRS_Synthesis2, AUTHOR = "James C. Hoe and Arvind", TITLE = {{Operation-Centric Hardware Description and Synthesis}}, JOURNAL = {{IEEE TRANSACTIONS on Computer-Aided Design of Integrated Circuits and Systems}}, VOLUME = {23}, NUMBER = {9}, MONTH = {September}, YEAR = {2004} } @ARTICLE{ArvindShen:TRS_Processors, AUTHOR = "Arvind and Xiaowei Shen", TITLE = {{Using Term Rewriting Systems to Design and Verify Processors}}, JOURNAL = {{IEEE Micro}}, VOLUME = {19}, NUMBER = {3}, PAGES = {36--46}, MONTH = May, YEAR = {1999} } % -------------- % Patents % -------------- @MISC{ArvindHoe:Patent, AUTHOR = "Arvind and James C. Hoe", TITLE = {{Digital Circuit Synthesis System}}, MONTH = {July}, HOWPUBLISHED = {{United States Patent US 6,597,664 B1}}, YEAR = {2003} } @MISC{Esposito:Patent, AUTHOR = {Thomas Esposito and Mieszko Lis and Ravi Nanavati and Joseph Stoy and Jacob Schwartz}, TITLE = {System and Method for Scheduling {TRS} Rules}, MONTH = {February}, HOWPUBLISHED = {{United States Patent US 133051-0001}}, YEAR = {2005} } % ------------- % Other % ------------- @misc{BSV:LangRef, title = "{Bluespec Language definition}", author = "Lennart Augustsson and Jacob Schwarz and Rishiyur S. Nikhil", year = 2001, pages = "95", note = {{Sandburst Corp.}} } @MISC{Interra:QoR, AUTHOR = {{Interra Systems}}, TITLE = {{Bluespec Testing Results: Comparing RTL Tool Output to Hand-designed RTL}}, HOWPUBLISHED = {{\texttt{http://www.bluespec.com/images/pdfs/InterraReport042604.pdf}}}, MONTH = {April}, YEAR = {2004} } @MISC{Bluespec:www, AUTHOR = {{Bluespec Inc.}}, HOWPUBLISHED = {{\texttt{http://www.bluespec.com}}}, } @MANUAL{Bluespec:TFRG, TITLE = "Bluespec SystemVerilog Version~3.8 Reference Guide", ORGANIZATION = "Bluespec,~Inc.", ADDRESS = {Waltham,~MA}, MONTH = "November", YEAR = {2004} } @MANUAL{Bluespec:UG, TITLE = "Bluespec SystemVerilog User Guide", ORGANIZATION = "Bluespec,~Inc.", ADDRESS = {Waltham,~MA}, MONTH = "November", YEAR = {2004} } @UNPUBLISHED{EckerEsenSteiniLis:BSV_Eval, AUTHOR = {Volkan Esen and Thomas Steininger and Wolfgang Ecker and Mieszko Lis}, TITLE = {{A Case Study in Rule-based Synthesis for IP Reuse}}, NOTE = {Unpublished}, MONTH = {November}, YEAR = {2004} } % ---------------------------------------------------- % Other Useful References % ---------------------------------------------------- @INPROCEEDINGS{Haskell:STM, AUTHOR = {Tim Harris and Simon Marlow and Simon Peyton-Jones and Maurice Herlihy}, TITLE = {Composable Memory Transactions}, BOOKTITLE = {PPoPP '05: Proceedings of the tenth ACM SIGPLAN symposium on Principles and practice of parallel programming}, YEAR = {2005} } @article{Dijkstra:GuardedCommands, author = {Edsger W. Dijkstra}, title = {Guarded commands, nondeterminacy and formal derivation of programs}, journal = {Commun. ACM}, volume = {18}, number = {8}, year = {1975}, issn = {0001-0782}, doi = {http://doi.acm.org/10.1145/360933.360975}, publisher = {ACM Press}, address = {New York, NY, USA}, } @book{ChandyMisra:Book, AUTHOR = "Chandy, K. Mani and Jayadev Misra", TITLE = "Parallel Program Design: A Foundation", PUBLISHER = {Addison-Wesley}, ADDRESS = {Reading, Massachusetts}, YEAR = {1988} } @MANUAL{SystemVerilog:LRM, TITLE = "SystemVerilog 3.1a Language Reference Manual", ORGANIZATION = "Accelera Organization,~Inc.", ADDRESS = {Napa,~CA}, MONTH = "May", YEAR = {2004} } @article{Hoare:CSP, author = {C. A. R. Hoare}, title = {Communicating sequential processes}, journal = {Commun. ACM}, volume = {21}, number = {8}, year = {1978}, issn = {0001-0782}, pages = {666--677}, doi = {http://doi.acm.org/10.1145/359576.359585}, publisher = {ACM Press}, address = {New York, NY, USA}, } @INPROCEEDINGS{ SystemC, AUTHOR = "S. Y. Liao", TITLE = "Towards a New Standard for System Level Design", PAGES = "2--7", BOOKTITLE = {{Proceedings of the Eighth International Workshop on Hardware/Software Codesign}}, MONTH={May}, YEAR={2000}, ADDRESS= {San Diego, ~CA} } @article{Maessen:StoreAtomicity, author = {Jan-Willem Maessen and Arvind}, title = {Store Atomicity for Transactional Memory}, journal = {Electr. Notes Theor. Comput. Sci.}, volume = {174}, number = {9}, year = {2007}, pages = {117-137}, ee = {http://dx.doi.org/10.1016/j.entcs.2007.04.009}, bibsource = {DBLP, http://dblp.uni-trier.de} } ================================================ FILE: doc/library/source/design/conclusion.rst ================================================ .. _Sec-Conclusion: Conclusion ========== `Connectal`_ bridges the gap between software and hardware development, enabling developers to create integrated solutions rapidly. With Connectal, we take a pragmatic approach to software and hardware development in which we try to avoid any dependence on proposed solutions to open research problems. Use of Connectal's interface compiler ensures that software and hardware remain consistent and make it easy to update the hardware/software boundary as needed in a variety of execution contexts. The generated portals permit concurrent and low-latency access to the accelerator and enable different processes or the kernel to have safe isolated access through dedicated interfaces. Support for sharing memory between software and hardware makes it easy to achieve high transfer speeds between the two environments. Connectal supports Linux and Android operating systems running on x86 and ARM CPUs. It currently supports Xilinx FPGAs and runs on the full range of Xilinx Series 7 devices. Our fully-scripted development process enables the use of continuous integration of software and hardware development. Integrating software development early makes it easier to ensure that the complete solution actually meets design targets and customer requirements. .. _Connectal: http://www.connectal.org/ ================================================ FILE: doc/library/source/design/connectal-framework.rst ================================================ .. _Sec-Framework: The Connectal Framework ======================= In and of themselves, none of the HW/SW interfaces considered in Section :ref:`Sec-StrStr` are particularly complex. On the other hand, implementing the complete set and maintaining correctness as the application evolves is a considerable amount of care, requiring deep understanding of both the application and the platform. The Connectal framework is a collection of tools and library components which was designed to address these challenges with the following features: * Easy declaration and invocation of remote methods between application components running on the host or in the FPGA. * Direct user-mode access to hardware accelerators from software. * High performance read and write bus master access to system memory from the FPGA * Infrastructure for sharing full speed memory port access between an arbitrary number of clients in the FPGA fabric * Portability across platforms using different CPUs, buses, operating systems, and FPGAs * Fully integrated tool-chain support for dependency builds and device configuration. In this section, we introduce the Connectal framework through a discussion of its prominent features. Portals ------- Connectal implements remote method invocation between application components using asynchronous messaging. The message and channel types are application specific, requiring the user to define the HW/SW interface using BSV interfaces as the interface definition language (IDL). These interfaces declare logical groups of unidirectional ``send'' methods, each of which is implemented as a FIFO channel by the Connectal interface compiler; all channels corresponding to a single BSV interface are grouped together into a single *portal*. From the interface specification, the Connectal interface compiler generates code for marshalling the arguments of a method into a message to be sent and unmarshaling values from a received message. It generates a \textit{proxy} to be invoked on the sending side and a \textit{wrapper} that invokes the appropriate method on the receiving side. Platform specific libraries are used to connect the proxies and wrappers to the communication fabric. In the hardware, each portal is assigned a disjoint address range. On the host, Connectal assigns each portal a unique Linux device (/dev/portal*n*$) which is accessed by the application software using the generated wrappers and proxies. An application can partition methods across several portals, to control access to the interfaces by specific hardware or software modules. To support bi-directional communication, at least two portals are required: one which allows software to ``invoke'' hardware, and another for hardware to ``invoke'' software. Each portal may be accessed by different threads, processes, or directly from the kernel. Direct user-mode access to hardware ----------------------------------- We designed Connectal to provide direct access to accelerators from user-mode programs in order to eliminate the need for device-drivers specific to each accelerator. We have implemented a kernel module for both X86 and ARM architectures with a minimal set of functionality: the driver implements \textbf{mmap} to map hardware registers into user space and \textbf{poll} to enable applications to suspend a thread waiting for interrupts originating from the hardware accelerators. These two pieces of functionality have been defined to be completely generic; no modification is required to kernel drivers as the HW/SW interface evolves. All knowledge of the interface register semantics (and corresponding changes) is encoded by the interface compiler in the generated proxies and wrappers which are compiled as part of the application and executed in user-mode. This approach is known as user-space device drivers~\cite{Khalidi:1995:EZI:974947,UIO:Howto} and has a number of distinct advantages over traditional kernel modules. To begin with, it reduces the number of components that need to be modified if the HW/SW interface changes, and eliminates the need for device-driver development expertise in many cases. Secondly, after the hardware registers have been mapped into user address space, the need for software to switch between user and kernel mode is all but eliminated since all ``driver'' functionality is being executed in user-space. Shared Access to Host Memory ---------------------------- Connectal generates a hardware FIFO corresponding to each method in the portal interface, and the software reads and writes these FIFOs under certain conditions. To improve throughput, Connectal libraries also support credit-based flow-control. Though credit-based flow-control with interrupts is more efficient than polling status registers from software, there is often the need for much higher bandwidth communication between the hardware and software. Hardware accelerators often communicate with the application through direct access to shared memory. An important feature of Connectal is a flexible, high performance API for allocating and sharing such memory, and support for reading and writing this memory from hardware and software. The Connectal framework implements this through the combination of a Linux kernel driver, C++ libraries, and BSV modules for the FPGA. We implemented a custom kernel memory allocator for Connectal, \textbf{portalmem}, using the kernel dmabuf support. Any solution which allocates and shares memory between hardware and software must meet two high-level requirements: * Allocated buffers must have reference counts to prevent memory leaks. * Efficient mechanisms must be provided to share the location of allocated regions. Using the portalmem driver, programs can allocate regions of system memory (DRAM) and map it into their own virtual address space. Reference-counted access to shared memory regions allocated using portalmem can be granted to other SW processes by transmitting the file descriptor for the allocated region. Reference counting has been implemented in the driver so that once an allocated memory region has been dereferenced by all SW and HW processes, it will be deallocated and returned to the kernel free memory pool. Simple hardware accelerators often require contiguous physical addresses. Unfortunately, when allocating memory from a shared pool in a running system, obtaining large areas of contiguous memory is often problematic, limiting the size of the region that can be allocated. To support indexed access to non-contiguous memory aggregates, Connectal provides address translation support to hardware accelerators in the FPGA, similar to the MMU functionality on the CPU side. .. _Sec-MemReadEngine: Distributed Access to Memory Ports ---------------------------------- When building accelerators for an algorithm, multiple parameters are often accessed directly from system memory using DMA. As the hardware implementation is parallelized, multiple accesses to each parameter may be required. In these cases, the number of memory clients in the application hardware usually exceeds the number of host memory ports. Sharing these ports requires substantial effort, and scaling up a memory interconnect while maximizing throughput and clock speed is extremely challenging. To support this common design pattern, the Connectal framework provides provides a portable, scalable, high performance library that applications can use to to facilitate the efficient sharing of host memory ports. This library is implemented as parameterized Bluespec modules which allow the user to easily configure high-performance memory access trees, supporting both reading and writing. Platform Portability -------------------- We structured Connectal to improve the portability of applications across CPU types, operating systems, FPGAs, and how the CPU and FPGA are connected. The software and hardware libraries are largely platform independent. As a result, applications implemented in the framework can be compiled to run on the range of different platforms. Supported platforms are shown in Figure :ref:`Fig-platforms`. Application software can be executed on x86 and ARM CPUs running either Ubuntu or Android operating systems. A range of different Xilinx FPGAs can be connected to the CPU and system memory via PCI Express or AXI. The BSV simulator (Bluesim) can be used in place of actual FPGA hardware for debugging purposes. When the target application needs to interact with other Linux kernel resources (for example, a block device or a network interface), the application may run in kernel mode with the logic run either in an FPGA or in Bluesim. .. image:: images/platforms.* .. _Fig-platforms: Platforms supported by Connectal ================================================ FILE: doc/library/source/design/design.rst ================================================ Connectal Design **************** .. toctree:: :maxdepth: 2 abstract.rst introduction.rst string-search.rst connectal-framework.rst implementing-string-search.rst toolchain.rst performance.rst related-work.rst conclusion.rst portalstructure.rst portal.rst interface_definitions.rst flowcontrol.rst host_interface.rst ================================================ FILE: doc/library/source/design/flowcontrol.rst ================================================ .. _flow_control: Flow Control ============ ================================================ FILE: doc/library/source/design/host_interface.rst ================================================ .. host_interface: Host Interface ============== ================================================ FILE: doc/library/source/design/images/Makefile ================================================ all: images %.png: %.pdf pdftoppm -singlefile -png $(*).pdf $(*) images: \ data_accel_logical0.png \ data_accel_logical1.png \ data_accel_logical2.png \ data_accel_logical3.png \ data_accel_logical4.png \ MemreadEngine.png \ msc0.png \ msc1.png \ msc2.png \ platform.png \ platforms.png ================================================ FILE: doc/library/source/design/implementing-string-search.rst ================================================ .. Sec-Impl: Implementing String Search ========================== Having covered the features of the Connectal at a high level, we now explain more specifically how the framework can be applied to implement the refinements outlined in Section :ref:`Sec-StrStr`. Initial Implementation ---------------------- The FPGA is connected to the host system with a PCIe bus, and to the memory array with wires. In addition to implementing a search kernel, the hardware accelerator must communicate with the software components and with the flash chips. Communication with the software takes place through portals, whose interface declaration is given below:: interface StrstrRequest; method Action setupNeedle(Bit#(8) needleChars); method Action search(Bit#(32) haystackPtr, Bit#(32) haystackLen); endinterface interface StrstrIndication; method Action searchResult(Int#(32) v); method Action setupComplete(); endinterface The hardware implements the StrstrRequest interface, which the software invokes (remotely) to specify the search string and the location in flash memory to search. The software implements the StrstrIndication interface, which the hardware invokes (remotely) to notify the software of configuration completion or search results. The interface compiler generates a separate portal for each of these interfaces. Within each portal, a dedicated unidirectional FIFO is assigned to each logical interface method. In our initial implementation the accelerator does not access system memory directly, so the search string is transmitted to the accelerator one character at a time via the {\tt setupNeedle} method. We will see in Section :ref:Sec-StringSearchSystemMemory` how to use a pointer to system memory instead. Invoking Hardware from Software ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Because the StrStrRequest functionality is implemented in hardware, the Connectal interface compiler generates a C++ \textbf{proxy} with the following interface to be invoked by the application software:: class StrStrRequestProxy : public Portal { public: void setupNeedle(uint32_t needleChars); void search(uint32_t haystackPtr, uint32_t haystackLen); }; The implementation of StrStrRequestProxy marshals the arguments of each method and en-queues them directly into their dedicated hardware FIFOs. To execute searches in the FPGA fabric over data stored in flash memory, the software developer simply instantiates *StrStrRequestProxy* and invokes its methods:: StrStrRequestProxy *proxy = new StrStrRequestProxy(...); proxy->search(haystackPtr, haystackLen); On the FPGA, the user implements the application logic as a BSV module with the StrStrRequest interface. A *wrapper* is generated by the interface compiler to connect this module to the hardware FIFOs. The wrapper unmarshals messages that it receives and then invokes the appropriate method in the StrStrRequest interface. Here is the BSV code that instantiates the generated wrapper and connects it to the user's \texttt{mkStrStr} module:: StrStrRequest strStr <- mkStrStr(...); StrStrRequestWrapper wrapper <- mkStrStrRequestWrapper(strStr); Figure :ref:`Fig-msc1`_ shows how all the pieces of an application implemented using Connectal work together when hardware functionality is invoked remotely from software. Direct access to the memory mapped hardware FIFOs by the generated proxy running in user-mode is key to the efficiency of our implementation strategy. .. only:: html .. image:: images/msc1.* .. only:: latexpdf .. image:: design/images/msc1.png .. _Fig-msc1: .. figure:: images/msc1.png SW invokes HW: *main* and *app HW* are implemented by the user. Invoking Software from Hardware ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invoking software from hardware takes a slightly different form, due primarily to the fact that ``main'' is still owned by software. Since the direction of the remote invocation is reversed, the proxy on this path will be instantiated on the FPGA and the wrapper instantiated on host side. The user implements the StrStrResponse interface in software and connects it to the generated wrapper using C++ subclasses:: class StrStrResponse: public StrStrResponseWrapper { ... void searchResult(int32_t v) {...} } The StrStrResponseWrapper constructor registers a pointer to the object with the event library which keeps track of all instantiated software wrappers. The wrapper implementation unmarshals messages sent through the hardware FIFOs and invokes the appropriate subclass interface method. To activate this path, main simply instantiates the response implementation and invokes the library event handler:: StrStrResponse *response = new StrStrResponse(...); while(1) portalExec_event(); On the invocation side, the interface compiler generates a proxy which the application logic instantiates and invokes directly:: StrStrResponseProxy proxy <- mkStrStrRequestProxy(); StrStrRequest strStr <- mkStrStr(... proxy.ifc ...); Figure :ref:Fig-msc0 shows how all the pieces of an application collaborate when software functionality is being invoked from hardware. .. only:: html .. image:: images/msc0.* .. only:: latexpdf .. image:: images/msc0.png .. _Fig-msc0: .. figure:: images/msc0.png HW invokes SW: `main', `ind::wrapper', and `app HW' are implemented by the user. The simplest software execution environment for the string search accelerator is to have a single thread making requests and waiting for responses as follows:: void search(char *str){ StrStrRequestProxy *req = new StrStrRequestProxy(...); StrStrResponse *resp = new StrStrResponse(...); while (char c = *str++) req->setupNeedle(c); // start search req->search(...); // handle responses from the HW while(1) portalExec_event(); } The call to :c:func:portalExec_event() checks for a response from HW. If there is a pending response, it invokes the method corresponding to that FIFO in the wrapper class. This generated method reads out a complete message from the FIFO and unmarshals it before invoking the user-defined call-back function, which in this case would be \texttt{StrStrResponse::searchResult}. Connecting To Flash ^^^^^^^^^^^^^^^^^^^ On BlueDBM, one of our target platforms, the flash memory array is connected directly to the FPGA chip, and DDR signals are used to read/write/erase flash memory cells. The RTL required to communicate with the memory requires some commonly used functionality, such as *SerDes* and DDR controllers, both of which are included in the BSV libraries distributed as part of the Connectal framework. Multithreading The Software --------------------------- In many cases, we would like to avoid a hardware-to-software path which requires the software to poll a hardware register on the other side of a bus for relatively infrequent events. To accommodate this, the Connectal framework generates interrupts which are raised when hardware invokes software interface methods. The generic Connectal driver connects these signals to the Linux kernel and the software wrappers can exploit then by calling poll. Connectal applications often use a separate thread to execute hardware-to-software asynchronous invocations, since dedicated thread can put itself to sleep until the hardware raises an interrupt. The ``main'' thread is free to do other work and can communicate with the ``indication'' thread using a semaphore as shown below:: class StrStrResponse: public StrStrResponseWrapper { sem_t sem; int v; void searchResult(int32_t v) { this->response = v; sem_post(&sem); } void waitResponse(){sem_wait(&sem);} }; StrStrResponse *resp; StrStrRequestProxy *req; int search(char *str){ while (char c = *str++) req->setupNeedle(c); // start search req->search(...); // wait for response resp->waitResponse(); // return result return resp->v; } The polling thread is started by a call to :c:func:portalExec_start(), which ultimately invokes the :c:func:portalExec_poll() function implemented in the Connectal event library. :c:func:portalExec_poll() invokes the system call \textbf{poll} on the FDs corresponding to all the indication or response portals, putting itself to sleep. When an interface method is invoked in the hardware proxy, an interrupt is raised, waking the indication thread. A register is read which indicates which method is being called and the corresponding wrapper method is invoked to read/marshal the arguments and invoke the actual user-defined methods. Figure :ref:`Fig-msc2` shows this process. .. only:: html .. image:: images/msc2.* .. only:: latexpdf .. image:: images/msc2.png .. _Fig-msc2: .. figure:: HW invokes SW using interrupts Multithreading often leads to simultaneous access to shared hardware resources. If a software solution to protect these resources (such as mutex) is not available, the hardware interface can be refactored into separate portals, one for each control thread. Each interface will generate a separate Portal which is assigned its own address space and Linux device. Using Linux devices in this way enables access control restrictions to be specified individually for each portal. This feature can be used to grant different users or processes exclusive access and prevent unauthorized access to specific pieces of hardware functionality. .. Sec-StringSearchSystemMemory: Shared Access to Host Memory ---------------------------- In the first three refinements presented in Section :ref:`Sec-StrStr`, all communication between hardware and software takes place through register-mapped IO. The final refinement in Section :ref:`Sec-StrStrDma` is to grant hardware and software shared access to host memory. The interface to the search accelerator shown below has been updated to use direct access to system memory for the search strings:: interface StrstrRequest; method Action setup(Bit#(32) needlePtr, Bit#(32) mpNextPtr, Bit#(32) needleLen); method Action search(Bit#(32) haystackPtr, Bit#(32) haystackLen, Bit#(32) iterCount); endinterface interface StrstrIndication; method Action searchResult(Int#(32) v); method Action setupComplete(); endinterface In order to share memory with hardware accelerators, it needs to be allocated using :c:func:portalAlloc(). Here is the search function updated accordingly:: int search(char *str){ int size = strlen(str)+1; int fd = portalAlloc(size, 0); char *sharedStr = portalMmap(fd, size); strcpy(sharedStr, str); // send a DMA reference to the search pattern req->needle(dma->reference(fd), size); // start search req->search(...); resp->waitResponse(); ... unmap and free the string return resp->v; } The application allocates shared memory via {\tt portalAlloc}, which returns a file descriptor, and then passes that file descriptor to {\tt mmap}, which maps the physical pages into the application's address space. The file descriptor corresponds to a dmabuf\cite{dmabuf}, which is a standard Linux kernel mechanism. To share that memory with the accelerator, the application calls {\tt reference}, which sends a logical to physical address mapping to the hardware's address translator. The call to {\tt reference} returns a handle, which the application sends to the accelerator. Connectal's BSV libraries for DMA enable the accelerator to read or write from offsets to these handles, taking care of address translation transparently. To fully exploit the data parallelism, {\tt mkStrStr} partitions the search space into $p$ partitions. It instantiates two memory read trees from the Connectal library ({\tt MemReadEngineV}, discussed in Section :ref:`Sec-MemReadEngine`, each with $p$ read servers. One set is used by the search kernels to read the configuration data from the host memory, while the other is used to read the ``haystack'' from flash. On supported platforms such as Zynq which provide multiple physical master connections to system memory, Connectal interleaves DMA requests over the parallel links. It does this on a per-read-client basis, rather than a per-request basis. Alternate Portal Implementations -------------------------------- Connectal separates the generation of code for marshalling and unmarshaling method arguments from the transport mechanism used to transmit the messages. This separation enables ``swappable'' application-specific transport libraries. In light of this, a large number of transport mechanism can be considered. Switching between mechanism requires a simple directive in the project Makefile (more details are given in Section :ref:`Sec-ToolChain`). By default, each portal is mapped to a region of address space and a memory-mapped FIFO channel is generated for each method. Though software access to all FIFO channels in a design may occur through single bus slave interface, Connectal libraries implement their multiplexing to ensure that each FIFO is independent, allowing concurrent access to different methods from multiple threads or processes. The default portal library implements the method FIFOs in the hardware accelerator. This provides the lowest latency path between hardware and software, taking about 1 microsecond to send a message. If higher bandwidth or transaction rates are needed, FIFOs implemented as a ring buffer in DRAM can be used instead. This requires more instructions per message send and receive, but may achieve higher throughput between the CPU and hardware. During the design exploration process, a component originally implemented on the FPGA may migrate to software running on the host processor. Remote invocations which were originally from software to hardware must be recast as software to software. Without changing the IDL specification, the transport mechanism assigned to a portal can be re-specified to implement communication between software components running either on the same host or across a network. Connectal uses UNIX sockets or shared memory to transport messages between the application software components or the hardware simulator. In other situations, TCP or UDP can be used to transport the messages to hardware running on another machine. Viable connections to the FPGA board range from low-speed interconnects such as JTAG, SPI, to higher-speed interconnects such as USB or Aurora over multi-gigabit per second transceivers. ================================================ FILE: doc/library/source/design/interface_definitions.rst ================================================ .. _interface_definitions: Interface Declarations ====================== ================================================ FILE: doc/library/source/design/introduction.rst ================================================ .. Sec-Introduction: Introduction ************ Because they are so small and inexpensive, processors are now included in all but the smallest hardware designs. This grants flexibility to hardware designers because the non-performance-critical components can be implemented in software and the performance-critical components can be implemented in hardware. Using software for parts of the design can decrease the effort required to implement configuration and orchestration logic (for example). It can also offer hardware developers greater adaptability in meeting new project requirements or supporting additional applications. As a system evolves through design exploration, the boundary between the software and hardware pieces can change substantially. The old paradigm of ``separate hardware and software designs before the project starts'' is no longer sustainable, and hardware teams are increasingly responsible for delivering significant software components. Despite this trend, hardware engineers find themselves with surprisingly poor support for the development of the software that is so integral to their project's success. They are often required to manually develop the necessary software and hardware to connect the two environments. In the software world, this is equivalent to manually re-creating header files from the prose description of an interface implemented by a library. Such ad hoc solutions are tedious, fragile, and difficult to maintain. Without a consistent framework and toolchain for jointly managing the components of the hardware/software boundary, designers are prone to make simple errors which can be expensive to debug. The goal of our work is to support the flexible and consistent partitioning of designs across hardware and software components. We have identified the following four goals as central to this endeavor: * Connect software and hardware by compiling interface declarations. * Enable concurrent access to hardware accelerators from software. * Enable high-bandwidth sharing of system memory with hardware accelerators. * Provide portability across platforms (CPU, OS, bus types, FPGAs). In this paper, we present a software-driven hardware development framework called `Connectal`_. Connectal consists of a fully-scripted tool-chain and a collection of libraries which can be used to develop production quality applications comprised of software components running on CPUs communicating with hardware components implemented in FPGA or ASIC. When designing Connectal, our primary goal was to create a collection of components which are easy to use for simple implementations and which can be configured or tuned for high performance in more complicated applications. To this end, we adopted a decidedly minimalist approach, attempting to provide the smallest viable programming interface which can guarantee consistent access to shared resources in a wide range of software and hardware execution environments. Because our framework targets the implementation of performance-critical systems rather than their simulation, we have worked hard to remove any performance penalty associated with its use. We wrote the hardware components of the Connectal libraries in `Bluespec System Verilog`_ (BSV) because it enables a higher level of abstraction than the alternatives and supports parameterized types. The software components are implemented in C/C++. We chose Bluespec interfaces as the interface definition language (IDL) for Connectal's interface compiler. This paper describes the Connectal framework, and how it can be used to flexibly move between a variety of software environments and communication models when mapping applications to platforms with connected FPGAs and CPUs. Document Organization ===================== In Section :ref:`Sec-StrStr`, we present an example running in a number of different execution environments. In Section :ref:`Sec-Framework`, we give an overview of the Connectal framework and its design goals. In Section :ref:`Sec-Impl` we discuss the details of Connectal and how it can be used to implement the example. Section :ref:`Sec-ToolChain` describes the implementation of Connectal, supported platforms, and the tool chain used to coordinate the various parts of the framework. The paper concludes with a discussion of performance metrics and related work. .. _Connectal: http://www.connectal.org/ .. _Bluespec System Verilog: http://www.bluespec.com/ .. [Hoe:Thesis]: Hoe:Thesis .. [HoeArvind:TRS_Synthesis2]: HoeArvind:TRS_Synthesis2 ================================================ FILE: doc/library/source/design/performance.rst ================================================ .. _Sec-Performance: Performance of Generated Systems ================================ A framework is only useful if it reduces the effort required by developers to achieve the desired performance objective. Trying to gauge the relative effort is difficult since the authors implemented both the framework and the running example. On PCIE-based platforms we were able to reduce the time required to search for a fixed set of strings in a large corpus by an order of magnitude after integrating hardware acceleration using Connectal. Performance improvements on the Zynq-based platforms was even greater due to the relative processing power of the ARM CPU and scaled with the number of bus master interfaced used for DMA. In the Connectal framework, developing these applications took very little time. Performance of Portals ---------------------- The current implementation of HW/SW \textbf{portal} transfers 32 bits per FPGA clock cycle. Our example designs run at 100MHz to 250MHz, depending on the complexity of the design and the speed grade of the FPGA used. Due to their intended use, the important performance metric of Portals is latency. These values are given in Figure~\ref{Fig:PortalLatency}. \begin{figure} \centering \begin{tabular}{|c|c|c|c|c|c|c|c|c|} \hline & \rt{KC705} & \rt{VC707} & \rt{ZYBO} & \rt{Zedboard} & \rt{ZC702} & \rt{ZC706} & \rt{Parallel} & \rt{Mini-ITX} \\ \hline HW $\rightarrow$ SW & 3 & 3 & X & 0.80 & 0.80 & 0.65 & X & 0.65 \\ \hline SW $\rightarrow$ HW & 5 & 5 & X & 1.50 & 1.50 & 1.10 & X & 1.10 \\ \hline \end{tabular} \caption{Latency ($\mu$s) of communication through portals on supported platforms\label{Fig:PortalLatency}} \end{figure} The Xilinx KC705 and VC707 boards connect to x86 CPUs and system memory via PCIe gen1. The default FPGA clock for those boards is 125MHz. The other platforms use AXI to connect the programmable logic to the quad-core ARM Cortex A9 and system memory. The ZYBO, Zedboard and ZC702 use a slower speed grade part on which our designs run at 100MHz. The ZC706 and Mini-ITX use a faster part on which many of our designs run at 200MHz. The lower latency measured on the ZC706 reflects the higher clock speed of the latency performance test. Performance of Reads/Writes of System Memory -------------------------------------------- For high bandwidth transfers, we assume the developer will have the application hardware read or write system memory directly. Direct access to memory enables transfers with longer bursts, reducing memory bus protocol overhead. The framework supports transfer widths of 32 to 128 bits per cycle, depending on the interconnect used. Our goal in the design of the library components used to read and write system memory is to ensure that a developer's application can use all bandwidth available to the FPGA when accessing system memory. DMA Bandwidth on supported platforms is listed in Figure\ref{Fig:DmaBandwidth}. \begin{figure} \centering \begin{tabular}{|c|c|c|c|c|c|c|c|c|} \hline & \rt{KC705} & \rt{VC707} & \rt{ZYBO} & \rt{Zedboard} & \rt{ZC702} & \rt{ZC706} & \rt{Parallel} & \rt{Mini-ITX} \\ \hline Read & 1.4 & 1.4 & X & 0.8 & 0.8 & 1.6 & X & 1.6 \\ \hline Write & 1.4 & 1.4 & X & 0.8 & 0.8 & 1.6 & X & 1.6 \\ \hline \end{tabular} \caption{Maximum bandwidth (GB/s) between FPGA and host memory using Connectal RTL libraries on supported platforms\label{Fig:DmaBandwidth}} \end{figure} On PCIe systems, Connectal currently supports 8 lane PCIe gen1. We've measured 1.4 gigabytes per second for both reads and writes. Maximum throughput of 8 lane PCIe gen1 is 1.8GB/s, taking into account 1 header transaction per 8 data transactions, where 8 is the maximum number of data transactions per request supported by our server's chipset. The current version of the test needs some more tuning in order to reach the full bandwidth available. In addition, we are in the process of updating to 8 lane PCIe gen2 using newer Xilinx cores. Zynq systems have four *high performance* ports for accessing system memory. Connectal enables an accelerator to use all four. In our experiments, we have been able to achieve 3.6x higher bandwidth using 4 ports than using 1 port. ================================================ FILE: doc/library/source/design/portal.rst ================================================ ================== What is Connectal? ================== Connectal provides a hardware-software interface for applications split between user mode code and custom hardware in an FPGA or ASIC. Connectal can automaticaly build the software and hardware glue for a message based interface and also provides for configuring and using shared memory between applications and hardware. Communications between hardware and software are provided by a bidirectional flow of events and regions of memory shared between hardware and software. Events from software to hardware are called requests and events from hardware to software are called indications, but in fact they are symmetric. .. _bsvdocumentation: http://wiki.bluespec.com/Home/BSV-Documentation .. _bluespecdotcom: http://www.bluespec.com/ Lexicon ------- connectal:: The name of the project, whose goal is to ease the task of building applications composed of hardware and software components. Programmers use bsv as an IDL to specify the interface between the hardware and software components. A combination of generated code and libraries coordinate the data-flow between the program modules. Because the HW and SW stacks are customized for each application, the overheads associated with communicating across the HW/SW boundary are low. HW/SW interface :: portal bsv:: Bluespec System Verilog. bsv is a language for describing hardware that is might higher level than verilog. See {bsvdocumentation}[BSV Documentation] and {bluespecdotcom}[Bluespec, Inc]. bluespec:: Shorthand for Bluespec System Verilog (bsv) indexterm:portal portal:: a logical request/indication pair is referred to as a portal. current tools require their specification in the IDL to be syntactically identifiable (i.e. fooRequest/fooIndication). An application can make use of multiple portals, which may be specified independently. request interface:: These methods are implemented by the application hardware to be invoked by application software. A bsv interface consisting of ‘Action’ methods. Because of the ‘Action’ type, data flow across this interface is unidirectional (SW -> HW). indication interface:: The dual of a request interface, indication interfaces are ‘Action’ methods implemented by application software to be invoked by application hardware. As with request interfaces, the data flow across this interface is unidirectional, but in the opposite direction. pcieportal/zynqportal:: these two loadable kernel modules implement the minimal set of driver functionality. Specifically, they expose portal HW registers to SW through mmap, and set up interrupts to notify SW that an indication method has been invoked by HW. portalalloc:: This loadable kernel module exposes a subset of dma-buf functionality to user-space software (though a set of ioctl commands) to allocate and manage memory regions which can be shared between SW and HW processes. Maintaining coherence of the allocated buffers between processes is not automatic: ioctl commands for flush/invalidate are provided to be invoked explicitly by the users if necessary. connectalgen:: The name of the interface compiler which takes as input the bsv interface specification along with a description of a target platform and generates logic in both HW and SW to support this interface across the communication fabric. Example setups: --------------- A zedboard ( http://www.zedboard.org/ ), with Android running on the embedded ARM processors (the Processing System 7), an application running as a user process, and custom hardware configured into the Programmable Logic FPGA. An x86 server, with Linux running on the host processor, an application running partly as a user process on the host and partly as hardware configured into an FPGA connected by PCI express (such as the Xilinx VC707 (http://www.xilinx.com/products/boards-and-kits/EK-V7-VC707-G.htm). Background ---------- When running part or all of an application in an FPGA, it is usually necessary to communicate between code running in user mode on the host and the hardware. Typically this has been accomplished by custom device drivers in the OS, or by shared memory mapped between the software and the hardware, or both. Shared memory has been particularly troublesome under Linux or Android, because devices frequently require contiguous memory, and the mechanisms for guaranteeing successful memory allocation often require reserving the maximum amount of memory at boot time. Portal tries to provide convenient solutions to these problems in a portable way. It is desirable to have * low latency for small messages * high bandwidth for large messages * notification of arriving messages * asynchronous replies to messages * support for hardware simulation by a separate user mode process * support for shared memory (DMA) between hardware and software Overview -------- Portal is implemented as a loadable kernel module device driver for Linux/Android and a set of tools to automatically construct the hardware and software glue necessary for communications. Short messages are handled by programmed I/O. The message interface from software to hardware (so called "requests") is defined as a bsv interface containing a number of Action methods, each with a name and typed arguments. The interface generator creates all the software and hardware glue so that software invocations of the interface stubs flow through to, and are turned into bsv invocations of the matching hardware. The machinery does not have flow control. Software is responsible for not overrunning the hardware. There is a debug mechanism which will return the request type of a failed method, but it does not tell which invocation failed. Hardware to software interfaces (so called “indications”) are likewise defined by bsv interfaces containing Action methods. Hardware invocations of these methods flow through to and cause software calls to corresponding user-supplied functions. In the current implementation there is flow control, in that the hardware will stall until there is room for a hardware to software message. There is also a mechanism for software to report a failure, and there is machinery for these failures to be returned to the hardware. ["seqdiag",target="request-response-1.png"] --------------------------------------------------------------------- { // edge label SW -> HW [label = "request"]; SW <- HW [label = "indication"]; } --------------------------------------------------------------------- Portals do not have to be structured as request/response. Hardware can send messages to software without a prior request from software. ["seqdiag",target="indication-only.png"] --------------------------------------------------------------------- { // edge label SW <- HW [label = "indication"]; } --------------------------------------------------------------------- Incoming messages can cause host interrupts, which wake up the device driver, which can wake up the user mode application by using the select(2) or poll(2) interfaces. Most of the time, communications between hardware and software will proceed without requiring use of the OS. User code will read and write directly to memory mapped I/O space. Library code will poll for incoming messages, and [true? eventually time out and call poll(2). Only when poll(2) or select(2) are called will the device driver enable hardware interrupts. Thus interrupts are only used to wake up software after a quiet period. The designer specifies a set of hardware functions that can be called from software, and a set of actions that the hardware can take which result in messages to software. Portal tools take this specification and build software glue modules to translate software function calls into I/O writes to hardware registers, and to report hardware events to software. For larger memory and OS bypass (OS bypass means letting the user mode application talk directly to the hardware without using the OS except for setup), portal implements shared memory. Portal memory objects are allocated by the user mode program, and appear as Linux file descriptors. The user can mmap(2) the file to obtain user mode access to the shared memory region. Portal does not assure that the memory is physically contiguous, but does pin it to prevent the OS from reusing the memory. An FPGA DMA controller module is provided that gives the illusion of contiguous memory to application hardware, while under the covers using a translation table of scattered addresses. The physical addresses are provided to the user code in order to initialize the dma controller, and address "handles" are provided for the application hardware to use. The DMA controller provides Bluespec objects that support streaming access with automatic page crossings, or random access. An Example ---------- An application developer will typically write the hardware part of the application in Bluespec and the software part of the application in C or C++. In a short example, there will be a bsv source file for the hardware and a cpp source file for the application. The application developer is free to specify whatever hardware-software interface makes sense. Refer to https://github.com/cambridgehackers/connectal In the examples directory, see [simple](../examples/simple/). The file [Simple.bsv](../examples/simple/Simple.bsv) defines the hardware, and testsimple.cpp supplies the software part. In this case, the software part is a test framework for the hardware. Simple.bsv declares a few `struct` and `enum` types:: typedef struct{ Bit#(32) a; Bit#(32) b; } S1 deriving (Bits); typedef struct{ Bit#(32) a; Bit#(16) b; Bit#(7) c; } S2 deriving (Bits); typedef enum { E1Choice1, E1Choice2, E1Choice3 } E1 deriving (Bits,Eq); typedef struct{ Bit#(32) a; E1 e1; } S3 deriving (Bits); Simple.bsv defines the actions (called Requests) that software can use to cause the hardware to act, and defines the notifications (called Indications) that the hardware can use to signal the software. :: interface SimpleIndication; method Action heard1(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); method Action heard3(S1 v); method Action heard4(S2 v); method Action heard5(Bit#(32) a, Bit#(64) b, Bit#(32) c); method Action heard6(Bit#(32) a, Bit#(40) b, Bit#(32) c); method Action heard7(Bit#(32) a, E1 e1); endinterface interface SimpleRequest; method Action say1(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action say3(S1 v); method Action say4(S2 v); method Action say5(Bit#(32)a, Bit#(64) b, Bit#(32) c); method Action say6(Bit#(32)a, Bit#(40) b, Bit#(32) c); method Action say7(S3 v); endinterface Software can start the hardware working via say, say2, ... Hardware signals back to software with heard and heard2 and so fort. In the case of this example, say and say2 merely echo their arguments back to software. The definitions in the bsv file are used by the connectal infrastructure ( a python program) to automatically create corresponding c++ interfaces.:: ../../connectalgen -Bbluesim -p bluesim -x mkBsimTop \ -s2h SimpleRequest \ -h2s SimpleIndication \ -s testsimple.cpp \ -t ../../bsv/BsimTop.bsv Simple.bsv Top.bsv The tools have to be told which interface records should be used for Software to Hardware messages and which should be used for Hardware to Software messages. These interfaces are given on the command line for genxpprojfrombsv connectalgen constructs all the hardware and software modules needed to wire up portals. This is sort of like an RPC compiler for the hardware-software interface. However, unlike an RPC each method is asynchronous. The user must also create a toplevel bsv module Top.bsv, which instantiates the user portals, the standard hardware environment, and any additional hardware modules. Rather than constructing the *makefilegen* command line from scratch, the examples in connectal use include *Makefile.connectal* and define some *make* variables. Here is the Makefile for the `simple` example:: CONNECTALDIR?=../.. INTERFACES = SimpleRequest SimpleIndication BSVFILES = Simple.bsv Top.bsv CPPFILES=testsimple.cpp include $(CONNECTALDIR)/Makefile.connectal Designs outside the connectal directory using `connectal` may also include `Makefile.connectal`:: CONNECTALDIR?=/scratch/connectal INTERFACES = ... BSVFILES = ... CPPFILES = ... include $(CONNECTALDIR)/Makefile.connectal simple/Top.bsv --------------- Each CONNECTAL design implements [Top.bsv](../examples/simple/Top.bsv) with some standard components. It defines the `IfcNames` enum, for use in identifying the portals between software and hardware:: typedef enum {SimpleIndication, SimpleRequest} IfcNames deriving (Eq,Bits); It defines `mkConnectalTop`, which instantiates the wrappers, proxies, and the design itself:: module mkConnectalTop(StdConnectalTop#(addrWidth)); :bsv:module:StdConnectalTop is parameterized by `addrWidth` because Zynq and x86 have different width addressing. `StdConnectalTop` is a typedef:: typedef ConnectalTop#(addrWidth,64,Empty) StdConnectalTop#(numeric type addrWidth); The "64" specifies the data width and `Empty` specifies the empty interface is exposed as pins from the design. In designs using HDMI, for example, `Empty` is replaced by `HDMI`. On some platforms, the design may be able to use different data widths, such as 128 bits on x86/PCIe. Next, `mkConnectalTop` instantiates user portals:: // instantiate user portals SimpleIndicationProxy simpleIndicationProxy <- mkSimpleIndicationProxy(SimpleIndication); Instantiate the design:: SimpleRequest simpleRequest <- mkSimpleRequest(simpleIndicationProxy.ifc); Instantiate the wrapper for the design:: SimpleRequestWrapper simpleRequestWrapper <- mkSimpleRequestWrapper(SimpleRequest,simpleRequest); Collect the portals into a vector:: Vector#(2,StdPortal) portals; portals[0] = simpleRequestWrapper.portalIfc; portals[1] = simpleIndicationProxy.portalIfc; Create an interrupt multiplexer from the vector of portals:: let interrupt_mux <- mkInterruptMux(portals); Create the system directory, which is used by software to locate each portal via the `IfcNames` enum:: // instantiate system directory StdDirectory dir <- mkStdDirectory(portals); let ctrl_mux <- mkAxiSlaveMux(dir,portals); The following generic interfaces are used by the platform specific top BSV module:: interface interrupt = interrupt_mux; interface ctrl = ctrl_mux; interface m_axi = null_axi_master; interface leds = echoRequestInternal.leds; endmodule : mkConnectalTop simple/testsimple.cpp --------------------- CONNECTAL generates header files declaring wrappers for hardware-to-software interfaces and proxies for software-to-hardware interfaces. These will be in the "jni/" subdirectory of the project directory. :: #include "SimpleIndication.h" #include "SimpleRequest.h" It also declares software equivalents for structs and enums declared in the processed BSV files:: #include "GeneratedTypes.h" CONNECTAL generates abstract virtual base classes for each Indication interface. :: class SimpleIndicationWrapper : public Portal { public: ... SimpleIndicationWrapper(int id, PortalPoller *poller = 0); virtual void heard1 ( const uint32_t v )= 0; ... }; Implement subclasses of the wrapper in order to define the callbacks:: class SimpleIndication : public SimpleIndicationWrapper { public: ... virtual void heard1(uint32_t a) { fprintf(stderr, "heard1(%d)\n", a); assert(a == v1a); incr_cnt(); } ... }; To connect these classes to the hardware, instantiate them using the `IfcNames` enum identifiers. CONNECTAL prepends the name of the type because C++ does not support overloading of enum tags. :: SimpleIndication *indication = new SimpleIndication(IfcNames_SimpleIndication); SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequest); Create a thread for handling notifications from hardware:: pthread_t tid; if(pthread_create(&tid, NULL, portalExec, NULL)){ exit(1); } Now the software invokes hardware methods via the proxy:: device->say1(v1a); device->say2(v2a,v2b); Simple Example Design Structure ------------------------------- The `simple` example consists of the following files:: Simple.bsv Makefile Top.bsv testsimple.cpp After running `make BOARD=zedboard verilog` in the `simple` directory, the `zedboard` project directory is created, populated by the generated files. A top level `Makefile` is created:: zedboard/Makefile makefilegen generates wrappers for software-to-hardware interfaces and proxies for hardware-to-software interfaces:: zedboard/sources/mkzynqtop/SimpleIndicationProxy.bsv zedboard/sources/mkzynqtop/SimpleRequestWrapper.bsv Connectal supports Android on Zynq platforms, so connectalgen generates `jni/Android.mk` for `ndk-build`:: zedboard/jni/Android.mk zedboard/jni/Application.mk Connectal generates `jni/Makefile` to compile the software for PCIe platforms (vc707 and kc705): zedboard/jni/Makefile CONNECTAL generates software proxies for software-to-hardware interfaces and software wrappers for hardware-to-software interfaces:: zedboard/jni/SimpleIndication.h zedboard/jni/SimpleIndication.cpp zedboard/jni/SimpleRequest.cpp zedboard/jni/SimpleRequest.h CONNECTAL also generates `GeneratedTypes.h` for struct and enum types in the processed BSV source files:: zedboard/jni/GeneratedTypes.h CONNECTAL copies in standard and specified constraints files:: zedboard/constraints/design_1_processing_system7_1_0.xdc zedboard/constraints/zedboard.xdc CONNECTAL generates several TCL files to run `vivado`. The `board.tcl` file specifies `partname`, `boardname`, and `connectaldir` for the other TCL scripts.:: zedboard/board.tcl To generate an FPGA bit file, run `make bits`. This runs vivado with the `mkzynqtop-impl.tcl` script.:: zedboard/mkzynqtop-impl.tcl make verilog ^^^^^^^^^^^^ Compiling to verilog results in the following verilog files:: zedboard/verilog/top/mkSimpleIndicationProxySynth.v zedboard/verilog/top/mkZynqTop.v Verilog library files referenced in the design are copied for use in synthesis.:: zedboard/verilog/top/FIFO1.v ... make bits ^^^^^^^^^ Running `make bits` in the zedboard directory results in timing reports:: zedboard/bin/mkzynqtop_post_place_timing_summary.rpt zedboard/bin/mkzynqtop_post_route_timing_summary.rpt zedboard/bin/mkzynqtop_post_route_timing.rpt and some design checkpoints:: zedboard/hw/mkzynqtop_post_synth.dcp zedboard/hw/mkzynqtop_post_place.dcp zedboard/hw/mkzynqtop_post_route.dcp and the FPGA configuration file in .bit and .bin formats:: zedboard/hw/mkZynqTop.bit zedboard/hw/mkZynqTop.bin make android_exe ^^^^^^^^^^^^^^^^ CONNECTAL supports Android 4.0 on Zynq platforms. It generates `jni/Android.mk` which is used by `ndk-build` to create a native Android executable.:: make android_exe This produces the ARM elf executable:: libs/armeabi/android_exe make run ^^^^^^^^ For Zynq platforms:: make run will copy the Android executable and FPGA configuration file to the target device, program the FPGA, and run the executable. See [run.android](../scripts/run.android) for details. It uses `checkip` to determine the IP address of the device via a USB console connection to the device (it is built/installed on the host machine from the git repo cambridgehackers/consolable). If the target is not connected to the build machine via USB, specify the IP address of the target manually:: make RUNPARAM=ipaddr run For PCIe platforms, `make run` programs the FPGA via USB and runs the software locally. For bluesim, `make run` invokes bluesim on the design and runs the software locally. Shared Memory ------------- Shared Memory Hardware ^^^^^^^^^^^^^^^^^^^^^^ In order to use shared memory, the hardware design instantiates a DMA module in Top.bsv:: AxiDmaServer#(addrWidth,64) dma <- mkAxiDmaServer(dmaIndicationProxy.ifc, readClients, writeClients); The AxiDmaServer multiplexes read and write requests from the clients, translates DMA addresses to physical addresses, initiates bus transactions to memory, and delivers responses to the clients. DMA requests are specified with respect to "portal" memory allocated by software and identified by a `pointer`. Requests and responses are tagged in order to enable pipelining:: typedef struct { SGLId pointer; Bit#(MemOffsetSize) offset; Bit#(8) burstLen; Bit#(6) tag; } MemRequest deriving (Bits); typedef struct { Bit#(dsz) data; Bit#(6) tag; } MemData#(numeric type dsz) deriving (Bits); Read clients implement the `MemReadClient` interface. On response to the read, `burstLen` `MemData` items will be put to the `readData` interface. The design must be ready to consume the data when it is delivered from the memory bus or the system may hang:: interface MemReadClient#(numeric type dsz); interface GetF#(MemRequest) readReq; interface PutF#(MemData#(dsz)) readData; endinterface Write clients implement `MemWriteClient`. To complete the transaction, `burstLen` data items will be consumed from the `writeData` interace. Upon completion of the request, the specified tag will be put to the `writeDone` interface. The data must be available when the write request is issued to the memory bus or the system may hang:: interface MemWriteClient#(numeric type dsz); interface GetF#(MemRequest) writeReq; interface GetF#(MemData#(dsz)) writeData; interface PutF#(Bit#(6)) writeDone; endinterface A design may implement `MemReadClient` and `MemWriteClient` interfaces directly, or it may instantiate DmaReadBuffer or DmaWriteBuffer. The `AxiDmaServer` is configured with physical address translations for each region of memory identified by a `pointer`. A design using DMA must export the `DmaConfig` and `DmaIndication` interfaces of the DMA server. Here are the DMA components of [memread_nobuff/Top.bsv](../examples/memread_nobuff/Top.bsv): Instantiate the design and its interface wrappers and proxies:: MemreadIndicationProxy memreadIndicationProxy <- mkMemreadIndicationProxy(MemreadIndication); Memread memread <- mkMemread(memreadIndicationProxy.ifc); MemreadRequestWrapper memreadRequestWrapper <- mkMemreadRequestWrapper(MemreadRequest,memread.request); Collect the read and write clients:: Vector#(1, MemReadClient#(64)) readClients = cons(memread.dmaClient, nil); Vector#(0, MemReadClient#(64)) writeClients = nil; Instantiate the DMA server and its wrapper and proxy:: DmaIndicationProxy dmaIndicationProxy <- mkDmaIndicationProxy(DmaIndication); AxiDmaServer#(addrWidth,64) dma <- mkAxiDmaServer(dmaIndicationProxy.ifc, readClients, writeClients); DmaConfigWrapper dmaConfigWrapper <- mkDmaConfigWrapper(DmaConfig,dma.request); Include `DmaConfig` and `DmaIndication` in the portals of the design:: Vector#(4,StdPortal) portals; portals[0] = memreadRequestWrapper.portalIfc; portals[1] = memreadIndicationProxy.portalIfc; portals[2] = dmaConfigWrapper.portalIfc; portals[3] = dmaIndicationProxy.portalIfc; The code generation tools will then produce the software glue necessary for the shared memory support libraries to initialize the DMA "library module" included in the hardware. Shared Memory Software ^^^^^^^^^^^^^^^^^^^^^^ The software side instantiates the DmaConfig proxy and the DmaIndication wrapper:: dma = new DmaConfigProxy(IfcNames_DmaConfig); dmaIndication = new DmaIndication(dma, IfcNames_DmaIndication); Call `dma->alloc()` to allocate DMA memory. Each chunk of portal memory is identified by a file descriptor. Portal memory may be shared with other processes. Portal memory is reference counted according to the number of file descriptors associated with it:: PortalAlloc *srcAlloc; dma->alloc(alloc_sz, &srcAlloc); Memory map it to make it accessible to software:: srcBuffer = (unsigned int *)mmap(0, alloc_sz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, srcAlloc->header.fd, 0); Connectal is currently using non-snooped interfaces, so the cache must be flushed and invalidated before hardware accesses portal memory:: dma->dCacheFlushInval(srcAlloc, srcBuffer); Call `dma->reference()` to get a pointer that may be passed to hardware:: unsigned int ref_srcAlloc = dma->reference(srcAlloc); This also transfers the DMA-to-physical address translation information to the hardware via the `DmaConfig` interface:: device->startRead(ref_srcAlloc, numWords, burstLen, iterCnt); Notes ----- stewart notes ^^^^^^^^^^^^^ .. caution:: Currently there are no valid bits and no protections against bursts crossing page boundaries .. caution:: There needs to be a way to synchronize Request actions and DMA reads, and to synchronize DMA writes with Indications, so that the writes complete to the coherence point before the indication is delivered to software. One could imagine an absurdly buffered memory interface and a rather direct path for I/O reads that could get out of order. ================================================ FILE: doc/library/source/design/portalstructure.rst ================================================ Portal Interface Structure ************************** Connectal connects software and hardware via portals, where each portal is an interface that allows one side to invoke methods on the other side. We generally call a portal from software to hardware to be a "request" and from hardware to software to be an "indication" interface:: Sequence Diagram to be drawn { SW; HW SW -> HW [label = "request"]; SW <- HW [label = "indication"]; } A portal is conceptually a FIFO, where the arguments to a method are packaged as a message. CONNECTAL generates a "proxy" that marshalls the arguments to the method into a message and a "wrapper" that unpacks the arguments and invokes the method. Currently, connectal Includes a library that implements portals from software to hardware via memory mapped hardware FIFOs. Portal Device Drivers ===================== Connectal uses a platform-specific driver to enable user-space applications to memory-map each portal used by the application and to enable the application to wait for interrupts from the hardware. indexterm:pcieportal indexterm:zynqportal * pcieportal.ko * zynqportal.ko Connectal also uses a generic driver to enable the applications to allocate DRAM that will be shared with the hardware and to send the memory mapping of that memory to the hardware. * portalmem.ko Portal Memory Map ================= Connectal is designed to support multiple tiles, each of which can hold an independent design. Currently, the number of tiles is one. Connectal currently supports up to 16 portals connected between software and hardware, for a total of 64KB of address space. ============= ========= Base address Function ============= ========= 0x0000 Portal 0 0x1000 Portal 1 0x2000 Portal 2 0x3000 Portal 3 0x4000 Portal 4 0x5000 Portal 5 0x6000 Portal 6 0x7000 Portal 7 0x8000 Portal 8 0x9000 Portal 9 0xa000 Portal 10 0xb000 Portal 11 0xc000 Portal 12 0xd000 Portal 13 0xe000 Portal 14 0xf000 Portal 15 ============= ========= Each portal uses 16KB of address space, consisting of a control register region and then per-method FIFOs, each of which takes 32 bytes of address space. ============== ========== Base address Function ============== ========== 0x000 Portal control regs 0x020 Method 0 FIFO 0x040 Method 1 FIFO ... ... ============== ========== For request portals, the FIFOs are from software to hardware, and for indication portals the FIFOs are from hardware to software. Portal FIFOs ------------ ============== ========== Base address Function ============== ========== 0x00 FIFO data (write request data, read indication data) 0x04 Request FIFO not full / Indication FIFO not empty ============== ========== Portal Control Registers ------------------------ ============= ============================= ========================================================= Base address Function Description ============= ============================= ========================================================= 0x00 Interrupt status register 1 if this portal has any messages ready, 0 otherwise 0x04 Interrupt enable register Write 1 to enable interrupts, 0 to disable 0x08 Number of tiles 0x0C Ready Channel number + 1 Reads as zero if no indication channel ready 0x10 Interface Id 0x14 Number of portals 0x18 Cycle count LSW Snapshots MSW when read 0x1C Cycle count MSW MSW of cycle count when LSW was read ============= ============================= ========================================================= ================================================ FILE: doc/library/source/design/references.bib ================================================ % ---------------------------------------------------- % Paper Specific References % ---------------------------------------------------- @inproceedings{DBLP:conf/fpga/WillenbergC13, author = {Ruediger Willenberg and Paul Chow}, title = {A remote memory access infrastructure for global address space programming models in FPGAs}, booktitle = {The 2013 {ACM/SIGDA} International Symposium on Field Programmable Gate Arrays, {FPGA} '13, Monterey, CA, USA, February 11-13, 2013}, pages = {211--220}, year = {2013}, url = {http://doi.acm.org/10.1145/2435264.2435301}, doi = {10.1145/2435264.2435301}, timestamp = {Wed, 27 Feb 2013 08:26:59 +0100}, biburl = {http://dblp.uni-trier.de/rec/bib/conf/fpga/WillenbergC13}, bibsource = {dblp computer science bibliography, http://dblp.org} } @article{DBLP:journals/jpdc/MooreLK12, author = {Nicholas Moore and Miriam Leeser and Laurie A. Smith King}, title = {VForce: An environment for portable applications on high performance systems with accelerators}, journal = {J. Parallel Distrib. Comput.}, volume = {72}, number = {9}, pages = {1144--1156}, year = {2012}, url = {http://dx.doi.org/10.1016/j.jpdc.2011.07.014}, doi = {10.1016/j.jpdc.2011.07.014}, timestamp = {Fri, 19 Oct 2012 13:56:48 +0200}, biburl = {http://dblp.uni-trier.de/rec/bib/journals/jpdc/MooreLK12}, bibsource = {dblp computer science bibliography, http://dblp.org} } @article{DBLP:journals/trets/SaldanaPMNWCWSP10, author = {Manuel Salda{\~{n}}a and Arun Patel and Christopher A. Madill and Daniel Nunes and Danyao Wang and Paul Chow and Ralph Wittig and Henry Styles and Andrew Putnam}, title = {{MPI} as a Programming Model for High-Performance Reconfigurable Computers}, journal = {{TRETS}}, volume = {3}, number = {4}, pages = {22}, year = {2010}, url = {http://doi.acm.org/10.1145/1862648.1862652}, doi = {10.1145/1862648.1862652}, timestamp = {Wed, 08 Dec 2010 08:58:19 +0100}, biburl = {http://dblp.uni-trier.de/rec/bib/journals/trets/SaldanaPMNWCWSP10}, bibsource = {dblp computer science bibliography, http://dblp.org} } @inproceedings{DBLP:conf/fpga/FilguerasGJAMLNV14, author = {Antonio Filgueras and Eduard Gil and Daniel Jim{\'{e}}nez{-}Gonz{\'{a}}lez and Carlos Alvarez and Xavier Martorell and Jan Langer and Juanjo Noguera and Kees A. Vissers}, title = {OmpSs@Zynq all-programmable SoC ecosystem}, booktitle = {The 2014 {ACM/SIGDA} International Symposium on Field-Programmable Gate Arrays, {FPGA} '14, Monterey, CA, {USA} - February 26 - 28, 2014}, pages = {137--146}, year = {2014}, url = {http://doi.acm.org/10.1145/2554688.2554777}, doi = {10.1145/2554688.2554777}, timestamp = {Mon, 24 Feb 2014 13:13:31 +0100}, biburl = {http://dblp.uni-trier.de/rec/bib/conf/fpga/FilguerasGJAMLNV14}, bibsource = {dblp computer science bibliography, http://dblp.org} } @article{DBLP:journals/ijrc/JozwikHETT13, author = {Krzysztof Jozwik and Shinya Honda and Masato Edahiro and Hiroyuki Tomiyama and Hiroaki Takada}, title = {Rainbow: An Operating System for Software-Hardware Multitasking on Dynamically Partially Reconfigurable FPGAs}, journal = {Int. J. Reconfig. Comp.}, volume = {2013}, year = {2013}, url = {http://dx.doi.org/10.1155/2013/789134}, doi = {10.1155/2013/789134}, timestamp = {Mon, 24 Mar 2014 18:09:23 +0100}, biburl = {http://dblp.uni-trier.de/rec/bib/journals/ijrc/JozwikHETT13}, bibsource = {dblp computer science bibliography, http://dblp.org} } @inproceedings{DBLP:conf/fpl/FlemingYAE14, author = {Kermin Fleming and Hsin{-}Jung Yang and Michael Adler and Joel S. Emer}, title = {The {LEAP} {FPGA} operating system}, booktitle = {24th International Conference on Field Programmable Logic and Applications, {FPL} 2014, Munich, Germany, 2-4 September, 2014}, pages = {1--8}, year = {2014}, url = {http://dx.doi.org/10.1109/FPL.2014.6927488}, doi = {10.1109/FPL.2014.6927488}, timestamp = {Thu, 30 Oct 2014 14:01:03 +0100}, biburl = {http://dblp.uni-trier.de/rec/bib/conf/fpl/FlemingYAE14}, bibsource = {dblp computer science bibliography, http://dblp.org} } @inproceedings{DBLP:conf/fpl/PeckAASBA06, author = {Wesley Peck and Erik K. Anderson and Jason Agron and Jim Stevens and Fabrice Baijot and David L. Andrews}, title = {Hthreads: {A} Computational Model for Reconfigurable Devices}, booktitle = {Proceedings of the 2006 International Conference on Field Programmable Logic and Applications (FPL), Madrid, Spain, August 28-30, 2006}, pages = {1--4}, year = {2006}, url = {http://doi.ieeecomputersociety.org/10.1109/FPL.2006.311336}, doi = {10.1109/FPL.2006.311336}, timestamp = {Mon, 11 Jul 2011 13:44:26 +0200}, biburl = {http://dblp.uni-trier.de/rec/bib/conf/fpl/PeckAASBA06}, bibsource = {dblp computer science bibliography, http://dblp.org} } @MISC{Opencl, AUTHOR = {{The Kronos Group}}, HOWPUBLISHED = {{https://www.khronos.org/registry/cl/}}}, } @MISC{AlteraOpencl, AUTHOR = {{Altera Inc.}}, HOWPUBLISHED = {{http://www.altera.com/products/software/opencl/opencl-index.html}} } @MISC{XilinxOpencl, AUTHOR = {{Xilinx Inc.}}, HOWPUBLISHED = {{http://www.xilinx.com}} } @inbook{mpAlgo, author = {Alberto Apostolico, Zvi Galil}, title = {Pattern Matching Algorithms}, year = {1997}, pages = {7-11}, chapter = {1}, note = {mp algorithm} } @INPROCEEDINGS{Chou92synthesisof, author = {Pai Chou and Ross Ortega and Gaetano Borriello}, title = {Synthesis of the Hardware/Software Interface in Microcontroller-Based Systems}, booktitle = {In Proceedings of the International Conference on Computer Aided Design}, year = {1992}, pages = {488--495} } @INPROCEEDINGS{Chou95thechinook, author = {Pai H. Chou and Ross B. Ortega and Gaetano Borriello}, title = {The Chinook Hardware/Software Co-Synthesis System}, booktitle = {In International Symposium on System Synthesis}, year = {1995}, pages = {22--27} } @inproceedings{DBLP:conf/dac/LiaoTG97, author = {Stan Y. Liao and Steven W. K. Tjiang and Rajesh K. Gupta}, title = {An Efficient Implementation of Reactivity for Modeling Hardware in the Scenic Design Environment}, booktitle = {DAC}, year = {1997}, pages = {70-75}, ee = {http://doi.acm.org/10.1145/266021.266037}, bibsource = {DBLP, http://dblp.uni-trier.de} } @INPROCEEDINGS{Abdulla04designingsafe, author = {Parosh Aziz Abdulla and Johann Deneux}, title = {Designing Safe, Reliable Systems using Scade}, booktitle = {In Proc. ISoLA 2004}, year = {2004} } @inproceedings{Colaco, author = {Cola\c{c}o, Jean-Louis and Hamon, Gr\'{e}goire and Pouzet, Marc}, title = {Mixing signals and modes in synchronous data-flow systems}, booktitle = {Proceedings of the 6th ACM \& IEEE International conference on Embedded software}, series = {EMSOFT '06}, year = {2006}, isbn = {1-59593-542-8}, location = {Seoul, Korea}, pages = {73--82}, numpages = {10}, acmid = {1176899}, publisher = {ACM}, address = {New York, NY, USA}, keywords = {compilation, languages, mode automata, synchronous}, } @ARTICLE{Lustre1991, author={Halbwachs, N. and Caspi, P. and Raymond, P. and Pilaud, D.}, journal={Proceedings of the IEEE}, title={The synchronous data flow programming language LUSTRE}, year={1991}, month={sep}, volume={79}, number={9}, pages={1305 -1320}, keywords={LUSTRE;description tools;program verification methodology;reactive systems;sequential program;synchronous data flow programming language;temporal logics;parallel languages;program verification;temporal logic;}, doi={10.1109/5.97300}, ISSN={0018-9219},} @inproceedings{MainlandM10, author = {Geoffrey Mainland and Greg Morrisett}, title = {Nikola: Embedding Compiled {GPU} Functions in {Haskell}}, booktitle = {Proceedings of the 2010 ACM SIGPLAN Symposium on Haskell (Haskell'10)}, year = {2010}, month = sep, location = {Baltimore, MD}, publisher = {ACM}, address = {New York, NY, USA}, pdf = {http://www.eecs.harvard.edu/~mainland/publications/mainland10nikola.pdf} } } @inproceedings{MEMOCODE2010, title={A Design Flow Based on Modular Refinement}, author = {Nirav Dave and Man Cheuk Ng and Michael Pellauer and Arvind}, booktitle = {Formal Methods and Models for Codesign (MEMOCODE 2010)}, location = {Grenoble, France. June 2010 } } @inproceedings{DBLP:conf/emsoft/TalpinBGG06, author = {Jean-Pierre Talpin and Christian Brunette and Thierry Gautier and Abdoulaye Gamati{\'e}}, title = {Polychronous mode automata}, booktitle = {EMSOFT}, year = {2006}, pages = {83-92}, ee = {http://doi.acm.org/10.1145/1176887.1176900}, bibsource = {DBLP, http://dblp.uni-trier.de} } @ARTICLE{Lynch89IOAutomata, author = {Nancy A. Lynch and Mark R. Tuttle}, title = {An introduction to input/output automata}, journal = {CWI Quarterly}, year = {1989}, volume = {2}, pages = {219--246} } @inproceedings{meredith-katelman-meseguer-rosu-2010-memocode, author={Patrick O'Neil Meredith and Michael Katelman and Jos{\'e} Meseguer and Grigore Ro\c{s}u}, title={A Formal Executable Semantics of {V}erilog}, booktitle={Eighth ACM/IEEE International Conference on Formal Methods and Models for Codesign (MEMOCODE'10)}, year={2010}, publisher={IEEE}, pages={179-188} } @article{DBLP:journals/dc/ShavitT97, author = {Nir Shavit and Dan Touitou}, title = {Software Transactional Memory}, journal = {Distributed Computing}, volume = {10}, number = {2}, year = {1997}, pages = {99-116}, bibsource = {DBLP, http://dblp.uni-trier.de} } @inproceedings{DBLP:conf/podc/SchererS05, author = {William N. Scherer III and Michael L. Scott}, title = {Advanced contention management for dynamic software transactional memory}, booktitle = {PODC}, year = {2005}, ee = {http://doi.acm.org/10.1145/1073814.1073861}, bibsource = {DBLP, http://dblp.uni-trier.de} } % pages = {240-248}, @inproceedings{DBLP:conf/ershov/DennisFL72, author = {Jack B. Dennis and John B. Fosseen and John P. Linderman}, title = {Data flow schemas}, booktitle = {International Sympoisum on Theoretical Programming}, year = {1972}, ee = {http://dx.doi.org/10.1007/3-540-06720-5_15}, bibsource = {DBLP, http://dblp.uni-trier.de} } % pages = {187-216}, @ARTICLE{ArvindNikhil:TaggedToken, author={Arvind and Nikhil, R.S.}, journal={Computers, IEEE Transactions on}, title={{Executing a program on the MIT Tagged-Token Dataflow Architecture }}, year={1990}, month=mar, volume={39}, number={3}, pages={300 -318}, keywords={Id;MIT tagged-token dataflow architecture;compilation;determinacy;dynamic dataflow graphs;fine-grained parallelism;general-purpose high-performance parallel computing;high-level language;multiprocessor architecture;operational semantics;parallel machine language;high level languages;parallel architectures;parallel programming;program compilers;}, doi={10.1109/12.48862}, ISSN={0018-9340},} @inproceedings{DBLP:conf/isca/Arvind81, author = {Arvind}, title = {Data Flow Languages and Architecture}, booktitle = {ISCA}, year = {1981}, pages = {1}, bibsource = {DBLP, http://dblp.uni-trier.de} } @article{DBLP:journals/tc/LeeM87, author = {Edward A. Lee and David G. Messerschmitt}, title = {Static Scheduling of Synchronous Data Flow Programs for Digital Signal Processing}, journal = {IEEE Trans. Computers}, volume = {36}, number = {1}, year = {1987}, pages = {24-35}, bibsource = {DBLP, http://dblp.uni-trier.de} } @ARTICLE{ESLIEEE/Agarwal/ManCheuk/Arvind, author={Agarwal, A. and Man Cheuk Ng and Arvind}, journal={Embedded Systems Letters, IEEE}, title={A Comparative Evaluation of High-Level Hardware Synthesis Using Reed-Solomon Decoder}, year={2010}, month=sept. , volume={2}, number={3}, pages={72 -76}, keywords={C code;HDL;Reed-Solomon decoder;high-level hardware synthesis;Reed-Solomon codes;decoding;hardware description languages;high level synthesis;}, doi={10.1109/LES.2010.2055231}, ISSN={1943-0663},} @inproceedings{DBLP:conf/cc/ThiesKA02, author = {William Thies and Michal Karczmarek and Saman P. Amarasinghe}, title = {StreamIt: A Language for Streaming Applications}, booktitle = {CC}, year = {2002}, ee = {http://link.springer.de/link/service/series/0558/bibs/2304/23040179.htm}, crossref = {DBLP:conf/cc/2002}, bibsource = {DBLP, http://dblp.uni-trier.de} } % pages = {179-196}, @proceedings{DBLP:conf/cc/2002, editor = {R. Nigel Horspool}, title = {Compiler Construction, 11th International Conference, CC 2002, Held as Part of the Joint European Conferences on Theory and Practice of Software, ETAPS 2002, Grenoble, France, April 8-12, 2002, Proceedings}, booktitle = {CC}, publisher = {Springer}, series = {Lecture Notes in Computer Science}, volume = {2304}, year = {2002}, isbn = {3-540-43369-4}, bibsource = {DBLP, http://dblp.uni-trier.de} } @inproceedings{DBLP:conf/ifip/Kahn74, author = {Gilles Kahn}, title = {The Semantics of Simple Language for Parallel Programming}, booktitle = {IFIP Congress}, year = {1974}, pages = {471-475}, bibsource = {DBLP, http://dblp.uni-trier.de} } @MISC{Verilator:www, AUTHOR = {{W. Snyder and P. Wasson, and D. Galbi}}, TITLE = {{Verilator}}, YEAR = {{2007}}, HOWPUBLISHED = {{\texttt{http://www.veripool.com/verilator.html}}}, } @MISC{AutoESL:www, AUTHOR = {{AutoESL Desisgn Technologies, Inc.}}, HOWPUBLISHED = {{\texttt{http://www.autoesl.com}}}, } @MISC{MDC09:Spec, AUTHOR = {{MEMOCode Design Contest}}, TITLE = {{Cartesian-to-Polar Interpolation}}, HOWPUBLISHED = {\texttt{{http://www.ece.cmu.edu/~jhoe/distribution/}} \texttt{mc09contest/contest09.pdf}} } @inproceedings{Strassen:MatrixAlgo, author = {Volker Strassen}, title = {Gaussian Elimination is Not Optimal}, booktitle = {Numerische Mathematik 13}, year = {1969}, pages = {354--356} } @MANUAL{IBM:PLBSpec, TITLE = "The CoreConnect (TM) Bus Architecture", ORGANIZATION = "IBM,~Inc.", YEAR = {1999} } @MISC{Memocode:DesignContest, AUTHOR = {{Forrest Brewer and James C. Hoe}}, TITLE = {{The First MEMOCODE HW/SW Co-design Contest}}, HOWPUBLISHED = {{\texttt{https://memocode07.ece.cmu.edu/contest.html}}}, MONTH = {March}, YEAR = {2007} } @ARTICLE{Volder:CORDIC, AUTHOR = "Jack E. Volder", TITLE = {{The CORDIC Trigonometric Computing Technique}}, JOURNAL = {{IRE Transactions on Electronic Computers}}, VOLUME = {8}, NUMBER = {3}, PAGES = {330--334}, MONTH = {September}, YEAR = {1959} } @article{Ptolemy, author = {Joseph T. Buck and Soonhoi Ha and Edward A. Lee and David G. Messerschmitt}, title = {Ptolemy: A Framework for Simulating and Prototyping Heterogenous Systems}, journal = {Int. Journal in Computer Simulation}, volume = {4}, number = {2}, year = {1994}, pages = {0-}, bibsource = {DBLP, http://dblp.uni-trier.de} } @MISC{PtolemyII, TITLE = {{Ptolomy II}}, AUTHOR = {{Department of EECS, University of California, Berkeley}}, HOWPUBLISHED = {{http://ptolemy.eecs.berkeley.edu/ptolemyII/}}} } @MISC{CatC:www, TITLE = {{Catapult-C}}, AUTHOR = {{Mentor Graphics}}, HOWPUBLISHED = {{{ http://www.mentor.com/products/esl/}}} } @MANUAL{CatC:Manual, TITLE = {{Catapult-C Manual and C/C++ style guide}}, ORGANIZATION = "Mentor Graphics", YEAR = {2004} } @inproceedings{REL:Lime, author = {Huang, Shan Shan and Hormati, Amir and Bacon, David F. and Rabbah, Rodric}, title = {Liquid Metal: Object-Oriented Programming Across the Hardware/Software Boundary}, booktitle = {ECOOP '08: Proceedings of the 22nd European conference on Object-Oriented Programming}, year = {2008}, isbn = {978-3-540-70591-8}, location = {Paphos, Cypress}, doi = {http://dx.doi.org/10.1007/978-3-540-70592-5_5}, address = {Berlin, Heidelberg}, } @article{Metropolis, author = {Felice Balarin and Yosinori Watanabe and Harry Hsieh and Luciano Lavagno and Claudio Passerone and Alberto Sangiovanni-Vincentelli}, title = {Metropolis: An Integrated Electronic System Design Environment}, journal ={Computer}, volume = {36}, issn = {0018-9162}, year = {2003}, pages = {45-52}, doi = {http://doi.ieeecomputersociety.org/10.1109/MC.2003.1193228}, publisher = {IEEE Computer Society}, address = {Los Alamitos, CA, USA}, } @inproceedings{REL:Rapide, author = {David C. Luckham}, title = {Rapide: A Language and Toolset for Causal Event Modeling of Distributed System Architectures}, booktitle = {WWCA}, year = {1998}, bibsource = {DBLP, http://dblp.uni-trier.de} } % pages = {88-96}, @article{REL:Shim, author = {Stephen A. Edwards and Olivier Tardieu}, title = {SHIM: a deterministic model for heterogeneous embedded systems}, journal = {IEEE Trans. VLSI Syst.}, volume = {14}, number = {8}, year = {2006}, pages = {854-867}, ee = {http://doi.ieeecomputersociety.org/10.1109/TVLSI.2006.878473}, bibsource = {DBLP, http://dblp.uni-trier.de} } @inproceedings{Magellan, author = {Karam S. Chatha and Ranga Vemuri}, title = {MAGELLAN: multiway hardware-software partitioning and scheduling for latency minimization of hierarchical control-dataflow task graphs}, booktitle = {CODES}, year = {2001}, pages = {42-47}, ee = {http://doi.acm.org/10.1145/371636.371671}, bibsource = {DBLP, http://dblp.uni-trier.de} } @MISC{Eles97systemlevel, author = {Petru Eles and Zebo Peng and Krzysztof Kuchcinski and Alexa Doboli}, title = {System Level Hardware/Software Partitioning Based on Simulated Annealing and Tabu Search}, year = {1997} } @article{Arato:2005:AAH:1044111.1044119, author = {Arat\'{o}, P\'{e}ter and Mann, Zolt\'{a}n \'{A}d\'{a}m and Orb\'{a}n, Andr\'{a}s}, title = {Algorithmic aspects of hardware/software partitioning}, journal = {ACM Trans. Des. Autom. Electron. Syst.}, volume = {10}, issue = {1}, month = {January}, year = {2005}, issn = {1084-4309}, pages = {136--156}, numpages = {21}, url = {http://doi.acm.org/10.1145/1044111.1044119}, doi = {http://doi.acm.org/10.1145/1044111.1044119}, acmid = {1044119}, publisher = {ACM}, address = {New York, NY, USA}, keywords = {Hardware/software partitioning, graph algorithms, graph bipartitioning, hardware/software codesign, optimization}, } @article{HWCo_Ernst, author = {Ernst, Rolf and Henkel, Jorg and Benner, Thomas}, title = {Hardware-Software Cosynthesis for Microcontrollers}, journal = {IEEE Des. Test}, volume = {10}, number = {4}, year = {1993}, issn = {0740-7475}, pages = {64--75}, doi = {http://dx.doi.org/10.1109/54.245964}, publisher = {IEEE Computer Society Press}, address = {Los Alamitos, CA, USA}, } @INPROCEEDINGS{Edwards:SynthesisFromEsterel, AUTHOR = "Stephen Edwards", TITLE = {{High-Level Synthesis from the Synchronous Language Esterel}}, BOOKTITLE = {{Proceedings of IWLS'02}}, YEAR = {2002}, ADDRESS = {New Orleans,~LA} } @inproceedings{DBLP:conf/concur/BerryC84, author = {G{\'e}rard Berry and Laurent Cosserat}, title = {{The ESTEREL Synchronous Programming Language and its Mathematical Semantics}}, booktitle = {Seminar on Concurrency}, year = {1984}, pages = {389-448}, ee = {http://dx.doi.org/10.1007/3-540-15670-4_19}, bibsource = {DBLP, http://dblp.uni-trier.de} } @INCOLLECTION{Berry:EsterelOnHW, AUTHOR = "G\'erard Berry", TITLE = {{Esterel on hardware}}, BOOKTITLE = {{Mechanized Reasoning and Hardware Design}}, PAGES = {87--104}, PUBLISHER = {Prentice Hall}, YEAR = {1992}, ADDRESS = {Hertfordshire,~UK} } @MISC{Synfora:www, TITLE = {{PICO Platform}}, AUTHOR = {{Synfora}}, HOWPUBLISHED = {{\texttt{http://www.synfora.com/}}} } @MISC{coware:www, TITLE = {{ESL Coware 2.0}}, HOWPUBLISHED = {{\texttt{http://www.coware.com/}}} } @MISC{carbon:www, TITLE = {{Carbon Design Systems Inc}}, HOWPUBLISHED = {{\texttt{http://carbondesignsystems.com}}} } @MISC{UIO:Howto, TITLE = {{The Userspace I/O HOWTO}}, HOWPUBLISHED = {{https://www.kernel.org/doc/htmldocs/uio-howto/index.html}}} @techreport{Khalidi:1995:EZI:974947, author = {Khalidi, Yousef A. and Thadani, Moti N.}, title = {{An Efficient Zero-Copy I/O Framework for UNIX}}, year = {1995}, publisher = {Sun Microsystems, Inc.}, address = {Mountain View, CA, USA}, } @inproceedings{Agrawal:2008:DTS:1404014.1404019, author = {Agrawal, Nitin and Prabhakaran, Vijayan and Wobber, Ted and Davis, John D. and Manasse, Mark and Panigrahy, Rina}, title = {Design Tradeoffs for SSD Performance}, booktitle = {USENIX 2008 Annual Technical Conference on Annual Technical Conference}, series = {ATC'08}, year = {2008}, location = {Boston, Massachusetts}, pages = {57--70}, numpages = {14}, url = {http://dl.acm.org/citation.cfm?id=1404014.1404019}, acmid = {1404019}, publisher = {USENIX Association}, address = {Berkeley, CA, USA}, } @MISC{dmabuf, author = {Semwal, Sumit}, title = {{DMA Buffer Sharing API Guide}}, howpublished = {https://www.kernel.org/doc/Documentation/dma-buf-sharing.txt}} @inproceedings{King:2012:AGH:2150976.2151011, author = {King, Myron and Dave, Nirav and Arvind}, title = {Automatic Generation of Hardware/Software Interfaces}, booktitle = {Proceedings of the Seventeenth International Conference on Architectural Support for Programming Languages and Operating Systems}, series = {ASPLOS XVII}, year = {2012}, isbn = {978-1-4503-0759-8}, location = {London, England, UK}, pages = {325--336}, numpages = {12}, url = {http://doi.acm.org/10.1145/2150976.2151011}, doi = {10.1145/2150976.2151011}, acmid = {2151011}, publisher = {ACM}, address = {New York, NY, USA}, keywords = {hardware/software codesign}, } ================================================ FILE: doc/library/source/design/related-work.rst ================================================ .. _Sec:RelWork Related Work ============ A number of research projects, such as Lime~\cite{REL:Lime}, BCL~\cite{King:2012:AGH:2150976.2151011}, HThreads~\cite{DBLP:conf/fpl/PeckAASBA06}, and CatapaultC~\cite{CatC:www} (to name just a few) bridge the software/hardware development gap by providing a single language for developing both the software and hardware components of the design. In addition, Altera and Xilinx have both implemented OpenCL~\cite{Opencl} on FPGAs~\cite{AlteraOpencl,XilinxOpencl} in an attempt to attract GPU programmers. The computation model of software differs significantly from that of hardware, and so far none of the unified language approaches deliver the same performance as languages designed specifically for hardware or software. Connectal is intended to be used for the design of performance-critical systems. In this context we think that designers prefer a mix of languages specifically designed for their respective implementation contexts. Infrastructures such as LEAP~\cite{DBLP:conf/fpl/FlemingYAE14}, Rainbow~\cite{DBLP:journals/ijrc/JozwikHETT13}, and OmpSs~\cite{DBLP:conf/fpga/FilguerasGJAMLNV14} (to name just a few) use resource abstraction to enable FPGA development. We found that in their intended context, these tools were easy to use but that performance tuning in applications not foreseen by the infrastructure developers was problematic. Some projects such as TMD-MPI~\cite{DBLP:journals/trets/SaldanaPMNWCWSP10}, VFORCE/ \\VSIPL++~\cite{DBLP:journals/jpdc/MooreLK12}, and GASNet/GAScore~\cite{DBLP:conf/fpga/WillenbergC13} target only the hardware software interface. These tools provide message passing capabilities, but rely on purely operational semantics to describe the HW/SW interface. Apart from the implementation details, Connectal distinguishes itself by using an IDL to enforce denotational interface semantics. UIO~\cite{UIO:Howto} is a user-space device driver framework for Linux. It is very similar to the Connectal's portal device driver, but it does not provide a solution to multiple device nodes per hardware device. The portal driver provides this so that different interfaces of a design may be accessed independently, providing process boundary protection, thread safety, and the ability for user processes and the kernel both to access the hardware device. ================================================ FILE: doc/library/source/design/string-search.rst ================================================ .. _Sec-StrStr: Accelerating String Search ========================== The structure of a hardware/software (HW/SW) system can evolve quite dramatically to reflect changing requirements, or during design exploration. In this section, we consider several different implementations of a simple string search application~\cite{mpAlgo}. Each variation represents a step in the iterative refinement process, intended to enhance performance or enable a different software execution environment. \begin{figure}[!h] \centering \includegraphics[width=0.43\textwidth]{platform.pdf} \caption{\label{Fig:Platform0}Target platform for string search application} \end{figure} Figure~\ref{Fig:Platform0} shows the target platform for our example. The pertinent components of the host system are the multi-core CPU, system memory, and PCI Express (PCIe) bus. The software components of our application will be run on the CPU in a Linux environment. Connected to the host is a PCIe expansion card containing (among other things) a high-performance FPGA chip and a large array of flash memory. The FPGA board was designed as a platform to accelerate ``big data'' analytics by moving more processing power closer to the storage device. .. _Sec:StrStrInitial: Initial Implementation ---------------------- \begin{figure}[!h] \centering \includegraphics[width=0.43\textwidth]{data_accel_logical0.pdf} \caption{\label{Fig:StringSearch0}Logical components of the string search system} \end{figure} The design process really begins with a pure software implementation of the algorithm, but the first attempt we consider is the initial inclusion of HW acceleration shown in Figure~\ref{Fig:StringSearch0}. The search functionality is executed by software running in user-space which communicates with the hardware accelerator through a device driver running in the Linux kernel. The hardware accelerator, implemented in the FPGA fabric, executes searches over data stored in the flash array as directed by the software. The FPGA has direct access to the massive flash memory array, so if we implement the search kernel in hardware, we can avoid bringing data into the CPU cache (an important consideration if we intend to run other programs simultaneously). By exploiting the high parallelism of the execution fabric as well as application aware caching of data, an FPGA implementation can outperform the same search executed on the CPU. Multithreading the Software --------------------------- The efficient use of flash memory requires a relatively sophisticated management strategy. Our first refinement is based on the observation that there are four distinct tasks which the application software executes (mostly) independently: * Send search command to the hardware. * Receive search results from the hardware. * Send commands to the hardware to manage the flash arrays * Receive responses from the flash management hardware To exploit the task-level parallelism in our application, we can assign one thread to each of the four enumerated tasks. To further improve efficiency, the two threads receiving data from the hardware put themselves to sleep by calling \textbf{poll} and are woken up only when a message has been received. \begin{figure}[!h] \centering \includegraphics[width=0.43\textwidth]{data_accel_logical1.pdf} \caption{\label{Fig:StringSearch1}Using a mutex to coordinate user-level access to hardware accelerator} \end{figure} With the introduction of multithreading, we will need a synchronization mechanism to enforce coherent access to the hardware resources. Because the tasks which need coordinating are all being executed as user-space threads, the access control must be implemented in software as well. As shown in Figure~\ref{Fig:StringSearch1}, a mutex is used to coordinate access to the shared hardware resource between user-level processes. .. _Sec:StrStrRefiningInterfaces: Refining the Interfaces ----------------------- \begin{figure}[!h] \centering \includegraphics[width=0.43\textwidth]{data_accel_logical2.pdf} \caption{\label{Fig:StringSearch2}Movement of functionality from user to kernel space. Software-based coordination between kernel and user processes are prohibitively expensive.} \end{figure} Figure~\ref{Fig:StringSearch2} shows a further refinement to our system in which we have reimplemented the Flash Management functionality as a block-device driver. Instead of directly operating on physical addresses, the string search now takes a file descriptor as input and uses a Linux system-call to retrieve the file block addresses through the file system. This refinement permits other developers to write applications which can take advantage of the accelerator without any knowledge of the internal details of the underlying storage device. It also enables support for different file systems as we now use a POSIX interface to generate physical block lists for the the storage device hardware. The problem with this refinement is that we no longer have an efficient SW mechanism to synchronize the block device driver running in kernel space with the application running in user space. \begin{figure}[htb] \centering \includegraphics[width=0.43\textwidth]{data_accel_logical3.pdf} \caption{\label{Fig:StringSearch3}Correct interface design removes the need for coordination between user and kernel threads.} \end{figure} To solve to this problem (shown in Figure~\ref{Fig:StringSearch3}), we can remove the need for explicit SW coordination altogether by giving each thread uncontested access to its own dedicated HW resources mapped into disjoint address regions. (There will of course be implicit synchronization through the file system.) .. _Sec:StrStrDma: Shared Access to Host Memory ---------------------------- In the previous implementations, all communication between hardware and software takes place through memory mapped register IO. Suppose that instead of searching for single strings, we want to search for large numbers of (potentially lengthy) strings stored in the flash array. Attempting to transfer these strings to the hardware accelerator using programmed register transfers introduces a performance bottleneck. In our final refinement, the program will allocate memory on the host system, populate it with the search strings, and pass a reference to this memory to the hardware accelerator which can then read the search strings directly from the host memory. \begin{figure}[htb] \centering \includegraphics[width=0.43\textwidth]{data_accel_logical4.pdf} \caption{\label{Fig:StringSearch4}Connectal support for DMA.} \end{figure} Efficient high-bandwidth communication in this style requires the ability to share allocated memory regions between hardware and software processes without copying. Normally, a programmer would simply call application space \textbf{malloc}, but this does not provide a buffer that can be shared with hardware or other software processes. As shown in Figure~\ref{Fig:StringSearch4}, a special-purpose memory allocator has been implemented in Linux, using dmabuf\cite{dmabuf} to provide reference counted sharing of memory buffers across user processes and hardware. To conclude, we consider how the HW/SW interface changed to accommodate each step in the refinement process: The hardware interface required by the design in Figure~\ref{Fig:StringSearch0} is relatively simple. Command/response queues in the hardware accelerator are exposed using a register interface with accompanying *empty*/*full* signals. To support the use of *poll* by the refinement in Figure~\ref{Fig:StringSearch1}, interrupt signals must be added to the hardware interface and connected to the Linux kernel. Partitioning the address space as required by the refinement in Figure~\ref{Fig:StringSearch3} necessitates a consistent remapping of registers in both hardware and software. ================================================ FILE: doc/library/source/design/toolchain.rst ================================================ .. _Sec:Toolchain: Workflow using Connectal ======================== In this section, we give an overview of the Connectal workflow and toolchain. The complete toolchain, libraries, and many running examples may be obtained at \textit{www.connectal.org} or by emailing \textit{connectal@googlegroups.com}. Top level structure of Connectal applications --------------------------------------------- The simplest Connectal application consists of 4 files: Makefile ^^^^^^^^ The top-level Makefile defines parameters for the entire application build process. In its simplest form, it specifies which Bluespec interfaces to use as portals, the hardware and software source files, and the libraries to use for the hardware and software compilation. Application Hardware ^^^^^^^^^^^^^^^^^^^^ Connectal applications typically have at least one BSV file containing declarations of the interfaces being exposed as portals, along with the implementation of the application hardware itself. Top.bsv ^^^^^^^ In this file, the developer instantiates the application hardware modules, connecting them to the generated wrappers and proxies for the portals exported to software. To connect to the host processor bus, a parameterized standard interface is used, making it easy to synthesize the application for different CPUs or for simulation. If CPU specific interface signals are needed by the design (for example, extra clocks that are generated by the PCIe core), then an optional CPU-specific interface can also be used. If the design uses multiple clock domains or additional pins on the FPGA, those connections are also made here by exporting a 'Pins' interface. The Bluespec compiler generates a Verilog module from the top level BSV module, in which the methods of exposed interfaces are implemented as Verilog ports. Those ports are associated to physical pins on the FPGA using a physical constraints file. Application CPP ^^^^^^^^^^^^^^^ The software portion of a Connectal application generally consists of at least one C++ file, which instantiates the generated software portal wrapper and proxies. The application software is also responsible for implementing main. Development cycle ------------------ After creating or editing the source code for the application, the development cycle consists of four steps: generating makefiles, compiling the interface, building the application, and running the application. Generating Makefiles ^^^^^^^^^^^^^^^^^^^^ Given the parameters specified in the application Makefile and a platform target specified at the command line, Connectal generates a target-specific Makefile to control the build process. This Makefile contains the complete dependency information for the generation of wrappers/proxies, the use of these wrappers/proxies in compiling both the software and hardware, and the collection of build artifacts into a package that can be either run locally or over a network to a remote 'device under test' machine. Compiling the Interface ^^^^^^^^^^^^^^^^^^^^^^^ The Connectal interface compiler generates the C++ and BSV files to implement wrappers and proxies for all interfaces specified in the application Makefile. Human readable \textbf{JSON} is used as an intermediate representation of portal interfaces, exposing a useful debugging window as well as a path for future support of additional languages and IDLs. Building the Application ^^^^^^^^^^^^^^^^^^^^^^^^ A target in the generated Makefile invokes GCC to compiler the software components of the application. The Bluespec compiler (bsc) is then invoked to compiler the hardware components to Verilog. A parameterized Tcl scripts is used to drive Vivado to build the Xilinx FPGA configuration bitstream for the design. A Connectal utility called `fpgamake`_ supports specification of which Bluespec and Verilog modules should be compiled to separate netlists and to enable separate place and route of those netlists given a floor plan. Separate synthesis and floor planning in this manner can reduce build times, and to make it easier to meet timing constraints. Another Connectal utility called `buildcache`_ speeds recompilation by caching previous compilation results and detecting cases where input files have not changed. Although similar to the better-known utility \textit{ccache}, this program has no specific knowledge of the tools being executed, allowing it to be integrated into any workflow and any tool set. This utility uses the system call \textbf{strace} to track which files are read and written by each build step, computing an 'input signature' of the MD5 checksum for each of these files. When the input signature matches, the output files are just refreshed from the cache, avoiding the long synthesis times for the unchanged portions of the project. Running the Application ^^^^^^^^^^^^^^^^^^^^^^^ As part of our goal to have a fully scripted design flow, the generated Makefile includes a \texttt{run} target that will program the FPGA and launch the specified application or test bench. In order to support shared target hardware resources, the developer can direct the run to a particular machines, which can be accessed over the network. For Ubuntu target machines, ssh is used to copy/run the application. For Android target machines, 'adb' is used. Continuous Integration and Debug Support ---------------------------------------- Connectal provides a fully scripted flow in order to make it easy to automate the building and running of applications for continuous integration. Our development team builds and runs large collections of tests whenever the source code repository is updated. Connectal also provides trace ring buffers in hardware and analysis software to trace and display the last transactions on the PCIe or AXI memory bus. This trace is useful when debugging performance or correctness problems, answering questions of the form: * What were the last memory requests and responses? * What was the timing of the last memory request and responses? * What were the last hardware method invocations or indications? .. _fpgamake: https://github.com/cambridgehackers/fpgamake .. _buildcache: https://github.com/cambridgehackers/buildcache ================================================ FILE: doc/library/source/devguide/clocks.rst ================================================ .. _devguide_clocks: *************************************** Clocking Your Design *************************************** Every board has a main clock, which is the clock exposed by "exposeCurrentClock". It has a default value, but that value can be overriden with CONNECTALFLAG --mainclockperiod, which is an integer specified in nanoseconds. There is a second clock available, which I called "derivedClock" because it was derived from the main clock. You can specify its clock period with --derivedclockperiod, which is a float specified in nanoseconds. I'm using an MMCM, which has one clock specified by a fractional divisor. On PCIe-connected boards, the main clock frequency defaults to the PCIe user clock frequency (125MHz for gen1, 250MHz for gen2). But you can override that, in which case your hardware is connected to PCIe via sync FIFOs. You are responsible for any synchronization required between the main and derived clock domains. There are two ways to get access to the derivedClock in your design. IMPORT_HOST_CLOCKS ================== This is simpler, and preserves the synthesis boundary on mkConnectalTop. See examples/echoslow In the Makefile CONNECTALFLAGS += -D IMPORT_HOST_CLOCKS Add ":host.derivedClock,host.derivedReset" to H2S_INTERFACES: H2S_INTERFACES = Echo:EchoIndication:host.derivedClock,host.derivedReset Or just pass in host.derivedClock and create a reset locally. Look at the generated /generatedbsv/Top.bsv to see how this changed the generated code. IMPORT_HOSTIF ============= This option is only useful for Zynq, in order to get access to other PS7 interfaces and clocks that are not part of the standard portal interface, e.g., I2C. CONNECTALFLAGS += -D IMPORT_HOSTIF Add ":host" to H2S_INTERFACES. See tests/test_sdio1 for an example of the use of IMPORT_HOSTIF, though it has a manually written Top.bsv. Setting Zynq Clock Speeds ========================= Default Clock Speeds ==================== The default values for --mainclockperiod and --derivedclockperiod for the each board are in the JSON files in the boardinfo directory. ================================================ FILE: doc/library/source/devguide/compilingproject.rst ================================================ .. _compiling_a_project: *************************************** Compiling and Running Connectal Project *************************************** Compiling on ConnectalBuild =========================== The Connectal toolchain can be run on ConnectalBuild using the following Buildbot web interface: http://connectalbuild.qrclab.com/projects. .. image:: connectalbuild-1.png *Before submitting a project, you must sign in using your github credentials.* We do not store credentials, but pass them througth to github. Next, enter a name for the project, which will be used for subsequent build requests through the Buildbot web interface. The project must be in a publicly accessible git-hub repository, whose Repo location is entered beginning with `git://`_ as follows `git://github.com/connectal-examples/leds.git`_. If the project makefile is not in the root directory of the repository, enter its relative path in the 'Path' field of the form. If a particular branch or revision number are desired, enter these as well. Check the button to select the build target. If you have selected a zynq-based platform and would like the tool-chain to automatically program the device and execute the design as its final step, then enter the IP address of your board. This works only because ``adb`` doesn't require authentication. SSH keys required to run on PCIe-based platforms are not currently supported. Finally, don't forget to click 'Add'. If the project name has already been used, you will be prompted to enter a new one at this point. Compiling Locally ================= Before compiling a project locally, you will need to install the toolchain. After setting the ``CONNECTALDIR`` to the root of the connectal source tree, enter the command ``make`` Running the Design ================== When preparing a zedboard: * Following the directions in the zynq-boot git repo, create an Android boot SD card files. * Write the SD card files into the first partition of an SD card (FAT format). * Verify that the boot mode jumpers on the board are JP8/9/10 (MIO3/4/5) == 110 for booting from SD card. * Verify that the PS_MIO0 pull-down jumper on the board JP6 is shorted. * Connect a USB cable to the 'UART' connector. Use the 'connectable' program from the connectable git repo to display linux console output. * Connect an ethernet cable (linux uses DHCP to get an IP address during boot). When preparing a PCIe board: * Attach a USB cable to the JTAG port .. _git://: git:// .. _git://github.com/connectal-examples/leds.git: git://github.com/connectal-examples/leds.git ================================================ FILE: doc/library/source/devguide/design.rst ================================================ Connectal Rationale =================== Are you happy with the connection between software development and hardware development on your projects? Do you wish you had more flexible tools for developing test benches, drivers, and applications using your hardware? Do you wish you didn't need a kernel driver? Do you wish that you could use a common flow to drive your hardware development, across simulation, timing verification, FPGA implementation, and even the ASIC back end? Do you wish you could use a better programming language to implement the hardware? Do you miss declared interfaces and structural types? Do you wish you had better tools for debugging the hardware? For reflecting conditions encountered on the hardware back into the simulation environment where you can drill down into the problem? These are the kinds of problems we encountered which inspired us to develop the Connectal framework. With Connectal, we are trying to bring the productivity of software engineering practices to hardware development without compromising on the performance of the hardware. Connectal provides: * Seamless development environment with test benches and apps written in C/C++ * Streamlined application structure * Faster builds and greater visibility simulating hardware in bluesim/modelsim/xsim * Support for capture traces on interfaces and replaying them in test benches ================================================ FILE: doc/library/source/devguide/devguide.rst ================================================ Connectal Developer's Guide =========================== .. toctree:: :maxdepth: 2 design.rst projectstructure.rst compilingproject.rst clocks.rst ================================================ FILE: doc/library/source/devguide/projectstructure.rst ================================================ Connectal Project Structure *************************** The set of files composing the input to the Connectal toolchain is referred to as a project. A collection of out-of-tree example projects is available at https://github.com/connectal-examples. To illustrate the structure of a project, this chapter uses the example https://github.com/connectal-examples/leds, which can be executed on the Bluesim or Zynq target platforms. Project Makefile ================ The top-level Makefile in the project (in our example, https://github.com/connectal-examples/leds/blob/master/Makefile) defines parameters building and executing the project. In its simplest form, it specifies the hardware and software source files, which Bluespec interfaces to use as interfaces (portals) between them, and the libraries to use for the hardware and software compilation:: INTERFACES = LedControllerRequest BSVFILES = LedController.bsv Top.bsv CPPFILES= testleds.cpp include \$(CONNECTALDIR)/Makefile.connectal ``BSVFILES`` is a list of bsv files containing interface definitions used to generate portals and module definitions used to generate HW components. Connectal bsv libraries can be used without being listed explicitly. ``CPPFILES`` is a list of C/C++ files containing software components and ``main``. The Connectal C/C++ libraries can be used without being listed explicitly. ``INTERFACES`` is a list of names of BSV interfaces which may be used to communicate between the HW and SW componentsy. In addition to user-defined interfaces, there are a wide variety of interfaces defined in Connectal libraries which may be included in this list. ``NUMBER_OF_MASTERS`` is used to designate the number of host bus masters the hardware components will instantiate. For PCIe-based platforms, this value can be set to 1, while on Zynq-based platforms values from 1 to 4 are valid. ``CONNECTALDIR`` must be set so that the top-level Connectal makefile can be included, defining the makefile build targets for the project. This brings in the default definitions of all project build parameters as well as the Connectal hardware and software libraries. When running the toolchain on AWS, this varible is set automatically in the build environment. (See :ref:`compiling_a_project`) Project Source ============== Interface Definitions --------------------- \label{interface_definitions} When generating portals, the Connectal interface compiler searches the Connectal bsv libraries and the files listed in ``BSVFILES`` for definitions of the interfaces listed in ``INTERFACES``. If the definition of a listed interfaces is not found, an error is reported and the compilation aborts. The interfaces in this list must be composed exclusively of ``Action`` methods. Supported method argument types are ``Bit\#(n)``, ``Bool``, ``Int\#(32)``, ``UInt\#(32)``, ``Float``, ``Vector\#(t)``, ``enum``, and ``struct``. Software -------- The software in a Connectal project consists of at least one C++ file which instantiates the generated portal wrappers and proxies and implements ``main()``. The following source defines the SW component of the example, which simply toggles LEDs on the Zedboard (\url{https://github.com/connectal-examples/leds/blob/master/testleds.cpp}):: #include #include "LedControllerRequest.h" #include "GeneratedTypes.h" int main(int argc, const char **argv) { LedControllerRequestProxy *device = new LedControllerRequestProxy(IfcNames_LedControllerRequest); for (int i = 0; i < 20; i++) { device->setLeds(10, 10000); sleep(1); device->setLeds(5, 10000); sleep(1); } } The makefile listed ``LedControllerRequest`` as the only communication interface. The generated proxies and wrappers for this interface are in ``LedControllerRequest.h`` which is included, along with C++ implementations of all additional interface types in ``GeneratedTypes.h``. Line 9 instantiates the proxy through which the software invokes the hardware methods (See also :ref:`flow_control`) To support projects that will execute software inside the linux kernel (for example, to work in conjunction with filesystems or the network stack), connectal project software can also be written in C. Hardware ========= Connectal projects typically have at least one BSV file containing interface declarations and module definitions. The implementation of the interfaces and all supporting infrastructure is standard BSV. Interfaces being used as portals are subject to the type restrictions described earlier (See also :ref:`interface_definitions`) Top.bsv ------- In Top.bsv (https://github.com/connectal-examples/leds/blob/master/Top.bsv), the developer instantiates all hardware modules explicitly. Interfaces which can be invoked through portals need to be connected to the generated wrappers and proxies. To connect to the host processor bus, a parameterized standard interface is used, making it easy to synthesize the application for different CPUs or for simulation:: // Connectal Libraries import CtrlMux::*; import Portal::*; import Leds::*; import MemTypes::*; import MemPortal::*; import HostInterface::*; import LedControllerRequest::*; import LedController::*; typedef enum {LedControllerRequestPortal} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(PhysAddrWidth)); LedController ledController <- mkLedControllerRequest(); LedControllerRequestWrapper ledControllerRequestWrapper <- mkLedControllerRequestWrapper(LedControllerRequestPortal, ledController.request); Vector#(1,StdPortal) portals; portals[0] = ledControllerRequestWrapper.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; interface leds = ledController.leds; endmodule Like the SW components, the HW begins by importing the generated wrappers and proxies corresponding to the interfaces listed in the project Makefile. The user-defined implementation of the LedControllerRequest interface is instantiated on line 14, and wrapped on line 15. This wrapped interface is connected to the bus using the library module ``mkSlaveMux`` on line 21 so it can be invoked from the software. At the end of the module definition, the top-level interface elements must be connected. A board-specific top-level module will include this file, instantiate ``mkConnectalTop`` and connect the interfaces to the actual peripherals. The module ``mkConnectalTop`` must be defined in a file named ``Top.bsv`` in the user project. The Bluespec compiler generates a Verilog module from the top level BSV module, in which the methods of exposed interfaces are implemented as Verilog ports. Those ports are bound to physical pins on the FPGA using a physical constraints file. If CPU specific interface signals are needed by the design (for example, extra clocks that are generated by the PCIe core), then an optional CPU-specific HostInterface parameter to ``mkConnectalTop`` can also be used. If the design uses external pins on the FPGA, those connections are also made here by exporting a 'Pins' interface (\hyperref[host_interface]{Section~\ref{host_interface}}) and providing bindings in the constraints file. ================================================ FILE: doc/library/source/examples/index.rst ================================================ Connectal Examples ================== .. toctree:: :maxdepth: 2 simple.rst ================================================ FILE: doc/library/source/examples/simple.rst ================================================ Simple Example ============== ================================================ FILE: doc/library/source/index.rst ================================================ .. connectal documentation master file, created by sphinx-quickstart on Tue Nov 25 12:27:26 2014. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. ===================================== Welcome to connectal's documentation! ===================================== Contents -------- .. toctree:: :maxdepth: 2 intro.rst installation.rst design/design.rst devguide/devguide.rst make.rst tools/tools.rst bsv/bsv.rst c/c.rst examples/index.rst Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` ================================================ FILE: doc/library/source/installation.rst ================================================ ============ Installation ============ Installing Connectal from Packages ----------------------------------- On Ubuntu systems, connectal may be installed from pre-built packages:: sudo add-apt-repository -y ppa:jamey-hicks/connectal sudo apt-get update sudo apt-get -y install connectal Installing Connectal from Source -------------------------------- Connectal source comes from three repositories:: git clone git://github.com/cambridgehackers/connectal git clone git://github.com/cambridgehackers/fpgamake git clone git://github.com/cambridgehackers/buildcache To use Connectal to build hardware/software applications, some additional packages are required:: cd connectal; sudo make install-dependences Installing Connectal and Bluespec on CentOS 7 --------------------------------------------- The following dependencies were needed on CentOS:: sudo yum install gmp glibc-devel autoconf gperf compat-libstdc++-33 CentOS does not have an iverilog packages, but it can be build from source, following the instructions in its repository: * https://github.com/steveicarus/iverilog.git Installing Connectal Drivers and PCI Express Utilities: ------------------------------------------------------- To run Connectal applications on FPGAs attached via PCI Express, a couple of device drivers have to be built and installed:: cd connectal; make all && sudo make install In addition, you will need to build and install fpgajtag and pciescan:: git clone git://github.com/cambridgehackers/pciescan (cd pciescan; make && sudo make install) git clone git://github.com/cambridgehackers/fpgajtag (cd fpgajtag; make && sudo make install) Installing Vivado ----------------- Download Vivado from Xilinx: http://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/2015-4.html Connectal builds do not use the Vivado SDK. Installing Ubuntu on Zynq (Zedboard, etc) ----------------------------------------- The shorthand instructions are: * Follow the instructions to install Ubuntu for Raspberry Pi 2 on and SD Card * Copy a Zedboard boot.bin to the first (VFAT) partition of the SD Card * Boot the Zedboard * Default password for user "ubuntu" is "ubuntu" Toolchain ^^^^^^^^^ Zynq contains dual ARM Cortex A9 cores, which are 32-bit processors using the ARMv7 instruction set. They are compatible with the toolchain used for Raspberry Pi 2, which has prefix "arm-linux-gnueabihf". The "eabi" suffix indicates the ARM extended application binary interface standard. The "hf" suffix indicates that the toolchain generates floating point instructions rather than subroutine calls to emulate floating point, because not all 32-bit ARM processors have floating point units. Download the base image ^^^^^^^^^^^^^^^^^^^^^^^ Download the Ubuntu SD card image: * http://cdimage.ubuntu.com/ubuntu/releases/16.04/release/ubuntu-16.04-preinstalled-server-armhf+raspi2.img.xz Which is referenced on this page: * https://wiki.ubuntu.com/ARM/RaspberryPi Formatting and SD Card for Ubuntu ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ubuntu 16.04 uses filesystem labels to determine which partitions to mount. There should be two partitions, with the following labels: * system-boot The first partition should be vfat so that the firmware in the Zynq ROM can read it to find boot.bin. The following command will format the partition and label it:: mkfs -t vfat -n system-boot /dev/sdb1 * cloudimg-rootfs The second partition should be a Linux filesystem (default ext4) containing the ubuntu installation. The following two commands will format a partition and label it:: mkfs -t ext4 /dev/sdb2 e2label /dev/sdb2 cloudimg-rootfs Install a boot.bin file ^^^^^^^^^^^^^^^^^^^^^^^ See the instructions at https://github.com/cambridgehackers/zynq-boot Configuring a Linux Kernel for Ubuntu 16.04 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I had to change the kernel configuration to suppport systemd, the init system used in Ubuntu 16.04. To be written ... ================================================ FILE: doc/library/source/intro.rst ================================================ ============ Introduction ============ Introduction goes here. ================================================ FILE: doc/library/source/make.rst ================================================ ======================= Connectal Makefile Variables ======================= .. toctree:: :maxdepth: 2 :numbered: makefile.connectal.rst makefile.connectal.build.rst ================================================ FILE: doc/library/source/makefile.connectal.build.rst ================================================ Makefile.connectal.build ======================== The target Makefile, which generated by makefilegen.py (which is invoked by Makefile.connectal), includes Makefile.connectal.build. Make targets ------------ .. make:target:: bits Builds the FPGA bitstream. .. make:target:: exe Builds the application software (executable or shared library). .. make:target:: run Programs the FPGA and Runs the application. Board-specific targets ---------------------- .. make:target:: ubuntu.exe Builds the application for boards using Ubuntu/Debian/CentOS Linux. Also used with xsim. .. make:target:: android.exe Builds the application for boards using Android (e.g., zedboard). .. make:target:: bsim_exe Builds the application for use with bluesim .. make:target:: bsim Builds the hardware for Bluespec bluesim simulator .. make:target:: xsim Builds the hardware for Xilinx xsim simulator Environment Variables --------------------- .. envvar:: RUNPARAM Specifies the name or address of the host on which to run the application. .. envvar:: NOFPGAJTAG (Deprecated, use :envvar::`NOPROGRAM`. See also See also :c:data:`noprogram`.) If NOFPGAJTAG is defined, then fpgajtag is not called by ubuntu.exe or android.exe. .. envvar:: NOPROGRAM If NOPROGRAM is defined, then the FPGA is not automatically programmed by ubuntu.exe or android.exe. See also :c:data:`noprogram`. Variables Controlling the Build ------------------------------- .. make:var:: V Binding V=1 makes the build verbose, displaying the commands that are run while building the project. .. make:var:: CONNECTAL_SHARED Bind to 1 to build a shared library instead of an executable application. .. make:var:: CONNECTAL_NOHARDWARE Binding to 1 suppresses creation of FPGA bitstream. .. make:var:: CONNECTAL_NDK_PARAM Specifies options to pass to ndk-build. Variables Controlling the Bluespec Compiler ------------------------------------------- .. make:var:: BSCOPTFLAGS Specifies bsc optimization flags. .. make:var:: BSCPATHFLAGS Specifies directories used to store output files from Bluespec compilation. .. make:var:: BSCFLAGS_COMMON Specifies Connectal-specific bsc flags. .. make:var:: BSCFLAGS_PROJECT Specifies project-specific bsc flags, -p argument passed to makefilegen.py via CONNECTALFLAGS. .. make:var:: BSCFLAGS_EXTRA Specifies additional flags to pass to bsc. Verilator-related Variables ------------------------- .. make:var:: VERILATOR_PROJECT_ARGS Flags passed to verilator when compiling verilog for simulation. For example, to enable saving signal traces to a VCD file, add the following to your project's Makefile:: CONNECTALFLAGS += -DVERILATOR_PROJECT_ARGS="--trace" Bluesim-related Variables ------------------------- .. make:var:: BSC_CXXFLAGS CXXFLAGS passed to C++ compiler when building application for bluesim target Vivado-related Variables ------------------------ .. make:var:: VIVADOFLAGS Specifies options to pass when running vivado. Buildcache related Variables ---------------------------- .. make:var:: USE_BUILDCACHE Bind to 1 to use buildcache. Variables Controlling the Application ------------------------------------- .. make:var:: CONNECTAL_DEBUG Bind CONNECTAL_DEBUG=1 to run the application under gdb. .. make:var:: RUN_ARGS Specifies arguments to pass to the application when invoking it. ================================================ FILE: doc/library/source/makefile.connectal.rst ================================================ Makefile.connectal ================== A Connectal design imports Makefile.connectal into its Makefile in order to drive the build. A number of variables are used to control the build and parameters of the design. Environment Variables --------------------- .. envvar:: CONNECTALDIR Points to the location where Makefile.connectal and the connectal tools are installed. Make Variables Defining the Application --------------------------------------- .. make:var:: BOARD This is typically set from the suffix of the build target, e.g., make build.zedbard defines BOARD=zedboard. .. make:var:: INTERFACES Specifies for which interfaces to generate c/c++/bsv proxies and wrappers. .. make:var:: NUMBER_OF_MASTERS Number of DMA masters in the design. Defaults to 1. .. make:var:: PIN_TYPE BSV interface of exported pins. Defaults to Empty. BSV type bsv:typedef::PinType is defined from PIN_TYPE. .. make:var:: PIN_TYPE_INCLUDE Which BSV package to import to get the declaration of PIN_TYPE. .. make:var:: PINOUT_FILE Which pin usage JSON files to pass to makefilegen.py as :option::`--pinout` options. .. make:var:: BSVFILES Lists the BSV files to scan when processing INTERFACES. .. make:var:: CPPFILES Lists the C/C++ files that implement the application. .. make:var:: CPPFILES2 Lists the C/C++ files that implement the (optional) second executable of an application. For example, a daemon that coordinates access to the hardware. .. make:var:: PORTAL_DUMP_MAP Specifies the option to provide to pcieflat to annotate PCIe traces with portal numbers and method names. Uses generatedDesignInterfaceFile.json. Auto Top -------- .. make:var:: S2H_INTERFACES .. make:var:: H2S_INTERFACES .. make:var:: MEM_READ_INTERFACES .. make:var:: MEM_WRITE_INTERFACES Controlling the Build --------------------- .. make:var:: CONNECTALFLAGS Flags to pass to makefilegen.py. See :ref:`_invocation_makefilegen.py` for its options. .. make:var:: V Controls verbosity of the build. V=1 for verbose. .. make:var:: USE_BUILDCACHE Define USE_BUILDCACHE=1 to use buildcache. Except fpgamake seems to use buildcache anyway. .. make:var:: BUILDCACHE Location of buildcache script. .. make:var:: BUILDCACHE_CACHEDIR To specify an alternate location for the buildcache cache files. .. make:var:: IPDIR Specifies into which directory to generate IP cores. This allows generated cores to be shared between designs when the FPGA part and core parameters match. .. make:var:: MAIN_CLOCK_PERIOD Bound to the clock period, in nanoseconds, of the clock domain of mkConnectalTop. Defaults to 8ns for vc707 and kc705. Defaults to 10ns for zedboard. Defaults to 5ns for zc706. .. make:var:: DEFAULT_DERIVED_CLOCK_PERIOD Bound to the default clock period, in nanoseconds, of the derived clock provided via HostInterface to mkConnectalTop. Defaults to half the period, twice the frequency of the main clock. .. make:var:: DERIVED_CLOCK_PERIOD Bound to the clock period, in nanoseconds, of the derived clock provided via HostInterface to mkConnectalTop. Defaults to DEFAULT_DERIVED_CLOCK_PERIOD. .. make:var:: BURST_LEN_SIZE Controls width of fields specifying memory request burst lengths. Defaults to 8. .. make:var:: RUNPARAM Specifies the name or IP address of the machine on which to run the application, e.g.:: make RUNPARAM=192.168.168.100 run.android Top Level Make Targets ---------------------- .. make:target:: build.% Builds software and bitfile for the specified board name, e.g.,:: make build.zedboard .. make:target:: run.% Programs the FPGA and runs the application using the build for the specified board name. Uses :make:var:RUNPARAM. For example,:: make RUNPARAM=sj10 run.vc707 Intermediate Make Targets ------------------------- .. make:target:: verilog Runs the build up through generation of verilog from BSV. Requires BOARD to be defined. .. make:target:: bits Generates the FPGA bit file from the design. Requires BOARD to be defined. .. make:target:: bsim For BOARD=bluesim, generates the simulation executable. .. make:target:: xsim For BOARD=xsim, generates the simulation executable. .. make:target:: android.exe Builds the software executable for boards using Android. .. make:target:: ubuntu.exe Builds the software executable for boards using Ubunto/CentOS. .. make:target:: bsim_exe Builds the software executable for bluesim. .. make:target:: gentarget This step creates the board directory and Makefile. .. make:target:: prebuild Additional steps needed before making verilog, etc. Use this target for dependences such as constraint file and IP core generation that need to be run before the design is built. This is a :: dependence, so you can specify it multiple times. ================================================ FILE: doc/library/source/themes/connectal/layout.html ================================================ {# connectal/layout.html ~~~~~~~~~~~~~~~~~~~ #} {%- extends "classic/layout.html" %} {% set script_files = script_files + ['_static/tracking.js'] %} ================================================ FILE: doc/library/source/themes/connectal/static/tracking.js_t ================================================ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-15845210-2', 'auto'); // Replace with your property ID. ga('send', 'pageview'); ================================================ FILE: doc/library/source/themes/connectal/theme.conf ================================================ [theme] inherit = classic ================================================ FILE: doc/library/source/tools/generate-constraints.rst ================================================ .. _invocation_generate-constraints.py Invocation of generate-constraints.py ======================= .. argparse:: :module: generate-constraints :func: newArgparser :prog: generate-constraints ================================================ FILE: doc/library/source/tools/makefilegen.rst ================================================ .. _invocation_makefilegen.py Invocation of makefilegen.py ============================ The :program:`makefilegen.py` script generates project Makefiles. Normally, it is invoked from Makefile.connectal and passed options via :make:var:`CONNECTALFLAGS`. Project Options --------------- .. option:: -B board, --board=board Specifies which board to build for. .. option:: --O os, --option=os Specifies which operating system to support. Usually derived from :option:board. .. option:: --project-dir=dir Specifies the directory in which to creat the Makefile that performs the build. Creates the directory if it does not exist. Source Options -------------- .. option:: bsvfile This positional argument specifies which BSV files to parse for type and interface declarations. .. option:: -s foo.cpp, --source=foo.cpp Specifies C and C++ files to include in the application. .. option:: --ipdir=dir Specifies where to store IP cores generated by Vivado or Quartus .. option:: --cachedir=dirname Specifies directory to be used by `buildcache` .. option:: --nocache Disables `buildcache` .. option:: -D var=value Binds var to value in software, BSV, Verilog, and Tcl contexts. .. option:: -v, --verbose Verbose operation Interface Options ----------------- .. option:: --interfaces=... To be written... .. option:: --dump_map Generate a JSON file describing the portals, for use in tracing tools such as `pcieflat`. Software Options ---------------- .. option:: --cflags=flags Specifies build flags for the C/C++ compiler .. option:: -I dir --cinclude=dir .. option:: -l lib, --clib=lib Link the application with library lib. .. option:: -S libfile, --clibfiles=libfile.a Link the application with library file `libfile.a`. .. option:: -L libdir, --clibdir=libdir Addes `libdir` to the software library path. .. option:: --nonstrict Pass --Wall to gcc instead of -Werror. .. option:: --shared Specifies to build a shared library instead of an executable. .. option:: --nohardware Suppresses build of hardware, for software-only projects. .. option:: --stl=stltype Specifies which C++ Standard Template Library to use for Android. The choices are: * stlport_static: STLport runtime C++ exceptions and RTTI and Standard Template Library * stlport_shared * gnustl_static: GNU STL runtime C++ exceptions and RTTI and Standard Template Library * gnustl_shared * c++_static: LLVM libc++ runtime C++ exceptions and RTTI and Standard Template Library * c++_shared * gabi++_static: GAbi++ runtime C++ exceptions and RTTI * gabi++_shared Hardware Options ---------------- .. option:: --bsvpath=dirname Adds `dirname` to the BSV module import path. .. option:: -b options, --bscflags=options Flags to pass to the BSV compiler. .. option:: -V file.v, --verilog=file.v Specifies verilog file to include in the design .. option:: --pinfo=project.json This does what? .. option:: --pinout=pinusage.json Specifies connection of pins on the board to top level signals of the design. A board-specific constraint file will be generated from pinusage.json and the boardinfo json file, and will be added to constraint and implconstraint. See :make:var::`PINOUT_FILE`, whose values are passed as --pinout options to makefilegen. .. option:: --constraint=file.xdc Specifies synthesis phase constraint file. .. option:: --implconstraint=file.xdc Specifies implementation (place and route) constraint file. .. option:: --unmanaged-implconstraint=file.xdc Specifies unmanaged implementation (place and route) constraint file. This causes the xdc file to be read in using the `-unmanaged` flag of `read_xdc`. This allows the xdc files to use more tcl commands than a normal xdc file (including `if` and `foreach`). .. option:: -P modulename, --partition=modulename Directs `fpgamake` to build a separate netlist for `modulename`. With `buildcache`, Reduces build times if module changes infrequently. Xilinx Options -------------- .. option:: --xci=core.xci Specifies IP core to include in the design. (Xilinx only) Altera Options -------------- .. option:: --qip=core.qip Specifies IP core to include in the design. (Altera only) .. option:: --qsf=settings.qsf Specifies Altera Quartus settings. Partial Reconfiguration Options ------------------------------- .. option:: --prtop=mkTop.dcp Specifies filename of previously built top level. .. option:: --prvariant=name ... .. option:: --reconfig=modulenames ... Bluesim Options ------------------ .. option:: -q, --qtused Link the bluesim `bsim` executable with libQt. .. option:: -m foo.cpp, --bsimsource foo.cpp Specifies additional sources to compile into the `bsim` executable. If you are using Bluespec import "BDPI" or SystemVerilog "DPI"/"DPI-C", you will need to link additional sources into the simulator. Note: These files are currently compiled with g++, even if they are C files. You will need to use extern "C" to export symbols to the simulator. Xsim Options ------------ .. option:: --xelabflags=flags Options to pass to `xelab` .. option:: --xsimflags Options to pass to `xsim` Clocking Options ---------------- .. option:: --mainclockperiod Specifies the period, in nanoseconds, of the main clock. Must be an integer. On Zynq boards, On PCIe-connected boards, if the main clock period differs from the PCIe clock period, then the design's portals and DMA ports will automatically be connected via SyncFIFO's. Each boardinfo JSON file specifies the default value for mainclockperiod. .. option:: --derivedclockperiod Connectal also makes a second clock available, host.derivedClock. The period of this clock is Each boardinfo JSON file specifies the default value for mainclockperiod. ================================================ FILE: doc/library/source/tools/pcieflat.rst ================================================ .. _invocation_pcieflat pcieflat ======== Usage:: pcieflat Dumps trace of PCIE transactions. The trace contains the following columns: ========= ====================== col description ========= ====================== dirtype TLP direction and type timestamp Timestamp of TLP, in main clock cycles delta Number of cycles since previous TLP type type:pktype:format be Byte enables hit BAR hit eof End of frame sof Start of frame address Request physical address tag Request tag ========= ====================== The first column, `dirtype`, contains RX if received by FPGA, TX if transmitted by FPGA, qq for start of request, pp for start of response, and cc for continuation. The second column, `timestamp`, displays the timestamp in terms of a 64-bit counter running at the PCIe user clock frequency (125MHz for gen1, 250MHz for gen2 and gen3). The third column, `delta`, displays the number of cycles since the previous TLP. If a TLP is transmitted and received on the same cycle, then the transmitted TLP will have a delta of 0. The first TLP shown in the trace will have a delta of 0. The fourth column shows the type of the TLP. If it is the start of a transaction, it will be of the form `type:tlppkttype:tlpformat`, where the types are: * CpuRReq: read request from CPU to FPGA * CpuWReq: write request from CPU to FPGA * CpuRRsp: read response from FPGA to CPU * DmaRReq: read request from FPGA to CPU DRAM * DmaWReq: write request from FPGA to CPU DRAM * DmaRRsp: read response from CPU DRAM to FPGA * CpuRCon: continuation data sent from FPGA to CPU (continuation of CpuRRsp or DmaWReq) * DmaRCon: continuation data sent from CPU DRAM to FPGA (continuation of DmaRRsp or CpuWReq) * Interru: interrupt message from FPGA to CPU The TLP `pkttype` is one of the following: * MRW: Memory read/write * COMP: additional data ("completion") of transaction The TLP `format` is one of the following: * MEM_WRITE_3DW_DATA: 96-bit write request header containing 32-bit address and 32-bit data * MEM_WRITE_4DW_DATA: 128-bit write request header containing 64-bit address and no data * MEM_READ__3DW: 96-bit read request header containing 32-bit address * MEM_READ__4DW: 128-bit read request header containing 64-bit address The `sof` and `eof` flags indicate the start and end TLPs of each transaction. Diagnosing Crashes ------------------ If the machine crashed, look for transactions that were started but not ended. These will generally fall before very large deltas, where the machine was rebooted before it had any more interactions with the FPGA. Example Trace -------------- Here are some excerpts from the output of `pcieflat` after running `tests/memserver_copy`:: pcieflat: devices are ['/dev/portal_0_6', '/dev/portal_0_5', '/dev/portal_0_4', '/dev/portal_0_3', '/dev/portal_0_2', '/dev/portal_0_1'] ts delta response XXX tlp address off be tag clid nosnp laddr data pkttype format foo (be hit eof sof) (1st last) req stat bcnt length RXpp 513858932 0 DmaRRsp:COMP:MEM_WRITE_3DW_DATA 09 0x4 tlp(ffff 0 0 1) tag:07 0300 0000 0 00 080 00 16 01179d1d TXcc 513858932 0 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:259b17012c9b1701339b17013a9b1701 RXcc 513858933 1 DmaRCon 08 0x4 tlp(ffff 0 0 0) data:249d17012b9d1701329d1701399d1701 TXcc 513858933 0 CpuRCon 10 0x8 tlp(ffff 0 1 0) data:419b1701489b17014f9b1701569b1701 RXcc 513858934 1 DmaRCon 08 0x4 tlp(ffff 0 0 0) data:409d1701479d17014e9d1701559d1701 RXcc 513858935 1 DmaRCon 08 0x4 tlp(ffff 0 0 0) data:5c9d1701639d17016a9d1701719d1701 RXcc 513858936 1 DmaRCon 08 0x4 tlp(ffff 0 1 0) data:789d17017f9d1701869d170164b19a21 RXpp 513858938 2 DmaRRsp:COMP:MEM_WRITE_3DW_DATA 09 0x4 tlp(ffff 0 0 1) tag:07 0300 0000 0 00 040 40 16 01179d8d RXcc 513858939 1 DmaRCon 08 0x4 tlp(ffff 0 0 0) data:949d17019b9d1701a29d1701a99d1701 RXcc 513858940 1 DmaRCon 08 0x4 tlp(ffff 0 0 0) data:b09d1701b79d1701be9d1701c59d1701 RXcc 513858941 1 DmaRCon 08 0x4 tlp(ffff 0 0 0) data:cc9d1701d39d1701da9d1701e19d1701 RXcc 513858942 1 DmaRCon 08 0x4 tlp(ffff 0 1 0) data:e89d1701ef9d1701f69d1701af3ad2c2 TXqq 513858949 7 DmaWReq: MRW:MEM_WRITE_4DW_DATA 11 0x8 tlp(ffff 0 0 1) address: 000000035f4fc680 be(1st: f last:f) tag:05 reqid:0300 length:32 TXcc 513858950 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:5d9b1701649b17016b9b1701729b1701 TXcc 513858951 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:799b1701809b1701879b17018e9b1701 TXcc 513858952 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:959b17019c9b1701a39b1701aa9b1701 TXcc 513858953 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:b19b1701b89b1701bf9b1701c69b1701 TXcc 513858954 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:cd9b1701d49b1701db9b1701e29b1701 TXcc 513858955 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:e99b1701f09b1701f79b1701fe9b1701 TXcc 513858956 1 CpuRCon 10 0x8 tlp(ffff 0 0 0) data:059c17010c9c1701139c17011a9c1701 TXcc 513858957 1 CpuRCon 10 0x8 tlp(ffff 0 1 0) data:219c1701289c17012f9c1701369c1701 It may contain DMA Read Requests:: TXqq 513859009 1 DmaRReq: MRW:MEM_READ__4DW 11 0x8 tlp(ffff 0 1 1) address: 000000039e8fc800 be(1st: f last:f) tag:00 reqid:0300 length:32 TXqq 513859010 1 DmaRReq: MRW:MEM_READ__4DW 11 0x8 tlp(ffff 0 1 1) address: 000000039e8fc880 be(1st: f last:f) tag:01 reqid:0300 length:32 The trace may contain interrupts:: TXqq 513865009 12 Interru: MRW:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 0 1 1) fee00000 0 be(f 0) tag:00 0300 1 0000406e It will also contain reads and writes from the CPU to the FPGA:: RXqq 513874994 9985 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df400000 0 be(f 0) tag:00 0038 1 TXpp 513875008 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 00 1 00000001 RXqq 513875159 151 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df402000 800 be(f 0) tag:00 0038 1 TXpp 513875173 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 00 1 00000000 RXqq 513875323 150 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df401000 400 be(f 0) tag:00 0038 1 TXpp 513875337 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 00 1 00000000 RXqq 513876236 899 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df40000c 3 be(f 0) tag:00 0038 1 TXpp 513876250 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 0c 1 00000001 RXqq 513876449 199 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df400020 8 be(f 0) tag:00 0038 1 TXpp 513876463 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 20 1 00000000 RXqq 513883818 7355 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df40000c 3 be(f 0) tag:00 0038 1 TXpp 513883832 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 0c 1 00000000 RXqq 513883976 144 CpuWReq: MRW:MEM_WRITE_3DW_DATA 09 0x4 tlp(ffff 4 1 1) df400004 1 be(f 0) tag:02 0000 1 00000001 RXqq 513884007 31 CpuRReq: MRW:MEM_READ__3DW 09 0x4 tlp(ffff 4 1 1) df40200c 803 be(f 0) tag:00 0038 1 TXpp 513884021 14 CpuRRsp:COMP:MEM_WRITE_3DW_DATA 11 0x8 tlp(ffff 4 1 1) tag:00 0038 0300 0 00 004 0c 1 00000000 RXqq 513884165 144 CpuWReq: MRW:MEM_WRITE_3DW_DATA 09 0x4 tlp(ffff 4 1 1) df402004 801 be(f 0) tag:03 0000 1 00000001 The trace will end with a summary of the kinds of PCIe transactions:: {'DmaWReq': 115, 'CpuRReq': 45, 'Interru': 3, 'CpuRRsp': 45, 'CpuRCon': 922, 'CpuWReq': 15, 'DmaRReq': 112, 'DmaRRsp': 141, 'DmaRCon': 904} 2302 ================================================ FILE: doc/library/source/tools/tools.rst ================================================ ======================= Connectal Tools ======================= .. toctree:: :maxdepth: 2 :numbered: makefilegen.rst generate-constraints.rst pcieflat.rst topgen.rst ================================================ FILE: doc/library/source/tools/topgen.rst ================================================ .. _invocation_topgen.py Invocation of topgen.py ======================= .. argparse:: :module: topgen :func: newArgparser :prog: topgen ================================================ FILE: doc/makefilegen.md ================================================ # Using makefilegen.py Here are the options supported by `makefilegen.py` | Option | Long Option | Default | Description | ---------|-------------|---------|-------------------------------------| | -b | --bscflags | | Options to pass to the BSV compiler | | -B | --board | zc702 | Board to generate code for (Mandatory) [bluesim, zedboard, zc702, vc707, kc705, ...]| | -C | --constraint| | Additional constraint files (Optional) | | -I | --contentid | | Specify 64-bit contentid for PCIe designs (Optional) | | -M | --make | | Run make on the specified targets after generating code (Optional) | | -O | --OS | | Operating system of platform, inferred from board (Optional) | | -V | --verilog | | Additional verilog sources to include in hardware synthesis. (Optional) | | -h2s | --h2sinterface | | Hardware to software interface | | -l | --clib | | Additional C++ libary (Optional) | | -p | --project-dir | ./xpsproj | Directory in which to generate files (Optional) | | -s | --source | | C++ source files (Optional) | | -s2h |--s2hinterface | | Software to hardware interface | | -t | --topbsv | | Top-level bsv file (Required) | | -x | --export | | Promote/export named interface from top module (Required) | ================================================ FILE: doc/maxcommonsubseq.md ================================================ ## Maximum Common Subsequence A problem very much related to DNA sequence alignment is the problem of finding the longest common subsequence in a pair of strings. Suppose we have two strings: A = " A B C D " B = "........B....C.." The longest common subsequence is "BC" even though the positions of the B and the C are different in the two strings and the gap between them is different. It was known in 1974 how to find the answer in O(mn) time and O(mn) space where m = len(A) and n = len(B). In 1975, Hirschberg discovered a way to find the longest common subsequence in O(mn) time but only O(m+n) space. Hirschberg, D. S. (1975). A Linear Space Algorithm for Computing Maximal Common Subsequences. CACM, 18(6), pp 341-343.(A Linear Space Algorithm for Computing Maximal Common Subsequences) Refer to [http://www.akira.ruc.dk/~keld/teaching/algoritmedesign_f03/Artikler/05/Hirschberg75.pdf]{ See also [http://en.wikipedia.org/wiki/Hirschberg's_algorithm](Wikipedia article on Hirschberg's Algorithm) The straightforward way to solve this problem is via dynamic programming. Let A_i be the first i characters of A, and B_j be the first j characters of B. Imagine a matrix L with m rows and n columns, such that L[i][j] is the length of the longest common subsequence of A_i and B_j Then if A[i-1]==B[j-1]: L[i][j] = L[i-1][j-1] + 1 else: L[i][j] = max(L[i][j-1], L[i-1][j]) If the last characters match, then L[i][j], the length of the longest common subsequence is the lcs of the prefixes plus 1. If the last characters don't match, then the lcs is the longer of L[i-1][j] or L[i][j-1]. In the references to A[i-1] and B[j-1], the -1's are there because in python strings are 0 origin. Since the dependencies of the recurrence are only "up" and "to the left" we can compute the whole matrix incrementally from top to bottom and left to right. Here is Hirschberg's Algorithm A: # compute maximal length subsequence of A and B def hirschbergalga(A, B): m = len(A) n = len(B) L = [[0 for j in xrange(n+1)] for i in xrange(m+1)] for i in xrange(1, m+1): L[i][0] = 0 for j in xrange(1, n+1): L[0][j] = 0 for i in xrange(1, m+1): for j in xrange(1, n+1): if A[i-1]==B[j-1]: L[i][j] = L[i-1][j-1] + 1 else: L[i][j] = max(L[i][j-1], L[i-1][j]) return L Consider again the recurrence. Row j of L depends only on earlier values in row j and on row j-1. Therefore we do not need to retain the entire matrix, but rather only the last two rows. If we also return the final row we get Hirschberg's Algorithm B def hirschbergalgb(A, B): m = len(A) n = len(B) K = [[0 for j in xrange(n+1)] for i in xrange(2)] for i in xrange(1,m+1): for j in xrange(n+1): K[0][j] = K[1][j] for j in xrange(1, n+1): if A[i-1]==B[j-1]: K[1][j] = K[0][j-1] + 1 else: K[1][j] = max(K[1][j-1], K[0][j]) LL = [K[1][j] for j in xrange(n+1)] return(LL) This is not coded as efficiently as it could be, in that the rows of K are copied every time through the loop. At this point, Hirschberg adopts a recursive strategy. For any point i in A there is at least one point j in B such that L[m][n] = L[i][j] + L'[i][j] where L' is the "reverse problem", the maximum length subsequence from subscripts i and j to the ends of strings A and B. In other words. The algorithm chooses an i halfway through string A, then uses Algorithm B to locate the corresponding point j, then recursively solves the two subproblems. def hirschbergalgc(A, B): m = len(A) n = len(B) C = "" if n == 0: return "" if m == 1: if A[0] in B: return A else: return "" i = m / 2 L1 = hirschbergalgb(A[0:i], B) L2 = hirschbergalgb(A[i:][::-1], B[::-1]) m = -1 for j in xrange(n+1): t = L1[j] + L2[n-j]; if t > m: m = t k = j C1 = hirschbergalgc(A[0:i],B[0:k]) C2 = hirschbergalgc(A[i:], B[k:]) return C1 + C2 This method takes a logarithmic recursion depth, because the subproblems are half the size at each level. The storage used is O(m+n) and the time is O(mn). The really clever bit is the use of Algorithm B to locate the j corresponding to a particular i. Algorithm B uses the dynamic programming recurrance to solve for all possible j values in a single pass, then it is a simple matter to find the best j. See the actual example code in connectal/examples/maxcommonsubseq/hirschberg.py ================================================ FILE: doc/previous/portal.asciidoc ================================================ CONNECTAL ==== Jamey Hicks , John Ankcorn, Myron King, L. Stewart - Scribe 0.002 April 29, 2014 == What is CONNECTAL? [role="lead"] CONNECTAL provides a hardware-software interface for applications split between user mode code and custom hardware in an FPGA or ASIC. CONNECTAL can automaticaly build the software and hardware glue for a message based interface and also provides for configuring and using shared memory between applications and hardware. Communications between hardware and software are provided by a bidirectional flow of events and regions of memory shared between hardware and software. Events from software to hardware are called requests and events from hardware to software are called indications, but in fact they are symmetric. :bsvdocumentation: http://wiki.bluespec.com/Home/BSV-Documentation :bluespecdotcom: http://www.bluespec.com/ == Lexicon connectal:: The name of the project, whose goal is to ease the task of building applications composed of hardware and software components. Programmers use bsv as an IDL to specify the interface between the hardware and software components. A combination of generated code and libraries coordinate the data-flow between the program modules. Because the HW and SW stacks are customized for each application, the overheads associated with communicating across the HW/SW boundary are low. HW/SW interface :: portal bsv:: Bluespec System Verilog. bsv is a language for describing hardware that is might higher level than verilog. See {bsvdocumentation}[BSV Documentation] and {bluespecdotcom}[Bluespec, Inc]. bluespec:: Shorthand for Bluespec System Verilog (bsv) indexterm:portal portal:: a logical request/indication pair is referred to as a portal. current tools require their specification in the IDL to be syntactically identifiable (i.e. fooRequest/fooIndication). An application can make use of multiple portals, which may be specified independently. request interface:: These methods are implemented by the application hardware to be invoked by application software. A bsv interface consisting of ‘Action’ methods. Because of the ‘Action’ type, data flow across this interface is unidirectional (SW -> HW). indication interface:: The dual of a request interface, indication interfaces are ‘Action’ methods implemented by application software to be invoked by application hardware. As with request interfaces, the data flow across this interface is unidirectional, but in the opposite direction. pcieportal/zynqportal:: these two loadable kernel modules implement the minimal set of driver functionality. Specifically, they expose portal HW registers to SW through mmap, and set up interrupts to notify SW that an indication method has been invoked by HW. portalalloc:: This loadable kernel module exposes a subset of dma-buf functionality to user-space software (though a set of ioctl commands) to allocate and manage memory regions which can be shared between SW and HW processes. Maintaining coherence of the allocated buffers between processes is not automatic: ioctl commands for flush/invalidate are provided to be invoked explicitly by the users if necessary. connectalgen:: The name of the interface compiler which takes as input the bsv interface specification along with a description of a target platform and generates logic in both HW and SW to support this interface across the communication fabric. == Example setups: A zedboard ( http://www.zedboard.org/ ), with Android running on the embedded ARM processors (the Processing System 7), an application running as a user process, and custom hardware configured into the Programmable Logic FPGA. An x86 server, with Linux running on the host processor, an application running partly as a user process on the host and partly as hardware configured into an FPGA connected by PCI express (such as the Xilinx VC707 (http://www.xilinx.com/products/boards-and-kits/EK-V7-VC707-G.htm). == Background When running part or all of an application in an FPGA, it is usually necessary to communicate between code running in user mode on the host and the hardware. Typically this has been accomplished by custom device drivers in the OS, or by shared memory mapped between the software and the hardware, or both. Shared memory has been particularly troublesome under Linux or Android, because devices frequently require contiguous memory, and the mechanisms for guaranteeing successful memory allocation often require reserving the maximum amount of memory at boot time. Portal tries to provide convenient solutions to these problems in a portable way. It is desirable to have * low latency for small messages * high bandwidth for large messages * notification of arriving messages * asynchronous replies to messages * support for hardware simulation by a separate user mode process * support for shared memory (DMA) between hardware and software == Overview Portal is implemented as a loadable kernel module device driver for Linux/Android and a set of tools to automatically construct the hardware and software glue necessary for communications. Short messages are handled by programmed I/O. The message interface from software to hardware (so called "requests") is defined as a bsv interface containing a number of Action methods, each with a name and typed arguments. The interface generator creates all the software and hardware glue so that software invocations of the interface stubs flow through to, and are turned into bsv invocations of the matching hardware. The machinery does not have flow control. Software is responsible for not overrunning the hardware. There is a debug mechanism which will return the request type of a failed method, but it does not tell which invocation failed. Hardware to software interfaces (so called “indications”) are likewise defined by bsv interfaces containing Action methods. Hardware invocations of these methods flow through to and cause software calls to corresponding user-supplied functions. In the current implementation there is flow control, in that the hardware will stall until there is room for a hardware to software message. There is also a mechanism for software to report a failure, and there is machinery for these failures to be returned to the hardware. ["seqdiag",target="request-response-1.png"] --------------------------------------------------------------------- { // edge label SW -> HW [label = "request"]; SW <- HW [label = "indication"]; } --------------------------------------------------------------------- Portals do not have to be structured as request/response. Hardware can send messages to software without a prior request from software. ["seqdiag",target="indication-only.png"] --------------------------------------------------------------------- { // edge label SW <- HW [label = "indication"]; } --------------------------------------------------------------------- Incoming messages can cause host interrupts, which wake up the device driver, which can wake up the user mode application by using the select(2) or poll(2) interfaces. Most of the time, communications between hardware and software will proceed without requiring use of the OS. User code will read and write directly to memory mapped I/O space. Library code will poll for incoming messages, and [true? eventually time out and call poll(2). Only when poll(2) or select(2) are called will the device driver enable hardware interrupts. Thus interrupts are only used to wake up software after a quiet period. The designer specifies a set of hardware functions that can be called from software, and a set of actions that the hardware can take which result in messages to software. Portal tools take this specification and build software glue modules to translate software function calls into I/O writes to hardware registers, and to report hardware events to software. For larger memory and OS bypass (OS bypass means letting the user mode application talk directly to the hardware without using the OS except for setup), portal implements shared memory. Portal memory objects are allocated by the user mode program, and appear as Linux file descriptors. The user can mmap(2) the file to obtain user mode access to the shared memory region. Portal does not assure that the memory is physically contiguous, but does pin it to prevent the OS from reusing the memory. An FPGA DMA controller module is provided that gives the illusion of contiguous memory to application hardware, while under the covers using a translation table of scattered addresses. The physical addresses are provided to the user code in order to initialize the dma controller, and address "handles" are provided for the application hardware to use. The DMA controller provides Bluespec objects that support streaming access with automatic page crossings, or random access. == An Example An application developer will typically write the hardware part of the application in Bluespec and the software part of the application in C or C++. In a short example, there will be a bsv source file for the hardware and a cpp source file for the application. The application developer is free to specify whatever hardware-software interface makes sense. Refer to https://github.com/cambridgehackers/connectal In the examples directory, see [simple](../examples/simple/). The file [Simple.bsv](../examples/simple/Simple.bsv) defines the hardware, and testsimple.cpp supplies the software part. In this case, the software part is a test framework for the hardware. Simple.bsv declares a few `struct` and `enum` types: --------------------------------- typedef struct{ Bit#(32) a; Bit#(32) b; } S1 deriving (Bits); typedef struct{ Bit#(32) a; Bit#(16) b; Bit#(7) c; } S2 deriving (Bits); typedef enum { E1Choice1, E1Choice2, E1Choice3 } E1 deriving (Bits,Eq); typedef struct{ Bit#(32) a; E1 e1; } S3 deriving (Bits); --------------------------------- Simple.bsv defines the actions (called Requests) that software can use to cause the hardware to act, and defines the notifications (called Indications) that the hardware can use to signal the software. --------------------------------- interface SimpleIndication; method Action heard1(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); method Action heard3(S1 v); method Action heard4(S2 v); method Action heard5(Bit#(32) a, Bit#(64) b, Bit#(32) c); method Action heard6(Bit#(32) a, Bit#(40) b, Bit#(32) c); method Action heard7(Bit#(32) a, E1 e1); endinterface interface SimpleRequest; method Action say1(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action say3(S1 v); method Action say4(S2 v); method Action say5(Bit#(32)a, Bit#(64) b, Bit#(32) c); method Action say6(Bit#(32)a, Bit#(40) b, Bit#(32) c); method Action say7(S3 v); endinterface --------------------------------- Software can start the hardware working via say, say2, ... Hardware signals back to software with heard and heard2 and so fort. In the case of this example, say and say2 merely echo their arguments back to software. The definitions in the bsv file are used by the connectal infrastructure ( a python program) to automatically create corresponding c++ interfaces. --------------------------------- ../../connectalgen -Bbluesim -p bluesim -x mkBsimTop \ -s2h SimpleRequest \ -h2s SimpleIndication \ -s testsimple.cpp \ -t ../../bsv/BsimTop.bsv Simple.bsv Top.bsv --------------------------------- The tools have to be told which interface records should be used for Software to Hardware messages and which should be used for Hardware to Software messages. These interfaces are given on the command line for genxpprojfrombsv connectalgen constructs all the hardware and software modules needed to wire up portals. This is sort of like an RPC compiler for the hardware-software interface. However, unlike an RPC each method is asynchronous. The user must also create a toplevel bsv module Top.bsv, which instantiates the user portals, the standard hardware environment, and any additional hardware modules. Rather than constructing the `connectalgen` command line from scratch, the examples in connectal use include [Makefile.connectal] and define some `make` variables. Here is the Makefile for the `simple` example: [source,makefile] --------------------------------- CONNECTALDIR?=../.. INTERFACES = SimpleRequest SimpleIndication BSVFILES = Simple.bsv Top.bsv CPPFILES=testsimple.cpp include $(CONNECTALDIR)/Makefile.connectal --------------------------------- Designs outside the connectal directory using `connectal` may also include `Makefile.connectal`: [source,makefile] --------------------------------- CONNECTALDIR?=/scratch/connectal INTERFACES = ... BSVFILES = ... CPPFILES = ... include $(CONNECTALDIR)/Makefile.connectal --------------------------------- === simple/Top.bsv Each CONNECTAL design implements [Top.bsv](../examples/simple/Top.bsv) with some standard components. It defines the `IfcNames` enum, for use in identifying the portals between software and hardware: --------------------------------- typedef enum {SimpleIndication, SimpleRequest} IfcNames deriving (Eq,Bits); --------------------------------- It defines `mkConnectalTop`, which instantiates the wrappers, proxies, and the design itself: --------------------------------- module mkConnectalTop(StdConnectalTop#(addrWidth)); --------------------------------- `StdConnectalTop` is parameterized by `addrWidth` because Zynq and x86 have different width addressing. `StdConnectalTop` is a typedef: --------------------------------- typedef ConnectalTop#(addrWidth,64,Empty) StdConnectalTop#(numeric type addrWidth); --------------------------------- The "64" specifies the data width and `Empty` specifies the empty interface is exposed as pins from the design. In designs using HDMI, for example, `Empty` is replaced by `HDMI`. On some platforms, the design may be able to use different data widths, such as 128 bits on x86/PCIe. Next, `mkConnectalTop` instantiates user portals: --------------------------------- // instantiate user portals SimpleIndicationProxy simpleIndicationProxy <- mkSimpleIndicationProxy(SimpleIndication); --------------------------------- Instantiate the design: --------------------------------- SimpleRequest simpleRequest <- mkSimpleRequest(simpleIndicationProxy.ifc); --------------------------------- Instantiate the wrapper for the design: --------------------------------- SimpleRequestWrapper simpleRequestWrapper <- mkSimpleRequestWrapper(SimpleRequest,simpleRequest); --------------------------------- Collect the portals into a vector: --------------------------------- Vector#(2,StdPortal) portals; portals[0] = simpleRequestWrapper.portalIfc; portals[1] = simpleIndicationProxy.portalIfc; --------------------------------- Create an interrupt multiplexer from the vector of portals: --------------------------------- let interrupt_mux <- mkInterruptMux(portals); --------------------------------- Create the system directory, which is used by software to locate each portal via the `IfcNames` enum: --------------------------------- // instantiate system directory StdDirectory dir <- mkStdDirectory(portals); let ctrl_mux <- mkAxiSlaveMux(dir,portals); --------------------------------- The following generic interfaces are used by the platform specific top BSV module: --------------------------------- interface interrupt = interrupt_mux; interface ctrl = ctrl_mux; interface m_axi = null_axi_master; interface leds = echoRequestInternal.leds; endmodule : mkConnectalTop --------------------------------- === simple/testsimple.cpp CONNECTAL generates header files declaring wrappers for hardware-to-software interfaces and proxies for software-to-hardware interfaces. These will be in the "jni/" subdirectory of the project directory. [source,C] --------------------------------- #include "SimpleIndication.h" #include "SimpleRequest.h" --------------------------------- It also declares software equivalents for structs and enums declared in the processed BSV files: [source,C] --------------------------------- #include "GeneratedTypes.h" --------------------------------- CONNECTAL generates abstract virtual base classes for each Indication interface. [source,C] --------------------------------- class SimpleIndicationWrapper : public Portal { public: ... SimpleIndicationWrapper(int id, PortalPoller *poller = 0); virtual void heard1 ( const uint32_t v )= 0; ... }; --------------------------------- Implement subclasses of the wrapper in order to define the callbacks [source,C] --------------------------------- class SimpleIndication : public SimpleIndicationWrapper { public: ... virtual void heard1(uint32_t a) { fprintf(stderr, "heard1(%d)\n", a); assert(a == v1a); incr_cnt(); } ... }; --------------------------------- To connect these classes to the hardware, instantiate them using the `IfcNames` enum identifiers. CONNECTAL prepends the name of the type because C++ does not support overloading of enum tags. [source,C] --------------------------------- SimpleIndication *indication = new SimpleIndication(IfcNames_SimpleIndication); SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequest); --------------------------------- Create a thread for handling notifications from hardware: [source,C] --------------------------------- pthread_t tid; if(pthread_create(&tid, NULL, portalExec, NULL)){ exit(1); } --------------------------------- Now the software invokes hardware methods via the proxy: [source,C] --------------------------------- device->say1(v1a); device->say2(v2a,v2b); --------------------------------- === Simple Example Design Structure The `simple` example consists of the following files: --------------------------------- Simple.bsv Makefile Top.bsv testsimple.cpp --------------------------------- After running `make BOARD=zedboard verilog` in the `simple` directory, the `zedboard` project directory is created, populated by the generated files. A top level `Makefile` is created: --------------------------------- zedboard/Makefile --------------------------------- connectalgen generates wrappers for software-to-hardware interfaces and proxies for hardware-to-software interfaces: --------------------------------- zedboard/sources/mkzynqtop/SimpleIndicationProxy.bsv zedboard/sources/mkzynqtop/SimpleRequestWrapper.bsv --------------------------------- CONNECTAL supports Android on Zynq platforms, so connectalgen generates `jni/Android.mk` for `ndk-build`. --------------------------------- zedboard/jni/Android.mk zedboard/jni/Application.mk --------------------------------- CONNECTAL generates `jni/Makefile` to compile the software for PCIe platforms (vc707 and kc705). --------------------------------- zedboard/jni/Makefile --------------------------------- CONNECTAL generates software proxies for software-to-hardware interfaces and software wrappers for hardware-to-software interfaces: --------------------------------- zedboard/jni/SimpleIndication.h zedboard/jni/SimpleIndication.cpp zedboard/jni/SimpleRequest.cpp zedboard/jni/SimpleRequest.h --------------------------------- CONNECTAL also generates `GeneratedTypes.h` for struct and enum types in the processed BSV source files: --------------------------------- zedboard/jni/GeneratedTypes.h --------------------------------- CONNECTAL copies in standard and specified constraints files: --------------------------------- zedboard/constraints/design_1_processing_system7_1_0.xdc zedboard/constraints/zedboard.xdc --------------------------------- CONNECTAL generates several TCL files to run `vivado`. The `board.tcl` file specifies `partname`, `boardname`, and `connectaldir` for the other TCL scripts. --------------------------------- zedboard/board.tcl --------------------------------- To generate an FPGA bit file, run `make bits`. This runs vivado with the `mkzynqtop-impl.tcl` script. --------------------------------- zedboard/mkzynqtop-impl.tcl --------------------------------- === make verilog Compiling to verilog results in the following verilog files: --------------------------------- zedboard/verilog/top/mkSimpleIndicationProxySynth.v zedboard/verilog/top/mkZynqTop.v --------------------------------- Verilog library files referenced in the design are copied for use in synthesis. --------------------------------- zedboard/verilog/top/FIFO1.v ... --------------------------------- === make bits Running `make bits` in the zedboard directory results in timing reports: --------------------------------- zedboard/hw/mkzynqtop_post_place_timing_summary.rpt zedboard/hw/mkzynqtop_post_route_timing_summary.rpt zedboard/hw/mkzynqtop_post_route_timing.rpt --------------------------------- and some design checkpoints: --------------------------------- zedboard/hw/mkzynqtop_post_synth.dcp zedboard/hw/mkzynqtop_post_place.dcp zedboard/hw/mkzynqtop_post_route.dcp --------------------------------- and the FPGA configuration file in .bit and .bin formats: --------------------------------- zedboard/hw/mkZynqTop.bit zedboard/hw/mkZynqTop.bin --------------------------------- === make android_exe CONNECTAL supports Android 4.0 on Zynq platforms. It generates `jni/Android.mk` which is used by `ndk-build` to create a native Android executable. --------------------------------- make android_exe --------------------------------- This produces the ARM elf executable: --------------------------------- libs/armeabi/android_exe --------------------------------- === make run For Zynq platforms, --------------------------------- make run --------------------------------- will copy the Android executable and FPGA configuration file to the target device, program the FPGA, and run the executable. See [run.android](../scripts/run.android) for details. It uses `checkip` to determine the IP address of the device via a USB console connection to the device (it is built/installed on the host machine from the git repo cambridgehackers/consolable). If the target is not connected to the build machine via USB, specify the IP address of the target manually: --------------------------------- make RUNPARAM=ipaddr run --------------------------------- For PCIe platforms, `make run` programs the FPGA via USB and runs the software locally. For bluesim, `make run` invokes bluesim on the design and runs the software locally. == Shared Memory === Shared Memory Hardware In order to use shared memory, the hardware design instantiates a DMA module in Top.bsv: --------------------------------- AxiDmaServer#(addrWidth,64) dma <- mkAxiDmaServer(dmaIndicationProxy.ifc, readClients, writeClients); --------------------------------- The `AxiDmaServer` multiplexes read and write requests from the clients, translates DMA addresses to physical addresses, initiates bus transactions to memory, and delivers responses to the clients. DMA requests are specified with respect to "portal" memory allocated by software and identified by a `pointer`. Requests and responses are tagged in order to enable pipelining. --------------------------------- typedef struct { SGLId pointer; Bit#(MemOffsetSize) offset; Bit#(8) burstLen; Bit#(6) tag; } MemRequest deriving (Bits); typedef struct { Bit#(dsz) data; Bit#(6) tag; } MemData#(numeric type dsz) deriving (Bits); --------------------------------- Read clients implement the `MemReadClient` interface. On response to the read, `burstLen` `MemData` items will be put to the `readData` interface. The design must be ready to consume the data when it is delivered from the memory bus or the system may hang. --------------------------------- interface MemReadClient#(numeric type dsz); interface GetF#(MemRequest) readReq; interface PutF#(MemData#(dsz)) readData; endinterface --------------------------------- Write clients implement `MemWriteClient`. To complete the transaction, `burstLen` data items will be consumed from the `writeData` interace. Upon completion of the request, the specified tag will be put to the `writeDone` interface. The data must be available when the write request is issued to the memory bus or the system may hang. --------------------------------- interface MemWriteClient#(numeric type dsz); interface GetF#(MemRequest) writeReq; interface GetF#(MemData#(dsz)) writeData; interface PutF#(Bit#(6)) writeDone; endinterface --------------------------------- A design may implement `MemReadClient` and `MemWriteClient` interfaces directly, or it may instantiate DmaReadBuffer or DmaWriteBuffer. The `AxiDmaServer` is configured with physical address translations for each region of memory identified by a `pointer`. A design using DMA must export the `DmaConfig` and `DmaIndication` interfaces of the DMA server. Here are the DMA components of [memread_nobuff/Top.bsv](../examples/memread_nobuff/Top.bsv): Instantiate the design and its interface wrappers and proxies: --------------------------------- MemreadIndicationProxy memreadIndicationProxy <- mkMemreadIndicationProxy(MemreadIndication); Memread memread <- mkMemread(memreadIndicationProxy.ifc); MemreadRequestWrapper memreadRequestWrapper <- mkMemreadRequestWrapper(MemreadRequest,memread.request); --------------------------------- Collect the read and write clients: --------------------------------- Vector#(1, MemReadClient#(64)) readClients = cons(memread.dmaClient, nil); Vector#(0, MemReadClient#(64)) writeClients = nil; --------------------------------- Instantiate the DMA server and its wrapper and proxy: --------------------------------- DmaIndicationProxy dmaIndicationProxy <- mkDmaIndicationProxy(DmaIndication); AxiDmaServer#(addrWidth,64) dma <- mkAxiDmaServer(dmaIndicationProxy.ifc, readClients, writeClients); DmaConfigWrapper dmaConfigWrapper <- mkDmaConfigWrapper(DmaConfig,dma.request); --------------------------------- Include `DmaConfig` and `DmaIndication` in the portals of the design: --------------------------------- Vector#(4,StdPortal) portals; portals[0] = memreadRequestWrapper.portalIfc; portals[1] = memreadIndicationProxy.portalIfc; portals[2] = dmaConfigWrapper.portalIfc; portals[3] = dmaIndicationProxy.portalIfc; --------------------------------- The code generation tools will then produce the software glue necessary for the shared memory support libraries to initialize the DMA "library module" included in the hardware. === Shared Memory Software The software side instantiates the DmaConfig proxy and the DmaIndication wrapper: --------------------------------- dma = new DmaConfigProxy(IfcNames_DmaConfig); dmaIndication = new DmaIndication(dma, IfcNames_DmaIndication); --------------------------------- Call `dma->alloc()` to allocate DMA memory. Each chunk of portal memory is identified by a file descriptor. Portal memory may be shared with other processes. Portal memory is reference counted according to the number of file descriptors associated with it. --------------------------------- PortalAlloc *srcAlloc; dma->alloc(alloc_sz, &srcAlloc); --------------------------------- Memory map it to make it accessible to software: --------------------------------- srcBuffer = (unsigned int *)mmap(0, alloc_sz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, srcAlloc->header.fd, 0); --------------------------------- CONNECTAL is currently using non-snooped interfaces, so the cache must be flushed and invalidated before hardware accesses portal memory: --------------------------------- dma->dCacheFlushInval(srcAlloc, srcBuffer); --------------------------------- Call `dma->reference()` to get a pointer that may be passed to hardware: --------------------------------- unsigned int ref_srcAlloc = dma->reference(srcAlloc); --------------------------------- This also transfers the DMA-to-physical address translation information to the hardware via the `DmaConfig` interface. --------------------------------- device->startRead(ref_srcAlloc, numWords, burstLen, iterCnt); --------------------------------- == Notes ***** stewart notes Currently there are no valid bits and no protections against bursts crossing page boundaries] There needs to be a way to synchronize Request actions and DMA reads, and to synchronize DMA writes with Indications, so that the writes complete to the coherence point before the indication is delivered to software. One could imagine an absurdly buffered memory interface and a rather direct path for I/O reads that could get out of order. ***** include::portalstructure.asciidoc[] == Index ================================================ FILE: doc/server.md ================================================ Data Center Accelerators ======================== Approach -------- * Application process can request a coprocessing tile to be loaded * Process startup triggers tile load * Tile deactivated when process ends * Tile manager on the FPGA * Only user of the pins and PCIe/system interface * The tiles export MemClient interfaces, which are connected to a corresponding MemServer for the tile. [draw nifty picture.] * As part of this, prepends tile number onto object ID used to access the MMU in MemServer, providing inter-tile, inter-process access control * Responsible for QoS, Fairness, Arbitration of resource use by tiles. * For virtualization, device-driver in the host OS controls the actual hardware * Device-driver in the guest OS requests resources from the host OS, i.e., a tile * Misbehaviour in a tile cannot affect other tiles: * PCIe transactions buffered. If tile logic not ready, then TLP deleted. * If worried about integrity of bitfile contents, perhaps only load ones that have been signed by an authorized build server Tasks ----- * Construct tile manager with fixed per-tile interface ports * Per-tile ports disabled during tile reconfiguration * Tile manager configuration and floor planning * Partial reconfiguration to load a tile * Disable ports without locking PCIe * Floor planning. * Relocatable tiles? * Implement tile loader Tile Interface -------------- interface Tile; interface PhysMemSlave portal; interface ReadOnly#(Bool) interrupt; interface Vector#(N,MemReadClient) readClients; interface Vector#(N,MemWriteClient) writeClients; interface Pins pins; endinterface Notes ----- * The Tile Manager looks like the infra that a Verilog module would plug into, but with fixed configuration. Questions --------- ================================================ FILE: doc/syntax.md ================================================ --Capitalization Foo: Type names, Typeclass names, Interface names, Enum labels, Tagged union labels, Package names foo: bit[..], int, module names, instance names, all variables, all type variables, rule names --Package package Package_name ; typedef statements import statements interface declarations module declarations endpackage [: Package_name] --Import Statement import Package_name :: * ; --Predefined Data Types Bit#(n) Int#(n) // signed Uint#(n) // unsigned Integer // static elaboration only Bool String Action ActionValue#(t) Rules Tuple2#(t1, t2) ... Tuple7#(t1,..., t7) int // Int#(32) Nat // Bit#(32) Maybe#(t) --Type Definition Type_name Type_name#(type_variable) // polymorphic type --Type Synonym typedef type Type_name[#({type type_var})]; example: typedef Bit#(8) Byte; typedef Tuple3#(a, a, a) Triple#(type a); --Interface Declaration interface ifc_name; method declarations subinterface declarations endinterface[:ifc_name] interface ifc_name #({type Type_name}); method declarations subinterface declarations endinterface[:ifc_name] example: interface MyIfc#(t) ; method Action tick() ; interface FIFO#(t) inbuffer ; endinterface:MyIfc --Method Declaration method Type method_name [(Type argument)] ; --Module Definition module module_name [# ({parameter})] ({Ifc_type ifc_name*})[provisos] ; module instantiations variable declaration and initializations rules interface/method definitions endmodule [:module_name] * ifc_name optional if only one ifc --Module Instantiation Ifc_type ifc_name <- module_name({parameter}); Ifc_type ifc_name <- module_name([{parameter,} clocked_by clock_name, reset_by reset_name]); example: Reg#(Time32) state <- mkReg(0); --Rules rule rule_name [rule_predicate] ; action statements endrule[: rule_name] rules [: rules_name] rule variable declaration or variable assignment endrules[: rules_name] --Action Block action [: action_name] ; action statements endaction [:action_name] --Value Method Definition method Type method_name ({parameter}) [if (method_predicate)]; method body statements return statement endmethod [:method_name] --Action Method Definition method Action method_name ({parameter}) [if (method_predicate)]; method body statements endmethod [:method_name] --ActionValue Method Definition method ActionValue method_name({parameter}) [if (method_predicate)]; method body statements return statement endmethod [:method_name] --Variable Declaration and Initialization Type {variable_name [= expression ]}; example: Integer x = 16, y = 32; int a[20], b[40]; Int#(5) xs[2][4] = {{1,2,3,4}, {5,6,7,8}}; --Variable Assignment variable_name = expression ; example: x = 23 ; b = foo.bar(x); --ActionValue Assignment Statement Special <- notation used to perform the action and return the value type identifier <- expression ; identifier <- expression ; --Implicit Type Declaration and Initialization let identifier = expression ; ---if expression is actionvalue method let identifier <-­ expression ; example: let n = valueof(Buffsize); let z <- rndm.get; --Register Read and Write register_name <= expression ; example: state <= state + 1 ; // same as: state._write (state.read() + 1) --Enumeration typedef enum {{Elements}} Type_name [deriving (Typeclass)]; example: typedef enum {Red, White, Blue} Color deriving (Eq, Bits); --Structure (struct value contains member1 and member2, etc.) typedef struct {Type member1;...;Type memberN} Type_name [#{[numeric] type type_variable}] [deriving (Typeclass)]; ----example: typedef struct {Int x; Int y;} Coord deriving (Eq, Bits); ----Declaration and initialization of a structure variable Type variable_name = Type{member:expression} Coord c1 = Coord{x:1, y:foo}; ----Update of a structure variable c1.x = c1.x + 5 ; ----Structure member selection xposition = c1.x ; --Tagged Union (union value contains member1 or member2) typedef union tagged {type Member1; ... ; type MemberN;} Type_name [#...[numeric] type type_variable]; example: typedef union tagged { void Invalid; int Valid; } MaybeInt; ---Declaration and initialization of a tagged union Type variable_name = Member expression ; MaybeInt x = tagged Valid 5 ; --Pattern Matching ---Tagged Union tagged Member [ pattern ] ---Structure tagged Type [ member:pattern ] ---Tuple tagged {pattern, pattern} ---Pattern Matching Examples -----Pattern matching in a case statement case (f(a)) matches tagged Valid .x : return x; tagged Invalid : return 0; endcase -----Pattern matching in an if statement if (x matches tagged Valid .n &&& n > 5...) ---Pattern Matching Assignment Statement match pattern = expression ; example: Tuple2#(Bits(32) x, Bool y) a_tuple; match {.a, .b} = a_tuple ; --Function Definition function type function_name ([{arguments}]) [provisos]; function body statements return statement endfunction [: function_name] --Attributes (* {attribute [= expression ]}*) ---Module Attributes (top­level only) synthesize RST_N = "string" CLK = "string" always_ready [= "interface_method"] always_enabled [= "interface_method"] descending urgency = "{rule_names}" preempts = "{rule_names, (list_rule_names)]}" doc = "string" ---Method Attributes always_ready [= "interface_method"] always_enabled [= "interface_method"] ready = "string" enable = "string" result = "string" prefix = "string" port = "string" ---Interface Attributes always_ready [= "interface_method"] always_enabled [= "interface_method"] ---Function Attributes (top­level only) noinline ---Rule Attributes fire_when_enabled no_implicit_conditions descending_urgency = "{rule_names}" preempts "{rule_names, [(list_rule_names)]}" --System Tasks and Functions $display $write $fopen $fdisplay $fwrite $fgetc $fflush $fclose $ungetc $finish $stop $dumpon $dumpoff $dumpvars $test$plusargs $time $stime --Importing C Functions import "BDPI" [c_function_name =] function Return_type function_name [{argument}]) [provisos] ; --Importing Verilog Modules import "BVI" [verilog_module_name] = module [[Type]] module_name [# ({parameter})] ({Ifc_type ifc_name}) [provisos] ; module statements importBVI statements endmodule [: module_name] ----importBVI Statements parameter parameter_name = expression ; port port_name = expression ; default_clock clock_name [(port_name, port_name)][= expression]; input_clock clock_name [(port_name, port_name)] = expression; output_clock clock_name (port_name [,port_name]); no_reset; default_reset clock_name ([port_name]) [= expression]; input_reset clock_name ([port_name]) = expression; output_reset clock_name ( port_name ); ancestor ( clock1, clock2 ); same_family ( clock1, clock2 ); method [output_port] method_name ({input_ports}) [enable enable_port] [ready ready_port][clocked_by clock_name] [reset_by clock_name]; schedule ({method_name}) operator ({method_name}); operators are CF, SB, SBR, and C path (port_name1, port_name2) ; --Defined Interfaces ---Reg interface Reg #(type a_type); method Action _write(a_type x1); method a_type _read(); endinterface: Reg ---PulseWire interface PulseWire; method Action send(); method Bool _read(); endinterface ---Wire typedef Reg#(a_type) Wire#(type a_type); --Defined Modules ---Reg module mkReg#(a_type resetval) (Reg#(a_type)); module mkRegU(Reg#(a_type)); module mkRegA#(a_type resetval)(Reg#(a_type)); ---Wire module mkWire(Wire#(a_type)); ---BypassWire module mkBypassWire(Wire#(a_type)); ---DWire module mkDWire#(a_type defaultval) (Wire#(a_type)); ---PulseWire module mkPulseWire(PulseWire); --Library Packages ---FIFOFs (import FIFOF::*;) see LRM for additional FIFOs ----Interface interface FIFOF #(type a_type); method Action enq(a_type x1); method Action deq(); method a_type first(); method Bool notFull(); method Bool notEmpty(); method Action clear(); endinterface: FIFOF ----Modules module mkFIFOF# (FIFO#(a_type)) ; module mkFIFOF1#(FIFO#(a_type)); module mkSizedFIFOF#(Integer n)(FIFO#(a_type)) ; module mkLFIFOF#(FIFO#(a_type)); ---Get/Put (importGetPut::*;) ----Interfaces interface Get#(type a_type); method ActionValue#(a_type) get(); endinterface: Get interface Put#(type a_type); method Action put(a_type x1); endinterface: Put ----Type typedef Tuple2#( Get#(a_type), Put#(a_type) ) GetPut#(type a_type); ----Connectable (import Connectable::*;) ----Typeclass typeclass Connectable#(type a , type b) ; ----Module mkConnection#(a x1, b x2) ; ---Client/Server (import ClientServer::*;) ----Interfaces interface Client#(type req_type, type resp_type); interface Get#(req_type) request; interface Put#(resp_type) response; endinterface: Client interface Server#(type req_type, type resp_type); interface Put#(req_type) request; interface Get#(resp_type) response; endinterface: Server ----Type typedef Tuple2#(Client#(req_type, resp_type), Server#(req_type,resp_type)) ClientServer#(type req_type, type resp_type); --BSV Example package Counter ; interface Counter#(type count_t); method count_t read(); method Action load(count_t newval); method Action increment(); method Action decrement(); endinterface module mkCounter(Counter#(count_t)) provisos(Arith#(count_t), Bits#(count_t, count_t_sz)); Reg#(count_t) value <- mkReg(0); PulseWire increment_called <- mkPulseWire(); PulseWire decrement_called <- mkPulseWire(); rule do_increment(increment_called && ! decrement_called); value <= value + 1; endrule rule do_decrement(!increment_called && decrement_called); value <= value ­ 1; endrule method count_t read(); return value; endmethod method Action load(count_t newval); value <= newval; endmethod method Action increment(); increment_called.send(); endmethod method Action decrement(); decrement_called.send(); endmethod endmodule endpackage: Counter ================================================ FILE: docker/Dockerfile ================================================ FROM bsc-contrib:latest ADD . /build/ RUN apt update; apt-get -y install jq python python-ply rsync awscli ENV PATH /opt/bluespec/bin:$PATH ENV BLUESPECDIR /opt/bluespec/lib ================================================ FILE: drivers/awsf1portal/Makefile ================================================ # On Centos: sudo yum install kernel-headers V?=0 ifeq ($(V),0) Q=@ else Q= endif CURRENTDIR := $(PWD) CONNECTALDIR ?= $(CURRENTDIR)/../.. include $(CONNECTALDIR)/Makefile.version pcieportal-objs := portal.o libxdma.o xdma_cdev.o cdev_ctrl.o cdev_events.o cdev_sgdma.o cdev_xvc.o cdev_bypass.o xdma_mod.o TARGET_MODULE:=pcieportal obj-m += pcieportal.o PKG_NAME?=connectal # DKMS only looks in /usr/src PREFIX?=/usr KVERSION=$(shell uname -r) KROOT=/lib/modules/$(KVERSION)/build export BS_MOD_DIR=$(DESTDIR)/lib/modules/$(KVERSION)/connectal .PHONY: default default: pcieportal.ko ../portalmem/portalmem.ko EXTRA_CFLAGS := -I$(CONNECTALDIR)/drivers/pciportal -I$(CONNECTALDIR)/cpp -I$(CONNECTALDIR) -I$(CONNECTALDIR)/drivers/portalmem -I$(CONNECTALDIR)/generated/cpp cflags-y += -I$(PWD) ../portalmem/portalmem.ko: ../portalmem/portalmem.c cd ../portalmem; make driverversion.h: VERSION=$(VERSION) echo "#define DRIVER_VERSION \"$$VERSION\"" > driverversion.h pcieportal.ko: portal.c pcieportal.h driverversion.h $(Q)$(MAKE) -C $(KROOT) M=$(PWD) modules .PHONY: modules_check modules_check: $(Q)$(MAKE) -C $(KROOT) C=2 M=$(PWD) modules .PHONY: install install: pcieportal.ko install -d -m755 $(BS_MOD_DIR) install -m644 pcieportal.ko $(BS_MOD_DIR) install -m644 ../portalmem/portalmem.ko $(BS_MOD_DIR) ifeq ("$(DESTDIR)", "") depmod endif .PHONY: uninstall uninstall: rm -f $(BS_MOD_DIR)/pcieportal.ko rmdir --ignore-fail-on-non-empty $(BS_MOD_DIR) ifeq ("$(DESTDIR)", "") depmod endif .PHONY: clean clean: $(Q)$(MAKE) -C $(KROOT) M=$(PWD) clean cd ../portalmem; make clean .PHONY: distclean distclean: clean .PHONY: rmmod rmmod: rmmod portalmem || true rmmod pcieportal || true .PHONY: insmod insmod: rmmod insmod pcieportal.ko -chmod agu+rw /dev/portal* insmod ../portalmem/portalmem.ko chmod agu+rw /dev/portalmem PCIEPORTAL_SOURCE=$(wildcard portal.c portal_internal.h pcieportal.h version.h cdev*.[ch] *xdma*.[ch] driverversion.h) PORTALMEM_SOURCE=$(wildcard ../portalmem/*.[ch]) CONNECTAL_HEADERS=$(addprefix ../../cpp/, portal.h portalKernel.h dmaSendFd.h) GENERATED_SOURCE=$(wildcard ../../generated/cpp/*.[ch]) .PHONY: install-dkms install-dkms: rm -f driverversion.h make driverversion.h mkdir -p $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) sed "s/@VERSION@/$(VERSION)/" dkms.conf | sed "s/@PKG_NAME@/$(PKG_NAME)/" > dkms.conf.out sed "s/@VERSION@/$(VERSION)/" Makefile.dkms > Makefile.dkms.out cp -fv dkms.conf.out $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/dkms.conf cp -fv Makefile.dkms.out $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/Makefile cp -fv $(PCIEPORTAL_SOURCE) $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) cp -fv $(PORTALMEM_SOURCE) $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) cp -fv $(CONNECTAL_HEADERS) $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) cp -fv $(GENERATED_SOURCE) $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) sed -i 's|drivers/portalmem/||' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] sed -i 's|drivers/pcieportal/||' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] sed -i 's|drivers/zynqportal/||' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] sed -i 's|../../cpp/||g' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] test-dkms: rm -fr test-dkms make DESTDIR=dkms install-dkms cd dkms$(PREFIX)/src/$(PKG_NAME)-$(VERSION); make -C $(KROOT) M=$(PWD)/dkms$(PREFIX)/src/$(PKG_NAME)-$(VERSION) modules rm -fr test-dkms ================================================ FILE: drivers/awsf1portal/Makefile.dkms ================================================ obj-m += pcieportal.o obj-m += portalmem.o pcieportal-objs := portal.o libxdma.o xdma_cdev.o cdev_ctrl.o cdev_events.o cdev_sgdma.o cdev_xvc.o cdev_bypass.o xdma_mod.o pcieportal.ko: driverversion.h driverversion.h: echo "#define DRIVER_VERSION \"@VERSION@\"" > driverversion.h ================================================ FILE: drivers/awsf1portal/cdev_bypass.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #include "libxdma_api.h" #include "xdma_cdev.h" #define write_register(v,mem,off) iowrite32(v, mem) static int copy_desc_data(struct xdma_transfer *transfer, char __user *buf, size_t *buf_offset, size_t buf_size) { int i; int copy_err; int rc = 0; BUG_ON(!buf); BUG_ON(!buf_offset); /* Fill user buffer with descriptor data */ for (i = 0; i < transfer->desc_num; i++) { if (*buf_offset + sizeof(struct xdma_desc) <= buf_size) { copy_err = copy_to_user(&buf[*buf_offset], transfer->desc_virt + i, sizeof(struct xdma_desc)); if (copy_err) { dbg_sg("Copy to user buffer failed\n"); *buf_offset = buf_size; rc = -EINVAL; } else { *buf_offset += sizeof(struct xdma_desc); } } else { rc = -ENOMEM; } } return rc; } static ssize_t char_bypass_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct xdma_dev *xdev; struct xdma_engine *engine; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_transfer *transfer; struct list_head *idx; size_t buf_offset = 0; int rc = 0; rc = xcdev_check(__func__, xcdev, 1); if (rc < 0) return rc; xdev = xcdev->xdev; engine = xcdev->engine; dbg_sg("In char_bypass_read()\n"); if (count & 3) { dbg_sg("Buffer size must be a multiple of 4 bytes\n"); return -EINVAL; } if (!buf) { dbg_sg("Caught NULL pointer\n"); return -EINVAL; } if (xdev->bypass_bar_idx < 0) { dbg_sg("Bypass BAR not present - unsupported operation\n"); return -ENODEV; } spin_lock(&engine->lock); if (!list_empty(&engine->transfer_list)) { list_for_each(idx, &engine->transfer_list) { transfer = list_entry(idx, struct xdma_transfer, entry); rc = copy_desc_data(transfer, buf, &buf_offset, count); } } spin_unlock(&engine->lock); if (rc < 0) return rc; else return buf_offset; } static ssize_t char_bypass_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct xdma_dev *xdev; struct xdma_engine *engine; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; u32 desc_data; u32 *bypass_addr; size_t buf_offset = 0; int rc = 0; int copy_err; rc = xcdev_check(__func__, xcdev, 1); if (rc < 0) return rc; xdev = xcdev->xdev; engine = xcdev->engine; if (count & 3) { dbg_sg("Buffer size must be a multiple of 4 bytes\n"); return -EINVAL; } if (!buf) { dbg_sg("Caught NULL pointer\n"); return -EINVAL; } if (xdev->bypass_bar_idx < 0) { dbg_sg("Bypass BAR not present - unsupported operation\n"); return -ENODEV; } dbg_sg("In char_bypass_write()\n"); spin_lock(&engine->lock); /* Write descriptor data to the bypass BAR */ bypass_addr = (u32 *)xdev->bar[xdev->bypass_bar_idx]; bypass_addr += engine->bypass_offset; while (buf_offset < count) { copy_err = copy_from_user(&desc_data, &buf[buf_offset], sizeof(u32)); if (!copy_err) { write_register(desc_data, bypass_addr, bypass_addr - engine->bypass_offset); buf_offset += sizeof(u32); rc = buf_offset; } else { dbg_sg("Error reading data from userspace buffer\n"); rc = -EINVAL; break; } } spin_unlock(&engine->lock); return rc; } /* * character device file operations for bypass operation */ static const struct file_operations bypass_fops = { .owner = THIS_MODULE, .open = char_open, .release = char_close, .read = char_bypass_read, .write = char_bypass_write, .mmap = bridge_mmap, }; void cdev_bypass_init(struct xdma_cdev *xcdev) { cdev_init(&xcdev->cdev, &bypass_fops); } ================================================ FILE: drivers/awsf1portal/cdev_ctrl.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include #include "version.h" #include "xdma_cdev.h" #include "cdev_ctrl.h" /* * character device file operations for control bus (through control bridge) */ static ssize_t char_ctrl_read(struct file *fp, char __user *buf, size_t count, loff_t *pos) { struct xdma_cdev *xcdev = (struct xdma_cdev *)fp->private_data; struct xdma_dev *xdev; void *reg; u32 w; int rv; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; xdev = xcdev->xdev; /* only 32-bit aligned and 32-bit multiples */ if (*pos & 3) return -EPROTO; /* first address is BAR base plus file position offset */ reg = xdev->bar[xcdev->bar] + *pos; //w = read_register(reg); w = ioread32(reg); dbg_sg("char_ctrl_read(@%p, count=%ld, pos=%d) value = 0x%08x\n", reg, (long)count, (int)*pos, w); rv = copy_to_user(buf, &w, 4); if (rv) dbg_sg("Copy to userspace failed but continuing\n"); *pos += 4; return 4; } static ssize_t char_ctrl_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_dev *xdev; void *reg; u32 w; int rv; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; xdev = xcdev->xdev; /* only 32-bit aligned and 32-bit multiples */ if (*pos & 3) return -EPROTO; /* first address is BAR base plus file position offset */ reg = xdev->bar[xcdev->bar] + *pos; rv = copy_from_user(&w, buf, 4); if (rv) { pr_info("copy from user failed %d/4, but continuing.\n", rv); } dbg_sg("char_ctrl_write(0x%08x @%p, count=%ld, pos=%d)\n", w, reg, (long)count, (int)*pos); //write_register(w, reg); iowrite32(w, reg); *pos += 4; return 4; } static long version_ioctl(struct xdma_cdev *xcdev, void __user *arg) { struct xdma_ioc_info obj; struct xdma_dev *xdev = xcdev->xdev; int rv; rv = copy_from_user((void *)&obj, arg, sizeof(struct xdma_ioc_info)); if (rv) { pr_info("copy from user failed %d/%ld.\n", rv, sizeof(struct xdma_ioc_info)); return -EFAULT; } memset(&obj, 0, sizeof(obj)); obj.vendor = xdev->pdev->vendor; obj.device = xdev->pdev->device; obj.subsystem_vendor = xdev->pdev->subsystem_vendor; obj.subsystem_device = xdev->pdev->subsystem_device; obj.feature_id = xdev->feature_id; obj.driver_version = DRV_MOD_VERSION_NUMBER; obj.domain = 0; obj.bus = PCI_BUS_NUM(xdev->pdev->devfn); obj.dev = PCI_SLOT(xdev->pdev->devfn); obj.func = PCI_FUNC(xdev->pdev->devfn); if (copy_to_user(arg, &obj, sizeof(struct xdma_ioc_info))) return -EFAULT; return 0; } long char_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct xdma_cdev *xcdev = (struct xdma_cdev *)filp->private_data; struct xdma_dev *xdev; struct xdma_ioc_base ioctl_obj; long result = 0; int rv; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; xdev = xcdev->xdev; pr_info("cmd 0x%x, xdev 0x%p, pdev 0x%p.\n", cmd, xdev, xdev->pdev); if (_IOC_TYPE(cmd) != XDMA_IOC_MAGIC) { pr_err("cmd %u, bad magic 0x%x/0x%x.\n", cmd, _IOC_TYPE(cmd), XDMA_IOC_MAGIC); return -ENOTTY; } if (_IOC_DIR(cmd) & _IOC_READ) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) && !(defined(RHEL_MAJOR) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,0)) result = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); #else result = !access_ok((void __user *)arg, _IOC_SIZE(cmd)); #endif } else if (_IOC_DIR(cmd) & _IOC_WRITE) #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) && !(defined(RHEL_MAJOR) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,0)) result = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); #else result = !access_ok((void __user *)arg, _IOC_SIZE(cmd)); #endif if (result) { pr_err("bad access %ld.\n", result); return -EFAULT; } switch (cmd) { case XDMA_IOCINFO: if (copy_from_user((void *)&ioctl_obj, (void *) arg, sizeof(struct xdma_ioc_base))) { pr_err("copy_from_user failed.\n"); return -EFAULT; } if (ioctl_obj.magic != XDMA_XCL_MAGIC) { pr_err("magic 0x%x != XDMA_XCL_MAGIC (0x%x).\n", ioctl_obj.magic, XDMA_XCL_MAGIC); return -ENOTTY; } return version_ioctl(xcdev, (void __user *)arg); case XDMA_IOCOFFLINE: if (!xdev) { pr_info("cmd %u, xdev NULL.\n", cmd); return -EINVAL; } xdma_device_offline(xdev->pdev, xdev); break; case XDMA_IOCONLINE: if (!xdev) { pr_info("cmd %u, xdev NULL.\n", cmd); return -EINVAL; } xdma_device_online(xdev->pdev, xdev); break; default: pr_err("UNKNOWN ioctl cmd 0x%x.\n", cmd); return -ENOTTY; } return 0; } /* maps the PCIe BAR into user space for memory-like access using mmap() */ int bridge_mmap(struct file *file, struct vm_area_struct *vma) { struct xdma_dev *xdev; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; unsigned long off; unsigned long phys; unsigned long vsize; unsigned long psize; int rv; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; xdev = xcdev->xdev; off = vma->vm_pgoff << PAGE_SHIFT; /* BAR physical address */ phys = pci_resource_start(xdev->pdev, xcdev->bar) + off; vsize = vma->vm_end - vma->vm_start; /* complete resource */ psize = pci_resource_end(xdev->pdev, xcdev->bar) - pci_resource_start(xdev->pdev, xcdev->bar) + 1 - off; dbg_sg("mmap(): xcdev = 0x%08lx\n", (unsigned long)xcdev); dbg_sg("mmap(): cdev->bar = %d\n", xcdev->bar); dbg_sg("mmap(): xdev = 0x%p\n", xdev); dbg_sg("mmap(): pci_dev = 0x%08lx\n", (unsigned long)xdev->pdev); dbg_sg("off = 0x%lx\n", off); dbg_sg("start = 0x%llx\n", (unsigned long long)pci_resource_start(xdev->pdev, xcdev->bar)); dbg_sg("phys = 0x%lx\n", phys); if (vsize > psize) return -EINVAL; /* * pages must not be cached as this would result in cache line sized * accesses to the end point */ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* * prevent touching the pages (byte access) for swap-in, * and prevent the pages from being swapped out */ vma->vm_flags |= VMEM_FLAGS; /* make MMIO accessible to user space */ rv = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, vsize, vma->vm_page_prot); dbg_sg("vma=0x%p, vma->vm_start=0x%lx, phys=0x%lx, size=%lu = %d\n", vma, vma->vm_start, phys >> PAGE_SHIFT, vsize, rv); if (rv) return -EAGAIN; return 0; } /* * character device file operations for control bus (through control bridge) */ static const struct file_operations ctrl_fops = { .owner = THIS_MODULE, .open = char_open, .release = char_close, .read = char_ctrl_read, .write = char_ctrl_write, .mmap = bridge_mmap, .unlocked_ioctl = char_ctrl_ioctl, }; void cdev_ctrl_init(struct xdma_cdev *xcdev) { cdev_init(&xcdev->cdev, &ctrl_fops); } ================================================ FILE: drivers/awsf1portal/cdev_ctrl.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef _XDMA_IOCALLS_POSIX_H_ #define _XDMA_IOCALLS_POSIX_H_ #include /* Use 'x' as magic number */ #define XDMA_IOC_MAGIC 'x' /* XL OpenCL X->58(ASCII), L->6C(ASCII), O->0 C->C L->6C(ASCII); */ #define XDMA_XCL_MAGIC 0X586C0C6C /* * S means "Set" through a ptr, * T means "Tell" directly with the argument value * G means "Get": reply by setting through a pointer * Q means "Query": response is on the return value * X means "eXchange": switch G and S atomically * H means "sHift": switch T and Q atomically * * _IO(type,nr) no arguments * _IOR(type,nr,datatype) read data from driver * _IOW(type,nr.datatype) write data to driver * _IORW(type,nr,datatype) read/write data * * _IOC_DIR(nr) returns direction * _IOC_TYPE(nr) returns magic * _IOC_NR(nr) returns number * _IOC_SIZE(nr) returns size */ enum XDMA_IOC_TYPES { XDMA_IOC_NOP, XDMA_IOC_INFO, XDMA_IOC_OFFLINE, XDMA_IOC_ONLINE, XDMA_IOC_MAX }; struct xdma_ioc_base { unsigned int magic; unsigned int command; }; struct xdma_ioc_info { struct xdma_ioc_base base; unsigned short vendor; unsigned short device; unsigned short subsystem_vendor; unsigned short subsystem_device; unsigned int dma_engine_version; unsigned int driver_version; unsigned long long feature_id; unsigned short domain; unsigned char bus; unsigned char dev; unsigned char func; }; /* IOCTL codes */ #define XDMA_IOCINFO _IOWR(XDMA_IOC_MAGIC, XDMA_IOC_INFO, \ struct xdma_ioc_info) #define XDMA_IOCOFFLINE _IO(XDMA_IOC_MAGIC, XDMA_IOC_OFFLINE) #define XDMA_IOCONLINE _IO(XDMA_IOC_MAGIC, XDMA_IOC_ONLINE) #define IOCTL_XDMA_ADDRMODE_SET _IOW('q', 4, int) #define IOCTL_XDMA_ADDRMODE_GET _IOR('q', 5, int) #define IOCTL_XDMA_ALIGN_GET _IOR('q', 6, int) #endif /* _XDMA_IOCALLS_POSIX_H_ */ ================================================ FILE: drivers/awsf1portal/cdev_events.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include "xdma_cdev.h" /* * character device file operations for events */ static ssize_t char_events_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { int rv; struct xdma_user_irq *user_irq; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; u32 events_user; unsigned long flags; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; user_irq = xcdev->user_irq; if (!user_irq) { pr_info("xcdev 0x%p, user_irq NULL.\n", xcdev); return -EINVAL; } if (count != 4) return -EPROTO; if (*pos & 3) return -EPROTO; /* * sleep until any interrupt events have occurred, * or a signal arrived */ rv = wait_event_interruptible(user_irq->events_wq, user_irq->events_irq != 0); if (rv) dbg_sg("wait_event_interruptible=%d\n", rv); /* wait_event_interruptible() was interrupted by a signal */ if (rv == -ERESTARTSYS) return -ERESTARTSYS; /* atomically decide which events are passed to the user */ spin_lock_irqsave(&user_irq->events_lock, flags); events_user = user_irq->events_irq; user_irq->events_irq = 0; spin_unlock_irqrestore(&user_irq->events_lock, flags); rv = copy_to_user(buf, &events_user, 4); if (rv) dbg_sg("Copy to user failed but continuing\n"); return 4; } static unsigned int char_events_poll(struct file *file, poll_table *wait) { struct xdma_user_irq *user_irq; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; unsigned long flags; unsigned int mask = 0; int rv; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; user_irq = xcdev->user_irq; if (!user_irq) { pr_info("xcdev 0x%p, user_irq NULL.\n", xcdev); return -EINVAL; } poll_wait(file, &user_irq->events_wq, wait); spin_lock_irqsave(&user_irq->events_lock, flags); if (user_irq->events_irq) mask = POLLIN | POLLRDNORM; /* readable */ spin_unlock_irqrestore(&user_irq->events_lock, flags); return mask; } /* * character device file operations for the irq events */ static const struct file_operations events_fops = { .owner = THIS_MODULE, .open = char_open, .release = char_close, .read = char_events_read, .poll = char_events_poll, }; void cdev_event_init(struct xdma_cdev *xcdev) { xcdev->user_irq = &(xcdev->xdev->user_irq[xcdev->bar]); cdev_init(&xcdev->cdev, &events_fops); } ================================================ FILE: drivers/awsf1portal/cdev_sgdma.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include #include "libxdma_api.h" #include "xdma_cdev.h" #include "cdev_sgdma.h" /* Module Parameters */ unsigned int sgdma_timeout = 10; module_param(sgdma_timeout, uint, 0644); MODULE_PARM_DESC(sgdma_timeout, "timeout in seconds for sgdma, default is 10 sec."); /* * character device file operations for SG DMA engine */ static loff_t char_sgdma_llseek(struct file *file, loff_t off, int whence) { loff_t newpos = 0; switch (whence) { case 0: /* SEEK_SET */ newpos = off; break; case 1: /* SEEK_CUR */ newpos = file->f_pos + off; break; case 2: /* SEEK_END, @TODO should work from end of address space */ newpos = UINT_MAX + off; break; default: /* can't happen */ return -EINVAL; } if (newpos < 0) return -EINVAL; file->f_pos = newpos; dbg_fops("char_sgdma_llseek: pos=%lld\n", (signed long long)newpos); #if 0 pr_err("0x%p, off 0x%lld, whence %d -> pos %lld.\n", file, (signed long long)off, whence, (signed long long)off); #endif return newpos; } /* char_sgdma_read_write() -- Read from or write to the device * * @buf userspace buffer * @count number of bytes in the userspace buffer * @pos byte-address in device * @dir_to_device If !0, a write to the device is performed * * Iterate over the userspace buffer, taking at most 255 * PAGE_SIZE bytes for * each DMA transfer. * * For each transfer, get the user pages, build a sglist, map, build a * descriptor table. submit the transfer. wait for the interrupt handler * to wake us on completion. */ static int check_transfer_align(struct xdma_engine *engine, const char __user *buf, size_t count, loff_t pos, int sync) { BUG_ON(!engine); /* AXI ST or AXI MM non-incremental addressing mode? */ if (engine->non_incr_addr) { int buf_lsb = (int)((uintptr_t)buf) & (engine->addr_align - 1); size_t len_lsb = count & ((size_t)engine->len_granularity - 1); int pos_lsb = (int)pos & (engine->addr_align - 1); dbg_tfr("AXI ST or MM non-incremental\n"); dbg_tfr("buf_lsb = %d, pos_lsb = %d, len_lsb = %ld\n", buf_lsb, pos_lsb, len_lsb); if (buf_lsb != 0) { dbg_tfr("FAIL: non-aligned buffer address %p\n", buf); return -EINVAL; } if ((pos_lsb != 0) && (sync)) { dbg_tfr("FAIL: non-aligned AXI MM FPGA addr 0x%llx\n", (unsigned long long)pos); return -EINVAL; } if (len_lsb != 0) { dbg_tfr("FAIL: len %d is not a multiple of %d\n", (int)count, (int)engine->len_granularity); return -EINVAL; } /* AXI MM incremental addressing mode */ } else { int buf_lsb = (int)((uintptr_t)buf) & (engine->addr_align - 1); int pos_lsb = (int)pos & (engine->addr_align - 1); if (buf_lsb != pos_lsb) { dbg_tfr("FAIL: Misalignment error\n"); dbg_tfr("host addr %p, FPGA addr 0x%llx\n", buf, pos); return -EINVAL; } } return 0; } /* * Map a user memory range into a scatterlist * inspired by vhost_scsi_map_to_sgl() * Returns the number of scatterlist entries used or -errno on error. */ static inline void xdma_io_cb_release(struct xdma_io_cb *cb) { int i; for (i = 0; i < cb->pages_nr; i++) put_page(cb->pages[i]); sg_free_table(&cb->sgt); kfree(cb->pages); memset(cb, 0, sizeof(*cb)); } static void char_sgdma_unmap_user_buf(struct xdma_io_cb *cb, bool write) { int i; sg_free_table(&cb->sgt); if (!cb->pages || !cb->pages_nr) return; for (i = 0; i < cb->pages_nr; i++) { if (cb->pages[i]) { if (!write) set_page_dirty_lock(cb->pages[i]); put_page(cb->pages[i]); } else break; } if (i != cb->pages_nr) pr_info("sgl pages %d/%u.\n", i, cb->pages_nr); kfree(cb->pages); cb->pages = NULL; } static int char_sgdma_map_user_buf_to_sgl(struct xdma_io_cb *cb, bool write) { struct sg_table *sgt = &cb->sgt; unsigned long len = cb->len; char *buf = cb->buf; struct scatterlist *sg; unsigned int pages_nr = (((unsigned long)buf + len + PAGE_SIZE -1) - ((unsigned long)buf & PAGE_MASK)) >> PAGE_SHIFT; int i; int rv; if (pages_nr == 0) { return -EINVAL; } if (sg_alloc_table(sgt, pages_nr, GFP_KERNEL)) { pr_err("sgl OOM.\n"); return -ENOMEM; } cb->pages = kcalloc(pages_nr, sizeof(struct page *), GFP_KERNEL); if (!cb->pages) { pr_err("pages OOM.\n"); rv = -ENOMEM; goto err_out; } rv = get_user_pages_fast((unsigned long)buf, pages_nr, 1/* write */, cb->pages); /* No pages were pinned */ if (rv < 0) { pr_err("unable to pin down %u user pages, %d.\n", pages_nr, rv); goto err_out; } /* Less pages pinned than wanted */ if (rv != pages_nr) { pr_err("unable to pin down all %u user pages, %d.\n", pages_nr, rv); rv = -EFAULT; cb->pages_nr = rv; goto err_out; } for (i = 1; i < pages_nr; i++) { if (cb->pages[i - 1] == cb->pages[i]) { pr_err("duplicate pages, %d, %d.\n", i - 1, i); rv = -EFAULT; cb->pages_nr = pages_nr; goto err_out; } } sg = sgt->sgl; for (i = 0; i < pages_nr; i++, sg = sg_next(sg)) { //unsigned int offset = (uintptr_t)buf & ~PAGE_MASK; unsigned int offset = offset_in_page(buf); unsigned int nbytes = min_t(unsigned int, PAGE_SIZE - offset, len); flush_dcache_page(cb->pages[i]); sg_set_page(sg, cb->pages[i], nbytes, offset); buf += nbytes; len -= nbytes; } BUG_ON(len); cb->pages_nr = pages_nr; return 0; err_out: char_sgdma_unmap_user_buf(cb, write); return rv; } static ssize_t char_sgdma_read_write(struct file *file, char __user *buf, size_t count, loff_t *pos, bool write) { int rv; ssize_t res = 0; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_dev *xdev; struct xdma_engine *engine; struct xdma_io_cb cb; rv = xcdev_check(__func__, xcdev, 1); if (rv < 0) return rv; xdev = xcdev->xdev; engine = xcdev->engine; dbg_tfr("file 0x%p, priv 0x%p, buf 0x%p,%llu, pos %llu, W %d, %s.\n", file, file->private_data, buf, (u64)count, (u64)*pos, write, engine->name); if ((write && engine->dir != DMA_TO_DEVICE) || (!write && engine->dir != DMA_FROM_DEVICE)) { pr_err("r/w mismatch. W %d, dir %d.\n", write, engine->dir); return -EINVAL; } rv = check_transfer_align(engine, buf, count, *pos, 1); if (rv) { pr_info("Invalid transfer alignment detected\n"); return rv; } memset(&cb, 0, sizeof(struct xdma_io_cb)); cb.buf = buf; cb.len = count; rv = char_sgdma_map_user_buf_to_sgl(&cb, write); if (rv < 0) return rv; res = xdma_xfer_submit(xdev, engine->channel, write, *pos, &cb.sgt, 0, sgdma_timeout * 1000); //pr_err("xfer_submit return=%lld.\n", (s64)res); //interrupt_status(xdev); char_sgdma_unmap_user_buf(&cb, write); return res; } static ssize_t char_sgdma_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { return char_sgdma_read_write(file, (char *)buf, count, pos, 1); } static ssize_t char_sgdma_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_engine *engine; int rv; rv = xcdev_check(__func__, xcdev, 1); if (rv < 0) return rv; engine = xcdev->engine; if (engine->streaming && engine->dir == DMA_FROM_DEVICE) { rv = xdma_cyclic_transfer_setup(engine); if (rv < 0 && rv != -EBUSY) return rv; /* 600 sec. timeout */ return xdma_engine_read_cyclic(engine, buf, count, 600000); } return char_sgdma_read_write(file, (char *)buf, count, pos, 0); } static int ioctl_do_perf_start(struct xdma_engine *engine, unsigned long arg) { int rv; struct xdma_dev *xdev; BUG_ON(!engine); xdev = engine->xdev; BUG_ON(!xdev); /* performance measurement already running on this engine? */ if (engine->xdma_perf) { dbg_perf("IOCTL_XDMA_PERF_START failed!\n"); dbg_perf("Perf measurement already seems to be running!\n"); return -EBUSY; } engine->xdma_perf = kzalloc(sizeof(struct xdma_performance_ioctl), GFP_KERNEL); if (!engine->xdma_perf) return -ENOMEM; rv = copy_from_user(engine->xdma_perf, (struct xdma_performance_ioctl *)arg, sizeof(struct xdma_performance_ioctl)); if (rv < 0) { dbg_perf("Failed to copy from user space 0x%lx\n", arg); return -EINVAL; } if (engine->xdma_perf->version != IOCTL_XDMA_PERF_V1) { dbg_perf("Unsupported IOCTL version %d\n", engine->xdma_perf->version); return -EINVAL; } enable_perf(engine); dbg_perf("transfer_size = %d\n", engine->xdma_perf->transfer_size); /* initialize wait queue */ init_waitqueue_head(&engine->xdma_perf_wq); xdma_performance_submit(xdev, engine); return 0; } static int ioctl_do_perf_stop(struct xdma_engine *engine, unsigned long arg) { struct xdma_transfer *transfer = NULL; int rv; dbg_perf("IOCTL_XDMA_PERF_STOP\n"); /* no performance measurement running on this engine? */ if (!engine->xdma_perf) { dbg_perf("No measurement in progress\n"); return -EINVAL; } /* stop measurement */ transfer = engine_cyclic_stop(engine); dbg_perf("Waiting for measurement to stop\n"); if (engine->xdma_perf) { get_perf_stats(engine); rv = copy_to_user((void __user *)arg, engine->xdma_perf, sizeof(struct xdma_performance_ioctl)); if (rv) { dbg_perf("Error copying result to user\n"); return -EINVAL; } } else { dbg_perf("engine->xdma_perf == NULL?\n"); } kfree(engine->xdma_perf); engine->xdma_perf = NULL; return 0; } static int ioctl_do_perf_get(struct xdma_engine *engine, unsigned long arg) { int rc; BUG_ON(!engine); dbg_perf("IOCTL_XDMA_PERF_GET\n"); if (engine->xdma_perf) { get_perf_stats(engine); rc = copy_to_user((void __user *)arg, engine->xdma_perf, sizeof(struct xdma_performance_ioctl)); if (rc) { dbg_perf("Error copying result to user\n"); return -EINVAL; } } else { dbg_perf("engine->xdma_perf == NULL?\n"); return -EPROTO; } return 0; } static int ioctl_do_addrmode_set(struct xdma_engine *engine, unsigned long arg) { return engine_addrmode_set(engine, arg); } static int ioctl_do_addrmode_get(struct xdma_engine *engine, unsigned long arg) { int rv; unsigned long src; BUG_ON(!engine); src = !!engine->non_incr_addr; dbg_perf("IOCTL_XDMA_ADDRMODE_GET\n"); rv = put_user(src, (int __user *)arg); return rv; } static int ioctl_do_align_get(struct xdma_engine *engine, unsigned long arg) { BUG_ON(!engine); dbg_perf("IOCTL_XDMA_ALIGN_GET\n"); return put_user(engine->addr_align, (int __user *)arg); } static long char_sgdma_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_dev *xdev; struct xdma_engine *engine; int rv = 0; rv = xcdev_check(__func__, xcdev, 1); if (rv < 0) return rv; xdev = xcdev->xdev; engine = xcdev->engine; switch (cmd) { case IOCTL_XDMA_PERF_START: rv = ioctl_do_perf_start(engine, arg); break; case IOCTL_XDMA_PERF_STOP: rv = ioctl_do_perf_stop(engine, arg); break; case IOCTL_XDMA_PERF_GET: rv = ioctl_do_perf_get(engine, arg); break; case IOCTL_XDMA_ADDRMODE_SET: rv = ioctl_do_addrmode_set(engine, arg); break; case IOCTL_XDMA_ADDRMODE_GET: rv = ioctl_do_addrmode_get(engine, arg); break; case IOCTL_XDMA_ALIGN_GET: rv = ioctl_do_align_get(engine, arg); break; default: dbg_perf("Unsupported operation\n"); rv = -EINVAL; break; } return rv; } static int char_sgdma_open(struct inode *inode, struct file *file) { struct xdma_cdev *xcdev; struct xdma_engine *engine; char_open(inode, file); xcdev = (struct xdma_cdev *)file->private_data; engine = xcdev->engine; if (engine->streaming && engine->dir == DMA_FROM_DEVICE) { if (engine->device_open == 1) return -EBUSY; else engine->device_open = 1; } return 0; } static int char_sgdma_close(struct inode *inode, struct file *file) { struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_engine *engine; int rv; rv = xcdev_check(__func__, xcdev, 1); if (rv < 0) return rv; engine = xcdev->engine; if (engine->streaming && engine->dir == DMA_FROM_DEVICE) { engine->device_open = 0; if (engine->cyclic_req) return xdma_cyclic_transfer_teardown(engine); } return 0; } static const struct file_operations sgdma_fops = { .owner = THIS_MODULE, .open = char_sgdma_open, .release = char_sgdma_close, .write = char_sgdma_write, .read = char_sgdma_read, .unlocked_ioctl = char_sgdma_ioctl, .llseek = char_sgdma_llseek, }; void cdev_sgdma_init(struct xdma_cdev *xcdev) { cdev_init(&xcdev->cdev, &sgdma_fops); } ================================================ FILE: drivers/awsf1portal/cdev_sgdma.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef _XDMA_IOCALLS_POSIX_H_ #define _XDMA_IOCALLS_POSIX_H_ #include #define IOCTL_XDMA_PERF_V1 (1) #define XDMA_ADDRMODE_MEMORY (0) #define XDMA_ADDRMODE_FIXED (1) /* * S means "Set" through a ptr, * T means "Tell" directly with the argument value * G means "Get": reply by setting through a pointer * Q means "Query": response is on the return value * X means "eXchange": switch G and S atomically * H means "sHift": switch T and Q atomically * * _IO(type,nr) no arguments * _IOR(type,nr,datatype) read data from driver * _IOW(type,nr.datatype) write data to driver * _IORW(type,nr,datatype) read/write data * * _IOC_DIR(nr) returns direction * _IOC_TYPE(nr) returns magic * _IOC_NR(nr) returns number * _IOC_SIZE(nr) returns size */ struct xdma_performance_ioctl { /* IOCTL_XDMA_IOCTL_Vx */ uint32_t version; uint32_t transfer_size; /* measurement */ uint32_t stopped; uint32_t iterations; uint64_t clock_cycle_count; uint64_t data_cycle_count; uint64_t pending_count; }; /* IOCTL codes */ #define IOCTL_XDMA_PERF_START _IOW('q', 1, struct xdma_performance_ioctl *) #define IOCTL_XDMA_PERF_STOP _IOW('q', 2, struct xdma_performance_ioctl *) #define IOCTL_XDMA_PERF_GET _IOR('q', 3, struct xdma_performance_ioctl *) #define IOCTL_XDMA_ADDRMODE_SET _IOW('q', 4, int) #define IOCTL_XDMA_ADDRMODE_GET _IOR('q', 5, int) #define IOCTL_XDMA_ALIGN_GET _IOR('q', 6, int) #endif /* _XDMA_IOCALLS_POSIX_H_ */ ================================================ FILE: drivers/awsf1portal/cdev_xvc.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include "xdma_cdev.h" #include "cdev_xvc.h" #define COMPLETION_LOOP_MAX 100 #define XVC_BAR_LENGTH_REG 0x0 #define XVC_BAR_TMS_REG 0x4 #define XVC_BAR_TDI_REG 0x8 #define XVC_BAR_TDO_REG 0xC #define XVC_BAR_CTRL_REG 0x10 #ifdef __REG_DEBUG__ /* SECTION: Function definitions */ inline void __write_register(const char *fn, u32 value, void *base, unsigned int off) { pr_info("%s: 0x%p, W reg 0x%lx, 0x%x.\n", fn, base, off, value); iowrite32(value, base + off); } inline u32 __read_register(const char *fn, void *base, unsigned int off) { u32 v = ioread32(base + off); pr_info("%s: 0x%p, R reg 0x%lx, 0x%x.\n", fn, base, off, v); return v; } #define write_register(v,base,off) __write_register(__func__, v, base, off) #define read_register(base,off) __read_register(__func__, base, off) #else #define write_register(v,base,off) iowrite32(v, (base) + (off)) #define read_register(base,off) ioread32((base) + (off)) #endif /* #ifdef __REG_DEBUG__ */ static int xvc_shift_bits(void *base, u32 tms_bits, u32 tdi_bits, u32 *tdo_bits) { u32 control; int count; /* set tms bit */ write_register(tms_bits, base, XVC_BAR_TMS_REG); /* set tdi bits and shift data out */ write_register(tdi_bits, base, XVC_BAR_TDI_REG); /* enable shift operation */ write_register(0x1, base, XVC_BAR_CTRL_REG); /* poll for completion */ count = COMPLETION_LOOP_MAX; while (count) { /* read control reg to check shift operation completion */ control = read_register(base, XVC_BAR_CTRL_REG); if ((control & 0x01) == 0) break; count--; } if (!count) { pr_warn("XVC bar transaction timed out (0x%0X)\n", control); return -ETIMEDOUT; } /* read tdo bits back out */ *tdo_bits = read_register(base, XVC_BAR_TDO_REG); return 0; } static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct xdma_cdev *xcdev = (struct xdma_cdev *)filp->private_data; struct xdma_dev *xdev; struct xvc_ioc xvc_obj; unsigned int opcode; unsigned int total_bits; unsigned int total_bytes; unsigned char *buffer = NULL; unsigned char *tms_buf = NULL; unsigned char *tdi_buf = NULL; unsigned char *tdo_buf = NULL; unsigned int bits, bits_left; void __iomem *iobase; int rv; rv = xcdev_check(__func__, xcdev, 0); if (rv < 0) return rv; xdev = xcdev->xdev; if (cmd != XDMA_IOCXVC) { pr_info("ioctl 0x%x, UNKNOWN cmd.\n", cmd); return -ENOIOCTLCMD; } rv = copy_from_user((void *)&xvc_obj, (void __user *)arg, sizeof(struct xvc_ioc)); /* anything not copied ? */ if (rv) { pr_info("copy_from_user xvc_obj failed: %d.\n", rv); goto cleanup; } opcode = xvc_obj.opcode; /* Invalid operation type, no operation performed */ if (opcode != 0x01 && opcode != 0x02) { pr_info("UNKNOWN opcode 0x%x.\n", opcode); return -EINVAL; } total_bits = xvc_obj.length; total_bytes = (total_bits + 7) >> 3; buffer = (char *)kmalloc(total_bytes * 3, GFP_KERNEL); if (!buffer) { pr_info("OOM %u, op 0x%x, len %u bits, %u bytes.\n", 3 * total_bytes, opcode, total_bits, total_bytes); rv = -ENOMEM; goto cleanup; } tms_buf = buffer; tdi_buf = tms_buf + total_bytes; tdo_buf = tdi_buf + total_bytes; rv = copy_from_user((void *)tms_buf, xvc_obj.tms_buf, total_bytes); if (rv) { pr_info("copy tmfs_buf failed: %d/%u.\n", rv, total_bytes); goto cleanup; } rv = copy_from_user((void *)tdi_buf, xvc_obj.tdi_buf, total_bytes); if (rv) { pr_info("copy tdi_buf failed: %d/%u.\n", rv, total_bytes); goto cleanup; } /* exclusive access */ spin_lock(&xcdev->lock); iobase = xdev->bar[xcdev->bar] + xcdev->base; /* set length register to 32 initially if more than one * word-transaction is to be done */ if (total_bits >= 32) write_register(0x20, iobase, XVC_BAR_LENGTH_REG); for (bits = 0, bits_left = total_bits; bits < total_bits; bits += 32, bits_left -= 32) { unsigned int bytes = bits >> 3; unsigned int shift_bytes = 4; u32 tms_store = 0; u32 tdi_store = 0; u32 tdo_store = 0; if (bits_left < 32) { /* set number of bits to shift out */ write_register(bits_left, iobase, XVC_BAR_LENGTH_REG); shift_bytes = (bits_left + 7) >> 3; } memcpy(&tms_store, tms_buf + bytes, shift_bytes); memcpy(&tdi_store, tdi_buf + bytes, shift_bytes); /* Shift data out and copy to output buffer */ rv = xvc_shift_bits(iobase, tms_store, tdi_store, &tdo_store); if (rv < 0) goto cleanup; memcpy(tdo_buf + bytes, &tdo_store, shift_bytes); } /* if testing bar access swap tdi and tdo bufferes to "loopback" */ if (opcode == 0x2) { char *tmp = tdo_buf; tdo_buf = tdi_buf; tdi_buf = tmp; } rv = copy_to_user((void *)xvc_obj.tdo_buf, tdo_buf, total_bytes); if (rv) { pr_info("copy back tdo_buf failed: %d/%u.\n", rv, total_bytes); rv = -EFAULT; goto cleanup; } cleanup: if (buffer) kfree(buffer); wmb(); spin_unlock(&xcdev->lock); return rv; } /* * character device file operations for the XVC */ static const struct file_operations xvc_fops = { .owner = THIS_MODULE, .open = char_open, .release = char_close, .unlocked_ioctl = xvc_ioctl, }; void cdev_xvc_init(struct xdma_cdev *xcdev) { #ifdef __XVC_BAR_NUM__ xcdev->bar = __XVC_BAR_NUM__; #endif #ifdef __XVC_BAR_OFFSET__ xcdev->base = __XVC_BAR_OFFSET__; #else xcdev->base = XVC_BAR_OFFSET_DFLT; #endif pr_info("xcdev 0x%p, bar %u, offset 0x%lx.\n", xcdev, xcdev->bar, xcdev->base); cdev_init(&xcdev->cdev, &xvc_fops); } ================================================ FILE: drivers/awsf1portal/cdev_xvc.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef __XVC_IOCTL_H__ #define __XVC_IOCTL_H__ #include /* * !!! TODO !!! * need a better way set the bar offset dynamicly */ #define XVC_BAR_OFFSET_DFLT 0x40000 /* DSA 4.0 */ #define XVC_MAGIC 0x58564344 // "XVCD" struct xvc_ioc { unsigned int opcode; unsigned int length; unsigned char *tms_buf; unsigned char *tdi_buf; unsigned char *tdo_buf; }; #define XDMA_IOCXVC _IOWR(XVC_MAGIC, 1, struct xvc_ioc) #endif /* __XVC_IOCTL_H__ */ ================================================ FILE: drivers/awsf1portal/dkms.conf ================================================ PACKAGE_NAME="@PKG_NAME@" PACKAGE_VERSION="@VERSION@" BUILT_MODULE_NAME[0]="pcieportal" DEST_MODULE_LOCATION[0]="/extra/fpga" BUILT_MODULE_NAME[1]="portalmem" DEST_MODULE_LOCATION[1]="/extra/fpga" AUTOINSTALL="yes" ================================================ FILE: drivers/awsf1portal/driverversion.h ================================================ #define DRIVER_VERSION "" ================================================ FILE: drivers/awsf1portal/libxdma.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include #include #include #include #include #include #include #include #include "libxdma.h" #include "libxdma_api.h" #include "cdev_sgdma.h" /* SECTION: Module licensing */ #ifdef __LIBXDMA_MOD__ #include "version.h" #define DRV_MODULE_NAME "libxdma" #define DRV_MODULE_DESC "Xilinx XDMA Base Driver" #define DRV_MODULE_RELDATE "Feb. 2017" static char version[] = DRV_MODULE_DESC " " DRV_MODULE_NAME " v" DRV_MODULE_VERSION "\n"; MODULE_AUTHOR("Xilinx, Inc."); MODULE_DESCRIPTION(DRV_MODULE_DESC); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_LICENSE("GPL v2"); #endif /* Module Parameters */ static unsigned int poll_mode; module_param(poll_mode, uint, 0644); MODULE_PARM_DESC(poll_mode, "Set 1 for hw polling, default is 0 (interrupts)"); static unsigned int interrupt_mode; module_param(interrupt_mode, uint, 0644); MODULE_PARM_DESC(interrupt_mode, "0 - MSI-x , 1 - MSI, 2 - Legacy"); static unsigned int enable_credit_mp; module_param(enable_credit_mp, uint, 0644); MODULE_PARM_DESC(enable_credit_mp, "Set 1 to enable creidt feature, default is 0 (no credit control)"); unsigned int desc_blen_max = XDMA_DESC_BLEN_MAX; module_param(desc_blen_max, uint, 0644); MODULE_PARM_DESC(desc_blen_max, "per descriptor max. buffer length, default is (1 << 28) - 1"); /* * xdma device management * maintains a list of the xdma devices */ static LIST_HEAD(xdev_list); static DEFINE_MUTEX(xdev_mutex); static LIST_HEAD(xdev_rcu_list); static DEFINE_SPINLOCK(xdev_rcu_lock); #ifndef list_last_entry #define list_last_entry(ptr, type, member) \ list_entry((ptr)->prev, type, member) #endif static inline void xdev_list_add(struct xdma_dev *xdev) { mutex_lock(&xdev_mutex); if (list_empty(&xdev_list)) xdev->idx = 0; else { struct xdma_dev *last; last = list_last_entry(&xdev_list, struct xdma_dev, list_head); xdev->idx = last->idx + 1; } list_add_tail(&xdev->list_head, &xdev_list); mutex_unlock(&xdev_mutex); dbg_init("dev %s, xdev 0x%p, xdma idx %d.\n", dev_name(&xdev->pdev->dev), xdev, xdev->idx); spin_lock(&xdev_rcu_lock); list_add_tail_rcu(&xdev->rcu_node, &xdev_rcu_list); spin_unlock(&xdev_rcu_lock); } #undef list_last_entry static inline void xdev_list_remove(struct xdma_dev *xdev) { mutex_lock(&xdev_mutex); list_del(&xdev->list_head); mutex_unlock(&xdev_mutex); spin_lock(&xdev_rcu_lock); list_del_rcu(&xdev->rcu_node); spin_unlock(&xdev_rcu_lock); synchronize_rcu(); } struct xdma_dev *xdev_find_by_pdev(struct pci_dev *pdev) { struct xdma_dev *xdev, *tmp; mutex_lock(&xdev_mutex); list_for_each_entry_safe(xdev, tmp, &xdev_list, list_head) { if (xdev->pdev == pdev) { mutex_unlock(&xdev_mutex); return xdev; } } mutex_unlock(&xdev_mutex); return NULL; } EXPORT_SYMBOL_GPL(xdev_find_by_pdev); static inline int debug_check_dev_hndl(const char *fname, struct pci_dev *pdev, void *hndl) { struct xdma_dev *xdev; if (!pdev) return -EINVAL; xdev = xdev_find_by_pdev(pdev); if (!xdev) { pr_info("%s pdev 0x%p, hndl 0x%p, NO match found!\n", fname, pdev, hndl); return -EINVAL; } if (xdev != hndl) { pr_err("%s pdev 0x%p, hndl 0x%p != 0x%p!\n", fname, pdev, hndl, xdev); return -EINVAL; } return 0; } #ifdef __LIBXDMA_DEBUG__ /* SECTION: Function definitions */ inline void __write_register(const char *fn, u32 value, void *iomem, unsigned long off) { pr_err("%s: w reg 0x%lx(0x%p), 0x%x.\n", fn, off, iomem, value); iowrite32(value, iomem); } #define write_register(v,mem,off) __write_register(__func__, v, mem, off) #else #define write_register(v,mem,off) iowrite32(v, mem) #endif inline u32 read_register(void *iomem) { return ioread32(iomem); } static inline u32 build_u32(u32 hi, u32 lo) { return ((hi & 0xFFFFUL) << 16) | (lo & 0xFFFFUL); } static inline u64 build_u64(u64 hi, u64 lo) { return ((hi & 0xFFFFFFFULL) << 32) | (lo & 0xFFFFFFFFULL); } static void check_nonzero_interrupt_status(struct xdma_dev *xdev) { struct interrupt_regs *reg = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); u32 w; w = read_register(®->user_int_enable); if (w) pr_info("%s xdma%d user_int_enable = 0x%08x\n", dev_name(&xdev->pdev->dev), xdev->idx, w); w = read_register(®->channel_int_enable); if (w) pr_info("%s xdma%d channel_int_enable = 0x%08x\n", dev_name(&xdev->pdev->dev), xdev->idx, w); w = read_register(®->user_int_request); if (w) pr_info("%s xdma%d user_int_request = 0x%08x\n", dev_name(&xdev->pdev->dev), xdev->idx, w); w = read_register(®->channel_int_request); if (w) pr_info("%s xdma%d channel_int_request = 0x%08x\n", dev_name(&xdev->pdev->dev), xdev->idx, w); w = read_register(®->user_int_pending); if (w) pr_info("%s xdma%d user_int_pending = 0x%08x\n", dev_name(&xdev->pdev->dev), xdev->idx, w); w = read_register(®->channel_int_pending); if (w) pr_info("%s xdma%d channel_int_pending = 0x%08x\n", dev_name(&xdev->pdev->dev), xdev->idx, w); } /* channel_interrupts_enable -- Enable interrupts we are interested in */ static void channel_interrupts_enable(struct xdma_dev *xdev, u32 mask) { struct interrupt_regs *reg = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); write_register(mask, ®->channel_int_enable_w1s, XDMA_OFS_INT_CTRL); } /* channel_interrupts_disable -- Disable interrupts we not interested in */ static void channel_interrupts_disable(struct xdma_dev *xdev, u32 mask) { struct interrupt_regs *reg = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); write_register(mask, ®->channel_int_enable_w1c, XDMA_OFS_INT_CTRL); } /* user_interrupts_enable -- Enable interrupts we are interested in */ static void user_interrupts_enable(struct xdma_dev *xdev, u32 mask) { struct interrupt_regs *reg = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); write_register(mask, ®->user_int_enable_w1s, XDMA_OFS_INT_CTRL); } /* user_interrupts_disable -- Disable interrupts we not interested in */ static void user_interrupts_disable(struct xdma_dev *xdev, u32 mask) { struct interrupt_regs *reg = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); write_register(mask, ®->user_int_enable_w1c, XDMA_OFS_INT_CTRL); } /* read_interrupts -- Print the interrupt controller status */ static u32 read_interrupts(struct xdma_dev *xdev) { struct interrupt_regs *reg = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); u32 lo; u32 hi; /* extra debugging; inspect complete engine set of registers */ hi = read_register(®->user_int_request); dbg_io("ioread32(0x%p) returned 0x%08x (user_int_request).\n", ®->user_int_request, hi); lo = read_register(®->channel_int_request); dbg_io("ioread32(0x%p) returned 0x%08x (channel_int_request)\n", ®->channel_int_request, lo); /* return interrupts: user in upper 16-bits, channel in lower 16-bits */ return build_u32(hi, lo); } void enable_perf(struct xdma_engine *engine) { u32 w; w = XDMA_PERF_CLEAR; write_register(w, &engine->regs->perf_ctrl, (unsigned long)(&engine->regs->perf_ctrl) - (unsigned long)(&engine->regs)); read_register(&engine->regs->identifier); w = XDMA_PERF_AUTO | XDMA_PERF_RUN; write_register(w, &engine->regs->perf_ctrl, (unsigned long)(&engine->regs->perf_ctrl) - (unsigned long)(&engine->regs)); read_register(&engine->regs->identifier); dbg_perf("IOCTL_XDMA_PERF_START\n"); } EXPORT_SYMBOL_GPL(enable_perf); void get_perf_stats(struct xdma_engine *engine) { u32 hi; u32 lo; BUG_ON(!engine); if (!engine->xdma_perf) { pr_info("%s perf struct not set up.\n", engine->name); return; } hi = 0; lo = read_register(&engine->regs->completed_desc_count); engine->xdma_perf->iterations = build_u64(hi, lo); hi = read_register(&engine->regs->perf_cyc_hi); lo = read_register(&engine->regs->perf_cyc_lo); engine->xdma_perf->clock_cycle_count = build_u64(hi, lo); hi = read_register(&engine->regs->perf_dat_hi); lo = read_register(&engine->regs->perf_dat_lo); engine->xdma_perf->data_cycle_count = build_u64(hi, lo); hi = read_register(&engine->regs->perf_pnd_hi); lo = read_register(&engine->regs->perf_pnd_lo); engine->xdma_perf->pending_count = build_u64(hi, lo); } EXPORT_SYMBOL_GPL(get_perf_stats); static void engine_reg_dump(struct xdma_engine *engine) { u32 w; BUG_ON(!engine); w = read_register(&engine->regs->identifier); pr_info("%s: ioread32(0x%p) = 0x%08x (id).\n", engine->name, &engine->regs->identifier, w); w &= BLOCK_ID_MASK; if (w != BLOCK_ID_HEAD) { pr_info("%s: engine id missing, 0x%08x exp. & 0x%x = 0x%x\n", engine->name, w, BLOCK_ID_MASK, BLOCK_ID_HEAD); return; } /* extra debugging; inspect complete engine set of registers */ w = read_register(&engine->regs->status); pr_info("%s: ioread32(0x%p) = 0x%08x (status).\n", engine->name, &engine->regs->status, w); w = read_register(&engine->regs->control); pr_info("%s: ioread32(0x%p) = 0x%08x (control)\n", engine->name, &engine->regs->control, w); w = read_register(&engine->sgdma_regs->first_desc_lo); pr_info("%s: ioread32(0x%p) = 0x%08x (first_desc_lo)\n", engine->name, &engine->sgdma_regs->first_desc_lo, w); w = read_register(&engine->sgdma_regs->first_desc_hi); pr_info("%s: ioread32(0x%p) = 0x%08x (first_desc_hi)\n", engine->name, &engine->sgdma_regs->first_desc_hi, w); w = read_register(&engine->sgdma_regs->first_desc_adjacent); pr_info("%s: ioread32(0x%p) = 0x%08x (first_desc_adjacent).\n", engine->name, &engine->sgdma_regs->first_desc_adjacent, w); w = read_register(&engine->regs->completed_desc_count); pr_info("%s: ioread32(0x%p) = 0x%08x (completed_desc_count).\n", engine->name, &engine->regs->completed_desc_count, w); w = read_register(&engine->regs->interrupt_enable_mask); pr_info("%s: ioread32(0x%p) = 0x%08x (interrupt_enable_mask)\n", engine->name, &engine->regs->interrupt_enable_mask, w); } /** * engine_status_read() - read status of SG DMA engine (optionally reset) * * Stores status in engine->status. * * @return -1 on failure, status register otherwise */ static void engine_status_dump(struct xdma_engine *engine) { u32 v = engine->status; char buffer[256]; char *buf = buffer; int len = 0; len = sprintf(buf, "SG engine %s status: 0x%08x: ", engine->name, v); if ((v & XDMA_STAT_BUSY)) len += sprintf(buf + len, "BUSY,"); if ((v & XDMA_STAT_DESC_STOPPED)) len += sprintf(buf + len, "DESC_STOPPED,"); if ((v & XDMA_STAT_DESC_COMPLETED)) len += sprintf(buf + len, "DESC_COMPL,"); /* common H2C & C2H */ if ((v & XDMA_STAT_COMMON_ERR_MASK)) { if ((v & XDMA_STAT_ALIGN_MISMATCH)) len += sprintf(buf + len, "ALIGN_MISMATCH "); if ((v & XDMA_STAT_MAGIC_STOPPED)) len += sprintf(buf + len, "MAGIC_STOPPED "); if ((v & XDMA_STAT_INVALID_LEN)) len += sprintf(buf + len, "INVLIAD_LEN "); if ((v & XDMA_STAT_IDLE_STOPPED)) len += sprintf(buf + len, "IDLE_STOPPED "); buf[len - 1] = ','; } if ((engine->dir == DMA_TO_DEVICE)) { /* H2C only */ if ((v & XDMA_STAT_H2C_R_ERR_MASK)) { len += sprintf(buf + len, "R:"); if ((v & XDMA_STAT_H2C_R_UNSUPP_REQ)) len += sprintf(buf + len, "UNSUPP_REQ "); if ((v & XDMA_STAT_H2C_R_COMPL_ABORT)) len += sprintf(buf + len, "COMPL_ABORT "); if ((v & XDMA_STAT_H2C_R_PARITY_ERR)) len += sprintf(buf + len, "PARITY "); if ((v & XDMA_STAT_H2C_R_HEADER_EP)) len += sprintf(buf + len, "HEADER_EP "); if ((v & XDMA_STAT_H2C_R_UNEXP_COMPL)) len += sprintf(buf + len, "UNEXP_COMPL "); buf[len - 1] = ','; } if ((v & XDMA_STAT_H2C_W_ERR_MASK)) { len += sprintf(buf + len, "W:"); if ((v & XDMA_STAT_H2C_W_DECODE_ERR)) len += sprintf(buf + len, "DECODE_ERR "); if ((v & XDMA_STAT_H2C_W_SLAVE_ERR)) len += sprintf(buf + len, "SLAVE_ERR "); buf[len - 1] = ','; } } else { /* C2H only */ if ((v & XDMA_STAT_C2H_R_ERR_MASK)) { len += sprintf(buf + len, "R:"); if ((v & XDMA_STAT_C2H_R_DECODE_ERR)) len += sprintf(buf + len, "DECODE_ERR "); if ((v & XDMA_STAT_C2H_R_SLAVE_ERR)) len += sprintf(buf + len, "SLAVE_ERR "); buf[len - 1] = ','; } } /* common H2C & C2H */ if ((v & XDMA_STAT_DESC_ERR_MASK)) { len += sprintf(buf + len, "DESC_ERR:"); if ((v & XDMA_STAT_DESC_UNSUPP_REQ)) len += sprintf(buf + len, "UNSUPP_REQ "); if ((v & XDMA_STAT_DESC_COMPL_ABORT)) len += sprintf(buf + len, "COMPL_ABORT "); if ((v & XDMA_STAT_DESC_PARITY_ERR)) len += sprintf(buf + len, "PARITY "); if ((v & XDMA_STAT_DESC_HEADER_EP)) len += sprintf(buf + len, "HEADER_EP "); if ((v & XDMA_STAT_DESC_UNEXP_COMPL)) len += sprintf(buf + len, "UNEXP_COMPL "); buf[len - 1] = ','; } buf[len - 1] = '\0'; pr_info("%s\n", buffer); } static u32 engine_status_read(struct xdma_engine *engine, bool clear, bool dump) { u32 value; BUG_ON(!engine); if (dump) engine_reg_dump(engine); /* read status register */ if (clear) value = engine->status = read_register(&engine->regs->status_rc); else value = engine->status = read_register(&engine->regs->status); if (dump) engine_status_dump(engine); return value; } /** * xdma_engine_stop() - stop an SG DMA engine * */ static void xdma_engine_stop(struct xdma_engine *engine) { u32 w; BUG_ON(!engine); dbg_tfr("xdma_engine_stop(engine=%p)\n", engine); w = 0; w |= (u32)XDMA_CTRL_IE_DESC_ALIGN_MISMATCH; w |= (u32)XDMA_CTRL_IE_MAGIC_STOPPED; w |= (u32)XDMA_CTRL_IE_READ_ERROR; w |= (u32)XDMA_CTRL_IE_DESC_ERROR; if (poll_mode) { w |= (u32) XDMA_CTRL_POLL_MODE_WB; } else { w |= (u32)XDMA_CTRL_IE_DESC_STOPPED; w |= (u32)XDMA_CTRL_IE_DESC_COMPLETED; /* Disable IDLE STOPPED for MM */ if ((engine->streaming && (engine->dir == DMA_FROM_DEVICE)) || (engine->xdma_perf)) w |= (u32)XDMA_CTRL_IE_IDLE_STOPPED; } dbg_tfr("Stopping SG DMA %s engine; writing 0x%08x to 0x%p.\n", engine->name, w, (u32 *)&engine->regs->control); write_register(w, &engine->regs->control, (unsigned long)(&engine->regs->control) - (unsigned long)(&engine->regs)); /* dummy read of status register to flush all previous writes */ dbg_tfr("xdma_engine_stop(%s) done\n", engine->name); } static void engine_start_mode_config(struct xdma_engine *engine) { u32 w; BUG_ON(!engine); /* If a perf test is running, enable the engine interrupts */ if (engine->xdma_perf) { w = XDMA_CTRL_IE_DESC_STOPPED; w |= XDMA_CTRL_IE_DESC_COMPLETED; w |= XDMA_CTRL_IE_DESC_ALIGN_MISMATCH; w |= XDMA_CTRL_IE_MAGIC_STOPPED; w |= XDMA_CTRL_IE_IDLE_STOPPED; w |= XDMA_CTRL_IE_READ_ERROR; w |= XDMA_CTRL_IE_DESC_ERROR; write_register(w, &engine->regs->interrupt_enable_mask, (unsigned long)(&engine->regs->interrupt_enable_mask) - (unsigned long)(&engine->regs)); } /* write control register of SG DMA engine */ w = (u32)XDMA_CTRL_RUN_STOP; w |= (u32)XDMA_CTRL_IE_READ_ERROR; w |= (u32)XDMA_CTRL_IE_DESC_ERROR; w |= (u32)XDMA_CTRL_IE_DESC_ALIGN_MISMATCH; w |= (u32)XDMA_CTRL_IE_MAGIC_STOPPED; if (poll_mode) { w |= (u32)XDMA_CTRL_POLL_MODE_WB; } else { w |= (u32)XDMA_CTRL_IE_DESC_STOPPED; w |= (u32)XDMA_CTRL_IE_DESC_COMPLETED; if ((engine->streaming && (engine->dir == DMA_FROM_DEVICE)) || (engine->xdma_perf)) w |= (u32)XDMA_CTRL_IE_IDLE_STOPPED; /* set non-incremental addressing mode */ if (engine->non_incr_addr) w |= (u32)XDMA_CTRL_NON_INCR_ADDR; } dbg_tfr("iowrite32(0x%08x to 0x%p) (control)\n", w, (void *)&engine->regs->control); /* start the engine */ write_register(w, &engine->regs->control, (unsigned long)(&engine->regs->control) - (unsigned long)(&engine->regs)); /* dummy read of status register to flush all previous writes */ w = read_register(&engine->regs->status); dbg_tfr("ioread32(0x%p) = 0x%08x (dummy read flushes writes).\n", &engine->regs->status, w); } /** * engine_start() - start an idle engine with its first transfer on queue * * The engine will run and process all transfers that are queued using * transfer_queue() and thus have their descriptor lists chained. * * During the run, new transfers will be processed if transfer_queue() has * chained the descriptors before the hardware fetches the last descriptor. * A transfer that was chained too late will invoke a new run of the engine * initiated from the engine_service() routine. * * The engine must be idle and at least one transfer must be queued. * This function does not take locks; the engine spinlock must already be * taken. * */ static struct xdma_transfer *engine_start(struct xdma_engine *engine) { struct xdma_transfer *transfer; u32 w; int extra_adj = 0; /* engine must be idle */ BUG_ON(engine->running); /* engine transfer queue must not be empty */ BUG_ON(list_empty(&engine->transfer_list)); /* inspect first transfer queued on the engine */ transfer = list_entry(engine->transfer_list.next, struct xdma_transfer, entry); BUG_ON(!transfer); /* engine is no longer shutdown */ engine->shutdown = ENGINE_SHUTDOWN_NONE; dbg_tfr("engine_start(%s): transfer=0x%p.\n", engine->name, transfer); /* initialize number of descriptors of dequeued transfers */ engine->desc_dequeued = 0; /* write lower 32-bit of bus address of transfer first descriptor */ w = cpu_to_le32(PCI_DMA_L(transfer->desc_bus)); dbg_tfr("iowrite32(0x%08x to 0x%p) (first_desc_lo)\n", w, (void *)&engine->sgdma_regs->first_desc_lo); write_register(w, &engine->sgdma_regs->first_desc_lo, (unsigned long)(&engine->sgdma_regs->first_desc_lo) - (unsigned long)(&engine->sgdma_regs)); /* write upper 32-bit of bus address of transfer first descriptor */ w = cpu_to_le32(PCI_DMA_H(transfer->desc_bus)); dbg_tfr("iowrite32(0x%08x to 0x%p) (first_desc_hi)\n", w, (void *)&engine->sgdma_regs->first_desc_hi); write_register(w, &engine->sgdma_regs->first_desc_hi, (unsigned long)(&engine->sgdma_regs->first_desc_hi) - (unsigned long)(&engine->sgdma_regs)); if (transfer->desc_adjacent > 0) { extra_adj = transfer->desc_adjacent - 1; if (extra_adj > MAX_EXTRA_ADJ) extra_adj = MAX_EXTRA_ADJ; } dbg_tfr("iowrite32(0x%08x to 0x%p) (first_desc_adjacent)\n", extra_adj, (void *)&engine->sgdma_regs->first_desc_adjacent); write_register(extra_adj, &engine->sgdma_regs->first_desc_adjacent, (unsigned long)(&engine->sgdma_regs->first_desc_adjacent) - (unsigned long)(&engine->sgdma_regs)); dbg_tfr("ioread32(0x%p) (dummy read flushes writes).\n", &engine->regs->status); wmb(); engine_start_mode_config(engine); engine_status_read(engine, 0, 0); dbg_tfr("%s engine 0x%p now running\n", engine->name, engine); /* remember the engine is running */ engine->running = 1; return transfer; } /** * engine_service() - service an SG DMA engine * * must be called with engine->lock already acquired * * @engine pointer to struct xdma_engine * */ static void engine_service_shutdown(struct xdma_engine *engine) { /* if the engine stopped with RUN still asserted, de-assert RUN now */ dbg_tfr("engine just went idle, resetting RUN_STOP.\n"); xdma_engine_stop(engine); engine->running = 0; /* awake task on engine's shutdown wait queue */ wake_up_interruptible(&engine->shutdown_wq); } struct xdma_transfer *engine_transfer_completion(struct xdma_engine *engine, struct xdma_transfer *transfer) { BUG_ON(!engine); if (unlikely(!transfer)) { pr_info("%s: xfer empty.\n", engine->name); return NULL; } /* synchronous I/O? */ /* awake task on transfer's wait queue */ wake_up_interruptible(&transfer->wq); return transfer; } struct xdma_transfer *engine_service_transfer_list(struct xdma_engine *engine, struct xdma_transfer *transfer, u32 *pdesc_completed) { BUG_ON(!engine); BUG_ON(!pdesc_completed); if (unlikely(!transfer)) { pr_info("%s xfer empty, pdesc completed %u.\n", engine->name, *pdesc_completed); return NULL; } /* * iterate over all the transfers completed by the engine, * except for the last (i.e. use > instead of >=). */ while (transfer && (!transfer->cyclic) && (*pdesc_completed > transfer->desc_num)) { /* remove this transfer from pdesc_completed */ *pdesc_completed -= transfer->desc_num; dbg_tfr("%s engine completed non-cyclic xfer 0x%p (%d desc)\n", engine->name, transfer, transfer->desc_num); /* remove completed transfer from list */ list_del(engine->transfer_list.next); /* add to dequeued number of descriptors during this run */ engine->desc_dequeued += transfer->desc_num; /* mark transfer as succesfully completed */ transfer->state = TRANSFER_STATE_COMPLETED; /* Complete transfer - sets transfer to NULL if an async * transfer has completed */ transfer = engine_transfer_completion(engine, transfer); /* if exists, get the next transfer on the list */ if (!list_empty(&engine->transfer_list)) { transfer = list_entry(engine->transfer_list.next, struct xdma_transfer, entry); dbg_tfr("Non-completed transfer %p\n", transfer); } else { /* no further transfers? */ transfer = NULL; } } return transfer; } static void engine_err_handle(struct xdma_engine *engine, struct xdma_transfer *transfer, u32 desc_completed) { u32 value; /* * The BUSY bit is expected to be clear now but older HW has a race * condition which could cause it to be still set. If it's set, re-read * and check again. If it's still set, log the issue. */ if (engine->status & XDMA_STAT_BUSY) { value = read_register(&engine->regs->status); if ((value & XDMA_STAT_BUSY) && printk_ratelimit()) pr_info("%s has errors but is still BUSY\n", engine->name); } if (printk_ratelimit()) { pr_info("%s, s 0x%x, aborted xfer 0x%p, cmpl %d/%d\n", engine->name, engine->status, transfer, desc_completed, transfer->desc_num); } /* mark transfer as failed */ transfer->state = TRANSFER_STATE_FAILED; xdma_engine_stop(engine); } struct xdma_transfer *engine_service_final_transfer(struct xdma_engine *engine, struct xdma_transfer *transfer, u32 *pdesc_completed) { BUG_ON(!engine); BUG_ON(!pdesc_completed); /* inspect the current transfer */ if (unlikely(!transfer)) { pr_info("%s xfer empty, pdesc completed %u.\n", engine->name, *pdesc_completed); return NULL; } else { if (((engine->dir == DMA_FROM_DEVICE) && (engine->status & XDMA_STAT_C2H_ERR_MASK)) || ((engine->dir == DMA_TO_DEVICE) && (engine->status & XDMA_STAT_H2C_ERR_MASK))) { pr_info("engine %s, status error 0x%x.\n", engine->name, engine->status); engine_status_dump(engine); engine_err_handle(engine, transfer, *pdesc_completed); goto transfer_del; } if (engine->status & XDMA_STAT_BUSY) pr_debug("engine %s is unexpectedly busy - ignoring\n", engine->name); /* the engine stopped on current transfer? */ if (*pdesc_completed < transfer->desc_num) { transfer->state = TRANSFER_STATE_FAILED; pr_info("%s, xfer 0x%p, stopped half-way, %d/%d.\n", engine->name, transfer, *pdesc_completed, transfer->desc_num); } else { dbg_tfr("engine %s completed transfer\n", engine->name); dbg_tfr("Completed transfer ID = 0x%p\n", transfer); dbg_tfr("*pdesc_completed=%d, transfer->desc_num=%d", *pdesc_completed, transfer->desc_num); if (!transfer->cyclic) { /* * if the engine stopped on this transfer, * it should be the last */ WARN_ON(*pdesc_completed > transfer->desc_num); } /* mark transfer as succesfully completed */ transfer->state = TRANSFER_STATE_COMPLETED; } transfer_del: /* remove completed transfer from list */ list_del(engine->transfer_list.next); /* add to dequeued number of descriptors during this run */ engine->desc_dequeued += transfer->desc_num; /* * Complete transfer - sets transfer to NULL if an asynchronous * transfer has completed */ transfer = engine_transfer_completion(engine, transfer); } return transfer; } static void engine_service_perf(struct xdma_engine *engine, u32 desc_completed) { BUG_ON(!engine); /* performance measurement is running? */ if (engine->xdma_perf) { /* a descriptor was completed? */ if (engine->status & XDMA_STAT_DESC_COMPLETED) { engine->xdma_perf->iterations = desc_completed; dbg_perf("transfer->xdma_perf->iterations=%d\n", engine->xdma_perf->iterations); } /* a descriptor stopped the engine? */ if (engine->status & XDMA_STAT_DESC_STOPPED) { engine->xdma_perf->stopped = 1; /* * wake any XDMA_PERF_IOCTL_STOP waiting for * the performance run to finish */ wake_up_interruptible(&engine->xdma_perf_wq); dbg_perf("transfer->xdma_perf stopped\n"); } } } static void engine_transfer_dequeue(struct xdma_engine *engine) { struct xdma_transfer *transfer; BUG_ON(!engine); /* pick first transfer on the queue (was submitted to the engine) */ transfer = list_entry(engine->transfer_list.next, struct xdma_transfer, entry); if (!transfer || transfer != &engine->cyclic_req->xfer) { pr_info("%s, xfer 0x%p != 0x%p.\n", engine->name, transfer, &engine->cyclic_req->xfer); return; } dbg_tfr("%s engine completed cyclic transfer 0x%p (%d desc).\n", engine->name, transfer, transfer->desc_num); /* remove completed transfer from list */ list_del(engine->transfer_list.next); } static int engine_ring_process(struct xdma_engine *engine) { struct xdma_result *result; int start; int eop_count = 0; BUG_ON(!engine); result = engine->cyclic_result; BUG_ON(!result); /* where we start receiving in the ring buffer */ start = engine->rx_tail; /* iterate through all newly received RX result descriptors */ dbg_tfr("%s, result %d, 0x%x, len 0x%x.\n", engine->name, engine->rx_tail, result[engine->rx_tail].status, result[engine->rx_tail].length); while (result[engine->rx_tail].status && !engine->rx_overrun) { /* EOP bit set in result? */ if (result[engine->rx_tail].status & RX_STATUS_EOP){ eop_count++; } /* increment tail pointer */ engine->rx_tail = (engine->rx_tail + 1) % CYCLIC_RX_PAGES_MAX; dbg_tfr("%s, head %d, tail %d, 0x%x, len 0x%x.\n", engine->name, engine->rx_head, engine->rx_tail, result[engine->rx_tail].status, result[engine->rx_tail].length); /* overrun? */ if (engine->rx_tail == engine->rx_head) { dbg_tfr("%s: overrun\n", engine->name); /* flag to user space that overrun has occurred */ engine->rx_overrun = 1; } } return eop_count; } static int engine_service_cyclic_polled(struct xdma_engine *engine) { int eop_count = 0; int rc = 0; struct xdma_poll_wb *writeback_data; u32 sched_limit = 0; BUG_ON(!engine); BUG_ON(engine->magic != MAGIC_ENGINE); writeback_data = (struct xdma_poll_wb *)engine->poll_mode_addr_virt; while (eop_count == 0) { if (sched_limit != 0) { if ((sched_limit % NUM_POLLS_PER_SCHED) == 0) schedule(); } sched_limit++; /* Monitor descriptor writeback address for errors */ if ((writeback_data->completed_desc_count) & WB_ERR_MASK) { rc = -1; break; } eop_count = engine_ring_process(engine); } if (eop_count == 0) { engine_status_read(engine, 1, 0); if ((engine->running) && !(engine->status & XDMA_STAT_BUSY)) { /* transfers on queue? */ if (!list_empty(&engine->transfer_list)) engine_transfer_dequeue(engine); engine_service_shutdown(engine); } } return rc; } static int engine_service_cyclic_interrupt(struct xdma_engine *engine) { int eop_count = 0; struct xdma_transfer *xfer; BUG_ON(!engine); BUG_ON(engine->magic != MAGIC_ENGINE); engine_status_read(engine, 1, 0); eop_count = engine_ring_process(engine); /* * wake any reader on EOP, as one or more packets are now in * the RX buffer */ xfer = &engine->cyclic_req->xfer; if(enable_credit_mp){ if (eop_count > 0) { //engine->eop_found = 1; } wake_up_interruptible(&xfer->wq); }else{ if (eop_count > 0) { /* awake task on transfer's wait queue */ dbg_tfr("wake_up_interruptible() due to %d EOP's\n", eop_count); engine->eop_found = 1; wake_up_interruptible(&xfer->wq); } } /* engine was running but is no longer busy? */ if ((engine->running) && !(engine->status & XDMA_STAT_BUSY)) { /* transfers on queue? */ if (!list_empty(&engine->transfer_list)) engine_transfer_dequeue(engine); engine_service_shutdown(engine); } return 0; } /* must be called with engine->lock already acquired */ static int engine_service_cyclic(struct xdma_engine *engine) { int rc = 0; dbg_tfr("engine_service_cyclic()"); BUG_ON(!engine); BUG_ON(engine->magic != MAGIC_ENGINE); if (poll_mode) rc = engine_service_cyclic_polled(engine); else rc = engine_service_cyclic_interrupt(engine); return rc; } static void engine_service_resume(struct xdma_engine *engine) { struct xdma_transfer *transfer_started; BUG_ON(!engine); /* engine stopped? */ if (!engine->running) { /* in the case of shutdown, let it finish what's in the Q */ if (!list_empty(&engine->transfer_list)) { /* (re)start engine */ transfer_started = engine_start(engine); pr_info("re-started %s engine with pending xfer 0x%p\n", engine->name, transfer_started); /* engine was requested to be shutdown? */ } else if (engine->shutdown & ENGINE_SHUTDOWN_REQUEST) { engine->shutdown |= ENGINE_SHUTDOWN_IDLE; /* awake task on engine's shutdown wait queue */ wake_up_interruptible(&engine->shutdown_wq); } else { dbg_tfr("no pending transfers, %s engine stays idle.\n", engine->name); } } else { /* engine is still running? */ if (list_empty(&engine->transfer_list)) { pr_warn("no queued transfers but %s engine running!\n", engine->name); WARN_ON(1); } } } /** * engine_service() - service an SG DMA engine * * must be called with engine->lock already acquired * * @engine pointer to struct xdma_engine * */ static int engine_service(struct xdma_engine *engine, int desc_writeback) { struct xdma_transfer *transfer = NULL; u32 desc_count = desc_writeback & WB_COUNT_MASK; u32 err_flag = desc_writeback & WB_ERR_MASK; int rv = 0; struct xdma_poll_wb *wb_data; BUG_ON(!engine); /* If polling detected an error, signal to the caller */ if (err_flag) rv = -1; /* Service the engine */ if (!engine->running) { dbg_tfr("Engine was not running!!! Clearing status\n"); engine_status_read(engine, 1, 0); return 0; } /* * If called by the ISR or polling detected an error, read and clear * engine status. For polled mode descriptor completion, this read is * unnecessary and is skipped to reduce latency */ if ((desc_count == 0) || (err_flag != 0)) engine_status_read(engine, 1, 0); /* * engine was running but is no longer busy, or writeback occurred, * shut down */ if ((engine->running && !(engine->status & XDMA_STAT_BUSY)) || (desc_count != 0)) engine_service_shutdown(engine); /* * If called from the ISR, or if an error occurred, the descriptor * count will be zero. In this scenario, read the descriptor count * from HW. In polled mode descriptor completion, this read is * unnecessary and is skipped to reduce latency */ if (!desc_count) desc_count = read_register(&engine->regs->completed_desc_count); dbg_tfr("desc_count = %d\n", desc_count); /* transfers on queue? */ if (!list_empty(&engine->transfer_list)) { /* pick first transfer on queue (was submitted to the engine) */ transfer = list_entry(engine->transfer_list.next, struct xdma_transfer, entry); dbg_tfr("head of queue transfer 0x%p has %d descriptors\n", transfer, (int)transfer->desc_num); dbg_tfr("Engine completed %d desc, %d not yet dequeued\n", (int)desc_count, (int)desc_count - engine->desc_dequeued); engine_service_perf(engine, desc_count); } /* account for already dequeued transfers during this engine run */ desc_count -= engine->desc_dequeued; /* Process all but the last transfer */ transfer = engine_service_transfer_list(engine, transfer, &desc_count); /* * Process final transfer - includes checks of number of descriptors to * detect faulty completion */ transfer = engine_service_final_transfer(engine, transfer, &desc_count); /* Before starting engine again, clear the writeback data */ if (poll_mode) { wb_data = (struct xdma_poll_wb *)engine->poll_mode_addr_virt; wb_data->completed_desc_count = 0; } /* Restart the engine following the servicing */ engine_service_resume(engine); return 0; } /* engine_service_work */ static void engine_service_work(struct work_struct *work) { struct xdma_engine *engine; unsigned long flags; engine = container_of(work, struct xdma_engine, work); BUG_ON(engine->magic != MAGIC_ENGINE); /* lock the engine */ spin_lock_irqsave(&engine->lock, flags); dbg_tfr("engine_service() for %s engine %p\n", engine->name, engine); if (engine->cyclic_req) engine_service_cyclic(engine); else engine_service(engine, 0); /* re-enable interrupts for this engine */ if (engine->xdev->msix_enabled){ write_register(engine->interrupt_enable_mask_value, &engine->regs->interrupt_enable_mask_w1s, (unsigned long)(&engine->regs->interrupt_enable_mask_w1s) - (unsigned long)(&engine->regs)); } else channel_interrupts_enable(engine->xdev, engine->irq_bitmask); /* unlock the engine */ spin_unlock_irqrestore(&engine->lock, flags); } static u32 engine_service_wb_monitor(struct xdma_engine *engine, u32 expected_wb) { struct xdma_poll_wb *wb_data; u32 desc_wb = 0; u32 sched_limit = 0; unsigned long timeout; BUG_ON(!engine); wb_data = (struct xdma_poll_wb *)engine->poll_mode_addr_virt; /* * Poll the writeback location for the expected number of * descriptors / error events This loop is skipped for cyclic mode, * where the expected_desc_count passed in is zero, since it cannot be * determined before the function is called */ timeout = jiffies + (POLL_TIMEOUT_SECONDS * HZ); while (expected_wb != 0) { desc_wb = wb_data->completed_desc_count; if (desc_wb & WB_ERR_MASK) break; else if (desc_wb == expected_wb) break; /* RTO - prevent system from hanging in polled mode */ if (time_after(jiffies, timeout)) { dbg_tfr("Polling timeout occurred"); dbg_tfr("desc_wb = 0x%08x, expected 0x%08x\n", desc_wb, expected_wb); if ((desc_wb & WB_COUNT_MASK) > expected_wb) desc_wb = expected_wb | WB_ERR_MASK; break; } /* * Define NUM_POLLS_PER_SCHED to limit how much time is spent * in the scheduler */ if (sched_limit != 0) { if ((sched_limit % NUM_POLLS_PER_SCHED) == 0) schedule(); } sched_limit++; } return desc_wb; } static int engine_service_poll(struct xdma_engine *engine, u32 expected_desc_count) { struct xdma_poll_wb *writeback_data; u32 desc_wb = 0; unsigned long flags; int rv = 0; BUG_ON(!engine); BUG_ON(engine->magic != MAGIC_ENGINE); writeback_data = (struct xdma_poll_wb *)engine->poll_mode_addr_virt; if ((expected_desc_count & WB_COUNT_MASK) != expected_desc_count) { dbg_tfr("Queued descriptor count is larger than supported\n"); return -1; } /* * Poll the writeback location for the expected number of * descriptors / error events This loop is skipped for cyclic mode, * where the expected_desc_count passed in is zero, since it cannot be * determined before the function is called */ desc_wb = engine_service_wb_monitor(engine, expected_desc_count); spin_lock_irqsave(&engine->lock, flags); dbg_tfr("%s service.\n", engine->name); if (engine->cyclic_req) { rv = engine_service_cyclic(engine); } else { rv = engine_service(engine, desc_wb); } spin_unlock_irqrestore(&engine->lock, flags); return rv; } static irqreturn_t user_irq_service(int irq, struct xdma_user_irq *user_irq) { unsigned long flags; BUG_ON(!user_irq); if (user_irq->handler) return user_irq->handler(user_irq->user_idx, user_irq->dev); spin_lock_irqsave(&(user_irq->events_lock), flags); if (!user_irq->events_irq) { user_irq->events_irq = 1; wake_up_interruptible(&(user_irq->events_wq)); } spin_unlock_irqrestore(&(user_irq->events_lock), flags); return IRQ_HANDLED; } /* * xdma_isr() - Interrupt handler * * @dev_id pointer to xdma_dev */ static irqreturn_t xdma_isr(int irq, void *dev_id) { u32 ch_irq; u32 user_irq; u32 mask; struct xdma_dev *xdev; struct interrupt_regs *irq_regs; dbg_irq("(irq=%d, dev 0x%p) <<<< ISR.\n", irq, dev_id); BUG_ON(!dev_id); xdev = (struct xdma_dev *)dev_id; if (!xdev) { WARN_ON(!xdev); dbg_irq("xdma_isr(irq=%d) xdev=%p ??\n", irq, xdev); return IRQ_NONE; } irq_regs = (struct interrupt_regs *)(xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); /* read channel interrupt requests */ ch_irq = read_register(&irq_regs->channel_int_request); dbg_irq("ch_irq = 0x%08x\n", ch_irq); /* * disable all interrupts that fired; these are re-enabled individually * after the causing module has been fully serviced. */ if (ch_irq) channel_interrupts_disable(xdev, ch_irq); /* read user interrupts - this read also flushes the above write */ user_irq = read_register(&irq_regs->user_int_request); dbg_irq("user_irq = 0x%08x\n", user_irq); if (user_irq) { int user = 0; u32 mask = 1; int max = xdev->h2c_channel_max; for (; user < max && user_irq; user++, mask <<= 1) { if (user_irq & mask) { user_irq &= ~mask; user_irq_service(irq, &xdev->user_irq[user]); } } } mask = ch_irq & xdev->mask_irq_h2c; if (mask) { int channel = 0; int max = xdev->h2c_channel_max; /* iterate over H2C (PCIe read) */ for (channel = 0; channel < max && mask; channel++) { struct xdma_engine *engine = &xdev->engine_h2c[channel]; /* engine present and its interrupt fired? */ if((engine->irq_bitmask & mask) && (engine->magic == MAGIC_ENGINE)) { mask &= ~engine->irq_bitmask; dbg_tfr("schedule_work, %s.\n", engine->name); schedule_work(&engine->work); } } } mask = ch_irq & xdev->mask_irq_c2h; if (mask) { int channel = 0; int max = xdev->c2h_channel_max; /* iterate over C2H (PCIe write) */ for (channel = 0; channel < max && mask; channel++) { struct xdma_engine *engine = &xdev->engine_c2h[channel]; /* engine present and its interrupt fired? */ if((engine->irq_bitmask & mask) && (engine->magic == MAGIC_ENGINE)) { mask &= ~engine->irq_bitmask; dbg_tfr("schedule_work, %s.\n", engine->name); schedule_work(&engine->work); } } } xdev->irq_count++; return IRQ_HANDLED; } /* * xdma_user_irq() - Interrupt handler for user interrupts in MSI-X mode * * @dev_id pointer to xdma_dev */ static irqreturn_t xdma_user_irq(int irq, void *dev_id) { struct xdma_user_irq *user_irq; dbg_irq("(irq=%d) <<<< INTERRUPT SERVICE ROUTINE\n", irq); BUG_ON(!dev_id); user_irq = (struct xdma_user_irq *)dev_id; return user_irq_service(irq, user_irq); } /* * xdma_channel_irq() - Interrupt handler for channel interrupts in MSI-X mode * * @dev_id pointer to xdma_dev */ static irqreturn_t xdma_channel_irq(int irq, void *dev_id) { struct xdma_dev *xdev; struct xdma_engine *engine; struct interrupt_regs *irq_regs; dbg_irq("(irq=%d) <<<< INTERRUPT service ROUTINE\n", irq); BUG_ON(!dev_id); engine = (struct xdma_engine *)dev_id; xdev = engine->xdev; if (!xdev) { WARN_ON(!xdev); dbg_irq("xdma_channel_irq(irq=%d) xdev=%p ??\n", irq, xdev); return IRQ_NONE; } irq_regs = (struct interrupt_regs *)(xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); /* Disable the interrupt for this engine */ write_register(engine->interrupt_enable_mask_value, &engine->regs->interrupt_enable_mask_w1c, (unsigned long) (&engine->regs->interrupt_enable_mask_w1c) - (unsigned long)(&engine->regs)); /* Dummy read to flush the above write */ read_register(&irq_regs->channel_int_pending); /* Schedule the bottom half */ schedule_work(&engine->work); /* * RTO - need to protect access here if multiple MSI-X are used for * user interrupts */ xdev->irq_count++; return IRQ_HANDLED; } /* * Unmap the BAR regions that had been mapped earlier using map_bars() */ static void unmap_bars(struct xdma_dev *xdev, struct pci_dev *dev) { int i; for (i = 0; i < XDMA_BAR_NUM; i++) { /* is this BAR mapped? */ if (xdev->bar[i]) { /* unmap BAR */ pci_iounmap(dev, xdev->bar[i]); /* mark as unmapped */ xdev->bar[i] = NULL; } } } static int map_single_bar(struct xdma_dev *xdev, struct pci_dev *dev, int idx) { resource_size_t bar_start; resource_size_t bar_len; resource_size_t map_len; bar_start = pci_resource_start(dev, idx); bar_len = pci_resource_len(dev, idx); map_len = bar_len; xdev->bar[idx] = NULL; /* do not map BARs with length 0. Note that start MAY be 0! */ if (!bar_len) { //pr_info("BAR #%d is not present - skipping\n", idx); return 0; } /* BAR size exceeds maximum desired mapping? */ if (bar_len > INT_MAX) { pr_info("Limit BAR %d mapping from %llu to %d bytes\n", idx, (u64)bar_len, INT_MAX); map_len = (resource_size_t)INT_MAX; } /* * map the full device memory or IO region into kernel virtual * address space */ dbg_init("BAR%d: %llu bytes to be mapped.\n", idx, (u64)map_len); xdev->bar[idx] = pci_iomap(dev, idx, map_len); if (!xdev->bar[idx]) { pr_info("Could not map BAR %d.\n", idx); return -1; } pr_info("BAR%d at 0x%llx mapped at 0x%p, length=%llu(/%llu)\n", idx, (u64)bar_start, xdev->bar[idx], (u64)map_len, (u64)bar_len); return (int)map_len; } static int is_config_bar(struct xdma_dev *xdev, int idx) { u32 irq_id = 0; u32 cfg_id = 0; int flag = 0; u32 mask = 0xffff0000; /* Compare only XDMA ID's not Version number */ struct interrupt_regs *irq_regs = (struct interrupt_regs *) (xdev->bar[idx] + XDMA_OFS_INT_CTRL); struct config_regs *cfg_regs = (struct config_regs *)(xdev->bar[idx] + XDMA_OFS_CONFIG); irq_id = read_register(&irq_regs->identifier); cfg_id = read_register(&cfg_regs->identifier); if (((irq_id & mask)== IRQ_BLOCK_ID) && ((cfg_id & mask)== CONFIG_BLOCK_ID)) { dbg_init("BAR %d is the XDMA config BAR\n", idx); flag = 1; } else { dbg_init("BAR %d is NOT the XDMA config BAR: 0x%x, 0x%x.\n", idx, irq_id, cfg_id); flag = 0; } return flag; } static void identify_bars(struct xdma_dev *xdev, int *bar_id_list, int num_bars, int config_bar_pos) { /* * The following logic identifies which BARs contain what functionality * based on the position of the XDMA config BAR and the number of BARs * detected. The rules are that the user logic and bypass logic BARs * are optional. When both are present, the XDMA config BAR will be the * 2nd BAR detected (config_bar_pos = 1), with the user logic being * detected first and the bypass being detected last. When one is * omitted, the type of BAR present can be identified by whether the * XDMA config BAR is detected first or last. When both are omitted, * only the XDMA config BAR is present. This somewhat convoluted * approach is used instead of relying on BAR numbers in order to work * correctly with both 32-bit and 64-bit BARs. */ BUG_ON(!xdev); BUG_ON(!bar_id_list); dbg_init("xdev 0x%p, bars %d, config at %d.\n", xdev, num_bars, config_bar_pos); switch (num_bars) { case 1: /* Only one BAR present - no extra work necessary */ break; case 2: if (config_bar_pos == 0) { xdev->bypass_bar_idx = bar_id_list[1]; } else if (config_bar_pos == 1) { xdev->user_bar_idx = bar_id_list[0]; } else { pr_info("2, XDMA config BAR unexpected %d.\n", config_bar_pos); } break; case 3: case 4: if ((config_bar_pos == 1) || (config_bar_pos == 2)) { /* user bar at bar #0 */ xdev->user_bar_idx = bar_id_list[0]; /* bypass bar at the last bar */ xdev->bypass_bar_idx = bar_id_list[num_bars - 1]; } else { pr_info("3/4, XDMA config BAR unexpected %d.\n", config_bar_pos); } break; default: /* Should not occur - warn user but safe to continue */ pr_info("Unexpected # BARs (%d), XDMA config BAR only.\n", num_bars); break; } pr_info("%d BARs: config %d, user %d, bypass %d.\n", num_bars, config_bar_pos, xdev->user_bar_idx, xdev->bypass_bar_idx); } /* map_bars() -- map device regions into kernel virtual address space * * Map the device memory regions into kernel virtual address space after * verifying their sizes respect the minimum sizes needed */ static int map_bars(struct xdma_dev *xdev, struct pci_dev *dev) { int rv; int i; int bar_id_list[XDMA_BAR_NUM]; int bar_id_idx = 0; int config_bar_pos = 0; /* iterate through all the BARs */ for (i = 0; i < XDMA_BAR_NUM; i++) { int bar_len; bar_len = map_single_bar(xdev, dev, i); if (bar_len == 0) { continue; } else if (bar_len < 0) { rv = -EINVAL; goto fail; } /* Try to identify BAR as XDMA control BAR */ if ((bar_len >= XDMA_BAR_SIZE) && (xdev->config_bar_idx < 0) && i == XDMA_CONFIG_BAR_NUM) { if (is_config_bar(xdev, i)) { xdev->config_bar_idx = i; config_bar_pos = bar_id_idx; pr_info("config bar %d, pos %d.\n", xdev->config_bar_idx, config_bar_pos); } } bar_id_list[bar_id_idx] = i; bar_id_idx++; } /* The XDMA config BAR must always be present */ if (xdev->config_bar_idx < 0) { pr_info("Failed to detect XDMA config BAR\n"); rv = -EINVAL; goto fail; } identify_bars(xdev, bar_id_list, bar_id_idx, config_bar_pos); /* successfully mapped all required BAR regions */ return 0; fail: /* unwind; unmap any BARs that we did map */ unmap_bars(xdev, dev); return rv; } /* * MSI-X interrupt: * vectors, followed by vectors */ /* * RTO - code to detect if MSI/MSI-X capability exists is derived * from linux/pci/msi.c - pci_msi_check_device */ #ifndef arch_msi_check_device int arch_msi_check_device(struct pci_dev *dev, int nvec, int type) { return 0; } #endif /* type = PCI_CAP_ID_MSI or PCI_CAP_ID_MSIX */ static int msi_msix_capable(struct pci_dev *dev, int type) { struct pci_bus *bus; int ret; if (!dev || dev->no_msi) return 0; for (bus = dev->bus; bus; bus = bus->parent) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) return 0; ret = arch_msi_check_device(dev, 1, type); if (ret) return 0; if (!pci_find_capability(dev, type)) return 0; return 1; } static void disable_msi_msix(struct xdma_dev *xdev, struct pci_dev *pdev) { if (xdev->msix_enabled) { pci_disable_msix(pdev); xdev->msix_enabled = 0; } else if (xdev->msi_enabled) { pci_disable_msi(pdev); xdev->msi_enabled = 0; } } static int enable_msi_msix(struct xdma_dev *xdev, struct pci_dev *pdev) { int rv = 0; BUG_ON(!xdev); BUG_ON(!pdev); if (!interrupt_mode && msi_msix_capable(pdev, PCI_CAP_ID_MSIX)) { int req_nvec = xdev->c2h_channel_max + xdev->h2c_channel_max + xdev->user_max; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) dbg_init("Enabling MSI-X\n"); rv = pci_alloc_irq_vectors(pdev, req_nvec, req_nvec, PCI_IRQ_MSIX); #else int i; dbg_init("Enabling MSI-X\n"); for (i = 0; i < req_nvec; i++) xdev->entry[i].entry = i; rv = pci_enable_msix(pdev, xdev->entry, req_nvec); #endif if (rv < 0) dbg_init("Couldn't enable MSI-X mode: %d\n", rv); xdev->msix_enabled = 1; } else if (interrupt_mode == 1 && msi_msix_capable(pdev, PCI_CAP_ID_MSI)) { /* enable message signalled interrupts */ dbg_init("pci_enable_msi()\n"); rv = pci_enable_msi(pdev); if (rv < 0) dbg_init("Couldn't enable MSI mode: %d\n", rv); xdev->msi_enabled = 1; } else { dbg_init("MSI/MSI-X not detected - using legacy interrupts\n"); } return rv; } static void pci_check_intr_pend(struct pci_dev *pdev) { u16 v; pci_read_config_word(pdev, PCI_STATUS, &v); if (v & PCI_STATUS_INTERRUPT) { pr_info("%s PCI STATUS Interrupt pending 0x%x.\n", dev_name(&pdev->dev), v); pci_write_config_word(pdev, PCI_STATUS, PCI_STATUS_INTERRUPT); } } static void pci_keep_intx_enabled(struct pci_dev *pdev) { /* workaround to a h/w bug: * when msix/msi become unavaile, default to legacy. * However the legacy enable was not checked. * If the legacy was disabled, no ack then everything stuck */ u16 pcmd, pcmd_new; pci_read_config_word(pdev, PCI_COMMAND, &pcmd); pcmd_new = pcmd & ~PCI_COMMAND_INTX_DISABLE; if (pcmd_new != pcmd) { pr_info("%s: clear INTX_DISABLE, 0x%x -> 0x%x.\n", dev_name(&pdev->dev), pcmd, pcmd_new); pci_write_config_word(pdev, PCI_COMMAND, pcmd_new); } } static void prog_irq_msix_user(struct xdma_dev *xdev, bool clear) { /* user */ struct interrupt_regs *int_regs = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); u32 i = xdev->c2h_channel_max + xdev->h2c_channel_max; u32 max = i + xdev->user_max; int j; for (j = 0; i < max; j++) { u32 val = 0; int k; int shift = 0; if (clear) i += 4; else for (k = 0; k < 4 && i < max; i++, k++, shift += 8) val |= (i & 0x1f) << shift; write_register(val, &int_regs->user_msi_vector[j], XDMA_OFS_INT_CTRL + ((unsigned long)&int_regs->user_msi_vector[j] - (unsigned long)int_regs)); dbg_init("vector %d, 0x%x.\n", j, val); } } static void prog_irq_msix_channel(struct xdma_dev *xdev, bool clear) { struct interrupt_regs *int_regs = (struct interrupt_regs *) (xdev->bar[xdev->config_bar_idx] + XDMA_OFS_INT_CTRL); u32 max = xdev->c2h_channel_max + xdev->h2c_channel_max; u32 i; int j; /* engine */ for (i = 0, j = 0; i < max; j++) { u32 val = 0; int k; int shift = 0; if (clear) i += 4; else for (k = 0; k < 4 && i < max; i++, k++, shift += 8) val |= (i & 0x1f) << shift; write_register(val, &int_regs->channel_msi_vector[j], XDMA_OFS_INT_CTRL + ((unsigned long)&int_regs->channel_msi_vector[j] - (unsigned long)int_regs)); dbg_init("vector %d, 0x%x.\n", j, val); } } static void irq_msix_channel_teardown(struct xdma_dev *xdev) { struct xdma_engine *engine; int j = 0; int i = 0; if (!xdev->msix_enabled) return; prog_irq_msix_channel(xdev, 1); engine = xdev->engine_h2c; for (i = 0; i < xdev->h2c_channel_max; i++, j++, engine++) { if (!engine->msix_irq_line) break; dbg_sg("Release IRQ#%d for engine %p\n", engine->msix_irq_line, engine); free_irq(engine->msix_irq_line, engine); } engine = xdev->engine_c2h; for (i = 0; i < xdev->c2h_channel_max; i++, j++, engine++) { if (!engine->msix_irq_line) break; dbg_sg("Release IRQ#%d for engine %p\n", engine->msix_irq_line, engine); free_irq(engine->msix_irq_line, engine); } } static int irq_msix_channel_setup(struct xdma_dev *xdev) { int i; int j = xdev->h2c_channel_max; int rv = 0; u32 vector; struct xdma_engine *engine; BUG_ON(!xdev); if (!xdev->msix_enabled) return 0; engine = xdev->engine_h2c; for (i = 0; i < xdev->h2c_channel_max; i++, engine++) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) vector = pci_irq_vector(xdev->pdev, i); #else vector = xdev->entry[i].vector; #endif rv = request_irq(vector, xdma_channel_irq, 0, xdev->mod_name, engine); if (rv) { pr_info("requesti irq#%d failed %d, engine %s.\n", vector, rv, engine->name); return rv; } pr_info("engine %s, irq#%d.\n", engine->name, vector); engine->msix_irq_line = vector; } engine = xdev->engine_c2h; for (i = 0; i < xdev->c2h_channel_max; i++, j++, engine++) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) vector = pci_irq_vector(xdev->pdev, j); #else vector = xdev->entry[j].vector; #endif rv = request_irq(vector, xdma_channel_irq, 0, xdev->mod_name, engine); if (rv) { pr_info("requesti irq#%d failed %d, engine %s.\n", vector, rv, engine->name); return rv; } pr_info("engine %s, irq#%d.\n", engine->name, vector); engine->msix_irq_line = vector; } return 0; } static void irq_msix_user_teardown(struct xdma_dev *xdev) { int i; int j = xdev->h2c_channel_max + xdev->c2h_channel_max; BUG_ON(!xdev); if (!xdev->msix_enabled) return; prog_irq_msix_user(xdev, 1); if (0) for (i = 0; i < xdev->user_max; i++, j++) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) u32 vector = pci_irq_vector(xdev->pdev, j); #else u32 vector = xdev->entry[j].vector; #endif dbg_init("user %d, releasing IRQ#%d\n", i, vector); free_irq(vector, &xdev->user_irq[i]); } } static int irq_msix_user_setup(struct xdma_dev *xdev) { int i; int j = xdev->h2c_channel_max + xdev->c2h_channel_max; int rv = 0; printk("irq_msix_user_setup min %d max %d\n", xdev->h2c_channel_max + xdev->c2h_channel_max, xdev->user_max); /* vectors set in probe_scan_for_msi() */ if (0) { for (i = 0; i < xdev->user_max; i++, j++) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) u32 vector = pci_irq_vector(xdev->pdev, j); #else u32 vector = xdev->entry[j].vector; #endif rv = request_irq(vector, xdma_user_irq, 0, xdev->mod_name, &xdev->user_irq[i]); if (rv) { pr_info("user %d couldn't use IRQ#%d, %d\n", i, vector, rv); break; } pr_info("%d-USR-%d, IRQ#%d with 0x%p\n", xdev->idx, i, vector, &xdev->user_irq[i]); } } /* If any errors occur, free IRQs that were successfully requested */ if (rv) { for (i--, j--; i >= 0; i--, j--) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) u32 vector = pci_irq_vector(xdev->pdev, j); #else u32 vector = xdev->entry[j].vector; #endif free_irq(vector, &xdev->user_irq[i]); } } return rv; } static int irq_msi_setup(struct xdma_dev *xdev, struct pci_dev *pdev) { int rv; xdev->irq_line = (int)pdev->irq; rv = request_irq(pdev->irq, xdma_isr, 0, xdev->mod_name, xdev); if (rv) dbg_init("Couldn't use IRQ#%d, %d\n", pdev->irq, rv); else dbg_init("Using IRQ#%d with 0x%p\n", pdev->irq, xdev); return rv; } static int irq_legacy_setup(struct xdma_dev *xdev, struct pci_dev *pdev) { u32 w; u8 val; void *reg; int rv; pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &val); dbg_init("Legacy Interrupt register value = %d\n", val); if (val > 1) { val--; w = (val<<24) | (val<<16) | (val<<8)| val; /* Program IRQ Block Channel vactor and IRQ Block User vector * with Legacy interrupt value */ reg = xdev->bar[xdev->config_bar_idx] + 0x2080; // IRQ user write_register(w, reg, 0x2080); write_register(w, reg+0x4, 0x2084); write_register(w, reg+0x8, 0x2088); write_register(w, reg+0xC, 0x208C); reg = xdev->bar[xdev->config_bar_idx] + 0x20A0; // IRQ Block write_register(w, reg, 0x20A0); write_register(w, reg+0x4, 0x20A4); } xdev->irq_line = (int)pdev->irq; rv = request_irq(pdev->irq, xdma_isr, IRQF_SHARED, xdev->mod_name, xdev); if (rv) dbg_init("Couldn't use IRQ#%d, %d\n", pdev->irq, rv); else dbg_init("Using IRQ#%d with 0x%p\n", pdev->irq, xdev); return rv; } static void irq_teardown(struct xdma_dev *xdev) { if (xdev->msix_enabled) { irq_msix_channel_teardown(xdev); irq_msix_user_teardown(xdev); } else if (xdev->irq_line != -1) { dbg_init("Releasing IRQ#%d\n", xdev->irq_line); free_irq(xdev->irq_line, xdev); } } static int irq_setup(struct xdma_dev *xdev, struct pci_dev *pdev) { pci_keep_intx_enabled(pdev); if (xdev->msix_enabled) { int rv = irq_msix_channel_setup(xdev); if (rv) return rv; rv = irq_msix_user_setup(xdev); if (rv) return rv; prog_irq_msix_channel(xdev, 0); prog_irq_msix_user(xdev, 0); return 0; } else if (xdev->msi_enabled) return irq_msi_setup(xdev, pdev); return irq_legacy_setup(xdev, pdev); } #ifdef __LIBXDMA_DEBUG__ static void dump_desc(struct xdma_desc *desc_virt) { int j; u32 *p = (u32 *)desc_virt; static char * const field_name[] = { "magic|extra_adjacent|control", "bytes", "src_addr_lo", "src_addr_hi", "dst_addr_lo", "dst_addr_hi", "next_addr", "next_addr_pad"}; char *dummy; /* remove warning about unused variable when debug printing is off */ dummy = field_name[0]; for (j = 0; j < 8; j += 1) { pr_info("0x%08lx/0x%02lx: 0x%08x 0x%08x %s\n", (uintptr_t)p, (uintptr_t)p & 15, (int)*p, le32_to_cpu(*p), field_name[j]); p++; } pr_info("\n"); } static void transfer_dump(struct xdma_transfer *transfer) { int i; struct xdma_desc *desc_virt = transfer->desc_virt; pr_info("xfer 0x%p, state 0x%x, f 0x%x, dir %d, len %u, last %d.\n", transfer, transfer->state, transfer->flags, transfer->dir, transfer->len, transfer->last_in_request); pr_info("transfer 0x%p, desc %d, bus 0x%llx, adj %d.\n", transfer, transfer->desc_num, (u64)transfer->desc_bus, transfer->desc_adjacent); for (i = 0; i < transfer->desc_num; i += 1) dump_desc(desc_virt + i); } #endif /* __LIBXDMA_DEBUG__ */ /* xdma_desc_alloc() - Allocate cache-coherent array of N descriptors. * * Allocates an array of 'number' descriptors in contiguous PCI bus addressable * memory. Chains the descriptors as a singly-linked list; the descriptor's * next * pointer specifies the bus address of the next descriptor. * * * @dev Pointer to pci_dev * @number Number of descriptors to be allocated * @desc_bus_p Pointer where to store the first descriptor bus address * * @return Virtual address of the first descriptor * */ static void transfer_desc_init(struct xdma_transfer *transfer, int count) { struct xdma_desc *desc_virt = transfer->desc_virt; dma_addr_t desc_bus = transfer->desc_bus; int i; int adj = count - 1; int extra_adj; u32 temp_control; BUG_ON(count > XDMA_TRANSFER_MAX_DESC); /* create singly-linked list for SG DMA controller */ for (i = 0; i < count - 1; i++) { /* increment bus address to next in array */ desc_bus += sizeof(struct xdma_desc); /* singly-linked list uses bus addresses */ desc_virt[i].next_lo = cpu_to_le32(PCI_DMA_L(desc_bus)); desc_virt[i].next_hi = cpu_to_le32(PCI_DMA_H(desc_bus)); desc_virt[i].bytes = cpu_to_le32(0); /* any adjacent descriptors? */ if (adj > 0) { extra_adj = adj - 1; if (extra_adj > MAX_EXTRA_ADJ) extra_adj = MAX_EXTRA_ADJ; adj--; } else { extra_adj = 0; } temp_control = DESC_MAGIC | (extra_adj << 8); desc_virt[i].control = cpu_to_le32(temp_control); } /* { i = number - 1 } */ /* zero the last descriptor next pointer */ desc_virt[i].next_lo = cpu_to_le32(0); desc_virt[i].next_hi = cpu_to_le32(0); desc_virt[i].bytes = cpu_to_le32(0); temp_control = DESC_MAGIC; desc_virt[i].control = cpu_to_le32(temp_control); } /* xdma_desc_link() - Link two descriptors * * Link the first descriptor to a second descriptor, or terminate the first. * * @first first descriptor * @second second descriptor, or NULL if first descriptor must be set as last. * @second_bus bus address of second descriptor */ static void xdma_desc_link(struct xdma_desc *first, struct xdma_desc *second, dma_addr_t second_bus) { /* * remember reserved control in first descriptor, but zero * extra_adjacent! */ /* RTO - what's this about? Shouldn't it be 0x0000c0ffUL? */ u32 control = le32_to_cpu(first->control) & 0x0000f0ffUL; /* second descriptor given? */ if (second) { /* * link last descriptor of 1st array to first descriptor of * 2nd array */ first->next_lo = cpu_to_le32(PCI_DMA_L(second_bus)); first->next_hi = cpu_to_le32(PCI_DMA_H(second_bus)); WARN_ON(first->next_hi); /* no second descriptor given */ } else { /* first descriptor is the last */ first->next_lo = 0; first->next_hi = 0; } /* merge magic, extra_adjacent and control field */ control |= DESC_MAGIC; /* write bytes and next_num */ first->control = cpu_to_le32(control); } /* xdma_desc_adjacent -- Set how many descriptors are adjacent to this one */ static void xdma_desc_adjacent(struct xdma_desc *desc, int next_adjacent) { int extra_adj = 0; /* remember reserved and control bits */ u32 control = le32_to_cpu(desc->control) & 0x0000f0ffUL; u32 max_adj_4k = 0; if (next_adjacent > 0) { extra_adj = next_adjacent - 1; if (extra_adj > MAX_EXTRA_ADJ){ extra_adj = MAX_EXTRA_ADJ; } max_adj_4k = (0x1000 - ((le32_to_cpu(desc->next_lo))&0xFFF))/32 - 1; if (extra_adj>max_adj_4k) { extra_adj = max_adj_4k; } if(extra_adj<0){ printk("Warning: extra_adj<0, converting it to 0\n"); extra_adj = 0; } } /* merge adjacent and control field */ control |= 0xAD4B0000UL | (extra_adj << 8); /* write control and next_adjacent */ desc->control = cpu_to_le32(control); } /* xdma_desc_control -- Set complete control field of a descriptor. */ static void xdma_desc_control_set(struct xdma_desc *first, u32 control_field) { /* remember magic and adjacent number */ u32 control = le32_to_cpu(first->control) & ~(LS_BYTE_MASK); BUG_ON(control_field & ~(LS_BYTE_MASK)); /* merge adjacent and control field */ control |= control_field; /* write control and next_adjacent */ first->control = cpu_to_le32(control); } /* xdma_desc_clear -- Clear bits in control field of a descriptor. */ static void xdma_desc_control_clear(struct xdma_desc *first, u32 clear_mask) { /* remember magic and adjacent number */ u32 control = le32_to_cpu(first->control); BUG_ON(clear_mask & ~(LS_BYTE_MASK)); /* merge adjacent and control field */ control &= (~clear_mask); /* write control and next_adjacent */ first->control = cpu_to_le32(control); } /* xdma_desc_done - recycle cache-coherent linked list of descriptors. * * @dev Pointer to pci_dev * @number Number of descriptors to be allocated * @desc_virt Pointer to (i.e. virtual address of) first descriptor in list * @desc_bus Bus address of first descriptor in list */ static inline void xdma_desc_done(struct xdma_desc *desc_virt) { memset(desc_virt, 0, XDMA_TRANSFER_MAX_DESC * sizeof(struct xdma_desc)); } /* xdma_desc() - Fill a descriptor with the transfer details * * @desc pointer to descriptor to be filled * @addr root complex address * @ep_addr end point address * @len number of bytes, must be a (non-negative) multiple of 4. * @dir, dma direction * is the end point address. If zero, vice versa. * * Does not modify the next pointer */ static void xdma_desc_set(struct xdma_desc *desc, dma_addr_t rc_bus_addr, u64 ep_addr, int len, int dir) { /* transfer length */ desc->bytes = cpu_to_le32(len); if (dir == DMA_TO_DEVICE) { /* read from root complex memory (source address) */ desc->src_addr_lo = cpu_to_le32(PCI_DMA_L(rc_bus_addr)); desc->src_addr_hi = cpu_to_le32(PCI_DMA_H(rc_bus_addr)); /* write to end point address (destination address) */ desc->dst_addr_lo = cpu_to_le32(PCI_DMA_L(ep_addr)); desc->dst_addr_hi = cpu_to_le32(PCI_DMA_H(ep_addr)); } else { /* read from end point address (source address) */ desc->src_addr_lo = cpu_to_le32(PCI_DMA_L(ep_addr)); desc->src_addr_hi = cpu_to_le32(PCI_DMA_H(ep_addr)); /* write to root complex memory (destination address) */ desc->dst_addr_lo = cpu_to_le32(PCI_DMA_L(rc_bus_addr)); desc->dst_addr_hi = cpu_to_le32(PCI_DMA_H(rc_bus_addr)); } } /* * should hold the engine->lock; */ static void transfer_abort(struct xdma_engine *engine, struct xdma_transfer *transfer) { struct xdma_transfer *head; BUG_ON(!engine); BUG_ON(!transfer); BUG_ON(transfer->desc_num == 0); pr_info("abort transfer 0x%p, desc %d, engine desc queued %d.\n", transfer, transfer->desc_num, engine->desc_dequeued); head = list_entry(engine->transfer_list.next, struct xdma_transfer, entry); if (head == transfer) list_del(engine->transfer_list.next); else pr_info("engine %s, transfer 0x%p NOT found, 0x%p.\n", engine->name, transfer, head); if (transfer->state == TRANSFER_STATE_SUBMITTED) transfer->state = TRANSFER_STATE_ABORTED; } /* transfer_queue() - Queue a DMA transfer on the engine * * @engine DMA engine doing the transfer * @transfer DMA transfer submitted to the engine * * Takes and releases the engine spinlock */ static int transfer_queue(struct xdma_engine *engine, struct xdma_transfer *transfer) { int rv = 0; struct xdma_transfer *transfer_started; struct xdma_dev *xdev; unsigned long flags; BUG_ON(!engine); BUG_ON(!engine->xdev); BUG_ON(!transfer); BUG_ON(transfer->desc_num == 0); dbg_tfr("transfer_queue(transfer=0x%p).\n", transfer); xdev = engine->xdev; if (xdma_device_flag_check(xdev, XDEV_FLAG_OFFLINE)) { pr_info("dev 0x%p offline, transfer 0x%p not queued.\n", xdev, transfer); return -EBUSY; } /* lock the engine state */ spin_lock_irqsave(&engine->lock, flags); engine->prev_cpu = get_cpu(); put_cpu(); /* engine is being shutdown; do not accept new transfers */ if (engine->shutdown & ENGINE_SHUTDOWN_REQUEST) { pr_info("engine %s offline, transfer 0x%p not queued.\n", engine->name, transfer); rv = -EBUSY; goto shutdown; } /* mark the transfer as submitted */ transfer->state = TRANSFER_STATE_SUBMITTED; /* add transfer to the tail of the engine transfer queue */ list_add_tail(&transfer->entry, &engine->transfer_list); /* engine is idle? */ if (!engine->running) { /* start engine */ dbg_tfr("transfer_queue(): starting %s engine.\n", engine->name); transfer_started = engine_start(engine); dbg_tfr("transfer=0x%p started %s engine with transfer 0x%p.\n", transfer, engine->name, transfer_started); } else { dbg_tfr("transfer=0x%p queued, with %s engine running.\n", transfer, engine->name); } shutdown: /* unlock the engine state */ dbg_tfr("engine->running = %d\n", engine->running); spin_unlock_irqrestore(&engine->lock, flags); return rv; } static void engine_alignments(struct xdma_engine *engine) { u32 w; u32 align_bytes; u32 granularity_bytes; u32 address_bits; w = read_register(&engine->regs->alignments); dbg_init("engine %p name %s alignments=0x%08x\n", engine, engine->name, (int)w); /* RTO - add some macros to extract these fields */ align_bytes = (w & 0x00ff0000U) >> 16; granularity_bytes = (w & 0x0000ff00U) >> 8; address_bits = (w & 0x000000ffU); dbg_init("align_bytes = %d\n", align_bytes); dbg_init("granularity_bytes = %d\n", granularity_bytes); dbg_init("address_bits = %d\n", address_bits); if (w) { engine->addr_align = align_bytes; engine->len_granularity = granularity_bytes; engine->addr_bits = address_bits; } else { /* Some default values if alignments are unspecified */ engine->addr_align = 1; engine->len_granularity = 1; engine->addr_bits = 64; } } static void engine_free_resource(struct xdma_engine *engine) { struct xdma_dev *xdev = engine->xdev; /* Release memory use for descriptor writebacks */ if (engine->poll_mode_addr_virt) { dbg_sg("Releasing memory for descriptor writeback\n"); dma_free_coherent(&xdev->pdev->dev, sizeof(struct xdma_poll_wb), engine->poll_mode_addr_virt, engine->poll_mode_bus); dbg_sg("Released memory for descriptor writeback\n"); engine->poll_mode_addr_virt = NULL; } if (engine->desc) { dbg_init("device %s, engine %s pre-alloc desc 0x%p,0x%llx.\n", dev_name(&xdev->pdev->dev), engine->name, engine->desc, engine->desc_bus); dma_free_coherent(&xdev->pdev->dev, XDMA_TRANSFER_MAX_DESC * sizeof(struct xdma_desc), engine->desc, engine->desc_bus); engine->desc = NULL; } if (engine->cyclic_result) { dma_free_coherent(&xdev->pdev->dev, CYCLIC_RX_PAGES_MAX * sizeof(struct xdma_result), engine->cyclic_result, engine->cyclic_result_bus); engine->cyclic_result = NULL; } } static void engine_destroy(struct xdma_dev *xdev, struct xdma_engine *engine) { BUG_ON(!xdev); BUG_ON(!engine); dbg_sg("Shutting down engine %s%d", engine->name, engine->channel); /* Disable interrupts to stop processing new events during shutdown */ write_register(0x0, &engine->regs->interrupt_enable_mask, (unsigned long)(&engine->regs->interrupt_enable_mask) - (unsigned long)(&engine->regs)); if (enable_credit_mp && engine->streaming && engine->dir == DMA_FROM_DEVICE) { u32 reg_value = (0x1 << engine->channel) << 16; struct sgdma_common_regs *reg = (struct sgdma_common_regs *) (xdev->bar[xdev->config_bar_idx] + (0x6*TARGET_SPACING)); write_register(reg_value, ®->credit_mode_enable_w1c, 0); } /* Release memory use for descriptor writebacks */ engine_free_resource(engine); memset(engine, 0, sizeof(struct xdma_engine)); /* Decrement the number of engines available */ xdev->engines_num--; } /** *engine_cyclic_stop() - stop a cyclic transfer running on an SG DMA engine * *engine->lock must be taken */ struct xdma_transfer *engine_cyclic_stop(struct xdma_engine *engine) { struct xdma_transfer *transfer = 0; /* transfers on queue? */ if (!list_empty(&engine->transfer_list)) { /* pick first transfer on the queue (was submitted to engine) */ transfer = list_entry(engine->transfer_list.next, struct xdma_transfer, entry); BUG_ON(!transfer); xdma_engine_stop(engine); if (transfer->cyclic) { if (engine->xdma_perf) dbg_perf("Stopping perf transfer on %s\n", engine->name); else dbg_perf("Stopping cyclic transfer on %s\n", engine->name); /* make sure the handler sees correct transfer state */ transfer->cyclic = 1; /* * set STOP flag and interrupt on completion, on the * last descriptor */ xdma_desc_control_set( transfer->desc_virt + transfer->desc_num - 1, XDMA_DESC_COMPLETED | XDMA_DESC_STOPPED); } else { dbg_sg("(engine=%p) running transfer is not cyclic\n", engine); } } else { dbg_sg("(engine=%p) found not running transfer.\n", engine); } return transfer; } EXPORT_SYMBOL_GPL(engine_cyclic_stop); static int engine_writeback_setup(struct xdma_engine *engine) { u32 w; struct xdma_dev *xdev; struct xdma_poll_wb *writeback; BUG_ON(!engine); xdev = engine->xdev; BUG_ON(!xdev); /* * RTO - doing the allocation per engine is wasteful since a full page * is allocated each time - better to allocate one page for the whole * device during probe() and set per-engine offsets here */ writeback = (struct xdma_poll_wb *)engine->poll_mode_addr_virt; writeback->completed_desc_count = 0; dbg_init("Setting writeback location to 0x%llx for engine %p", engine->poll_mode_bus, engine); w = cpu_to_le32(PCI_DMA_L(engine->poll_mode_bus)); write_register(w, &engine->regs->poll_mode_wb_lo, (unsigned long)(&engine->regs->poll_mode_wb_lo) - (unsigned long)(&engine->regs)); w = cpu_to_le32(PCI_DMA_H(engine->poll_mode_bus)); write_register(w, &engine->regs->poll_mode_wb_hi, (unsigned long)(&engine->regs->poll_mode_wb_hi) - (unsigned long)(&engine->regs)); return 0; } /* engine_create() - Create an SG DMA engine bookkeeping data structure * * An SG DMA engine consists of the resources for a single-direction transfer * queue; the SG DMA hardware, the software queue and interrupt handling. * * @dev Pointer to pci_dev * @offset byte address offset in BAR[xdev->config_bar_idx] resource for the * SG DMA * controller registers. * @dir: DMA_TO/FROM_DEVICE * @streaming Whether the engine is attached to AXI ST (rather than MM) */ static int engine_init_regs(struct xdma_engine *engine) { u32 reg_value; int rv = 0; write_register(XDMA_CTRL_NON_INCR_ADDR, &engine->regs->control_w1c, (unsigned long)(&engine->regs->control_w1c) - (unsigned long)(&engine->regs)); engine_alignments(engine); /* Configure error interrupts by default */ reg_value = XDMA_CTRL_IE_DESC_ALIGN_MISMATCH; reg_value |= XDMA_CTRL_IE_MAGIC_STOPPED; reg_value |= XDMA_CTRL_IE_MAGIC_STOPPED; reg_value |= XDMA_CTRL_IE_READ_ERROR; reg_value |= XDMA_CTRL_IE_DESC_ERROR; /* if using polled mode, configure writeback address */ if (poll_mode) { rv = engine_writeback_setup(engine); if (rv) { dbg_init("%s descr writeback setup failed.\n", engine->name); goto fail_wb; } } else { /* enable the relevant completion interrupts */ reg_value |= XDMA_CTRL_IE_DESC_STOPPED; reg_value |= XDMA_CTRL_IE_DESC_COMPLETED; if (engine->streaming && engine->dir == DMA_FROM_DEVICE) reg_value |= XDMA_CTRL_IE_IDLE_STOPPED; } /* Apply engine configurations */ write_register(reg_value, &engine->regs->interrupt_enable_mask, (unsigned long)(&engine->regs->interrupt_enable_mask) - (unsigned long)(&engine->regs)); engine->interrupt_enable_mask_value = reg_value; /* only enable credit mode for AXI-ST C2H */ if (enable_credit_mp && engine->streaming && engine->dir == DMA_FROM_DEVICE) { struct xdma_dev *xdev = engine->xdev; u32 reg_value = (0x1 << engine->channel) << 16; struct sgdma_common_regs *reg = (struct sgdma_common_regs *) (xdev->bar[xdev->config_bar_idx] + (0x6*TARGET_SPACING)); write_register(reg_value, ®->credit_mode_enable_w1s, 0); } return 0; fail_wb: return rv; } static int engine_alloc_resource(struct xdma_engine *engine) { struct xdma_dev *xdev = engine->xdev; engine->desc = dma_alloc_coherent(&xdev->pdev->dev, XDMA_TRANSFER_MAX_DESC * sizeof(struct xdma_desc), &engine->desc_bus, GFP_KERNEL); if (!engine->desc) { pr_warn("dev %s, %s pre-alloc desc OOM.\n", dev_name(&xdev->pdev->dev), engine->name); goto err_out; } if (poll_mode) { engine->poll_mode_addr_virt = dma_alloc_coherent( &xdev->pdev->dev, sizeof(struct xdma_poll_wb), &engine->poll_mode_bus, GFP_KERNEL); if (!engine->poll_mode_addr_virt) { pr_warn("%s, %s poll pre-alloc writeback OOM.\n", dev_name(&xdev->pdev->dev), engine->name); goto err_out; } } if (engine->streaming && engine->dir == DMA_FROM_DEVICE) { engine->cyclic_result = dma_alloc_coherent(&xdev->pdev->dev, CYCLIC_RX_PAGES_MAX * sizeof(struct xdma_result), &engine->cyclic_result_bus, GFP_KERNEL); if (!engine->cyclic_result) { pr_warn("%s, %s pre-alloc result OOM.\n", dev_name(&xdev->pdev->dev), engine->name); goto err_out; } } return 0; err_out: engine_free_resource(engine); return -ENOMEM; } static int engine_init(struct xdma_engine *engine, struct xdma_dev *xdev, int offset, enum dma_data_direction dir, int channel) { int rv; u32 val; dbg_init("channel %d, offset 0x%x, dir %d.\n", channel, offset, dir); /* set magic */ engine->magic = MAGIC_ENGINE; engine->channel = channel; /* engine interrupt request bit */ engine->irq_bitmask = (1 << XDMA_ENG_IRQ_NUM) - 1; engine->irq_bitmask <<= (xdev->engines_num * XDMA_ENG_IRQ_NUM); engine->bypass_offset = xdev->engines_num * BYPASS_MODE_SPACING; /* parent */ engine->xdev = xdev; /* register address */ engine->regs = (xdev->bar[xdev->config_bar_idx] + offset); engine->sgdma_regs = xdev->bar[xdev->config_bar_idx] + offset + SGDMA_OFFSET_FROM_CHANNEL; val = read_register(&engine->regs->identifier); if (val & 0x8000U) engine->streaming = 1; /* remember SG DMA direction */ engine->dir = dir; sprintf(engine->name, "%d-%s%d-%s", xdev->idx, (dir == DMA_TO_DEVICE) ? "H2C" : "C2H", channel, engine->streaming ? "ST" : "MM"); dbg_init("engine %p name %s irq_bitmask=0x%08x\n", engine, engine->name, (int)engine->irq_bitmask); /* initialize the deferred work for transfer completion */ INIT_WORK(&engine->work, engine_service_work); if (dir == DMA_TO_DEVICE) xdev->mask_irq_h2c |= engine->irq_bitmask; else xdev->mask_irq_c2h |= engine->irq_bitmask; xdev->engines_num++; rv = engine_alloc_resource(engine); if (rv) return rv; rv = engine_init_regs(engine); if (rv) return rv; return 0; } /* transfer_destroy() - free transfer */ static void transfer_destroy(struct xdma_dev *xdev, struct xdma_transfer *xfer) { /* free descriptors */ xdma_desc_done(xfer->desc_virt); if (xfer->last_in_request && (xfer->flags & XFER_FLAG_NEED_UNMAP)) { struct sg_table *sgt = xfer->sgt; if (sgt->nents) { pci_unmap_sg(xdev->pdev, sgt->sgl, sgt->nents, xfer->dir); sgt->nents = 0; } } } static int transfer_build(struct xdma_engine *engine, struct xdma_request_cb *req, unsigned int desc_max) { struct xdma_transfer *xfer = &req->xfer; struct sw_desc *sdesc = &(req->sdesc[req->sw_desc_idx]); int i = 0; int j = 0; for (; i < desc_max; i++, j++, sdesc++) { dbg_desc("sw desc %d/%u: 0x%llx, 0x%x, ep 0x%llx.\n", i + req->sw_desc_idx, req->sw_desc_cnt, sdesc->addr, sdesc->len, req->ep_addr); /* fill in descriptor entry j with transfer details */ xdma_desc_set(xfer->desc_virt + j, sdesc->addr, req->ep_addr, sdesc->len, xfer->dir); xfer->len += sdesc->len; /* for non-inc-add mode don't increment ep_addr */ if (!engine->non_incr_addr) req->ep_addr += sdesc->len; } req->sw_desc_idx += desc_max; return 0; } static int transfer_init(struct xdma_engine *engine, struct xdma_request_cb *req) { struct xdma_transfer *xfer = &req->xfer; unsigned int desc_max = min_t(unsigned int, req->sw_desc_cnt - req->sw_desc_idx, XDMA_TRANSFER_MAX_DESC); int i = 0; int last = 0; u32 control; memset(xfer, 0, sizeof(*xfer)); /* initialize wait queue */ init_waitqueue_head(&xfer->wq); /* remember direction of transfer */ xfer->dir = engine->dir; xfer->desc_virt = engine->desc; xfer->desc_bus = engine->desc_bus; transfer_desc_init(xfer, desc_max); dbg_sg("transfer->desc_bus = 0x%llx.\n", (u64)xfer->desc_bus); transfer_build(engine, req, desc_max); /* terminate last descriptor */ last = desc_max - 1; xdma_desc_link(xfer->desc_virt + last, 0, 0); /* stop engine, EOP for AXI ST, req IRQ on last descriptor */ control = XDMA_DESC_STOPPED; control |= XDMA_DESC_EOP; control |= XDMA_DESC_COMPLETED; xdma_desc_control_set(xfer->desc_virt + last, control); xfer->desc_num = xfer->desc_adjacent = desc_max; dbg_sg("transfer 0x%p has %d descriptors\n", xfer, xfer->desc_num); /* fill in adjacent numbers */ for (i = 0; i < xfer->desc_num; i++) xdma_desc_adjacent(xfer->desc_virt + i, xfer->desc_num - i - 1); return 0; } #ifdef __LIBXDMA_DEBUG__ static void sgt_dump(struct sg_table *sgt) { int i; struct scatterlist *sg = sgt->sgl; pr_info("sgt 0x%p, sgl 0x%p, nents %u/%u.\n", sgt, sgt->sgl, sgt->nents, sgt->orig_nents); for (i = 0; i < sgt->orig_nents; i++, sg = sg_next(sg)) pr_info("%d, 0x%p, pg 0x%p,%u+%u, dma 0x%llx,%u.\n", i, sg, sg_page(sg), sg->offset, sg->length, sg_dma_address(sg), sg_dma_len(sg)); } static void xdma_request_cb_dump(struct xdma_request_cb *req) { int i; pr_info("request 0x%p, total %u, ep 0x%llx, sw_desc %u, sgt 0x%p.\n", req, req->total_len, req->ep_addr, req->sw_desc_cnt, req->sgt); sgt_dump(req->sgt); for (i = 0; i < req->sw_desc_cnt; i++) pr_info("%d/%u, 0x%llx, %u.\n", i, req->sw_desc_cnt, req->sdesc[i].addr, req->sdesc[i].len); } #endif static void xdma_request_free(struct xdma_request_cb *req) { if (((unsigned long)req) >= VMALLOC_START && ((unsigned long)req) < VMALLOC_END) vfree(req); else kfree(req); } static struct xdma_request_cb * xdma_request_alloc(unsigned int sdesc_nr) { struct xdma_request_cb *req; unsigned int size = sizeof(struct xdma_request_cb) + sdesc_nr * sizeof(struct sw_desc); req = kzalloc(size, GFP_KERNEL); if (!req) { req = vmalloc(size); if (req) memset(req, 0, size); } if (!req) { pr_info("OOM, %u sw_desc, %u.\n", sdesc_nr, size); return NULL; } return req; } static struct xdma_request_cb * xdma_init_request(struct sg_table *sgt, u64 ep_addr) { struct xdma_request_cb *req; struct scatterlist *sg = sgt->sgl; int max = sgt->nents; int extra = 0; int i, j = 0; for (i = 0; i < max; i++, sg = sg_next(sg)) { unsigned int len = sg_dma_len(sg); if (unlikely(len > desc_blen_max)) extra += (len + desc_blen_max - 1) / desc_blen_max; } //pr_info("ep 0x%llx, desc %u+%u.\n", ep_addr, max, extra); max += extra; req = xdma_request_alloc(max); if (!req) return NULL; req->sgt = sgt; req->ep_addr = ep_addr; for (i = 0, sg = sgt->sgl; i < sgt->nents; i++, sg = sg_next(sg)) { unsigned int tlen = sg_dma_len(sg); dma_addr_t addr = sg_dma_address(sg); req->total_len += tlen; while (tlen) { req->sdesc[j].addr = addr; if (tlen > desc_blen_max) { req->sdesc[j].len = desc_blen_max; addr += desc_blen_max; tlen -= desc_blen_max; } else { req->sdesc[j].len = tlen; tlen = 0; } j++; } } BUG_ON(j > max); req->sw_desc_cnt = j; #ifdef __LIBXDMA_DEBUG__ xdma_request_cb_dump(req); #endif return req; } ssize_t xdma_xfer_submit(void *dev_hndl, int channel, bool write, u64 ep_addr, struct sg_table *sgt, bool dma_mapped, int timeout_ms) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; struct xdma_engine *engine; int rv = 0; ssize_t done = 0; struct scatterlist *sg = sgt->sgl; int nents; enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; struct xdma_request_cb *req = NULL; if (!dev_hndl) return -EINVAL; if (debug_check_dev_hndl(__func__, xdev->pdev, dev_hndl) < 0) return -EINVAL; if (write == 1) { if (channel >= xdev->h2c_channel_max) { pr_warn("H2C channel %d >= %d.\n", channel, xdev->h2c_channel_max); return -EINVAL; } engine = &xdev->engine_h2c[channel]; } else if (write == 0) { if (channel >= xdev->c2h_channel_max) { pr_warn("C2H channel %d >= %d.\n", channel, xdev->c2h_channel_max); return -EINVAL; } engine = &xdev->engine_c2h[channel]; } else { pr_warn("write %d, exp. 0|1.\n", write); return -EINVAL; } BUG_ON(!engine); BUG_ON(engine->magic != MAGIC_ENGINE); xdev = engine->xdev; if (xdma_device_flag_check(xdev, XDEV_FLAG_OFFLINE)) { pr_info("xdev 0x%p, offline.\n", xdev); return -EBUSY; } /* check the direction */ if (engine->dir != dir) { pr_info("0x%p, %s, %d, W %d, 0x%x/0x%x mismatch.\n", engine, engine->name, channel, write, engine->dir, dir); return -EINVAL; } if (!dma_mapped) { nents = pci_map_sg(xdev->pdev, sg, sgt->orig_nents, dir); if (!nents) { pr_info("map sgl failed, sgt 0x%p.\n", sgt); return -EIO; } sgt->nents = nents; } else { BUG_ON(!sgt->nents); } req = xdma_init_request(sgt, ep_addr); if (!req) { rv = -ENOMEM; goto unmap_sgl; } dbg_tfr("%s, len %u sg cnt %u.\n", engine->name, req->total_len, req->sw_desc_cnt); sg = sgt->sgl; nents = req->sw_desc_cnt; while (nents) { unsigned long flags; struct xdma_transfer *xfer; /* one transfer at a time */ spin_lock(&engine->desc_lock); /* build transfer */ rv = transfer_init(engine, req); if (rv < 0) { spin_unlock(&engine->desc_lock); goto unmap_sgl; } xfer = &req->xfer; if (!dma_mapped) xfer->flags = XFER_FLAG_NEED_UNMAP; /* last transfer for the given request? */ nents -= xfer->desc_num; if (!nents) { xfer->last_in_request = 1; xfer->sgt = sgt; } dbg_tfr("xfer, %u, ep 0x%llx, done %lu, sg %u/%u.\n", xfer->len, req->ep_addr, done, req->sw_desc_idx, req->sw_desc_cnt); #ifdef __LIBXDMA_DEBUG__ transfer_dump(xfer); #endif rv = transfer_queue(engine, xfer); if (rv < 0) { spin_unlock(&engine->desc_lock); pr_info("unable to submit %s, %d.\n", engine->name, rv); goto unmap_sgl; } /* * When polling, determine how many descriptors have been queued * on the engine to determine the writeback value expected */ if (poll_mode) { unsigned int desc_count; spin_lock_irqsave(&engine->lock, flags); desc_count = xfer->desc_num; spin_unlock_irqrestore(&engine->lock, flags); dbg_tfr("%s poll desc_count=%d\n", engine->name, desc_count); rv = engine_service_poll(engine, desc_count); } else { rv = wait_event_interruptible_timeout(xfer->wq, (xfer->state != TRANSFER_STATE_SUBMITTED), msecs_to_jiffies(timeout_ms)); } spin_lock_irqsave(&engine->lock, flags); switch(xfer->state) { case TRANSFER_STATE_COMPLETED: spin_unlock_irqrestore(&engine->lock, flags); dbg_tfr("transfer %p, %u, ep 0x%llx compl, +%lu.\n", xfer, xfer->len, req->ep_addr - xfer->len, done); done += xfer->len; rv = 0; break; case TRANSFER_STATE_FAILED: pr_info("xfer 0x%p,%u, failed, ep 0x%llx.\n", xfer, xfer->len, req->ep_addr - xfer->len); spin_unlock_irqrestore(&engine->lock, flags); #ifdef __LIBXDMA_DEBUG__ transfer_dump(xfer); sgt_dump(sgt); #endif rv = -EIO; break; default: /* transfer can still be in-flight */ pr_info("xfer 0x%p,%u, s 0x%x timed out, ep 0x%llx.\n", xfer, xfer->len, xfer->state, req->ep_addr); engine_status_read(engine, 0, 1); //engine_status_dump(engine); transfer_abort(engine, xfer); xdma_engine_stop(engine); spin_unlock_irqrestore(&engine->lock, flags); #ifdef __LIBXDMA_DEBUG__ transfer_dump(xfer); sgt_dump(sgt); #endif rv = -ERESTARTSYS; break; } transfer_destroy(xdev, xfer); spin_unlock(&engine->desc_lock); if (rv < 0) goto unmap_sgl; } /* while (sg) */ unmap_sgl: if (!dma_mapped && sgt->nents) { pci_unmap_sg(xdev->pdev, sgt->sgl, sgt->orig_nents, dir); sgt->nents = 0; } if (req) xdma_request_free(req); if (rv < 0) return rv; return done; } EXPORT_SYMBOL_GPL(xdma_xfer_submit); int xdma_performance_submit(struct xdma_dev *xdev, struct xdma_engine *engine) { u8 *buffer_virt; u32 max_consistent_size = 128 * 32 * 1024; /* 1024 pages, 4MB */ dma_addr_t buffer_bus; /* bus address */ struct xdma_transfer *transfer; u64 ep_addr = 0; int num_desc_in_a_loop = 128; int size_in_desc = engine->xdma_perf->transfer_size; int size = size_in_desc * num_desc_in_a_loop; int i; BUG_ON(size_in_desc > max_consistent_size); if (size > max_consistent_size) { size = max_consistent_size; num_desc_in_a_loop = size / size_in_desc; } buffer_virt = dma_alloc_coherent(&xdev->pdev->dev, size, &buffer_bus, GFP_KERNEL); /* allocate transfer data structure */ transfer = kzalloc(sizeof(struct xdma_transfer), GFP_KERNEL); BUG_ON(!transfer); /* 0 = write engine (to_dev=0) , 1 = read engine (to_dev=1) */ transfer->dir = engine->dir; /* set number of descriptors */ transfer->desc_num = num_desc_in_a_loop; /* allocate descriptor list */ if (!engine->desc) { engine->desc = dma_alloc_coherent(&xdev->pdev->dev, num_desc_in_a_loop * sizeof(struct xdma_desc), &engine->desc_bus, GFP_KERNEL); BUG_ON(!engine->desc); dbg_init("device %s, engine %s pre-alloc desc 0x%p,0x%llx.\n", dev_name(&xdev->pdev->dev), engine->name, engine->desc, engine->desc_bus); } transfer->desc_virt = engine->desc; transfer->desc_bus = engine->desc_bus; transfer_desc_init(transfer, transfer->desc_num); dbg_sg("transfer->desc_bus = 0x%llx.\n", (u64)transfer->desc_bus); for (i = 0; i < transfer->desc_num; i++) { struct xdma_desc *desc = transfer->desc_virt + i; dma_addr_t rc_bus_addr = buffer_bus + size_in_desc * i; /* fill in descriptor entry with transfer details */ xdma_desc_set(desc, rc_bus_addr, ep_addr, size_in_desc, engine->dir); } /* stop engine and request interrupt on last descriptor */ xdma_desc_control_set(transfer->desc_virt, 0); /* create a linked loop */ xdma_desc_link(transfer->desc_virt + transfer->desc_num - 1, transfer->desc_virt, transfer->desc_bus); transfer->cyclic = 1; /* initialize wait queue */ init_waitqueue_head(&transfer->wq); //printk("=== Descriptor print for PERF \n"); //transfer_dump(transfer); dbg_perf("Queueing XDMA I/O %s request for performance measurement.\n", engine->dir ? "write (to dev)" : "read (from dev)"); transfer_queue(engine, transfer); return 0; } EXPORT_SYMBOL_GPL(xdma_performance_submit); static struct xdma_dev *alloc_dev_instance(struct pci_dev *pdev) { int i; struct xdma_dev *xdev; struct xdma_engine *engine; BUG_ON(!pdev); /* allocate zeroed device book keeping structure */ xdev = kzalloc(sizeof(struct xdma_dev), GFP_KERNEL); if (!xdev) { pr_info("OOM, xdma_dev.\n"); return NULL; } spin_lock_init(&xdev->lock); xdev->magic = MAGIC_DEVICE; xdev->config_bar_idx = -1; xdev->user_bar_idx = -1; xdev->bypass_bar_idx = -1; xdev->irq_line = -1; /* create a driver to device reference */ xdev->pdev = pdev; dbg_init("xdev = 0x%p\n", xdev); /* Set up data user IRQ data structures */ for (i = 0; i < 16; i++) { xdev->user_irq[i].xdev = xdev; spin_lock_init(&xdev->user_irq[i].events_lock); init_waitqueue_head(&xdev->user_irq[i].events_wq); xdev->user_irq[i].handler = NULL; xdev->user_irq[i].user_idx = i; /* 0 based */ } engine = xdev->engine_h2c; for (i = 0; i < XDMA_CHANNEL_NUM_MAX; i++, engine++) { spin_lock_init(&engine->lock); spin_lock_init(&engine->desc_lock); INIT_LIST_HEAD(&engine->transfer_list); init_waitqueue_head(&engine->shutdown_wq); init_waitqueue_head(&engine->xdma_perf_wq); } engine = xdev->engine_c2h; for (i = 0; i < XDMA_CHANNEL_NUM_MAX; i++, engine++) { spin_lock_init(&engine->lock); spin_lock_init(&engine->desc_lock); INIT_LIST_HEAD(&engine->transfer_list); init_waitqueue_head(&engine->shutdown_wq); init_waitqueue_head(&engine->xdma_perf_wq); } return xdev; } static int request_regions(struct xdma_dev *xdev, struct pci_dev *pdev) { int rv; BUG_ON(!xdev); BUG_ON(!pdev); dbg_init("pci_request_regions()\n"); rv = pci_request_regions(pdev, xdev->mod_name); /* could not request all regions? */ if (rv) { dbg_init("pci_request_regions() = %d, device in use?\n", rv); /* assume device is in use so do not disable it later */ xdev->regions_in_use = 1; } else { xdev->got_regions = 1; } return rv; } static int set_dma_mask(struct pci_dev *pdev) { BUG_ON(!pdev); dbg_init("sizeof(dma_addr_t) == %ld\n", sizeof(dma_addr_t)); /* 64-bit addressing capability for XDMA? */ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { /* query for DMA transfer */ /* @see Documentation/DMA-mapping.txt */ dbg_init("pci_set_dma_mask()\n"); /* use 64-bit DMA */ dbg_init("Using a 64-bit DMA mask.\n"); /* use 32-bit DMA for descriptors */ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); /* use 64-bit DMA, 32-bit for consistent */ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { dbg_init("Could not set 64-bit DMA mask.\n"); pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); /* use 32-bit DMA */ dbg_init("Using a 32-bit DMA mask.\n"); } else { dbg_init("No suitable DMA possible.\n"); return -EINVAL; } return 0; } static u32 get_engine_channel_id(struct engine_regs *regs) { u32 value; BUG_ON(!regs); value = read_register(®s->identifier); return (value & 0x00000f00U) >> 8; } static u32 get_engine_id(struct engine_regs *regs) { u32 value; BUG_ON(!regs); value = read_register(®s->identifier); return (value & 0xffff0000U) >> 16; } static void remove_engines(struct xdma_dev *xdev) { struct xdma_engine *engine; int i; BUG_ON(!xdev); /* iterate over channels */ for (i = 0; i < xdev->h2c_channel_max; i++) { engine = &xdev->engine_h2c[i]; if (engine->magic == MAGIC_ENGINE) { dbg_sg("Remove %s, %d", engine->name, i); engine_destroy(xdev, engine); dbg_sg("%s, %d removed", engine->name, i); } } for (i = 0; i < xdev->c2h_channel_max; i++) { engine = &xdev->engine_c2h[i]; if (engine->magic == MAGIC_ENGINE) { dbg_sg("Remove %s, %d", engine->name, i); engine_destroy(xdev, engine); dbg_sg("%s, %d removed", engine->name, i); } } } static int probe_for_engine(struct xdma_dev *xdev, enum dma_data_direction dir, int channel) { struct engine_regs *regs; int offset = channel * CHANNEL_SPACING; u32 engine_id; u32 engine_id_expected; u32 channel_id; struct xdma_engine *engine; int rv; /* register offset for the engine */ /* read channels at 0x0000, write channels at 0x1000, * channels at 0x100 interval */ if (dir == DMA_TO_DEVICE) { engine_id_expected = XDMA_ID_H2C; engine = &xdev->engine_h2c[channel]; } else { offset += H2C_CHANNEL_OFFSET; engine_id_expected = XDMA_ID_C2H; engine = &xdev->engine_c2h[channel]; } regs = xdev->bar[xdev->config_bar_idx] + offset; engine_id = get_engine_id(regs); channel_id = get_engine_channel_id(regs); if ((engine_id != engine_id_expected) || (channel_id != channel)) { dbg_init("%s %d engine, reg off 0x%x, id mismatch 0x%x,0x%x," "exp 0x%x,0x%x, SKIP.\n", dir == DMA_TO_DEVICE ? "H2C" : "C2H", channel, offset, engine_id, channel_id, engine_id_expected, channel_id != channel); return -EINVAL; } dbg_init("found AXI %s %d engine, reg. off 0x%x, id 0x%x,0x%x.\n", dir == DMA_TO_DEVICE ? "H2C" : "C2H", channel, offset, engine_id, channel_id); /* allocate and initialize engine */ rv = engine_init(engine, xdev, offset, dir, channel); if (rv != 0) { pr_info("failed to create AXI %s %d engine.\n", dir == DMA_TO_DEVICE ? "H2C" : "C2H", channel); return rv; } return 0; } static int probe_engines(struct xdma_dev *xdev) { int i; int rv = 0; BUG_ON(!xdev); /* iterate over channels */ for (i = 0; i < xdev->h2c_channel_max; i++) { rv = probe_for_engine(xdev, DMA_TO_DEVICE, i); if (rv) break; } xdev->h2c_channel_max = i; for (i = 0; i < xdev->c2h_channel_max; i++) { rv = probe_for_engine(xdev, DMA_FROM_DEVICE, i); if (rv) break; } xdev->c2h_channel_max = i; return 0; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) static void pci_enable_relaxed_ordering(struct pci_dev *pdev) { pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN); } #else static void pci_enable_relaxed_ordering(struct pci_dev *pdev) { u16 v; int pos; pos = pci_pcie_cap(pdev); if (pos > 0) { pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &v); v |= PCI_EXP_DEVCTL_RELAX_EN; pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, v); } } #endif static void pci_check_extended_tag(struct xdma_dev *xdev, struct pci_dev *pdev) { u16 cap; u32 v; void *__iomem reg; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); #else int pos; pos = pci_pcie_cap(pdev); if (pos > 0) pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &cap); else { pr_info("pdev 0x%p, unable to access pcie cap.\n", pdev); return; } #endif if ((cap & PCI_EXP_DEVCTL_EXT_TAG)) return; /* extended tag not enabled */ pr_info("0x%p EXT_TAG disabled.\n", pdev); if (xdev->config_bar_idx < 0) { pr_info("pdev 0x%p, xdev 0x%p, config bar UNKNOWN.\n", pdev, xdev); return; } reg = xdev->bar[xdev->config_bar_idx] + XDMA_OFS_CONFIG + 0x4C; v = read_register(reg); v = (v & 0xFF) | (((u32)32) << 8); write_register(v, reg, XDMA_OFS_CONFIG + 0x4C); } void *xdma_device_open(const char *mname, struct pci_dev *pdev, int *user_max, int *h2c_channel_max, int *c2h_channel_max) { struct xdma_dev *xdev = NULL; int rv = 0; pr_info("%s device %s, 0x%p.\n", mname, dev_name(&pdev->dev), pdev); /* allocate zeroed device book keeping structure */ xdev = alloc_dev_instance(pdev); if (!xdev) return NULL; xdev->mod_name = mname; xdev->user_max = *user_max; xdev->h2c_channel_max = *h2c_channel_max; xdev->c2h_channel_max = *c2h_channel_max; xdma_device_flag_set(xdev, XDEV_FLAG_OFFLINE); xdev_list_add(xdev); if (xdev->user_max == 0 || xdev->user_max > MAX_USER_IRQ) xdev->user_max = MAX_USER_IRQ; if (xdev->h2c_channel_max == 0 || xdev->h2c_channel_max > XDMA_CHANNEL_NUM_MAX) xdev->h2c_channel_max = XDMA_CHANNEL_NUM_MAX; if (xdev->c2h_channel_max == 0 || xdev->c2h_channel_max > XDMA_CHANNEL_NUM_MAX) xdev->c2h_channel_max = XDMA_CHANNEL_NUM_MAX; rv = pci_enable_device(pdev); if (rv) { dbg_init("pci_enable_device() failed, %d.\n", rv); goto err_enable; } /* keep INTx enabled */ pci_check_intr_pend(pdev); /* enable relaxed ordering */ pci_enable_relaxed_ordering(pdev); pci_check_extended_tag(xdev, pdev); /* force MRRS to be 512 */ rv = pcie_set_readrq(pdev, 512); if (rv) pr_info("device %s, error set PCI_EXP_DEVCTL_READRQ: %d.\n", dev_name(&pdev->dev), rv); /* enable bus master capability */ pci_set_master(pdev); rv = request_regions(xdev, pdev); if (rv) goto err_regions; rv = map_bars(xdev, pdev); if (rv) goto err_map; rv = set_dma_mask(pdev); if (rv) goto err_mask; check_nonzero_interrupt_status(xdev); /* explicitely zero all interrupt enable masks */ channel_interrupts_disable(xdev, ~0); user_interrupts_disable(xdev, ~0); read_interrupts(xdev); rv = probe_engines(xdev); if (rv) goto err_engines; rv = enable_msi_msix(xdev, pdev); if (rv < 0) goto err_enable_msix; rv = irq_setup(xdev, pdev); if (rv < 0) goto err_interrupts; if (!poll_mode) channel_interrupts_enable(xdev, ~0); /* Flush writes */ read_interrupts(xdev); *user_max = xdev->user_max; *h2c_channel_max = xdev->h2c_channel_max; *c2h_channel_max = xdev->c2h_channel_max; xdma_device_flag_clear(xdev, XDEV_FLAG_OFFLINE); return (void *)xdev; err_interrupts: irq_teardown(xdev); err_enable_msix: disable_msi_msix(xdev, pdev); err_engines: remove_engines(xdev); err_mask: unmap_bars(xdev, pdev); err_map: if (xdev->got_regions) pci_release_regions(pdev); err_regions: if (!xdev->regions_in_use) pci_disable_device(pdev); err_enable: xdev_list_remove(xdev); kfree(xdev); return NULL; } EXPORT_SYMBOL_GPL(xdma_device_open); void xdma_device_close(struct pci_dev *pdev, void *dev_hndl) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; dbg_init("pdev 0x%p, xdev 0x%p.\n", pdev, dev_hndl); if (!dev_hndl) return; if (debug_check_dev_hndl(__func__, pdev, dev_hndl) < 0) return; dbg_sg("remove(dev = 0x%p) where pdev->dev.driver_data = 0x%p\n", pdev, xdev); if (xdev->pdev != pdev) { dbg_sg("pci_dev(0x%lx) != pdev(0x%lx)\n", (unsigned long)xdev->pdev, (unsigned long)pdev); } channel_interrupts_disable(xdev, ~0); user_interrupts_disable(xdev, ~0); read_interrupts(xdev); irq_teardown(xdev); disable_msi_msix(xdev, pdev); remove_engines(xdev); unmap_bars(xdev, pdev); if (xdev->got_regions) { dbg_init("pci_release_regions 0x%p.\n", pdev); pci_release_regions(pdev); } if (!xdev->regions_in_use) { dbg_init("pci_disable_device 0x%p.\n", pdev); pci_disable_device(pdev); } xdev_list_remove(xdev); kfree(xdev); } EXPORT_SYMBOL_GPL(xdma_device_close); void xdma_device_offline(struct pci_dev *pdev, void *dev_hndl) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; struct xdma_engine *engine; int i; if (!dev_hndl) return; if (debug_check_dev_hndl(__func__, pdev, dev_hndl) < 0) return; pr_info("pdev 0x%p, xdev 0x%p.\n", pdev, xdev); xdma_device_flag_set(xdev, XDEV_FLAG_OFFLINE); /* wait for all engines to be idle */ for (i = 0; i < xdev->h2c_channel_max; i++) { unsigned long flags; engine = &xdev->engine_h2c[i]; if (engine->magic == MAGIC_ENGINE) { spin_lock_irqsave(&engine->lock, flags); engine->shutdown |= ENGINE_SHUTDOWN_REQUEST; xdma_engine_stop(engine); engine->running = 0; spin_unlock_irqrestore(&engine->lock, flags); } } for (i = 0; i < xdev->c2h_channel_max; i++) { unsigned long flags; engine = &xdev->engine_c2h[i]; if (engine->magic == MAGIC_ENGINE) { spin_lock_irqsave(&engine->lock, flags); engine->shutdown |= ENGINE_SHUTDOWN_REQUEST; xdma_engine_stop(engine); engine->running = 0; spin_unlock_irqrestore(&engine->lock, flags); } } /* turn off interrupts */ channel_interrupts_disable(xdev, ~0); user_interrupts_disable(xdev, ~0); read_interrupts(xdev); irq_teardown(xdev); pr_info("xdev 0x%p, done.\n", xdev); } EXPORT_SYMBOL_GPL(xdma_device_offline); void xdma_device_online(struct pci_dev *pdev, void *dev_hndl) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; struct xdma_engine *engine; unsigned long flags; int i; if (!dev_hndl) return; if (debug_check_dev_hndl(__func__, pdev, dev_hndl) < 0) return; pr_info("pdev 0x%p, xdev 0x%p.\n", pdev, xdev); for (i = 0; i < xdev->h2c_channel_max; i++) { engine = &xdev->engine_h2c[i]; if (engine->magic == MAGIC_ENGINE) { engine_init_regs(engine); spin_lock_irqsave(&engine->lock, flags); engine->shutdown &= ~ENGINE_SHUTDOWN_REQUEST; spin_unlock_irqrestore(&engine->lock, flags); } } for (i = 0; i < xdev->c2h_channel_max; i++) { engine = &xdev->engine_c2h[i]; if (engine->magic == MAGIC_ENGINE) { engine_init_regs(engine); spin_lock_irqsave(&engine->lock, flags); engine->shutdown &= ~ENGINE_SHUTDOWN_REQUEST; spin_unlock_irqrestore(&engine->lock, flags); } } /* re-write the interrupt table */ if (!poll_mode) { irq_setup(xdev, pdev); channel_interrupts_enable(xdev, ~0); user_interrupts_enable(xdev, xdev->mask_irq_user); read_interrupts(xdev); } xdma_device_flag_clear(xdev, XDEV_FLAG_OFFLINE); pr_info("xdev 0x%p, done.\n", xdev); } EXPORT_SYMBOL_GPL(xdma_device_online); int xdma_device_restart(struct pci_dev *pdev, void *dev_hndl) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; if (!dev_hndl) return -EINVAL; if (debug_check_dev_hndl(__func__, pdev, dev_hndl) < 0) return -EINVAL; pr_info("NOT implemented, 0x%p.\n", xdev); return -EINVAL; } EXPORT_SYMBOL_GPL(xdma_device_restart); int xdma_user_isr_register(void *dev_hndl, unsigned int mask, irq_handler_t handler, void *dev) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; int i; if (!dev_hndl) return -EINVAL; if (debug_check_dev_hndl(__func__, xdev->pdev, dev_hndl) < 0) return -EINVAL; for (i = 0; i < xdev->user_max && mask; i++) { unsigned int bit = (1 << i); if ((bit & mask) == 0) continue; mask &= ~bit; xdev->user_irq[i].handler = handler; xdev->user_irq[i].dev = dev; } return 0; } EXPORT_SYMBOL_GPL(xdma_user_isr_register); int xdma_user_isr_enable(void *dev_hndl, unsigned int mask) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; if (!dev_hndl) return -EINVAL; if (debug_check_dev_hndl(__func__, xdev->pdev, dev_hndl) < 0) return -EINVAL; xdev->mask_irq_user |= mask; /* enable user interrupts */ user_interrupts_enable(xdev, mask); read_interrupts(xdev); return 0; } EXPORT_SYMBOL_GPL(xdma_user_isr_enable); int xdma_user_isr_disable(void *dev_hndl, unsigned int mask) { struct xdma_dev *xdev = (struct xdma_dev *)dev_hndl; if (!dev_hndl) return -EINVAL; if (debug_check_dev_hndl(__func__, xdev->pdev, dev_hndl) < 0) return -EINVAL; xdev->mask_irq_user &= ~mask; user_interrupts_disable(xdev, mask); read_interrupts(xdev); return 0; } EXPORT_SYMBOL_GPL(xdma_user_isr_disable); #ifdef __LIBXDMA_MOD__ static int __init xdma_base_init(void) { printk(KERN_INFO "%s", version); return 0; } static void __exit xdma_base_exit(void) { return; } module_init(xdma_base_init); module_exit(xdma_base_exit); #endif /* makes an existing transfer cyclic */ static void xdma_transfer_cyclic(struct xdma_transfer *transfer) { /* link last descriptor to first descriptor */ xdma_desc_link(transfer->desc_virt + transfer->desc_num - 1, transfer->desc_virt, transfer->desc_bus); /* remember transfer is cyclic */ transfer->cyclic = 1; } static int transfer_monitor_cyclic(struct xdma_engine *engine, struct xdma_transfer *transfer, int timeout_ms) { struct xdma_result *result; int rc = 0; BUG_ON(!engine); BUG_ON(!transfer); result = engine->cyclic_result; BUG_ON(!result); if (poll_mode) { int i ; for (i = 0; i < 5; i++) { rc = engine_service_poll(engine, 0); if (rc) { pr_info("%s service_poll failed %d.\n", engine->name, rc); rc = -ERESTARTSYS; } if (result[engine->rx_head].status) return 0; } } else { if (enable_credit_mp){ dbg_tfr("%s: rx_head=%d,rx_tail=%d, wait ...\n", engine->name, engine->rx_head, engine->rx_tail); rc = wait_event_interruptible_timeout( transfer->wq, (engine->rx_head!=engine->rx_tail || engine->rx_overrun), msecs_to_jiffies(timeout_ms)); dbg_tfr("%s: wait returns %d, rx %d/%d, overrun %d.\n", engine->name, rc, engine->rx_head, engine->rx_tail, engine->rx_overrun); } else { rc = wait_event_interruptible_timeout( transfer->wq, engine->eop_found, msecs_to_jiffies(timeout_ms)); dbg_tfr("%s: wait returns %d, eop_found %d.\n", engine->name, rc, engine->eop_found); } } return 0; } struct scatterlist *sglist_index(struct sg_table *sgt, unsigned int idx) { struct scatterlist *sg = sgt->sgl; int i; if (idx >= sgt->orig_nents) return NULL; if (!idx) return sg; for (i = 0; i < idx; i++, sg = sg_next(sg)) ; return sg; } static int copy_cyclic_to_user(struct xdma_engine *engine, int pkt_length, int head, char __user *buf, size_t count) { struct scatterlist *sg; int more = pkt_length; BUG_ON(!engine); BUG_ON(!buf); dbg_tfr("%s, pkt_len %d, head %d, user buf idx %u.\n", engine->name, pkt_length, head, engine->user_buffer_index); sg = sglist_index(&engine->cyclic_sgt, head); if (!sg) { pr_info("%s, head %d OOR, sgl %u.\n", engine->name, head, engine->cyclic_sgt.orig_nents); return -EIO; } /* EOP found? Transfer anything from head to EOP */ while (more) { unsigned int copy = more > PAGE_SIZE ? PAGE_SIZE : more; unsigned int blen = count - engine->user_buffer_index; int rv; if (copy > blen) copy = blen; dbg_tfr("%s sg %d, 0x%p, copy %u to user %u.\n", engine->name, head, sg, copy, engine->user_buffer_index); rv = copy_to_user(&buf[engine->user_buffer_index], page_address(sg_page(sg)), copy); if (rv) { pr_info("%s copy_to_user %u failed %d\n", engine->name, copy, rv); return -EIO; } more -= copy; engine->user_buffer_index += copy; if (engine->user_buffer_index == count) { /* user buffer used up */ break; } head++; if (head >= CYCLIC_RX_PAGES_MAX) { head = 0; sg = engine->cyclic_sgt.sgl; } else sg = sg_next(sg); } return pkt_length; } static int complete_cyclic(struct xdma_engine *engine, char __user *buf, size_t count) { struct xdma_result *result; int pkt_length = 0; int fault = 0; int eop = 0; int head; int rc = 0; int num_credit = 0; unsigned long flags; BUG_ON(!engine); result = engine->cyclic_result; BUG_ON(!result); spin_lock_irqsave(&engine->lock, flags); /* where the host currently is in the ring buffer */ head = engine->rx_head; /* iterate over newly received results */ while (engine->rx_head != engine->rx_tail||engine->rx_overrun) { WARN_ON(result[engine->rx_head].status==0); dbg_tfr("%s, result[%d].status = 0x%x length = 0x%x.\n", engine->name, engine->rx_head, result[engine->rx_head].status, result[engine->rx_head].length); if ((result[engine->rx_head].status >> 16) != C2H_WB) { pr_info("%s, result[%d].status 0x%x, no magic.\n", engine->name, engine->rx_head, result[engine->rx_head].status); fault = 1; } else if (result[engine->rx_head].length > PAGE_SIZE) { pr_info("%s, result[%d].len 0x%x, > PAGE_SIZE 0x%lx.\n", engine->name, engine->rx_head, result[engine->rx_head].length, PAGE_SIZE); fault = 1; } else if (result[engine->rx_head].length == 0) { pr_info("%s, result[%d].length 0x%x.\n", engine->name, engine->rx_head, result[engine->rx_head].length); fault = 1; /* valid result */ } else { pkt_length += result[engine->rx_head].length; num_credit++; /* seen eop? */ //if (result[engine->rx_head].status & RX_STATUS_EOP) if (result[engine->rx_head].status & RX_STATUS_EOP){ eop = 1; engine->eop_found = 1; } dbg_tfr("%s, pkt_length=%d (%s)\n", engine->name, pkt_length, eop ? "with EOP" : "no EOP yet"); } /* clear result */ result[engine->rx_head].status = 0; result[engine->rx_head].length = 0; /* proceed head pointer so we make progress, even when fault */ engine->rx_head = (engine->rx_head + 1) % CYCLIC_RX_PAGES_MAX; /* stop processing if a fault/eop was detected */ if (fault || eop){ break; } } spin_unlock_irqrestore(&engine->lock, flags); if (fault) return -EIO; rc = copy_cyclic_to_user(engine, pkt_length, head, buf, count); engine->rx_overrun = 0; /* if copy is successful, release credits */ if(rc > 0) write_register(num_credit,&engine->sgdma_regs->credits, 0); return rc; } ssize_t xdma_engine_read_cyclic(struct xdma_engine *engine, char __user *buf, size_t count, int timeout_ms) { int i = 0; int rc = 0; int rc_len = 0; struct xdma_transfer *transfer; BUG_ON(!engine); BUG_ON(engine->magic != MAGIC_ENGINE); transfer = &engine->cyclic_req->xfer; BUG_ON(!transfer); engine->user_buffer_index = 0; do { rc = transfer_monitor_cyclic(engine, transfer, timeout_ms); if (rc < 0) return rc; rc = complete_cyclic(engine, buf, count); if (rc < 0) return rc; rc_len += rc; i++; if (i > 10) break; } while (!engine->eop_found); if(enable_credit_mp) engine->eop_found = 0; return rc_len; } static void sgt_free_with_pages(struct sg_table *sgt, int dir, struct pci_dev *pdev) { struct scatterlist *sg = sgt->sgl; int npages = sgt->orig_nents; int i; for (i = 0; i < npages; i++, sg = sg_next(sg)) { struct page *pg = sg_page(sg); dma_addr_t bus = sg_dma_address(sg); if (pg) { if (pdev) pci_unmap_page(pdev, bus, PAGE_SIZE, dir); __free_page(pg); } else break; } sg_free_table(sgt); memset(sgt, 0, sizeof(struct sg_table)); } static int sgt_alloc_with_pages(struct sg_table *sgt, unsigned int npages, int dir, struct pci_dev *pdev) { struct scatterlist *sg; int i; if (sg_alloc_table(sgt, npages, GFP_KERNEL)) { pr_info("sgt OOM.\n"); return -ENOMEM; } sg = sgt->sgl; for (i = 0; i < npages; i++, sg = sg_next(sg)) { struct page *pg = alloc_page(GFP_KERNEL); if (!pg) { pr_info("%d/%u, page OOM.\n", i, npages); goto err_out; } if (pdev) { dma_addr_t bus = pci_map_page(pdev, pg, 0, PAGE_SIZE, dir); if (unlikely(pci_dma_mapping_error(pdev, bus))) { pr_info("%d/%u, page 0x%p map err.\n", i, npages, pg); __free_page(pg); goto err_out; } sg_dma_address(sg) = bus; sg_dma_len(sg) = PAGE_SIZE; } sg_set_page(sg, pg, PAGE_SIZE, 0); } sgt->orig_nents = sgt->nents = npages; return 0; err_out: sgt_free_with_pages(sgt, dir, pdev); return -ENOMEM; } int xdma_cyclic_transfer_setup(struct xdma_engine *engine) { struct xdma_dev *xdev; struct xdma_transfer *xfer; dma_addr_t bus; unsigned long flags; int i; int rc; BUG_ON(!engine); xdev = engine->xdev; BUG_ON(!xdev); if (engine->cyclic_req) { pr_info("%s: exclusive access already taken.\n", engine->name); return -EBUSY; } spin_lock_irqsave(&engine->lock, flags); engine->rx_tail = 0; engine->rx_head = 0; engine->rx_overrun = 0; engine->eop_found = 0; rc = sgt_alloc_with_pages(&engine->cyclic_sgt, CYCLIC_RX_PAGES_MAX, engine->dir, xdev->pdev); if (rc < 0) { pr_info("%s cyclic pages %u OOM.\n", engine->name, CYCLIC_RX_PAGES_MAX); goto err_out; } engine->cyclic_req = xdma_init_request(&engine->cyclic_sgt, 0); if (!engine->cyclic_req) { pr_info("%s cyclic request OOM.\n", engine->name); rc = -ENOMEM; goto err_out; } #ifdef __LIBXDMA_DEBUG__ xdma_request_cb_dump(engine->cyclic_req); #endif rc = transfer_init(engine, engine->cyclic_req); if (rc < 0) goto err_out; xfer = &engine->cyclic_req->xfer; /* replace source addresses with result write-back addresses */ memset(engine->cyclic_result, 0, CYCLIC_RX_PAGES_MAX * sizeof(struct xdma_result)); bus = engine->cyclic_result_bus; for (i = 0; i < xfer->desc_num; i++) { xfer->desc_virt[i].src_addr_lo = cpu_to_le32(PCI_DMA_L(bus)); xfer->desc_virt[i].src_addr_hi = cpu_to_le32(PCI_DMA_H(bus)); bus += sizeof(struct xdma_result); } /* set control of all descriptors */ for (i = 0; i < xfer->desc_num; i++) { xdma_desc_control_clear(xfer->desc_virt + i, LS_BYTE_MASK); xdma_desc_control_set(xfer->desc_virt + i, XDMA_DESC_EOP | XDMA_DESC_COMPLETED); } /* make this a cyclic transfer */ xdma_transfer_cyclic(xfer); #ifdef __LIBXDMA_DEBUG__ transfer_dump(xfer); #endif if(enable_credit_mp){ //write_register(RX_BUF_PAGES,&engine->sgdma_regs->credits); write_register(128, &engine->sgdma_regs->credits, 0); } spin_unlock_irqrestore(&engine->lock, flags); /* start cyclic transfer */ transfer_queue(engine, xfer); return 0; /* unwind on errors */ err_out: if (engine->cyclic_req) { xdma_request_free(engine->cyclic_req); engine->cyclic_req = NULL; } if (engine->cyclic_sgt.orig_nents) { sgt_free_with_pages(&engine->cyclic_sgt, engine->dir, xdev->pdev); engine->cyclic_sgt.orig_nents = 0; engine->cyclic_sgt.nents = 0; engine->cyclic_sgt.sgl = NULL; } spin_unlock_irqrestore(&engine->lock, flags); return rc; } static int cyclic_shutdown_polled(struct xdma_engine *engine) { BUG_ON(!engine); spin_lock(&engine->lock); dbg_tfr("Polling for shutdown completion\n"); do { engine_status_read(engine, 1, 0); schedule(); } while (engine->status & XDMA_STAT_BUSY); if ((engine->running) && !(engine->status & XDMA_STAT_BUSY)) { dbg_tfr("Engine has stopped\n"); if (!list_empty(&engine->transfer_list)) engine_transfer_dequeue(engine); engine_service_shutdown(engine); } dbg_tfr("Shutdown completion polling done\n"); spin_unlock(&engine->lock); return 0; } static int cyclic_shutdown_interrupt(struct xdma_engine *engine) { int rc; BUG_ON(!engine); rc = wait_event_interruptible_timeout(engine->shutdown_wq, !engine->running, msecs_to_jiffies(10000)); #if 0 if (rc) { dbg_tfr("wait_event_interruptible=%d\n", rc); return rc; } #endif if (engine->running) { pr_info("%s still running?!, %d\n", engine->name, rc); return -EINVAL; } return rc; } int xdma_cyclic_transfer_teardown(struct xdma_engine *engine) { int rc; struct xdma_dev *xdev = engine->xdev; struct xdma_transfer *transfer; unsigned long flags; transfer = engine_cyclic_stop(engine); spin_lock_irqsave(&engine->lock, flags); if (transfer) { dbg_tfr("%s: stop transfer 0x%p.\n", engine->name, transfer); if (transfer != &engine->cyclic_req->xfer) { pr_info("%s unexpected transfer 0x%p/0x%p\n", engine->name, transfer, &engine->cyclic_req->xfer); } } /* allow engine to be serviced after stop request */ spin_unlock_irqrestore(&engine->lock, flags); /* wait for engine to be no longer running */ if (poll_mode) rc = cyclic_shutdown_polled(engine); else rc = cyclic_shutdown_interrupt(engine); /* obtain spin lock to atomically remove resources */ spin_lock_irqsave(&engine->lock, flags); if (engine->cyclic_req) { xdma_request_free(engine->cyclic_req); engine->cyclic_req = NULL; } if (engine->cyclic_sgt.orig_nents) { sgt_free_with_pages(&engine->cyclic_sgt, engine->dir, xdev->pdev); engine->cyclic_sgt.orig_nents = 0; engine->cyclic_sgt.nents = 0; engine->cyclic_sgt.sgl = NULL; } spin_unlock_irqrestore(&engine->lock, flags); return 0; } int engine_addrmode_set(struct xdma_engine *engine, unsigned long arg) { int rv; unsigned long dst; u32 w = XDMA_CTRL_NON_INCR_ADDR; dbg_perf("IOCTL_XDMA_ADDRMODE_SET\n"); rv = get_user(dst, (int __user *)arg); if (rv == 0) { engine->non_incr_addr = !!dst; if (engine->non_incr_addr) write_register(w, &engine->regs->control_w1s, (unsigned long)(&engine->regs->control_w1s) - (unsigned long)(&engine->regs)); else write_register(w, &engine->regs->control_w1c, (unsigned long)(&engine->regs->control_w1c) - (unsigned long)(&engine->regs)); } engine_alignments(engine); return rv; } ================================================ FILE: drivers/awsf1portal/libxdma.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef XDMA_LIB_H #define XDMA_LIB_H #include #include #include #include #include #include #include #include #include #include #include /* Switch debug printing on/off */ #define XDMA_DEBUG 0 #define XDMA_CONFIG_BAR_NUM (2) // no need to search for it. -Jamey /* SECTION: Preprocessor macros/constants */ #define XDMA_BAR_NUM (6) /* maximum amount of register space to map */ #define XDMA_BAR_SIZE (0x8000UL) /* Use this definition to poll several times between calls to schedule */ #define NUM_POLLS_PER_SCHED 100 #define XDMA_CHANNEL_NUM_MAX (4) /* * interrupts per engine, rad2_vul.sv:237 * .REG_IRQ_OUT (reg_irq_from_ch[(channel*2) +: 2]), */ #define XDMA_ENG_IRQ_NUM (1) #define MAX_EXTRA_ADJ (15) #define RX_STATUS_EOP (1) /* Target internal components on XDMA control BAR */ #define XDMA_OFS_INT_CTRL (0x2000UL) #define XDMA_OFS_CONFIG (0x3000UL) /* maximum number of desc per transfer request */ #define XDMA_TRANSFER_MAX_DESC (2048) /* maximum size of a single DMA transfer descriptor */ #define XDMA_DESC_BLEN_BITS 28 #define XDMA_DESC_BLEN_MAX ((1 << (XDMA_DESC_BLEN_BITS)) - 1) /* bits of the SG DMA control register */ #define XDMA_CTRL_RUN_STOP (1UL << 0) #define XDMA_CTRL_IE_DESC_STOPPED (1UL << 1) #define XDMA_CTRL_IE_DESC_COMPLETED (1UL << 2) #define XDMA_CTRL_IE_DESC_ALIGN_MISMATCH (1UL << 3) #define XDMA_CTRL_IE_MAGIC_STOPPED (1UL << 4) #define XDMA_CTRL_IE_IDLE_STOPPED (1UL << 6) #define XDMA_CTRL_IE_READ_ERROR (0x1FUL << 9) #define XDMA_CTRL_IE_DESC_ERROR (0x1FUL << 19) #define XDMA_CTRL_NON_INCR_ADDR (1UL << 25) #define XDMA_CTRL_POLL_MODE_WB (1UL << 26) /* bits of the SG DMA status register */ #define XDMA_STAT_BUSY (1UL << 0) #define XDMA_STAT_DESC_STOPPED (1UL << 1) #define XDMA_STAT_DESC_COMPLETED (1UL << 2) #define XDMA_STAT_ALIGN_MISMATCH (1UL << 3) #define XDMA_STAT_MAGIC_STOPPED (1UL << 4) #define XDMA_STAT_INVALID_LEN (1UL << 5) #define XDMA_STAT_IDLE_STOPPED (1UL << 6) #define XDMA_STAT_COMMON_ERR_MASK \ (XDMA_STAT_ALIGN_MISMATCH | XDMA_STAT_MAGIC_STOPPED | \ XDMA_STAT_INVALID_LEN) /* desc_error, C2H & H2C */ #define XDMA_STAT_DESC_UNSUPP_REQ (1UL << 19) #define XDMA_STAT_DESC_COMPL_ABORT (1UL << 20) #define XDMA_STAT_DESC_PARITY_ERR (1UL << 21) #define XDMA_STAT_DESC_HEADER_EP (1UL << 22) #define XDMA_STAT_DESC_UNEXP_COMPL (1UL << 23) #define XDMA_STAT_DESC_ERR_MASK \ (XDMA_STAT_DESC_UNSUPP_REQ | XDMA_STAT_DESC_COMPL_ABORT | \ XDMA_STAT_DESC_PARITY_ERR | XDMA_STAT_DESC_HEADER_EP | \ XDMA_STAT_DESC_UNEXP_COMPL) /* read error: H2C */ #define XDMA_STAT_H2C_R_UNSUPP_REQ (1UL << 9) #define XDMA_STAT_H2C_R_COMPL_ABORT (1UL << 10) #define XDMA_STAT_H2C_R_PARITY_ERR (1UL << 11) #define XDMA_STAT_H2C_R_HEADER_EP (1UL << 12) #define XDMA_STAT_H2C_R_UNEXP_COMPL (1UL << 13) #define XDMA_STAT_H2C_R_ERR_MASK \ (XDMA_STAT_H2C_R_UNSUPP_REQ | XDMA_STAT_H2C_R_COMPL_ABORT | \ XDMA_STAT_H2C_R_PARITY_ERR | XDMA_STAT_H2C_R_HEADER_EP | \ XDMA_STAT_H2C_R_UNEXP_COMPL) /* write error, H2C only */ #define XDMA_STAT_H2C_W_DECODE_ERR (1UL << 14) #define XDMA_STAT_H2C_W_SLAVE_ERR (1UL << 15) #define XDMA_STAT_H2C_W_ERR_MASK \ (XDMA_STAT_H2C_W_DECODE_ERR | XDMA_STAT_H2C_W_SLAVE_ERR) /* read error: C2H */ #define XDMA_STAT_C2H_R_DECODE_ERR (1UL << 9) #define XDMA_STAT_C2H_R_SLAVE_ERR (1UL << 10) #define XDMA_STAT_C2H_R_ERR_MASK \ (XDMA_STAT_C2H_R_DECODE_ERR | XDMA_STAT_C2H_R_SLAVE_ERR) /* all combined */ #define XDMA_STAT_H2C_ERR_MASK \ (XDMA_STAT_COMMON_ERR_MASK | XDMA_STAT_DESC_ERR_MASK | \ XDMA_STAT_H2C_R_ERR_MASK | XDMA_STAT_H2C_W_ERR_MASK) #define XDMA_STAT_C2H_ERR_MASK \ (XDMA_STAT_COMMON_ERR_MASK | XDMA_STAT_DESC_ERR_MASK | \ XDMA_STAT_C2H_R_ERR_MASK) /* bits of the SGDMA descriptor control field */ #define XDMA_DESC_STOPPED (1UL << 0) #define XDMA_DESC_COMPLETED (1UL << 1) #define XDMA_DESC_EOP (1UL << 4) #define XDMA_PERF_RUN (1UL << 0) #define XDMA_PERF_CLEAR (1UL << 1) #define XDMA_PERF_AUTO (1UL << 2) #define MAGIC_ENGINE 0xEEEEEEEEUL #define MAGIC_DEVICE 0xDDDDDDDDUL /* upper 16-bits of engine identifier register */ #define XDMA_ID_H2C 0x1fc0U #define XDMA_ID_C2H 0x1fc1U /* for C2H AXI-ST mode */ #define CYCLIC_RX_PAGES_MAX 256 #define LS_BYTE_MASK 0x000000FFUL #define BLOCK_ID_MASK 0xFFF00000 #define BLOCK_ID_HEAD 0x1FC00000 #define IRQ_BLOCK_ID 0x1fc20000UL #define CONFIG_BLOCK_ID 0x1fc30000UL #define WB_COUNT_MASK 0x00ffffffUL #define WB_ERR_MASK (1UL << 31) #define POLL_TIMEOUT_SECONDS 10 #define MAX_USER_IRQ 16 #define MAX_DESC_BUS_ADDR (0xffffffffULL) #define DESC_MAGIC 0xAD4B0000UL #define C2H_WB 0x52B4UL #define MAX_NUM_ENGINES (XDMA_CHANNEL_NUM_MAX * 2) #define H2C_CHANNEL_OFFSET 0x1000 #define SGDMA_OFFSET_FROM_CHANNEL 0x4000 #define CHANNEL_SPACING 0x100 #define TARGET_SPACING 0x1000 #define BYPASS_MODE_SPACING 0x0100 /* obtain the 32 most significant (high) bits of a 32-bit or 64-bit address */ #define PCI_DMA_H(addr) ((addr >> 16) >> 16) /* obtain the 32 least significant (low) bits of a 32-bit or 64-bit address */ #define PCI_DMA_L(addr) (addr & 0xffffffffUL) #ifndef VM_RESERVED #define VMEM_FLAGS (VM_IO | VM_DONTEXPAND | VM_DONTDUMP) #else #define VMEM_FLAGS (VM_IO | VM_RESERVED) #endif #ifdef __LIBXDMA_DEBUG__ #define dbg_io pr_err #define dbg_fops pr_err #define dbg_perf pr_err #define dbg_sg pr_err #define dbg_tfr pr_err #define dbg_irq pr_err #define dbg_init pr_err #define dbg_desc pr_err #else /* disable debugging */ #define dbg_io(...) #define dbg_fops(...) #define dbg_perf(...) #define dbg_sg(...) #define dbg_tfr(...) #define dbg_irq(...) #define dbg_init(...) #define dbg_desc(...) #endif /* SECTION: Enum definitions */ enum transfer_state { TRANSFER_STATE_NEW = 0, TRANSFER_STATE_SUBMITTED, TRANSFER_STATE_COMPLETED, TRANSFER_STATE_FAILED, TRANSFER_STATE_ABORTED }; enum shutdown_state { ENGINE_SHUTDOWN_NONE = 0, /* No shutdown in progress */ ENGINE_SHUTDOWN_REQUEST = 1, /* engine requested to shutdown */ ENGINE_SHUTDOWN_IDLE = 2 /* engine has shutdown and is idle */ }; enum dev_capabilities { CAP_64BIT_DMA = 2, CAP_64BIT_DESC = 4, CAP_ENGINE_WRITE = 8, CAP_ENGINE_READ = 16 }; /* SECTION: Structure definitions */ struct config_regs { u32 identifier; u32 reserved_1[4]; u32 msi_enable; }; /** * SG DMA Controller status and control registers * * These registers make the control interface for DMA transfers. * * It sits in End Point (FPGA) memory BAR[0] for 32-bit or BAR[0:1] for 64-bit. * It references the first descriptor which exists in Root Complex (PC) memory. * * @note The registers must be accessed using 32-bit (PCI DWORD) read/writes, * and their values are in little-endian byte ordering. */ struct engine_regs { u32 identifier; u32 control; u32 control_w1s; u32 control_w1c; u32 reserved_1[12]; /* padding */ u32 status; u32 status_rc; u32 completed_desc_count; u32 alignments; u32 reserved_2[14]; /* padding */ u32 poll_mode_wb_lo; u32 poll_mode_wb_hi; u32 interrupt_enable_mask; u32 interrupt_enable_mask_w1s; u32 interrupt_enable_mask_w1c; u32 reserved_3[9]; /* padding */ u32 perf_ctrl; u32 perf_cyc_lo; u32 perf_cyc_hi; u32 perf_dat_lo; u32 perf_dat_hi; u32 perf_pnd_lo; u32 perf_pnd_hi; } __packed; struct engine_sgdma_regs { u32 identifier; u32 reserved_1[31]; /* padding */ /* bus address to first descriptor in Root Complex Memory */ u32 first_desc_lo; u32 first_desc_hi; /* number of adjacent descriptors at first_desc */ u32 first_desc_adjacent; u32 credits; } __packed; struct msix_vec_table_entry { u32 msi_vec_addr_lo; u32 msi_vec_addr_hi; u32 msi_vec_data_lo; u32 msi_vec_data_hi; } __packed; struct msix_vec_table { struct msix_vec_table_entry entry_list[32]; } __packed; struct interrupt_regs { u32 identifier; u32 user_int_enable; u32 user_int_enable_w1s; u32 user_int_enable_w1c; u32 channel_int_enable; u32 channel_int_enable_w1s; u32 channel_int_enable_w1c; u32 reserved_1[9]; /* padding */ u32 user_int_request; u32 channel_int_request; u32 user_int_pending; u32 channel_int_pending; u32 reserved_2[12]; /* padding */ u32 user_msi_vector[8]; u32 channel_msi_vector[8]; } __packed; struct sgdma_common_regs { u32 padding[8]; u32 credit_mode_enable; u32 credit_mode_enable_w1s; u32 credit_mode_enable_w1c; } __packed; /* Structure for polled mode descriptor writeback */ struct xdma_poll_wb { u32 completed_desc_count; u32 reserved_1[7]; } __packed; /** * Descriptor for a single contiguous memory block transfer. * * Multiple descriptors are linked by means of the next pointer. An additional * extra adjacent number gives the amount of extra contiguous descriptors. * * The descriptors are in root complex memory, and the bytes in the 32-bit * words must be in little-endian byte ordering. */ struct xdma_desc { u32 control; u32 bytes; /* transfer length in bytes */ u32 src_addr_lo; /* source address (low 32-bit) */ u32 src_addr_hi; /* source address (high 32-bit) */ u32 dst_addr_lo; /* destination address (low 32-bit) */ u32 dst_addr_hi; /* destination address (high 32-bit) */ /* * next descriptor in the single-linked list of descriptors; * this is the PCIe (bus) address of the next descriptor in the * root complex memory */ u32 next_lo; /* next desc address (low 32-bit) */ u32 next_hi; /* next desc address (high 32-bit) */ } __packed; /* 32 bytes (four 32-bit words) or 64 bytes (eight 32-bit words) */ struct xdma_result { u32 status; u32 length; u32 reserved_1[6]; /* padding */ } __packed; struct sw_desc { dma_addr_t addr; unsigned int len; }; /* Describes a (SG DMA) single transfer for the engine */ struct xdma_transfer { struct list_head entry; /* queue of non-completed transfers */ struct xdma_desc *desc_virt; /* virt addr of the 1st descriptor */ dma_addr_t desc_bus; /* bus addr of the first descriptor */ int desc_adjacent; /* adjacent descriptors at desc_bus */ int desc_num; /* number of descriptors in transfer */ enum dma_data_direction dir; wait_queue_head_t wq; /* wait queue for transfer completion */ enum transfer_state state; /* state of the transfer */ unsigned int flags; #define XFER_FLAG_NEED_UNMAP 0x1 int cyclic; /* flag if transfer is cyclic */ int last_in_request; /* flag if last within request */ unsigned int len; struct sg_table *sgt; }; struct xdma_request_cb { struct sg_table *sgt; unsigned int total_len; u64 ep_addr; struct xdma_transfer xfer; unsigned int sw_desc_idx; unsigned int sw_desc_cnt; struct sw_desc sdesc[0]; }; struct xdma_engine { unsigned long magic; /* structure ID for sanity checks */ struct xdma_dev *xdev; /* parent device */ char name[5]; /* name of this engine */ int version; /* version of this engine */ //dev_t cdevno; /* character device major:minor */ //struct cdev cdev; /* character device (embedded struct) */ /* HW register address offsets */ struct engine_regs *regs; /* Control reg BAR offset */ struct engine_sgdma_regs *sgdma_regs; /* SGDAM reg BAR offset */ u32 bypass_offset; /* Bypass mode BAR offset */ /* Engine state, configuration and flags */ enum shutdown_state shutdown; /* engine shutdown mode */ enum dma_data_direction dir; int device_open; /* flag if engine node open, ST mode only */ int running; /* flag if the driver started engine */ int non_incr_addr; /* flag if non-incremental addressing used */ int streaming; int addr_align; /* source/dest alignment in bytes */ int len_granularity; /* transfer length multiple */ int addr_bits; /* HW datapath address width */ int channel; /* engine indices */ int max_extra_adj; /* descriptor prefetch capability */ int desc_dequeued; /* num descriptors of completed transfers */ u32 status; /* last known status of device */ u32 interrupt_enable_mask_value;/* only used for MSIX mode to store per-engine interrupt mask value */ /* Transfer list management */ struct list_head transfer_list; /* queue of transfers */ /* Members applicable to AXI-ST C2H (cyclic) transfers */ struct xdma_result *cyclic_result; dma_addr_t cyclic_result_bus; /* bus addr for transfer */ struct xdma_request_cb *cyclic_req; struct sg_table cyclic_sgt; u8 eop_found; /* used only for cyclic(rx:c2h) */ int rx_tail; /* follows the HW */ int rx_head; /* where the SW reads from */ int rx_overrun; /* flag if overrun occured */ /* for copy from cyclic buffer to user buffer */ unsigned int user_buffer_index; /* Members associated with polled mode support */ u8 *poll_mode_addr_virt; /* virt addr for descriptor writeback */ dma_addr_t poll_mode_bus; /* bus addr for descriptor writeback */ /* Members associated with interrupt mode support */ wait_queue_head_t shutdown_wq; /* wait queue for shutdown sync */ spinlock_t lock; /* protects concurrent access */ int prev_cpu; /* remember CPU# of (last) locker */ int msix_irq_line; /* MSI-X vector for this engine */ u32 irq_bitmask; /* IRQ bit mask for this engine */ struct work_struct work; /* Work queue for interrupt handling */ spinlock_t desc_lock; /* protects concurrent access */ dma_addr_t desc_bus; struct xdma_desc *desc; /* for performance test support */ struct xdma_performance_ioctl *xdma_perf; /* perf test control */ wait_queue_head_t xdma_perf_wq; /* Perf test sync */ }; struct xdma_user_irq { struct xdma_dev *xdev; /* parent device */ u8 user_idx; /* 0 ~ 15 */ u8 events_irq; /* accumulated IRQs */ spinlock_t events_lock; /* lock to safely update events_irq */ wait_queue_head_t events_wq; /* wait queue to sync waiting threads */ irq_handler_t handler; void *dev; }; /* XDMA PCIe device specific book-keeping */ #define XDEV_FLAG_OFFLINE 0x1 struct xdma_dev { struct list_head list_head; struct list_head rcu_node; unsigned long magic; /* structure ID for sanity checks */ struct pci_dev *pdev; /* pci device struct from probe() */ int idx; /* dev index */ const char *mod_name; /* name of module owning the dev */ spinlock_t lock; /* protects concurrent access */ unsigned int flags; /* PCIe BAR management */ void *__iomem bar[XDMA_BAR_NUM]; /* addresses for mapped BARs */ int user_bar_idx; /* BAR index of user logic */ int config_bar_idx; /* BAR index of XDMA config logic */ int bypass_bar_idx; /* BAR index of XDMA bypass logic */ int regions_in_use; /* flag if dev was in use during probe() */ int got_regions; /* flag if probe() obtained the regions */ int user_max; int c2h_channel_max; int h2c_channel_max; /* Interrupt management */ int irq_count; /* interrupt counter */ int irq_line; /* flag if irq allocated successfully */ int msi_enabled; /* flag if msi was enabled for the device */ int msix_enabled; /* flag if msi-x was enabled for the device */ #if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) struct msix_entry entry[32]; /* msi-x vector/entry table */ #endif struct xdma_user_irq user_irq[16]; /* user IRQ management */ unsigned int mask_irq_user; /* XDMA engine management */ int engines_num; /* Total engine count */ u32 mask_irq_h2c; u32 mask_irq_c2h; struct xdma_engine engine_h2c[XDMA_CHANNEL_NUM_MAX]; struct xdma_engine engine_c2h[XDMA_CHANNEL_NUM_MAX]; /* SD_Accel specific */ enum dev_capabilities capabilities; u64 feature_id; }; static inline int xdma_device_flag_check(struct xdma_dev *xdev, unsigned int f) { unsigned long flags; spin_lock_irqsave(&xdev->lock, flags); if (xdev->flags & f) { spin_unlock_irqrestore(&xdev->lock, flags); return 1; } spin_unlock_irqrestore(&xdev->lock, flags); return 0; } static inline int xdma_device_flag_test_n_set(struct xdma_dev *xdev, unsigned int f) { unsigned long flags; int rv = 0; spin_lock_irqsave(&xdev->lock, flags); if (xdev->flags & f) { spin_unlock_irqrestore(&xdev->lock, flags); rv = 1; } else xdev->flags |= f; spin_unlock_irqrestore(&xdev->lock, flags); return rv; } static inline void xdma_device_flag_set(struct xdma_dev *xdev, unsigned int f) { unsigned long flags; spin_lock_irqsave(&xdev->lock, flags); xdev->flags |= f; spin_unlock_irqrestore(&xdev->lock, flags); } static inline void xdma_device_flag_clear(struct xdma_dev *xdev, unsigned int f) { unsigned long flags; spin_lock_irqsave(&xdev->lock, flags); xdev->flags &= ~f; spin_unlock_irqrestore(&xdev->lock, flags); } void write_register(u32 value, void *iomem); u32 read_register(void *iomem); struct xdma_dev *xdev_find_by_pdev(struct pci_dev *pdev); void xdma_device_offline(struct pci_dev *pdev, void *dev_handle); void xdma_device_online(struct pci_dev *pdev, void *dev_handle); int xdma_performance_submit(struct xdma_dev *xdev, struct xdma_engine *engine); struct xdma_transfer *engine_cyclic_stop(struct xdma_engine *engine); void enable_perf(struct xdma_engine *engine); void get_perf_stats(struct xdma_engine *engine); int xdma_cyclic_transfer_setup(struct xdma_engine *engine); int xdma_cyclic_transfer_teardown(struct xdma_engine *engine); ssize_t xdma_engine_read_cyclic(struct xdma_engine *, char __user *, size_t, int); int engine_addrmode_set(struct xdma_engine *engine, unsigned long arg); #endif /* XDMA_LIB_H */ ================================================ FILE: drivers/awsf1portal/libxdma_api.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * * Copyright(c) Sidebranch. * Copyright(c) Xilinx, Inc. * * Karen Xie * Leon Woestenberg * ******************************************************************************/ #ifndef __XDMA_BASE_API_H__ #define __XDMA_BASE_API_H__ #include #include #include /* * functions exported by the xdma driver */ typedef struct { u64 write_submitted; u64 write_completed; u64 read_requested; u64 read_completed; u64 restart; u64 open; u64 close; u64 msix_trigger; } xdma_statistics; /* * This struct should be constantly updated by XMDA using u64_stats_* APIs * The front end will read the structure without locking (That's why updating atomically is a must) * every time it prints the statistics. */ //static XDMA_Statistics stats; /* * xdma_device_open - read the pci bars and configure the fpga * should be called from probe() * NOTE: * user interrupt will not enabled until xdma_user_isr_enable() * is called * @pdev: ptr to pci_dev * @mod_name: the module name to be used for request_irq * @user_max: max # of user/event (interrupts) to be configured * @channel_max: max # of c2h and h2c channels to be configured * NOTE: if the user/channel provisioned is less than the max specified, * libxdma will update the user_max/channel_max * returns * a opaque handle (for libxdma to identify the device) * NULL, in case of error */ void *xdma_device_open(const char *mod_name, struct pci_dev *pdev, int *user_max, int *h2c_channel_max, int *c2h_channel_max); /* * xdma_device_close - prepare fpga for removal: disable all interrupts (users * and xdma) and release all resources * should called from remove() * @pdev: ptr to struct pci_dev * @tuples: from xdma_device_open() */ void xdma_device_close(struct pci_dev *pdev, void *dev_handle); /* * xdma_device_restart - restart the fpga * @pdev: ptr to struct pci_dev * TODO: * may need more refining on the parameter list * return < 0 in case of error * TODO: exact error code will be defined later */ int xdma_device_restart(struct pci_dev *pdev, void *dev_handle); /* * xdma_user_isr_register - register a user ISR handler * It is expected that the xdma will register the ISR, and for the user * interrupt, it will call the corresponding handle if it is registered and * enabled. * * @pdev: ptr to the the pci_dev struct * @mask: bitmask of user interrupts (0 ~ 15)to be registered * bit 0: user interrupt 0 * ... * bit 15: user interrupt 15 * any bit above bit 15 will be ignored. * @handler: the correspoinding handler * a NULL handler will be treated as de-registeration * @name: to be passed to the handler, ignored if handler is NULL` * @dev: to be passed to the handler, ignored if handler is NULL` * return < 0 in case of error * TODO: exact error code will be defined later */ int xdma_user_isr_register(void *dev_hndl, unsigned int mask, irq_handler_t handler, void *dev); /* * xdma_user_isr_enable/disable - enable or disable user interrupt * @pdev: ptr to the the pci_dev struct * @mask: bitmask of user interrupts (0 ~ 15)to be registered * return < 0 in case of error * TODO: exact error code will be defined later */ int xdma_user_isr_enable(void *dev_hndl, unsigned int mask); int xdma_user_isr_disable(void *dev_hndl, unsigned int mask); /* * xdma_xfer_submit - submit data for dma operation (for both read and write) * This is a blocking call * @channel: channle number (< channel_max) * == channel_max means libxdma can pick any channel available:q * @dir: DMA_FROM/TO_DEVICE * @offset: offset into the DDR/BRAM memory to read from or write to * @sg_tbl: the scatter-gather list of data buffers * @timeout: timeout in mili-seconds, *currently ignored * return # of bytes transfered or * < 0 in case of error * TODO: exact error code will be defined later */ ssize_t xdma_xfer_submit(void *dev_hndl, int channel, bool write, u64 ep_addr, struct sg_table *sgt, bool dma_mapped, int timeout_ms); /////////////////////missing API//////////////////// //xdma_get_channle_state - if no interrupt on DMA hang is available //xdma_channle_restart #endif ================================================ FILE: drivers/awsf1portal/linux/dma-buf.h ================================================ /* * Header file for dma buffer sharing framework. * * Copyright(C) 2011 Linaro Limited. All rights reserved. * Author: Sumit Semwal * * Many thanks to linaro-mm-sig list, and specially * Arnd Bergmann , Rob Clark and * Daniel Vetter for their support in creation and * refining of this idea. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ #ifndef __DMA_BUF_H__ #define __DMA_BUF_H__ #include #include #include #include #include #include struct device; struct dma_buf; struct dma_buf_attachment; /** * struct dma_buf_ops - operations possible on struct dma_buf * @attach: [optional] allows different devices to 'attach' themselves to the * given buffer. It might return -EBUSY to signal that backing storage * is already allocated and incompatible with the requirements * of requesting device. * @detach: [optional] detach a given device from this buffer. * @map_dma_buf: returns list of scatter pages allocated, increases usecount * of the buffer. Requires atleast one attach to be called * before. Returned sg list should already be mapped into * _device_ address space. This call may sleep. May also return * -EINTR. Should return -EINVAL if attach hasn't been called yet. * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter * pages. * @release: release this buffer; to be called after the last dma_buf_put. * @begin_cpu_access: [optional] called before cpu access to invalidate cpu * caches and allocate backing storage (if not yet done) * respectively pin the objet into memory. * @end_cpu_access: [optional] called after cpu access to flush caches. * @kmap_atomic: maps a page from the buffer into kernel address * space, users may not block until the subsequent unmap call. * This callback must not sleep. * @kunmap_atomic: [optional] unmaps a atomically mapped page from the buffer. * This Callback must not sleep. * @kmap: maps a page from the buffer into kernel address space. * @kunmap: [optional] unmaps a page from the buffer. * @mmap: used to expose the backing storage to userspace. Note that the * mapping needs to be coherent - if the exporter doesn't directly * support this, it needs to fake coherency by shooting down any ptes * when transitioning away from the cpu domain. * @vmap: [optional] creates a virtual mapping for the buffer into kernel * address space. Same restrictions as for vmap and friends apply. * @vunmap: [optional] unmaps a vmap from the buffer */ struct dma_buf_ops { int (*attach)(struct dma_buf *, struct device *, struct dma_buf_attachment *); void (*detach)(struct dma_buf *, struct dma_buf_attachment *); /* For {map,unmap}_dma_buf below, any specific buffer attributes * required should get added to device_dma_parameters accessible * via dev->dma_params. */ struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY * if the call would block. */ /* after final dma_buf_put() */ void (*release)(struct dma_buf *); int (*begin_cpu_access)(struct dma_buf *, size_t, size_t, enum dma_data_direction); void (*end_cpu_access)(struct dma_buf *, size_t, size_t, enum dma_data_direction); void *(*kmap_atomic)(struct dma_buf *, unsigned long); void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); void *(*kmap)(struct dma_buf *, unsigned long); void (*kunmap)(struct dma_buf *, unsigned long, void *); int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); void *(*vmap)(struct dma_buf *); void (*vunmap)(struct dma_buf *, void *vaddr); }; /** * struct dma_buf - shared buffer object * @size: size of the buffer * @file: file pointer used for sharing buffers across, and for refcounting. * @attachments: list of dma_buf_attachment that denotes all devices attached. * @ops: dma_buf_ops associated with this buffer object. * @priv: exporter specific private data for this buffer object. */ struct dma_buf { size_t size; struct file *file; struct list_head attachments; const struct dma_buf_ops *ops; /* mutex to serialize list manipulation, attach/detach and vmap/unmap */ struct mutex lock; unsigned vmapping_counter; void *vmap_ptr; void *priv; }; /** * struct dma_buf_attachment - holds device-buffer attachment data * @dmabuf: buffer for this attachment. * @dev: device attached to the buffer. * @node: list of dma_buf_attachment. * @priv: exporter specific attachment data. * * This structure holds the attachment information between the dma_buf buffer * and its user device(s). The list contains one attachment struct per device * attached to the buffer. */ struct dma_buf_attachment { struct dma_buf *dmabuf; struct device *dev; struct list_head node; void *priv; }; /** * get_dma_buf - convenience wrapper for get_file. * @dmabuf: [in] pointer to dma_buf * * Increments the reference count on the dma-buf, needed in case of drivers * that either need to create additional references to the dmabuf on the * kernel side. For example, an exporter that needs to keep a dmabuf ptr * so that subsequent exports don't create a new dmabuf. */ static inline void get_dma_buf(struct dma_buf *dmabuf) { get_file(dmabuf->file); } struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, struct device *dev); void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *dmabuf_attach); struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, size_t size, int flags); int dma_buf_fd(struct dma_buf *dmabuf, int flags); struct dma_buf *dma_buf_get(int fd); void dma_buf_put(struct dma_buf *dmabuf); struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, enum dma_data_direction dir); void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, enum dma_data_direction dir); void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); void *dma_buf_kmap(struct dma_buf *, unsigned long); void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); void *dma_buf_vmap(struct dma_buf *); void dma_buf_vunmap(struct dma_buf *, void *vaddr); #endif /* __DMA_BUF_H__ */ ================================================ FILE: drivers/awsf1portal/pcieportal.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef __PCIEPORTAL_H__ #define __PCIEPORTAL_H__ #include /* * IOCTLs */ /* magic number for IOCTLs */ #define BNOC_IOC_MAGIC 0xB5 /* Number of boards to support */ #define NUM_BOARDS 4 #define MAX_NUM_PORTALS 32 /* Structures used with IOCTLs */ typedef struct { unsigned long base; unsigned int trace; unsigned int traceLength; unsigned int intval[MAX_NUM_PORTALS]; unsigned int name[MAX_NUM_PORTALS]; } tTraceInfo; typedef struct { int fd; int id; } tSendFd; typedef struct { int index; /* in param */ char md5[33]; /* out param -- asciz */ char filename[33]; /* out param -- asciz */ } PortalSignaturePcie; typedef unsigned int tTlpData[6]; typedef struct ChangeEntry { unsigned int timestamp; unsigned char src; unsigned int value : 24; } tChangeEntry; /* IOCTL code definitions */ #define BNOC_GET_TLP _IOR(BNOC_IOC_MAGIC,7,tTlpData*) #define BNOC_TRACE _IOWR(BNOC_IOC_MAGIC,8,tTraceInfo*) #define BNOC_ENABLE_TRACE _IOR(BNOC_IOC_MAGIC,8,int*) #define PCIE_SEND_FD _IOR(BNOC_IOC_MAGIC,12,tSendFd*) #define PCIE_DEREFERENCE _IOR(BNOC_IOC_MAGIC,13,int) #define PCIE_SIGNATURE _IOR(BNOC_IOC_MAGIC,14,PortalSignaturePcie) #define PCIE_CHANGE_ENTRY _IOR(BNOC_IOC_MAGIC,15,tChangeEntry*) #endif // __PCIEPORTAL_H__ ================================================ FILE: drivers/awsf1portal/portal.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Linux device driver for CONNECTAL portals on FPGAs connected via PCIe. */ #include #include #include /* LINUX_VERSION_CODE, KERNEL_VERSION */ #include /* pci device types, fns, etc. */ #include /* error codes */ #include /* I/O mapping, reading, writing */ #include /* struct cdev */ #include /* struct file_operations */ #include /* __init, __exit, etc. */ #include /* ioctl macros */ #include /* request_irq, free_irq, etc. */ #include /* kmalloc, kfree, struct page, etc. */ #include /* task_struct */ #include /* sg_* operations */ #include /* mutex_lock, mutex_unlock, etc. */ #include /* poll_table, etc. */ #include /* copy_to_user, copy_from_user */ #include #include "driverversion.h" #include "libxdma.h" #include "xdma_mod.h" #include "pcieportal.h" #include "portal_internal.h" #define CONNECTAL_DRIVER_CODE #include "portal.h" // PORTAL_BASE_OFFSET #include "dmaSendFd.h" #include "portalKernel.h" /* stem used for module and device names */ #define DEV_NAME "portal" #define BLUESPEC_VENDOR_ID 0x1be7 #define AMAZON_VENDOR_ID 0x1d0f #define CONNECTAL_DEVICE_ID 0xc100 #define AMAZON_DEVICE_ID 0xf000 /* CSR address space offsets */ #define CSR_ID ( 0 << 2) /* 64-bit */ #define CSR_TLPDATAFIFO_DEQ ( 768 << 2) #define CSR_TLPTRACELENGTHREG ( 774 << 2) #define CSR_TLPTRACINGREG ( 775 << 2) #define CSR_TLPDATABRAMRESPONSESLICE0 ( 776 << 2) #define CSR_TLPDATABRAMRESPONSESLICE1 ( 777 << 2) #define CSR_TLPDATABRAMRESPONSESLICE2 ( 778 << 2) #define CSR_TLPDATABRAMRESPONSESLICE3 ( 779 << 2) #define CSR_TLPDATABRAMRESPONSESLICE4 ( 780 << 2) #define CSR_TLPDATABRAMRESPONSESLICE5 ( 781 << 2) #define CSR_TLPPCIEWRADDRREG ( 792 << 2) #define CSR_CHANGELO ( 801 << 2) #define CSR_CHANGEHI ( 802 << 2) /* MSIX must be in separate 4kb page */ #define CSR_MSIX_ADDR_LO (1024 << 2) #define CSR_MSIX_ADDR_HI (1025 << 2) #define CSR_MSIX_MSG_DATA (1026 << 2) #define CSR_MSIX_MASKED (1027 << 2) #define PCR_IID_OFFSET 0x010 #define PCR_NUM_TILES_OFFSET 0x008 #define PCR_NUM_PORTALS_OFFSET 0x014 #define MAX_MSIX_ENTRIES 16 #define MAX_MINOR_COUNT (NUM_BOARDS * MAX_NUM_PORTALS) /* static device data */ static dev_t device_number; static char portalp[MAX_MINOR_COUNT]; // free map of minor numbers static struct class *pcieportal_class = NULL; static unsigned long long expected_magic = 'B' | ((unsigned long long) 'l' << 8) | ((unsigned long long) 'u' << 16) | ((unsigned long long) 'e' << 24) | ((unsigned long long) 's' << 32) | ((unsigned long long) 'p' << 40) | ((unsigned long long) 'e' << 48) | ((unsigned long long) 'c' << 56); /* * interrupt handler */ static irqreturn_t intr_handler(int irq, void *p) { tTile *this_tile = p; tBoard *this_board = this_tile->board; int i; //printk(KERN_INFO "%s_%d: interrupt %d!\n", DEV_NAME, this_tile->device_tile-1, irq); for (i = 0; i < MAX_NUM_PORTALS; i++) { if ((this_tile->device_tile-1 == this_board->portal[i].device_tile) || this_tile->board->info.aws_shell) { wake_up_interruptible(&(this_board->portal[i].wait_queue)); } } return IRQ_HANDLED; } /* * driver file operations */ /* open the device file */ static int pcieportal_open(struct inode *inode, struct file *filp) { int err = 0; tPortal *this_portal = (tPortal *)inode->i_cdev; if (!this_portal) { printk("pcieportal_open: basedevice_number=%x /dev/connectal\n", device_number); } else { printk("pcieportal_open: basedevice_number=%x tile=%d name=%d\n", device_number, this_portal->device_tile, this_portal->device_name); //printk("[%s:%d] inode %p filp %p portal %p priv %p privp %p extra %p\n", __FUNCTION__, __LINE__, inode, filp, this_portal, filp->private_data, privp, this_portal->extra); init_waitqueue_head(&(this_portal->wait_queue)); /* increment the open file count */ this_portal->board->open_count += 1; } filp->private_data = (void *) this_portal; // FIXME: why does the kernel think this device is RDONLY? filp->f_mode |= FMODE_WRITE; return err; } /* close the device file */ static int pcieportal_release(struct inode *inode, struct file *filp) { tPortal *this_portal = (tPortal *) filp->private_data; if (this_portal) { struct list_head *pmlist; PortalInternal devptr = {.map_base = this_portal->regs, .transport = &kernelfunc}; /* decrement the open file count */ init_waitqueue_head(&(this_portal->wait_queue)); this_portal->board->open_count -= 1; printk("%s_%d_%d: Closed device file\n", DEV_NAME, this_portal->device_tile, this_portal->device_name); list_for_each(pmlist, &this_portal->pmlist) { struct pmentry *pmentry = list_entry(pmlist, struct pmentry, pmlist); printk(" returning id=%d fmem=%p\n", pmentry->id, pmentry->fmem); MMURequest_idReturn(&devptr, pmentry->id); fput(pmentry->fmem); kfree(pmentry); } INIT_LIST_HEAD(&this_portal->pmlist); } return 0; /* success */ } /* poll operation to predict blocking of reads & writes */ static unsigned int pcieportal_poll(struct file *filp, poll_table *poll_table) { tPortal *this_portal = (tPortal *) filp->private_data; unsigned int mask = 0; uint32_t status = 0; //printk(KERN_INFO "%s_%d_%d: poll function called\n", DEV_NAME, this_portal->device_tile, this_portal->device_name); poll_wait(filp, &this_portal->wait_queue, poll_table); if (this_portal->regs) { status = *this_portal->regs; } if (status) mask |= POLLIN | POLLRDNORM; /* readable */ //mask |= POLLOUT | POLLWRNORM; /* writable */ //printk(KERN_INFO "%s_%d_%d: poll return status is %x\n", DEV_NAME, this_portal->device_tile, this_portal->device_name, mask); return mask; } /* * driver IOCTL operations */ static long pcieportal_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int err = 0; tPortal *this_portal = (tPortal *) filp->private_data; tBoard *this_board = NULL; //tBoardInfo info; if (this_portal) this_board = this_portal->board; /* basic sanity checks */ if (_IOC_DIR(cmd) & _IOC_READ) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) && !(defined(RHEL_MAJOR) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,0)) err = !access_ok(VERIFY_WRITE, (void __user *) arg, _IOC_SIZE(cmd)); #else err = !access_ok((void __user *) arg, _IOC_SIZE(cmd)); #endif } else if (_IOC_DIR(cmd) & _IOC_WRITE) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) && !(defined(RHEL_MAJOR) && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,0)) err = !access_ok(VERIFY_WRITE, (void __user *) arg, _IOC_SIZE(cmd)); #else err = !access_ok((void __user *) arg, _IOC_SIZE(cmd)); #endif } if (!err) switch (cmd) { case PCIE_SEND_FD: { /* pushd down allocated fd */ tSendFd sendFd; struct pmentry *pmentry; PortalInternal devptr = {.map_base = this_portal->regs, .transport = &kernelfunc}; err = copy_from_user(&sendFd, (void __user *) arg, sizeof(sendFd)); if (err) break; pmentry = (struct pmentry *)kzalloc(sizeof(struct pmentry), GFP_KERNEL); INIT_LIST_HEAD(&pmentry->pmlist); pmentry->fmem = fget(sendFd.fd); pmentry->id = sendFd.id; printk("[%s:%d] PCIE_SEND_FD fd=%x id=%x fmem=%p **\n", __FUNCTION__, __LINE__, sendFd.fd, sendFd.id, pmentry->fmem); list_add(&pmentry->pmlist, &this_portal->pmlist); err = send_fd_to_portal(&devptr, sendFd.fd, sendFd.id, 0); if (err < 0) break; err = 0; } break; case PCIE_DEREFERENCE: { int id = arg; struct list_head *pmlist, *n; PortalInternal devptr = {.map_base = this_portal->regs, .transport = &kernelfunc}; err = -ENOENT; MMURequest_idReturn(&devptr, id); list_for_each_safe(pmlist, n, &this_portal->pmlist) { struct pmentry *pmentry = list_entry(pmlist, struct pmentry, pmlist); if (pmentry->id == id) { printk("%s:%d releasing portalmem id=%d fmem=%p count=%ld\n", __FUNCTION__, __LINE__, id, pmentry->fmem, (unsigned long)pmentry->fmem->f_count.counter); fput(pmentry->fmem); list_del(&pmentry->pmlist); kfree(pmentry); err = 0; break; } } } break; default: return -ENOTTY; } if (err) return -EFAULT; return 0; } static int portal_mmap(struct file *filp, struct vm_area_struct *vma) { tPortal *this_portal = (tPortal *) filp->private_data; struct pci_dev *pci_dev = this_portal->board->pci_dev; off_t off; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; if (vma->vm_pgoff < 16) { if (this_portal->board->info.aws_shell) { off = pci_dev->resource[0].start + this_portal->offset; } else { off = pci_dev->resource[2].start + this_portal->offset; } printk("portal_mmap portal_number=%d board_start=%012lx portal_start=%012lx\n", this_portal->portal_number, (long) pci_dev->resource[2].start, off); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_pgoff = off >> PAGE_SHIFT; //vma->vm_flags |= VM_IO | VM_RESERVED; } else { if (!this_portal->virt) { this_portal->virt = dma_alloc_coherent(&pci_dev->dev, vma->vm_end - vma->vm_start, &this_portal->dma_handle, GFP_ATOMIC); //this_portal->virt =pci_alloc_consistent(pci_dev, PORTAL_BASE_OFFSET, &this_portal->extra->dma_handle); printk("dma_alloc_coherent virt=%p dma_handle=%p\n", this_portal->virt, (void *) this_portal->dma_handle); } //vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); off = this_portal->dma_handle; } vma->vm_flags |= VM_IO; if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; } static ssize_t pcieportal_read(struct file *filp, char *buffer, size_t length, loff_t *offset) { return 0; } /* file operations pointers */ static const struct file_operations pcieportal_fops = { .owner = THIS_MODULE, .open = pcieportal_open, .read = pcieportal_read, .release = pcieportal_release, .poll = pcieportal_poll, .unlocked_ioctl = pcieportal_ioctl, .compat_ioctl = pcieportal_ioctl, .mmap = portal_mmap }; static int connectal_open(struct inode *inode, struct file *filp) { int err = 0; tBoard *this_board = container_of(inode->i_cdev, tBoard, cdev); printk("%s: basedevice_number=%x /dev/connectal\n", __FUNCTION__, device_number); filp->private_data = (void *) this_board; return err; } static ssize_t connectal_read(struct file *filp, char *buffer, size_t length, loff_t *offset) { return 0; } static const struct file_operations connectal_fops = { .owner = THIS_MODULE, .open = connectal_open, .read = connectal_read }; static int pcieportal_dma_pcis_open(struct inode *inode, struct file *filp) { tBoard *this_board = container_of(inode->i_cdev, tBoard, dma_pcis_cdev); int err = 0; printk("pcieportal_dma_pcis_open this_board %lx\n", (long)this_board); filp->private_data = (void *) this_board; // FIXME: why does the kernel think this device is RDONLY? filp->f_mode |= FMODE_WRITE; return err; } /* close the device file */ static int pcieportal_dma_pcis_release(struct inode *inode, struct file *filp) { // do we need to unmap? return 0; /* success */ } static int portal_dma_pcis_mmap(struct file *filp, struct vm_area_struct *vma) { tBoard *this_board = (tBoard *) filp->private_data; struct pci_dev *pci_dev = this_board->pci_dev; off_t off = 0; printk("%s: this_board %08lx\n", __FUNCTION__, (long)this_board); if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; if (this_board->info.aws_shell) { off = pci_dev->resource[4].start; } else { printk("portal_dma_pcis only supported on AWS F1\n"); return -EINVAL; } printk("portal_dma_pcis_mmap board_start=%012lx", (long) pci_dev->resource[4].start); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_pgoff = off >> PAGE_SHIFT; //vma->vm_flags |= VM_IO | VM_RESERVED; vma->vm_flags |= VM_IO; if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; } static const struct file_operations pcieportal_dma_pcis_fops = { .owner = THIS_MODULE, .open = pcieportal_dma_pcis_open, .read = pcieportal_read, .release = pcieportal_dma_pcis_release, .mmap = portal_dma_pcis_mmap }; #ifdef PCIEPORTAL_TUNE_CAPS static void tune_pcie_caps(struct pci_dev *dev) { struct pci_dev *parent; u16 rc_mpss, rc_mps, ep_mpss, ep_mps; u16 rc_mrrs, ep_mrrs, max_mrrs; printk("%s: %s:%d\n", DEV_NAME, __FUNCTION__, __LINE__); parent = dev->bus->self; // why does parent have to be root? if (!pci_is_root_bus(parent->bus)) { printk("%s: parent is not root\n", DEV_NAME); return; } /* max payload size adjustment */ rc_mpss = parent->pcie_mpss; rc_mps = ffs(pcie_get_mps(parent)) - 8; ep_mpss = dev->pcie_mpss; ep_mps = ffs(pcie_get_mps(dev)) - 8; rc_mpss = max(rc_mpss, ep_mpss); if (rc_mpss > rc_mps) { rc_mps = rc_mpss; pcie_set_mps(parent, 128 << rc_mps); } if (rc_mpss > ep_mps) { ep_mps = rc_mpss; pcie_set_mps(dev, 128 << ep_mps); } printk("%s: %s:%d parent.mps=%d dev.mps=%d\n", DEV_NAME, __FUNCTION__, __LINE__, pcie_get_mps(parent), pcie_get_mps(dev)); /* max read request size, limited to 4096 by PCIe spec */ max_mrrs = 128 << 5; rc_mrrs = pcie_get_readrq(parent); ep_mrrs = pcie_get_readrq(dev); if (max_mrrs > rc_mrrs) { rc_mrrs = max_mrrs; pcie_set_readrq(parent, rc_mrrs); } if (max_mrrs > ep_mrrs) { ep_mrrs = max_mrrs; pcie_set_readrq(dev, ep_mrrs); } printk("%s: %s:%d parent.readrq=%d dev.readrq=%d\n", DEV_NAME, __FUNCTION__, __LINE__, pcie_get_readrq(parent), pcie_get_readrq(dev)); } #endif // PCIEPORTAL_TUNE_CAPS int pcieportal_board_activate(int activate, tBoard *this_board, struct xdma_pci_dev *xpdev, struct pci_dev *dev) { int i; int err = 0; unsigned long long magic_num; #if 0 int rc; int num_entries = MAX_MSIX_ENTRIES; struct msix_entry msix_entries[MAX_MSIX_ENTRIES]; #endif int fpn = 0; int num_tiles, tile_index; void __iomem *ptile; int board_number = this_board->info.board_number; if (!device_number) { pcieportal_class = class_create(THIS_MODULE, "Connectal"); if (IS_ERR(pcieportal_class)) { printk(KERN_ERR "%s: failed to create class Connectal\n", DEV_NAME); return PTR_ERR(pcieportal_class); } /* dynamically allocate a device number */ if (alloc_chrdev_region(&device_number, 1, MAX_MINOR_COUNT + 1, DEV_NAME) < 0) { printk(KERN_ERR "%s: failed to allocate character device region\n", DEV_NAME); class_destroy(pcieportal_class); return -1; } } printk("this_board %08lx\n", (long)this_board); if (activate && this_board->extra == 0) { for (i = 0; i < MAX_NUM_PORTALS; i++) { INIT_LIST_HEAD(&this_board->portal[i].pmlist); } } printk("[%s:%d]\n", __FUNCTION__, __LINE__); if (activate) { dev_t this_device_number; void *portal_base = 0; for (i = 0; i < MAX_NUM_PORTALS; i++) this_board->portal[i].device_name = -1; for (i = 0; i < MAX_NUM_PORTALS; i++) init_waitqueue_head(&(this_board->portal[i].wait_queue)); this_board->pci_dev = dev; /* enable the PCI device */ if (pci_enable_device(dev)) { printk(KERN_ERR "%s: failed to enable %s\n", DEV_NAME, pci_name(dev)); err = -EFAULT; goto err_exit; } /* reserve PCI memory regions */ for (i = 0; i < 5; i++) printk("pci bar %d start=%08lx end=%08lx flags=%lx\n", i, (unsigned long) dev->resource[i].start, (unsigned long) dev->resource[i].end, dev->resource[i].flags); /* mapped BARs */ this_board->bar0io = xpdev->xdev->bar[0]; printk("bar0io=%p\n", this_board->bar0io); this_board->bar1io = xpdev->xdev->bar[1]; printk("bar1io=%p\n", this_board->bar1io); this_board->bar2io = xpdev->xdev->bar[2]; printk("bar2io=%p\n", this_board->bar2io); this_board->bar4io = xpdev->xdev->bar[4]; printk("bar4io=%p\n", this_board->bar4io); if (!this_board->bar4io) { this_board->info.aws_shell = 0; // this replaces 'connectal/pcie/connectalutil/connectalutil trace /dev/fpga0' // but why is it needed?... iowrite32(0, this_board->bar0io + CSR_TLPPCIEWRADDRREG); // enable tracing iowrite32(1, this_board->bar0io + CSR_TLPTRACINGREG); /* check the magic number in BAR 0 */ magic_num = ((long long)ioread32(this_board->bar0io + CSR_ID + 4)) << 32; magic_num |= ioread32(this_board->bar0io + CSR_ID); if (magic_num != expected_magic) { printk(KERN_ERR "%s: magic number %llx does not match expected %llx\n", DEV_NAME, magic_num, expected_magic); err = -EINVAL; } // check for xdma on bar2 } else { this_board->info.aws_shell = 1; printk(" xdma block ID %x\n", ioread32(this_board->bar2io + 0x0000)); printk(" irq block ID %x\n", ioread32(this_board->bar2io + 0x2000)); printk("config block ID %x\n", ioread32(this_board->bar2io + 0x3000)); } printk("pci_dev %08lx\n", (long)this_board->pci_dev); this_board->irq_num = pci_irq_vector(this_board->pci_dev, 8); for (i = 8; i < 16; i++) { int irq_num = pci_irq_vector(this_board->pci_dev, i); if (request_irq(irq_num, intr_handler, 0, DEV_NAME, (void *)&this_board->tile[0])) { printk(KERN_ERR "%s: Failed to get requested IRQ %d\n", DEV_NAME, irq_num); err = -EBUSY; } } #if 0 /* enable MSIX */ for (i = 0; i < num_entries; i++) msix_entries[i].entry = i; if ((num_entries = pci_enable_msix_range(dev, msix_entries, num_entries, num_entries)) < 0) { printk(KERN_ERR "%s: Failed to setup MSIX interrupts\n", DEV_NAME); err = -EFAULT; goto BARS_MAPPED_label; } this_board->irq_num = msix_entries[0].vector; printk(KERN_INFO "%s: Using MSIX interrupts num_entries=%d check_device\n", DEV_NAME, num_entries); for (i = 0; i < num_entries; i++) printk(KERN_INFO "%s: msix_entries[%d] vector=%d entry=%08x\n", DEV_NAME, i, msix_entries[i].vector, msix_entries[i].entry); /* install the IRQ handler */ for (i = 0; i < num_entries; i++) { if (request_irq(this_board->irq_num + i, intr_handler, 0, DEV_NAME, (void *) &this_board->tile[i])) { printk(KERN_ERR "%s: Failed to get requested IRQ %d\n", DEV_NAME, this_board->irq_num); err = -EBUSY; goto MSI_ENABLED_label; } } /* set MSIX Entry 0 Vector Control value to 0 (unmasked) */ printk(KERN_INFO "%s: MSIX interrupts enabled with %d IRQs starting at %d\n", DEV_NAME, num_entries, this_board->irq_num); iowrite32(0, this_board->bar0io + CSR_MSIX_MASKED); pci_set_master(dev); /* enable PCI bus master */ #endif if (this_board->info.aws_shell) { portal_base = this_board->bar0io; ptile = this_board->bar0io; printk("bar0io[0]=%08x\n", *(int *)this_board->bar0io); // enable user interrupts via XDMA block in AWS F1 Shell iowrite32(0xFFFF, this_board->bar2io + 0x2000 + 4); printk("enabled user interrupts in XDMA %x\n", ioread32(this_board->bar2io + 0x2000 + 4)); } else { portal_base = this_board->bar2io; ptile = this_board->bar2io; } num_tiles = *(volatile uint32_t *)(ptile + PCR_NUM_TILES_OFFSET); if (num_tiles < 0 || num_tiles > 16) num_tiles = 0; tile_index = 0; do { // loop over all tiles void __iomem *pportal = ptile; int num_portals = *(volatile uint32_t *)(pportal + PCR_NUM_PORTALS_OFFSET); int portal_index = 0; printk("tile %d num_portals %d\n", tile_index, num_portals); this_board->tile[tile_index].board = this_board; this_board->tile[tile_index].device_tile = tile_index + 1; do { // loop over all portals in a tile int freep; uint32_t iid = *(volatile uint32_t *)(pportal + PCR_IID_OFFSET); tPortal *this_portal = &this_board->portal[fpn]; unsigned long offs = ((unsigned long)pportal) - ((unsigned long)portal_base); if (iid == -1) break; printk("%s:%d num_tiles %x/%x num_portals %x/%x fpn %x iid=%d pportal %p offset %lx\n", __FUNCTION__, __LINE__, tile_index, num_tiles, portal_index, num_portals, fpn, iid, pportal, offs); for (freep = 0; freep < sizeof(portalp)/sizeof(portalp[0]); freep++) if (!portalp[freep]) break; if (freep == sizeof(portalp)/sizeof(portalp[0])) { printk(KERN_ERR "%s: too many portals\n", KERN_ERR); err = -EFAULT; } else portalp[freep] = 1; this_portal->device_number = freep; this_portal->device_tile = tile_index; this_portal->portal_number = fpn; this_portal->device_name = iid; this_portal->board = this_board; this_portal->regs = (volatile uint32_t *)pportal; this_portal->offset = offs; /* add the device operations */ cdev_init(&this_portal->cdev, &pcieportal_fops); this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + this_portal->device_number); printk("%s:%d: calling cdev_add this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); if (cdev_add(&this_portal->cdev, this_device_number, 1)) { printk(KERN_ERR "%s: cdev_add %x failed\n", DEV_NAME, this_device_number); err = -EFAULT; } else { /* create a device node via udev */ printk("%s:%d: calling_device_create /dev/%s_b%dt%dp%d = %x\n", DEV_NAME, __LINE__, DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name, this_device_number); device_create(pcieportal_class, &dev->dev, this_device_number, this_portal, "%s_b%dt%dp%d", DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name); printk(KERN_INFO "%s: /dev/%s_b%dt%dp%d = %x created\n", DEV_NAME, DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name, this_device_number); } if (++fpn >= MAX_NUM_PORTALS){ printk(KERN_INFO "%s: MAX_NUM_PORTALS exceeded", __func__); err = -EFAULT; break; } pportal += PORTAL_BASE_OFFSET; } while (++portal_index < num_portals); ptile += TILE_BASE_OFFSET; } while (++tile_index < num_tiles); this_board->info.num_portals = fpn; if (board_number == 0) { this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT); cdev_init(&this_board->cdev, &connectal_fops); printk("%s:%d: calling cdev_add this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); if (cdev_add(&this_board->cdev, this_device_number, 1)) { printk(KERN_ERR "%s: cdev_add board failed\n", DEV_NAME); } printk("%s:%d: calling device_create this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); device_create(pcieportal_class, &dev->dev, this_device_number, NULL, "connectal"); // add the device node for portal_dma_pcis this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT + 1); cdev_init(&this_board->dma_pcis_cdev, &pcieportal_dma_pcis_fops); printk("%s:%d: calling cdev_add this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); printk("%s:%d: calling cdev_add this_board=%lx\n", DEV_NAME, __LINE__, (long)this_board); if (cdev_add(&this_board->dma_pcis_cdev, this_device_number, 1)) { printk(KERN_ERR "%s: cdev_add board failed\n", DEV_NAME); } printk("%s:%d: calling device_create this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); device_create(pcieportal_class, &dev->dev, this_device_number, NULL, "portal_dma_pcis"); } printk("%s:%d num_portals %d\n", DEV_NAME, __LINE__, this_board->info.num_portals); printk("%s:%d returning %d\n", DEV_NAME, __LINE__, err); if (err == 0) return err; /* if board activated correctly, return */ } /* end of if(activate) */ printk("%s:%d\n", DEV_NAME, __LINE__); /******** deactivate board *******/ if (board_number == 0) { device_destroy(pcieportal_class, MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT)); cdev_del(&this_board->cdev); device_destroy(pcieportal_class, MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT + 1)); cdev_del(&this_board->dma_pcis_cdev); } fpn = 0; printk("%s:%d\n", DEV_NAME, __LINE__); printk("%s:%d num_portals %d\n", DEV_NAME, __LINE__, this_board->info.num_portals); while(fpn < this_board->info.num_portals) { tPortal *this_portal = &this_board->portal[fpn]; /* remove device node in udev */ dev_t this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + this_portal->device_number); portalp[this_portal->device_name] = 0; device_destroy(pcieportal_class, this_device_number); printk(KERN_INFO "%s: /dev/%s_b%dt%dp%d = %x removed\n", DEV_NAME, DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name, this_device_number); /* remove device */ cdev_del(&this_board->portal[fpn].cdev); fpn++; } #if 0 pci_clear_master(dev); /* disable PCI bus master */ #endif printk("%s:%d\n", DEV_NAME, __LINE__); /* set MSIX Entry 0 Vector Control value to 1 (masked) */ iowrite32(1, this_board->bar0io + CSR_MSIX_MASKED); #if 0 disable_irq(this_board->irq_num); for (i = 0; i < num_entries; i++) free_irq(this_board->irq_num + i, (void *) &this_board->tile[i]); #endif for (i = 8; i < 16; i++) { int irq_num = pci_irq_vector(this_board->pci_dev, i); free_irq(irq_num, (void *)&this_board->tile[0]); } if (pcieportal_class) class_destroy(pcieportal_class); err_exit: this_board->pci_dev = NULL; #if 0 pci_set_drvdata(dev, NULL); #endif printk("%s:%d\n", DEV_NAME, __LINE__); return err; } /* driver PCI operations */ #if 0 static int pcieportal_probe(struct pci_dev *dev, const struct pci_device_id *id) { tBoard *this_board = NULL; int board_number = 0; int activated; printk("******[%s:%d] probe %p dev %p id %p getdrv %p\n", __FUNCTION__, __LINE__, &pcieportal_probe, dev, id, pci_get_drvdata(dev)); printk(KERN_INFO "%s: PCI probe for 0x%04x 0x%04x\n", DEV_NAME, dev->vendor, dev->device); /* double-check vendor and device */ if ((dev->vendor != BLUESPEC_VENDOR_ID || dev->device != CONNECTAL_DEVICE_ID) && (dev->vendor != AMAZON_VENDOR_ID || dev->device != AMAZON_DEVICE_ID)) { printk(KERN_ERR "%s: probe with invalid vendor or device ID\n", DEV_NAME); return -EINVAL; } /* assign a board number */ while (board_map[board_number].pci_dev && board_number < NUM_BOARDS) board_number++; if (board_number >= NUM_BOARDS) { printk(KERN_ERR "%s: %d boards are already in use!\n", DEV_NAME, NUM_BOARDS); return -EBUSY; } this_board = &board_map[board_number]; printk(KERN_INFO "%s: board_number = %d\n", DEV_NAME, board_number); memset(this_board, 0, sizeof(tBoard)); this_board->info.board_number = board_number; activated = pcieportal_board_activate(1, this_board, 0, dev); if (activated) { pci_set_drvdata(dev, this_board); } return activated; } static void pcieportal_remove(struct pci_dev *dev) { tBoard *this_board = pci_get_drvdata(dev); printk("*****[%s:%d] getdrv %p\n", __FUNCTION__, __LINE__, this_board); if (!this_board) { printk(KERN_ERR "%s: Unable to locate board when removing PCI device %p\n", DEV_NAME, dev); return; } pcieportal_board_activate(0, this_board, dev); } /* PCI ID pattern table */ static #ifdef DEFINE_PCI_DEVICE_TABLE // changed in Linux 4.8 DEFINE_PCI_DEVICE_TABLE(pcieportal_id_table) #else const struct pci_device_id pcieportal_id_table[] #endif = { { PCI_DEVICE(BLUESPEC_VENDOR_ID, CONNECTAL_DEVICE_ID)}, { PCI_DEVICE(AMAZON_VENDOR_ID, AMAZON_DEVICE_ID)}, { /* end: all zeros */ } }; MODULE_DEVICE_TABLE(pci, pcieportal_id_table); static pci_ers_result_t pcieportal_error_detected(struct pci_dev *pdev, enum pci_channel_state error) { printk(KERN_ERR "%s:%s: pcie error %d\n", DEV_NAME, __FUNCTION__, error); return PCI_ERS_RESULT_CAN_RECOVER; } static pci_ers_result_t pcieportal_error_mmio_enabled(struct pci_dev *pdev) { printk(KERN_ERR "%s:%s\n", DEV_NAME, __FUNCTION__); return PCI_ERS_RESULT_CAN_RECOVER; } static pci_ers_result_t pcieportal_error_slot_reset(struct pci_dev *pdev) { printk(KERN_ERR "%s:%s\n", DEV_NAME, __FUNCTION__); return PCI_ERS_RESULT_CAN_RECOVER; } static void pcieportal_error_resume(struct pci_dev *pdev) { printk(KERN_ERR "%s:%s\n", DEV_NAME, __FUNCTION__); } static const struct pci_error_handlers pcieportal_err_handler = { .error_detected = pcieportal_error_detected, .mmio_enabled = pcieportal_error_mmio_enabled, .slot_reset = pcieportal_error_slot_reset, .resume = pcieportal_error_resume, }; #endif /* * driver initialization and exit * * these routines are responsible for allocating and * freeing kernel resources, creating device nodes, * registering the driver, obtaining a major and minor * numbers, etc. */ #if 0 /* PCI driver operations pointers */ static struct pci_driver pcieportal_ops = { .name = DEV_NAME, .id_table = pcieportal_id_table, .probe = pcieportal_probe, .remove = pcieportal_remove, .err_handler = &pcieportal_err_handler, }; /* first routine called on module load */ static int pcieportal_init(void) { int status; printk("[%s:%d]\n", __FUNCTION__, __LINE__); pcieportal_class = class_create(THIS_MODULE, "Connectal"); if (IS_ERR(pcieportal_class)) { printk(KERN_ERR "%s: failed to create class Connectal\n", DEV_NAME); return PTR_ERR(pcieportal_class); } /* dynamically allocate a device number */ if (alloc_chrdev_region(&device_number, 1, MAX_MINOR_COUNT + 1, DEV_NAME) < 0) { printk(KERN_ERR "%s: failed to allocate character device region\n", DEV_NAME); class_destroy(pcieportal_class); return -1; } /* initialize driver data */ memset(board_map, 0, sizeof(board_map)); /* log the fact that we loaded the driver module */ printk(KERN_INFO "%s: Registered Connectal Pcieportal driver %s\n", DEV_NAME, DRIVER_VERSION); printk(KERN_INFO "%s: Major = %d Minors = %d to %d\n", DEV_NAME, MAJOR(device_number), MINOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT - 1); /* register the driver with the PCI subsystem */ status = pci_register_driver(&pcieportal_ops); if (status < 0) { printk(KERN_ERR "%s: failed to register PCI driver\n", DEV_NAME); class_destroy(pcieportal_class); return status; } printk("[%s:%d]\n", __FUNCTION__, __LINE__); return 0; /* success */ } /* routine called on module unload */ static void pcieportal_exit(void) { /* unregister the driver with the PCI subsystem */ pci_unregister_driver(&pcieportal_ops); /* release reserved device numbers */ unregister_chrdev_region(device_number, MAX_MINOR_COUNT + 1); class_destroy(pcieportal_class); /* log that the driver module has been unloaded */ printk(KERN_INFO "%s: Unregistered Connectal Pcieportal driver %s\n", DEV_NAME, DRIVER_VERSION); } /* * driver module data for the kernel */ module_init(pcieportal_init); module_exit(pcieportal_exit); #endif MODULE_AUTHOR("Bluespec, Inc., Cambridge hackers"); MODULE_DESCRIPTION("PCIe device driver for PCIe FPGA portals"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(DRIVER_VERSION); ================================================ FILE: drivers/awsf1portal/portal_internal.h ================================================ /* Copyright (c) 2020 Accelerated Tech, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef __PORTAL_INTERNAL_H__ #define __PORTAL_INTERNAL_H__ #include #include #include "pcieportal.h" #ifdef __KERNEL__ /* * Per-device data */ typedef struct { struct cdev cdev; /* per-portal cdev structure */ unsigned int device_number; unsigned int device_tile; unsigned int portal_number; unsigned int device_name; struct tBoard *board; void *virt; volatile uint32_t *regs; // Pointer to access portal from kernel unsigned long offset; // Offset from base of BAR2 struct extra_info *extra; struct list_head pmlist; wait_queue_head_t wait_queue; /* used for interrupt notifications */ dma_addr_t dma_handle; } tPortal; typedef struct { unsigned int device_tile; struct tBoard *board; } tTile; struct pmentry { struct file *fmem; int id; struct list_head pmlist; }; typedef struct tBoard { struct cdev cdev; struct cdev dma_pcis_cdev; void __iomem *bar0io, *bar1io, *bar2io, *bar4io; /* bars */ struct pci_dev *pci_dev; /* pci device pointer */ tPortal portal[MAX_NUM_PORTALS]; unsigned int irq_num; unsigned int open_count; tTile tile[MAX_NUM_PORTALS]; struct extra_info *extra; struct extra_info *pcis; // DMA PCIS on AWSF1 struct { unsigned int board_number; unsigned int portal_number; unsigned int num_portals; unsigned int aws_shell; } info; /* board identification fields */ } tBoard; extern tBoard* get_pcie_portal_descriptor(void); #endif struct xdma_pci_dev; int pcieportal_board_activate(int activate, tBoard *this_board, struct xdma_pci_dev *xpdev, struct pci_dev *dev); #endif /* __BLUENOC_H__ */ ================================================ FILE: drivers/awsf1portal/version.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef __XDMA_VERSION_H__ #define __XDMA_VERSION_H__ #define DRV_MOD_MAJOR 2017 #define DRV_MOD_MINOR 1 #define DRV_MOD_PATCHLEVEL 47 #define DRV_MODULE_VERSION \ __stringify(DRV_MOD_MAJOR) "." \ __stringify(DRV_MOD_MINOR) "." \ __stringify(DRV_MOD_PATCHLEVEL) #define DRV_MOD_VERSION_NUMBER \ ((DRV_MOD_MAJOR)*1000 + (DRV_MOD_MINOR)*100 + DRV_MOD_PATCHLEVEL) #endif /* ifndef __XDMA_VERSION_H__ */ ================================================ FILE: drivers/awsf1portal/xdma_cdev.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include "xdma_cdev.h" struct class *g_xdma_class; enum cdev_type { CHAR_USER, CHAR_CTRL, CHAR_XVC, CHAR_EVENTS, CHAR_XDMA_H2C, CHAR_XDMA_C2H, CHAR_BYPASS_H2C, CHAR_BYPASS_C2H, CHAR_BYPASS, }; static const char * const devnode_names[] = { XDMA_NODE_NAME "%d_user", XDMA_NODE_NAME "%d_control", XDMA_NODE_NAME "%d_xvc", XDMA_NODE_NAME "%d_events_%d", XDMA_NODE_NAME "%d_h2c_%d", XDMA_NODE_NAME "%d_c2h_%d", XDMA_NODE_NAME "%d_bypass_h2c_%d", XDMA_NODE_NAME "%d_bypass_c2h_%d", XDMA_NODE_NAME "%d_bypass", }; enum xpdev_flags_bits { XDF_CDEV_USER, XDF_CDEV_CTRL, XDF_CDEV_XVC, XDF_CDEV_EVENT, XDF_CDEV_SG, XDF_CDEV_BYPASS, }; static inline void xpdev_flag_set(struct xdma_pci_dev *xpdev, enum xpdev_flags_bits fbit) { xpdev->flags |= 1 << fbit; } static inline void xcdev_flag_clear(struct xdma_pci_dev *xpdev, enum xpdev_flags_bits fbit) { xpdev->flags &= ~(1 << fbit); } static inline int xpdev_flag_test(struct xdma_pci_dev *xpdev, enum xpdev_flags_bits fbit) { return xpdev->flags & (1 << fbit); } #ifdef __XDMA_SYSFS__ ssize_t show_device_numbers(struct device *dev, struct device_attribute *attr, char *buf) { struct xdma_pci_dev *xpdev = (struct xdma_pci_dev *)dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%d\t%d\n", xpdev->major, xpdev->xdev->idx); } static DEVICE_ATTR(xdma_dev_instance, S_IRUGO, show_device_numbers, NULL); #endif static int config_kobject(struct xdma_cdev *xcdev, enum cdev_type type) { int rv = -EINVAL; struct xdma_dev *xdev = xcdev->xdev; struct xdma_engine *engine = xcdev->engine; switch (type) { case CHAR_XDMA_H2C: case CHAR_XDMA_C2H: case CHAR_BYPASS_H2C: case CHAR_BYPASS_C2H: BUG_ON(!engine); rv = kobject_set_name(&xcdev->cdev.kobj, devnode_names[type], xdev->idx, engine->channel); break; case CHAR_BYPASS: case CHAR_USER: case CHAR_CTRL: case CHAR_XVC: rv = kobject_set_name(&xcdev->cdev.kobj, devnode_names[type], xdev->idx); break; case CHAR_EVENTS: rv = kobject_set_name(&xcdev->cdev.kobj, devnode_names[type], xdev->idx, xcdev->bar); break; default: pr_warn("%s: UNKNOWN type 0x%x.\n", __func__, type); break; } if (rv) pr_err("%s: type 0x%x, failed %d.\n", __func__, type, rv); return rv; } int xcdev_check(const char *fname, struct xdma_cdev *xcdev, bool check_engine) { struct xdma_dev *xdev; if (!xcdev || xcdev->magic != MAGIC_CHAR) { pr_info("%s, xcdev 0x%p, magic 0x%lx.\n", fname, xcdev, xcdev ? xcdev->magic : 0xFFFFFFFF); return -EINVAL; } xdev = xcdev->xdev; if (!xdev || xdev->magic != MAGIC_DEVICE) { pr_info("%s, xdev 0x%p, magic 0x%lx.\n", fname, xdev, xdev ? xdev->magic : 0xFFFFFFFF); return -EINVAL; } if (check_engine) { struct xdma_engine *engine = xcdev->engine; if (!engine || engine->magic != MAGIC_ENGINE) { pr_info("%s, engine 0x%p, magic 0x%lx.\n", fname, engine, engine ? engine->magic : 0xFFFFFFFF); return -EINVAL; } } return 0; } int char_open(struct inode *inode, struct file *file) { struct xdma_cdev *xcdev; /* pointer to containing structure of the character device inode */ xcdev = container_of(inode->i_cdev, struct xdma_cdev, cdev); BUG_ON(xcdev->magic != MAGIC_CHAR); /* create a reference to our char device in the opened file */ file->private_data = xcdev; return 0; } /* * Called when the device goes from used to unused. */ int char_close(struct inode *inode, struct file *file) { struct xdma_dev *xdev; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; BUG_ON(!xcdev); BUG_ON(xcdev->magic != MAGIC_CHAR); /* fetch device specific data stored earlier during open */ xdev = xcdev->xdev; BUG_ON(!xdev); BUG_ON(xdev->magic != MAGIC_DEVICE); return 0; } /* create_xcdev() -- create a character device interface to data or control bus * * If at least one SG DMA engine is specified, the character device interface * is coupled to the SG DMA file operations which operate on the data bus. If * no engines are specified, the interface is coupled with the control bus. */ static int create_sys_device(struct xdma_cdev *xcdev, enum cdev_type type) { struct xdma_dev *xdev = xcdev->xdev; struct xdma_engine *engine = xcdev->engine; int last_param; if (type == CHAR_EVENTS) last_param = xcdev->bar; else last_param = engine ? engine->channel : 0; xcdev->sys_device = device_create(g_xdma_class, &xdev->pdev->dev, xcdev->cdevno, NULL, devnode_names[type], xdev->idx, last_param); if (!xcdev->sys_device) { pr_err("device_create(%s) failed\n", devnode_names[type]); return -1; } return 0; } static int destroy_xcdev(struct xdma_cdev *cdev) { if (!cdev) { pr_warn("cdev NULL.\n"); return 0; } if (cdev->magic != MAGIC_CHAR) { pr_warn("cdev 0x%p magic mismatch 0x%lx\n", cdev, cdev->magic); return 0; } BUG_ON(!cdev->xdev); BUG_ON(!g_xdma_class); BUG_ON(!cdev->sys_device); if (cdev->sys_device) device_destroy(g_xdma_class, cdev->cdevno); cdev_del(&cdev->cdev); return 0; } static int create_xcdev(struct xdma_pci_dev *xpdev, struct xdma_cdev *xcdev, int bar, struct xdma_engine *engine, enum cdev_type type) { int rv; int minor; struct xdma_dev *xdev = xpdev->xdev; dev_t dev; spin_lock_init(&xcdev->lock); /* new instance? */ if (!xpdev->major) { /* allocate a dynamically allocated char device node */ int rv = alloc_chrdev_region(&dev, XDMA_MINOR_BASE, XDMA_MINOR_COUNT, XDMA_NODE_NAME); if (rv) { pr_err("unable to allocate cdev region %d.\n", rv); return rv; } xpdev->major = MAJOR(dev); } /* * do not register yet, create kobjects and name them, */ xcdev->magic = MAGIC_CHAR; xcdev->cdev.owner = THIS_MODULE; xcdev->xpdev = xpdev; xcdev->xdev = xdev; xcdev->engine = engine; xcdev->bar = bar; rv = config_kobject(xcdev, type); if (rv < 0) return rv; switch (type) { case CHAR_USER: case CHAR_CTRL: /* minor number is type index for non-SGDMA interfaces */ minor = type; cdev_ctrl_init(xcdev); break; case CHAR_XVC: /* minor number is type index for non-SGDMA interfaces */ minor = type; cdev_xvc_init(xcdev); break; case CHAR_XDMA_H2C: minor = 32 + engine->channel; cdev_sgdma_init(xcdev); break; case CHAR_XDMA_C2H: minor = 36 + engine->channel; cdev_sgdma_init(xcdev); break; case CHAR_EVENTS: minor = 10 + bar; cdev_event_init(xcdev); break; case CHAR_BYPASS_H2C: minor = 64 + engine->channel; cdev_bypass_init(xcdev); break; case CHAR_BYPASS_C2H: minor = 68 + engine->channel; cdev_bypass_init(xcdev); break; case CHAR_BYPASS: minor = 100; cdev_bypass_init(xcdev); break; default: pr_info("type 0x%x NOT supported.\n", type); return -EINVAL; } xcdev->cdevno = MKDEV(xpdev->major, minor); /* bring character device live */ rv = cdev_add(&xcdev->cdev, xcdev->cdevno, 1); if (rv < 0) { pr_err("cdev_add failed %d, type 0x%x.\n", rv, type); goto unregister_region; } dbg_init("xcdev 0x%p, %u:%u, %s, type 0x%x.\n", xcdev, xpdev->major, minor, xcdev->cdev.kobj.name, type); /* create device on our class */ if (g_xdma_class) { rv = create_sys_device(xcdev, type); if (rv < 0) goto del_cdev; } return 0; del_cdev: cdev_del(&xcdev->cdev); unregister_region: unregister_chrdev_region(dev, XDMA_MINOR_COUNT); return rv; } void xpdev_destroy_interfaces(struct xdma_pci_dev *xpdev) { int i; #ifdef __XDMA_SYSFS__ device_remove_file(&xpdev->pdev->dev, &dev_attr_xdma_dev_instance); #endif if (xpdev_flag_test(xpdev, XDF_CDEV_SG)) { /* iterate over channels */ for (i = 0; i < xpdev->h2c_channel_max; i++) /* remove SG DMA character device */ destroy_xcdev(&xpdev->sgdma_h2c_cdev[i]); for (i = 0; i < xpdev->c2h_channel_max; i++) destroy_xcdev(&xpdev->sgdma_c2h_cdev[i]); } if (xpdev_flag_test(xpdev, XDF_CDEV_EVENT)) { for (i = 0; i < xpdev->user_max; i++) destroy_xcdev(&xpdev->events_cdev[i]); } /* remove control character device */ if (xpdev_flag_test(xpdev, XDF_CDEV_CTRL)) { destroy_xcdev(&xpdev->ctrl_cdev); } /* remove user character device */ if (xpdev_flag_test(xpdev, XDF_CDEV_USER)) { destroy_xcdev(&xpdev->user_cdev); } if (xpdev_flag_test(xpdev, XDF_CDEV_XVC)) { destroy_xcdev(&xpdev->xvc_cdev); } if (xpdev_flag_test(xpdev, XDF_CDEV_BYPASS)) { /* iterate over channels */ for (i = 0; i < xpdev->h2c_channel_max; i++) /* remove DMA Bypass character device */ destroy_xcdev(&xpdev->bypass_h2c_cdev[i]); for (i = 0; i < xpdev->c2h_channel_max; i++) destroy_xcdev(&xpdev->bypass_c2h_cdev[i]); destroy_xcdev(&xpdev->bypass_cdev_base); } if (xpdev->major) unregister_chrdev_region(MKDEV(xpdev->major, XDMA_MINOR_BASE), XDMA_MINOR_COUNT); } int xpdev_create_interfaces(struct xdma_pci_dev *xpdev) { struct xdma_dev *xdev = xpdev->xdev; struct xdma_engine *engine; int i; int rv = 0; /* initialize control character device */ rv = create_xcdev(xpdev, &xpdev->ctrl_cdev, xdev->config_bar_idx, NULL, CHAR_CTRL); if (rv < 0) { pr_err("create_char(ctrl_cdev) failed\n"); goto fail; } xpdev_flag_set(xpdev, XDF_CDEV_CTRL); /* initialize events character device */ for (i = 0; i < xpdev->user_max; i++) { rv = create_xcdev(xpdev, &xpdev->events_cdev[i], i, NULL, CHAR_EVENTS); if (rv < 0) { pr_err("create char event %d failed, %d.\n", i, rv); goto fail; } } xpdev_flag_set(xpdev, XDF_CDEV_EVENT); /* iterate over channels */ for (i = 0; i < xpdev->h2c_channel_max; i++) { engine = &xdev->engine_h2c[i]; if (engine->magic != MAGIC_ENGINE) continue; rv = create_xcdev(xpdev, &xpdev->sgdma_h2c_cdev[i], i, engine, CHAR_XDMA_H2C); if (rv < 0) { pr_err("create char h2c %d failed, %d.\n", i, rv); goto fail; } } for (i = 0; i < xpdev->c2h_channel_max; i++) { engine = &xdev->engine_c2h[i]; if (engine->magic != MAGIC_ENGINE) continue; rv = create_xcdev(xpdev, &xpdev->sgdma_c2h_cdev[i], i, engine, CHAR_XDMA_C2H); if (rv < 0) { pr_err("create char c2h %d failed, %d.\n", i, rv); goto fail; } } xpdev_flag_set(xpdev, XDF_CDEV_SG); /* ??? Bypass */ /* Initialize Bypass Character Device */ if (xdev->bypass_bar_idx > 0){ for (i = 0; i < xpdev->h2c_channel_max; i++) { engine = &xdev->engine_h2c[i]; if (engine->magic != MAGIC_ENGINE) continue; rv = create_xcdev(xpdev, &xpdev->bypass_h2c_cdev[i], i, engine, CHAR_BYPASS_H2C); if (rv < 0) { pr_err("create h2c %d bypass I/F failed, %d.\n", i, rv); goto fail; } } for (i = 0; i < xpdev->c2h_channel_max; i++) { engine = &xdev->engine_c2h[i]; if (engine->magic != MAGIC_ENGINE) continue; rv = create_xcdev(xpdev, &xpdev->bypass_c2h_cdev[i], i, engine, CHAR_BYPASS_C2H); if (rv < 0) { pr_err("create c2h %d bypass I/F failed, %d.\n", i, rv); goto fail; } } rv = create_xcdev(xpdev, &xpdev->bypass_cdev_base, xdev->bypass_bar_idx, NULL, CHAR_BYPASS); if (rv < 0) { pr_err("create bypass failed %d.\n", rv); goto fail; } xpdev_flag_set(xpdev, XDF_CDEV_BYPASS); } /* initialize user character device */ if (xdev->user_bar_idx >= 0) { rv = create_xcdev(xpdev, &xpdev->user_cdev, xdev->user_bar_idx, NULL, CHAR_USER); if (rv < 0) { pr_err("create_char(user_cdev) failed\n"); goto fail; } xpdev_flag_set(xpdev, XDF_CDEV_USER); /* xvc */ rv = create_xcdev(xpdev, &xpdev->xvc_cdev, xdev->user_bar_idx, NULL, CHAR_XVC); if (rv < 0) { pr_err("create xvc failed, %d.\n", rv); goto fail; } xpdev_flag_set(xpdev, XDF_CDEV_XVC); } #ifdef __XDMA_SYSFS__ /* sys file */ rv = device_create_file(&xpdev->pdev->dev, &dev_attr_xdma_dev_instance); if (rv) { pr_err("Failed to create device file \n"); goto fail; } #endif return 0; fail: rv = -1; xpdev_destroy_interfaces(xpdev); return rv; } int xdma_cdev_init(void) { g_xdma_class = class_create(THIS_MODULE, XDMA_NODE_NAME); if (IS_ERR(g_xdma_class)) { dbg_init(XDMA_NODE_NAME ": failed to create class"); return -1; } return 0; } void xdma_cdev_cleanup(void) { if (g_xdma_class) class_destroy(g_xdma_class); } ================================================ FILE: drivers/awsf1portal/xdma_cdev.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef __XDMA_CHRDEV_H__ #define __XDMA_CHRDEV_H__ #include #include #include #include #include "xdma_mod.h" #define XDMA_NODE_NAME "xdma" #define XDMA_MINOR_BASE (0) #define XDMA_MINOR_COUNT (255) void xdma_cdev_cleanup(void); int xdma_cdev_init(void); int char_open(struct inode *inode, struct file *file); int char_close(struct inode *inode, struct file *file); int xcdev_check(const char *, struct xdma_cdev *, bool); void cdev_ctrl_init(struct xdma_cdev *xcdev); void cdev_xvc_init(struct xdma_cdev *xcdev); void cdev_event_init(struct xdma_cdev *xcdev); void cdev_sgdma_init(struct xdma_cdev *xcdev); void cdev_bypass_init(struct xdma_cdev *xcdev); void xpdev_destroy_interfaces(struct xdma_pci_dev *xpdev); int xpdev_create_interfaces(struct xdma_pci_dev *xpdev); int bridge_mmap(struct file *file, struct vm_area_struct *vma); #endif /* __XDMA_CHRDEV_H__ */ ================================================ FILE: drivers/awsf1portal/xdma_ioctl.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * * Copyright(c) Sidebranch. * Copyright(c) Xilinx, Inc. * * Karen Xie * Leon Woestenberg * ******************************************************************************/ #ifndef _XDMA_IOCALLS_POSIX_H_ #define _XDMA_IOCALLS_POSIX_H_ #include /* Use 'x' as magic number */ #define XDMA_IOC_MAGIC 'x' /* XL OpenCL X->58(ASCII), L->6C(ASCII), O->0 C->C L->6C(ASCII); */ #define XDMA_XCL_MAGIC 0X586C0C6C #define IOCTL_XDMA_PERF_V1 (1) #define XDMA_ADDRMODE_MEMORY (0) #define XDMA_ADDRMODE_FIXED (1) /* * S means "Set" through a ptr, * T means "Tell" directly with the argument value * G means "Get": reply by setting through a pointer * Q means "Query": response is on the return value * X means "eXchange": switch G and S atomically * H means "sHift": switch T and Q atomically * * _IO(type,nr) no arguments * _IOR(type,nr,datatype) read data from driver * _IOW(type,nr.datatype) write data to driver * _IORW(type,nr,datatype) read/write data * * _IOC_DIR(nr) returns direction * _IOC_TYPE(nr) returns magic * _IOC_NR(nr) returns number * _IOC_SIZE(nr) returns size */ enum XDMA_IOC_TYPES { XDMA_IOC_NOP, XDMA_IOC_INFO, XDMA_IOC_MAX }; struct xdma_ioc_base { unsigned int magic; unsigned int command; }; struct xdma_ioc_info { struct xdma_ioc_base base; unsigned short vendor; unsigned short device; unsigned short subsystem_vendor; unsigned short subsystem_device; unsigned dma_engine_version; unsigned driver_version; unsigned long long feature_id; unsigned short domain; unsigned char bus; unsigned char dev; unsigned char func; }; /* IOCTL codes */ #define XDMA_IOCINFO _IOWR(XDMA_IOC_MAGIC, XDMA_IOC_INFO, struct xdma_ioc_info) #define IOCTL_XDMA_ADDRMODE_SET _IOW('q', 4, int) #define IOCTL_XDMA_ADDRMODE_GET _IOR('q', 5, int) #define IOCTL_XDMA_ALIGN_GET _IOR('q', 6, int) #endif /* _XDMA_IOCALLS_POSIX_H_ */ ================================================ FILE: drivers/awsf1portal/xdma_mod.c ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include #include #include #include /* include early, to verify it depends only on the headers above */ #include "libxdma_api.h" #include "libxdma.h" #include "xdma_mod.h" #include "xdma_cdev.h" #include "version.h" #define DRV_MODULE_NAME "xdma" #define DRV_MODULE_DESC "Xilinx XDMA Classic Driver" #define DRV_MODULE_RELDATE "Feb. 2017" static char version[] = DRV_MODULE_DESC " " DRV_MODULE_NAME " v" DRV_MODULE_VERSION "\n"; MODULE_AUTHOR("Xilinx, Inc."); MODULE_DESCRIPTION(DRV_MODULE_DESC); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_LICENSE("GPL v2"); /* SECTION: Module global variables */ static int xpdev_cnt = 0; static const struct pci_device_id pci_ids[] = { { PCI_DEVICE(0x10ee, 0x903f), }, { PCI_DEVICE(0x10ee, 0x9038), }, { PCI_DEVICE(0x10ee, 0x9028), }, { PCI_DEVICE(0x10ee, 0x9018), }, { PCI_DEVICE(0x10ee, 0x9034), }, { PCI_DEVICE(0x10ee, 0x9024), }, { PCI_DEVICE(0x10ee, 0x9014), }, { PCI_DEVICE(0x10ee, 0x9032), }, { PCI_DEVICE(0x10ee, 0x9022), }, { PCI_DEVICE(0x10ee, 0x9012), }, { PCI_DEVICE(0x10ee, 0x9031), }, { PCI_DEVICE(0x10ee, 0x9021), }, { PCI_DEVICE(0x10ee, 0x9011), }, { PCI_DEVICE(0x10ee, 0x8011), }, { PCI_DEVICE(0x10ee, 0x8012), }, { PCI_DEVICE(0x10ee, 0x8014), }, { PCI_DEVICE(0x10ee, 0x8018), }, { PCI_DEVICE(0x10ee, 0x8021), }, { PCI_DEVICE(0x10ee, 0x8022), }, { PCI_DEVICE(0x10ee, 0x8024), }, { PCI_DEVICE(0x10ee, 0x8028), }, { PCI_DEVICE(0x10ee, 0x8031), }, { PCI_DEVICE(0x10ee, 0x8032), }, { PCI_DEVICE(0x10ee, 0x8034), }, { PCI_DEVICE(0x10ee, 0x8038), }, { PCI_DEVICE(0x10ee, 0x7011), }, { PCI_DEVICE(0x10ee, 0x7012), }, { PCI_DEVICE(0x10ee, 0x7014), }, { PCI_DEVICE(0x10ee, 0x7018), }, { PCI_DEVICE(0x10ee, 0x7021), }, { PCI_DEVICE(0x10ee, 0x7022), }, { PCI_DEVICE(0x10ee, 0x7024), }, { PCI_DEVICE(0x10ee, 0x7028), }, { PCI_DEVICE(0x10ee, 0x7031), }, { PCI_DEVICE(0x10ee, 0x7032), }, { PCI_DEVICE(0x10ee, 0x7034), }, { PCI_DEVICE(0x10ee, 0x7038), }, { PCI_DEVICE(0x10ee, 0x6828), }, { PCI_DEVICE(0x10ee, 0x6830), }, { PCI_DEVICE(0x10ee, 0x6928), }, { PCI_DEVICE(0x10ee, 0x6930), }, { PCI_DEVICE(0x10ee, 0x6A28), }, { PCI_DEVICE(0x10ee, 0x6A30), }, { PCI_DEVICE(0x10ee, 0x6D30), }, { PCI_DEVICE(0x10ee, 0x4808), }, { PCI_DEVICE(0x10ee, 0x4828), }, { PCI_DEVICE(0x10ee, 0x4908), }, { PCI_DEVICE(0x10ee, 0x4A28), }, { PCI_DEVICE(0x10ee, 0x4B28), }, { PCI_DEVICE(0x10ee, 0x2808), }, { PCI_DEVICE(0x10ee, 0x2808), }, { PCI_DEVICE(0x1d0f, 0xf000), }, { PCI_DEVICE(0x1d0f, 0xf001), }, { PCI_DEVICE(0x1d0f, 0x1042), }, // Connectal via PCIE { PCI_DEVICE(0x1be7, 0xc100), }, {0,} }; MODULE_DEVICE_TABLE(pci, pci_ids); static void xpdev_free(struct xdma_pci_dev *xpdev) { struct xdma_dev *xdev = xpdev->xdev; pr_info("xpdev 0x%p, destroy_interfaces, xdev 0x%p.\n", xpdev, xdev); xpdev_destroy_interfaces(xpdev); xpdev->xdev = NULL; pr_info("xpdev 0x%p, xdev 0x%p xdma_device_close.\n", xpdev, xdev); xdma_device_close(xpdev->pdev, xdev); xpdev_cnt--; kfree(xpdev); } static struct xdma_pci_dev *xpdev_alloc(struct pci_dev *pdev) { struct xdma_pci_dev *xpdev = kmalloc(sizeof(*xpdev), GFP_KERNEL); if (!xpdev) return NULL; memset(xpdev, 0, sizeof(*xpdev)); xpdev->magic = MAGIC_DEVICE; xpdev->pdev = pdev; xpdev->user_max = MAX_USER_IRQ; xpdev->h2c_channel_max = XDMA_CHANNEL_NUM_MAX; xpdev->c2h_channel_max = XDMA_CHANNEL_NUM_MAX; xpdev_cnt++; return xpdev; } static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { int rv = 0; struct xdma_pci_dev *xpdev = NULL; struct xdma_dev *xdev; void *hndl; xpdev = xpdev_alloc(pdev); if (!xpdev) return -ENOMEM; hndl = xdma_device_open(DRV_MODULE_NAME, pdev, &xpdev->user_max, &xpdev->h2c_channel_max, &xpdev->c2h_channel_max); if (!hndl) return -EINVAL; BUG_ON(xpdev->user_max > MAX_USER_IRQ); BUG_ON(xpdev->h2c_channel_max > XDMA_CHANNEL_NUM_MAX); BUG_ON(xpdev->c2h_channel_max > XDMA_CHANNEL_NUM_MAX); if (!xpdev->h2c_channel_max && !xpdev->c2h_channel_max) pr_warn("NO engine found!\n"); if (xpdev->user_max) { u32 mask = (1 << (xpdev->user_max + 1)) - 1; rv = xdma_user_isr_enable(hndl, mask); if (rv) goto err_out; } /* make sure no duplicate */ xdev = xdev_find_by_pdev(pdev); if (!xdev) { pr_warn("NO xdev found!\n"); return -EINVAL; } BUG_ON(hndl != xdev ); pr_info("%s xdma%d, pdev 0x%p, xdev 0x%p, 0x%p, usr %d, ch %d,%d.\n", dev_name(&pdev->dev), xdev->idx, pdev, xpdev, xdev, xpdev->user_max, xpdev->h2c_channel_max, xpdev->c2h_channel_max); xpdev->xdev = hndl; rv = xpdev_create_interfaces(xpdev); if (rv) goto err_out; rv = pcieportal_board_activate(1, &xpdev->portal_board, xpdev, pdev); if (rv) goto err_out; dev_set_drvdata(&pdev->dev, xpdev); return 0; err_out: pr_err("pdev 0x%p, err %d.\n", pdev, rv); xpdev_free(xpdev); return rv; } static void remove_one(struct pci_dev *pdev) { struct xdma_pci_dev *xpdev; if (!pdev) return; xpdev = dev_get_drvdata(&pdev->dev); if (!xpdev) return; pcieportal_board_activate(0, &xpdev->portal_board, xpdev, pdev); pr_info("pdev 0x%p, xdev 0x%p, 0x%p.\n", pdev, xpdev, xpdev->xdev); xpdev_free(xpdev); dev_set_drvdata(&pdev->dev, NULL); } static pci_ers_result_t xdma_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); switch (state) { case pci_channel_io_normal: return PCI_ERS_RESULT_CAN_RECOVER; case pci_channel_io_frozen: pr_warn("dev 0x%p,0x%p, frozen state error, reset controller\n", pdev, xpdev); xdma_device_offline(pdev, xpdev->xdev); pci_disable_device(pdev); return PCI_ERS_RESULT_NEED_RESET; case pci_channel_io_perm_failure: pr_warn("dev 0x%p,0x%p, failure state error, req. disconnect\n", pdev, xpdev); return PCI_ERS_RESULT_DISCONNECT; } return PCI_ERS_RESULT_NEED_RESET; } static pci_ers_result_t xdma_slot_reset(struct pci_dev *pdev) { struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); pr_info("0x%p restart after slot reset\n", xpdev); if (pci_enable_device_mem(pdev)) { pr_info("0x%p failed to renable after slot reset\n", xpdev); return PCI_ERS_RESULT_DISCONNECT; } pci_set_master(pdev); pci_restore_state(pdev); pci_save_state(pdev); xdma_device_online(pdev, xpdev->xdev); return PCI_ERS_RESULT_RECOVERED; } static void xdma_error_resume(struct pci_dev *pdev) { struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); pr_info("dev 0x%p,0x%p.\n", pdev, xpdev); #if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) && !(defined(RHEL_MAJOR) && RHEL_RELEASE_VERSION(8,3) >= RHEL_RELEASE_CODE) pci_cleanup_aer_uncorrect_error_status(pdev); #else pci_aer_clear_nonfatal_status(pdev); #endif } #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) static void xdma_reset_prepare(struct pci_dev *pdev) { struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); pr_info("dev 0x%p,0x%p.\n", pdev, xpdev); xdma_device_offline(pdev, xpdev->xdev); } static void xdma_reset_done(struct pci_dev *pdev) { struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); pr_info("dev 0x%p,0x%p.\n", pdev, xpdev); xdma_device_online(pdev, xpdev->xdev); } #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) static void xdma_reset_notify(struct pci_dev *pdev, bool prepare) { struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); pr_info("dev 0x%p,0x%p, prepare %d.\n", pdev, xpdev, prepare); if (prepare) xdma_device_offline(pdev, xpdev->xdev); else xdma_device_online(pdev, xpdev->xdev); } #endif static const struct pci_error_handlers xdma_err_handler = { .error_detected = xdma_error_detected, .slot_reset = xdma_slot_reset, .resume = xdma_error_resume, #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) .reset_prepare = xdma_reset_prepare, .reset_done = xdma_reset_done, #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) .reset_notify = xdma_reset_notify, #endif }; static struct pci_driver pci_driver = { .name = DRV_MODULE_NAME, .id_table = pci_ids, .probe = probe_one, .remove = remove_one, .err_handler = &xdma_err_handler, }; static int __init xdma_mod_init(void) { int rv; extern unsigned int desc_blen_max; extern unsigned int sgdma_timeout; pr_info("%s", version); if (desc_blen_max > XDMA_DESC_BLEN_MAX) desc_blen_max = XDMA_DESC_BLEN_MAX; pr_info("desc_blen_max: 0x%x/%u, sgdma_timeout: %u sec.\n", desc_blen_max, desc_blen_max, sgdma_timeout); rv = xdma_cdev_init(); if (rv < 0) return rv; return pci_register_driver(&pci_driver); } static void __exit xdma_mod_exit(void) { /* unregister this driver from the PCI bus driver */ dbg_init("pci_unregister_driver.\n"); pci_unregister_driver(&pci_driver); xdma_cdev_cleanup(); } module_init(xdma_mod_init); module_exit(xdma_mod_exit); ================================================ FILE: drivers/awsf1portal/xdma_mod.h ================================================ /******************************************************************************* * * Xilinx XDMA IP Core Linux Driver * Copyright(c) 2015 - 2017 Xilinx, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * The full GNU General Public License is included in this distribution in * the file called "LICENSE". * * Karen Xie * ******************************************************************************/ #ifndef __XDMA_MODULE_H__ #define __XDMA_MODULE_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libxdma.h" #include "portal_internal.h" #define MAGIC_ENGINE 0xEEEEEEEEUL #define MAGIC_DEVICE 0xDDDDDDDDUL #define MAGIC_CHAR 0xCCCCCCCCUL #define MAGIC_BITSTREAM 0xBBBBBBBBUL struct xdma_cdev { unsigned long magic; /* structure ID for sanity checks */ struct xdma_pci_dev *xpdev; struct xdma_dev *xdev; dev_t cdevno; /* character device major:minor */ struct cdev cdev; /* character device embedded struct */ int bar; /* PCIe BAR for HW access, if needed */ unsigned long base; /* bar access offset */ struct xdma_engine *engine; /* engine instance, if needed */ struct xdma_user_irq *user_irq; /* IRQ value, if needed */ struct device *sys_device; /* sysfs device */ spinlock_t lock; }; /* XDMA PCIe device specific book-keeping */ struct xdma_pci_dev { unsigned long magic; /* structure ID for sanity checks */ struct pci_dev *pdev; /* pci device struct from probe() */ struct xdma_dev *xdev; int major; /* major number */ int instance; /* instance number */ int user_max; int c2h_channel_max; int h2c_channel_max; unsigned int flags; /* character device structures */ struct xdma_cdev ctrl_cdev; struct xdma_cdev sgdma_c2h_cdev[XDMA_CHANNEL_NUM_MAX]; struct xdma_cdev sgdma_h2c_cdev[XDMA_CHANNEL_NUM_MAX]; struct xdma_cdev events_cdev[16]; struct xdma_cdev user_cdev; struct xdma_cdev bypass_c2h_cdev[XDMA_CHANNEL_NUM_MAX]; struct xdma_cdev bypass_h2c_cdev[XDMA_CHANNEL_NUM_MAX]; struct xdma_cdev bypass_cdev_base; struct xdma_cdev xvc_cdev; struct tBoard portal_board; void *data; }; struct xdma_io_cb { void __user *buf; size_t len; unsigned int pages_nr; struct sg_table sgt; struct page **pages; }; #endif /* ifndef __XDMA_MODULE_H__ */ ================================================ FILE: drivers/connectalsdhci/Makefile ================================================ V?=0 ifeq ($(V),0) Q=@ else Q= endif CONNECTALDIR ?= $(PWD)/../.. include $(CONNECTALDIR)/Makefile.version obj-m += connectalsdhci.o CROSS_COMPILE?=arm-linux-gnueabi- ccflags-y := -I$(src)/../portalmem -I$(src)/../../cpp -I$(PWD)/../.. -I$(src)/../../generated/cpp \ -DDRIVER_VERSION="KBUILD_STR($(VERSION))" connectalsdhci.ko: connectalsdhci.c @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) xilinx_zynq_portal_defconfig @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) oldconfig @$(MAKE) -j 8 ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) zImage @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) modules clean: @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) clean ================================================ FILE: drivers/connectalsdhci/connectalsdhci.c ================================================ /* * Based on sdhci-of-xilinx.c * * Copyright (c) 2015 Quanta Research Cambridge Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */ #include #include #include #include // defined in drivers/mmc/host/sdhci-of-xilinxps.c extern int sdhci_zynq_remove(struct platform_device *pdev); extern int sdhci_zynq_probe(struct platform_device *pdev); extern int xsdhcips_suspend(struct device *dev); extern int xsdhcips_resume(struct device *dev); #ifdef CONFIG_PM_SLEEP static const struct dev_pm_ops xsdhcips_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(xsdhcips_suspend, xsdhcips_resume) }; #define XSDHCIPS_PM (&xsdhcips_dev_pm_ops) #else /* ! CONFIG_PM_SLEEP */ #define XSDHCIPS_PM NULL #endif /* ! CONFIG_PM_SLEEP */ static const struct of_device_id sdhci_zynq_of_match[] = { { .compatible = "connectalsdhci" }, {}, }; MODULE_DEVICE_TABLE(of, sdhci_zynq_of_match); static struct platform_driver sdhci_zynq_driver = { .driver = { .name = "connectalsdhci-zynq", .owner = THIS_MODULE, .of_match_table = sdhci_zynq_of_match, .pm = XSDHCIPS_PM, }, .probe = local_zynq_probe, .remove = local_zynq_remove, }; module_platform_driver(sdhci_zynq_driver); MODULE_LICENSE("GPL v2"); ================================================ FILE: drivers/connectalspi/Makefile ================================================ V?=0 ifeq ($(V),0) Q=@ else Q= endif CONNECTALDIR ?= $(PWD)/../.. include $(CONNECTALDIR)/Makefile.version obj-m += connectalspi.o CROSS_COMPILE?=arm-linux-gnueabi- ccflags-y := -I$(src)/../portalmem -I$(src)/../../cpp -I$(PWD)/../.. -I$(src)/../../generated/cpp \ -DDRIVER_VERSION="KBUILD_STR($(VERSION))" connectalspi.ko: connectalspi.c @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) xilinx_zynq_portal_defconfig @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) oldconfig @$(MAKE) -j 8 ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) zImage @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) modules clean: @$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) clean ================================================ FILE: drivers/connectalspi/connectalspi.c ================================================ /* * Based on spi-xilinx-ps.c * * Copyright (c) 2015 Quanta Research Cambridge Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */ #include #include #include #include //#define POKE_REG_ONLY // defined in drivers/spi/spi-xilinx-ps.c extern int xspips_remove(struct platform_device *pdev); extern int xspips_probe(struct platform_device *pdev); extern int xspips_suspend(struct device *dev); extern int xspips_resume(struct device *dev); #define XPSS_SYS_CTRL_BASEADDR 0xF8000000 // SLCR #define XSLCR_MIO_PIN_00_OFFSET 0x700 /* MIO PIN0 control register */ #define XSLCR_MIO_L0_SHIFT 1 #define XSLCR_MIO_L1_SHIFT 2 #define XSLCR_MIO_L2_SHIFT 3 #define XSLCR_MIO_L3_SHIFT 5 #define XSLCR_MIO_LMASK 0xFE #define XSLCR_MIO_PIN_XX_TRI_ENABLE 1 #define XSLCR_MIO_PIN_GPIO_ENABLE (0x00 << XSLCR_MIO_L3_SHIFT) #define XSLCR_MIO_PIN_SDIO_ENABLE (0x04 << XSLCR_MIO_L3_SHIFT) #define XSLCR_MIO_PIN_SPI_ENABLE (0x05 << XSLCR_MIO_L3_SHIFT) #define PINOFF(PIN) (XPSS_SYS_CTRL_BASEADDR + XSLCR_MIO_PIN_00_OFFSET + (PIN) * 4) static const struct { uint32_t pinaddr; uint32_t enable; } spi0_pindef[] = { {PINOFF(16), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(17), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(18), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(19), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(20), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(21), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(28), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(29), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(30), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(31), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(32), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(33), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(40), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(41), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(42), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(43), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(44), XSLCR_MIO_PIN_SPI_ENABLE}, {PINOFF(45), XSLCR_MIO_PIN_SPI_ENABLE}, {0,0}}; uint32_t bit_sel(uint32_t lsb, uint32_t msb, uint32_t v) { return (v >> lsb) & ~(~0 << (msb-lsb+1)); } static int local_probe(struct platform_device *pdev) { uint32_t ind = 0; uint32_t pinaddr = 0; int rv = 0; #ifndef POKE_REG_ONLY rv = xspips_probe(pdev); #endif while ((pinaddr = spi0_pindef[ind].pinaddr)) { // u32 en = spi0_pindef[ind].enable; u32 v = readl(ioremap_nocache(pinaddr, sizeof(u32))); printk("[%s:%d] %08x %x\n", __FUNCTION__, __LINE__, pinaddr, (v>>5)&7); ind++; } { struct clk *devclk = clk_get_sys("SPI0", NULL); printk("[%s:%d] devclk %x\n", __FUNCTION__, __LINE__, devclk); printk("[%s:%d] rate %d\n", __FUNCTION__, __LINE__, clk_get_rate(devclk)); } { u32 v = readl(ioremap_nocache(0xF8000158, sizeof(u32))); printk("[%s:%d] spi_clk_ctrl v: %08x\n", __FUNCTION__, __LINE__, v); printk("[%s:%d] spi_clk_ctrl divisor: %d\n", __FUNCTION__, __LINE__, bit_sel(8,13,v)); printk("[%s:%d] spi_clk_ctrl srcsel: %d\n", __FUNCTION__, __LINE__, bit_sel(4,5,v)); printk("[%s:%d] spi_clk_ctrl clkact1: %d\n", __FUNCTION__, __LINE__, bit_sel(1,1,v)); printk("[%s:%d] spi_clk_ctrl clkact0: %d\n", __FUNCTION__, __LINE__, bit_sel(0,0,v)); } { u32 v = readl(ioremap_nocache(0xF800012C, sizeof(u32))); printk("[%s:%d] aper_clk_ctrl v: %08x\n", __FUNCTION__, __LINE__, v); printk("[%s:%d] aper_clk_ctrl spi1_cpu_1xclkact: %08x\n", __FUNCTION__, __LINE__, bit_sel(15,15,v)); printk("[%s:%d] aper_clk_ctrl spi0_cpu_1xclkact: %08x\n", __FUNCTION__, __LINE__, bit_sel(14,14,v)); } { u32 v = readl(ioremap_nocache(0xE0006000, sizeof(u32))); printk("[%s:%d] spi_config_reg0 v: %08x\n", __FUNCTION__, __LINE__, v); printk("[%s:%d] spi_config_reg0 baud_rate_div: %08x\n", __FUNCTION__, __LINE__, bit_sel(3,5,v)); } return rv; } static int local_remove(struct platform_device *pdev) { printk("[%s:%d] v %x\n", __FUNCTION__, __LINE__); #ifndef POKE_REG_ONLY return xspips_remove(pdev); #else return 0; #endif } #ifdef CONFIG_PM_SLEEP static const struct dev_pm_ops xspips_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(xspips_suspend, xspips_resume) }; #define XSPIPS_PM (&xspips_dev_pm_ops) #else /* ! CONFIG_PM_SLEEP */ #define XSPIPS_PM NULL #endif /* ! CONFIG_PM_SLEEP */ static struct of_device_id xspips_of_match[] = { { .compatible = "connectalspi", }, { /* end of table */} }; MODULE_DEVICE_TABLE(of, xspips_of_match); /* * xspips_driver - This structure defines the SPI subsystem platform driver */ static struct platform_driver xspips_driver = { .probe = local_probe, .remove = local_remove, .driver = { .name = "connectalspi-zynq", .owner = THIS_MODULE, .of_match_table = xspips_of_match, .pm = XSPIPS_PM, }, }; module_platform_driver(xspips_driver); MODULE_LICENSE("GPL"); ================================================ FILE: drivers/pcieportal/Makefile ================================================ # On Centos: sudo yum install kernel-headers V?=0 ifeq ($(V),0) Q=@ else Q= endif CURRENTDIR := $(PWD) CONNECTALDIR ?= $(CURRENTDIR)/../.. include $(CONNECTALDIR)/Makefile.version obj-m += pcieportal.o PKG_NAME?=connectal # DKMS only looks in /usr/src PREFIX?=/usr KVERSION=$(shell uname -r) KROOT=/lib/modules/$(KVERSION)/build export BS_MOD_DIR=$(DESTDIR)/lib/modules/$(KVERSION)/connectal .PHONY: default default: pcieportal.ko ../portalmem/portalmem.ko EXTRA_CFLAGS := -I$(CONNECTALDIR)/drivers/pciportal -I$(CONNECTALDIR)/cpp -I$(CONNECTALDIR) -I$(CONNECTALDIR)/drivers/portalmem -I$(CONNECTALDIR)/generated/cpp cflags-y += -I$(PWD) ../portalmem/portalmem.ko: ../portalmem/portalmem.c cd ../portalmem; make driverversion.h: VERSION=$(VERSION) echo "#define DRIVER_VERSION \"$$VERSION\"" > driverversion.h pcieportal.ko: pcieportal.c pcieportal.h driverversion.h $(Q)$(MAKE) -C $(KROOT) M=$(PWD) modules .PHONY: modules_check modules_check: $(Q)$(MAKE) -C $(KROOT) C=2 M=$(PWD) modules .PHONY: install install: pcieportal.ko install -d -m755 $(BS_MOD_DIR) install -m644 pcieportal.ko $(BS_MOD_DIR) install -m644 ../portalmem/portalmem.ko $(BS_MOD_DIR) ifeq ("$(DESTDIR)", "") depmod endif .PHONY: uninstall uninstall: rm -f $(BS_MOD_DIR)/pcieportal.ko rmdir --ignore-fail-on-non-empty $(BS_MOD_DIR) ifeq ("$(DESTDIR)", "") depmod endif .PHONY: clean clean: $(Q)$(MAKE) -C $(KROOT) M=$(PWD) clean cd ../portalmem; make clean .PHONY: distclean distclean: clean .PHONY: rmmod rmmod: rmmod portalmem || true rmmod pcieportal || true .PHONY: insmod insmod: rmmod insmod pcieportal.ko -chmod agu+rw /dev/portal* insmod ../portalmem/portalmem.ko chmod agu+rw /dev/portalmem .PHONY: install-dkms install-dkms: rm -f driverversion.h make driverversion.h mkdir -p $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) sed "s/@VERSION@/$(VERSION)/" dkms.conf | sed "s/@PKG_NAME@/$(PKG_NAME)/" > dkms.conf.out sed "s/@VERSION@/$(VERSION)/" Makefile.dkms > Makefile.dkms.out cp -fv dkms.conf.out $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/dkms.conf cp -fv Makefile.dkms.out $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/Makefile cp -fv pcieportal.c pcieportal.h driverversion.h $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) cp -fv ../../cpp/*.[ch] ../portalmem/*.[ch] \ ../../generated/cpp/*.[ch] \ $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION) sed -i 's|drivers/portalmem/||' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] sed -i 's|drivers/pcieportal/||' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] sed -i 's|drivers/zynqportal/||' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] sed -i 's|../../cpp/||g' $(DESTDIR)$(PREFIX)/src/$(PKG_NAME)-$(VERSION)/*.[ch] ================================================ FILE: drivers/pcieportal/Makefile.dkms ================================================ obj-m += pcieportal.o obj-m += portalmem.o pcieportal.ko: driverversion.h driverversion.h: echo "#define DRIVER_VERSION \"@VERSION@\"" > driverversion.h ================================================ FILE: drivers/pcieportal/dkms.conf ================================================ PACKAGE_NAME="@PKG_NAME@" PACKAGE_VERSION="@VERSION@" BUILT_MODULE_NAME[0]="pcieportal" DEST_MODULE_LOCATION[0]="/extra/fpga" BUILT_MODULE_NAME[1]="portalmem" DEST_MODULE_LOCATION[1]="/extra/fpga" AUTOINSTALL="yes" ================================================ FILE: drivers/pcieportal/driverversion.h ================================================ #define DRIVER_VERSION "" ================================================ FILE: drivers/pcieportal/linux/dma-buf.h ================================================ /* * Header file for dma buffer sharing framework. * * Copyright(C) 2011 Linaro Limited. All rights reserved. * Author: Sumit Semwal * * Many thanks to linaro-mm-sig list, and specially * Arnd Bergmann , Rob Clark and * Daniel Vetter for their support in creation and * refining of this idea. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ #ifndef __DMA_BUF_H__ #define __DMA_BUF_H__ #include #include #include #include #include #include struct device; struct dma_buf; struct dma_buf_attachment; /** * struct dma_buf_ops - operations possible on struct dma_buf * @attach: [optional] allows different devices to 'attach' themselves to the * given buffer. It might return -EBUSY to signal that backing storage * is already allocated and incompatible with the requirements * of requesting device. * @detach: [optional] detach a given device from this buffer. * @map_dma_buf: returns list of scatter pages allocated, increases usecount * of the buffer. Requires atleast one attach to be called * before. Returned sg list should already be mapped into * _device_ address space. This call may sleep. May also return * -EINTR. Should return -EINVAL if attach hasn't been called yet. * @unmap_dma_buf: decreases usecount of buffer, might deallocate scatter * pages. * @release: release this buffer; to be called after the last dma_buf_put. * @begin_cpu_access: [optional] called before cpu access to invalidate cpu * caches and allocate backing storage (if not yet done) * respectively pin the objet into memory. * @end_cpu_access: [optional] called after cpu access to flush caches. * @kmap_atomic: maps a page from the buffer into kernel address * space, users may not block until the subsequent unmap call. * This callback must not sleep. * @kunmap_atomic: [optional] unmaps a atomically mapped page from the buffer. * This Callback must not sleep. * @kmap: maps a page from the buffer into kernel address space. * @kunmap: [optional] unmaps a page from the buffer. * @mmap: used to expose the backing storage to userspace. Note that the * mapping needs to be coherent - if the exporter doesn't directly * support this, it needs to fake coherency by shooting down any ptes * when transitioning away from the cpu domain. * @vmap: [optional] creates a virtual mapping for the buffer into kernel * address space. Same restrictions as for vmap and friends apply. * @vunmap: [optional] unmaps a vmap from the buffer */ struct dma_buf_ops { int (*attach)(struct dma_buf *, struct device *, struct dma_buf_attachment *); void (*detach)(struct dma_buf *, struct dma_buf_attachment *); /* For {map,unmap}_dma_buf below, any specific buffer attributes * required should get added to device_dma_parameters accessible * via dev->dma_params. */ struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY * if the call would block. */ /* after final dma_buf_put() */ void (*release)(struct dma_buf *); int (*begin_cpu_access)(struct dma_buf *, size_t, size_t, enum dma_data_direction); void (*end_cpu_access)(struct dma_buf *, size_t, size_t, enum dma_data_direction); void *(*kmap_atomic)(struct dma_buf *, unsigned long); void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); void *(*kmap)(struct dma_buf *, unsigned long); void (*kunmap)(struct dma_buf *, unsigned long, void *); int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); void *(*vmap)(struct dma_buf *); void (*vunmap)(struct dma_buf *, void *vaddr); }; /** * struct dma_buf - shared buffer object * @size: size of the buffer * @file: file pointer used for sharing buffers across, and for refcounting. * @attachments: list of dma_buf_attachment that denotes all devices attached. * @ops: dma_buf_ops associated with this buffer object. * @priv: exporter specific private data for this buffer object. */ struct dma_buf { size_t size; struct file *file; struct list_head attachments; const struct dma_buf_ops *ops; /* mutex to serialize list manipulation, attach/detach and vmap/unmap */ struct mutex lock; unsigned vmapping_counter; void *vmap_ptr; void *priv; }; /** * struct dma_buf_attachment - holds device-buffer attachment data * @dmabuf: buffer for this attachment. * @dev: device attached to the buffer. * @node: list of dma_buf_attachment. * @priv: exporter specific attachment data. * * This structure holds the attachment information between the dma_buf buffer * and its user device(s). The list contains one attachment struct per device * attached to the buffer. */ struct dma_buf_attachment { struct dma_buf *dmabuf; struct device *dev; struct list_head node; void *priv; }; /** * get_dma_buf - convenience wrapper for get_file. * @dmabuf: [in] pointer to dma_buf * * Increments the reference count on the dma-buf, needed in case of drivers * that either need to create additional references to the dmabuf on the * kernel side. For example, an exporter that needs to keep a dmabuf ptr * so that subsequent exports don't create a new dmabuf. */ static inline void get_dma_buf(struct dma_buf *dmabuf) { get_file(dmabuf->file); } struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, struct device *dev); void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *dmabuf_attach); struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, size_t size, int flags); int dma_buf_fd(struct dma_buf *dmabuf, int flags); struct dma_buf *dma_buf_get(int fd); void dma_buf_put(struct dma_buf *dmabuf); struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, enum dma_data_direction dir); void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, enum dma_data_direction dir); void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); void *dma_buf_kmap(struct dma_buf *, unsigned long); void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); void *dma_buf_vmap(struct dma_buf *); void dma_buf_vunmap(struct dma_buf *, void *vaddr); #endif /* __DMA_BUF_H__ */ ================================================ FILE: drivers/pcieportal/pcieportal.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Linux device driver for CONNECTAL portals on FPGAs connected via PCIe. */ #include #include #include /* LINUX_VERSION_CODE, KERNEL_VERSION */ #include /* pci device types, fns, etc. */ #include /* error codes */ #include /* I/O mapping, reading, writing */ #include /* struct cdev */ #include /* struct file_operations */ #include /* __init, __exit, etc. */ #include /* ioctl macros */ #include /* request_irq, free_irq, etc. */ #include /* kmalloc, kfree, struct page, etc. */ #include /* task_struct */ #include /* sg_* operations */ #include /* mutex_lock, mutex_unlock, etc. */ #include /* poll_table, etc. */ #include /* copy_to_user, copy_from_user */ #include #include "driverversion.h" #include "pcieportal.h" #define CONNECTAL_DRIVER_CODE #include "portal.h" // PORTAL_BASE_OFFSET #include "dmaSendFd.h" #include "portalKernel.h" /* stem used for module and device names */ #define DEV_NAME "portal" #define BLUESPEC_VENDOR_ID 0x1be7 #define AMAZON_VENDOR_ID 0x1d0f #define CONNECTAL_DEVICE_ID 0xc100 #define AMAZON_DEVICE_ID 0xf000 /* CSR address space offsets */ #define CSR_ID ( 0 << 2) /* 64-bit */ #define CSR_TLPDATAFIFO_DEQ ( 768 << 2) #define CSR_TLPTRACELENGTHREG ( 774 << 2) #define CSR_TLPTRACINGREG ( 775 << 2) #define CSR_TLPDATABRAMRESPONSESLICE0 ( 776 << 2) #define CSR_TLPDATABRAMRESPONSESLICE1 ( 777 << 2) #define CSR_TLPDATABRAMRESPONSESLICE2 ( 778 << 2) #define CSR_TLPDATABRAMRESPONSESLICE3 ( 779 << 2) #define CSR_TLPDATABRAMRESPONSESLICE4 ( 780 << 2) #define CSR_TLPDATABRAMRESPONSESLICE5 ( 781 << 2) #define CSR_TLPPCIEWRADDRREG ( 792 << 2) #define CSR_CHANGELO ( 801 << 2) #define CSR_CHANGEHI ( 802 << 2) /* MSIX must be in separate 4kb page */ #define CSR_MSIX_ADDR_LO (1024 << 2) #define CSR_MSIX_ADDR_HI (1025 << 2) #define CSR_MSIX_MSG_DATA (1026 << 2) #define CSR_MSIX_MASKED (1027 << 2) #define PCR_IID_OFFSET 0x010 #define PCR_NUM_TILES_OFFSET 0x008 #define PCR_NUM_PORTALS_OFFSET 0x014 #define MAX_MSIX_ENTRIES 16 #define MAX_MINOR_COUNT (NUM_BOARDS * MAX_NUM_PORTALS) /* static device data */ static dev_t device_number; static char portalp[MAX_MINOR_COUNT]; // free map of minor numbers static struct class *pcieportal_class = NULL; typedef struct extra_info { /* these datatypes are not available to userspace */ struct cdev cdev; /* per-portal cdev structure */ wait_queue_head_t wait_queue; /* used for interrupt notifications */ dma_addr_t dma_handle; tPortal *portal; } extra_info; static extra_info extra_portal_info[MAX_MINOR_COUNT]; static extra_info extra_board_info[NUM_BOARDS]; static extra_info pcis_board_info[NUM_BOARDS]; static tBoard board_map[NUM_BOARDS + 1]; static unsigned long long expected_magic = 'B' | ((unsigned long long) 'l' << 8) | ((unsigned long long) 'u' << 16) | ((unsigned long long) 'e' << 24) | ((unsigned long long) 's' << 32) | ((unsigned long long) 'p' << 40) | ((unsigned long long) 'e' << 48) | ((unsigned long long) 'c' << 56); static tTraceInfo traceInfo; /* * interrupt handler */ static irqreturn_t intr_handler(int irq, void *p) { tTile *this_tile = p; tBoard *this_board = this_tile->board; int i; //printk(KERN_INFO "%s_%d: interrupt!\n", DEV_NAME, this_tile->device_tile-1); for (i = 0; i < MAX_NUM_PORTALS; i++) { if ((this_tile->device_tile-1 == this_board->portal[i].device_tile) || this_tile->board->info.aws_shell) { if (this_board->portal[i].extra) wake_up_interruptible(&(this_board->portal[i].extra->wait_queue)); } } return IRQ_HANDLED; } /* * driver file operations */ /* open the device file */ static int pcieportal_open(struct inode *inode, struct file *filp) { int err = 0; tPortal *this_portal = ((extra_info *)inode->i_cdev)->portal; if (!this_portal) { printk("pcieportal_open: basedevice_number=%x /dev/connectal\n", device_number); } else { printk("pcieportal_open: basedevice_number=%x tile=%d name=%d\n", device_number, this_portal->device_tile, this_portal->device_name); //printk("[%s:%d] inode %p filp %p portal %p priv %p privp %p extra %p\n", __FUNCTION__, __LINE__, inode, filp, this_portal, filp->private_data, privp, this_portal->extra); init_waitqueue_head(&(this_portal->extra->wait_queue)); /* increment the open file count */ this_portal->board->open_count += 1; } filp->private_data = (void *) this_portal; // FIXME: why does the kernel think this device is RDONLY? filp->f_mode |= FMODE_WRITE; return err; } /* close the device file */ static int pcieportal_release(struct inode *inode, struct file *filp) { tPortal *this_portal = (tPortal *) filp->private_data; if (this_portal) { struct list_head *pmlist; PortalInternal devptr = {.map_base = this_portal->regs, .transport = &kernelfunc}; /* decrement the open file count */ init_waitqueue_head(&(this_portal->extra->wait_queue)); this_portal->board->open_count -= 1; printk("%s_%d_%d: Closed device file\n", DEV_NAME, this_portal->device_tile, this_portal->device_name); list_for_each(pmlist, &this_portal->pmlist) { struct pmentry *pmentry = list_entry(pmlist, struct pmentry, pmlist); printk(" returning id=%d fmem=%p\n", pmentry->id, pmentry->fmem); MMURequest_idReturn(&devptr, pmentry->id); fput(pmentry->fmem); kfree(pmentry); } INIT_LIST_HEAD(&this_portal->pmlist); } return 0; /* success */ } /* poll operation to predict blocking of reads & writes */ static unsigned int pcieportal_poll(struct file *filp, poll_table *poll_table) { tPortal *this_portal = (tPortal *) filp->private_data; unsigned int mask = 0; uint32_t status = 0; //printk(KERN_INFO "%s_%d_%d: poll function called\n", DEV_NAME, this_portal->device_tile, this_portal->device_name); poll_wait(filp, &this_portal->extra->wait_queue, poll_table); if (this_portal->regs) { status = *this_portal->regs; } if (status) mask |= POLLIN | POLLRDNORM; /* readable */ //mask |= POLLOUT | POLLWRNORM; /* writable */ //printk(KERN_INFO "%s_%d_%d: poll return status is %x\n", DEV_NAME, this_portal->device_tile, this_portal->device_name, mask); return mask; } /* * driver IOCTL operations */ static long pcieportal_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int err = 0; tPortal *this_portal = (tPortal *) filp->private_data; tBoard *this_board = NULL; //tBoardInfo info; static int trace_index; if (this_portal) this_board = this_portal->board; /* basic sanity checks */ if (_IOC_DIR(cmd) & _IOC_READ) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) err = !access_ok(VERIFY_WRITE, (void __user *) arg, _IOC_SIZE(cmd)); #else err = !access_ok((void __user *) arg, _IOC_SIZE(cmd)); #endif } else if (_IOC_DIR(cmd) & _IOC_WRITE) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) err = !access_ok(VERIFY_WRITE, (void __user *) arg, _IOC_SIZE(cmd)); #else err = !access_ok((void __user *) arg, _IOC_SIZE(cmd)); #endif } if (!err) switch (cmd) { case BNOC_GET_TLP: { /* copy board identification info to a user-space struct */ unsigned int tlp[6]; memset((char *) tlp, 0xbf, sizeof(tlp)); tlp[5] = ioread32(this_board->bar0io + CSR_TLPDATABRAMRESPONSESLICE5); mb(); tlp[0] = ioread32(this_board->bar0io + CSR_TLPDATABRAMRESPONSESLICE0); mb(); tlp[4] = ioread32(this_board->bar0io + CSR_TLPDATABRAMRESPONSESLICE4); mb(); tlp[1] = ioread32(this_board->bar0io + CSR_TLPDATABRAMRESPONSESLICE1); mb(); tlp[3] = ioread32(this_board->bar0io + CSR_TLPDATABRAMRESPONSESLICE3); mb(); tlp[2] = ioread32(this_board->bar0io + CSR_TLPDATABRAMRESPONSESLICE2); iowrite32(trace_index++, this_board->bar0io + CSR_TLPDATAFIFO_DEQ); // now deq the tlpDataFifo err = copy_to_user((void __user *) arg, tlp, sizeof(tTlpData)); break; } case BNOC_TRACE: { trace_index = 0; iowrite32(0, this_board->bar0io + CSR_TLPPCIEWRADDRREG); traceInfo.trace = ioread32(this_board->bar0io + CSR_TLPTRACINGREG); traceInfo.traceLength = ioread32(this_board->bar0io + CSR_TLPTRACELENGTHREG); if (traceInfo.traceLength == 0xbad0add0) // unimplemented traceInfo.traceLength = 2048; // default value iowrite32(0, this_board->bar0io + CSR_TLPTRACINGREG); // disable tracing printk("disable tracing old trace=%d\n", traceInfo.trace); err = copy_to_user((void __user *) arg, &traceInfo, sizeof(tTraceInfo)); iowrite32(trace_index++, this_board->bar0io + CSR_TLPDATAFIFO_DEQ); } break; case BNOC_ENABLE_TRACE: traceInfo.trace = ioread32(this_board->bar0io + CSR_TLPTRACINGREG); iowrite32(1, this_board->bar0io + CSR_TLPTRACINGREG); // disable tracing break; case PCIE_SEND_FD: { /* pushd down allocated fd */ tSendFd sendFd; struct pmentry *pmentry; PortalInternal devptr = {.map_base = this_portal->regs, .transport = &kernelfunc}; err = copy_from_user(&sendFd, (void __user *) arg, sizeof(sendFd)); if (err) break; pmentry = (struct pmentry *)kzalloc(sizeof(struct pmentry), GFP_KERNEL); INIT_LIST_HEAD(&pmentry->pmlist); pmentry->fmem = fget(sendFd.fd); pmentry->id = sendFd.id; printk("[%s:%d] PCIE_SEND_FD fd=%x id=%x fmem=%p **\n", __FUNCTION__, __LINE__, sendFd.fd, sendFd.id, pmentry->fmem); list_add(&pmentry->pmlist, &this_portal->pmlist); err = send_fd_to_portal(&devptr, sendFd.fd, sendFd.id, 0); if (err < 0) break; err = 0; } break; case PCIE_DEREFERENCE: { int id = arg; struct list_head *pmlist, *n; PortalInternal devptr = {.map_base = this_portal->regs, .transport = &kernelfunc}; err = -ENOENT; MMURequest_idReturn(&devptr, id); list_for_each_safe(pmlist, n, &this_portal->pmlist) { struct pmentry *pmentry = list_entry(pmlist, struct pmentry, pmlist); if (pmentry->id == id) { printk("%s:%d releasing portalmem id=%d fmem=%p count=%ld\n", __FUNCTION__, __LINE__, id, pmentry->fmem, (unsigned long)pmentry->fmem->f_count.counter); fput(pmentry->fmem); list_del(&pmentry->pmlist); kfree(pmentry); err = 0; break; } } } break; case PCIE_SIGNATURE: { return 0; } case PCIE_CHANGE_ENTRY: { tChangeEntry entry; uint32_t vlo; vlo = ioread32(this_board->bar0io + CSR_CHANGELO); entry.timestamp = ioread32(this_board->bar0io + CSR_CHANGEHI); entry.src = (vlo >> 24); entry.value = vlo; printk("%s: timestamp=%08x src=%02x value=%96x\n", "portal", entry.timestamp, entry.src, entry.value); if (copy_to_user((void __user *)arg, &entry, sizeof(entry))) return -EFAULT; return 0; } break; default: return -ENOTTY; } if (err) return -EFAULT; return 0; } static int portal_mmap(struct file *filp, struct vm_area_struct *vma) { tPortal *this_portal = (tPortal *) filp->private_data; struct pci_dev *pci_dev = this_portal->board->pci_dev; off_t off; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; if (vma->vm_pgoff < 16) { if (this_portal->board->info.aws_shell) { off = pci_dev->resource[0].start + this_portal->offset; } else { off = pci_dev->resource[2].start + this_portal->offset; } printk("portal_mmap portal_number=%d board_start=%012lx portal_start=%012lx\n", this_portal->portal_number, (long) pci_dev->resource[2].start, off); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_pgoff = off >> PAGE_SHIFT; //vma->vm_flags |= VM_IO | VM_RESERVED; } else { if (!this_portal->virt) { this_portal->virt = dma_alloc_coherent(&pci_dev->dev, vma->vm_end - vma->vm_start, &this_portal->extra->dma_handle, GFP_ATOMIC); //this_portal->virt =pci_alloc_consistent(pci_dev, PORTAL_BASE_OFFSET, &this_portal->extra->dma_handle); printk("dma_alloc_coherent virt=%p dma_handle=%p\n", this_portal->virt, (void *) this_portal->extra->dma_handle); } //vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); off = this_portal->extra->dma_handle; } vma->vm_flags |= VM_IO; if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; } static ssize_t pcieportal_read(struct file *filp, char *buffer, size_t length, loff_t *offset) { return 0; } /* file operations pointers */ static const struct file_operations pcieportal_fops = { .owner = THIS_MODULE, .open = pcieportal_open, .read = pcieportal_read, .release = pcieportal_release, .poll = pcieportal_poll, .unlocked_ioctl = pcieportal_ioctl, .compat_ioctl = pcieportal_ioctl, .mmap = portal_mmap }; static int pcieportal_dma_pcis_open(struct inode *inode, struct file *filp) { //tBoard *this_board = &board_map[0]; int err = 0; printk("pcieportal_dma_pcis_open\n"); filp->private_data = (void *) &board_map[0]; // FIXME: why does the kernel think this device is RDONLY? filp->f_mode |= FMODE_WRITE; return err; } /* close the device file */ static int pcieportal_dma_pcis_release(struct inode *inode, struct file *filp) { // do we need to unmap? return 0; /* success */ } static int portal_dma_pcis_mmap(struct file *filp, struct vm_area_struct *vma) { tBoard *this_board = &board_map[0]; struct pci_dev *pci_dev = this_board->pci_dev; off_t off = 0; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; if (this_board->info.aws_shell) { off = pci_dev->resource[4].start; } else { printk("portal_dma_pcis only supported on AWS F1\n"); return -EINVAL; } printk("portal_dma_pcis_mmap board_start=%012lx", (long) pci_dev->resource[4].start); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_pgoff = off >> PAGE_SHIFT; //vma->vm_flags |= VM_IO | VM_RESERVED; vma->vm_flags |= VM_IO; if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; } static const struct file_operations pcieportal_dma_pcis_fops = { .owner = THIS_MODULE, .open = pcieportal_dma_pcis_open, .read = pcieportal_read, .release = pcieportal_dma_pcis_release, .mmap = portal_dma_pcis_mmap }; #ifdef PCIEPORTAL_TUNE_CAPS static void tune_pcie_caps(struct pci_dev *dev) { struct pci_dev *parent; u16 rc_mpss, rc_mps, ep_mpss, ep_mps; u16 rc_mrrs, ep_mrrs, max_mrrs; printk("%s: %s:%d\n", DEV_NAME, __FUNCTION__, __LINE__); parent = dev->bus->self; // why does parent have to be root? if (!pci_is_root_bus(parent->bus)) { printk("%s: parent is not root\n", DEV_NAME); return; } /* max payload size adjustment */ rc_mpss = parent->pcie_mpss; rc_mps = ffs(pcie_get_mps(parent)) - 8; ep_mpss = dev->pcie_mpss; ep_mps = ffs(pcie_get_mps(dev)) - 8; rc_mpss = max(rc_mpss, ep_mpss); if (rc_mpss > rc_mps) { rc_mps = rc_mpss; pcie_set_mps(parent, 128 << rc_mps); } if (rc_mpss > ep_mps) { ep_mps = rc_mpss; pcie_set_mps(dev, 128 << ep_mps); } printk("%s: %s:%d parent.mps=%d dev.mps=%d\n", DEV_NAME, __FUNCTION__, __LINE__, pcie_get_mps(parent), pcie_get_mps(dev)); /* max read request size, limited to 4096 by PCIe spec */ max_mrrs = 128 << 5; rc_mrrs = pcie_get_readrq(parent); ep_mrrs = pcie_get_readrq(dev); if (max_mrrs > rc_mrrs) { rc_mrrs = max_mrrs; pcie_set_readrq(parent, rc_mrrs); } if (max_mrrs > ep_mrrs) { ep_mrrs = max_mrrs; pcie_set_readrq(dev, ep_mrrs); } printk("%s: %s:%d parent.readrq=%d dev.readrq=%d\n", DEV_NAME, __FUNCTION__, __LINE__, pcie_get_readrq(parent), pcie_get_readrq(dev)); } #endif // PCIEPORTAL_TUNE_CAPS static int board_activate(int activate, tBoard *this_board, struct pci_dev *dev) { int i; int rc, err = 0; unsigned long long magic_num; int num_entries = MAX_MSIX_ENTRIES; struct msix_entry msix_entries[MAX_MSIX_ENTRIES]; int fpn = 0; int num_tiles, tile_index; void __iomem *ptile; printk("[%s:%d]\n", __FUNCTION__, __LINE__); for (i = 0; i < MAX_NUM_PORTALS; i++) if (!this_board->portal[i].extra) { printk(KERN_ERR "%s: extra not initialized!!! %s\n", DEV_NAME, pci_name(dev)); err = -EFAULT; goto err_exit; } if (activate) { dev_t this_device_number; void *portal_base = 0; for (i = 0; i < MAX_NUM_PORTALS; i++) this_board->portal[i].device_name = -1; for (i = 0; i < MAX_NUM_PORTALS; i++) init_waitqueue_head(&(this_board->portal[i].extra->wait_queue)); this_board->pci_dev = dev; /* enable the PCI device */ if (pci_enable_device(dev)) { printk(KERN_ERR "%s: failed to enable %s\n", DEV_NAME, pci_name(dev)); err = -EFAULT; goto err_exit; } /* reserve PCI memory regions */ for (i = 0; i < 5; i++) printk("pci bar %d start=%08lx end=%08lx flags=%lx\n", i, (unsigned long) dev->resource[i].start, (unsigned long) dev->resource[i].end, dev->resource[i].flags); traceInfo.base = dev->resource[2].start; /* remember physical address of bar2 */ if ((rc = pci_request_region(dev, 0, "bar0"))) { printk("failed to request region bar0 rc=%d\n", rc); err = -EBUSY; goto PCI_DEV_ENABLED_label; } rc = pci_request_region(dev, 1, "bar1"); printk("reserving region bar1 rc=%d\n", rc); rc = pci_request_region(dev, 2, "bar2"); printk("reserving region bar2 rc=%d\n", rc); /* map BARs */ this_board->bar0io = pci_iomap(dev, 0, 0); printk("bar0io=%p\n", this_board->bar0io); this_board->bar1io = pci_iomap(dev, 1, 0); printk("bar1io=%p\n", this_board->bar1io); this_board->bar2io = pci_iomap(dev, 2, 0); printk("bar2io=%p\n", this_board->bar2io); this_board->bar4io = pci_iomap(dev, 4, 0); printk("bar4io=%p\n", this_board->bar4io); if (!this_board->bar1io) { this_board->bar1io = pci_iomap(dev, 1, 8192); printk("bar1io=%p\n", this_board->bar1io); } if (!this_board->bar0io) { printk("failed to map bar0\n"); err = -EFAULT; goto BARS_ALLOCATED_label; } if (!this_board->bar2io) { printk("failed to map bar2\n"); err = -EFAULT; goto BARS_ALLOCATED_label; } if (!this_board->bar4io) { this_board->info.aws_shell = 0; // this replaces 'connectal/pcie/connectalutil/connectalutil trace /dev/fpga0' // but why is it needed?... iowrite32(0, this_board->bar0io + CSR_TLPPCIEWRADDRREG); // enable tracing iowrite32(1, this_board->bar0io + CSR_TLPTRACINGREG); /* check the magic number in BAR 0 */ magic_num = ((long long)ioread32(this_board->bar0io + CSR_ID + 4)) << 32; magic_num |= ioread32(this_board->bar0io + CSR_ID); if (magic_num != expected_magic) { printk(KERN_ERR "%s: magic number %llx does not match expected %llx\n", DEV_NAME, magic_num, expected_magic); err = -EINVAL; goto BARS_MAPPED_label; } // check for xdma on bar2 } else { this_board->info.aws_shell = 1; printk(" xdma block ID %x\n", ioread32(this_board->bar2io + 0x0000)); printk(" irq block ID %x\n", ioread32(this_board->bar2io + 0x2000)); printk("config block ID %x\n", ioread32(this_board->bar2io + 0x3000)); } /* set DMA mask */ if (pci_set_dma_mask(dev, DMA_BIT_MASK(48))) { printk(KERN_ERR "%s: pci_set_dma_mask failed for 48-bit DMA\n", DEV_NAME); err = -EIO; goto BARS_MAPPED_label; } /* enable MSIX */ for (i = 0; i < num_entries; i++) msix_entries[i].entry = i; if ((num_entries = pci_enable_msix_range(dev, msix_entries, num_entries, num_entries)) < 0) { printk(KERN_ERR "%s: Failed to setup MSIX interrupts\n", DEV_NAME); err = -EFAULT; goto BARS_MAPPED_label; } this_board->irq_num = msix_entries[0].vector; printk(KERN_INFO "%s: Using MSIX interrupts num_entries=%d check_device\n", DEV_NAME, num_entries); for (i = 0; i < num_entries; i++) printk(KERN_INFO "%s: msix_entries[%d] vector=%d entry=%08x\n", DEV_NAME, i, msix_entries[i].vector, msix_entries[i].entry); /* install the IRQ handler */ for (i = 0; i < num_entries; i++) { if (request_irq(this_board->irq_num + i, intr_handler, 0, DEV_NAME, (void *) &this_board->tile[i])) { printk(KERN_ERR "%s: Failed to get requested IRQ %d\n", DEV_NAME, this_board->irq_num); err = -EBUSY; goto MSI_ENABLED_label; } } /* set MSIX Entry 0 Vector Control value to 0 (unmasked) */ printk(KERN_INFO "%s: MSIX interrupts enabled with %d IRQs starting at %d\n", DEV_NAME, num_entries, this_board->irq_num); iowrite32(0, this_board->bar0io + CSR_MSIX_MASKED); pci_set_master(dev); /* enable PCI bus master */ if (this_board->info.aws_shell) { portal_base = this_board->bar0io; ptile = this_board->bar0io; printk("bar0io[0]=%08x\n", *(int *)this_board->bar0io); // enable user interrupts via XDMA block in AWS F1 Shell iowrite32(0xFFFF, this_board->bar2io + 0x2000 + 4); printk("enabled user interrupts in XDMA %x\n", ioread32(this_board->bar2io + 0x2000 + 4)); } else { portal_base = this_board->bar2io; ptile = this_board->bar2io; } num_tiles = *(volatile uint32_t *)(ptile + PCR_NUM_TILES_OFFSET); if (num_tiles < 0 || num_tiles > 16) num_tiles = 0; tile_index = 0; do { // loop over all tiles void __iomem *pportal = ptile; int num_portals = *(volatile uint32_t *)(pportal + PCR_NUM_PORTALS_OFFSET); int portal_index = 0; this_board->tile[tile_index].board = this_board; this_board->tile[tile_index].device_tile = tile_index + 1; do { // loop over all portals in a tile int freep; uint32_t iid = *(volatile uint32_t *)(pportal + PCR_IID_OFFSET); tPortal *this_portal = &this_board->portal[fpn]; unsigned long offs = ((unsigned long)pportal) - ((unsigned long)portal_base); printk("%s:%d num_tiles %x/%x num_portals %x/%x fpn %x iid=%d pportal %p offset %lx\n", __FUNCTION__, __LINE__, tile_index, num_tiles, portal_index, num_portals, fpn, iid, pportal, offs); traceInfo.intval[fpn] = ioread32(this_board->bar0io + CSR_MSIX_MSG_DATA + 16*fpn); traceInfo.name[fpn] = iid; for (freep = 0; freep < sizeof(portalp)/sizeof(portalp[0]); freep++) if (!portalp[freep]) break; if (freep == sizeof(portalp)/sizeof(portalp[0])) { printk(KERN_ERR "%s: too many portals\n", KERN_ERR); err = -EFAULT; } else portalp[freep] = 1; this_portal->device_number = freep; this_portal->device_tile = tile_index; this_portal->portal_number = fpn; this_portal->device_name = iid; this_portal->board = this_board; this_portal->regs = (volatile uint32_t *)pportal; this_portal->offset = offs; /* add the device operations */ cdev_init(&this_portal->extra->cdev, &pcieportal_fops); this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + this_portal->device_number); printk("%s:%d: calling cdev_add this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); if (cdev_add(&this_portal->extra->cdev, this_device_number, 1)) { printk(KERN_ERR "%s: cdev_add %x failed\n", DEV_NAME, this_device_number); err = -EFAULT; } else { /* create a device node via udev */ printk("%s:%d: calling_device_create /dev/%s_b%dt%dp%d = %x\n", DEV_NAME, __LINE__, DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name, this_device_number); device_create(pcieportal_class, &dev->dev, this_device_number, this_portal, "%s_b%dt%dp%d", DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name); printk(KERN_INFO "%s: /dev/%s_b%dt%dp%d = %x created\n", DEV_NAME, DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name, this_device_number); } if (++fpn >= MAX_NUM_PORTALS){ printk(KERN_INFO "%s: MAX_NUM_PORTALS exceeded", __func__); err = -EFAULT; break; } pportal += PORTAL_BASE_OFFSET; } while (++portal_index < num_portals); ptile += TILE_BASE_OFFSET; } while (++tile_index < num_tiles); this_board->info.num_portals = fpn; pci_set_drvdata(dev, this_board); if (this_board->info.board_number == 0) { this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT); cdev_init(&this_board->extra->cdev, &pcieportal_fops); printk("%s:%d: calling cdev_add this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); if (cdev_add(&this_board->extra->cdev, this_device_number, 1)) { printk(KERN_ERR "%s: cdev_add board failed\n", DEV_NAME); } printk("%s:%d: calling device_create this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); device_create(pcieportal_class, &dev->dev, this_device_number, NULL, "connectal"); // add the device node for portal_dma_pcis this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT + 1); cdev_init(&this_board->pcis->cdev, &pcieportal_dma_pcis_fops); printk("%s:%d: calling cdev_add this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); if (cdev_add(&this_board->pcis->cdev, this_device_number, 1)) { printk(KERN_ERR "%s: cdev_add board failed\n", DEV_NAME); } printk("%s:%d: calling device_create this_device_number=%x\n", DEV_NAME, __LINE__, this_device_number); device_create(pcieportal_class, &dev->dev, this_device_number, NULL, "portal_dma_pcis"); } #ifdef PCIEPORTAL_TUNE_CAPS tune_pcie_caps(dev); #endif // PCIEPORTAL_TUNE_CAPS if (err == 0) return err; /* if board activated correctly, return */ } /* end of if(activate) */ /******** deactivate board *******/ if (this_board->info.board_number == 0) { device_destroy(pcieportal_class, MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT)); cdev_del(&this_board->extra->cdev); device_destroy(pcieportal_class, MKDEV(MAJOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT + 1)); cdev_del(&this_board->pcis->cdev); } fpn = 0; while(fpn < this_board->info.num_portals) { tPortal *this_portal = &this_board->portal[fpn]; /* remove device node in udev */ dev_t this_device_number = MKDEV(MAJOR(device_number), MINOR(device_number) + this_portal->device_number); portalp[this_portal->device_name] = 0; device_destroy(pcieportal_class, this_device_number); printk(KERN_INFO "%s: /dev/%s_b%dt%dp%d = %x removed\n", DEV_NAME, DEV_NAME, this_portal->board->info.board_number, this_portal->device_tile, this_portal->device_name, this_device_number); /* remove device */ cdev_del(&this_board->portal[fpn].extra->cdev); fpn++; } pci_clear_master(dev); /* disable PCI bus master */ /* set MSIX Entry 0 Vector Control value to 1 (masked) */ iowrite32(1, this_board->bar0io + CSR_MSIX_MASKED); disable_irq(this_board->irq_num); for (i = 0; i < num_entries; i++) free_irq(this_board->irq_num + i, (void *) &this_board->tile[i]); MSI_ENABLED_label: /* disable MSI/MSIX */ pci_disable_msix(dev); BARS_MAPPED_label: /* unmap PCI BARs */ if (this_board->bar0io) pci_iounmap(dev, this_board->bar0io); if (this_board->bar1io) pci_iounmap(dev, this_board->bar1io); if (this_board->bar2io) pci_iounmap(dev, this_board->bar2io); if (this_board->bar4io) pci_iounmap(dev, this_board->bar4io); BARS_ALLOCATED_label: pci_release_regions(dev); /* release PCI memory regions */ PCI_DEV_ENABLED_label: pci_disable_device(dev); /* disable pci device */ err_exit: this_board->pci_dev = NULL; pci_set_drvdata(dev, NULL); return err; } /* driver PCI operations */ static int pcieportal_probe(struct pci_dev *dev, const struct pci_device_id *id) { tBoard *this_board = NULL; int i, board_number = 0; printk("******[%s:%d] probe %p dev %p id %p getdrv %p\n", __FUNCTION__, __LINE__, &pcieportal_probe, dev, id, pci_get_drvdata(dev)); printk(KERN_INFO "%s: PCI probe for 0x%04x 0x%04x\n", DEV_NAME, dev->vendor, dev->device); /* double-check vendor and device */ if ((dev->vendor != BLUESPEC_VENDOR_ID || dev->device != CONNECTAL_DEVICE_ID) && (dev->vendor != AMAZON_VENDOR_ID || dev->device != AMAZON_DEVICE_ID)) { printk(KERN_ERR "%s: probe with invalid vendor or device ID\n", DEV_NAME); return -EINVAL; } /* assign a board number */ while (board_map[board_number].pci_dev && board_number < NUM_BOARDS) board_number++; if (board_number >= NUM_BOARDS) { printk(KERN_ERR "%s: %d boards are already in use!\n", DEV_NAME, NUM_BOARDS); return -EBUSY; } this_board = &board_map[board_number]; printk(KERN_INFO "%s: board_number = %d\n", DEV_NAME, board_number); memset(this_board, 0, sizeof(tBoard)); for (i = 0; i < MAX_NUM_PORTALS; i++) { this_board->portal[i].extra = &extra_portal_info[board_number * MAX_NUM_PORTALS + i]; extra_portal_info[board_number * MAX_NUM_PORTALS + i].portal = &this_board->portal[i]; INIT_LIST_HEAD(&this_board->portal[i].pmlist); } this_board->extra = &extra_board_info[board_number]; this_board->pcis = &pcis_board_info[board_number]; this_board->info.board_number = board_number; return board_activate(1, this_board, dev); } static void pcieportal_remove(struct pci_dev *dev) { tBoard *this_board = pci_get_drvdata(dev); printk("*****[%s:%d] getdrv %p\n", __FUNCTION__, __LINE__, this_board); if (!this_board) { printk(KERN_ERR "%s: Unable to locate board when removing PCI device %p\n", DEV_NAME, dev); return; } board_activate(0, this_board, dev); } /* PCI ID pattern table */ static #ifdef DEFINE_PCI_DEVICE_TABLE // changed in Linux 4.8 DEFINE_PCI_DEVICE_TABLE(pcieportal_id_table) #else const struct pci_device_id pcieportal_id_table[] #endif = { { PCI_DEVICE(BLUESPEC_VENDOR_ID, CONNECTAL_DEVICE_ID)}, { PCI_DEVICE(AMAZON_VENDOR_ID, AMAZON_DEVICE_ID)}, { /* end: all zeros */ } }; MODULE_DEVICE_TABLE(pci, pcieportal_id_table); static pci_ers_result_t pcieportal_error_detected(struct pci_dev *pdev, enum pci_channel_state error) { printk(KERN_ERR "%s:%s: pcie error %d\n", DEV_NAME, __FUNCTION__, error); return PCI_ERS_RESULT_CAN_RECOVER; } static pci_ers_result_t pcieportal_error_mmio_enabled(struct pci_dev *pdev) { printk(KERN_ERR "%s:%s\n", DEV_NAME, __FUNCTION__); return PCI_ERS_RESULT_CAN_RECOVER; } static pci_ers_result_t pcieportal_error_slot_reset(struct pci_dev *pdev) { printk(KERN_ERR "%s:%s\n", DEV_NAME, __FUNCTION__); return PCI_ERS_RESULT_CAN_RECOVER; } static void pcieportal_error_resume(struct pci_dev *pdev) { printk(KERN_ERR "%s:%s\n", DEV_NAME, __FUNCTION__); } static const struct pci_error_handlers pcieportal_err_handler = { .error_detected = pcieportal_error_detected, .mmio_enabled = pcieportal_error_mmio_enabled, .slot_reset = pcieportal_error_slot_reset, .resume = pcieportal_error_resume, }; /* PCI driver operations pointers */ static struct pci_driver pcieportal_ops = { .name = DEV_NAME, .id_table = pcieportal_id_table, .probe = pcieportal_probe, .remove = pcieportal_remove, .err_handler = &pcieportal_err_handler, }; /* * * get the tBoard struct * */ tBoard* get_pcie_portal_descriptor(void) { return &board_map[0]; } /* * driver initialization and exit * * these routines are responsible for allocating and * freeing kernel resources, creating device nodes, * registering the driver, obtaining a major and minor * numbers, etc. */ /* first routine called on module load */ static int pcieportal_init(void) { int status; printk("[%s:%d]\n", __FUNCTION__, __LINE__); pcieportal_class = class_create(THIS_MODULE, "Connectal"); if (IS_ERR(pcieportal_class)) { printk(KERN_ERR "%s: failed to create class Connectal\n", DEV_NAME); return PTR_ERR(pcieportal_class); } /* dynamically allocate a device number */ if (alloc_chrdev_region(&device_number, 1, MAX_MINOR_COUNT + 1, DEV_NAME) < 0) { printk(KERN_ERR "%s: failed to allocate character device region\n", DEV_NAME); class_destroy(pcieportal_class); return -1; } /* initialize driver data */ memset(board_map, 0, sizeof(board_map)); /* log the fact that we loaded the driver module */ printk(KERN_INFO "%s: Registered Connectal Pcieportal driver %s\n", DEV_NAME, DRIVER_VERSION); printk(KERN_INFO "%s: Major = %d Minors = %d to %d\n", DEV_NAME, MAJOR(device_number), MINOR(device_number), MINOR(device_number) + MAX_MINOR_COUNT - 1); /* register the driver with the PCI subsystem */ status = pci_register_driver(&pcieportal_ops); if (status < 0) { printk(KERN_ERR "%s: failed to register PCI driver\n", DEV_NAME); class_destroy(pcieportal_class); return status; } printk("[%s:%d]\n", __FUNCTION__, __LINE__); return 0; /* success */ } /* routine called on module unload */ static void pcieportal_exit(void) { /* unregister the driver with the PCI subsystem */ pci_unregister_driver(&pcieportal_ops); /* release reserved device numbers */ unregister_chrdev_region(device_number, MAX_MINOR_COUNT + 1); class_destroy(pcieportal_class); /* log that the driver module has been unloaded */ printk(KERN_INFO "%s: Unregistered Connectal Pcieportal driver %s\n", DEV_NAME, DRIVER_VERSION); } /* * driver module data for the kernel */ module_init(pcieportal_init); module_exit(pcieportal_exit); EXPORT_SYMBOL(get_pcie_portal_descriptor); MODULE_AUTHOR("Bluespec, Inc., Cambridge hackers"); MODULE_DESCRIPTION("PCIe device driver for PCIe FPGA portals"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(DRIVER_VERSION); ================================================ FILE: drivers/pcieportal/pcieportal.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef __BLUENOC_H__ #define __BLUENOC_H__ #include /* * IOCTLs */ /* magic number for IOCTLs */ #define BNOC_IOC_MAGIC 0xB5 /* Number of boards to support */ #define NUM_BOARDS 4 #define MAX_NUM_PORTALS 32 /* Structures used with IOCTLs */ typedef struct { unsigned long base; unsigned int trace; unsigned int traceLength; unsigned int intval[MAX_NUM_PORTALS]; unsigned int name[MAX_NUM_PORTALS]; } tTraceInfo; typedef struct { int fd; int id; } tSendFd; typedef struct { int index; /* in param */ char md5[33]; /* out param -- asciz */ char filename[33]; /* out param -- asciz */ } PortalSignaturePcie; typedef unsigned int tTlpData[6]; typedef struct ChangeEntry { unsigned int timestamp; unsigned char src; unsigned int value : 24; } tChangeEntry; /* IOCTL code definitions */ #define BNOC_GET_TLP _IOR(BNOC_IOC_MAGIC,7,tTlpData*) #define BNOC_TRACE _IOWR(BNOC_IOC_MAGIC,8,tTraceInfo*) #define BNOC_ENABLE_TRACE _IOR(BNOC_IOC_MAGIC,8,int*) #define PCIE_SEND_FD _IOR(BNOC_IOC_MAGIC,12,tSendFd*) #define PCIE_DEREFERENCE _IOR(BNOC_IOC_MAGIC,13,int) #define PCIE_SIGNATURE _IOR(BNOC_IOC_MAGIC,14,PortalSignaturePcie) #define PCIE_CHANGE_ENTRY _IOR(BNOC_IOC_MAGIC,15,tChangeEntry*) #ifdef __KERNEL__ /* * Per-device data */ typedef struct { unsigned int device_number; unsigned int device_tile; unsigned int portal_number; unsigned int device_name; struct tBoard *board; void *virt; volatile uint32_t *regs; // Pointer to access portal from kernel unsigned long offset; // Offset from base of BAR2 struct extra_info *extra; struct list_head pmlist; } tPortal; typedef struct { unsigned int device_tile; struct tBoard *board; } tTile; struct pmentry { struct file *fmem; int id; struct list_head pmlist; }; typedef struct tBoard { void __iomem *bar0io, *bar1io, *bar2io, *bar4io; /* bars */ struct pci_dev *pci_dev; /* pci device pointer */ tPortal portal[MAX_NUM_PORTALS]; unsigned int irq_num; unsigned int open_count; tTile tile[MAX_NUM_PORTALS]; struct extra_info *extra; struct extra_info *pcis; // DMA PCIS on AWSF1 struct { unsigned int board_number; unsigned int portal_number; unsigned int num_portals; unsigned int aws_shell; } info; /* board identification fields */ } tBoard; extern tBoard* get_pcie_portal_descriptor(void); #endif #endif /* __BLUENOC_H__ */ ================================================ FILE: drivers/portalmem/Makefile ================================================ V?=0 ifeq ($(V),0) Q=@ else Q= endif DEFCONFIG ?= xilinx_zynq_portal_atheros_sdio_defconfig CONNECTALDIR ?= $(PWD)/../.. include $(CONNECTALDIR)/Makefile.version obj-m = portalmem.o ccflags-y := -I$(CONNECTALDIR) ifeq ("$(KROOT)","") KVERSION=$(shell uname -r) export KROOT=/lib/modules/$(KVERSION)/build else CROSS_COMPILE?=arm-linux-gnueabi- PARAM=ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) endif portalmem.ko: portalmem.h portalmem.c driverversion.h ifneq ("$(PARAM)","") $(Q)$(MAKE) $(PARAM) -C $(KROOT) $(DEFCONFIG) $(Q)$(MAKE) $(PARAM) -C $(KROOT) -j8 zImage endif $(Q)$(MAKE) $(PARAM) -C $(KROOT) M=$(PWD) modules driverversion.h: VERSION=$(VERSION) echo "#define DRIVER_VERSION \"$VERSION\"" > driverversion.h parallellaportalmem.ko: portalmem.h portalmem.c $(Q)$(MAKE) $(PARAM) -C $(KROOT) parallella_defconfig $(Q)$(MAKE) $(PARAM) -C $(KROOT) -j8 LOADADDR=0x8000 uImage $(Q)$(MAKE) $(PARAM) -C $(KROOT) M=$(PWD) modules clean: $(Q)$(MAKE) $(PARAM) -C $(KROOT) M=$(PWD) clean ================================================ FILE: drivers/portalmem/portalmem.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * Copyright (c) 2015 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "drivers/portalmem/portalmem.h" #include "driverversion.h" #ifdef DEBUG // was KERN_DEBUG #define driver_devel(format, ...) \ do { \ printk(format, ## __VA_ARGS__); \ } while (0) #else #define driver_devel(format, ...) #endif #define DRIVER_NAME "portalmem" #define DRIVER_DESCRIPTION "Memory management between HW and SW processes" static struct miscdevice miscdev; static void free_buffer_page(struct page *page, unsigned int order) { __free_pages(page, order); } static int pa_buffer_free(struct pa_buffer *buffer) { struct sg_table *table = buffer->sg_table; struct scatterlist *sg; LIST_HEAD(pages); int i; printk("PortalAlloc::pa_system_heap_free\n"); for_each_sg(table->sgl, sg, table->nents, i){ free_buffer_page(sg_page(sg), get_order(sg->length)); } sg_free_table(table); kfree(table); kfree(buffer); return 0; } /* * driver dma_buf callback functions */ static struct sg_table *pa_dma_buf_map(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { return ((struct pa_buffer *)attachment->dmabuf->priv)->sg_table; } static void pa_dma_buf_unmap(struct dma_buf_attachment *attachment, struct sg_table *table, enum dma_data_direction direction) { } //from: http://stackoverflow.com/questions/654393/examining-mmaped-addresses-using-gdb static inline int custom_vma_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write) { void __iomem *maddr = NULL; struct pa_buffer *buffer = vma->vm_private_data; struct scatterlist *sg; int i; int offset = 0; struct sg_table *table; if (!buffer) return -EFAULT; offset = (addr) - vma->vm_start; table = buffer->sg_table; for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); maddr = page_address(page); if (offset < sg->length) break; offset -= sg->length; } if (write) memcpy(maddr + offset, buf, len); else memcpy(buf, maddr + offset, len); return len; } static struct vm_operations_struct custom_vm_ops = { .access = custom_vma_access, }; #ifdef __arm__ #include #include "asm/thread_info.h" #include "asm-generic/current.h" static void llshow_pte(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; printk(KERN_ALERT "pgd = %p\n", mm->pgd); pgd = pgd_offset(mm, addr); printk(KERN_ALERT "[%08lx] *pgd=%08llx", addr, (long long)pgd_val(*pgd)); do { pud_t *pud; pmd_t *pmd; pte_t *pte; if (pgd_none(*pgd)) break; if (pgd_bad(*pgd)) { printk("(bad)"); break; } pud = pud_offset(pgd, addr); if (PTRS_PER_PUD != 1) printk(", *pud=%08llx", (long long)pud_val(*pud)); if (pud_none(*pud)) break; if (pud_bad(*pud)) { printk("(bad)"); break; } pmd = pmd_offset(pud, addr); if (PTRS_PER_PMD != 1) printk(", *pmd=%08llx", (long long)pmd_val(*pmd)); if (pmd_none(*pmd)) break; if (pmd_bad(*pmd)) { printk("(bad)"); break; } /* We must not map this if we have highmem enabled */ if (PageHighMem(pfn_to_page(pmd_val(*pmd) >> PAGE_SHIFT))) break; pte = pte_offset_map(pmd, addr); printk(", *pte=%08llx", (long long)pte_val(*pte)); #ifndef CONFIG_ARM_LPAE printk(", *ppte=%08llx", (long long)pte_val(pte[PTE_HWTABLE_PTRS])); #endif pte_unmap(pte); } while(0); printk("\n"); } #endif static int pa_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) { struct pa_buffer *buffer = dmabuf->priv; int ret = 0; struct scatterlist *sg; int i; buffer->vaddr = (void *)(long)vma->vm_start; /* Fill in vma_ops::access(), so that gdb print command works correctly */ vma->vm_ops = &custom_vm_ops; vma->vm_private_data = buffer; printk("pa_dma_buf_mmap %p %ld\n", (dmabuf->file), (unsigned long)dmabuf->file->f_count.counter); if (!buffer->cached) { // pgprot_writecombine must be disabled so that ld/strex work correctly on arm (in C: __gnu_cxx::__exchange_and_add ) // however, that currently breaks connectal examples. Jamey 10/2014 // According to Arm ARM A3.4.5: "LDREX and STREX ... only on memory with Normal" // According to Arm ARM B3.7.2: TEX[2:0]/C/B == 000/0/1 -> "Device", 001/1/1 -> "Normal" // (this is the difference between calling pgprot_writecombine() or not) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); } mutex_lock(&buffer->lock); /* now map it to userspace */ { struct sg_table *table = buffer->sg_table; unsigned long addr = vma->vm_start; unsigned long offset = vma->vm_pgoff * PAGE_SIZE; //printk("(0) pa_system_heap_map_user %08lx %08lx %08lx\n", vma->vm_start, vma->vm_end, offset); for_each_sg(table->sgl, sg, table->nents, i) { struct page *page = sg_page(sg); unsigned long remainder = vma->vm_end - addr; unsigned int len = sg->length; // sg->length is unsigned int //printk("pa_system_heap_map_user %08x %08x\n", sg->length, sg_dma_len(sg)); //printk("(1) pa_system_heap_map_user %08lx %08lx %08x\n", (unsigned long) page, remainder, len); if (offset >= (sg->length)) { //printk("feck %08lx %08x\n", offset, (sg->length)); offset -= (sg->length); continue; } else if (offset) { page += offset / PAGE_SIZE; len = (sg->length) - offset; offset = 0; } len = min((unsigned long)len, remainder); //printk("(2) pa_system_heap_map_user %08lx %08lx %08lx\n", addr, (unsigned long)page, page_to_pfn(page)); remap_pfn_range(vma, addr, page_to_pfn(page), len, vma->vm_page_prot); #ifdef __arm__ llshow_pte(current->mm, (unsigned long) addr); #endif addr += len; if (addr >= vma->vm_end) break; } } mutex_unlock(&buffer->lock); if (ret) pr_err("%s: failure mapping buffer to userspace\n", __func__); return ret; } static void pa_dma_buf_release(struct dma_buf *dmabuf) { struct pa_buffer *buffer = dmabuf->priv; printk("PortalAlloc::pa_dma_buf_release %p %ld\n", (dmabuf->file), (unsigned long)dmabuf->file->f_count.counter); pa_buffer_free(buffer); } static void *pa_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) { struct pa_buffer *buffer = dmabuf->priv; return buffer->vaddr + offset * PAGE_SIZE; } static void pa_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *ptr) { } static int pa_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) size_t start, size_t len, #endif enum dma_data_direction direction) { struct pa_buffer *buffer = dmabuf->priv; void *vaddr = NULL; mutex_lock(&buffer->lock); vaddr = buffer->vaddr; if (!buffer->kmap_cnt) { struct sg_table *table = buffer->sg_table; int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; struct page **pages = vmalloc(sizeof(struct page *) * npages); struct page **tmp = pages; if (pages) { int i, j; struct scatterlist *sg; pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); for_each_sg(table->sgl, sg, table->nents, i) { int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; struct page *page = sg_page(sg); BUG_ON(i >= npages); for (j = 0; j < npages_this_entry; j++) *(tmp++) = page++; } vaddr = vmap(pages, npages, VM_MAP, pgprot); vfree(pages); } } if (!IS_ERR_OR_NULL(vaddr)) { buffer->vaddr = vaddr; buffer->kmap_cnt++; } mutex_unlock(&buffer->lock); if (IS_ERR(vaddr)) return PTR_ERR(vaddr); if (!vaddr) return -ENOMEM; return 0; } static #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) int #else void #endif pa_dma_buf_end_cpu_access(struct dma_buf *dmabuf, #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) size_t start, size_t len, #endif enum dma_data_direction direction) { struct pa_buffer *buffer = dmabuf->priv; mutex_lock(&buffer->lock); if (!--buffer->kmap_cnt) { vunmap(buffer->vaddr); buffer->vaddr = NULL; } mutex_unlock(&buffer->lock); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) return 0; #endif } static void *pa_dma_buf_vmap(struct dma_buf *dmabuf) { struct pa_buffer *buffer = dmabuf->priv; pa_dma_buf_begin_cpu_access(dmabuf, #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) 0, 0, #endif 0); return buffer->vaddr; } static void pa_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) { printk("%s: dmabuf %p vaddr %p\n", __FUNCTION__, dmabuf, vaddr); } static struct dma_buf_ops dma_buf_ops = { .map_dma_buf = pa_dma_buf_map, .unmap_dma_buf = pa_dma_buf_unmap, .mmap = pa_dma_buf_mmap, .release = pa_dma_buf_release, .begin_cpu_access = pa_dma_buf_begin_cpu_access, .end_cpu_access = pa_dma_buf_end_cpu_access, #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)) .kmap_atomic = pa_dma_buf_kmap, .kunmap_atomic = pa_dma_buf_kunmap, .kmap = pa_dma_buf_kmap, .kunmap = pa_dma_buf_kunmap, #else #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) && !(defined(RHEL_MAJOR) && RHEL_MAJOR >= 8) .map_atomic = pa_dma_buf_kmap, .unmap_atomic = pa_dma_buf_kunmap, #endif #if !(defined(RHEL_MAJOR) && RHEL_MAJOR >= 8) .map = pa_dma_buf_kmap, .unmap = pa_dma_buf_kunmap, #endif #endif .vmap = pa_dma_buf_vmap, .vunmap = pa_dma_buf_vunmap, }; int portalmem_dmabuffer_destroy(int fd) { struct file *fmem = fget(fd); pa_dma_buf_release(fmem->private_data); //printk("%s:%d: fput fd=%d fmem=%p\n", __FUNCTION__, __LINE__, fd, fmem); fput(fmem); return 0; } int portalmem_dmabuffer_create(PortalAlloc portalAlloc) { static const unsigned int orders[] = {8, 4, 0}; unsigned int allocated_orders[] = {0,0,0}; struct pa_buffer *buffer; struct sg_table *table; struct scatterlist *sg; struct list_head pages; struct page_info { struct page *page; unsigned long order; struct list_head list; } *info = NULL, *tmp_info; unsigned int max_order = orders[0]; long size_remaining; int infocount = 0; size_t align = 4096; size_t len = portalAlloc.len; int return_fd; unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY ); unsigned int low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN); #ifdef __GFP_NO_KSWAPD high_order_gfp_flags |= __GFP_NO_KSWAPD; #endif #ifdef __GFP_WAIT high_order_gfp_flags &= ~__GFP_WAIT; #endif printk("%s, size=%ld cached=%d\n", __FUNCTION__, (long)portalAlloc.len, portalAlloc.cached); len = PAGE_ALIGN(round_up(len, align)); size_remaining = len; buffer = kzalloc(sizeof(struct pa_buffer), GFP_KERNEL); if (!buffer) return -ENOMEM; buffer->cached = portalAlloc.cached; table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); if (!table) { kfree(buffer); return -ENOMEM; } INIT_LIST_HEAD(&pages); while (size_remaining > 0) { int ordindex = 0; info = NULL; for (; ordindex < ARRAY_SIZE(orders); ordindex++) { gfp_t gfp_flags = low_order_gfp_flags; if (orders[ordindex] > 4) gfp_flags = high_order_gfp_flags; if (size_remaining >= (PAGE_SIZE << orders[ordindex]) && max_order >= orders[ordindex]) { struct page *page = alloc_pages(gfp_flags, orders[ordindex]); if (page) { info = kmalloc(sizeof(*info), GFP_KERNEL); info->page = page; info->order = orders[ordindex]; list_add_tail(&info->list, &pages); size_remaining -= (1 << info->order) * PAGE_SIZE; max_order = info->order; infocount++; allocated_orders[ordindex] += 1; //printk("%s, alloc_pages succeeded with order=%d\n", __FUNCTION__, orders[ordindex]); break; } else { //printk("%s, alloc_pages failed with order=%d\n", __FUNCTION__, orders[ordindex]); } } //printk("%s, alloc_pages skipping order=%d\n", __FUNCTION__, orders[ordindex]); } if (!info) break; } printk("%s orders_allocated %d:%d, %d:%d, %d:%d\n", __FUNCTION__, orders[0], allocated_orders[0],orders[1], allocated_orders[1],orders[2], allocated_orders[2]); if (info) { int ret = sg_alloc_table(table, infocount, GFP_KERNEL); if (!ret) { struct dma_buf *dmabuf; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) || LINUX_VERSION_CODE == KERNEL_VERSION(3,10,0)) struct dma_buf_export_info export_info = { .exp_name = "portalmem", }; #endif sg = table->sgl; list_for_each_entry_safe(info, tmp_info, &pages, list) { struct page *page = info->page; sg_set_page(sg, page, (1 << info->order) * PAGE_SIZE, 0); sg = sg_next(sg); list_del(&info->list); kfree(info); } if (IS_ERR_OR_NULL(table)) { pa_buffer_free(buffer); return PTR_ERR(table); } buffer->sg_table = table; buffer->size = len; mutex_init(&buffer->lock); /* this will set up dma addresses for the sglist -- it is not technically correct as per the dma api -- a specific device isn't really taking ownership here. However, in practice on our systems the only dma_address space is physical addresses. Additionally, we can't afford the overhead of invalidating every allocation via dma_map_sg. The implicit contract here is that memory is ready for dma, ie if it has a cached mapping that mapping has been invalidated */ for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, infocount){ #ifdef __arm__ unsigned int length = sg->length; dma_addr_t start_addr = sg_phys(sg); dma_addr_t end_addr = start_addr+length; outer_clean_range(start_addr, end_addr); outer_inv_range(start_addr, end_addr); #endif sg_dma_address(sg) = sg_phys(sg); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) || LINUX_VERSION_CODE == KERNEL_VERSION(3,10,0)) export_info.ops = &dma_buf_ops; export_info.size = len; export_info.flags = O_RDWR; export_info.priv = buffer; dmabuf = dma_buf_export(&export_info); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) dmabuf = dma_buf_export(buffer, &dma_buf_ops, len, O_RDWR , NULL); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) dmabuf = dma_buf_export(buffer, &dma_buf_ops, len, O_RDWR); #else #error no dma_buf support known for this kernel version #endif if (IS_ERR(dmabuf)) pa_buffer_free(buffer); printk("pa_get_dma_buf fmem=%p count=%ld\n", dmabuf->file, (unsigned long)dmabuf->file->f_count.counter); return_fd = dma_buf_fd(dmabuf, O_CLOEXEC); if (return_fd < 0) dma_buf_put(dmabuf); return return_fd; } kfree(table); } list_for_each_entry(info, &pages, list) { free_buffer_page(info->page, info->order); kfree(info); } kfree(buffer); return -ENOMEM; } /* * driver file operations */ static long pa_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { switch (cmd) { case PA_MALLOC: { struct PortalAlloc portalAlloc; if (copy_from_user(&portalAlloc, (void __user *)arg, sizeof(portalAlloc))) return -EFAULT; return portalmem_dmabuffer_create(portalAlloc); } case PA_ELEMENT_SIZE: { struct PortalElementSize req; struct file *fmem; struct sg_table *sgtable; struct scatterlist *sg; int i = 0; int retsize = 0; // 0 -> end of sglist items if (copy_from_user(&req, (void __user *)arg, sizeof(req))) return -EFAULT; fmem = fget(req.fd); //printk("%s:%d: fget fd=%d fmem=%p\n", __FUNCTION__, __LINE__, req.fd, fmem); sgtable = ((struct pa_buffer *)((struct dma_buf *)fmem->private_data)->priv)->sg_table; for_each_sg(sgtable->sgl, sg, sgtable->nents, i) { if (i == req.index) { retsize = sg->length; break; } } //printk("%s:%d: fput fd=%d fmem=%p\n", __FUNCTION__, __LINE__, req.fd, fmem); fput(fmem); return retsize; } default: printk("pa_unlocked_ioctl ENOTTY cmd=%x\n", cmd); return -ENOTTY; } return -ENODEV; } static struct file_operations pa_fops = { .owner = THIS_MODULE, .unlocked_ioctl = pa_unlocked_ioctl }; /* * driver initialization and exit */ static int __init pa_init(void) { struct miscdevice *md = &miscdev; printk("PortalAlloc::pa_init\n"); md->minor = MISC_DYNAMIC_MINOR; md->name = "portalmem"; md->fops = &pa_fops; md->parent = NULL; misc_register(md); return 0; } static void __exit pa_exit(void) { struct miscdevice *md = &miscdev; printk("PortalAlloc::pa_exit\n"); misc_deregister(md); } EXPORT_SYMBOL(portalmem_dmabuffer_create); EXPORT_SYMBOL(portalmem_dmabuffer_destroy); module_init(pa_init); module_exit(pa_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION(DRIVER_DESCRIPTION); MODULE_VERSION(DRIVER_VERSION); ================================================ FILE: drivers/portalmem/portalmem.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * Copyright (c) 2015 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef __PORTALALLOC_H__ #define __PORTALALLOC_H__ typedef struct DmaEntry { long dma_address; unsigned int length; // to match length field in scatterlist.h } DmaEntry; typedef struct PortalAlloc { size_t len; int cached; } PortalAlloc; typedef struct PortalElementSize { int fd; int index; } PortalElementSize; typedef struct { int index; /* in param */ char md5[33]; /* out param -- asciz */ char filename[33]; /* out param -- asciz */ } PortalSignatureMem; #define PA_MALLOC _IOR('B', 14, PortalAlloc) #define PA_ELEMENT_SIZE _IOR('B', 15, PortalElementSize) #define PA_SIGNATURE _IOR('B', 20, PortalSignatureMem) /** * struct pa_buffer - metadata for a particular buffer * @size: size of the buffer * @lock: protects the buffers cnt fields * @kmap_cnt: number of times the buffer is mapped to the kernel * @vaddr: the kenrel mapping if kmap_cnt is not zero * @sg_table: the sg table for the buffer */ #ifdef __KERNEL__ struct pa_buffer { size_t size; struct mutex lock; int kmap_cnt; int cached; void *vaddr; struct sg_table *sg_table; }; int portalmem_dmabuffer_create(struct PortalAlloc arg); int portalmem_dmabuffer_destroy(int fd); #endif #endif /* __PORTALALLOC_H__ */ ================================================ FILE: drivers/zynqportal/Makefile ================================================ V?=0 ifeq ($(V),0) Q=@ else Q= endif CONNECTALDIR ?= $(PWD)/../.. include $(CONNECTALDIR)/Makefile.version obj-m += zynqportal.o DEFCONFIG?=xilinx_zynq_portal_atheros_sdio_defconfig CROSS_COMPILE?=arm-linux-gnueabi- KROOT?=$(CONNECTALDIR)/../linux-xlnx ccflags-y := -I$(src)/../portalmem -I$(src)/../../cpp -I$(PWD)/../.. -I$(src)/../../generated/cpp \ -DDRIVER_VERSION="\"$(VERSION)\"" zynqportal.ko: zynqportal.h zynqportal.c echo "$(VERSION)" $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) $(DEFCONFIG) $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) oldconfig $(Q)$(MAKE) -j 8 ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) zImage $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) modules parallellazynqportal.ko: zynqportal.h zynqportal.c echo "$(VERSION)" $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) parallella_defconfig $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) oldconfig $(Q)$(MAKE) -j 8 ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) LOADADDR=0x8000 uImage $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) modules clean: $(Q)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KROOT) M=$(PWD) clean ================================================ FILE: drivers/zynqportal/zynqportal.c ================================================ /* * Generic bridge to memory-mapped hardware * * Author: Jamey Hicks * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */ #define DEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __arm__ #include // cache_flush_all #include // outer_flush_* #endif #include "zynqportal.h" #define CONNECTAL_DRIVER_CODE #include "../../cpp/dmaSendFd.h" #include "../../cpp/portalKernel.h" #define DRIVER_NAME "zynqportal" #define DRIVER_DESCRIPTION "Generic userspace hardware bridge" #define STATUS_OFFSET 0x000 #define MASK_OFFSET 0x004 #define NUM_TILES_OFFSET 0x008 #define IID_OFFSET 0x010 #define NUM_PORTALS_OFFSET 0x014 #define MSB_OFFSET 0x018 #define LSB_OFFSET 0x01C #define MAX_NUM_PORTALS 16 #define MAX_NUM_TILES 2 #ifdef DEBUG // was KERN_DEBUG #define driver_devel(format, ...) \ do { \ printk(format, ## __VA_ARGS__); \ } while (0) #else #define driver_devel(format, ...) #endif struct pmentry { struct file *fmem; int id; struct list_head pmlist; }; struct portal_data { struct miscdevice misc; // use container_of to get (struct portal_data *) from (struct miscdevice *) wait_queue_head_t wait_queue; dma_addr_t dev_base_phys; void *map_base; char name[128]; char irqname[128]; struct list_head pmlist;; }; struct connectal_data{ struct miscdevice misc; /* must be first element (pointer passed to misc_register) */ unsigned int portal_irq; struct portal_data portald[MAX_NUM_TILES][MAX_NUM_PORTALS + 1]; }; static DEFINE_MUTEX(connectal_mutex); /* anyone should be able to get PORTAL_DIRECTORY_COUNTER */ // FIXME: directory_virt = ws.portal_data; #define DIRECTORY_VIRT ((void *)ws.connectal_data->portald[0]) static PortalInterruptTime inttime; static int flush = 0; static struct { struct connectal_data *connectal_data; } ws; static struct workqueue_struct *wq = 0; static void connectal_work_handler(struct work_struct *__xxx); static DECLARE_DELAYED_WORK(connectal_work, connectal_work_handler); /* * Local helper functions */ static irqreturn_t portal_isr(int irq, void *dev_id) { // request_irq used the portal_data pointer as dev_id; struct portal_data *portal_data = (struct portal_data *)dev_id; irqreturn_t rc = IRQ_NONE; //driver_devel("%s %s %d %p\n", __func__, portal_data->misc.name, irq, dev_id); if (portal_data->name[0] && readl((void *)(STATUS_OFFSET + (unsigned long) portal_data->map_base))) { inttime.msb = readl(DIRECTORY_VIRT + MSB_OFFSET); inttime.lsb = readl(DIRECTORY_VIRT + LSB_OFFSET); // disable interrupt. this will be re-enabled by user mode // driver after all the HW->SW FIFOs have been emptied writel(0, (void *)(MASK_OFFSET + (unsigned long) portal_data->map_base)); wake_up_interruptible(&portal_data->wait_queue); rc = IRQ_HANDLED; } return rc; } /* * file_operations functions */ static int portal_open(struct inode *inode, struct file *filep) { struct portal_data *portal_data = container_of((struct miscdevice *)filep->private_data, struct portal_data, misc); init_waitqueue_head(&portal_data->wait_queue); return 0; } long portal_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { struct portal_data *portal_data = container_of((struct miscdevice *)filep->private_data, struct portal_data, misc); switch (cmd) { case PORTAL_SET_FCLK_RATE: { PortalClockRequest request; char clkname[32]; int status = 0; struct clk *fclk = NULL; if (copy_from_user(&request, (void __user *)arg, sizeof(request))) return -EFAULT; #if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) snprintf(clkname, sizeof(clkname), "FPGA%d", request.clknum); fclk = clk_get_sys(clkname, NULL); #else snprintf(clkname, sizeof(clkname), "fclk%d", request.clknum); fclk = clk_get(portal_data->misc.this_device, clkname); #endif printk(KERN_INFO "[%s:%d] fclk %s %p\n", __FUNCTION__, __LINE__, clkname, fclk); if (IS_ERR_OR_NULL(fclk)) return -ENODEV; request.actual_rate = clk_round_rate(fclk, request.requested_rate); printk(KERN_INFO "%s requested rate %ld actual rate %ld\n", __FUNCTION__, request.requested_rate, request.actual_rate); if ((status = clk_set_rate(fclk, request.actual_rate))) { printk(KERN_INFO "[%s:%d] err\n", __FUNCTION__, __LINE__); return status; } if (copy_to_user((void __user *)arg, &request, sizeof(request))) return -EFAULT; return 0; } break; case PORTAL_SEND_FD: { /* pushd down allocated fd */ PortalSendFd sendFd; struct pmentry *pmentry; PortalInternal devptr = {.map_base = portal_data->map_base, .transport=&kernelfunc}; int err = copy_from_user(&sendFd, (void __user *) arg, sizeof(sendFd)); if (err) break; printk("[%s:%d] PORTAL_SEND_FD fd 0x%x id 0x%x **\n", __FUNCTION__, __LINE__, sendFd.fd, sendFd.id); pmentry = (struct pmentry *)kzalloc(sizeof(struct pmentry), GFP_KERNEL); if (!pmentry) return -EFAULT; INIT_LIST_HEAD(&pmentry->pmlist); mutex_lock(&connectal_mutex); pmentry->fmem = fget(sendFd.fd); pmentry->id = sendFd.id; list_add(&pmentry->pmlist, &portal_data->pmlist); err = send_fd_to_portal(&devptr, sendFd.fd, sendFd.id, 0); mutex_unlock(&connectal_mutex); if (err < 0) break; return 0; } case PORTAL_DEREFERENCE: { int id = arg; struct list_head *pmlist, *n; PortalInternal devptr = {.map_base = portal_data->map_base, .transport=&kernelfunc}; MMURequest_idReturn(&devptr, id); list_for_each_safe(pmlist, n, &portal_data->pmlist) { struct pmentry *pmentry = list_entry(pmlist, struct pmentry, pmlist); if (pmentry->id == id) { printk("%s:%d releasing portalmem object %d fmem=%p\n", __FUNCTION__, __LINE__, id, pmentry->fmem); fput(pmentry->fmem); list_del(&pmentry->pmlist); kfree(pmentry); return 0; } } return -ENOENT; } break; case PORTAL_DCACHE_FLUSH_INVAL: { flush = 1; } // fall through case PORTAL_DCACHE_INVAL: { struct scatterlist *sg; PortalCacheRequest cacheReq; struct file *fmem; struct dma_buf *dma_buf; struct pa_buffer *pa_buffer; struct sg_table *sgtable; long offset = 0; int i; int verbose_flush = 0; void *virt; long flush_offset; long flush_length; int err; if (verbose_flush) printk("[%s:%d] portal dcache flush=%d\n", __FUNCTION__, __LINE__, flush); err = copy_from_user(&cacheReq, (void __user *) arg, sizeof(cacheReq)); if (err) break; if (verbose_flush) printk("[%s:%d] portal fd %d\n", __FUNCTION__, __LINE__, cacheReq.fd); fmem = fget(cacheReq.fd); if (verbose_flush) printk("[%s:%d] portal fmem %p\n", __FUNCTION__, __LINE__, fmem); if (!fmem) { printk("[%s:%d] invalid fd %d\n", __FUNCTION__, __LINE__, cacheReq.fd); return -EINVAL; } dma_buf = (struct dma_buf *)fmem->private_data; if (verbose_flush) printk("[%s:%d] portal dma_buf %p\n", __FUNCTION__, __LINE__, dma_buf); pa_buffer = ((struct pa_buffer *)(dma_buf)->priv); if (verbose_flush) printk("[%s:%d] portal pa_buffer %p\n", __FUNCTION__, __LINE__, pa_buffer); sgtable = pa_buffer->sg_table; if (verbose_flush) printk("[%s:%d] portal sgtable %p\n", __FUNCTION__, __LINE__, sgtable); virt = pa_buffer->vaddr; flush_offset = cacheReq.base - virt; flush_length = cacheReq.len; if (verbose_flush) printk("[%s:%d] fd %d flush %d base %p virt %p flush_offset %lx flush_length %lx\n", __FUNCTION__, __LINE__, cacheReq.fd, flush, cacheReq.base, virt, flush_offset, flush_length); flush_cache_all(); for_each_sg(sgtable->sgl, sg, sgtable->nents, i) { unsigned int length = sg->length; dma_addr_t start_addr = sg_phys(sg); dma_addr_t end_addr = start_addr+length; long end_offset = offset + length; if (flush_length && offset <= flush_offset && flush_offset < end_offset) { long delta = (flush_offset - offset); start_addr += delta; length -= delta; if (flush_length < length) { if (verbose_flush) printk("last segment: adjusting end_addr\n"); end_addr = start_addr + flush_length; } if (verbose_flush) { printk("[%s:%d] start %lx end %lx len %lx delta %lx flush_length %lx\n", __FUNCTION__, __LINE__, (long)start_addr, (long)end_addr, (long)length, (long)delta, flush_length); printk("[%s:%d] start_offset %lx end_offset %lx flush_offset %lx\n", __FUNCTION__, __LINE__, offset, end_offset, flush_offset); } #ifdef __arm__ if (flush) { //flush_user_range(virt, virt+length, 0); outer_flush_range(start_addr, end_addr); } else { outer_inv_range(start_addr, end_addr); } #endif flush_offset += length; flush_length -= length; } offset += sg->length; } fput(fmem); flush = 0; return 0; } case PORTAL_DIRECTORY_READ: return readl(DIRECTORY_VIRT + arg); case PORTAL_INTERRUPT_TIME: if (copy_to_user((void __user *)arg, &inttime, sizeof(inttime))) return -EFAULT; return 0; default: printk("portal_unlocked_ioctl ENOTTY cmd=%x\n", cmd); return -ENOTTY; } return -ENODEV; } int portal_mmap(struct file *filep, struct vm_area_struct *vma) { struct portal_data *portal_data = container_of((struct miscdevice *)filep->private_data, struct portal_data, misc); if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_pgoff = portal_data->dev_base_phys >> PAGE_SHIFT; vma->vm_flags |= VM_IO; #if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) vma->vm_flags |= VM_RESERVED; #endif if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; } unsigned int portal_poll (struct file *filep, poll_table *poll_table) { struct portal_data *portal_data = container_of((struct miscdevice *)filep->private_data, struct portal_data, misc); poll_wait(filep, &portal_data->wait_queue, poll_table); if (readl((void *)(STATUS_OFFSET + (unsigned long) portal_data->map_base))) return POLLIN | POLLRDNORM; /* when we wake up, always return back to user */ return 0; } static int portal_release(struct inode *inode, struct file *filep) { struct portal_data *portal_data = container_of((struct miscdevice *)filep->private_data, struct portal_data, misc); PortalInternal devptr = {.map_base = portal_data->map_base, .transport=&kernelfunc}; struct list_head *pmlist; driver_devel("%s inode=%p filep=%p\n", __func__, inode, filep); if (portal_data->name[0]) { // disable interrupt writel(0, (void *)(STATUS_OFFSET + (unsigned long) portal_data->map_base)); } init_waitqueue_head(&portal_data->wait_queue); list_for_each(pmlist, &portal_data->pmlist) { struct pmentry *pmentry = list_entry(pmlist, struct pmentry, pmlist); printk(" returning id=%d fmem=%p\n", pmentry->id, pmentry->fmem); MMURequest_idReturn(&devptr, pmentry->id); fput(pmentry->fmem); kfree(pmentry); } INIT_LIST_HEAD(&portal_data->pmlist); return 0; } static const struct file_operations portal_fops = { .owner = THIS_MODULE, .open = portal_open, .mmap = portal_mmap, .unlocked_ioctl = portal_unlocked_ioctl, .poll = portal_poll, .release = portal_release, }; static int remove_portal_devices(struct connectal_data *connectal_data) { int fpn, t; for(t = 0; t < MAX_NUM_TILES; t++) for (fpn = 0; fpn < MAX_NUM_PORTALS; fpn++) { if (connectal_data->portald[t][fpn].name[0]) misc_deregister(&connectal_data->portald[t][fpn].misc); connectal_data->portald[t][fpn].name[0] = 0; } return 0; } // this is called with connectal_mutex locked static void connectal_work_handler(struct work_struct *__xxx) { int num_tiles = 0, num_portals = 0, fpn, t = 0; struct device_node *of_node = ws.connectal_data->misc.this_device->of_node; remove_portal_devices(ws.connectal_data); do{ fpn = 0; do { int rc; struct portal_data *portal_data = &ws.connectal_data->portald[t][fpn]; if(fpn==0){ num_portals = readl(portal_data->map_base+NUM_PORTALS_OFFSET); if(t==0) num_tiles = readl(portal_data->map_base+NUM_TILES_OFFSET); } else { if(num_portals != readl(portal_data->map_base+NUM_PORTALS_OFFSET)) driver_devel("%s: num_portals mismatch. Expected %d read %d\n", __func__, num_portals, readl(portal_data->map_base+NUM_PORTALS_OFFSET));; if(num_tiles != readl(portal_data->map_base+NUM_TILES_OFFSET)) driver_devel("%s: num_tiles mismatch. Expected %d read %d\n", __func__, num_tiles, readl(portal_data->map_base+NUM_TILES_OFFSET));; } sprintf(portal_data->name, "portal_b%dt%dp%d", 0, t, readl(portal_data->map_base+IID_OFFSET)); driver_devel("%s: t=%d fpn=%08x top=%d name=%s\n", __func__, t, fpn, fpn==num_portals, portal_data->misc.name); portal_data->misc.minor = MISC_DYNAMIC_MINOR; rc = misc_register( &portal_data->misc); portal_data->misc.this_device->of_node = of_node; driver_devel("%s: rc=%d minor=%d\n", __func__, rc, portal_data->misc.minor); if (fpn+1==num_portals) break; fpn++; } while (fpn < num_portals && fpn < MAX_NUM_PORTALS); if (fpn > MAX_NUM_PORTALS - 1) { printk(KERN_INFO "%s: MAX_NUM_PORTALS exceeded", __func__); } t++; } while (t < num_tiles && t < MAX_NUM_TILES); mutex_unlock(&connectal_mutex); } static int connectal_open(struct inode *inode, struct file *filep) { driver_devel("%s:%d\n", __func__, __LINE__); mutex_lock(&connectal_mutex); queue_delayed_work(wq, &connectal_work, msecs_to_jiffies(0)); return 0; } long connectal_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { switch (cmd) { #ifdef CONFIG_CLKDEV_LOOKUP case PORTAL_SET_FCLK_RATE: { PortalClockRequest request; char clkname[32]; int status = 0; struct clk *fclk = NULL; if (copy_from_user(&request, (void __user *)arg, sizeof(request))) return -EFAULT; snprintf(clkname, sizeof(clkname), "FPGA%d", request.clknum); fclk = clk_get_sys(clkname, NULL); printk(KERN_INFO "[%s:%d] fclk %s %p\n", __FUNCTION__, __LINE__, clkname, fclk); if (!fclk) return -ENODEV; request.actual_rate = clk_round_rate(fclk, request.requested_rate); printk(KERN_INFO "%s requested rate %ld actual rate %ld\n", __FUNCTION__, request.requested_rate, request.actual_rate); if ((status = clk_set_rate(fclk, request.actual_rate))) { printk(KERN_INFO "[%s:%d] err\n", __FUNCTION__, __LINE__); return status; } if (copy_to_user((void __user *)arg, &request, sizeof(request))) return -EFAULT; return 0; } break; #endif case PORTAL_DCACHE_FLUSH_INVAL: { flush = 1; } // fall through case PORTAL_DCACHE_INVAL: { struct scatterlist *sg; PortalCacheRequest cacheReq; struct file *fmem; struct pa_buffer *pa_buffer; struct sg_table *sgtable; long offset = 0; int i; int verbose_flush = 0; void *virt; long flush_offset; long flush_length; int err = copy_from_user(&cacheReq, (void __user *) arg, sizeof(cacheReq)); if (err) break; if (verbose_flush) printk("[%s:%d] portal fd %d\n", __FUNCTION__, __LINE__, cacheReq.fd); fmem = fget(cacheReq.fd); pa_buffer = ((struct pa_buffer *)((struct dma_buf *)fmem->private_data)->priv); sgtable = pa_buffer->sg_table; virt = pa_buffer->vaddr; flush_offset = cacheReq.base - virt; flush_length = cacheReq.len; if (verbose_flush) printk("[%s:%d] fd %d flush %d base %p virt %p flush_offset %lx flush_length %lx\n", __FUNCTION__, __LINE__, cacheReq.fd, flush, cacheReq.base, virt, flush_offset, flush_length); flush_cache_all(); for_each_sg(sgtable->sgl, sg, sgtable->nents, i) { unsigned int length = sg->length; dma_addr_t start_addr = sg_phys(sg); dma_addr_t end_addr = start_addr+length; long end_offset = offset + length; if (flush_length && offset <= flush_offset && flush_offset < end_offset) { long delta = (flush_offset - offset); start_addr += delta; length -= delta; if (flush_length < length) { printk("last segment: adjusting end_addr\n"); end_addr = start_addr + flush_length; } if (verbose_flush) { printk("[%s:%d] start %lx end %lx len %lx delta %lx flush_length %lx\n", __FUNCTION__, __LINE__, (long)start_addr, (long)end_addr, (long)length, (long)delta, flush_length); printk("[%s:%d] start_offset %lx end_offset %lx flush_offset %lx\n", __FUNCTION__, __LINE__, offset, end_offset, flush_offset); } #ifdef __arm__ if (flush) { //flush_user_range(virt, virt+length, 0); outer_flush_range(start_addr, end_addr); } else { outer_inv_range(start_addr, end_addr); } #endif flush_offset += length; flush_length -= length; } offset += sg->length; } fput(fmem); flush = 0; return 0; } default: printk("portal_unlocked_ioctl ENOTTY cmd=%x\n", cmd); return -ENOTTY; } return -ENODEV; } static ssize_t connectal_read(struct file *filp, char *buffer, size_t length, loff_t *offset) { driver_devel("%s:%d\n", __func__, __LINE__); mutex_lock(&connectal_mutex); mutex_unlock(&connectal_mutex); return 0; } static const struct file_operations connectal_fops = { .owner = THIS_MODULE, .open = connectal_open, .read = connectal_read, .unlocked_ioctl = connectal_unlocked_ioctl, }; static int connectal_of_probe(struct platform_device *pdev) { u32 size; int rc, fpn, t = 0; struct connectal_data *connectal_data; const char *dname = (char *)of_get_property(pdev->dev.of_node, "device-name", &size); struct resource *reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!dname || !reg_res || !irq_res) { pr_err("%s: Error getting device-name or resources\n", DRIVER_NAME); return -EINVAL; } wq = create_singlethread_workqueue("connectal"); if (!wq) { pr_err("Error creating workqueue\n"); return -EINVAL; } mutex_lock(&connectal_mutex); connectal_data = kzalloc(sizeof(struct connectal_data), GFP_KERNEL); connectal_data->misc.name = dname; connectal_data->misc.minor = MISC_DYNAMIC_MINOR; connectal_data->misc.fops = &connectal_fops; connectal_data->portal_irq = irq_res->start; rc = misc_register(&connectal_data->misc); connectal_data->misc.this_device->of_node = pdev->dev.of_node; driver_devel("%s: name=%s rc=%d minor=%d\n", __func__, connectal_data->misc.name, rc, connectal_data->misc.minor); dev_set_drvdata(&pdev->dev, connectal_data); ws.connectal_data = connectal_data; for(t = 0; t < MAX_NUM_TILES; t++) for (fpn = 0; fpn < MAX_NUM_PORTALS; fpn++) { struct portal_data *portal_data = &connectal_data->portald[t][fpn]; portal_data->dev_base_phys = reg_res->start+((t * TILE_BASE_OFFSET)+(fpn*PORTAL_BASE_OFFSET)); portal_data->map_base = ioremap_nocache(portal_data->dev_base_phys, PORTAL_BASE_OFFSET); portal_data->misc.name = portal_data->name; portal_data->misc.fops = &portal_fops; INIT_LIST_HEAD(&portal_data->pmlist); sprintf(portal_data->irqname, "zynqportal_b%dt%dp%d", 0, t, fpn); if (request_irq(connectal_data->portal_irq, portal_isr, IRQF_TRIGGER_HIGH | IRQF_SHARED , portal_data->irqname, portal_data)) { printk("%s Failed to register irq\n", __func__); } } mutex_unlock(&connectal_mutex); return 0; } static int connectal_of_remove(struct platform_device *pdev) { int fpn, t = 0; struct connectal_data* connectal_data = dev_get_drvdata(&pdev->dev); driver_devel("%s: %s\n",__FUNCTION__, pdev->name); mutex_lock(&connectal_mutex); for(t = 0; t < MAX_NUM_TILES; t++) for (fpn = 0; fpn < MAX_NUM_PORTALS; fpn++) free_irq(connectal_data->portal_irq, &connectal_data->portald[t][fpn]); remove_portal_devices(connectal_data); misc_deregister(&connectal_data->misc); dev_set_drvdata(&pdev->dev, NULL); cancel_delayed_work_sync(&connectal_work); destroy_workqueue(wq); kfree(connectal_data); mutex_unlock(&connectal_mutex); return 0; } static struct of_device_id connectal_of_match[] #if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) __devinitdata #endif = { { .compatible = "linux,ushw-bridge-0.01.a" }, /* old name */ { .compatible = "linux,portal-0.01.a" }, {/* end of table */}, }; MODULE_DEVICE_TABLE(of, connectal_of_match); static struct platform_driver connectal_of_driver = { .probe = connectal_of_probe, .remove = connectal_of_remove, .driver = { .owner = THIS_MODULE, .name = DRIVER_NAME, .of_match_table = connectal_of_match, }, }; /* * Module functions */ static int __init connectal_of_init(void) { if (platform_driver_register(&connectal_of_driver)) { pr_err("Error portal driver registration\n"); return -ENODEV; } return 0; } static void __exit connectal_of_exit(void) { platform_driver_unregister(&connectal_of_driver); } #ifndef MODULE late_initcall(connectal_of_init); #else module_init(connectal_of_init); module_exit(connectal_of_exit); #endif MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION(DRIVER_DESCRIPTION); MODULE_VERSION(DRIVER_VERSION); ================================================ FILE: drivers/zynqportal/zynqportal.h ================================================ /* * Generic userspace hardware bridge * * Author: Jamey Hicks * * 2012 (c) Jamey Hicks * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */ #ifndef __PORTAL_H__ #define __PORTAL_H__ typedef struct { int clknum; long requested_rate; long actual_rate; } PortalClockRequest; typedef struct { int fd; int id; } PortalSendFd; typedef struct { uint32_t msb; uint32_t lsb; } PortalInterruptTime; typedef struct { int fd; void *base; size_t len; } PortalCacheRequest; typedef struct { int index; /* in param */ char md5[33]; /* out param -- asciz */ char filename[33]; /* out param -- asciz */ } PortalSignature; #define PORTAL_SET_FCLK_RATE _IOWR('B', 40, PortalClockRequest) #define PORTAL_SEND_FD _IOR('B', 42, PortalSendFd) #define PORTAL_DCACHE_FLUSH_INVAL _IOR('B', 43, PortalCacheRequest) #define PORTAL_DIRECTORY_READ _IOR('B', 44, unsigned long) #define PORTAL_INTERRUPT_TIME _IOR('B', 45, PortalInterruptTime) #define PORTAL_DCACHE_INVAL _IOR('B', 46, PortalCacheRequest) #define PORTAL_DEREFERENCE _IOR('B', 47, int) #define PORTAL_SIGNATURE _IOR('B', 47, PortalSignature) #endif /* __PORTAL_H__ */ ================================================ FILE: etc/modules-load.d/connectal.conf ================================================ portalmem ================================================ FILE: etc/udev/rules.d/51-connectaltty.rules ================================================ # For Ubuntu 12.04 # zedboard SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="0008", MODE="0666", OWNER="jenkins" KERNEL=="ttyACM*", ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="0008", MODE:="0666" # zc702 SUBSYSTEM=="usb", ATTR{idVendor}=="10c4", ATTR{idProduct}=="ea60", MODE="0666", OWNER="jenkins" KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666" # zybo SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE="0666", OWNER="jenkins" KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE:="0666" ================================================ FILE: etc/udev/rules.d/52-altera-usb.rules ================================================ # Allow users to access Altera Jtag device ACTION=="add", ATTR{idVendor}=="09fb", MODE:="666" ================================================ FILE: etc/udev/rules.d/52-connectaltest.rules ================================================ # # rule for connectal kernel test module # KERNEL=="connectaltest", MODE="0666" ================================================ FILE: etc/udev/rules.d/52-digilent-usb.rules ================================================ ########################################################################### # # # 52-digilent-usb.rules -- UDEV rules for Digilent USB Devices # # # ########################################################################### # Author: MTA # # Copyright 2010 Digilent Inc. # ########################################################################### # File Description: # # # # This file contains the rules used by UDEV when creating entries for # # Digilent USB devices. In order for Digilent's shared libraries and # # applications to access these devices without root privalages it is # # necessary for UDEV to create entries for which all users have read # # and write permission. # # # # Usage: # # # # Copy this file to "/etc/udev/rules.d/" and execute # # "/sbin/udevcontrol reload_rules" as root. This only needs to be done # # immediately after installation. Each time you reboot your system the # # rules are automatically loaded by UDEV. # # # ########################################################################### # Revision History: # # # # 04/15/2010(MTA): created # # 02/28/2011(MTA): modified to support FTDI based devices # # 07/10/2012(MTA): modified to work with UDEV versions 098 or newer # # 04/19/2013(MTA): modified mode assignment to use ":=" insetead of "=" # # so that our permission settings can't be overwritten by other # # rules files # # # ########################################################################### # Create "/dev" entries for Digilent device's with read and write # permission granted to all users. ATTR{idVendor}=="1443", MODE:="666" ACTION=="add", ATTR{idVendor}=="0403", ATTR{manufacturer}=="Digilent", MODE:="666", RUN+="/usr/local/sbin/dftdrvdtch %s{busnum} %s{devnum}" # The following rules (if present) cause UDEV to ignore all UEVENTS for # which the subsystem is "usb_endpoint" and the action is "add" or # "remove". These rules are necessary to work around what appears to be a # bug in the Kernel used by Red Hat Enterprise Linux 5/CentOS 5. The Kernel # sends UEVENTS to remove and then add entries for the endpoints of a USB # device in "/dev" each time a process releases an interface. This occurs # each time a data transaction occurs. When an FPGA is configured or flash # device is written a large number of transactions take place. If the # following lines are commented out then UDEV will be overloaded for a long # period of time while it tries to process the massive number of UEVENTS it # receives from the kernel. Please note that this work around only applies # to systems running RHEL5 or CentOS 5 and as a result the rules will only # be present on those systems. ================================================ FILE: etc/udev/rules.d/99-pcieportal.rules ================================================ # UDev rules for setting up Bluespec emulation device drivers ACTION=="add",SUBSYSTEM=="pci",ATTR{vendor}=="0x1be7", ATTR{device}="0xb100", RUN+="/sbin/modprobe -ba pcieportal portalmem" KERNEL=="portal*",MODE="666" KERNEL=="xdma*",MODE="666" KERNEL=="portalmem",MODE="666" KERNEL=="connectal",MODE="666" ================================================ FILE: examples/algo1_nandsim/Algo1NandSim.bsv ================================================ import GetPut::*; import Connectable::*; import Vector::*; import BuildVector::*; import ConnectalConfig::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import NandSim::*; import Strstr::*; interface Algo1NandSim; interface NandCfgRequest nandCfgRequest; interface MMURequest nandMMURequest; interface MemServerRequest nandMemServerRequest; interface StrstrRequest strstrRequest; interface Vector#(2, MemReadClient#(DataBusWidth)) dmaReadClients; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaWriteClients; endinterface module mkAlgo1NandSim#(NandCfgIndication nandCfgIndication, MMUIndication nandMMUIndication, MemServerIndication nandSimMemServerIndication, StrstrIndication strstrIndication)(Algo1NandSim); Strstr#(64,64) strstr <- mkStrstr(strstrIndication); NandSim nandSim <- mkNandSim(nandCfgIndication); MMU#(PhysAddrWidth) nandMMU <- mkMMU(0, False, nandMMUIndication); MemServer#(PhysAddrWidth,64,1) nandSimMemServer <- mkMemServer(strstr.haystack_read_client, nil, vec(nandMMU), nandSimMemServerIndication); let nandSimMemCnx <- mkConnection(nandSimMemServer.masters[0], nandSim.memSlave); // rule rl_readReq; // let req <- nandSimMemServer.masters[0].read_client.readReq.get(); // $display("rl_readReq addr=%h", req.addr); // nandSim.memSlave.read_server.readReq.put(req); // endrule // let readDataCnx <- mkConnection(nandSimMemServer.masters[0].read_client.readData, nandSim.memSlave.read_server.readData); // let writeReqCnx <- mkConnection(nandSimMemServer.masters[0].write_client.writeReq, nandSim.memSlave.write_server.writeReq); // let writeDataCnx <- mkConnection(nandSimMemServer.masters[0].write_client.writeData, nandSim.memSlave.write_server.writeData); // let writeDoneCnx <- mkConnection(nandSimMemServer.masters[0].write_client.writeDone, nandSim.memSlave.write_server.writeDone); interface dmaReadClients = append(nandSim.readClient, strstr.config_read_client); interface dmaWriteClients = nandSim.writeClient; interface nandCfgRequest = nandSim.request; interface nandMMURequest = nandMMU.request; interface strstrRequest = strstr.request; interface nandMemServerRequest = nandSimMemServer.request; endmodule ================================================ FILE: examples/algo1_nandsim/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = NandCfgRequest:Algo1NandSim.nandCfgRequest MMURequest:Algo1NandSim.nandMMURequest MemServerRequest:Algo1NandSim.nandMemServerRequest StrstrRequest:Algo1NandSim.strstrRequest H2S_INTERFACES = Algo1NandSim:NandCfgIndication,MMUIndication,MemServerIndication,StrstrIndication MEM_READ_INTERFACES = lAlgo1NandSim.dmaReadClients MEM_WRITE_INTERFACES = lAlgo1NandSim.dmaWriteClients BSVFILES = $(CONNECTALDIR)/lib/nandsim/bsv/NandSim.bsv $(CONNECTALDIR)/lib/strstr/bsv/Strstr.bsv Algo1NandSim.bsv CPPFILES=test.cpp nandsim.cpp CONNECTALFLAGS += -D ALGO_NANDSIM CONNECTALFLAGS += -D DEGPAR=2 CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/strstr/cpp CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/nandsim/cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/algo1_nandsim/nandsim.cpp ================================================ #include #include #include #include #include #include #include "portal.h" #include "dmaManager.h" #include "NandCfgRequest.h" #include "NandCfgIndication.h" class NandCfgIndication : public NandCfgIndicationWrapper { public: unsigned int rDataCnt; virtual void readDone(uint32_t v){ fprintf(stderr, "NandSim::readDone v=%x\n", v); sem_post(&sem); } virtual void writeDone(uint32_t v){ fprintf(stderr, "NandSim::writeDone v=%x\n", v); sem_post(&sem); } virtual void eraseDone(uint32_t v){ fprintf(stderr, "NandSim::eraseDone v=%x\n", v); sem_post(&sem); } virtual void configureNandDone(){ fprintf(stderr, "NandSim::configureNandDone\n"); sem_post(&sem); } NandCfgIndication(int id) : NandCfgIndicationWrapper(id) { sem_init(&sem, 0, 0); } void wait() { fprintf(stderr, "NandSim::wait for semaphore\n"); sem_wait(&sem); } private: sem_t sem; }; int initNandSim(DmaManager *hostDma) { NandCfgRequestProxy *nandcfgRequest = new NandCfgRequestProxy(IfcNames_NandCfgRequestS2H); NandCfgIndication *nandcfgIndication = new NandCfgIndication(IfcNames_NandCfgIndicationH2S); int nandBytes = 1 << 12; int nandAlloc = portalAlloc(nandBytes, 0); fprintf(stderr, "testnandsim::nandAlloc=%d\n", nandAlloc); int ref_nandAlloc = hostDma->reference(nandAlloc); fprintf(stderr, "ref_nandAlloc=%d\n", ref_nandAlloc); fprintf(stderr, "testnandsim::NAND alloc fd=%d ref=%d\n", nandAlloc, ref_nandAlloc); nandcfgRequest->configureNand(ref_nandAlloc, nandBytes); nandcfgIndication->wait(); const char *filename = "../test.bin"; fprintf(stderr, "testnandsim::opening %s\n", filename); // open up the text file and read it into an allocated memory buffer int data_fd = open(filename, O_RDONLY); if (data_fd < 0) { fprintf(stderr, "%s:%d failed to open file %s errno=%d:%s\n", __FUNCTION__, __LINE__, filename, errno, strerror(errno)); return 0; } off_t data_len = lseek(data_fd, 0, SEEK_END); fprintf(stderr, "%s:%d fd=%d data_len=%ld\n", __FUNCTION__, __LINE__, data_fd, data_len); data_len = data_len & ~15; // because we are using a burst length of 16 lseek(data_fd, 0, SEEK_SET); int dataAlloc = portalAlloc(data_len, 0); char *data = (char *)portalMmap(dataAlloc, data_len); ssize_t read_len = read(data_fd, data, data_len); if(read_len != data_len) { fprintf(stderr, "%s:%d::error reading %s %ld %ld\n", __FUNCTION__, __LINE__, filename, (long)data_len, (long) read_len); exit(-1); } int ref_dataAlloc = hostDma->reference(dataAlloc); // write the contents of data into "flash" memory portalCacheFlush(ref_dataAlloc, data, data_len, 1); fprintf(stderr, "testnandsim::invoking write %08x %08lx\n", ref_dataAlloc, (long)data_len); nandcfgRequest->startWrite(ref_dataAlloc, 0, 0, data_len, 16); nandcfgIndication->wait(); fprintf(stderr, "%s:%d finished -- data_len=%ld\n", __FUNCTION__, __LINE__, data_len); return data_len; } ================================================ FILE: examples/algo1_nandsim/test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "MMURequest.h" #include "MMUIndication.h" #include "MemServerRequest.h" #include "MemServerIndication.h" #include "StrstrIndication.h" #include "StrstrRequest.h" static int trace_memory = 1; extern "C" { #include "drivers/portalmem/portalmem.h" #include "userReference.h" } #include "nandsim.h" #include "strstr.h" class MMUIndicationNandSim : public MMUIndicationWrapper { DmaManager *portalMemory; sem_t sem; public: int sglId; MMUIndicationNandSim(DmaManager *pm, unsigned int id, int tile=DEFAULT_TILE) : MMUIndicationWrapper(id,tile), portalMemory(pm) { sem_init(&sem, 0, 0); } void wait() { sem_wait(&sem); } virtual void configResp(uint32_t pointer){ fprintf(stderr, "MMUIndication::configResp: %x\n", pointer); portalMemory->confResp(pointer); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MMUIndication::error(code=0x%x, pointer=0x%x, offset=0x%"PRIx64" extra=-0x%"PRIx64"\n", code, pointer, offset, extra); //if (--mmu_error_limit < 0) exit(-1); } virtual void idResponse(uint32_t sglId){ fprintf(stderr, "MMUIndication::idResponse: %x\n", sglId); if (portalMemory) portalMemory->sglIdResp(sglId); this->sglId = sglId; sem_post(&sem); } }; class MemServerIndicationNandSim : public MemServerIndicationWrapper { MemServerRequestProxy *memServerRequestProxy; sem_t mtSem; uint64_t mtCnt; void init(){ if (sem_init(&mtSem, 0, 0)) PORTAL_PRINTF("MemServerIndication::init failed to init mtSem\n"); } public: MemServerIndicationNandSim(unsigned int id, int tile=DEFAULT_TILE) : MemServerIndicationWrapper(id,tile), memServerRequestProxy(NULL) {init();} virtual void addrResponse(uint64_t physAddr){ fprintf(stderr, "DmaIndication::addrResponse(physAddr=%"PRIx64")\n", physAddr); } virtual void reportStateDbg(const DmaDbgRec rec){ fprintf(stderr, "MemServerIndication::reportStateDbg: {x:%08x y:%08x z:%08x w:%08x}\n", rec.x,rec.y,rec.z,rec.w); } virtual void reportMemoryTraffic(uint64_t words){ //fprintf(stderr, "reportMemoryTraffic: words=%"PRIx64"\n", words); mtCnt = words; sem_post(&mtSem); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MemServerIndication::error(code=%x, pointer=%x, offset=%"PRIx64" extra=%"PRIx64"\n", code, pointer, offset, extra); if (--mem_error_limit < 0) exit(-1); } uint64_t receiveMemoryTraffic(){ sem_wait(&mtSem); return mtCnt; } uint64_t getMemoryTraffic(const ChannelType rc){ assert(memServerRequestProxy); memServerRequestProxy->memoryTraffic(rc); return receiveMemoryTraffic(); } }; size_t numBytes = 1 << 10; extern int initNandSim(DmaManager *hostDma); int main(int argc, const char **argv) { fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); DmaManager *hostDma = platformInit(); MMURequestProxy *nandsimMMU = new MMURequestProxy(IfcNames_MMURequestS2H); DmaManager *nandsimDma = new DmaManager(nandsimMMU); StrstrRequestProxy *strstrRequest = new StrstrRequestProxy(IfcNames_StrstrRequestS2H); StrstrIndication *strstrIndication = new StrstrIndication(IfcNames_StrstrIndicationH2S); MMUIndicationNandSim nandsimMMUIndication(nandsimDma,IfcNames_MMUIndicationH2S); MemServerIndicationNandSim nandsimMemServerIndication(IfcNames_MemServerIndicationH2S); fprintf(stderr, "Initializing nandSim...\n"); int haystack_len = initNandSim(hostDma); int haystack_base = 0; fprintf(stderr, "haystack_base=%d haystack_len=%d\n", haystack_base, haystack_len); fprintf(stderr, "Main::allocating memory...\n"); // allocate memory for strstr data int needleAlloc = portalAlloc(numBytes, 0); int mpNextAlloc = portalAlloc(numBytes, 0); int ref_needleAlloc = hostDma->reference(needleAlloc); int ref_mpNextAlloc = hostDma->reference(mpNextAlloc); fprintf(stderr, "%s:%d %08x %08x\n", __FUNCTION__, __LINE__, ref_needleAlloc, ref_mpNextAlloc); char *needle = (char *)portalMmap(needleAlloc, numBytes); int *mpNext = (int *)portalMmap(mpNextAlloc, numBytes); const char *needle_text = "ababab"; int needle_len = strlen(needle_text); strncpy(needle, needle_text, needle_len); compute_MP_next(needle, mpNext, needle_len); portalCacheFlush(needleAlloc, needle, numBytes, 1); portalCacheFlush(mpNextAlloc, mpNext, numBytes, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); // request the next sglist identifier from the sglistMMU hardware module // which is used by the mem server accessing flash memory. int id = 0; fprintf(stderr, "[%s:%d]\n", __FUNCTION__, __LINE__); if (1) { MMURequest_idRequest(nandsimDma->priv.sglDevice, 0); sem_wait(&nandsimDma->priv.sglIdSem); id = nandsimDma->priv.sglId; } else { nandsimMMU->idRequest(0); nandsimMMUIndication.wait(); id = nandsimMMUIndication.sglId; } fprintf(stderr, "[%s:%d] id=%d\n", __FUNCTION__, __LINE__, id); // pairs of ('offset','size') pointing to space in nandsim memory // this is unsafe. To do it properly, we should get this list from // nandsim_exe or from the kernel driver. This code here might overrun // the backing store allocated by nandsim_exe. RegionRef region[] = {{0, 0x100000}, {0x100000, 0x100000}}; fprintf(stderr, "[%s:%d]\n", __FUNCTION__, __LINE__); int ref_haystackInNandMemory = send_reference_to_portal(nandsimDma->priv.sglDevice, sizeof(region)/sizeof(region[0]), region, id); sem_wait(&(nandsimDma->priv.confSem)); fprintf(stderr, "[%s:%d] %08x\n", __FUNCTION__, __LINE__, ref_haystackInNandMemory); // at this point, ref_needleAlloc and ref_mpNextAlloc are valid sgListIds for use by // the host memory dma hardware, and ref_haystackInNandMemory is a valid sgListId for // use by the nandsim dma hardware fprintf(stderr, "about to setup device %d %d\n", ref_needleAlloc, ref_mpNextAlloc); strstrRequest->setup(ref_needleAlloc, ref_mpNextAlloc, needle_len); fprintf(stderr, "about to invoke search %d\n", ref_haystackInNandMemory); strstrRequest->search(ref_haystackInNandMemory, haystack_len); strstrIndication->wait(); fprintf(stderr, "algo1_nandsim: Done %d\n", (strstrIndication->match_cnt==3)); sleep(2); exit(!(strstrIndication->match_cnt==3)); } ================================================ FILE: examples/algo2_nandsim/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = NandCfgRequest RegexpRequest NandCfgIndication RegexpIndication BSVFILES = $(CONNECTALDIR)/lib/nandsim/bsv/NandSim.bsv $(CONNECTALDIR)/lib/regexp/bsv/Regexp.bsv $(CONNECTALDIR)/lib/nandsim/bsv/NandSimNames.bsv Top.bsv CPPFILES=test.cpp CPPFILES2=../nandsim/testnandsim.cpp CONNECTALFLAGS += -D HAYSTACKREADCLIENTS=1 CONNECTALFLAGS += -D DEGPAR=4 -D MAX_NUM_STATES=32 -D MAX_NUM_CHARS=32 CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/regexp/cpp CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/nandsim/cpp CONNECTALFLAGS += -D ALGO_NANDSIM include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/algo2_nandsim/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import BRAM::*; import DefaultValue::*; import Connectable::*; import CtrlMux::*; import Portal::*; import ConnectalMemory::*; import MemServer::*; import MemServerInternal::*; import ConnectalMMU::*; import ConnectalConfig::*; import NandCfgRequest::*; import MMURequest::*; import RegexpRequest::*; import NandCfgIndication::*; import MemServerRequest::*; import MemServerIndication::*; import MMUIndication::*; import RegexpIndication::*; import NandSim::*; import NandSimNames::*; import Regexp::*; module mkConnectalTop(ConnectalTop); // nandsim NandCfgIndicationProxy nandSimIndicationProxy <- mkNandCfgIndicationProxy(IfcNames_NandCfgIndicationH2S); NandSim nandSim <- mkNandSim(nandSimIndicationProxy.ifc); NandCfgRequestWrapper nandSimRequestWrapper <- mkNandCfgRequestWrapper(IfcNames_NandCfgRequestS2H,nandSim.request); // regexp algo RegexpIndicationProxy regexpIndicationProxy <- mkRegexpIndicationProxy(IfcNames_AlgoIndicationH2S); Regexp#(64) regexp <- mkRegexp(regexpIndicationProxy.ifc); RegexpRequestWrapper regexpRequestWrapper <- mkRegexpRequestWrapper(IfcNames_AlgoRequestS2H,regexp.request); // backing store mmu MMUIndicationProxy mMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMUIndicationH2S); MMU#(PhysAddrWidth) mMU <- mkMMU(0, True, mMUIndicationProxy.ifc); MMURequestWrapper mMURequestWrapper <- mkMMURequestWrapper(IfcNames_MMURequestS2H, mMU.request); // algo mmu MMUIndicationProxy algoMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMUIndicationH2S); MMU#(PhysAddrWidth) algoMMU <- mkMMU(1, True, algoMMUIndicationProxy.ifc); MMURequestWrapper algoMMURequestWrapper <- mkMMURequestWrapper(IfcNames_MMURequestS2H, algoMMU.request); // nandsim mmu MMUIndicationProxy nandsimMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_NandMMUIndicationH2S); MMU#(PhysAddrWidth) nandsimMMU <- mkMMU(0, False, nandsimMMUIndicationProxy.ifc); MMURequestWrapper nandsimMMURequestWrapper <- mkMMURequestWrapper(IfcNames_NandMMURequestS2H, nandsimMMU.request); // host memory dma server MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_MemServerIndicationH2S); let rcs = append(regexp.config_read_client,nandSim.readClient); MemServer#(PhysAddrWidth,64,1) hostDma <- mkMemServer(rcs, nandSim.writeClient, cons(mMU,cons(algoMMU,nil)), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper memServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_MemServerRequestS2H, hostDma.request); // nandsim memory dma server MemServerIndicationProxy nandsimMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_NandMemServerIndicationH2S); MemServer#(PhysAddrWidth,64,1) nandsimDma <- mkMemServer(regexp.haystack_read_client, nil, cons(nandsimMMU,nil), nandsimMemServerIndicationProxy.ifc); mkConnection(nandsimDma.masters[0], nandSim.memSlave); Vector#(13,StdPortal) portals; portals[0] = nandSimRequestWrapper.portalIfc; portals[1] = nandSimIndicationProxy.portalIfc; portals[2] = regexpRequestWrapper.portalIfc; portals[3] = regexpIndicationProxy.portalIfc; portals[4] = mMURequestWrapper.portalIfc; portals[5] = mMUIndicationProxy.portalIfc; portals[6] = nandsimMMURequestWrapper.portalIfc; portals[7] = nandsimMMUIndicationProxy.portalIfc; portals[8] = algoMMURequestWrapper.portalIfc; portals[9] = algoMMUIndicationProxy.portalIfc; portals[10] = hostMemServerIndicationProxy.portalIfc; portals[11] = nandsimMemServerIndicationProxy.portalIfc; portals[12] = memServerRequestWrapper.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = hostDma.masters; endmodule : mkConnectalTop ================================================ FILE: examples/algo2_nandsim/test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include "dmaManager.h" #include "MMURequest.h" #include "MMUIndication.h" #include "NandCfgIndication.h" #include "NandCfgRequest.h" #include "RegexpIndication.h" #include "RegexpRequest.h" static int trace_memory = 1; extern "C" { #include "sys/ioctl.h" #include "drivers/portalmem/portalmem.h" #include "sock_utils.h" #include "userReference.h" } #include "regexp_utils.h" #include "nandsim.h" class MMUIndicationNAND : public MMUIndicationWrapper { DmaManager *portalMemory; public: MMUIndicationNAND(DmaManager *pm, unsigned int id, int tile=DEFAULT_TILE) : MMUIndicationWrapper(id,tile), portalMemory(pm) {} MMUIndicationNAND(DmaManager *pm, unsigned int id, PortalTransportFunctions *item, void *param) : MMUIndicationWrapper(id, item, param), portalMemory(pm) {} virtual void configResp(uint32_t pointer){ fprintf(stderr, "MMUIndication::configResp: %x\n", pointer); portalMemory->confResp(pointer); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MMUIndication::error(code=0x%x, pointer=0x%x, offset=0x%"PRIx64" extra=-0x%"PRIx64"\n", code, pointer, offset, extra); //if (--mmu_error_limit < 0) exit(-1); } virtual void idResponse(uint32_t sglId){ portalMemory->sglIdResp(sglId); } }; size_t numBytes = 1 << 10; int main(int argc, const char **argv) { fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); //MMURequestProxy *hostMMURequest = new MMURequestProxy(IfcNames_MMURequestS2H); DmaManager *hostDma = platformInit(); MMURequestProxy *nandsimMMURequest = new MMURequestProxy(IfcNames_NandMMURequestS2H); DmaManager *nandsimDma = new DmaManager(nandsimMMURequest); MMUIndicationNAND nandsimMMUIndication(nandsimDma,IfcNames_NandMMUIndicationH2S); RegexpRequestProxy *device = new RegexpRequestProxy(IfcNames_AlgoRequestS2H); RegexpIndication *deviceIndication = new RegexpIndication(IfcNames_AlgoIndicationH2S); //MemServerIndication hostMemServerIndication(IfcNames_MemServerIndicationH2S); //MemServerIndication nandsimMemServerIndication(IfcNames_NandMemServerIndicationH2S); haystack_dma = hostDma; //haystack_mmu = hostMMURequest; regexp = device; fprintf(stderr, "Main::allocating memory...\n"); // this is hard-coded into the REParser.java assert(32 == MAX_NUM_STATES); assert(32 == MAX_NUM_CHARS); //////////////////////////////////////////////////////////////////// // fprintf(stderr, "Main::waiting to connect to nandsim_exe\n"); wait_for_connect_nandsim_exe(); fprintf(stderr, "Main::connected to nandsim_exe\n"); // base of haystack in "flash" memory // this is read from nandsim_exe, but could also come from kernel driver int haystack_base = read_from_nandsim_exe(); int haystack_len = read_from_nandsim_exe(); (void) haystack_base; // unused // request the next sglist identifier from the sglistMMU hardware module // which is used by the mem server accessing flash memory. int id = 0; MMURequest_idRequest(nandsimDma->priv.sglDevice, 0); sem_wait(&nandsimDma->priv.sglIdSem); id = nandsimDma->priv.sglId; // pairs of ('offset','size') pointing to space in nandsim memory // this is unsafe. To do it properly, we should get this list from // nandsim_exe or from the kernel driver. This code here might overrun // the backing store allocated by nandsim_exe. RegionRef region[] = {{0, 0x100000}, {0x100000, 0x100000}}; printf("[%s:%d]\n", __FUNCTION__, __LINE__); int ref_haystackInNandMemory = send_reference_to_portal(nandsimDma->priv.sglDevice, sizeof(region)/sizeof(region[0]), region, id); sem_wait(&(nandsimDma->priv.confSem)); fprintf(stderr, "%08x\n", ref_haystackInNandMemory); // //////////////////////////////////////////////////////////////////// if(1){ P charMapP; P stateMapP; P stateTransitionsP; readfile("../jregexp.charMap", &charMapP); readfile("../jregexp.stateMap", &stateMapP); readfile("../jregexp.stateTransitions", &stateTransitionsP); portalCacheFlush(charMapP.alloc, charMapP.mem, charMapP.length, 1); portalCacheFlush(stateMapP.alloc, stateMapP.mem, stateMapP.length, 1); portalCacheFlush(stateTransitionsP.alloc, stateTransitionsP.mem, stateTransitionsP.length, 1); for(int i = 0; i < num_tests; i++){ device->setup(charMapP.ref, charMapP.length); device->setup(stateMapP.ref, stateMapP.length); device->setup(stateTransitionsP.ref, stateTransitionsP.length); // for this test, we are just re-usng the same haystack which // has been written to the nandsim backing store by nandsim_exe if(i==0){ readfile("test.bin", &haystackP[0]); sw_match_cnt = num_tests*sw_ref(&haystackP[0], &charMapP, &stateMapP, &stateTransitionsP); } sem_wait(&test_sem); int token = deviceIndication->token; assert(token < max_num_tokens); token_map[token] = i; fprintf(stderr, "Main::about to invoke search %08x %08x\n", ref_haystackInNandMemory, haystack_len); // Regexp uses a data-bus width of 8 bytes. length must be a multiple of this dimension device->search(token, ref_haystackInNandMemory, haystack_len & ~((1<<3)-1)); } sem_wait(&test_sem); close(charMapP.alloc); close(stateMapP.alloc); close(stateTransitionsP.alloc); } fprintf(stderr, "hw_match_cnt=%d, sw_match_cnt=%d\n", hw_match_cnt, sw_match_cnt); return (hw_match_cnt == sw_match_cnt ? 0 : -1); } ================================================ FILE: examples/aurora/Aurora.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; import GetPut::*; import ClientServer::*; import ConnectalXilinxCells::*; import XilinxCells::*; import BviAurora::*; import Clocks::*; import FrequencyCounter::*; import Gtx::*; (* always_enabled, always_ready *) interface AuroraPins; method Action userClk(Bit#(1) p, Bit#(1) n); method Action mgtRefClk(Bit#(1) p, Bit#(1) n); method Action mgtRx(Bit#(1) p, Bit#(1) n); method Bit#(1) mgtTx_p(); method Bit#(1) mgtTx_n(); interface DiffClock smaUserClk; endinterface interface AuroraIndication; method Action received(Bit#(64) v); method Action debug(Bit#(1) channelUp, Bit#(1) laneUp, Bit#(1) hard_err, Bit#(1) soft_err, Bit#(1) qpllLock, Bit#(1) qpllRefClkLost); method Action userClkElapsedCycles(Bit#(32) cycles); method Action mgtRefClkElapsedCycles(Bit#(32) cycles); method Action outClkElapsedCycles(Bit#(32) cycles); method Action outRefClkElapsedCycles(Bit#(32) cycles); method Action drpResponse(Bit#(16) v); endinterface interface AuroraRequest; method Action send(Bit#(64) v); method Action debug(); method Action pma_init(Bit#(1) v); method Action userClkElapsedCycles(Bit#(32) period); method Action mgtRefClkElapsedCycles(Bit#(32) period); method Action outClkElapsedCycles(Bit#(32) period); method Action outRefClkElapsedCycles(Bit#(32) period); method Action drpRequest(Bit#(9) addr, Bit#(16) data, Bit#(1) isWrite); method Action qpllReset(Bit#(1) v); method Action loopback(Bit#(3) v); endinterface interface Aurora; interface AuroraRequest request; interface AuroraPins pins; endinterface module mkAuroraRequest#(AuroraIndication indication)(Aurora); let defaultClock <- exposeCurrentClock; let defaultReset <- exposeCurrentReset; Wire#(Bit#(1)) userClkWireP <- mkDWire(0); Wire#(Bit#(1)) userClkWireN <- mkDWire(0); Clock userClkIn <- mkClockIBUFDS(userClkWireP, userClkWireN); Clock userClk <- mkClockBUFG(clocked_by userClkIn); DiffClock smaUserClockDS <- mkClockOBUFDS(clocked_by userClk); let userReset <- mkAsyncReset(16, defaultReset, userClk); let userClkFreqCounter <- mkFrequencyCounter(userClk, userReset); Wire#(Bit#(1)) mgtRefClkWireP <- mkDWire(0); Wire#(Bit#(1)) mgtRefClkWireN <- mkDWire(0); Clock mgtRefClk <- mkClockIBUFDS_GTE2(True, mgtRefClkWireP, mgtRefClkWireN); let mgtRefClkReset <- mkAsyncReset(16, defaultReset, mgtRefClk); let mgtRefClkFreqCounter <- mkFrequencyCounter(mgtRefClk, mgtRefClkReset); let b2c <- mkB2C(); Clock txClock <- mkClockBUFG(clocked_by b2c.c); Clock syncClock = txClock; // should be doubled let common <- mkGtxe2Common(defaultClock, mgtRefClk, defaultClock); // let outClk <- mkClockBUFG(clocked_by common.qpll.outClk); // let outClkReset <- mkAsyncReset(2, defaultReset, outClk); // let outClkFreqCounter <- mkFrequencyCounter(outClk, outClkReset); // let outRefClk <- mkClockBUFG(clocked_by common.qpll.outRefClk); // let outRefClkReset <- mkAsyncReset(2, defaultReset, outRefClk); // let outRefClkFreqCounter <- mkFrequencyCounter(outRefClk, outRefClkReset); let initReset <- mkAsyncReset(128, defaultReset, userClk); let aur <- mkBviAurora64(/* init_clk */ defaultClock, mgtRefClk, /* sync_clk */ syncClock, /* user_clk */ txClock, /* init_clk_reset */ defaultReset, /* refclk1_in_reset */ defaultReset, /* reset */ defaultReset, /* sync_clk_reset */ defaultReset, /* user_clk_reset */ defaultReset); Reg#(Bit#(1)) pmaInitVal <- mkReg(0); Reg#(Bit#(3)) loopbackVal <- mkReg(0); Reg#(Bit#(15)) ccCounter <- mkReg(0); rule tx_out_clk_rule; b2c.inputclock(aur.tx.out_clk()); endrule // gt_pll_lock rule settings; aur.loopback(loopbackVal); aur.power.down(0); aur.pma.init(pmaInitVal); endrule rule qpll; //aur.gt_qpllclk_quad2_in(common.qpll.outClk()); //aur.gt_qpllrefclk_quad2_in(common.qpll.outRefClk()); endrule rule receive if (unpack(aur.m_axi_rx.tvalid())); let v = 0; indication.received(aur.m_axi_rx.tdata()); endrule Reg#(Bit#(1)) ccValue <- mkReg(0); rule doCC; aur.do_.cc(ccValue); endrule // The CC block code should be sent atleast once for every 5000 clock cycles. rule countCC; let counter = ccCounter + 1; let doCC = 0; if (aur.channel.up() == 0) counter = 0; if (counter > 4992) doCC = 1; if (counter > 5000) counter = 0; ccCounter <= counter; ccValue <= doCC; endrule rule userclkfreqcounter_rule; let ec <- userClkFreqCounter.elapsedCycles(); indication.userClkElapsedCycles(ec); endrule rule mgtrefclkfreqcounter_rule; let ec <- mgtRefClkFreqCounter.elapsedCycles(); indication.mgtRefClkElapsedCycles(ec); endrule rule outclkfreqcounter_rule; // let ec <- outClkFreqCounter.elapsedCycles(); // indication.outClkElapsedCycles(ec); endrule rule outrefclkfreqcounter_rule; // let ec <- outRefClkFreqCounter.elapsedCycles(); // indication.outRefClkElapsedCycles(ec); endrule rule drpResponseRule; let v <- common.drp.response.get(); indication.drpResponse(v); endrule interface AuroraRequest request; method Action send(Bit#(64) v) if (unpack(aur.s_axi_tx.tready())); aur.s_axi_tx.tdata(v); aur.s_axi_tx.tkeep(-1); aur.s_axi_tx.tlast(1); aur.s_axi_tx.tvalid(1); endmethod method Action debug(); indication.debug(aur.channel.up(), aur.lane.up(), aur.hard.err(), aur.soft.err(), common.qpll.lock(), common.qpll.refClkLost()); endmethod method Action pma_init(Bit#(1) v); pmaInitVal <= v; endmethod method Action loopback(Bit#(3) v); loopbackVal <= v; endmethod method Action userClkElapsedCycles(Bit#(32) period); userClkFreqCounter.start(period); endmethod method Action mgtRefClkElapsedCycles(Bit#(32) period); mgtRefClkFreqCounter.start(period); endmethod method Action outClkElapsedCycles(Bit#(32) period); // outClkFreqCounter.start(period); endmethod method Action outRefClkElapsedCycles(Bit#(32) period); // outRefClkFreqCounter.start(period); endmethod method Action drpRequest(Bit#(9) addr, Bit#(16) data, Bit#(1) isWrite); common.drp.request.put(DrpRequest { addr: addr, data: data, isWrite: unpack(isWrite) }); endmethod method Action qpllReset(Bit#(1) v); common.qpll.reset(unpack(v)); endmethod endinterface interface AuroraPins pins; method Action userClk(Bit#(1) p, Bit#(1) n); userClkWireP <= p; userClkWireN <= n; endmethod method Action mgtRefClk(Bit#(1) p, Bit#(1) n); mgtRefClkWireP <= p; mgtRefClkWireN <= n; endmethod method Action mgtRx(Bit#(1) p, Bit#(1) n); aur.rxp(p); aur.rxn(n); endmethod method mgtTx_p = aur.txp; method mgtTx_n = aur.txn; interface DiffClock smaUserClk = smaUserClockDS; endinterface endmodule ================================================ FILE: examples/aurora/BviAurora.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* ../../generated/scripts/importbvi.py -o BviAurora.bsv -I BviAurora64 -P Au64 -n refclk1_in -n gt_qpllclk_quad2 -n gt_qpllrefclk_quad2 -c refclk1_in -r reset -c clk_in -c init_clk -c user_clk -c sync_clk ../../generated/xilinx/zc706/aurora_64b66b_0/aurora_64b66b_0_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface Au64Channel; method Bit#(1) up(); endinterface (* always_ready, always_enabled *) interface Au64Do; method Action cc(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Drp; method Action clk_in(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Gt; method Bit#(1) pll_lock(); method Action rxcdrovrden_in(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Hard; method Bit#(1) err(); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface Au64Lane; method Bit#(1) up(); endinterface (* always_ready, always_enabled *) interface Au64Link; method Bit#(1) reset_out(); endinterface (* always_ready, always_enabled *) interface Au64M_axi_rx; method Bit#(64) tdata(); method Bit#(8) tkeep(); method Bit#(1) tlast(); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface Au64Mmcm; method Action not_locked(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Pma; method Action init(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Power; method Action down(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Reset; method Action pb(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64S_axi; method Action araddr(Bit#(32) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(32) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64S_axi_tx; method Action tdata(Bit#(64) v); method Action tkeep(Bit#(8) v); method Action tlast(Bit#(1) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Au64Soft; method Bit#(1) err(); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface Au64Sys; method Bit#(1) reset_out(); endinterface (* always_ready, always_enabled *) interface Au64Tx; method Bit#(1) out_clk(); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface BviAurora64; interface Au64Channel channel; interface Au64Do do_; interface Au64Drp drp; interface Au64Gt gt; method Action gt_qpllclk_quad2_in(Bit#(1) v); method Action gt_qpllrefclk_quad2_in(Bit#(1) v); interface Au64Hard hard; interface Au64Lane lane; interface Au64Link link; method Action loopback(Bit#(3) v); interface Au64M_axi_rx m_axi_rx; interface Au64Mmcm mmcm; interface Au64Pma pma; interface Au64Power power; interface Au64Reset reset; method Action rxn(Bit#(1) v); method Action rxp(Bit#(1) v); interface Au64S_axi s_axi; interface Au64S_axi_tx s_axi_tx; interface Au64Soft soft; interface Au64Sys sys; interface Au64Tx tx; method Bit#(1) txn(); method Bit#(1) txp(); endinterface import "BVI" aurora_64b66b_0 = module mkBviAurora64#(Clock init_clk, Clock refclk1_in, Clock sync_clk, Clock user_clk, Reset init_clk_reset, Reset refclk1_in_reset, Reset reset, Reset sync_clk_reset, Reset user_clk_reset)(BviAurora64); default_clock clk(); default_reset rst(); input_clock init_clk(init_clk) = init_clk; input_reset init_clk_reset() = init_clk_reset; /* from clock*/ input_clock refclk1_in(refclk1_in) = refclk1_in; input_reset refclk1_in_reset() = refclk1_in_reset; /* from clock*/ input_reset reset(reset) = reset; input_clock sync_clk(sync_clk) = sync_clk; input_reset sync_clk_reset() = sync_clk_reset; /* from clock*/ input_clock user_clk(user_clk) = user_clk; input_reset user_clk_reset() = user_clk_reset; /* from clock*/ interface Au64Channel channel; method channel_up up(); endinterface interface Au64Do do_; method cc(do_cc) enable((*inhigh*) EN_do_cc); endinterface interface Au64Drp drp; method clk_in(drp_clk_in) enable((*inhigh*) EN_drp_clk_in); endinterface interface Au64Gt gt; method gt_pll_lock pll_lock(); method rxcdrovrden_in(gt_rxcdrovrden_in) enable((*inhigh*) EN_gt_rxcdrovrden_in); endinterface method gt_qpllclk_quad2_in(gt_qpllclk_quad2_in) enable((*inhigh*) EN_gt_qpllclk_quad2_in); method gt_qpllrefclk_quad2_in(gt_qpllrefclk_quad2_in) enable((*inhigh*) EN_gt_qpllrefclk_quad2_in); interface Au64Hard hard; method hard_err err(); endinterface interface Au64Lane lane; method lane_up up(); endinterface interface Au64Link link; method link_reset_out reset_out(); endinterface method loopback(loopback) enable((*inhigh*) EN_loopback); interface Au64M_axi_rx m_axi_rx; method m_axi_rx_tdata tdata(); method m_axi_rx_tkeep tkeep(); method m_axi_rx_tlast tlast(); method m_axi_rx_tvalid tvalid(); endinterface interface Au64Mmcm mmcm; method not_locked(mmcm_not_locked) enable((*inhigh*) EN_mmcm_not_locked); endinterface interface Au64Pma pma; method init(pma_init) enable((*inhigh*) EN_pma_init); endinterface interface Au64Power power; method down(power_down) enable((*inhigh*) EN_power_down); endinterface interface Au64Reset reset; method pb(reset_pb) enable((*inhigh*) EN_reset_pb); endinterface method rxn(rxn) enable((*inhigh*) EN_rxn); method rxp(rxp) enable((*inhigh*) EN_rxp); interface Au64S_axi s_axi; method araddr(s_axi_araddr) enable((*inhigh*) EN_s_axi_araddr); method s_axi_arready arready(); method arvalid(s_axi_arvalid) enable((*inhigh*) EN_s_axi_arvalid); method awaddr(s_axi_awaddr) enable((*inhigh*) EN_s_axi_awaddr); method s_axi_awready awready(); method awvalid(s_axi_awvalid) enable((*inhigh*) EN_s_axi_awvalid); method bready(s_axi_bready) enable((*inhigh*) EN_s_axi_bready); method s_axi_bvalid bvalid(); method s_axi_rdata rdata(); method rready(s_axi_rready) enable((*inhigh*) EN_s_axi_rready); method s_axi_rvalid rvalid(); method wdata(s_axi_wdata) enable((*inhigh*) EN_s_axi_wdata); method s_axi_wready wready(); method wvalid(s_axi_wvalid) enable((*inhigh*) EN_s_axi_wvalid); endinterface interface Au64S_axi_tx s_axi_tx; method tdata(s_axi_tx_tdata) enable((*inhigh*) EN_s_axi_tx_tdata); method tkeep(s_axi_tx_tkeep) enable((*inhigh*) EN_s_axi_tx_tkeep); method tlast(s_axi_tx_tlast) enable((*inhigh*) EN_s_axi_tx_tlast); method s_axi_tx_tready tready(); method tvalid(s_axi_tx_tvalid) enable((*inhigh*) EN_s_axi_tx_tvalid); endinterface interface Au64Soft soft; method soft_err err(); endinterface interface Au64Sys sys; method sys_reset_out reset_out(); endinterface interface Au64Tx tx; method tx_out_clk out_clk() clocked_by (user_clk); endinterface method txn txn(); method txp txp(); schedule (channel.up, do_.cc, drp.clk_in, gt.pll_lock, gt.rxcdrovrden_in, gt_qpllclk_quad2_in, gt_qpllrefclk_quad2_in, hard.err, lane.up, link.reset_out, loopback, m_axi_rx.tdata, m_axi_rx.tkeep, m_axi_rx.tlast, m_axi_rx.tvalid, mmcm.not_locked, pma.init, power.down, reset.pb, rxn, rxp, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wvalid, s_axi_tx.tdata, s_axi_tx.tkeep, s_axi_tx.tlast, s_axi_tx.tready, s_axi_tx.tvalid, soft.err, sys.reset_out, tx.out_clk, txn, txp) CF (channel.up, do_.cc, drp.clk_in, gt.pll_lock, gt.rxcdrovrden_in, gt_qpllclk_quad2_in, gt_qpllrefclk_quad2_in, hard.err, lane.up, link.reset_out, loopback, m_axi_rx.tdata, m_axi_rx.tkeep, m_axi_rx.tlast, m_axi_rx.tvalid, mmcm.not_locked, pma.init, power.down, reset.pb, rxn, rxp, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wvalid, s_axi_tx.tdata, s_axi_tx.tkeep, s_axi_tx.tlast, s_axi_tx.tready, s_axi_tx.tvalid, soft.err, sys.reset_out, tx.out_clk, txn, txp); endmodule ================================================ FILE: examples/aurora/Gtx.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import GetPut::*; import ClientServer::*; import Clocks::*; interface Drp#(numeric type asz, numeric type dsz); method Action addr(Bit#(asz) a); method Action en(Bit#(1) en); method Action we(Bit#(1) we); method Bit#(dsz) dout(); method Action din(Bit#(dsz) d); method Bit#(1) rdy(); endinterface interface Gtxe2Qpll; method Action reset(Bool v); method Bit#(1) lock(); interface Clock outClk; interface Clock outRefClk; method Bit#(1) refClkLost(); endinterface interface VGtxe2Common; (* always_ready, always_enabled *) interface Gtxe2Qpll qpll; (* always_ready, always_enabled *) interface Drp#(9,16) drp; endinterface import "BVI" GTXE2_COMMON = module vMkGtxe2Common#(Clock qpllLockDetClk, Clock gtrefclk0, Clock drpClk)(VGtxe2Common); default_clock clk(); default_reset reset(); input_clock gtrefclk0(GTREFCLK0) = gtrefclk0; input_clock qpllLockDetClk(QPLLLOCKDETCLK) = qpllLockDetClk; input_clock drpClk(DRPCLK) = drpClk; parameter BIAS_CFG = (64'h0000040000001000); parameter COMMON_CFG = (32'h00000000); parameter QPLL_CFG = (27'h06801C1); parameter QPLL_CLKOUT_CFG = (4'b0000); parameter QPLL_COARSE_FREQ_OVRD = (6'b010000); parameter QPLL_COARSE_FREQ_OVRD_EN = (1'b0); parameter QPLL_CP = (10'b0000011111); parameter QPLL_CP_MONITOR_EN = (1'b0); parameter QPLL_DMONITOR_SEL = (1'b0); parameter QPLL_FBDIV = (10'b0000100000); parameter QPLL_FBDIV_MONITOR_EN = (1'b0); parameter QPLL_FBDIV_RATIO = (1'b1); parameter QPLL_INIT_CFG = (24'h000006); parameter QPLL_LOCK_CFG = (16'h21E8); parameter QPLL_LPF = (4'b1111); parameter QPLL_REFCLK_DIV = (1); port GTGREFCLK = 0; port GTNORTHREFCLK0 = 0; port GTNORTHREFCLK1 = 0; //port GTREFCLK0 = gtrefclk0; port GTREFCLK1 = 0; port GTSOUTHREFCLK0 = 0; port GTSOUTHREFCLK1 = 0; port QPLLLOCKEN = 1; port QPLLOUTRESET = 0; port QPLLPD = 0; port QPLLREFCLKSEL = 3'b1; port QPLLRSVD1 = 0; port QPLLRSVD2 = 5'b11111; port RCALENB = 1; port BGBYPASSB = 1; port BGMONITORENB = 1; port BGPDB = 1; port BGRCALOVRD = 5'b11111; port PMARSVD = 0; interface Drp drp; method din(DRPDI) enable((*inhigh*)EN_DI) clocked_by(drpClk); method addr(DRPADDR) enable((*inhigh*)EN_ADDR) clocked_by(drpClk); method en(DRPEN) enable((*inhigh*)EN_EN) clocked_by(drpClk); method we(DRPWE) enable((*inhigh*)EN_WE) clocked_by(drpClk); method DRPDO dout() clocked_by(drpClk); method DRPRDY rdy() clocked_by(drpClk); endinterface interface Gtxe2Qpll qpll; method reset(QPLLRESET) enable ((*inhigh*)EN_RESET); method QPLLLOCK lock(); output_clock outClk(QPLLOUTCLK); output_clock outRefClk(QPLLOUTREFCLK); method QPLLREFCLKLOST refClkLost(); endinterface schedule (qpll_reset, qpll_lock, qpll_refClkLost, drp_addr, drp_din, drp_en, drp_we, drp_dout, drp_rdy, drp_we) CF (qpll_reset, qpll_lock, qpll_refClkLost, drp_addr, drp_din, drp_en, drp_we, drp_dout, drp_rdy, drp_we); endmodule: vMkGtxe2Common typedef struct { Bool isWrite; Bit#(asz) addr; Bit#(dsz) data; } DrpRequest#(numeric type asz, numeric type dsz) deriving (Bits,Eq); interface Gtxe2Common; interface Gtxe2Qpll qpll; interface Server#(DrpRequest#(9,16),Bit#(16)) drp; endinterface (* synthesize *) module mkGtxe2Common#(Clock qpllLockDetClk, Clock gtrefclk0, Clock drpClk)(Gtxe2Common); let m <- vMkGtxe2Common(qpllLockDetClk, gtrefclk0, drpClk); let defaultReset <- exposeCurrentReset(); let drpReset <- mkAsyncReset(2, defaultReset, drpClk); Wire#(Bit#(1)) drpen <- mkDWire(0, clocked_by drpClk, reset_by drpReset); rule drpenrule; m.drp.en(drpen); endrule Reg#(Bool) resetWire <- mkReg(False); rule qpll_reset_rule; m.qpll.reset(resetWire); endrule interface Gtxe2Qpll qpll; method Action reset(Bool v); resetWire <= v; endmethod method lock = m.qpll.lock; interface outClk = m.qpll.outClk; interface outRefClk = m.qpll.outRefClk; method refClkLost = m.qpll.refClkLost; endinterface interface Server drp; interface Put request; method Action put(DrpRequest#(9,16) req); m.drp.addr(req.addr); m.drp.din(req.data); m.drp.we(pack(req.isWrite)); drpen <= 1; endmethod endinterface interface Get response; method ActionValue#(Bit#(16)) get() if (unpack(m.drp.rdy())); return m.drp.dout(); endmethod endinterface endinterface endmodule ================================================ FILE: examples/aurora/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = AuroraRequest AuroraIndication BSVFILES = Aurora.bsv Top.bsv CPPFILES=testaurora.cpp PIN_TYPE = AuroraPins PIN_TYPE_INCLUDE = BviAurora CONNECTALFLAGS += -C $(BOARD)/sources/aurora-$(BOARD).xdc -C aurora-clocks.xdc --tcl clock.tcl AURORA_V = $(CONNECTALDIR)/generated/xilinx/$(BOARD)/aurora_64b66b_0/aurora_64b66b_0_stub.v gentarget:: $(BOARD)/sources/aurora-$(BOARD).xdc prebuild:: $(AURORA_V) BviAurora.bsv $(AURORA_V): synth-ip.tcl (cd $(BOARD); vivado -mode batch -source ../synth-ip.tcl) BviAurora.bsv: $(CONNECTALDIR)/generated/scripts/importbvi.py -o BviAurora.bsv -I BviAurora64 -P Au64 -n refclk1_in -n gt_qpllclk_quad2 -n gt_qpllrefclk_quad2 -c refclk1_in -r reset -c clk_in -c init_clk -c user_clk -c sync_clk $(AURORA_V) $(BOARD)/sources/aurora-$(BOARD).xdc: aurora.json $(CONNECTALDIR)/boardinfo/$(BOARD).json mkdir -p $(BOARD)/sources $(CONNECTALDIR)/scripts/generate-constraints.py --boardfile $(CONNECTALDIR)/boardinfo/$(BOARD).json --pinoutfile aurora.json > $(BOARD)/sources/aurora-$(BOARD).xdc include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/aurora/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ export Aurora::*; export mkConnectalTop; import Vector::*; import FIFO::*; import Connectable::*; import CtrlMux::*; import Portal::*; import ConnectalConfig::*; import AuroraIndication::*; import AuroraRequest::*; import Aurora::*; typedef enum {IfcNames_AuroraIndication, IfcNames_AuroraRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); // instantiate user portals AuroraIndicationProxy auroraIndicationProxy <- mkAuroraIndicationProxy(IfcNames_AuroraIndication); let auroraRequest <- mkAuroraRequest(auroraIndicationProxy.ifc); AuroraRequestWrapper auroraRequestWrapper <- mkAuroraRequestWrapper(IfcNames_AuroraRequest,auroraRequest.request); Vector#(2,StdPortal) portals; portals[0] = auroraRequestWrapper.portalIfc; portals[1] = auroraIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; interface pins = auroraRequest.pins; endmodule : mkConnectalTop ================================================ FILE: examples/aurora/aurora-clocks.xdc ================================================ create_clock -name user_clk -period "6.4" [get_ports "userClk_p"] create_clock -name mgtref_clk -period "6.4" [get_ports "mgtRefClk_p"] ================================================ FILE: examples/aurora/aurora.json ================================================ { "userClk_p": { "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "userClk_p" }, "userClk_n": { "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "userClk_n" }, "smaUserClk_p": { "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "smaUserClk_p" }, "smaUserClk_n": { "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "smaUserClk_n" }, "mgtRefClk_p": { "DIFF_TERM": "TRUE", "fmc": "mgtRefClk_p" }, "mgtRefClk_n": { "DIFF_TERM": "TRUE", "fmc": "mgtRefClk_n" }, "mgtRx_p": { "fmc": "mgtRx_p" }, "mgtRx_n": { "fmc": "mgtRx_n" }, "mgtTx_p": { "fmc": "mgtTx_p" }, "mgtTx_n": { "fmc": "mgtTx_n" } } ================================================ FILE: examples/aurora/clock.tcl ================================================ ## disconnect unused CLK and RST ports inserted by bsc foreach {pat} {CLK_GATE*} { puts $pat puts ports puts [get_ports $pat] puts nets puts [get_nets $pat] foreach {net} [get_nets $pat] { disconnect_net -net $net -objects [get_pins -of_objects $net] } } ================================================ FILE: examples/aurora/synth-ip.tcl ================================================ source board.tcl source $connectaldir/scripts/connectal-synth-ip.tcl connectal_synth_ip aurora_64b66b 9.2 aurora_64b66b_0 [list CONFIG.interface_mode {Framing} CONFIG.C_GT_LOC_5 {1} CONFIG.C_GT_LOC_1 {X}] ================================================ FILE: examples/aurora/testaurora.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "AuroraIndication.h" #include "AuroraRequest.h" #include "GeneratedTypes.h" class AuroraIndication : public AuroraIndicationWrapper { public: uint32_t cnt; void incr_cnt(){ if (++cnt == 7) exit(0); } virtual void received(uint64_t v) { fprintf(stderr, "Received v=%lld", v); } virtual void debug(uint32_t channelUp, uint32_t laneUp, uint32_t hardErr, uint32_t softErr, uint32_t qpllLock, uint32_t qpllRefClkLost) { fprintf(stderr, "debug: channelUp=%d laneUp=%d hardErr=%d, softErr=%d qpllLock=%d qpllRefClkLost=%d\n", channelUp, laneUp, hardErr, softErr, qpllLock, qpllRefClkLost); } virtual void userClkElapsedCycles(uint32_t ec) { fprintf(stderr, "userClk freq=%f MHz\n", (float)ec / 5.0); } virtual void mgtRefClkElapsedCycles(uint32_t ec) { fprintf(stderr, "mgtRefClk freq=%f MHz\n", (float)ec / 5.0); } virtual void outClkElapsedCycles(uint32_t ec) { fprintf(stderr, "outClk freq=%f MHz\n", (float)ec / 5.0); } virtual void outRefClkElapsedCycles(uint32_t ec) { fprintf(stderr, "outRefClk freq=%f MHz\n", (float)ec / 5.0); } virtual void drpResponse(uint32_t v) { fprintf(stderr, "drp response %#x\n", v); } AuroraIndication(unsigned int id) : AuroraIndicationWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { PortalPoller *poller = new PortalPoller(); AuroraIndication *indication = new AuroraIndication(IfcNames_AuroraIndication); AuroraRequestProxy *device = new AuroraRequestProxy(IfcNames_AuroraRequest, poller); long freq = 0; setClockFrequency(0, 200000000, &freq); fprintf(stderr, "Main::calling say1(%d)\n", 0); device->send(0); fprintf(stderr, "Main::about to go to sleep\n"); int count = 0; while(true){ device->debug(); device->userClkElapsedCycles(1000); device->mgtRefClkElapsedCycles(1000); device->qpllReset(count < 2); device->pma_init(count < 2); device->loopback(1); if (count < 0x14) { fprintf(stderr, "Reading drp reg %x\n", count+0x30); device->drpRequest(count+0x30, 0, 0); } count++; sleep(1); } } ================================================ FILE: examples/bscan/BscanIF.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BRAM :: *; import Bscan :: *; import GetPut :: *; import Connectable :: *; import DefaultValue :: *; import Clocks :: *; import HostInterface:: *; interface BscanIndication; method Action bscanGet(Bit#(64) v); endinterface interface BscanRequest; method Action bscanGet(Bit#(8) addr); method Action bscanPut(Bit#(8) addr, Bit#(64) v); endinterface interface BscanIF; interface BscanRequest request; endinterface module mkBscanIF#(HostInterface host, BscanIndication indication)(BscanIF); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reg#(Bit#(8)) addrReg <- mkReg(0); BscanBram#(Bit#(8),Bit#(64)) bscanBram <- mkBscanBram(123, addrReg, host.bscan); let bram <- mkBRAM2Server(defaultValue); mkConnection(bscanBram.bramClient, bram.portB); rule tdorule; host.bscan.tdo(bscanBram.data_out()); endrule rule bscanGetRule2; let v <- bram.portA.response.get(); indication.bscanGet(v); endrule interface BscanRequest request; method Action bscanGet(Bit#(8) addr); bram.portA.request.put(BRAMRequest {write:False, responseOnWrite:False, address:addr, datain: ?}); endmethod method Action bscanPut(Bit#(8) addr, Bit#(64) v); bram.portA.request.put(BRAMRequest {write:True, responseOnWrite:False, address:addr, datain: truncate(v)}); endmethod endinterface endmodule ================================================ FILE: examples/bscan/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = BscanRequest:BscanIF.request:host H2S_INTERFACES = BscanIF:BscanIndication:host BSVFILES = BscanIF.bsv CPPFILES=testbscan.cpp CONNECTALFLAGS += -D IMPORT_HOSTIF include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/bscan/testbscan.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include //#include //#include #include "BscanIndication.h" #include "BscanRequest.h" #include "GeneratedTypes.h" static BscanRequestProxy *bscanRequestProxy = 0; static sem_t sem_bscan; class BscanIndication : public BscanIndicationWrapper { public: virtual void bscanGet(uint64_t v) { printf("bscanGet: %llx\n", (long long)v); sem_post(&sem_bscan); } BscanIndication(unsigned int id) : BscanIndicationWrapper(id) { } }; int main(int argc, const char **argv) { BscanIndication *bscanIndication = new BscanIndication(IfcNames_BscanIndicationH2S); bscanRequestProxy = new BscanRequestProxy(IfcNames_BscanRequestS2H); if (argc == 1) { int v = 42; printf("Bscan put %x\n", v); for (int i = 0; i < 255; i++) { printf("Bscan put %x\n", i); bscanRequestProxy->bscanPut(i, i*v); } for (int i = 0; i < 16; i++) bscanRequestProxy->bscanGet(i); } else if (argc == 2) { bscanRequestProxy->bscanGet(atoll(argv[1])); sem_wait(&sem_bscan); } else if (argc == 3) bscanRequestProxy->bscanPut(atoll(argv[1]), atoll(argv[2])); printf("[%s:%d] now sleep for 20 sec\n", __FUNCTION__, __LINE__); sleep(20); return 0; } ================================================ FILE: examples/caffe/Conv.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FloatingPoint::*; import GetPut::*; import FIFO::*; import FIFOF::*; import Vector::*; import StmtFSM::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import ConnectalConfig::*; import FloatOps::*; import Gearbox::*; import GearboxGetPut::*; import DefaultValue::*; import Pipe::*; import ClientServer::*; typedef struct { Bit#(32) bottom_hw; Bit#(32) kernel_hw; Bit#(32) in_group_size; Bit#(32) baseSize; Bit#(32) conv_in_width; Bit#(32) kernel_w; Bit#(32) objectId; } ConnectalParamType deriving (Eq,Bits); interface ConvIndication; method Action outputp(Bit#(32) addr, Float v); endinterface interface ConvRequest; method Action init(ConnectalParamType param); method Action forward_kernel(Bit#(32) ap_limit, Bit#(32) aq_limit, Bit#(1) askip, Float atemp, Bit#(32) abpx, Bit#(32) awpx, Bit#(32) aoutputp); endinterface interface Conv; interface ConvRequest request; interface Vector#(1,MemReadClient#(DataBusWidth)) readDma; interface Vector#(1,MemWriteClient#(DataBusWidth)) writeDma; endinterface typedef struct { Float a; Float b; Bool last; } DotType deriving (Bits, Eq); interface DotProd; interface PipeIn#(DotType) sendPair; interface PipeOut#(Float) done; method Action init(Float atemp); method Action incrementWait(); endinterface (* synthesize *) module mkDotProd(DotProd); FIFOF#(DotType) dotFifo <- mkFIFOF; FIFOF#(Bool) lastFifo <- mkFIFOF1; FIFOF#(Float) innerDone <- mkFIFOF; FloatAlu adder <- mkFloatAdder(defaultValue); FloatAlu mul <- mkFloatMultiplier(defaultValue); Reg#(Float) temp <- mkReg(0); Reg#(Bool) running <- mkReg(False); Reg#(Bit#(32)) waitCount <- mkReg(0); rule dotrule; let v <- toGet(dotFifo).get; mul.request.put(tuple2(v.a, v.b)); toPut(lastFifo).put(v.last); endrule rule addrule; match {.resp,.*} <- mul.response.get; adder.request.put(tuple2(resp,temp)); endrule rule storerule if (running); let v <- toGet(lastFifo).get; match {.resp,.*} <- adder.response.get; temp <= resp; if (v) begin waitCount <= waitCount - 1; if (waitCount == 1) begin innerDone.enq(resp); running <= False; end end endrule interface sendPair = toPipeIn(dotFifo); interface done = toPipeOut(innerDone); method Action init(Float atemp) if (!running); temp <= atemp; running <= True; waitCount <= 0; endmethod method Action incrementWait(); waitCount <= waitCount + 1; endmethod endmodule module mkConv#(ConvIndication indication)(Conv); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Gearbox#(2, 1, DotType) floatGear <- mkNto1Gearbox(defaultClock, defaultReset, defaultClock, defaultReset); MemReadEngine#(DataBusWidth,DataBusWidth,2,2) rEngine <- mkMemReadEngine; MemWriteEngine#(DataBusWidth,DataBusWidth,2,1) wEngine <- mkMemWriteEngine; Vector#(2, Server#(Double,Float)) dToF <- replicateM(mkDoubleToFloat); DotProd dotp <- mkDotProd; Reg#(ConnectalParamType) param <- mkReg(unpack(0)); Reg#(Bit#(32)) p_limit <- mkReg(0); Reg#(Bit#(32)) q_limit <- mkReg(0); Reg#(Bit#(1)) skip <- mkReg(0); Reg#(Bit#(32)) bpx <- mkReg(0); Reg#(Bit#(32)) wpx <- mkReg(0); Reg#(Bit#(32)) outputp <- mkReg(0); Reg#(Bit#(32)) k <- mkReg(0); Reg#(Bit#(32)) p <- mkReg(0); Reg#(Bit#(32)) bp <- mkReg(0); Reg#(Bit#(32)) wp <- mkReg(0); Reg#(Bool) fsmRunning <- mkReg(False); Reg#(Bit#(BurstLenSize)) burstLenInBytes <- mkReg(8); Reg#(Bool) dtypeFloat <- mkReg(False); Reg#(Bool) dumpStart <- mkReg(False); FIFOF#(Bool) dLast <- mkFIFOF; rule readResD if (!dtypeFloat); let vb <- toGet(rEngine.readServers[0].data).get; let vw <- toGet(rEngine.readServers[1].data).get; dToF[0].request.put(unpack(vb.data)); dToF[1].request.put(unpack(vw.data)); toPut(dLast).put(vb.last); endrule rule pushDotD; let vb <- dToF[0].response.get(); let vw <- dToF[1].response.get(); let vl <- toGet(dLast).get(); toPut(dotp.sendPair).put(DotType{a: vb, b: vw, last: vl}); endrule rule readResF if (dtypeFloat); let vb <- toGet(rEngine.readServers[0].data).get; let vw <- toGet(rEngine.readServers[1].data).get; Vector#(2, DotType) temp; temp[0] = DotType{a: unpack(vb.data[31:0]), b: unpack(vw.data[31:0]), last: False}; temp[1] = DotType{a: unpack(vb.data[63:32]), b: unpack(vw.data[63:32]), last: vb.last}; if (vb.last && skip != 0) temp[1].a = 0; floatGear.enq(temp); endrule rule pushDotF; let vb <- toGet(floatGear).get; toPut(dotp.sendPair).put(vb); endrule rule finishProcessing; let v <- toGet(dotp.done).get; // Write convolution result into output (image, channel, y, x) // *CACCESS(outputp) = v; indication.outputp(outputp, v); fsmRunning <= False; endrule FSM fsm <- mkFSM(seq // for each 'in_group', add contribution into convolution for ( k <= 0; k < param.in_group_size; k <= k + 1) seq bp <= bpx; wp <= wpx; // Calculate single 2D filter convolution for ( p <= 0; p < p_limit; p <= p + 1) action dotp.incrementWait; rEngine.readServers[0].request.put(MemengineCmd{sglId:param.objectId, base:extend(bp), len:q_limit, burstLen:burstLenInBytes, tag: 0}); rEngine.readServers[1].request.put(MemengineCmd{sglId:param.objectId, base:extend(wp), len:q_limit, burstLen:burstLenInBytes, tag: 0}); bp <= bp + param.conv_in_width; wp <= wp + param.kernel_w; endaction bpx <= bpx + param.bottom_hw; wpx <= wpx + param.kernel_hw; endseq endseq); interface ConvRequest request; method Action init(ConnectalParamType aparam); param <= aparam; dtypeFloat <= (aparam.baseSize == 4); if (!dumpStart) begin //$dumpon; dumpStart <= True; end endmethod method Action forward_kernel(Bit#(32) ap_limit, Bit#(32) aq_limit, Bit#(1) askip, Float atemp, Bit#(32) abpx, Bit#(32) awpx, Bit#(32) aoutputp) if (!fsmRunning); p_limit <= ap_limit; q_limit <= aq_limit; skip <= askip; dotp.init(atemp); bpx <= extend(abpx); wpx <= extend(awpx); outputp <= aoutputp; fsmRunning <= True; fsm.start(); endmethod endinterface interface readDma = cons(rEngine.dmaClient, nil); interface writeDma = cons(wEngine.dmaClient, nil); endmodule //void backward_bias(const ParamType *param, CPtr tptr) //{ // int output_hw = param->height_out_ * param->width_out_ * sizeof(Dtype); // for (int j = 0; j < param->num_output_ * sizeof(Dtype); j += sizeof(Dtype)) { // Dtype temp = 0; // for (int i = 0; i < output_hw; i += sizeof(Dtype)) { // temp += *CACCESS(tptr) * *CACCESS(param->bias_multiplier_ + i); // tptr += sizeof(Dtype); // } // *CACCESS(param->bias_diff + j) += temp; // } //} //void backward_kernel(const ParamType *param, int pad_x, int pad_y, int gchan, int wchan, Dtype chain_grad, CPtr bottom_bp, CPtr bottom_diff_bp) //{ // int p_start = MAX(0, pad_y); // int p_limit = MIN(param->kernel_h_ * sizeof(Dtype), param->conv_in_height_ * sizeof(Dtype) + pad_y); // int q_start = MAX(0, pad_x); // int q_limit = MIN(param->kernel_w_ * sizeof(Dtype), param->conv_in_width_ * sizeof(Dtype) + pad_x); // for (int p = p_start; p < p_limit; p += sizeof(Dtype)) { // for (int q = q_start; q < q_limit; q += sizeof(Dtype)) { // int belement = gchan + p * param->conv_in_width_ + q; // int welement = wchan + p * param->kernel_w_ + q; // // gradient w.r.t. weight. Note that we will accumulate diffs. // if (param->weight_diff) // *CACCESS(param->weight_diff + welement) += *CACCESS(bottom_bp + belement) * chain_grad; // // gradient w.r.t. bottom data, if necessary. // if (bottom_diff_bp) // *CACCESS(bottom_diff_bp + belement) += *CACCESS(param->weight + welement) * chain_grad; // } // } //} ================================================ FILE: examples/caffe/INSTALL ================================================ cmake libboost-all-dev libgoogle-glog-dev libprotobuf-dev protobuf-compiler libhdf5-dev liblmdb-dev libleveldb-dev libsnappy-dev libopencv-dev libatlas-dev libatlas-blas-dev libblas-dev libopenblas-dev libatlas-base-dev libpapi-dev ================================================ FILE: examples/caffe/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ConvRequest:Conv.request H2S_INTERFACES = Conv:ConvIndication MEM_READ_INTERFACES = lConv.readDma MEM_WRITE_INTERFACES = lConv.writeDma # Direct convolution/gradient calculation version CPPFILES = $(CONNECTALDIR)/lib/cpp/connectal_conv.cpp BSVFILES = Conv.bsv CONNECTALFLAGS += --shared --bsvpath $(CONNECTALDIR)/lib/matmul/bsv include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/caffe/README.md ================================================ apt-get install libopencv-dev libopencv-core-dev apt-get install autoconf apt-get install libtool apt-get install gtkwave apt-get install cmake apt-get install boost apt-get install libboost-dev apt-get install libboost-system apt-get install libboost-system-dev libboost-thread-dev apt-get install libgoogle-glog-dev glib-dev apt-get install libgoogle-glog-dev apt-get install libhdf5-dev apt-get install liblmdb-dev apt-get install libleveldb-dev apt-get install libsnappy-dev apt-get install libatlas-dev apt-get install libopenblas-dev apt-get install libatlas-dev libblas-test libopenblas-dev libatlas-cpp-0.6-dev libatlas-base-dev apt-get install python-numpy apt-get install libboost-python-dev apt-get install python-numpy apt-get install gfortran ================================================ FILE: examples/echo/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echo/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv CPPFILES= testecho.cpp CONNECTALFLAGS += -D TRACE_PORTAL include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echo/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/echo2ind/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request1; interface EchoRequest request2; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication1, EchoIndication indication2)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication1.heard(delay.first); endrule rule heard2; delay2.deq; indication2.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request1; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface interface EchoRequest request2; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echo2ind/Makefile ================================================ # Test program for multiple interfaces of same datatype CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request1,Echo.request2 H2S_INTERFACES = Echo:EchoIndication,EchoIndication BSVFILES = Echo.bsv CPPFILES= testecho.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echo2ind/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static EchoRequestProxy *echoRequestProxy1 = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; EchoIndication echoIndication(IfcNames_EchoIndicationH2S0); EchoIndication echoIndication1(IfcNames_EchoIndicationH2S1); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H0); echoRequestProxy1 = new EchoRequestProxy(IfcNames_EchoRequestS2H1); int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/echofast/Makefile ================================================ CONNECTALFLAGS += -D BSV_POSITIVE_RESET ifeq ($(BOARD),zedboard) MAIN_CLOCK_PERIOD=5.0 DERIVED_CLOCK_PERIOD=10.0 endif ifeq ($(BOARD),zc706) MAIN_CLOCK_PERIOD=2.0 DERIVED_CLOCK_PERIOD=5.0 endif include ../echo/Makefile ================================================ FILE: examples/echohost/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; import ConnectalConfig::*; import HostInterface::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(HostInterface host, EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echohost/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request:host H2S_INTERFACES = Echo:EchoIndication:host BSVFILES = ../echo/Echo.bsv CPPFILES= ../echo/testecho.cpp ## for testing fpgamake: FPGAMAKE_CONNECTALFLAGS += -P mkEchoIndicationProxySynth -P mkEchoRequestWrapperMemPortalPipes PORTAL_DUMP_MAP = "EchoIndication:EchoRequest:SwallowRequest" CONNECTALFLAGS += -D IMPORT_HOSTIF include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echohost/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/echohost/vc707_floorplan.xdc ================================================ startgroup create_pblock pblock_ep7 resize_pblock pblock_ep7 -add {SLICE_X184Y54:SLICE_X221Y166 DSP48_X18Y22:DSP48_X19Y65 RAMB18_X12Y22:RAMB18_X14Y65 RAMB36_X12Y11:RAMB36_X14Y32} add_cells_to_pblock pblock_ep7 [get_cells [list host_ep7]] -clear_locs set_property HD.PARTPIN_RANGE {SLICE_X185Y54:SLICE_X186Y166} [get_pins host_ep7/*] set_property CONTAIN_ROUTING true [get_pblocks pblock_ep7] endgroup startgroup create_pblock pblock_pciehost resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X173Y197 DSP48_X9Y22:DSP48_X16Y77 RAMB18_X7Y22:RAMB18_X10Y77 RAMB36_X7Y11:RAMB36_X10Y38} add_cells_to_pblock pblock_pciehost [get_cells [list host_pciehost]] -clear_locs set_property HD.PARTPIN_RANGE {SLICE_X112Y55:SLICE_X113Y197} [get_pins host_pciehost/*] set_property HD.PARTPIN_RANGE {SLICE_X172Y55:SLICE_X173Y197} [get_pins host_pciehost/*pci_re*] set_property HD.PARTPIN_RANGE {SLICE_X172Y55:SLICE_X173Y197} [get_pins host_pciehost/*pci*] set_property CONTAIN_ROUTING true [get_pblocks pblock_pciehost] endgroup # startgroup # create_pblock pblock_pciehost # resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X221Y197 DSP48_X9Y22:DSP48_X19Y77 RAMB18_X7Y22:RAMB18_X14Y77 RAMB36_X7Y11:RAMB36_X14Y38} # add_cells_to_pblock pblock_pciehost [get_cells [list host]] -clear_locs # set_property HD.PARTPIN_RANGE {SLICE_X112Y55:SLICE_X113Y197} [get_pins host/*] # endgroup ================================================ FILE: examples/echoinvert/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import Vector::*; import EchoInterface::*; import EchoIndication::*; interface Echo; interface EchoRequest request; interface EchoIndicationInverse inverseIfc; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho(Echo); `ifdef BOARD_bluesim let inv <- mkEchoIndicationInverter; `else let inv <- mkEchoIndicationInverterV; `endif EchoIndication indication = inv.ifc; FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); Reg#(Bool) dumpStart <- mkReg(False); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); if (!dumpStart) begin $dumpon; dumpStart <= True; end delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface interface inverseIfc = inv.inverseIfc; endmodule ================================================ FILE: examples/echoinvert/EchoInterface.bsv ================================================ interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface ================================================ FILE: examples/echoinvert/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = !Echo:EchoIndication BSVFILES = EchoInterface.bsv CPPFILES= testecho.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echoinvert/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/echojson/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echojson/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request SwallowRequest:Swallow.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv Swallow.bsv CPPFILES=testecho.cpp CPPFILES2=daemon.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echojson/Swallow.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface SwallowRequest; method Action swallow(Bit#(32) v); endinterface interface Swallow; interface SwallowRequest request; endinterface module mkSwallow(Swallow); Reg#(Bit#(32)) sink <- mkReg(0); interface SwallowRequest request; method Action swallow(Bit#(32) v); sink <= v; endmethod endinterface endmodule ================================================ FILE: examples/echojson/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *echoRequestProxy; EchoIndicationProxy *sIndicationProxy; static int daemon_trace ;//= 1; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t v) { if (daemon_trace) fprintf(stderr, "daemon: %p heard an echo: %d\n", sIndicationProxy, v); sIndicationProxy->heard(v); } void heard2(uint16_t a, uint16_t b) { if (daemon_trace) fprintf(stderr, "daemon: %p heard an echo2: %d %d\n", sIndicationProxy, a, b); sIndicationProxy->heard2(a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; class EchoRequest : public EchoRequestWrapper { public: void say ( const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d] proxy %p\n", __FUNCTION__, __LINE__, echoRequestProxy); echoRequestProxy->say(v); } void say2 ( const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d] proxy %p\n", __FUNCTION__, __LINE__, echoRequestProxy); echoRequestProxy->say2(a, b); } void setLeds ( const uint8_t v ) { fprintf(stderr, "daemon[%s:%d] proxy %p\n", __FUNCTION__, __LINE__, echoRequestProxy); echoRequestProxy->setLeds(v); sleep(1); exit(1); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestWrapper(id, item, param, &EchoRequestJson_handleMessage, 1000) {} }; int main(int argc, const char **argv) { PortalSocketParam param; //#define USE_UNIX_SOCKET #ifdef USE_UNIX_SOCKET #define PARAM NULL #else #define PARAM ¶m #endif EchoIndication *echoIndication = new EchoIndication(IfcNames_EchoIndicationH2S, NULL, NULL); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int rc = getaddrinfo("127.0.0.1", "5000", NULL, ¶m.addr); sIndicationProxy = new EchoIndicationProxy(IfcNames_EchoIndicationH2S, &transportSocketResp, PARAM, &EchoIndicationJsonProxyReq, 1000); rc = getaddrinfo("127.0.0.1", "5001", NULL, ¶m.addr); EchoRequest *sRequest = new EchoRequest(IfcNames_EchoRequestS2H, &transportSocketResp, PARAM); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: examples/echojson/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *sRequestProxy; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { fprintf(stderr, "heard an s: %d\n", v); sRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { fprintf(stderr, "heard an s2: %ld %ld\n", (long)a, (long)b); sem_post(&sem_heard2); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param, &EchoIndicationJson_handleMessage, 1000) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { sRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { PortalSocketParam param = {0}; //#define USE_UNIX_SOCKET #ifdef USE_UNIX_SOCKET #define PARAM NULL #else #define PARAM ¶m #endif int rc = getaddrinfo("127.0.0.1", "5000", NULL, ¶m.addr); EchoIndication *sIndication = new EchoIndication(IfcNames_EchoIndicationH2S, &transportSocketInit, PARAM); rc = getaddrinfo("127.0.0.1", "5001", NULL, ¶m.addr); sRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H, &transportSocketInit, PARAM, &EchoRequestJsonProxyReq, 1000); int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); sRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/echojsonpy/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) x); method Action heard2(Bit#(16) x, Bit#(16) y); endinterface interface EchoRequest; method Action say(Bit#(32) x); method Action say2(Bit#(16) x, Bit#(16) y); method Action setLeds(Bit#(8)x); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echojsonpy/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request SwallowRequest:Swallow.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv Swallow.bsv CPPFILES=daemon.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echojsonpy/Swallow.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface SwallowRequest; method Action swallow(Bit#(32) v); endinterface interface Swallow; interface SwallowRequest request; endinterface module mkSwallow(Swallow); Reg#(Bit#(32)) sink <- mkReg(0); interface SwallowRequest request; method Action swallow(Bit#(32) v); sink <= v; endmethod endinterface endmodule ================================================ FILE: examples/echojsonpy/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoIndicationProxy *sIndicationProxy; static int daemon_trace = 1; class EchoRequest : public EchoRequestWrapper { public: void say ( const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon say(%d)\n", v); sIndicationProxy->heard(v); } void say2 ( const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon say2(%d, %d)\n", a,b); sIndicationProxy->heard2(a, b); } void setLeds ( const uint8_t v ) { if (daemon_trace) fprintf(stderr, "daemon setLeds(%d)\n", v); sleep(1); exit(1); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestWrapper(id, item, param, &EchoRequestJson_handleMessage, 1000) {} }; int main(int argc, const char **argv) { PortalSocketParam param; //talk to testecho.py int rc = getaddrinfo("0.0.0.0", "5000", NULL, ¶m.addr); sIndicationProxy = new EchoIndicationProxy(IfcNames_EchoIndicationH2S, &transportSocketResp, ¶m, &EchoIndicationJsonProxyReq, 1000); rc = getaddrinfo("0.0.0.0", "5001", NULL, ¶m.addr); EchoRequest *sRequest = new EchoRequest(IfcNames_EchoRequestS2H, &transportSocketResp, ¶m); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: examples/echojsonpy/old_testecho.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import sys import socket import struct import time import ctypes import json import math class BaseClass(object): def __init__(self, classtype): self._type = classtype class socket_client: def __init__(self, devaddr, devport): self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.connect((devaddr, devport)) self.llen = ctypes.sizeof(ctypes.c_int); def recv_frame(self): bytes_recd = 0 while bytes_recd < self.llen: chunk = self.s.recv(self.llen) bytes_recd = len(chunk) liw = struct.unpack("hh", chunk)[0] blen = (liw-1)*self.llen bytes_recd = 0 buffer = [] while bytes_recd < blen: chunk = self.s.recv(blen) bytes_recd += len(chunk) buffer.append(chunk) rv = buffer[0] for b in buffer[1:]: rv = rv + b return rv def send_frame(self, data): liw = math.ceil(len(data)/4.0) padding = ''.join([' ' for i in range(len(data), int(liw*4))]) print("send_frame (%d) %d %s" % (len(data),liw, data)) self.s.send(struct.pack("@i", (1+liw))+data+padding) def shutdown(self): self.s.shutdown(socket.SHUT_RDWR) self.s.close() def toascii(u): return u.encode('ascii', 'replace') def createSendMethod(methname): def method(self, d): d['name'] = methname js = json.dumps(d, separators=(',',':'), sort_keys=True) self.s.send_frame(js) return (methname,method) def createDefaultCallbackMethod(methname): def method(self, d): print("default %s(%s)" %(methname, str(d))) return (methname,method) def createWrapperEvent(meths): def method(self): msg = self.s.recv_frame() d = json.loads(msg) n = d.pop('name') getattr(self, n)(d) return method def ProxyClassFactory(name, meths, BaseClass=BaseClass): def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) BaseClass.__init__(self, name[:-len("Class")]) newclass = type(toascii(name), (BaseClass,),dict([("__init__",__init__)]+list(map(createSendMethod, meths)))) return newclass def WrapperClassFactory(name, meths, BaseClass=BaseClass): def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) BaseClass.__init__(self, name[:-len("Class")]) newclass = type(toascii(name), (BaseClass,),dict([("__init__",__init__), ("event", createWrapperEvent(meths))]+list(map(createDefaultCallbackMethod, meths)))) return newclass if __name__ == "__main__": ind_addr = "127.0.0.1" ind_port = 5000 req_addr = "127.0.0.1" req_port = 5001 ind_s = socket_client(ind_addr, ind_port) req_s = socket_client(req_addr, req_port) json_data=open('./bluesim/generatedDesignInterfaceFile.json') data = json.load(json_data) json_data.close() proxy_classes = {} wrapper_classes = {} for ifc in data['interfaces']: methods = [decl['name'] for decl in ifc['decls']] proxy_classes[ifc['name']] = ProxyClassFactory(ifc['name'], methods) wrapper_classes[ifc['name']] = WrapperClassFactory(ifc['name'], methods) ei = wrapper_classes['EchoIndication'](s=ind_s) er = proxy_classes['EchoRequest'](s=req_s) def new_heard(d): print("new heard(%s)" %(str(d))) er.say({'x':1}) ei.event() er.say({'x':1}) setattr(ei,'heard', new_heard) ei.event() er.say2({'x':2,'y':1}) ei.event() er.setLeds({'x':0}) time.sleep(1) req_s.shutdown() ind_s.shutdown() ================================================ FILE: examples/echojsonpy/testecho.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import time import sys import os import argparse sys.path.append(os.path.abspath('../../scripts')) import portalJson if __name__ == "__main__": argparser = argparse.ArgumentParser('Display gyroscope data') argparser.add_argument('-a', '--address', help='Device address', default=None) options = argparser.parse_args() print(options.address) if not options.address: options.address = os.environ['RUNPARAM'] ind_port = 5000 req_port = 5001 ind_p = portalJson.portal(options.address, ind_port) req_p = portalJson.portal(options.address, req_port) d = {'name':'say','x':1} print(d) req_p.send(d) print(ind_p.recv()) d = {'name':'say','x':3} print(d) req_p.send(d) print(ind_p.recv()) d = {'name':'say2','x':2,'y':1} print(d) req_p.send(d) print(ind_p.recv()) d = {'name':'setLeds','x':0} print(d) req_p.send(d) time.sleep(1) req_p.shutdown() ind_p.shutdown() ================================================ FILE: examples/echomux/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndicationSW; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequestSW; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface EchoIndication; method Action heard(Bit#(32) id, Bit#(32) v); method Action heard2(Bit#(32) id, Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) id, Bit#(32) v); method Action say2(Bit#(32) id, Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(32) id, Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(32) id; Bit#(32) v; } EchoPair1 deriving (Bits); typedef struct { Bit#(32) id; Bit#(16) a; Bit#(16) b; } EchoPair2 deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(EchoPair1) delay1 <- mkSizedFIFO(8); FIFO#(EchoPair2) delay2 <- mkSizedFIFO(8); rule heard; delay1.deq; indication.heard(delay1.first.id, delay1.first.v); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.id, delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) id, Bit#(32) v); delay1.enq(EchoPair1 { id: id, v: v}); endmethod method Action say2(Bit#(32) id, Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair2 { id: id, a: a, b: b}); endmethod method Action setLeds(Bit#(32) id, Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echomux/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = EchoRequestSW EchoIndicationSW SecondRequest SecondIndication ThirdRequest ThirdIndication S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv Services.bsv CPPFILES=testecho.cpp CPPFILES2=daemon.cpp AUTOTOP = --portname IfcNames_SecondRequest --portname IfcNames_SecondIndication --portname IfcNames_ThirdRequest --portname IfcNames_ThirdIndication include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echomux/Services.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface EchoIndicationSW; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequestSW; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface SecondRequest; method Action say(Bit#(32) v, Bit#(64) a, Bit#(32)b); endinterface interface SecondIndication; method Action heard(Bit#(32) v, Bit#(32) a); endinterface interface ThirdRequest; method Action say(); endinterface interface ThirdIndication; method Action heard(); endinterface ================================================ FILE: examples/echomux/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" #include "EchoRequestSW.h" #include "EchoIndicationSW.h" #include "SecondRequest.h" #include "SecondIndication.h" #include "ThirdRequest.h" #include "ThirdIndication.h" EchoIndicationSWProxy *sIndicationProxy; EchoRequestProxy *echoRequestProxy; static int daemon_trace = 1; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t id, uint32_t v) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo: id %d %d\n", id, v); this->pint.request_index = id; sIndicationProxy->heard(v); } void heard2(uint32_t id, uint16_t a, uint16_t b) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo2: id %d %d %d\n", id, a, b); this->pint.request_index = id; sIndicationProxy->heard2(a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; class EchoRequest : public EchoRequestSWWrapper { public: void say ( const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon[%s] id %d %d\n", __FUNCTION__, this->pint.indication_index, v); echoRequestProxy->say(this->pint.indication_index, v); } void say2 ( const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon[%s] id %d %d %d\n", __FUNCTION__, this->pint.indication_index, a, b); echoRequestProxy->say2(this->pint.indication_index, a, b); } void setLeds ( const uint8_t v ) { fprintf(stderr, "daemon[%s] id %d %d\n", __FUNCTION__, this->pint.indication_index, v); echoRequestProxy->setLeds(this->pint.indication_index, v); } void disconnect(void) { fprintf(stderr, "daemon[%s] id %d\n", __FUNCTION__, this->pint.indication_index); sleep(1); exit(1); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestSWWrapper(id, item, param) {} }; SecondIndicationProxy *sSecondIndicationProxy; class SecondRequest : public SecondRequestWrapper { public: void say(uint32_t v, uint64_t a, uint32_t b) { if (daemon_trace) fprintf(stderr, "daemonSecond[%s] %d %lld %d\n", __FUNCTION__, v, (long long)a, b); sSecondIndicationProxy->pint.request_index = this->pint.indication_index; sSecondIndicationProxy->heard(v*4, a*2); } SecondRequest(unsigned int id, PortalTransportFunctions *item, void *param) : SecondRequestWrapper(id, item, param) {} }; ThirdIndicationProxy *sThirdIndicationProxy; class ThirdRequest : public ThirdRequestWrapper { public: void say ( ) { if (daemon_trace) fprintf(stderr, "daemonThird[%s]\n", __FUNCTION__); sThirdIndicationProxy->pint.request_index = this->pint.indication_index; sThirdIndicationProxy->heard(); } ThirdRequest(unsigned int id, PortalTransportFunctions *item, void *param) : ThirdRequestWrapper(id, item, param) {} }; int main(int argc, const char **argv) { PortalSocketParam paramSocket = {}; PortalMuxParam param = {}; EchoIndication echoIndication(IfcNames_EchoIndicationH2S, NULL, NULL); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); Portal *mcommon = new Portal(0, 0, sizeof(uint32_t), portal_mux_handler, NULL, &transportSocketResp, ¶mSocket, 0); param.pint = &mcommon->pint; sIndicationProxy = new EchoIndicationSWProxy(IfcNames_EchoIndicationH2S, &transportMux, ¶m); EchoRequest sRequest(IfcNames_EchoRequestS2H, &transportMux, ¶m); sSecondIndicationProxy = new SecondIndicationProxy(IfcNames_SecondIndication, &transportMux, ¶m); SecondRequest sSecondRequest(IfcNames_SecondRequest, &transportMux, ¶m); sThirdIndicationProxy = new ThirdIndicationProxy(IfcNames_ThirdIndication, &transportMux, ¶m); ThirdRequest sThirdRequest(IfcNames_ThirdRequest, &transportMux, ¶m); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: examples/echomux/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequestSW.h" #include "EchoIndicationSW.h" #include "SecondRequest.h" #include "SecondIndication.h" #include "ThirdRequest.h" #include "ThirdIndication.h" static sem_t semEcho; EchoRequestSWProxy *sEcho; class EchoIndication : public EchoIndicationSWWrapper { public: virtual void heard(uint32_t v) { fprintf(stderr, "heard an s: %d\n", v); sEcho->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&semEcho); //fprintf(stderr, "heard an s2: %ld %ld\n", a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationSWWrapper(id, item, param) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); sEcho->say(v); sem_wait(&semEcho); } static void call_say2(int v, int v2) { sEcho->say2(v, v2); sem_wait(&semEcho); } //static sem_t semSecond; SecondRequestProxy *sSecond; class SecondIndication : public SecondIndicationWrapper { public: virtual void heard(uint32_t v, uint32_t a) { fprintf(stderr, "Secondheard an s: %d %d\n", v, a); } SecondIndication(unsigned int id, PortalTransportFunctions *item, void *param) : SecondIndicationWrapper(id, item, param) {} }; //static sem_t semThird; ThirdRequestProxy *sThird; class ThirdIndication : public ThirdIndicationWrapper { public: virtual void heard() { fprintf(stderr, "Thirdheard\n"); } ThirdIndication(unsigned int id, PortalTransportFunctions *item, void *param) : ThirdIndicationWrapper(id, item, param) {} }; int main(int argc, const char **argv) { PortalSocketParam paramSocket = {}; PortalMuxParam param = {}; Portal *mcommon = new Portal(0, 0, sizeof(uint32_t), portal_mux_handler, NULL, &transportSocketInit, ¶mSocket, 0); param.pint = &mcommon->pint; EchoIndication sIndication(IfcNames_EchoIndicationH2S, &transportMux, ¶m); sEcho = new EchoRequestSWProxy(IfcNames_EchoRequestS2H, &transportMux, ¶m); SecondIndication sSecondIndication(IfcNames_SecondIndication, &transportMux, ¶m); sSecond = new SecondRequestProxy(IfcNames_SecondRequest, &transportMux, ¶m); ThirdIndication sThirdIndication(IfcNames_ThirdIndication, &transportMux, ¶m); sThird = new ThirdRequestProxy(IfcNames_ThirdRequest, &transportMux, ¶m); int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); sSecond->say(v*99, v * 1000000000L, v*55); call_say(v*5); sThird->say(); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); sEcho->setLeds(9); return 0; } ================================================ FILE: examples/echoproto/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; import EchoRequest::*; import EchoIndication::*; import GeneratedTypes::*; interface Echo; interface EchoRequest request; endinterface module mkEcho#(EchoIndication indication)(Echo); FIFO#(EchoHeard) delay <- mkSizedFIFO(8); FIFO#(EchoHeard2) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first); endrule interface EchoRequest request; method Action say(EchoSay v); delay.enq(EchoHeard{v: v.v}); endmethod method Action say2(EchoSay2 v); delay2.enq(EchoHeard2{ a: v.a, b: v.b}); endmethod method Action setLeds(EchoLeds v); endmethod endinterface endmodule ================================================ FILE: examples/echoproto/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication CPPFILES=testecho.cpp #CONNECTALFLAGS += --protobuf interface.json CONNECTALFLAGS += --protobuf echo_pb.json include $(CONNECTALDIR)/Makefile.connectal prebuild:: $(CONNECTALDIR)/../protobuf/src/protoc --cpp_out=. --bsv_out=. echo.proto ================================================ FILE: examples/echoproto/echo.proto ================================================ syntax = "proto2"; package echo; message EchoSay { required fixed32 v = 1; } message EchoSay2 { required fixed32 a = 1; required fixed32 b = 2; } message EchoLeds { required fixed32 v = 1; } message EchoHeard { required fixed32 v = 1; } message EchoHeard2 { required fixed32 a = 1; required fixed32 b = 2; } message Empty { } service EchoRequest { rpc say (EchoSay) returns (Empty); rpc say2 (EchoSay2) returns (Empty); rpc setLeds (EchoLeds) returns (Empty); } service EchoIndication { rpc heard (EchoHeard) returns (Empty); rpc heard2 (EchoHeard2) returns (Empty); } ================================================ FILE: examples/echoproto/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" #include "topEnum.h" static EchoRequestProxy *echoRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(EchoHeard v) { EchoSay2 tmp = {v.v, 2*v.v}; printf("heard an echo: %d\n", v.v); echoRequestProxy->say2(tmp); } virtual void heard2(EchoHeard2 v) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(fixed32 v) { EchoSay tmp = {v}; printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(tmp); sem_wait(&sem_heard2); } static void call_say2(fixed32 v, fixed32 v2) { EchoSay2 tmp = {v, v2}; echoRequestProxy->say2(tmp); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); EchoLeds tmp = {9}; echoRequestProxy->setLeds(tmp); return 0; } ================================================ FILE: examples/echopy/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; import EchoInterface::*; interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoResponse indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); $display("say %h", v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); $display("say2 %h %h", a, b); delay2.enq(EchoPair { a: a, b: b}); endmethod endinterface endmodule ================================================ FILE: examples/echopy/EchoInterface.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface EchoResponse; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); endinterface ================================================ FILE: examples/echopy/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoResponse BSVFILES = EchoInterface.bsv PYFILES = testecho.py CONNECTALFLAGS += --run-args="$(PWD)/testecho.py $(CONNECTALDIR)/scripts/portal.py $(PWD)/$(BOARD)/bin/connectal.so" CONNECTALFLAGS += -D PYTHONPATH="$(CONNECTALDIR)/scripts:." -D CONNECTALDIR="$(CONNECTALDIR)" ifeq ($(BOARD),zedboard_ubuntu) prebuild:: ./ubuntu-python-dev.sh endif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echopy/testecho.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # from __future__ import print_function import ctypes, json, os, sys, threading, time, portal class Echo: def __init__(self): self.proxy = portal.NativeProxy('EchoRequest', self, responseInterface='EchoResponse', rpc=True) self.response = None def call_say(self, a): self.proxy.say(a) print('say response:', self.response) def call_say2(self, a, b): self.proxy.say2(a, b) print('say2 response:', self.response) def heard(self, v): print('heard called!!!', v) self.response = v def heard2(self, a, b): print('heard2 called!!!', a, b) self.response = (a,b) echo = Echo() v = 42 print("Saying %d" % v) echo.call_say(v); echo.call_say2(v, v*3); echo.call_say(v*5); echo.call_say(v*17); echo.call_say(v*93); echo.proxy.stopPolling = True ================================================ FILE: examples/echopy/ubuntu-python-dev.sh ================================================ #!/bin/sh for path in p/python2.7/libpython2.7_2.7.11-7ubuntu1_armhf p/python2.7/libpython2.7-dev_2.7.11-7ubuntu1_armhf libj/libjsoncpp/libjsoncpp1_1.7.2-1_armhf libj/libjsoncpp/libjsoncpp-dev_1.7.2-1_armhf; do pkg=`basename $path` [ -f $pkg.deb ] || ( wget http://ports.ubuntu.com/ubuntu-ports/pool/main/$path.deb; ar x $pkg.deb; xzcat data.tar.xz | tar -xvf - ) done sed -i "s|#define _POSIX_C_SOURCE 200112L|/* _POSIX_C_SOURCE defined by features.h*/|" usr/include/arm-linux-gnueabihf/python2.7/pyconfig.h sed -i "s|#define _XOPEN_SOURCE 600|/* _XOPEN_SOURCE defined by features.h*/|" usr/include/arm-linux-gnueabihf/python2.7/pyconfig.h rm -f data.tar.xz control.tar.gz debian-binary ================================================ FILE: examples/echoshared/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echoshared/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication INTERFACES = MMURequest MMUIndication MemServerRequest MemServerIndication BSVFILES = Echo.bsv $(CONNECTALDIR)/bsv/ConnectalMemory.bsv CPPFILES=testecho.cpp $(CONNECTALDIR)/cpp/transportShared.c $(CONNECTALDIR)/cpp/dmaManager.c CPPFILES2=daemon.cpp $(CONNECTALDIR)/cpp/transportShared.c $(CONNECTALDIR)/cpp/dmaManager.c AUTOTOP = --portname MMURequestS2H --portname MMUIndicationH2S include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echoshared/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "EchoRequest.h" #include "EchoIndication.h" #include "MMUServer.h" static EchoRequestProxy *echoRequestProxy; static EchoIndicationProxy *sIndicationProxy; static int daemon_trace;// = 1; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t v) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo: %d\n", v); sIndicationProxy->heard(v); } void heard2(uint16_t a, uint16_t b) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo2: %d %d\n", a, b); sIndicationProxy->heard2(a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; class EchoRequest : public EchoRequestWrapper { public: void say ( const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->say(v); } void say2 ( const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->say2(a, b); } void setLeds ( const uint8_t v ) { fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->setLeds(v); sleep(1); exit(0); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestWrapper(id, item, param) {} }; static EchoRequest *sRequest; int main(int argc, const char **argv) { EchoIndication echoIndication(IfcNames_EchoIndicationH2S, NULL, NULL); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); sRequest = new EchoRequest(IfcNames_EchoRequestS2H, &transportShared, NULL); sIndicationProxy = new EchoIndicationProxy(IfcNames_EchoIndicationH2S, &transportShared, NULL); MMUServer *mServer = new MMUServer(IfcNames_MMURequestS2H, new MMUIndicationProxy(IfcNames_MMUIndicationH2S, &transportSocketResp, NULL), &transportSocketResp, NULL); mServer->registerInterface(IfcNames_EchoRequestS2H, &sRequest->pint); mServer->registerInterface(IfcNames_EchoIndicationH2S, &sIndicationProxy->pint); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: examples/echoshared/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "EchoRequest.h" #include "EchoIndication.h" #include "dmaManager.h" #define LOOP_COUNT 2 EchoRequestProxy *sRequestProxy; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { fprintf(stderr, "heard an s: %d\n", v); sRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //fprintf(stderr, "heard an s2: %d %d\n", a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { sRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { int alloc_sz = 64-4; DmaManager *dma = platformInit(); PortalSharedParam param = {{dma}, (uint32_t)alloc_sz}; EchoIndication sIndication(IfcNames_EchoIndicationH2S, &transportShared, ¶m); sRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H, &transportShared, ¶m); for (int i = 0; i < LOOP_COUNT; i++) { int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); } sRequestProxy->setLeds(9); sleep(2); return 0; } ================================================ FILE: examples/echoslow/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import FIFO::*; import GetPut::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(Clock derivedClock, Reset derivedReset, EchoIndication indication)(Echo); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; let delay_toslow <- mkSyncFIFO(16, clock, reset, derivedClock); let delay_fromslow <- mkSyncFIFO(16, derivedClock, derivedReset, clock); let delay2_toslow <- mkSyncFIFO(16, clock, reset, derivedClock); let delay2_fromslow <- mkSyncFIFO(16, derivedClock, derivedReset, clock); rule heard_slow; // derivedClock domain let v <- toGet(delay_toslow).get(); delay_fromslow.enq(v); endrule rule hear_fast; let v <- toGet(delay_fromslow).get(); indication.heard(v); endrule rule heard2_slow; // derivedClock domain let v <- toGet(delay2_toslow).get(); delay2_fromslow.enq(v); endrule rule heard2_fast; let v <- toGet(delay2_fromslow).get(); indication.heard2(v.b, v.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay_toslow.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2_toslow.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echoslow/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication:host.derivedClock,host.derivedReset BSVFILES = Echo.bsv CPPFILES= ../echo/testecho.cpp CONNECTALFLAGS += -D IMPORT_HOST_CLOCKS CONNECTALFLAGS += --derivedclockperiod=125 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echosoft/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echosoft/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request SwallowRequest:Swallow.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv Swallow.bsv CPPFILES=testecho.cpp CPPFILES2=daemon.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echosoft/Swallow.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface SwallowRequest; method Action swallow(Bit#(32) v); endinterface interface Swallow; interface SwallowRequest request; endinterface module mkSwallow(Swallow); Reg#(Bit#(32)) sink <- mkReg(0); interface SwallowRequest request; method Action swallow(Bit#(32) v); sink <= v; endmethod endinterface endmodule ================================================ FILE: examples/echosoft/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *echoRequestProxy; EchoIndicationProxy *sIndicationProxy; static int daemon_trace;// = 1; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t v) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo: %d\n", v); sIndicationProxy->heard(v); } void heard2(uint16_t a, uint16_t b) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo2: %d %d\n", a, b); sIndicationProxy->heard2(a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; class EchoRequest : public EchoRequestWrapper { public: void say ( const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->say(v); } void say2 ( const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->say2(a, b); } void setLeds ( const uint8_t v ) { fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->setLeds(v); } void disconnect (void) { fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); sleep(1); exit(1); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestWrapper(id, item, param) {} }; int main(int argc, const char **argv) { PortalSocketParam param; //#define USE_UNIX_SOCKET #ifdef USE_UNIX_SOCKET #define PARAM NULL #else #define PARAM ¶m #endif EchoIndication echoIndication(IfcNames_EchoIndicationH2S, NULL, NULL); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); getaddrinfo("127.0.0.1", "5000", NULL, ¶m.addr); sIndicationProxy = new EchoIndicationProxy(IfcNames_EchoIndicationH2S, &transportSocketResp, PARAM); getaddrinfo("127.0.0.1", "5001", NULL, ¶m.addr); EchoRequest sRequest(IfcNames_EchoRequestS2H, &transportSocketResp, PARAM); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: examples/echosoft/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *sRequestProxy; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t v) { fprintf(stderr, "heard an s: %d\n", v); sRequestProxy->say2(v, 2*v); } void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //fprintf(stderr, "heard an s2: %ld %ld\n", a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { sRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { PortalSocketParam param = {0}; //#define USE_UNIX_SOCKET #ifdef USE_UNIX_SOCKET #define PARAM NULL #else #define PARAM ¶m #endif getaddrinfo("127.0.0.1", "5000", NULL, ¶m.addr); EchoIndication sIndication(IfcNames_EchoIndicationH2S, &transportSocketInit, PARAM); getaddrinfo("127.0.0.1", "5001", NULL, ¶m.addr); sRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H, &transportSocketInit, PARAM); int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); sRequestProxy->setLeds(9); portal_disconnect(&sRequestProxy->pint); portal_disconnect(&sIndication.pint); sleep(10); return 0; } ================================================ FILE: examples/echotrace/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echotrace/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = MMURequest S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv $(CONNECTALDIR)/bsv/ConnectalMemory.bsv CPPFILES=testecho.cpp $(CONNECTALDIR)/cpp/transportShared.c $(CONNECTALDIR)/cpp/dmaManager.c include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echotrace/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "dmaManager.h" #include "EchoIndication.h" #include "EchoRequest.h" static EchoRequestProxy *echoRequestProxy, *echoRequestTrace; static sem_t sem_heard2; static void memdump(uint8_t *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printf("\n"); printf("%s: ",title); } printf("%02x ", *p++); i++; len--; } printf("\n"); } class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); echoRequestTrace->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); echoRequestTrace->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); echoRequestTrace->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int alloc_sz = 1000; PortalSharedParam param = {{NULL}, (uint32_t)alloc_sz}; echoRequestTrace = new EchoRequestProxy(IfcNames_EchoRequestS2H, &transportTrace, ¶m); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); echoRequestTrace->setLeds(9); volatile unsigned int *p = echoRequestTrace->pint.map_base; printf("[%s] Dump trace buffer: limit %d write %d read %d start %d\n", __FUNCTION__, p[SHARED_LIMIT], p[SHARED_WRITE], p[SHARED_READ], p[SHARED_START]); uint32_t current = p[SHARED_WRITE]; while (current != p[SHARED_READ]) { unsigned int hdr = p[current-1]; current -= (hdr & 0xffff); printf ("W[%3d] %08x", current, hdr); memdump((uint8_t *)&p[current], ((hdr & 0xffff)-1) * sizeof(uint32_t), ""); } return 0; } ================================================ FILE: examples/echotrace/vc707_floorplan.xdc ================================================ startgroup create_pblock pblock_ep7 resize_pblock pblock_ep7 -add {SLICE_X184Y54:SLICE_X221Y166 DSP48_X18Y22:DSP48_X19Y65 RAMB18_X12Y22:RAMB18_X14Y65 RAMB36_X12Y11:RAMB36_X14Y32} add_cells_to_pblock pblock_ep7 [get_cells [list host_ep7]] -clear_locs set_property HD.PARTPIN_RANGE {SLICE_X185Y54:SLICE_X186Y166} [get_pins host_ep7/*] set_property CONTAIN_ROUTING true [get_pblocks pblock_ep7] endgroup startgroup create_pblock pblock_pciehost resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X173Y197 DSP48_X9Y22:DSP48_X16Y77 RAMB18_X7Y22:RAMB18_X10Y77 RAMB36_X7Y11:RAMB36_X10Y38} add_cells_to_pblock pblock_pciehost [get_cells [list host_pciehost]] -clear_locs set_property HD.PARTPIN_RANGE {SLICE_X112Y55:SLICE_X113Y197} [get_pins host_pciehost/*] set_property HD.PARTPIN_RANGE {SLICE_X172Y55:SLICE_X173Y197} [get_pins host_pciehost/*pci_re*] set_property HD.PARTPIN_RANGE {SLICE_X172Y55:SLICE_X173Y197} [get_pins host_pciehost/*pci*] set_property CONTAIN_ROUTING true [get_pblocks pblock_pciehost] endgroup # startgroup # create_pblock pblock_pciehost # resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X221Y197 DSP48_X9Y22:DSP48_X19Y77 RAMB18_X7Y22:RAMB18_X14Y77 RAMB36_X7Y11:RAMB36_X14Y38} # add_cells_to_pblock pblock_pciehost [get_cells [list host]] -clear_locs # set_property HD.PARTPIN_RANGE {SLICE_X112Y55:SLICE_X113Y197} [get_pins host/*] # endgroup ================================================ FILE: examples/echowebsocket/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/echowebsocket/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request SwallowRequest:Swallow.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv Swallow.bsv CPPFILES=testecho.cpp $(CONNECTALDIR)/cpp/portalWebSocket.c CPPFILES2=daemon.cpp $(CONNECTALDIR)/cpp/portalWebSocket.c CONNECTALFLAGS += -lwebsockets include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/echowebsocket/Swallow.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface SwallowRequest; method Action swallow(Bit#(32) v); endinterface interface Swallow; interface SwallowRequest request; endinterface module mkSwallow(Swallow); Reg#(Bit#(32)) sink <- mkReg(0); interface SwallowRequest request; method Action swallow(Bit#(32) v); sink <= v; endmethod endinterface endmodule ================================================ FILE: examples/echowebsocket/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *echoRequestProxy; EchoIndicationProxy *sIndicationProxy; static int daemon_trace ;//= 1; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t v) { if (daemon_trace) fprintf(stderr, "daemon: %p heard an echo: %d\n", sIndicationProxy, v); sIndicationProxy->heard(v); } void heard2(uint16_t a, uint16_t b) { if (daemon_trace) fprintf(stderr, "daemon: %p heard an echo2: %d %d\n", sIndicationProxy, a, b); sIndicationProxy->heard2(a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; class EchoRequest : public EchoRequestWrapper { public: void say ( const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d] proxy %p\n", __FUNCTION__, __LINE__, echoRequestProxy); echoRequestProxy->say(v); } void say2 ( const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d] proxy %p\n", __FUNCTION__, __LINE__, echoRequestProxy); echoRequestProxy->say2(a, b); } void setLeds ( const uint8_t v ) { fprintf(stderr, "daemon[%s:%d] proxy %p\n", __FUNCTION__, __LINE__, echoRequestProxy); echoRequestProxy->setLeds(v); sleep(1); exit(1); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestWrapper(id, item, param, &EchoRequestJson_handleMessage, 1000) {} }; int main(int argc, const char **argv) { PortalSocketParam param; //#define USE_UNIX_SOCKET #ifdef USE_UNIX_SOCKET #define PARAM NULL #else #define PARAM ¶m #endif EchoIndication *echoIndication = new EchoIndication(IfcNames_EchoIndicationH2S, NULL, NULL); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int rc = getaddrinfo("127.0.0.1", "5000", NULL, ¶m.addr); sIndicationProxy = new EchoIndicationProxy(IfcNames_EchoIndicationH2S, &transportWebSocketResp, PARAM, &EchoIndicationJsonProxyReq, 1000); rc = getaddrinfo("127.0.0.1", "5001", NULL, ¶m.addr); EchoRequest *sRequest = new EchoRequest(IfcNames_EchoRequestS2H, &transportWebSocketResp, PARAM); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: examples/echowebsocket/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *sRequestProxy; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { fprintf(stderr, "heard an s: %d\n", v); sRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { fprintf(stderr, "heard an s2: %ld %ld\n", (long)a, (long)b); sem_post(&sem_heard2); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param, &EchoIndicationJson_handleMessage, 1000) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { sRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { PortalSocketParam param = {0}; //#define USE_UNIX_SOCKET #ifdef USE_UNIX_SOCKET #define PARAM NULL #else #define PARAM ¶m #endif int rc = getaddrinfo("127.0.0.1", "5000", NULL, ¶m.addr); EchoIndication *sIndication = new EchoIndication(IfcNames_EchoIndicationH2S, &transportWebSocketInit, PARAM); rc = getaddrinfo("127.0.0.1", "5001", NULL, ¶m.addr); sRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H, &transportWebSocketInit, PARAM, &EchoRequestJsonProxyReq, 1000); int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); sRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/fmcomms1/ExtraXilinxCells.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface DiffOut; method Bit#(1) read_p(); method Bit#(1) read_n(); endinterface import "BVI" OBUFDS = module mkxOBUFDS#(Wire#(Bit#(1)) i)(DiffOut); default_clock clk(); default_reset rstn(); port I = i; method O read_p(); method OB read_n(); path(I, O); path(I, OB); schedule (read_p, read_n) CF (read_p, read_n); endmodule: mkxOBUFDS ================================================ FILE: examples/fmcomms1/ExtraXilinxCells.bsv.pp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface DiffOut; method Bit#(1) read_p(); method Bit#(1) read_n(); endinterface import "BVI" OBUFDS = module mkxOBUFDS#(Wire#(Bit#(1)) i)(DiffOut); default_clock clk(); default_reset rstn(); port I = i; method O read_p(); method OB read_n(); path(I, O); path(I, OB); schedule (read_p, read_n) CF (read_p, read_n); endmodule: mkxOBUFDS ================================================ FILE: examples/fmcomms1/FMComms1.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import ClientServer::*; import GetPut::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; import Connectable::*; interface FMComms1Request; method Action startRead(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) run); method Action startWrite(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) run); method Action getReadStatus(); method Action getWriteStatus(); endinterface interface FMComms1; interface FMComms1Request request; interface MemReadClient#(64) readDmaClient; interface MemWriteClient#(64) writeDmaClient; endinterface interface FMComms1Indication; method Action readStatus(Bit#(32) numIter, Bit#(32) running); method Action writeStatus(Bit#(32) numIter, Bit#(32) running); endinterface /* This is like a combined memread and memwrite. * The read side is set to repetitively read a buffer, until * another portal call is made to startRead with the run bit off. * * Writes are the same */ module mkFMComms1#(FMComms1Indication indication, PipeIn#(Bit#(64)) dac, PipeOut#(Bit#(64)) adc) (FMComms1); Reg#(SGLId) readPointer <- mkReg(0); Reg#(Bit#(32)) readNumWords <- mkReg(0); Reg#(Bit#(32)) readIterCount <- mkReg(0); Reg#(Bit#(BurstLenSize)) readBurstLen <- mkReg(0); Reg#(Bit#(1)) readRun <- mkReg(0); MemReadEngine#(64,64,1,1) re <- mkMemReadEngineBuff(64*16); Reg#(SGLId) writePointer <- mkReg(0); Reg#(Bit#(32)) writeNumWords <- mkReg(0); Reg#(Bit#(32)) writeIterCount <- mkReg(0); Reg#(Bit#(BurstLenSize)) writeBurstLen <- mkReg(0); Reg#(Bit#(1)) writeRun <- mkReg(0); MemWriteEngine#(64,64,1,1) we <- mkMemWriteEngineBuff(64*16); mkConnection(adc, we.writeServers[0].data); rule readrule; let v <- toGet(re.readServers[0].data).get; toPut(dac).put(v.data); if (v.last && readRun == 0) indication.readStatus(readIterCount, zeroExtend(readRun)); endrule rule readStart (readRun == 1); readIterCount <= readIterCount + 1; re.readServers[0].request.put(MemengineCmd{sglId:readPointer, base:0, len:readNumWords*4, burstLen:readBurstLen*4}); endrule rule writeStart (writeRun == 1); writeIterCount <= writeIterCount + 1; we.writeServers[0].request.put(MemengineCmd{sglId:writePointer, base:0, len:writeNumWords*4, burstLen:writeBurstLen*4}); endrule rule writeFinish; let rv <- we.writeServers[0].done.get; if (writeRun == 0) indication.writeStatus(writeIterCount, zeroExtend(writeRun)); endrule interface MemReadClient readDmaClient = re.dmaClient; interface ObjectWeadClient writeDmaClient = we.dmaClient; interface FMComms1Request request; method Action startRead(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) run); $display("startRead rdPointer=%d numWords=%h burstLen=%d run=%d", pointer, numWords, burstLen, run); if (run == 1) indication.readStatus(readIterCount, run); readPointer <= pointer; readNumWords <= numWords; readBurstLen <= truncate(burstLen); readRun <= truncate(run); endmethod method Action startWrite(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) run); $display("startWrite rdPointer=%d numWords=%h burstLen=%d run=%d", pointer, numWords, burstLen, run); if (run == 1) indication.writeStatus(writeIterCount, run); writePointer <= pointer; writeNumWords <= numWords; writeBurstLen <= truncate(burstLen); writeRun <= truncate(run); endmethod method Action getReadStatus(); indication.readStatus(readIterCount, zeroExtend(readRun)); endmethod method Action getWriteStatus(); indication.writeStatus(writeIterCount, zeroExtend(writeRun)); endmethod endinterface endmodule ================================================ FILE: examples/fmcomms1/FMComms1ADC.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import XilinxCells::*; import ConnectalXilinxCells::*; import Gearbox::*; import Pipe::*; import FIFO::*; import BRAMFIFO::*; import Vector::*; import Clocks::*; import DefaultValue::*; (* always_enabled *) interface FMComms1ADCPins; method Action io_adc_data_p(Bit#(14) v); method Action io_adc_data_n(Bit#(14) v); method Action io_adc_or_p(Bit#(1) v); method Action io_adc_or_n(Bit#(1) v); method Action io_adc_dco_p(Bit#(1) v); method Action io_adc_dco_n(Bit#(1) v); interface Clock deleteme_unused_clock; interface Reset deleteme_unused_reset; endinterface typedef struct { Bit#(14) data_i; Bit#(1) z_i; Bit#(1) or_i; Bit#(14) data_q; Bit#(1) z_q; Bit#(1) or_q; } IQ deriving (Bits); interface FMComms1ADC; interface FMComms1ADCPins pins; interface PipeOut#(Bit#(64)) adc; endinterface /* This module accepts inputs from an Analog Devices FMComms1 * evaluation board Analog to Digital Converter, and delivers * the data as a PipeOut type on the default clock. * * Input is double data rate, with clock supplied by the FMComms1 * Input data is 14 bits twos-complement or offset binary, plus * an overrange signa= * * Differential inputs are converted to single ended by using Xilinx IBUFDS * cells. The clock is converted to single ended by an IBUFGDS cell * * DDR data is convered to SDR using IDDR cells * At this point, the data is a 14 bit in-phase data signal, plus in-phase * overrange, and a 14 bit quadrature signal, plus overrange. * * The data is packed into a 64-bit IQ datatype, with overrange as the LSB * * The 32-bit data is converted to 64-bits by a Gearbox * * Clock conversion happens 64-bits wide using a SyncBRAMFIFO, which * presents a PipeOut channel to the rest of the logic. */ module mkFMComms1ADC(FMComms1ADC); Clock def_clock <- exposeCurrentClock; Reset def_reset <- exposeCurrentReset; function Bit#(1) foo(ReadOnly#(Bit#(1)) v); return (v._read()); endfunction function ReadOnly#(Bit#(14)) rofromrov(Vector#(14, ReadOnly#(Bit#(1))) v); return(interface ReadOnly; method Bit#(14) _read; return ( pack(map(foo, v))); endmethod endinterface ); endfunction Clock adc_dco; /* DDR clock */ Wire#(Bit#(1)) adc_dco_p <- mkDWire(0); Wire#(Bit#(1)) adc_dco_n <- mkDWire(0); adc_dco <- mkConnectalClockIBUFDS(adc_dco_p, adc_dco_n); Reset adc_reset <- mkAsyncReset(3, def_reset, adc_dco); Vector#(14, Wire#(Bit#(1))) adc_data_p = newVector; for (Integer i = 0; i < 14; i = i + 1) adc_data_p[i] <- mkDWire(0, clocked_by adc_dco, reset_by adc_reset); Vector#(14, Wire#(Bit#(1))) adc_data_n = newVector; for (Integer i = 0; i < 14; i = i + 1) adc_data_n[i] <- mkDWire(0, clocked_by adc_dco, reset_by adc_reset); Wire#(Bit#(1)) adc_or_p <- mkDWire(0, clocked_by adc_dco, reset_by adc_reset); Wire#(Bit#(1)) adc_or_n <- mkDWire(0, clocked_by adc_dco, reset_by adc_reset); Vector#(14, ReadOnly#(Bit#(1))) v_adc_data; /* data */ ReadOnly#(Bit#(14)) adc_data; ReadOnly#(Bit#(1)) adc_or; /* overrange */ for(Integer i = 0; i < 14; i = i + 1) v_adc_data[i] <- mkIBUFDS(adc_data_p[i], adc_data_n[i], clocked_by adc_dco, reset_by adc_reset); adc_data = rofromrov(v_adc_data); adc_or <- mkIBUFDS(adc_or_p, adc_or_n, clocked_by adc_dco, reset_by adc_reset); IDDRParams#(Bit#(14)) iddrparams_data = defaultValue; // iddrparams_data.ddr_clk_edge = "SAME_EDGE_PIPELINED"; iddrparams_data.ddr_clk_edge = "SAME_EDGE"; IDDR#(Bit#(14)) adc_sdr_data <- mkIDDR(iddrparams_data, clocked_by adc_dco); IDDRParams#(Bit#(1)) iddrparams_or = defaultValue; // iddrparams_or.ddr_clk_edge = "SAME_EDGE_PIPELINED"; iddrparams_or.ddr_clk_edge = "SAME_EDGE"; IDDR#(Bit#(1)) adc_sdr_or <- mkIDDR(iddrparams_or, clocked_by adc_dco); rule sendup_adc_data; adc_sdr_data.d(pack(adc_data)); endrule rule sendup_adc_or; adc_sdr_or.d(adc_or); endrule rule alwaysenable; adc_sdr_data.ce(True); adc_sdr_data.s(False); adc_sdr_or.ce(True); adc_sdr_or.s(False); endrule Gearbox#(1, 2, IQ) gb <- mk1toNGearbox(adc_dco, adc_reset, adc_dco, adc_reset); SyncFIFOIfc#(Vector#(2, IQ)) infifo <- mkSyncBRAMFIFO(128, adc_dco, adc_reset, def_clock, def_reset); rule sendup_gb_data; gb.enq(unpack(pack(IQ{data_i: adc_sdr_data.q1, z_i: 0, or_i: adc_sdr_or.q1, data_q: adc_sdr_data.q2, z_q: 0, or_q: adc_sdr_or.q2}))); endrule rule sendup_adc_fifo_data; gb.deq(); infifo.enq(gb.first()); endrule interface FMComms1ADCPins pins; method Action io_adc_data_p(Bit#(14) v); for (Integer i = 0; i < 14; i = i + 1) adc_data_p[i] <= v[i]; endmethod method Action io_adc_data_n(Bit#(14) v); for (Integer i = 0; i < 14; i = i + 1) adc_data_n[i] <= v[i]; endmethod method Action io_adc_or_p(Bit#(1) v); adc_or_p <= v; endmethod method Action io_adc_or_n(Bit#(1) v); adc_or_n <= v; endmethod method Action io_adc_dco_p(Bit#(1) v); adc_dco_p <= v; endmethod method Action io_adc_dco_n(Bit#(1) v); adc_dco_n <= v; endmethod interface deleteme_unused_clock = adc_dco; interface deleteme_unused_reset = adc_reset; endinterface interface PipeOut adc; method Bit#(64) first(); return(unpack(pack(infifo.first))); endmethod method Action deq() = infifo.deq; method Bool notEmpty() = infifo.notEmpty; endinterface endmodule ================================================ FILE: examples/fmcomms1/FMComms1DAC.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import XilinxCells::*; import ConnectalXilinxCells::*; import ConnectalClocks::*; import Gearbox::*; import Pipe::*; import FIFO::*; import BRAMFIFO::*; import Vector::*; import Clocks::*; import DefaultValue::*; import ExtraXilinxCells::*; (* always_enabled *) interface FMComms1DACPins; method Bit#(14) io_dac_data_p(); method Bit#(14) io_dac_data_n(); method Action io_dac_dco_p(Bit#(1) v); method Action io_dac_dco_n(Bit#(1) v); method Bit#(1) io_dac_dci_p(); method Bit#(1) io_dac_dci_n(); method Clock deleteme_unused_clock; method Reset deleteme_unused_reset; endinterface typedef struct { Bit#(16) data_i; Bit#(16) data_q; } OIQ deriving (Bits); interface FMComms1DAC; interface FMComms1DACPins pins; interface PipeIn#(Bit#(64)) dac; endinterface /* This module drives an Analog Devices FMComms1 * evaluation board Digital to Analog Converter, it accepts * the data as a PipeIn type on the default clock. * The FMComms1 supplies the DAC clock as a differential pair * * Output is double data rate, with clock supplied by the FMComms1 * Output data is 14 bits twos-complement or offset binary * * Differential outputs are converted from single ended by using Xilinx OBUFDS * cells. The clock is converted to single ended by an IBUFGDS cell * * DDR data is convered from SDR using ODDR cells * At this point, the data is a 14 bit in-phase data signal, * plus a 14 bit quadrature signal, interleaved * * The SDR data is a 32-bit OIQ datatype * * The 32-bit data is converted from 64-bits by a Gearbox * * Clock conversion happens 64-bits wide using a SyncBRAMFIFO, which * presents a PipeIn channel to the rest of the logic. */ module mkFMComms1DAC(FMComms1DAC); Clock def_clock <- exposeCurrentClock; Reset def_reset <- exposeCurrentReset; Clock dac_dco; Wire#(Bit#(1)) dac_dco_p <- mkDWire(0); Wire#(Bit#(1)) dac_dco_n <- mkDWire(0); dac_dco <- mkConnectalClockIBUFDS(dac_dco_p, dac_dco_n); Reset dac_reset <- mkAsyncReset(3, def_reset, dac_dco); SyncFIFOIfc#(Vector#(2, OIQ)) outfifo <- mkSyncBRAMFIFO(128, def_clock, def_reset, dac_dco, dac_reset); Gearbox#(2, 1, OIQ) gb <- mkNto1Gearbox(dac_dco, dac_reset, dac_dco, dac_reset); ODDRParams#(Bit#(14)) oddrparams = defaultValue; // oddrparams.ddr_clk_edge = "SAME_EDGE_PIPELINED"; oddrparams.ddr_clk_edge = "SAME_EDGE"; ODDR#(Bit#(14)) dac_ddr <- mkODDR(oddrparams, clocked_by (dac_dco)); Vector#(14, Wire#(Bit#(1))) dac_ddr_data <- replicateM(mkDWire(0)); Vector#(14, DiffOut) dac_out = newVector; for (Integer i = 0; i < 14; i = i + 1) dac_out[i] <- mkxOBUFDS(dac_ddr_data[i]); C2B dac_dco_as_bit <- mkC2B(dac_dco); Wire#(Bit#(1)) dac_dci_wire <- mkDWire(0); rule senddown_clk; dac_dci_wire <= dac_dco_as_bit.o(); endrule DiffOut dac_dci <- mkxOBUFDS(dac_dci_wire); rule senddown_gb; outfifo.deq(); gb.enq(outfifo.first()); endrule rule senddown_oddr; let d = gb.first; gb.deq(); dac_ddr.d1(d[0].data_i[15:2]); dac_ddr.d2(d[0].data_q[15:2]); endrule rule alwaysenable; dac_ddr.ce(True); dac_ddr.s(False); endrule function Bit#(1) foo_p(DiffOut v); return (v.read_p()); endfunction function Bit#(1) foo_n(DiffOut v); return (v.read_n()); endfunction function Bit#(14) get_p(Vector#(14, DiffOut) v); return(pack(map(foo_p, v))); endfunction function Bit#(14) get_n(Vector#(14, DiffOut) v); return(pack(map(foo_n, v))); endfunction interface FMComms1DACPins pins; method Bit#(14) io_dac_data_p(); return(get_p(dac_out)); endmethod method Bit#(14) io_dac_data_n(); return(get_n(dac_out)); endmethod method Bit#(1) io_dac_dci_p(); return(dac_dci.read_p()); endmethod method Bit#(1) io_dac_dci_n(); return(dac_dci.read_n()); endmethod method Action io_dac_dco_p(Bit#(1) v); dac_dco_p <= v; endmethod method Action io_dac_dco_n(Bit#(1) v); dac_dco_n <= v; endmethod interface deleteme_unused_clock = dac_dco; interface deleteme_unused_reset = dac_reset; endinterface interface PipeIn dac; method Action enq(Bit#(64) v); outfifo.enq(unpack(pack(v))); endmethod method Bool notFull() = outfifo.notFull; endinterface endmodule ================================================ FILE: examples/fmcomms1/FMComms1Pins.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //import Vector::*; //import GetPut::*; //import Connectable :: *; //import Clocks :: *; //import FIFO::*; //import Portal::*; //import ConnectalConfig::*; //import CtrlMux::*; //import ConnectalMemTypes::*; //import MemServer::*; //import ConnectalMMU::*; //import PS7LIB::*; //import PPS7LIB::*; //import FMComms1Request::*; //import FMComms1Indication::*; //import MemServerRequest::*; //import MMURequest::*; //import MemServerIndication::*; //import MMUIndication::*; //import BlueScopeEventPIORequest::*; //import BlueScopeEventPIOIndication::*; //import XilinxCells::*; //import ConnectalXilinxCells::*; //import ConnectalClocks::*; //import BlueScopeEventPIO::*; import FMComms1ADC::*; import FMComms1DAC::*; //import FMComms1::*; //import extraXilinxCells::*; /* Duplicate def here, this is also in ZynqTop */ interface I2C_Pins; interface Inout#(Bit#(1)) scl; interface Inout#(Bit#(1)) sda; endinterface interface FMComms1Pins; interface FMComms1ADCPins adcpins; interface FMComms1DACPins dacpins; interface I2C_Pins i2c1; method Bit#(1) ad9548_ref_p(); method Bit#(1) ad9548_ref_n(); // (* prefix="" *) endinterface ================================================ FILE: examples/fmcomms1/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = FMComms1Request FMComms1Indication \ BlueScopeEventPIORequest BlueScopeEventPIOIndication BSVFILES = ../../lib/bsv/BlueScopeEventPIO.bsv \ FMComms1ADC.bsv FMComms1DAC.bsv FMComms1.bsv \ Top.bsv CPPFILES=testfmcomms1.cpp fmci2c.c i2c_zedboardandroid.c CONNECTALFLAGS = -C fmcomms1-$(BOARD).xdc --tcl clock.tcl CONNECTALFLAGS += -D USE_FMC_I2C1 -D IMPORT_HOSTIF PIN_TYPE = FMComms1Pins PIN_TYPE_INCLUDE = FMComms1Pins ifeq ($(BOARD),zedboard) HAS_PS7=true #CONNECTALFLAGS += -D USE_I2C0 endif ifeq ($(BOARD),zc702) HAS_PS7=true endif USER_PIN_BINDINGS ?= --pin-binding fmc:fmc1 gentarget:: fmcomms1-$(BOARD).xdc fmcomms1-$(BOARD).xdc: fmcomms1-fmc.json $(CONNECTALDIR)/boardinfo/$(BOARD).json $(CONNECTALDIR)/scripts/generate-constraints.py $(USER_PIN_BINDINGS) -o fmcomms1-$(BOARD).xdc --boardfile $(CONNECTALDIR)/boardinfo/$(BOARD).json --pinoutfile fmcomms1-fmc.json include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/fmcomms1/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Vector::*; import GetPut::*; import Connectable :: *; import Clocks :: *; import FIFO::*; import Portal::*; import ConnectalConfig::*; import HostInterface::*; import CtrlMux::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import PS7LIB::*; import PPS7LIB::*; import FMComms1Request::*; import FMComms1Indication::*; import MemServerRequest::*; import MMURequest::*; import MemServerIndication::*; import MMUIndication::*; import BlueScopeEventPIORequest::*; import BlueScopeEventPIOIndication::*; import XilinxCells::*; import ConnectalXilinxCells::*; import ConnectalClocks::*; import BlueScopeEventPIO::*; import FMComms1ADC::*; import FMComms1DAC::*; import FMComms1::*; import ExtraXilinxCells::*; import FMComms1Pins::*; `define BlueScopeEventPIOSampleLength 512 typedef enum { IfcNames_BlueScopeEventPIORequest, IfcNames_BlueScopeEventPIOIndication, IfcNames_FMComms1Request, IfcNames_FMComms1Indication, IfcNames_MemServerIndicationH2S, IfcNames_MemServerRequestS2H, IfcNames_MMURequestS2H, IfcNames_MMUIndicationH2S} IfcNames deriving (Eq,Bits); /* clk1 is the FCLKCLK1 controlled by software */ module mkConnectalTop#(HostInterface host)(ConnectalTop); Clock clk1 = host.ps7.fclkclk[1]; C2B ref_clk_as_bit <- mkC2B(clk1); Wire#(Bit#(1)) ref_clk_wire <- mkDWire(0); rule senddown_clk; ref_clk_wire <= ref_clk_as_bit.o(); endrule DiffOut ref_clk <- mkxOBUFDS(ref_clk_wire); FMComms1ADC adc <- mkFMComms1ADC(); FMComms1DAC dac <- mkFMComms1DAC(); BlueScopeEventPIOIndicationProxy blueScopeEventPIOIndicationProxy <- mkBlueScopeEventPIOIndicationProxy(IfcNames_BlueScopeEventPIOIndication); BlueScopeEventPIOControl#(32) bs <- mkBlueScopeEventPIO(`BlueScopeEventPIOSampleLength, blueScopeEventPIOIndicationProxy.ifc); BlueScopeEventPIORequestWrapper blueScopeEventPIORequestWrapper <- mkBlueScopeEventPIORequestWrapper(IfcNames_BlueScopeEventPIORequest,bs.requestIfc); `ifdef USE_FMC_I2C1 Clock mainclock = host.ps7.fclkclk[0]; Reset mainreset = host.ps7.fclkreset[0]; let tscl1 <- mkIOBUF(~host.ps7.i2c[1].scltn, host.ps7.i2c[1].sclo, clocked_by mainclock, reset_by mainreset); let tsda1 <- mkIOBUF(~host.ps7.i2c[1].sdatn, host.ps7.i2c[1].sdao, clocked_by mainclock, reset_by mainreset); rule sdai1; host.ps7.i2c[1].sdai(tsda1.o); host.ps7.i2c[1].scli(tscl1.o); endrule rule watchi2c; let a = host.ps7.i2c[1].sclo(); let b = host.ps7.i2c[1].scltn(); let c = host.ps7.i2c[1].sdao(); let d = host.ps7.i2c[1].sdatn(); bs.bse.dataIn({a, b, tscl1.o, c, d, tsda1.o, 0}); endrule `endif FMComms1IndicationProxy fmcomms1IndicationProxy <- mkFMComms1IndicationProxy(IfcNames_FMComms1Indication); FMComms1 fmcomms1 <- mkFMComms1(fmcomms1IndicationProxy.ifc, dac.dac, adc.adc); FMComms1RequestWrapper fmcomms1RequestWrapper <- mkFMComms1RequestWrapper(IfcNames_FMComms1Request, fmcomms1.request); Vector#(1, MemReadClient#(64)) readClients = cons(fmcomms1.readDmaClient, nil); Vector#(1, MemWriteClient#(64)) writeClients = cons(fmcomms1.writeDmaClient, nil); MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMUIndicationH2S); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_MMURequestS2H, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_MemServerIndicationH2S); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(readClients, writeClients, cons(hostMMU,nil), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_MemServerRequestS2H, dma.request); Vector#(8,StdPortal) portals; portals[0] = fmcomms1RequestWrapper.portalIfc; portals[1] = fmcomms1IndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = hostMemServerIndicationProxy.portalIfc; portals[4] = hostMMURequestWrapper.portalIfc; portals[5] = hostMMUIndicationProxy.portalIfc; portals[6] = blueScopeEventPIORequestWrapper.portalIfc; portals[7] = blueScopeEventPIOIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; interface FMComms1Pins pins; `ifdef USE_FMC_I2C1 interface I2C_Pins i2c1; interface Inout scl = tscl1.io; interface Inout sda = tsda1.io; endinterface `endif interface FMComms1ADCPins adcpins = adc.pins; interface FMComms1ADCPins dacpins = dac.pins; method Bit#(1) ad9548_ref_p(); return(ref_clk.read_p()); endmethod method Bit#(1) ad9548_ref_n(); return(ref_clk.read_n()); endmethod endinterface endmodule : mkConnectalTop ================================================ FILE: examples/fmcomms1/clock.tcl ================================================ ## disconnect unused CLK and RST ports inserted by bsc foreach {pat} {CLK_GATE_* CLK_pins_spi_clock} { foreach {net} [get_nets $pat] { disconnect_net -net $net -objects [get_pins -of_objects $net] } } ================================================ FILE: examples/fmcomms1/fmci2c.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* copied from jca's i2chdmi.h */ #include #include #include #include #include "/usr/include/linux/i2c.h" #include "/usr/include/linux/i2c-dev.h" #include #include #include #include #include "i2c_zedboardandroid.h" int fmcomms1_get_version(int fd, int device, unsigned char *datap, int size) { int status; struct i2c_msg msgs[2]; unsigned char command = 1; struct i2c_rdwr_ioctl_data arg; msgs[0].addr = device; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = &command; msgs[1].addr = device; msgs[1].flags = I2C_M_RD | I2C_M_RECV_LEN; msgs[1].len = 33; msgs[1].buf = datap; arg.msgs = &msgs[0]; arg.nmsgs = 1; datap[0] = 1; status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stdout, "[%s:%d]: ioctl I2C_RW write status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } arg.msgs = &msgs[1]; status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stdout, "[%s:%d]: ioctl I2C_RW read status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } return status; } unsigned char version_data[256]; unsigned char msgbuf[256]; void testi2c(const char *i2cdevice, int deviceid) { int fd; int i; int res; printf("i2cdevice is %s, deviceid is 0x%02x\n", i2cdevice, deviceid); I2C_Init(i2cdevice, deviceid); // start version query memset(version_data, 0, 256); for (i = 0; i < 256; i += 16) { int j; res = I2C_Read(0x50, i, 64, msgbuf); printf("returned %d bytes\n", msgbuf[0]); for (j=0; j < 17; j += 1) { printf(" %2x[%c]", msgbuf[j],isalnum(msgbuf[j]) ? msgbuf[j]:' '); } printf("\n"); if (res < 0) { fprintf(stdout, "testi2c failed eeprom read at %d\n", i); return; } } /* memset(version_data, 0, 128); res = fmcomms1_get_version(fd, deviceid, version_data, 128); printf ("getversion result %d\n", res); for (i = 0; i < 32; i += 1) { if ((i != 0) && ((i % 16) == 0)) printf("\n"); printf(" %2x[%c]", version_data[i],isalnum(version_data[i]) ? version_data[i]:' '); } printf("\n"); */ } ================================================ FILE: examples/fmcomms1/fmci2c.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef __cplusplus extern "C" { #endif void testi2c(const char *i2cdevice, int deviceid); #ifdef __cplusplus } #endif ================================================ FILE: examples/fmcomms1/fmcomms1-fmc.json ================================================ { "*dac_dco_p_v": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "CLK0_M2C_p" }, "*dac_dco_n_v": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "CLK0_M2C_n" }, "*adc_data_p_v[8]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA02_p" }, "*adc_data_n_v[8]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA02_n" }, "*adc_data_p_v[9]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA04_p" }, "*adc_data_n_v[9]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA04_n" }, "*adc_data_p_v[7]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA07_p" }, "*adc_data_n_v[7]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA07_n" }, "*dac_frame_p_v": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA11_p" }, "*dac_frame_n": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA11_n" }, "*dac_data_p[14]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA15_p" }, "*dac_data_n[14]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA15_n" }, "*dac_data_p[12]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA19_p" }, "*dac_data_n[12]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA19_n" }, "*dac_dci_p": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA21_p" }, "*dac_dci_n": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA21_n" }, "*dac_data_p[6]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA24_p" }, "*dac_data_n[6]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA24_n" }, "*dac_data_p[3]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA28_p" }, "*dac_data_n[3]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA28_n" }, "*dac_data_p[2]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA30_p" }, "*dac_data_n[2]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA30_n" }, "*dac_data_p[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA32_p" }, "*dac_data_n[0]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA32_n" }, "*adc_dco_p_v": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "CLK1_M2C_p" }, "*adc_dco_n_v": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "CLK1_M2C_n" }, "*adc_or_p_v": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA00_p_CC" }, "*adc_or_n_v": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA00_n_CC" }, "*adc_data_p_v[3]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA03_p" }, "*adc_data_n_v[3]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA03_n" }, "*adc_data_p_v[11]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA08_p" }, "*adc_data_n_v[11]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA08_n" }, "*adc_data_p_v[6]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA12_p" }, "*adc_data_n_v[6]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA12_n" }, "*dac_data_p[15]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA16_p" }, "*dac_data_n[15]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA16_n" }, "*dac_data_p[13]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA20_p" }, "*dac_data_n[13]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA20_n" }, "*dac_data_p[8]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA22_p" }, "*dac_data_n[8]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA22_n" }, "*dac_data_p[7]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA25_p" }, "*dac_data_n[7]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA25_n" }, "*dac_data_p[5]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA29_p" }, "*dac_data_n[5]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA29_n" }, "*dac_data_p[4]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA31_p" }, "*dac_data_n[4]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA31_n" }, "*dac_data_p[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA33_p" }, "*dac_data_n[1]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA33_n" }, "*adc_data_p_v[13]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA01_p_CC" }, "*adc_data_n_v[13]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA01_n_CC" }, "*adc_data_p_v[4]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA05_p" }, "*adc_data_n_v[4]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA05_n" }, "*adc_data_p_v[10]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA09_p" }, "*adc_data_n_v[10]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA09_n" }, "*adc_data_p_v[2]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA13_p" }, "*adc_data_n_v[2]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA13_n" }, "*ad9548_ref_p": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA17_p_CC" }, "*ad9548_ref_n": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA17_n_CC" }, "*dac_data_p[11]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA23_p" }, "*dac_data_n[11]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA23_n" }, "*dac_data_p[10]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA26_p" }, "*dac_data_n[10]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA26_n" }, "*adc_data_p_v[12]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA06_p" }, "*adc_data_n_v[12]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA06_n" }, "*adc_data_p_v[5]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA10_p" }, "*adc_data_n_v[5]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA10_n" }, "*adc_data_p_v[1]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA14_p" }, "*adc_data_n_v[1]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA14_n" }, "*adc_data_p_v[0]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA18_p_CC" }, "*adc_data_n_v[0]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA18_n_CC" }, "*dac_data_p[9]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA27_p" }, "*dac_data_n[9]": { "PIO_DIRECTION": "OUTPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA27_n" }, "*i2c1_scl": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS33", "fmc": "SCL" }, "*i2c1_sda": { "PIO_DIRECTION": "BIDIR", "IOSTANDARD": "LVCMOS33", "fmc": "SDA" } } ================================================ FILE: examples/fmcomms1/i2c_zedboardandroid.c ================================================ /**************************************************************************//** * @file i2c_zedboardandroid.c * @brief ZYNQ Hardware I2C functions implementation. * ******************************************************************************* * API copied from i2c_ps7.c * Copyright 2011(c) Analog Devices, Inc. */ #include "/usr/include/linux/i2c.h" #include "/usr/include/linux/i2c-dev.h" #include #include #include #include static int fd; void dump_i2c_msg(struct i2c_msg *msg) { int i; fprintf(stdout, " addr 0x%02x flags[", msg->addr); if (msg->flags & I2C_M_RD) fprintf(stdout, " RD"); else fprintf(stdout, " WR"); if (msg->flags & I2C_M_RECV_LEN) fprintf(stdout, " RDLEN"); else fprintf(stdout, " "); fprintf(stdout, " ] len %d ", msg->len); if ((msg->flags & I2C_M_RD) == 0) { fprintf(stdout, " ["); for (i = 0; i < msg->len; i += 1) fprintf(stdout, " %02x", msg->buf[i]); fprintf(stdout, " ]\n"); } else { fprintf(stdout, "\n"); } } void dump_i2c_rdwr(struct i2c_rdwr_ioctl_data *arg) { int i; fprintf(stdout, "i2c_rdwr[%d]\n", arg->nmsgs); for (i = 0; i < arg->nmsgs; i += 1) dump_i2c_msg(&arg->msgs[i]); } /**************************************************************************//** * @brief Initializes the I2C communication multiplexer. * * @param sel - Multiplexer selection value. * * @return Returns 0 or negative error code. ******************************************************************************/ uint32_t I2C_Init(char * devfile, uint32_t i2cAddr) { uint32_t ret = 0; fprintf(stdout, "opening %s\n", devfile); fd = open(devfile, O_RDWR); if (fd < 0) { fprintf(stdout, "can't open device %s: %s [%d]", devfile, strerror(errno), errno); } return ret; } /**************************************************************************//** * @brief Writes data to an I2C slave. * * @param i2cAddr - The address of the I2C slave. * @param regAddr - Address of the I2C register to be read. * Must be set to -1 if it is not used. * @param txSize - Number of bytes to write to the slave. * @param txBuf - Buffer to store the data to be transmitted. * * @return Returns the number of bytes written. ******************************************************************************/ uint32_t I2C_Write(uint32_t i2cAddr, uint32_t regAddr, uint32_t txSize, uint8_t* txBuf) { int status, i; unsigned char buf[128]; struct i2c_msg msgs[1]; struct i2c_rdwr_ioctl_data arg; msgs[0].addr = i2cAddr; msgs[0].flags = 0; msgs[0].buf = buf; arg.msgs = msgs; arg.nmsgs = 1; if (txSize > 127) return -1; if (regAddr != 0xffffffff) { buf[0] = regAddr; memcpy(&buf[1], txBuf, txSize); msgs[0].len = txSize + 1; } else { memcpy(&buf[0], txBuf, txSize); msgs[0].len = txSize; } fprintf(stdout, "I2C_Write(0x%02x, 0x%02x, %d, [", i2cAddr, regAddr, txSize); for (i = 0 ; i < msgs[0].len; i += 1) fprintf(stdout, " %02x", buf[i]); fprintf(stdout, " ])\n"); dump_i2c_rdwr(&arg); status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stdout, "[%s:%d]: ioctl I2C_RW 1 status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } fprintf(stdout, "returns %d\n", txSize); return txSize; } /**************************************************************************//** * @brief Reads data from an I2C slave. * * @param i2cAddr - The address of the I2C slave. * @param regAddr - Address of the I2C register to be read. * Must be set to -1 if it is not used. * @param rxSize - Number of bytes to read from the slave. * @param rxBuf - Buffer to store the read data. * * @return Returns the number of bytes read. ******************************************************************************/ uint32_t I2C_Read(uint32_t i2cAddr, uint32_t regAddr, uint32_t rxSize, uint8_t* rxBuf) { int status, i; unsigned char buf[128]; struct i2c_msg msgs[1]; struct i2c_rdwr_ioctl_data arg; msgs[0].addr = i2cAddr; msgs[0].flags = I2C_M_RD | I2C_M_RECV_LEN; msgs[0].len = rxSize; msgs[0].buf = buf; arg.msgs = msgs; arg.nmsgs = 1; buf[0] = 1; if (regAddr != 0xffffffff) I2C_Write(i2cAddr, regAddr, 0, NULL); fprintf(stdout, "I2C_Read(0x%02x, 0x%02x, %d)\n", i2cAddr, regAddr, rxSize); dump_i2c_rdwr(&arg); status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stdout, "[%s, %d]: ioctl I2C_RW status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } if (buf[0] > rxSize) buf[0] = rxSize; memcpy(rxBuf, &buf[1], buf[0]); fprintf(stdout, " returns %d [", buf[0]); for (i = 0 ; i <= buf[0]; i += 1) fprintf(stdout, " %02x", buf[i]); fprintf(stdout, " ]\n"); return buf[0]; } ================================================ FILE: examples/fmcomms1/i2c_zedboardandroid.h ================================================ /**************************************************************************//** * @file i2c_zedboardandroid.h * @brief ZYNQ Hardware I2C header file. * ******************************************************************************* * API copied from i2c_ps7.h * Copyright 2011(c) Analog Devices, Inc. */ #include uint32_t I2C_Init(const char * devfile, uint32_t i2cAddr); uint32_t I2C_Read(uint32_t i2cAddr, uint32_t regAddr, uint32_t rxSize, uint8_t* rxBuf); uint32_t I2C_Write(uint32_t i2cAddr, uint32_t regAddr, uint32_t txSize, uint8_t* txBuf); ================================================ FILE: examples/fmcomms1/readtrace.py ================================================ from __future__ import print_function lastevent = 0 osclo = 0 oscltn = 0 oscli = 0 osdao = 0 osdatn = 0 osdai = 0 bitnum = 0 databyte = 0 def reportEvent(v, timestamp): global osclo global oscltn global oscli global osdao global osdatn global osdai global lastevent global bitnum global databyte sclo = (v & 0x80000000) >> 31 scltn = (v & 0x40000000) >> 30 scli = (v & 0x20000000) >> 29 sdao = (v & 0x10000000) >> 28 sdatn = (v & 0x8000000) >> 27 sdai = (v & 0x4000000) >> 26 print("ts %8x %d sclo %d scltn %d scli %d sdao %d sdatn %d sdai %d" % (timestamp, (timestamp - lastevent), sclo, scltn, scli, sdao, sdatn, sdai)) lastevent = timestamp if (not oscltn and scltn): print("drive SCL") if (oscltn and not scltn): print("listen SCL") if (not osdatn and sdatn): print("drive SDA") if (osdatn and not sdatn): print("listen SDA") if (oscli and scli and osdai and not sdai): print("START") bitnum = 0 if (oscli and scli and not osdai and sdai): print( "STOP") if (not oscli and scli and sdai): if sdatn: print( "databit 1 TX") else: print( "databit 1 RX") if bitnum == 8: print("databyte %02x NACK" % databyte) bitnum = 0 databyte = 0 else: print ("bitnum %x" % bitnum) databyte = (databyte << 1) + 1 bitnum = bitnum + 1 if (not oscli and scli and not sdai): if sdatn: print( "databit 0 TX") else: print( "databit 0 RX") if bitnum == 8: print("databyte %02x ACK" % databyte) bitnum = 0 databyte = 0 else: print ("bitnum %x" % bitnum) databyte = (databyte << 1) + 0 bitnum = bitnum + 1 osclo = sclo oscltn = scltn oscli = scli osdao = sdao osdatn = sdatn osdai = sdai reportEvent(0x24000000, 0x44200000) reportEvent(0x2c000000, 0x4446383e) reportEvent(0x68000000, 0x444639ad) reportEvent(0x48000000, 0x444639b3) reportEvent(0x40000000, 0x44463c30) reportEvent(0x44000000, 0x44463c36) reportEvent(0x04000000, 0x44463d9f) reportEvent(0x24000000, 0x44463da5) reportEvent(0x44000000, 0x44463f98) reportEvent(0x48000000, 0x44464022) reportEvent(0x08000000, 0x44464191) reportEvent(0x28000000, 0x44464197) reportEvent(0x48000000, 0x4446438a) reportEvent(0x40000000, 0x44464413) reportEvent(0x44000000, 0x44464419) reportEvent(0x24000000, 0x44464587) reportEvent(0x64000000, 0x4446477b) reportEvent(0x44000000, 0x44464781) reportEvent(0x4c000000, 0x44464805) reportEvent(0x48000000, 0x4446480b) reportEvent(0x08000000, 0x44464974) reportEvent(0x28000000, 0x4446497a) reportEvent(0x68000000, 0x44464b6d) reportEvent(0x48000000, 0x44464b73) reportEvent(0x08000000, 0x44464d66) reportEvent(0x68000000, 0x44464f5f) reportEvent(0x08000000, 0x44465158) reportEvent(0x28000000, 0x4446515e) reportEvent(0x48000000, 0x44465351) reportEvent(0x08000000, 0x4446554a) reportEvent(0x28000000, 0x44465550) reportEvent(0x48000000, 0x44465743) reportEvent(0x28000000, 0x44465940) reportEvent(0x68000000, 0x44465b34) reportEvent(0x48000000, 0x44465b3a) reportEvent(0x40000000, 0x44465bbe) reportEvent(0x00000000, 0x44465d2d) reportEvent(0x20000000, 0x44465d33) reportEvent(0x60000000, 0x44465f26) reportEvent(0x40000000, 0x44465f2c) reportEvent(0x44000000, 0x44465f43) reportEvent(0x4c000000, 0x44465fb0) reportEvent(0x08000000, 0x4446611f) reportEvent(0x68000000, 0x44466318) reportEvent(0x08000000, 0x44466511) reportEvent(0x28000000, 0x44466517) reportEvent(0x48000000, 0x4446670a) reportEvent(0x08000000, 0x44466903) reportEvent(0x28000000, 0x44466909) reportEvent(0x48000000, 0x44466afc) reportEvent(0x28000000, 0x44466cf9) reportEvent(0x68000000, 0x44466eed) reportEvent(0x48000000, 0x44466ef3) reportEvent(0x08000000, 0x444670e6) reportEvent(0x28000000, 0x444670ec) reportEvent(0x68000000, 0x444672df) reportEvent(0x48000000, 0x444672e5) reportEvent(0x08000000, 0x444674d8) reportEvent(0x68000000, 0x444676d1) reportEvent(0x08000000, 0x444678ca) reportEvent(0x28000000, 0x444678d0) reportEvent(0x48000000, 0x44467ac3) reportEvent(0x08000000, 0x44467cbc) reportEvent(0x28000000, 0x44467cc2) reportEvent(0x48000000, 0x44467eb5) reportEvent(0x40000000, 0x44467f3e) reportEvent(0x20000000, 0x444680b2) reportEvent(0x60000000, 0x444682a6) reportEvent(0x40000000, 0x444682ac) reportEvent(0x4c000000, 0x44468330) reportEvent(0x48000000, 0x44468336) reportEvent(0x08000000, 0x4446849f) reportEvent(0x28000000, 0x444684a5) reportEvent(0x20000000, 0x44468722) reportEvent(0x24000000, 0x44468728) reportEvent(0x28000000, 0x44473a9c) reportEvent(0x68000000, 0x44473c0b) reportEvent(0x40000000, 0x44473e8e) reportEvent(0x44000000, 0x44473e94) reportEvent(0x04000000, 0x44473ffd) reportEvent(0x24000000, 0x44474003) reportEvent(0x44000000, 0x444741f6) reportEvent(0x4c000000, 0x4447427f) reportEvent(0x48000000, 0x44474285) reportEvent(0x08000000, 0x444743ef) reportEvent(0x28000000, 0x444743f5) reportEvent(0x48000000, 0x444745e8) reportEvent(0x40000000, 0x44474671) reportEvent(0x24000000, 0x444747e6) reportEvent(0x64000000, 0x444749d9) reportEvent(0x44000000, 0x444749df) reportEvent(0x4c000000, 0x44474a63) reportEvent(0x48000000, 0x44474a69) reportEvent(0x08000000, 0x44474bd2) reportEvent(0x68000000, 0x44474dcb) reportEvent(0x48000000, 0x44474dd1) reportEvent(0x08000000, 0x44474fc4) reportEvent(0x48000000, 0x444751bd) reportEvent(0x08000000, 0x444753b6) reportEvent(0x28000000, 0x444753bc) reportEvent(0x48000000, 0x444755af) reportEvent(0x28000000, 0x444757ac) reportEvent(0x48000000, 0x444759a1) reportEvent(0x40000000, 0x44475a2a) reportEvent(0x24000000, 0x44475b9f) reportEvent(0x64000000, 0x44475d92) reportEvent(0x44000000, 0x44475d98) reportEvent(0x00000000, 0x44475db6) reportEvent(0x40000000, 0x44475dbc) reportEvent(0x00000000, 0x44475f8b) reportEvent(0x60000000, 0x44476184) reportEvent(0x40000000, 0x4447618a) reportEvent(0x00000000, 0x4447637d) reportEvent(0x60000000, 0x44476c18) reportEvent(0x40000000, 0x44476c1e) reportEvent(0x00000000, 0x44476e11) reportEvent(0x60000000, 0x4447700a) reportEvent(0x00000000, 0x44477203) reportEvent(0x20000000, 0x44477209) reportEvent(0x40000000, 0x444773fc) reportEvent(0x00000000, 0x444775f5) reportEvent(0x20000000, 0x444775fb) reportEvent(0x40000000, 0x444777ee) reportEvent(0x20000000, 0x444779eb) reportEvent(0x60000000, 0x44477bdf) reportEvent(0x40000000, 0x44477be5) reportEvent(0x00000000, 0x44477dd8) reportEvent(0x20000000, 0x44477dde) reportEvent(0x60000000, 0x44477fd1) reportEvent(0x40000000, 0x44477fd7) reportEvent(0x00000000, 0x444781ca) reportEvent(0x60000000, 0x444783c3) reportEvent(0x44000000, 0x444783e0) reportEvent(0x04000000, 0x444785bc) reportEvent(0x24000000, 0x444785c2) reportEvent(0x44000000, 0x444787b5) reportEvent(0x48000000, 0x4447883f) reportEvent(0x08000000, 0x444789ae) reportEvent(0x28000000, 0x444789b4) reportEvent(0x48000000, 0x44478ba7) reportEvent(0x40000000, 0x44478c30) reportEvent(0x20000000, 0x4447941f) reportEvent(0x40000000, 0x4447960d) reportEvent(0x00000000, 0x44479806) reportEvent(0x20000000, 0x4447980c) reportEvent(0x40000000, 0x444799ff) reportEvent(0x20000000, 0x44479bfc) reportEvent(0x60000000, 0x44479df0) reportEvent(0x40000000, 0x44479df6) reportEvent(0x00000000, 0x44479fe9) reportEvent(0x20000000, 0x44479fef) reportEvent(0x60000000, 0x4447a1e2) reportEvent(0x40000000, 0x4447a1e8) reportEvent(0x00000000, 0x4447a3db) reportEvent(0x60000000, 0x4447a5d4) reportEvent(0x00000000, 0x4447a7cd) reportEvent(0x20000000, 0x4447a7d3) reportEvent(0x40000000, 0x4447a9c6) reportEvent(0x00000000, 0x4447abbf) reportEvent(0x20000000, 0x4447abc5) reportEvent(0x40000000, 0x4447adb8) reportEvent(0x20000000, 0x4447afb5) reportEvent(0x60000000, 0x4447b1a9) reportEvent(0x40000000, 0x4447b1af) reportEvent(0x4c000000, 0x4447b233) reportEvent(0x48000000, 0x4447b239) reportEvent(0x08000000, 0x4447b3a2) reportEvent(0x28000000, 0x4447b3a8) reportEvent(0x68000000, 0x4447b59b) reportEvent(0x48000000, 0x4447b5a1) reportEvent(0x40000000, 0x4447b625) reportEvent(0x00000000, 0x4447b794) reportEvent(0x20000000, 0x4447be12) reportEvent(0x60000000, 0x4447c001) reportEvent(0x40000000, 0x4447c007) reportEvent(0x00000000, 0x4447c1fa) reportEvent(0x20000000, 0x4447c200) reportEvent(0x60000000, 0x4447c3f3) reportEvent(0x40000000, 0x4447c3f9) reportEvent(0x00000000, 0x4447c5ec) reportEvent(0x60000000, 0x4447c7e5) reportEvent(0x00000000, 0x4447c9de) reportEvent(0x20000000, 0x4447c9e4) reportEvent(0x40000000, 0x4447cbd7) reportEvent(0x00000000, 0x4447cdd0) reportEvent(0x20000000, 0x4447cdd6) reportEvent(0x40000000, 0x4447cfc9) reportEvent(0x20000000, 0x4447d1c6) reportEvent(0x60000000, 0x4447d3ba) reportEvent(0x40000000, 0x4447d3c0) reportEvent(0x00000000, 0x4447d5b3) reportEvent(0x20000000, 0x4447d5b9) reportEvent(0x60000000, 0x4447d7ac) reportEvent(0x40000000, 0x4447d7b2) reportEvent(0x00000000, 0x4447d9a5) reportEvent(0x60000000, 0x4447db9e) reportEvent(0x44000000, 0x4447dbbb) reportEvent(0x48000000, 0x4447dc28) reportEvent(0x08000000, 0x4447dd97) reportEvent(0x28000000, 0x4447dd9d) reportEvent(0x48000000, 0x4447df90) reportEvent(0x00000000, 0x4447e189) reportEvent(0x60000000, 0x4447e9f6) reportEvent(0x00000000, 0x4447ebef) reportEvent(0x20000000, 0x4447ebf5) reportEvent(0x40000000, 0x4447ede8) reportEvent(0x00000000, 0x4447efe1) reportEvent(0x20000000, 0x4447efe7) reportEvent(0x40000000, 0x4447f1da) reportEvent(0x20000000, 0x4447f3d7) reportEvent(0x60000000, 0x4447f5cb) reportEvent(0x40000000, 0x4447f5d1) reportEvent(0x00000000, 0x4447f7c4) reportEvent(0x20000000, 0x4447f7ca) reportEvent(0x60000000, 0x4447f9bd) reportEvent(0x40000000, 0x4447f9c3) reportEvent(0x00000000, 0x4447fbb6) reportEvent(0x60000000, 0x4447fdaf) reportEvent(0x00000000, 0x4447ffa8) reportEvent(0x20000000, 0x4447ffae) reportEvent(0x40000000, 0x444801a1) reportEvent(0x44000000, 0x444801be) reportEvent(0x04000000, 0x4448039a) reportEvent(0x24000000, 0x444803a0) reportEvent(0x44000000, 0x44480593) reportEvent(0x4c000000, 0x4448061c) reportEvent(0x48000000, 0x44480622) reportEvent(0x28000000, 0x44480790) reportEvent(0x68000000, 0x44480984) reportEvent(0x48000000, 0x4448098a) reportEvent(0x40000000, 0x44480a0e) reportEvent(0x00000000, 0x44480b7d) reportEvent(0x20000000, 0x444811f4) reportEvent(0x40000000, 0x444813eb) reportEvent(0x20000000, 0x444815e8) reportEvent(0x60000000, 0x444817dc) reportEvent(0x40000000, 0x444817e2) reportEvent(0x00000000, 0x444819d5) reportEvent(0x20000000, 0x444819db) reportEvent(0x60000000, 0x44481bce) reportEvent(0x40000000, 0x44481bd4) reportEvent(0x00000000, 0x44481dc7) reportEvent(0x60000000, 0x44481fc0) reportEvent(0x00000000, 0x444821b9) reportEvent(0x20000000, 0x444821bf) reportEvent(0x40000000, 0x444823b2) reportEvent(0x00000000, 0x444825ab) reportEvent(0x20000000, 0x444825b1) reportEvent(0x40000000, 0x444827a4) reportEvent(0x20000000, 0x444829a1) reportEvent(0x60000000, 0x44482b95) reportEvent(0x40000000, 0x44482b9b) reportEvent(0x00000000, 0x44482d8e) reportEvent(0x20000000, 0x44482d94) reportEvent(0x60000000, 0x44482f87) reportEvent(0x40000000, 0x44482f8d) reportEvent(0x44000000, 0x44482fa4) reportEvent(0x4c000000, 0x44483011) reportEvent(0x08000000, 0x44483180) reportEvent(0x68000000, 0x44483379) reportEvent(0x40000000, 0x44483403) reportEvent(0x00000000, 0x44483572) reportEvent(0x60000000, 0x44483ddf) reportEvent(0x40000000, 0x44483de5) reportEvent(0x00000000, 0x44483fd8) reportEvent(0x60000000, 0x444841d1) reportEvent(0x00000000, 0x444843ca) reportEvent(0x20000000, 0x444843d0) reportEvent(0x40000000, 0x444845c3) reportEvent(0x00000000, 0x444847bc) reportEvent(0x20000000, 0x444847c2) reportEvent(0x40000000, 0x444849b5) reportEvent(0x44000000, 0x444849d2) reportEvent(0x24000000, 0x44484bb2) reportEvent(0x64000000, 0x44484da6) reportEvent(0x44000000, 0x44484dac) reportEvent(0x00000000, 0x00000000) reportEvent(0x40000000, 0x44484dcd) reportEvent(0x00000000, 0x44484f9f) reportEvent(0x20000000, 0x44484fa5) reportEvent(0x60000000, 0x44485198) reportEvent(0x40000000, 0x4448519e) reportEvent(0x00000000, 0x44485391) reportEvent(0x60000000, 0x4448558a) reportEvent(0x44000000, 0x444855a7) reportEvent(0x04000000, 0x44485783) reportEvent(0x24000000, 0x44485789) reportEvent(0x44000000, 0x4448597c) reportEvent(0x48000000, 0x44485a06) reportEvent(0x08000000, 0x44485b75) reportEvent(0x28000000, 0x44485b7b) reportEvent(0x48000000, 0x44485d6e) reportEvent(0x40000000, 0x44485df7) reportEvent(0x20000000, 0x444865e2) reportEvent(0x40000000, 0x444867d4) reportEvent(0x00000000, 0x444869cd) reportEvent(0x20000000, 0x444869d3) reportEvent(0x40000000, 0x44486bc6) reportEvent(0x20000000, 0x44486dc3) reportEvent(0x60000000, 0x44486fb7) reportEvent(0x40000000, 0x44486fbd) reportEvent(0x00000000, 0x444871b0) reportEvent(0x20000000, 0x444871b6) reportEvent(0x60000000, 0x444873a9) reportEvent(0x40000000, 0x444873af) reportEvent(0x00000000, 0x444875a2) reportEvent(0x60000000, 0x4448779b) reportEvent(0x00000000, 0x44487994) reportEvent(0x20000000, 0x4448799a) reportEvent(0x40000000, 0x44487b8d) reportEvent(0x00000000, 0x44487d86) reportEvent(0x20000000, 0x44487d8c) reportEvent(0x40000000, 0x44487f7f) reportEvent(0x20000000, 0x4448817c) reportEvent(0x60000000, 0x44488370) reportEvent(0x40000000, 0x44488376) reportEvent(0x44000000, 0x4448838e) reportEvent(0x4c000000, 0x444883fa) reportEvent(0x48000000, 0x44488400) reportEvent(0x08000000, 0x44488569) reportEvent(0x28000000, 0x4448856f) reportEvent(0x68000000, 0x44488762) reportEvent(0x48000000, 0x44488768) reportEvent(0x40000000, 0x444887ec) reportEvent(0x00000000, 0x4448895b) reportEvent(0x04000000, 0x44488fb0) reportEvent(0x64000000, 0x444891c8) reportEvent(0x44000000, 0x444891ce) reportEvent(0x04000000, 0x444893c1) reportEvent(0x24000000, 0x444893c7) reportEvent(0x64000000, 0x444895ba) reportEvent(0x44000000, 0x444895c0) reportEvent(0x04000000, 0x444897b3) reportEvent(0x64000000, 0x444899ac) reportEvent(0x04000000, 0x44489ba5) reportEvent(0x24000000, 0x44489bab) reportEvent(0x44000000, 0x44489d9e) reportEvent(0x00000000, 0x44489f97) reportEvent(0x20000000, 0x44489f9d) reportEvent(0x40000000, 0x4448a190) reportEvent(0x44000000, 0x4448a1ad) reportEvent(0x24000000, 0x4448a38d) reportEvent(0x64000000, 0x4448a581) reportEvent(0x44000000, 0x4448a587) reportEvent(0x44000000, 0x4448a5a7) reportEvent(0x00000000, 0x4448a77a) reportEvent(0x20000000, 0x4448a780) reportEvent(0x60000000, 0x4448a973) reportEvent(0x40000000, 0x4448a979) reportEvent(0x04000000, 0x4448ab6c) reportEvent(0x64000000, 0x4448ad65) reportEvent(0x48000000, 0x4448adef) reportEvent(0x08000000, 0x4448af5e) reportEvent(0x28000000, 0x4448af64) reportEvent(0x48000000, 0x4448b157) reportEvent(0x44000000, 0x4448b1e5) reportEvent(0x04000000, 0x4448b350) reportEvent(0x00000000, 0x4448b9b2) reportEvent(0x60000000, 0x4448bbbd) reportEvent(0x00000000, 0x4448bdb6) reportEvent(0x20000000, 0x4448bdbc) reportEvent(0x40000000, 0x4448bfaf) reportEvent(0x00000000, 0x4448c1a8) reportEvent(0x20000000, 0x4448c1ae) reportEvent(0x40000000, 0x4448c3a1) reportEvent(0x20000000, 0x4448c59e) reportEvent(0x60000000, 0x4448c792) reportEvent(0x40000000, 0x4448c798) reportEvent(0x00000000, 0x4448c98b) reportEvent(0x20000000, 0x4448c991) reportEvent(0x60000000, 0x4448cb84) reportEvent(0x40000000, 0x4448cb8a) reportEvent(0x00000000, 0x4448cd7d) reportEvent(0x60000000, 0x4448cf76) reportEvent(0x00000000, 0x4448d16f) reportEvent(0x20000000, 0x4448d175) reportEvent(0x40000000, 0x4448d368) reportEvent(0x44000000, 0x4448d385) reportEvent(0x04000000, 0x4448d561) reportEvent(0x24000000, 0x4448d567) reportEvent(0x44000000, 0x4448d75a) reportEvent(0x4c000000, 0x4448d7e3) reportEvent(0x48000000, 0x4448d7e9) reportEvent(0x28000000, 0x4448d957) reportEvent(0x68000000, 0x4448db4b) reportEvent(0x48000000, 0x4448db51) reportEvent(0x40000000, 0x4448dbd5) reportEvent(0x00000000, 0x4448dd44) reportEvent(0x20000000, 0x4448e3bf) reportEvent(0x40000000, 0x4448e5b2) reportEvent(0x20000000, 0x4448e7af) reportEvent(0x60000000, 0x4448e9a3) reportEvent(0x40000000, 0x4448e9a9) reportEvent(0x00000000, 0x4448eb9c) reportEvent(0x20000000, 0x4448eba2) reportEvent(0x60000000, 0x4448ed95) reportEvent(0x40000000, 0x4448ed9b) reportEvent(0x00000000, 0x4448ef8e) reportEvent(0x60000000, 0x4448f187) reportEvent(0x44000000, 0x4448f1a4) reportEvent(0x04000000, 0x4448f380) reportEvent(0x24000000, 0x4448f386) reportEvent(0x44000000, 0x4448f579) reportEvent(0x44000000, 0x4448f59e) reportEvent(0x00000000, 0x4448f772) reportEvent(0x20000000, 0x4448f778) reportEvent(0x40000000, 0x4448f96b) reportEvent(0x20000000, 0x4448fb68) reportEvent(0x60000000, 0x4448fd5c) reportEvent(0x40000000, 0x4448fd62) reportEvent(0x00000000, 0x4448ff55) reportEvent(0x20000000, 0x4448ff5b) reportEvent(0x60000000, 0x4449014e) reportEvent(0x40000000, 0x44490154) reportEvent(0x44000000, 0x4449016b) reportEvent(0x4c000000, 0x444901d8) reportEvent(0x08000000, 0x44490347) reportEvent(0x68000000, 0x44490540) reportEvent(0x40000000, 0x444905ca) reportEvent(0x00000000, 0x44490739) reportEvent(0x20000000, 0x44490db8) reportEvent(0x60000000, 0x44490fa6) reportEvent(0x40000000, 0x44490fac) reportEvent(0x00000000, 0x4449119f) reportEvent(0x60000000, 0x44491398) reportEvent(0x00000000, 0x44491591) reportEvent(0x20000000, 0x44491597) reportEvent(0x40000000, 0x4449178a) reportEvent(0x44000000, 0x444917a7) reportEvent(0x04000000, 0x44491983) reportEvent(0x24000000, 0x44491989) reportEvent(0x44000000, 0x44491b7c) reportEvent(0x24000000, 0x44491d79) reportEvent(0x64000000, 0x44491f6d) reportEvent(0x44000000, 0x44491f73) reportEvent(0x00000000, 0x00000000) reportEvent(0x40000000, 0x44491f94) reportEvent(0x00000000, 0x44492166) reportEvent(0x20000000, 0x4449216c) reportEvent(0x60000000, 0x4449235f) reportEvent(0x40000000, 0x44492365) reportEvent(0x00000000, 0x44492558) reportEvent(0x60000000, 0x44492751) reportEvent(0x44000000, 0x4449276e) reportEvent(0x04000000, 0x4449294a) reportEvent(0x24000000, 0x44492950) reportEvent(0x44000000, 0x44492b43) reportEvent(0x48000000, 0x44492bcd) reportEvent(0x08000000, 0x44492d3c) reportEvent(0x28000000, 0x44492d42) reportEvent(0x48000000, 0x44492f35) reportEvent(0x40000000, 0x44492fbe) reportEvent(0x20000000, 0x444937a8) reportEvent(0x40000000, 0x4449399b) reportEvent(0x00000000, 0x44493b94) reportEvent(0x20000000, 0x44493b9a) reportEvent(0x40000000, 0x44493d8d) reportEvent(0x20000000, 0x44493f8a) reportEvent(0x60000000, 0x4449417e) reportEvent(0x40000000, 0x44494184) reportEvent(0x04000000, 0x44494377) reportEvent(0x24000000, 0x4449437d) reportEvent(0x64000000, 0x44494570) reportEvent(0x44000000, 0x44494576) reportEvent(0x44000000, 0x44494595) reportEvent(0x00000000, 0x44494769) reportEvent(0x60000000, 0x44494962) reportEvent(0x44000000, 0x4449497f) reportEvent(0x04000000, 0x44494b5b) reportEvent(0x24000000, 0x44494b61) reportEvent(0x44000000, 0x44494d54) reportEvent(0x04000000, 0x44494f4d) reportEvent(0x24000000, 0x44494f53) reportEvent(0x44000000, 0x44495146) reportEvent(0x44000000, 0x44495169) reportEvent(0x20000000, 0x44495343) reportEvent(0x60000000, 0x44495537) reportEvent(0x40000000, 0x4449553d) reportEvent(0x4c000000, 0x444955c1) reportEvent(0x48000000, 0x444955c7) reportEvent(0x08000000, 0x44495730) reportEvent(0x28000000, 0x44495736) reportEvent(0x68000000, 0x44495929) reportEvent(0x48000000, 0x4449592f) reportEvent(0x40000000, 0x444959b3) reportEvent(0x00000000, 0x44495b22) reportEvent(0x20000000, 0x44496199) reportEvent(0x60000000, 0x4449638f) reportEvent(0x40000000, 0x44496395) reportEvent(0x00000000, 0x44496588) reportEvent(0x20000000, 0x4449658e) reportEvent(0x60000000, 0x44496781) reportEvent(0x40000000, 0x44496787) reportEvent(0x44000000, 0x4449679e) reportEvent(0x04000000, 0x4449697a) reportEvent(0x64000000, 0x44496b73) reportEvent(0x44000000, 0x44496b96) reportEvent(0x00000000, 0x44496d6c) reportEvent(0x20000000, 0x44496d72) reportEvent(0x40000000, 0x44496f65) reportEvent(0x44000000, 0x44496f82) reportEvent(0x04000000, 0x4449715e) reportEvent(0x24000000, 0x44497164) reportEvent(0x44000000, 0x44497357) reportEvent(0x24000000, 0x44497554) reportEvent(0x64000000, 0x44497748) reportEvent(0x44000000, 0x4449774e) reportEvent(0x04000000, 0x44497941) reportEvent(0x24000000, 0x44497947) reportEvent(0x64000000, 0x44497b3a) reportEvent(0x44000000, 0x44497b40) reportEvent(0x00000000, 0x00000000) reportEvent(0x44000000, 0x44497b5f) reportEvent(0x40000000, 0x44497b65) reportEvent(0x00000000, 0x44497d33) reportEvent(0x60000000, 0x44497f2c) reportEvent(0x44000000, 0x44497f49) reportEvent(0x48000000, 0x44497fb6) reportEvent(0x08000000, 0x44498125) reportEvent(0x28000000, 0x4449812b) reportEvent(0x48000000, 0x4449831e) reportEvent(0x00000000, 0x44498517) reportEvent(0x04000000, 0x44498b70) reportEvent(0x24000000, 0x44498b93) reportEvent(0x64000000, 0x44498d84) reportEvent(0x00000000, 0x44498da7) reportEvent(0x00000000, 0x44498f7d) reportEvent(0x20000000, 0x44498f83) reportEvent(0x40000000, 0x44499176) reportEvent(0x00000000, 0x4449936f) reportEvent(0x20000000, 0x44499375) reportEvent(0x40000000, 0x44499568) reportEvent(0x20000000, 0x44499765) reportEvent(0x60000000, 0x44499959) reportEvent(0x40000000, 0x4449995f) reportEvent(0x00000000, 0x44499b52) reportEvent(0x20000000, 0x44499b58) reportEvent(0x60000000, 0x44499d4b) reportEvent(0x40000000, 0x44499d51) reportEvent(0x44000000, 0x44499d68) reportEvent(0x04000000, 0x44499f44) reportEvent(0x64000000, 0x4449a13d) reportEvent(0x04000000, 0x4449a336) reportEvent(0x24000000, 0x4449a33c) reportEvent(0x44000000, 0x4449a52f) reportEvent(0x44000000, 0x4449a554) reportEvent(0x40000000, 0x4449a55a) reportEvent(0x00000000, 0x4449a728) reportEvent(0x20000000, 0x4449a72e) reportEvent(0x40000000, 0x4449a921) reportEvent(0x44000000, 0x4449a93e) reportEvent(0x4c000000, 0x4449a9aa) reportEvent(0x48000000, 0x4449a9b0) reportEvent(0x28000000, 0x4449ab1e) reportEvent(0x68000000, 0x4449ad12) reportEvent(0x48000000, 0x4449ad18) reportEvent(0x40000000, 0x4449ad9c) reportEvent(0x00000000, 0x4449af0b) reportEvent(0x04000000, 0x4449b563) reportEvent(0x24000000, 0x4449b586) reportEvent(0x44000000, 0x4449b779) reportEvent(0x24000000, 0x4449b976) reportEvent(0x64000000, 0x4449bb6a) reportEvent(0x44000000, 0x4449bb70) reportEvent(0x40000000, 0x4449bb8f) reportEvent(0x40000000, 0x4449bb95) reportEvent(0x00000000, 0x4449bd63) reportEvent(0x20000000, 0x4449bd69) reportEvent(0x60000000, 0x4449bf5c) reportEvent(0x40000000, 0x4449bf62) reportEvent(0x00000000, 0x4449c155) reportEvent(0x60000000, 0x4449c34e) reportEvent(0x44000000, 0x4449c36b) reportEvent(0x04000000, 0x4449c547) reportEvent(0x24000000, 0x4449c54d) reportEvent(0x44000000, 0x4449c740) reportEvent(0x04000000, 0x4449c939) reportEvent(0x24000000, 0x4449c93f) reportEvent(0x44000000, 0x4449cb32) reportEvent(0x24000000, 0x4449cd2f) reportEvent(0x64000000, 0x4449cf23) reportEvent(0x44000000, 0x4449cf29) reportEvent(0x40000000, 0x4449cf4a) reportEvent(0x00000000, 0x4449d11c) reportEvent(0x20000000, 0x4449d122) reportEvent(0x60000000, 0x4449d315) reportEvent(0x40000000, 0x4449d31b) reportEvent(0x44000000, 0x4449d332) reportEvent(0x48000000, 0x4449d39f) reportEvent(0x08000000, 0x4449d50e) reportEvent(0x68000000, 0x4449d707) reportEvent(0x40000000, 0x4449d791) reportEvent(0x44000000, 0x4449d797) reportEvent(0x04000000, 0x4449d900) reportEvent(0x00000000, 0x4449df5b) reportEvent(0x00000000, 0x4449df61) reportEvent(0x20000000, 0x4449df77) reportEvent(0x60000000, 0x4449e16d) reportEvent(0x40000000, 0x4449e173) reportEvent(0x44000000, 0x4449e18a) reportEvent(0x04000000, 0x4449e366) reportEvent(0x64000000, 0x4449e55f) reportEvent(0x40000000, 0x4449e583) reportEvent(0x40000000, 0x4449e589) reportEvent(0x00000000, 0x4449e758) reportEvent(0x20000000, 0x4449e75e) reportEvent(0x40000000, 0x4449e951) reportEvent(0x00000000, 0x4449eb4a) reportEvent(0x20000000, 0x4449eb50) reportEvent(0x40000000, 0x4449ed43) reportEvent(0x20000000, 0x4449ef40) reportEvent(0x60000000, 0x4449f134) reportEvent(0x40000000, 0x4449f13a) reportEvent(0x00000000, 0x4449f32d) reportEvent(0x20000000, 0x4449f333) reportEvent(0x60000000, 0x4449f526) reportEvent(0x40000000, 0x4449f52c) reportEvent(0x00000000, 0x4449f71f) reportEvent(0x60000000, 0x4449f918) reportEvent(0x44000000, 0x4449f935) reportEvent(0x04000000, 0x4449fb11) reportEvent(0x24000000, 0x4449fb17) reportEvent(0x44000000, 0x4449fd0a) reportEvent(0x48000000, 0x4449fd94) reportEvent(0x08000000, 0x4449ff03) reportEvent(0x28000000, 0x4449ff09) reportEvent(0x48000000, 0x444a00fc) reportEvent(0x40000000, 0x444a0185) reportEvent(0x44000000, 0x444a018b) reportEvent(0x00000000, 0x444a0954) reportEvent(0x20000000, 0x444a0970) reportEvent(0x40000000, 0x444a0b62) reportEvent(0x44000000, 0x444a0b7f) reportEvent(0x04000000, 0x444a0d5b) reportEvent(0x24000000, 0x444a0d61) reportEvent(0x44000000, 0x444a0f54) reportEvent(0x24000000, 0x444a1151) reportEvent(0x64000000, 0x444a1345) reportEvent(0x44000000, 0x444a134b) reportEvent(0x00000000, 0x00000000) reportEvent(0x40000000, 0x444a136c) reportEvent(0x00000000, 0x444a153e) reportEvent(0x20000000, 0x444a1544) reportEvent(0x60000000, 0x444a1737) reportEvent(0x40000000, 0x444a173d) reportEvent(0x44000000, 0x444a1754) reportEvent(0x04000000, 0x444a1930) reportEvent(0x64000000, 0x444a1b29) reportEvent(0x04000000, 0x444a1d22) reportEvent(0x24000000, 0x444a1d28) reportEvent(0x44000000, 0x444a1f1b) reportEvent(0x04000000, 0x444a2114) reportEvent(0x24000000, 0x444a211a) reportEvent(0x44000000, 0x444a230d) reportEvent(0x44000000, 0x444a2330) reportEvent(0x20000000, 0x444a250a) reportEvent(0x60000000, 0x444a26fe) reportEvent(0x40000000, 0x444a2704) reportEvent(0x4c000000, 0x444a2788) reportEvent(0x48000000, 0x444a278e) reportEvent(0x08000000, 0x444a28f7) reportEvent(0x28000000, 0x444a28fd) reportEvent(0x68000000, 0x444a2af0) reportEvent(0x48000000, 0x444a2af6) reportEvent(0x40000000, 0x444a2b7a) reportEvent(0x44000000, 0x444a2b80) reportEvent(0x04000000, 0x444a2ce9) reportEvent(0x04000000, 0x444a3344) reportEvent(0x20000000, 0x444a3361) reportEvent(0x60000000, 0x444a3556) reportEvent(0x40000000, 0x444a355c) reportEvent(0x04000000, 0x444a374f) reportEvent(0x24000000, 0x444a3755) reportEvent(0x64000000, 0x444a3948) reportEvent(0x44000000, 0x444a394e) reportEvent(0x04000000, 0x444a3b41) reportEvent(0x64000000, 0x444a3d3a) reportEvent(0x44000000, 0x444a3d5d) reportEvent(0x00000000, 0x444a3f33) reportEvent(0x20000000, 0x444a3f39) reportEvent(0x40000000, 0x444a412c) reportEvent(0x00000000, 0x444a4325) reportEvent(0x20000000, 0x444a432b) reportEvent(0x40000000, 0x444a451e) reportEvent(0x20000000, 0x444a471b) reportEvent(0x60000000, 0x444a490f) reportEvent(0x40000000, 0x444a4915) reportEvent(0x00000000, 0x444a4b08) reportEvent(0x20000000, 0x444a4b0e) reportEvent(0x60000000, 0x444a4d01) reportEvent(0x40000000, 0x444a4d07) reportEvent(0x04000000, 0x444a4efa) reportEvent(0x64000000, 0x444a50f3) reportEvent(0x48000000, 0x444a517d) reportEvent(0x08000000, 0x444a52ec) reportEvent(0x28000000, 0x444a52f2) reportEvent(0x48000000, 0x444a54e5) reportEvent(0x44000000, 0x444a5573) reportEvent(0x04000000, 0x444a56de) reportEvent(0x00000000, 0x444a5d41) reportEvent(0x20000000, 0x444a5d5b) reportEvent(0x60000000, 0x444a5f4b) reportEvent(0x44000000, 0x444a5f68) reportEvent(0x04000000, 0x444a6144) reportEvent(0x24000000, 0x444a614a) reportEvent(0x44000000, 0x444a633d) reportEvent(0x04000000, 0x444a6536) reportEvent(0x24000000, 0x444a653c) reportEvent(0x44000000, 0x444a672f) reportEvent(0x44000000, 0x444a6752) reportEvent(0x20000000, 0x444a692c) reportEvent(0x60000000, 0x444a6b20) reportEvent(0x40000000, 0x444a6b26) reportEvent(0x04000000, 0x444a6d19) reportEvent(0x24000000, 0x444a6d1f) reportEvent(0x64000000, 0x444a6f12) reportEvent(0x44000000, 0x444a6f18) reportEvent(0x04000000, 0x444a710b) reportEvent(0x64000000, 0x444a7304) reportEvent(0x44000000, 0x444a7327) reportEvent(0x00000000, 0x444a74fd) reportEvent(0x20000000, 0x444a7503) reportEvent(0x40000000, 0x444a76f6) reportEvent(0x00000000, 0x444a78ef) reportEvent(0x20000000, 0x444a78f5) reportEvent(0x40000000, 0x444a7ae8) reportEvent(0x44000000, 0x444a7b05) reportEvent(0x4c000000, 0x444a7b71) reportEvent(0x48000000, 0x444a7b77) reportEvent(0x28000000, 0x444a7ce5) reportEvent(0x68000000, 0x444a7ed9) reportEvent(0x48000000, 0x444a7edf) reportEvent(0x40000000, 0x444a7f63) reportEvent(0x04000000, 0x444a80d2) reportEvent(0x04000000, 0x444a8730) reportEvent(0x20000000, 0x444a874d) reportEvent(0x40000000, 0x444a8940) reportEvent(0x44000000, 0x444a895d) reportEvent(0x24000000, 0x444a8b3d) reportEvent(0x64000000, 0x444a8d31) reportEvent(0x44000000, 0x444a8d37) reportEvent(0x04000000, 0x444a8f2a) reportEvent(0x24000000, 0x444a8f30) reportEvent(0x64000000, 0x444a9123) reportEvent(0x44000000, 0x444a9129) reportEvent(0x44000000, 0x444a9147) reportEvent(0x00000000, 0x444a931c) reportEvent(0x60000000, 0x444a9515) reportEvent(0x44000000, 0x444a9532) reportEvent(0x04000000, 0x444a970e) reportEvent(0x24000000, 0x444a9714) reportEvent(0x44000000, 0x444a9907) reportEvent(0x04000000, 0x444a9b00) reportEvent(0x24000000, 0x444a9b06) reportEvent(0x44000000, 0x444a9cf9) reportEvent(0x24000000, 0x444a9ef6) reportEvent(0x64000000, 0x444aa0ea) reportEvent(0x44000000, 0x444aa0f0) reportEvent(0x04000000, 0x444aa2e3) reportEvent(0x24000000, 0x444aa2e9) reportEvent(0x64000000, 0x444aa4dc) reportEvent(0x44000000, 0x444aa4e2) reportEvent(0x48000000, 0x444aa566) reportEvent(0x08000000, 0x444aa6d5) reportEvent(0x68000000, 0x444aa8ce) reportEvent(0x40000000, 0x444aa958) reportEvent(0x44000000, 0x444aa95e) reportEvent(0x04000000, 0x444aaac7) reportEvent(0x04000000, 0x444ab129) reportEvent(0x20000000, 0x444ab146) reportEvent(0x60000000, 0x444ab334) reportEvent(0x40000000, 0x444ab33a) reportEvent(0x44000000, 0x444ab351) reportEvent(0x04000000, 0x444ab52d) reportEvent(0x64000000, 0x444ab726) reportEvent(0x04000000, 0x444ab91f) reportEvent(0x24000000, 0x444ab925) reportEvent(0x44000000, 0x444abb18) reportEvent(0x00000000, 0x00000000) reportEvent(0x44000000, 0x444abb3d) reportEvent(0x40000000, 0x444abb43) reportEvent(0x00000000, 0x444abd11) reportEvent(0x20000000, 0x444abd17) reportEvent(0x40000000, 0x444abf0a) reportEvent(0x20000000, 0x444ac107) reportEvent(0x60000000, 0x444ac2fb) reportEvent(0x40000000, 0x444ac301) reportEvent(0x04000000, 0x444ac4f4) reportEvent(0x24000000, 0x444ac4fa) reportEvent(0x64000000, 0x444ac6ed) reportEvent(0x44000000, 0x444ac6f3) reportEvent(0x04000000, 0x444ac8e6) reportEvent(0x64000000, 0x444acadf) reportEvent(0x04000000, 0x444accd8) reportEvent(0x24000000, 0x444accde) reportEvent(0x44000000, 0x444aced1) reportEvent(0x48000000, 0x444acf5b) reportEvent(0x08000000, 0x444ad0ca) reportEvent(0x28000000, 0x444ad0d0) reportEvent(0x48000000, 0x444ad2c3) reportEvent(0x40000000, 0x444ad34c) reportEvent(0x44000000, 0x444ad352) reportEvent(0x04000000, 0x444adb1a) reportEvent(0x20000000, 0x444adb37) reportEvent(0x40000000, 0x444add29) reportEvent(0x00000000, 0x444adf22) reportEvent(0x20000000, 0x444adf28) reportEvent(0x40000000, 0x444ae11b) reportEvent(0x44000000, 0x444ae138) reportEvent(0x24000000, 0x444ae318) reportEvent(0x64000000, 0x444ae50c) reportEvent(0x44000000, 0x444ae512) reportEvent(0x00000000, 0x00000000) reportEvent(0x40000000, 0x444ae533) reportEvent(0x00000000, 0x444ae705) reportEvent(0x20000000, 0x444ae70b) reportEvent(0x60000000, 0x444ae8fe) reportEvent(0x40000000, 0x444ae904) reportEvent(0x00000000, 0x444aeaf7) reportEvent(0x60000000, 0x444aecf0) reportEvent(0x00000000, 0x444aeee9) reportEvent(0x20000000, 0x444aeeef) reportEvent(0x40000000, 0x444af0e2) reportEvent(0x00000000, 0x444af2db) reportEvent(0x20000000, 0x444af2e1) reportEvent(0x40000000, 0x444af4d4) reportEvent(0x20000000, 0x444af6d1) reportEvent(0x60000000, 0x444af8c5) reportEvent(0x40000000, 0x444af8cb) reportEvent(0x44000000, 0x444af8e3) reportEvent(0x4c000000, 0x444af94f) reportEvent(0x48000000, 0x444af955) reportEvent(0x08000000, 0x444afabe) reportEvent(0x28000000, 0x444afac4) reportEvent(0x68000000, 0x444afcb7) reportEvent(0x48000000, 0x444afcbd) reportEvent(0x40000000, 0x444afd41) reportEvent(0x00000000, 0x444afeb0) reportEvent(0x20000000, 0x444b0528) reportEvent(0x60000000, 0x444b071d) reportEvent(0x40000000, 0x444b0723) reportEvent(0x04000000, 0x444b0916) reportEvent(0x24000000, 0x444b091c) reportEvent(0x64000000, 0x444b0b0f) reportEvent(0x44000000, 0x444b0b15) reportEvent(0x00000000, 0x444b0d08) reportEvent(0x60000000, 0x444b0f01) reportEvent(0x00000000, 0x444b10fa) reportEvent(0x20000000, 0x444b1100) reportEvent(0x40000000, 0x444b12f3) reportEvent(0x00000000, 0x444b14ec) reportEvent(0x20000000, 0x444b14f2) reportEvent(0x40000000, 0x444b16e5) reportEvent(0x44000000, 0x444b1702) reportEvent(0x24000000, 0x444b18e2) reportEvent(0x64000000, 0x444b1ad6) reportEvent(0x44000000, 0x444b1adc) reportEvent(0x00000000, 0x444b1afb) reportEvent(0x40000000, 0x444b1b01) reportEvent(0x00000000, 0x444b1ccf) reportEvent(0x20000000, 0x444b1cd5) reportEvent(0x60000000, 0x444b1ec8) reportEvent(0x40000000, 0x444b1ece) reportEvent(0x00000000, 0x444b20c1) reportEvent(0x60000000, 0x444b22ba) reportEvent(0x44000000, 0x444b22d7) reportEvent(0x48000000, 0x444b2344) reportEvent(0x08000000, 0x444b24b3) reportEvent(0x28000000, 0x444b24b9) reportEvent(0x48000000, 0x444b26ac) reportEvent(0x44000000, 0x444b273a) reportEvent(0x04000000, 0x444b28a5) reportEvent(0x00000000, 0x444b2f05) reportEvent(0x00000000, 0x444b2f0b) reportEvent(0x60000000, 0x444b3112) reportEvent(0x44000000, 0x444b312f) reportEvent(0x04000000, 0x444b330b) reportEvent(0x24000000, 0x444b3311) reportEvent(0x44000000, 0x444b3504) reportEvent(0x04000000, 0x444b36fd) reportEvent(0x24000000, 0x444b3703) reportEvent(0x44000000, 0x444b38f6) reportEvent(0x44000000, 0x444b3919) reportEvent(0x20000000, 0x444b3af3) reportEvent(0x60000000, 0x444b3ce7) reportEvent(0x40000000, 0x444b3ced) reportEvent(0x00000000, 0x444b3ee0) reportEvent(0x20000000, 0x444b3ee6) reportEvent(0x60000000, 0x444b40d9) reportEvent(0x40000000, 0x444b40df) reportEvent(0x44000000, 0x444b40f6) reportEvent(0x04000000, 0x444b42d2) reportEvent(0x64000000, 0x444b44cb) reportEvent(0x00000000, 0x444b44ee) reportEvent(0x00000000, 0x444b46c4) reportEvent(0x20000000, 0x444b46ca) reportEvent(0x40000000, 0x444b48bd) reportEvent(0x44000000, 0x444b48da) reportEvent(0x04000000, 0x444b4ab6) reportEvent(0x24000000, 0x444b4abc) reportEvent(0x44000000, 0x444b4caf) reportEvent(0x4c000000, 0x444b4d38) reportEvent(0x48000000, 0x444b4d3e) reportEvent(0x28000000, 0x444b4eac) reportEvent(0x68000000, 0x444b50a0) reportEvent(0x48000000, 0x444b50a6) reportEvent(0x40000000, 0x444b512a) reportEvent(0x04000000, 0x444b5299) reportEvent(0x04000000, 0x444b58f5) reportEvent(0x20000000, 0x444b5912) reportEvent(0x40000000, 0x444b5b07) reportEvent(0x44000000, 0x444b5b24) reportEvent(0x24000000, 0x444b5d04) reportEvent(0x64000000, 0x444b5ef8) reportEvent(0x44000000, 0x444b5efe) reportEvent(0x04000000, 0x444b60f1) reportEvent(0x24000000, 0x444b60f7) reportEvent(0x64000000, 0x444b62ea) reportEvent(0x44000000, 0x444b62f0) reportEvent(0x04000000, 0x444b64e3) reportEvent(0x64000000, 0x444b66dc) reportEvent(0x44000000, 0x444b66ff) reportEvent(0x00000000, 0x444b68d5) reportEvent(0x20000000, 0x444b68db) reportEvent(0x40000000, 0x444b6ace) reportEvent(0x44000000, 0x444b6aeb) reportEvent(0x04000000, 0x444b6cc7) reportEvent(0x24000000, 0x444b6ccd) reportEvent(0x44000000, 0x444b6ec0) reportEvent(0x24000000, 0x444b70bd) reportEvent(0x64000000, 0x444b72b1) reportEvent(0x44000000, 0x444b72b7) reportEvent(0x40000000, 0x444b72d6) reportEvent(0x00000000, 0x444b74aa) reportEvent(0x20000000, 0x444b74b0) reportEvent(0x60000000, 0x444b76a3) reportEvent(0x40000000, 0x444b76a9) reportEvent(0x44000000, 0x444b76c0) reportEvent(0x48000000, 0x444b772d) reportEvent(0x08000000, 0x444b789c) reportEvent(0x68000000, 0x444b7a95) reportEvent(0x40000000, 0x444b7b1f) reportEvent(0x44000000, 0x444b7b25) reportEvent(0x04000000, 0x444b7c8e) reportEvent(0x00000000, 0x444b82ef) reportEvent(0x20000000, 0x444b8309) reportEvent(0x60000000, 0x444b84fb) reportEvent(0x40000000, 0x444b8501) reportEvent(0x44000000, 0x444b8518) reportEvent(0x04000000, 0x444b86f4) reportEvent(0x64000000, 0x444b88ed) reportEvent(0x04000000, 0x444b8ae6) reportEvent(0x24000000, 0x444b8aec) reportEvent(0x44000000, 0x444b8cdf) reportEvent(0x00000000, 0x00000000) reportEvent(0x40000000, 0x444b8d05) reportEvent(0x00000000, 0x444b8ed8) reportEvent(0x20000000, 0x444b8ede) reportEvent(0x40000000, 0x444b90d1) reportEvent(0x44000000, 0x444b90ee) reportEvent(0x24000000, 0x444b92ce) reportEvent(0x64000000, 0x444b94c2) reportEvent(0x44000000, 0x444b94c8) reportEvent(0x40000000, 0x444b94e9) reportEvent(0x00000000, 0x444b96bb) reportEvent(0x20000000, 0x444b96c1) reportEvent(0x60000000, 0x444b98b4) reportEvent(0x40000000, 0x444b98ba) reportEvent(0x00000000, 0x444b9aad) reportEvent(0x60000000, 0x444b9ca6) reportEvent(0x44000000, 0x444b9cc3) reportEvent(0x04000000, 0x444b9e9f) reportEvent(0x24000000, 0x444b9ea5) reportEvent(0x44000000, 0x444ba098) reportEvent(0x48000000, 0x444ba122) reportEvent(0x08000000, 0x444ba291) reportEvent(0x28000000, 0x444ba297) reportEvent(0x48000000, 0x444ba48a) reportEvent(0x40000000, 0x444ba513) reportEvent(0x44000000, 0x444ba519) reportEvent(0x04000000, 0x444bace4) reportEvent(0x20000000, 0x444bad01) reportEvent(0x40000000, 0x444baef0) reportEvent(0x44000000, 0x444baf0d) reportEvent(0x04000000, 0x444bb0e9) reportEvent(0x24000000, 0x444bb0ef) reportEvent(0x44000000, 0x444bb2e2) reportEvent(0x24000000, 0x444bb4df) reportEvent(0x64000000, 0x444bb6d3) reportEvent(0x44000000, 0x444bb6d9) reportEvent(0x40000000, 0x444bb6fa) reportEvent(0x00000000, 0x444bb8cc) reportEvent(0x20000000, 0x444bb8d2) reportEvent(0x60000000, 0x444bbac5) reportEvent(0x40000000, 0x444bbacb) reportEvent(0x00000000, 0x444bbcbe) reportEvent(0x60000000, 0x444bbeb7) reportEvent(0x00000000, 0x444bc0b0) reportEvent(0x20000000, 0x444bc0b6) reportEvent(0x40000000, 0x444bc2a9) reportEvent(0x44000000, 0x444bc2c6) reportEvent(0x04000000, 0x444bc4a2) reportEvent(0x24000000, 0x444bc4a8) reportEvent(0x44000000, 0x444bc69b) reportEvent(0x24000000, 0x444bc898) reportEvent(0x64000000, 0x444bca8c) reportEvent(0x44000000, 0x444bca92) reportEvent(0x4c000000, 0x444bcb16) reportEvent(0x48000000, 0x444bcb1c) reportEvent(0x08000000, 0x444bcc85) reportEvent(0x28000000, 0x444bcc8b) reportEvent(0x68000000, 0x444bce7e) reportEvent(0x48000000, 0x444bce84) reportEvent(0x40000000, 0x444bcf08) reportEvent(0x44000000, 0x444bcf0e) reportEvent(0x04000000, 0x444bd077) reportEvent(0x00000000, 0x00000000) reportEvent(0x00000000, 0x00000000) reportEvent(0x60000000, 0x444bd8e4) reportEvent(0x40000000, 0x444bd8ea) reportEvent(0x04000000, 0x444bdadd) reportEvent(0x24000000, 0x444bdae3) reportEvent(0x64000000, 0x444bdcd6) reportEvent(0x44000000, 0x444bdcdc) reportEvent(0x04000000, 0x444bdecf) reportEvent(0x64000000, 0x444be0c8) reportEvent(0x44000000, 0x444be0eb) reportEvent(0x00000000, 0x444be2c1) reportEvent(0x20000000, 0x444be2c7) reportEvent(0x40000000, 0x444be4ba) reportEvent(0x00000000, 0x444be6b3) reportEvent(0x20000000, 0x444be6b9) reportEvent(0x40000000, 0x444be8ac) reportEvent(0x44000000, 0x444be8c9) reportEvent(0x24000000, 0x444beaa9) reportEvent(0x64000000, 0x444bec9d) reportEvent(0x44000000, 0x444beca3) reportEvent(0x40000000, 0x444becc4) reportEvent(0x00000000, 0x444bee96) reportEvent(0x20000000, 0x444bee9c) reportEvent(0x60000000, 0x444bf08f) reportEvent(0x40000000, 0x444bf095) reportEvent(0x44000000, 0x444bf0ac) reportEvent(0x04000000, 0x444bf288) reportEvent(0x64000000, 0x444bf481) reportEvent(0x48000000, 0x444bf50b) reportEvent(0x08000000, 0x444bf67a) reportEvent(0x28000000, 0x444bf680) reportEvent(0x48000000, 0x444bf873) reportEvent(0x44000000, 0x444bf901) reportEvent(0x04000000, 0x444bfa6c) reportEvent(0x28000000, 0x444c00c9) reportEvent(0x00000000, 0x444c00cf) reportEvent(0x20000000, 0x444c00e5) reportEvent(0x60000000, 0x444c02d9) reportEvent(0x44000000, 0x444c02f6) reportEvent(0x04000000, 0x444c04d2) reportEvent(0x24000000, 0x444c04d8) reportEvent(0x44000000, 0x444c06cb) reportEvent(0x04000000, 0x444c08c4) reportEvent(0x24000000, 0x444c08ca) reportEvent(0x44000000, 0x444c0abd) reportEvent(0x24000000, 0x444c0cba) reportEvent(0x64000000, 0x444c0eae) reportEvent(0x44000000, 0x444c0eb4) reportEvent(0x4c000000, 0x44465fb0) reportEvent(0x00000000, 0x444c10a7) reportEvent(0x20000000, 0x444c10ad) reportEvent(0x60000000, 0x444c12a0) reportEvent(0x40000000, 0x444c12a6) reportEvent(0x00000000, 0x444c1499) reportEvent(0x60000000, 0x444c1692) reportEvent(0x44000000, 0x444c16af) reportEvent(0x04000000, 0x444c188b) reportEvent(0x24000000, 0x444c1891) reportEvent(0x44000000, 0x444c1a84) reportEvent(0x04000000, 0x444c1c7d) reportEvent(0x24000000, 0x444c1c83) reportEvent(0x44000000, 0x444c1e76) reportEvent(0x4c000000, 0x444c1eff) reportEvent(0x48000000, 0x444c1f05) reportEvent(0x28000000, 0x444c2073) reportEvent(0x68000000, 0x444c2267) reportEvent(0x48000000, 0x444c226d) reportEvent(0x40000000, 0x444c22f1) reportEvent(0x04000000, 0x444c2460) reportEvent(0x24000000, 0x444c2ad7) reportEvent(0x44000000, 0x444c2cce) reportEvent(0x24000000, 0x444c2ecb) reportEvent(0x64000000, 0x444c30bf) reportEvent(0x44000000, 0x444c30c5) reportEvent(0x40000000, 0x444c30e3) reportEvent(0x40000000, 0x444c30e9) reportEvent(0x00000000, 0x444c32b8) reportEvent(0x20000000, 0x444c32be) reportEvent(0x60000000, 0x444c34b1) reportEvent(0x40000000, 0x444c34b7) reportEvent(0x00000000, 0x444c36aa) reportEvent(0x60000000, 0x444c38a3) reportEvent(0x44000000, 0x444c38c0) reportEvent(0x04000000, 0x444c3a9c) reportEvent(0x24000000, 0x444c3aa2) reportEvent(0x44000000, 0x444c3c95) reportEvent(0x44000000, 0x444c3cba) reportEvent(0x00000000, 0x444c3e8e) reportEvent(0x20000000, 0x444c3e94) reportEvent(0x40000000, 0x444c4087) reportEvent(0x44000000, 0x444c40a4) reportEvent(0x24000000, 0x444c4284) reportEvent(0x64000000, 0x444c4478) reportEvent(0x44000000, 0x444c447e) reportEvent(0x04000000, 0x444c4671) reportEvent(0x24000000, 0x444c4677) reportEvent(0x64000000, 0x444c486a) reportEvent(0x44000000, 0x444c4870) reportEvent(0x4c000000, 0x444c48f4) reportEvent(0x08000000, 0x444c4a63) reportEvent(0x68000000, 0x444c4c5c) reportEvent(0x40000000, 0x444c4ce6) reportEvent(0x44000000, 0x444c4cec) reportEvent(0x04000000, 0x444c4e55) reportEvent(0x04000000, 0x444c54b4) reportEvent(0x20000000, 0x444c54d1) reportEvent(0x60000000, 0x444c56c2) reportEvent(0x40000000, 0x444c56c8) reportEvent(0x44000000, 0x444c56df) reportEvent(0x04000000, 0x444c58bb) reportEvent(0x64000000, 0x444c5ab4) reportEvent(0x00000000, 0x444c5cad) reportEvent(0x20000000, 0x444c5cb3) reportEvent(0x40000000, 0x444c5ea6) reportEvent(0x00000000, 0x444c609f) reportEvent(0x20000000, 0x444c60a5) reportEvent(0x40000000, 0x444c6298) reportEvent(0x20000000, 0x444c6495) reportEvent(0x60000000, 0x444c6689) reportEvent(0x40000000, 0x444c668f) reportEvent(0x44000000, 0x444c66a7) reportEvent(0x04000000, 0x444c6882) reportEvent(0x24000000, 0x444c6888) reportEvent(0x64000000, 0x444c6a7b) reportEvent(0x44000000, 0x444c6a81) reportEvent(0x04000000, 0x444c6c74) reportEvent(0x64000000, 0x444c6e6d) reportEvent(0x00000000, 0x444775f5) reportEvent(0x00000000, 0x444c7066) reportEvent(0x20000000, 0x444c706c) reportEvent(0x40000000, 0x444c725f) reportEvent(0x44000000, 0x444c727c) reportEvent(0x48000000, 0x444c72e9) reportEvent(0x08000000, 0x444c7458) reportEvent(0x28000000, 0x444c745e) reportEvent(0x48000000, 0x444c7651) reportEvent(0x40000000, 0x444c76da) reportEvent(0x44000000, 0x444c76e0) reportEvent(0x00000000, 0x444c7ea6) reportEvent(0x00000000, 0x444c7eac) reportEvent(0x20000000, 0x444c7ec3) reportEvent(0x40000000, 0x444c80b7) reportEvent(0x44000000, 0x444c80d4) reportEvent(0x04000000, 0x444c82b0) reportEvent(0x24000000, 0x444c82b6) reportEvent(0x44000000, 0x444c84a9) reportEvent(0x44000000, 0x444c84cc) reportEvent(0x20000000, 0x444c86a6) reportEvent(0x60000000, 0x444c889a) reportEvent(0x40000000, 0x444c88a0) reportEvent(0x00000000, 0x444c8a93) reportEvent(0x20000000, 0x444c8a99) reportEvent(0x60000000, 0x444c8c8c) reportEvent(0x40000000, 0x444c8c92) reportEvent(0x04000000, 0x444c8e85) reportEvent(0x64000000, 0x444c907e) reportEvent(0x04000000, 0x444c9277) reportEvent(0x24000000, 0x444c927d) reportEvent(0x44000000, 0x444c9470) reportEvent(0x40000000, 0x444c9493) reportEvent(0x40000000, 0x444c9499) reportEvent(0x00000000, 0x444c9669) reportEvent(0x20000000, 0x444c966f) reportEvent(0x40000000, 0x444c9862) reportEvent(0x44000000, 0x444c987f) reportEvent(0x24000000, 0x444c9a5f) reportEvent(0x64000000, 0x444c9c53) reportEvent(0x44000000, 0x444c9c59) reportEvent(0x4c000000, 0x444c9cdd) reportEvent(0x48000000, 0x444c9ce3) reportEvent(0x08000000, 0x444c9e4c) reportEvent(0x28000000, 0x444c9e52) reportEvent(0x68000000, 0x444ca045) reportEvent(0x48000000, 0x444ca04b) reportEvent(0x40000000, 0x444ca0cf) reportEvent(0x44000000, 0x444ca0d5) reportEvent(0x04000000, 0x444ca23e) reportEvent(0x04000000, 0x444ca898) reportEvent(0x20000000, 0x444ca8b5) reportEvent(0x60000000, 0x444caaab) reportEvent(0x40000000, 0x444caab1) reportEvent(0x04000000, 0x444caca4) reportEvent(0x24000000, 0x444cacaa) reportEvent(0x64000000, 0x444cae9d) reportEvent(0x44000000, 0x444caea3) reportEvent(0x00000000, 0x444cb096) reportEvent(0x60000000, 0x444cb28f) reportEvent(0x00000000, 0x444cb488) reportEvent(0x20000000, 0x444cb48e) reportEvent(0x40000000, 0x444cb681) reportEvent(0x00000000, 0x444cb87a) reportEvent(0x20000000, 0x444cb880) reportEvent(0x40000000, 0x444cba73) reportEvent(0x20000000, 0x444cbc70) reportEvent(0x60000000, 0x444cbe64) reportEvent(0x40000000, 0x444cbe6a) reportEvent(0x44000000, 0x444cbe82) reportEvent(0x04000000, 0x444cc05d) reportEvent(0x24000000, 0x444cc063) reportEvent(0x64000000, 0x444cc256) reportEvent(0x44000000, 0x444cc25c) reportEvent(0x04000000, 0x444cc44f) reportEvent(0x64000000, 0x444cc648) reportEvent(0x04000000, 0x444cc841) reportEvent(0x24000000, 0x444cc847) reportEvent(0x44000000, 0x444cca3a) reportEvent(0x48000000, 0x444ccac4) reportEvent(0x08000000, 0x444ccc33) reportEvent(0x28000000, 0x444ccc39) reportEvent(0x20000000, 0x444cceb5) reportEvent(0x24000000, 0x444ccebb) reportEvent(0x2c000000, 0x444d8621) reportEvent(0x28000000, 0x444d8627) reportEvent(0x68000000, 0x444d8790) reportEvent(0x48000000, 0x444d8796) reportEvent(0x40000000, 0x444d8a13) reportEvent(0x44000000, 0x444d8a19) reportEvent(0x04000000, 0x444d8b82) reportEvent(0x44000000, 0x444d8d7b) reportEvent(0x48000000, 0x444d8e05) reportEvent(0x08000000, 0x444d8f74) reportEvent(0x28000000, 0x444d8f7a) reportEvent(0x48000000, 0x444d916d) reportEvent(0x44000000, 0x444d91fb) reportEvent(0x24000000, 0x444d936a) reportEvent(0x44000000, 0x444d955f) reportEvent(0x4c000000, 0x444d95e8) reportEvent(0x48000000, 0x444d95ee) reportEvent(0x28000000, 0x444d975d) reportEvent(0x68000000, 0x444d9950) reportEvent(0x48000000, 0x444d9956) reportEvent(0x08000000, 0x444d9b49) reportEvent(0x68000000, 0x444d9d42) reportEvent(0x48000000, 0x444d9d48) reportEvent(0x08000000, 0x444d9f3b) reportEvent(0x48000000, 0x444da134) reportEvent(0x08000000, 0x444da32d) reportEvent(0x28000000, 0x444da333) reportEvent(0x48000000, 0x444da526) reportEvent(0x08000000, 0x444da71f) reportEvent(0x28000000, 0x444da725) reportEvent(0x48000000, 0x444da918) reportEvent(0x40000000, 0x444da9a1) reportEvent(0x20000000, 0x444dab16) reportEvent(0x60000000, 0x444dad09) reportEvent(0x40000000, 0x444dad0f) reportEvent(0x4c000000, 0x444dad93) reportEvent(0x48000000, 0x444dad99) reportEvent(0x08000000, 0x444daf02) reportEvent(0x68000000, 0x444db0fb) reportEvent(0x48000000, 0x444db101) reportEvent(0x08000000, 0x444db2f4) reportEvent(0x48000000, 0x444db4ed) reportEvent(0x08000000, 0x444db6e6) reportEvent(0x28000000, 0x444db6ec) reportEvent(0x48000000, 0x444db8df) reportEvent(0x44000000, 0x444db96d) reportEvent(0x24000000, 0x444dbadc) reportEvent(0x44000000, 0x444dbcd1) reportEvent(0x4c000000, 0x444dbd5a) reportEvent(0x48000000, 0x444dbd60) reportEvent(0x28000000, 0x444dbecf) reportEvent(0x68000000, 0x444dc0c2) reportEvent(0x48000000, 0x444dc0c8) reportEvent(0x08000000, 0x444dc2bb) reportEvent(0x68000000, 0x444dc4b4) reportEvent(0x48000000, 0x444dc4ba) reportEvent(0x08000000, 0x444dc6ad) reportEvent(0x48000000, 0x444dc8a6) reportEvent(0x08000000, 0x444dca9f) reportEvent(0x28000000, 0x444dcaa5) reportEvent(0x48000000, 0x444dcc98) reportEvent(0x00000000, 0x444dce91) reportEvent(0x20000000, 0x444dce97) reportEvent(0x40000000, 0x444dd08a) reportEvent(0x44000000, 0x444dd0a7) reportEvent(0x4c000000, 0x444dd113) reportEvent(0x48000000, 0x444dd119) reportEvent(0x28000000, 0x444dd288) reportEvent(0x20000000, 0x444dd505) reportEvent(0x2c000000, 0x444e5d1b) reportEvent(0x28000000, 0x444e5d21) reportEvent(0x68000000, 0x444e5e8a) reportEvent(0x48000000, 0x444e5e90) reportEvent(0x40000000, 0x444e610d) reportEvent(0x44000000, 0x444e6113) reportEvent(0x04000000, 0x444e627c) reportEvent(0x64000000, 0x444e6475) reportEvent(0x48000000, 0x444e64ff) reportEvent(0x08000000, 0x444e666e) reportEvent(0x28000000, 0x444e6674) reportEvent(0x48000000, 0x444e6867) reportEvent(0x44000000, 0x444e68f5) reportEvent(0x04000000, 0x444e6a60) reportEvent(0x24000000, 0x444e6a66) reportEvent(0x44000000, 0x444e6c59) reportEvent(0x4c000000, 0x444e6ce2) reportEvent(0x48000000, 0x444e6ce8) reportEvent(0x28000000, 0x444e6e56) reportEvent(0x68000000, 0x444e704a) reportEvent(0x48000000, 0x444e7050) reportEvent(0x08000000, 0x444e7243) reportEvent(0x28000000, 0x444e7249) reportEvent(0x68000000, 0x444e743c) reportEvent(0x48000000, 0x444e7442) reportEvent(0x08000000, 0x444e7635) reportEvent(0x68000000, 0x444e782e) reportEvent(0x08000000, 0x444e7a27) reportEvent(0x28000000, 0x444e7a2d) reportEvent(0x48000000, 0x444e7c20) reportEvent(0x44000000, 0x444e7cae) reportEvent(0x04000000, 0x444e7e19) reportEvent(0x24000000, 0x444e7e1f) reportEvent(0x44000000, 0x444e8012) reportEvent(0x44000000, 0x444e8035) reportEvent(0x20000000, 0x444e820f) reportEvent(0x60000000, 0x444e8403) reportEvent(0x40000000, 0x444e8409) reportEvent(0x00000000, 0x444e85fc) reportEvent(0x20000000, 0x444e8ca3) reportEvent(0x40000000, 0x444e8e98) reportEvent(0x24000000, 0x444e9096) reportEvent(0x64000000, 0x444e9289) reportEvent(0x44000000, 0x444e928f) reportEvent(0x04000000, 0x444e9482) reportEvent(0x24000000, 0x444e9488) reportEvent(0x64000000, 0x444e967b) reportEvent(0x44000000, 0x444e9681) reportEvent(0x44000000, 0x444e969f) reportEvent(0x00000000, 0x444e9874) reportEvent(0x40000000, 0x444e9a6d) reportEvent(0x44000000, 0x444e9a8a) reportEvent(0x04000000, 0x444e9c66) reportEvent(0x24000000, 0x444e9c6c) reportEvent(0x44000000, 0x444e9e5f) reportEvent(0x04000000, 0x444ea058) reportEvent(0x24000000, 0x444ea05e) reportEvent(0x44000000, 0x444ea251) reportEvent(0x04000000, 0x444ea449) reportEvent(0x24000000, 0x444ea44f) reportEvent(0x64000000, 0x444ea642) reportEvent(0x44000000, 0x444ea648) reportEvent(0x24000000, 0x444ea666) reportEvent(0x40000000, 0x444ea66c) reportEvent(0x00000000, 0x444ea83b) reportEvent(0x60000000, 0x444eaa34) reportEvent(0x40000000, 0x444eaa3a) reportEvent(0x44000000, 0x444eaa51) reportEvent(0x48000000, 0x444eaabe) reportEvent(0x08000000, 0x444eac2d) reportEvent(0x48000000, 0x444eae26) reportEvent(0x40000000, 0x444eaeb0) reportEvent(0x44000000, 0x444eaeb6) reportEvent(0x04000000, 0x444eb01f) reportEvent(0x04000000, 0x444eb680) reportEvent(0x60000000, 0x444eb88c) reportEvent(0x40000000, 0x444eb892) reportEvent(0x44000000, 0x444eb8a9) reportEvent(0x04000000, 0x444eba85) reportEvent(0x44000000, 0x444ebc7e) reportEvent(0x04000000, 0x444ebe77) reportEvent(0x24000000, 0x444ebe7d) reportEvent(0x44000000, 0x444ec070) reportEvent(0x40000000, 0x444ec099) reportEvent(0x00000000, 0x444ec269) reportEvent(0x20000000, 0x444ec26f) reportEvent(0x40000000, 0x444ec462) reportEvent(0x20000000, 0x444ec660) reportEvent(0x60000000, 0x444ec853) reportEvent(0x40000000, 0x444ec859) reportEvent(0x00000000, 0x444eca4c) reportEvent(0x60000000, 0x444ecc45) reportEvent(0x40000000, 0x444ecc4b) reportEvent(0x00000000, 0x444ece3e) reportEvent(0x40000000, 0x444ed037) reportEvent(0x44000000, 0x444ed054) reportEvent(0x04000000, 0x444ed230) reportEvent(0x24000000, 0x444ed236) reportEvent(0x44000000, 0x444ed429) reportEvent(0x4c000000, 0x444ed4b2) reportEvent(0x48000000, 0x444ed4b8) reportEvent(0x28000000, 0x444ed626) reportEvent(0x48000000, 0x444ed81b) reportEvent(0x40000000, 0x444ed8a4) reportEvent(0x04000000, 0x444ee071) reportEvent(0x20000000, 0x444ee08c) reportEvent(0x40000000, 0x444ee281) reportEvent(0x44000000, 0x444ee29e) reportEvent(0x04000000, 0x444ee47a) reportEvent(0x24000000, 0x444ee480) reportEvent(0x44000000, 0x444ee673) reportEvent(0x24000000, 0x444ee871) reportEvent(0x64000000, 0x444eea64) reportEvent(0x44000000, 0x444eea6a) reportEvent(0x00000000, 0x4448dd44) reportEvent(0x44000000, 0x444eea89) reportEvent(0x40000000, 0x444eea8f) reportEvent(0x00000000, 0x444eec5d) reportEvent(0x60000000, 0x444eee56) reportEvent(0x40000000, 0x444eee5c) reportEvent(0x44000000, 0x444eee73) reportEvent(0x04000000, 0x444ef04f) reportEvent(0x44000000, 0x444ef248) reportEvent(0x04000000, 0x444ef441) reportEvent(0x24000000, 0x444ef447) reportEvent(0x44000000, 0x444ef63a) reportEvent(0x40000000, 0x444ef663) reportEvent(0x00000000, 0x444ef833) reportEvent(0x20000000, 0x444ef839) reportEvent(0x40000000, 0x444efa2c) reportEvent(0x20000000, 0x444efc2a) reportEvent(0x60000000, 0x444efe1d) reportEvent(0x40000000, 0x444efe23) reportEvent(0x4c000000, 0x444efea7) reportEvent(0x48000000, 0x444efead) reportEvent(0x08000000, 0x444f0016) reportEvent(0x68000000, 0x444f020f) reportEvent(0x48000000, 0x444f0215) reportEvent(0x40000000, 0x444f0299) reportEvent(0x44000000, 0x444f029f) reportEvent(0x04000000, 0x444f0408) reportEvent(0x04000000, 0x444f0a68) reportEvent(0x60000000, 0x444f0c75) reportEvent(0x40000000, 0x444f0c7b) reportEvent(0x04000000, 0x444f0e6e) reportEvent(0x64000000, 0x444f1067) reportEvent(0x44000000, 0x444f106d) reportEvent(0x04000000, 0x444f1260) reportEvent(0x44000000, 0x444f1459) reportEvent(0x40000000, 0x44490fac) reportEvent(0x00000000, 0x444f1652) reportEvent(0x20000000, 0x444f1658) reportEvent(0x40000000, 0x444f184b) reportEvent(0x44000000, 0x444f1868) reportEvent(0x04000000, 0x444f1a44) reportEvent(0x24000000, 0x444f1a4a) reportEvent(0x44000000, 0x444f1c3d) reportEvent(0x24000000, 0x444f1e3b) reportEvent(0x64000000, 0x444f202e) reportEvent(0x44000000, 0x444f2034) reportEvent(0x04000000, 0x444f2227) reportEvent(0x64000000, 0x444f2420) reportEvent(0x44000000, 0x444f2426) reportEvent(0x04000000, 0x444f2619) reportEvent(0x44000000, 0x444f2812) reportEvent(0x48000000, 0x444f289c) reportEvent(0x08000000, 0x444f2a0b) reportEvent(0x28000000, 0x444f2a11) reportEvent(0x48000000, 0x444f2c04) reportEvent(0x44000000, 0x444f2c92) reportEvent(0x04000000, 0x444f2dfd) reportEvent(0x04000000, 0x444f3458) reportEvent(0x40000000, 0x444f366a) reportEvent(0x44000000, 0x444f3687) reportEvent(0x04000000, 0x444f3863) reportEvent(0x24000000, 0x444f3869) reportEvent(0x44000000, 0x444f3a5c) reportEvent(0x24000000, 0x444f3c59) reportEvent(0x44000000, 0x444f3e4e) reportEvent(0x44000000, 0x444f3e71) reportEvent(0x20000000, 0x444f404c) reportEvent(0x60000000, 0x444f423f) reportEvent(0x40000000, 0x444f4245) reportEvent(0x00000000, 0x444f4438) reportEvent(0x60000000, 0x444f4631) reportEvent(0x40000000, 0x444f4637) reportEvent(0x44000000, 0x444f464e) reportEvent(0x04000000, 0x444f482a) reportEvent(0x44000000, 0x444f4a23) reportEvent(0x04000000, 0x444f4c1c) reportEvent(0x24000000, 0x444f4c22) reportEvent(0x44000000, 0x444f4e15) reportEvent(0x04000000, 0x444f500e) reportEvent(0x24000000, 0x444f5014) reportEvent(0x44000000, 0x444f5207) reportEvent(0x4c000000, 0x444f5290) reportEvent(0x48000000, 0x444f5296) reportEvent(0x28000000, 0x444f5405) reportEvent(0x68000000, 0x444f55f8) reportEvent(0x48000000, 0x444f55fe) reportEvent(0x40000000, 0x444f5682) reportEvent(0x04000000, 0x444f57f1) reportEvent(0x04000000, 0x444f5e50) reportEvent(0x20000000, 0x444f5e6d) reportEvent(0x40000000, 0x444f605f) reportEvent(0x20000000, 0x444f625d) reportEvent(0x60000000, 0x444f6450) reportEvent(0x40000000, 0x444f6456) reportEvent(0x04000000, 0x444f6649) reportEvent(0x64000000, 0x444f6842) reportEvent(0x44000000, 0x444f6848) reportEvent(0x44000000, 0x444f6866) reportEvent(0x00000000, 0x444f6a3b) reportEvent(0x40000000, 0x444f6c34) reportEvent(0x00000000, 0x444f6e2d) reportEvent(0x20000000, 0x444f6e33) reportEvent(0x40000000, 0x444f7026) reportEvent(0x20000000, 0x444f7223) reportEvent(0x40000000, 0x444f7418) reportEvent(0x20000000, 0x444f7616) reportEvent(0x60000000, 0x444f7809) reportEvent(0x40000000, 0x444f780f) reportEvent(0x00000000, 0x444f7a02) reportEvent(0x60000000, 0x444f7bfb) reportEvent(0x40000000, 0x444f7c01) reportEvent(0x44000000, 0x444f7c18) reportEvent(0x48000000, 0x444f7c85) reportEvent(0x08000000, 0x444f7df4) reportEvent(0x48000000, 0x444f7fed) reportEvent(0x40000000, 0x444f8077) reportEvent(0x00000000, 0x444f81e6) reportEvent(0x20000000, 0x444f885d) reportEvent(0x60000000, 0x444f8a53) reportEvent(0x40000000, 0x444f8a59) reportEvent(0x44000000, 0x444f8a70) reportEvent(0x04000000, 0x444f8c4c) reportEvent(0x44000000, 0x444f8e45) reportEvent(0x44000000, 0x444f8e6a) reportEvent(0x00000000, 0x444f903e) reportEvent(0x20000000, 0x444f9044) reportEvent(0x40000000, 0x444f9237) reportEvent(0x00000000, 0x444f9430) reportEvent(0x20000000, 0x444f9436) reportEvent(0x40000000, 0x444f9629) reportEvent(0x20000000, 0x444f9827) reportEvent(0x60000000, 0x444f9a1a) reportEvent(0x40000000, 0x444f9a20) reportEvent(0x44000000, 0x444f9a37) reportEvent(0x04000000, 0x444f9c13) reportEvent(0x64000000, 0x444f9e0c) reportEvent(0x44000000, 0x444f9e12) reportEvent(0x44000000, 0x444f9e30) reportEvent(0x00000000, 0x444fa005) reportEvent(0x40000000, 0x444fa1fe) reportEvent(0x00000000, 0x444fa3f7) reportEvent(0x20000000, 0x444fa3fd) reportEvent(0x40000000, 0x444fa5f0) reportEvent(0x44000000, 0x444fa60d) reportEvent(0x4c000000, 0x444fa679) reportEvent(0x48000000, 0x444fa67f) reportEvent(0x28000000, 0x444fa7ed) reportEvent(0x48000000, 0x444fa9e2) reportEvent(0x40000000, 0x444faa6b) reportEvent(0x04000000, 0x444fb23c) reportEvent(0x20000000, 0x444fb257) reportEvent(0x40000000, 0x444fb448) reportEvent(0x44000000, 0x444fb465) reportEvent(0x04000000, 0x444fb641) reportEvent(0x24000000, 0x444fb647) reportEvent(0x44000000, 0x444fb83a) reportEvent(0x24000000, 0x444fba38) reportEvent(0x64000000, 0x444fbc2b) reportEvent(0x44000000, 0x444fbc31) reportEvent(0x44000000, 0x444fbc51) reportEvent(0x00000000, 0x444fbe24) reportEvent(0x60000000, 0x444fc01d) reportEvent(0x40000000, 0x444fc023) reportEvent(0x00000000, 0x444fc216) reportEvent(0x40000000, 0x444fc40f) reportEvent(0x44000000, 0x444fc42c) reportEvent(0x04000000, 0x444fc608) reportEvent(0x24000000, 0x444fc60e) reportEvent(0x44000000, 0x444fc801) reportEvent(0x40000000, 0x444fc82a) reportEvent(0x20000000, 0x444fc9fe) reportEvent(0x40000000, 0x444fcbf3) reportEvent(0x24000000, 0x444fcdf1) reportEvent(0x64000000, 0x444fcfe4) reportEvent(0x44000000, 0x444fcfea) reportEvent(0x4c000000, 0x444fd06e) reportEvent(0x48000000, 0x444fd074) reportEvent(0x08000000, 0x444fd1dd) reportEvent(0x68000000, 0x444fd3d6) reportEvent(0x48000000, 0x444fd3dc) reportEvent(0x40000000, 0x444fd460) reportEvent(0x44000000, 0x444fd466) reportEvent(0x04000000, 0x444fd5cf) reportEvent(0x04000000, 0x444fdc2d) reportEvent(0x20000000, 0x444fdc48) reportEvent(0x60000000, 0x444fde3c) reportEvent(0x40000000, 0x444fde42) reportEvent(0x04000000, 0x444fe035) reportEvent(0x64000000, 0x444fe22e) reportEvent(0x44000000, 0x444fe234) reportEvent(0x04000000, 0x444fe427) reportEvent(0x44000000, 0x444fe620) reportEvent(0x04000000, 0x444fe819) reportEvent(0x24000000, 0x444fe81f) reportEvent(0x44000000, 0x444fea12) reportEvent(0x40000000, 0x4449cf4a) reportEvent(0x40000000, 0x444fea38) reportEvent(0x20000000, 0x444fec0f) reportEvent(0x40000000, 0x444fee04) reportEvent(0x44000000, 0x444fee21) reportEvent(0x24000000, 0x444ff002) reportEvent(0x64000000, 0x444ff1f5) reportEvent(0x44000000, 0x444ff1fb) reportEvent(0x04000000, 0x444ff3ee) reportEvent(0x64000000, 0x444ff5e7) reportEvent(0x44000000, 0x444ff5ed) reportEvent(0x04000000, 0x4449d900) reportEvent(0x44000000, 0x444ff60c) reportEvent(0x40000000, 0x444ff612) reportEvent(0x00000000, 0x444ff7e0) reportEvent(0x40000000, 0x444ff9d9) reportEvent(0x44000000, 0x444ff9f6) reportEvent(0x48000000, 0x444ffa63) reportEvent(0x08000000, 0x444ffbd2) reportEvent(0x28000000, 0x444ffbd8) reportEvent(0x48000000, 0x444ffdcb) reportEvent(0x44000000, 0x444ffe59) reportEvent(0x04000000, 0x444fffc4) reportEvent(0x04000000, 0x44500624) reportEvent(0x20000000, 0x44500641) reportEvent(0x40000000, 0x44500831) reportEvent(0x44000000, 0x4450084e) reportEvent(0x04000000, 0x44500a2a) reportEvent(0x24000000, 0x44500a30) reportEvent(0x44000000, 0x44500c23) reportEvent(0x24000000, 0x44500e20) reportEvent(0x44000000, 0x44501015) reportEvent(0x20000000, 0x4449f333) reportEvent(0x40000000, 0x4450103b) reportEvent(0x20000000, 0x44501213) reportEvent(0x60000000, 0x44501406) reportEvent(0x40000000, 0x4450140c) reportEvent(0x44000000, 0x44501423) reportEvent(0x04000000, 0x445015ff) reportEvent(0x64000000, 0x445017f8) reportEvent(0x44000000, 0x445017fe) reportEvent(0x44000000, 0x4450181c) reportEvent(0x00000000, 0x445019f1) reportEvent(0x40000000, 0x44501bea) reportEvent(0x00000000, 0x44501de3) reportEvent(0x20000000, 0x44501de9) reportEvent(0x40000000, 0x44501fdc) reportEvent(0x44000000, 0x44501ff9) reportEvent(0x24000000, 0x445021d9) reportEvent(0x44000000, 0x445023ce) reportEvent(0x4c000000, 0x44502457) reportEvent(0x48000000, 0x4450245d) reportEvent(0x28000000, 0x445025cc) reportEvent(0x68000000, 0x445027bf) reportEvent(0x48000000, 0x445027c5) reportEvent(0x40000000, 0x44502849) reportEvent(0x04000000, 0x445029b8) reportEvent(0x00000000, 0x00000000) reportEvent(0x40000000, 0x444a136c) reportEvent(0x40000000, 0x44503226) reportEvent(0x44000000, 0x44503243) reportEvent(0x24000000, 0x44503424) reportEvent(0x64000000, 0x44503617) reportEvent(0x44000000, 0x4450361d) reportEvent(0x04000000, 0x44503810) reportEvent(0x64000000, 0x44503a09) reportEvent(0x44000000, 0x44503a0f) reportEvent(0x44000000, 0x44503a2c) reportEvent(0x00000000, 0x44503c02) reportEvent(0x40000000, 0x44503dfb) reportEvent(0x00000000, 0x44503ff4) reportEvent(0x20000000, 0x44503ffa) reportEvent(0x40000000, 0x445041ed) reportEvent(0x00000000, 0x445043e6) reportEvent(0x20000000, 0x445043ec) reportEvent(0x40000000, 0x445045df) reportEvent(0x24000000, 0x445047dd) reportEvent(0x64000000, 0x445049d0) reportEvent(0x44000000, 0x445049d6) reportEvent(0x04000000, 0x44504bc9) reportEvent(0x64000000, 0x44504dc2) reportEvent(0x44000000, 0x44504dc8) reportEvent(0x48000000, 0x44504e4c) reportEvent(0x08000000, 0x44504fbb) reportEvent(0x48000000, 0x445051b4) reportEvent(0x40000000, 0x4450523e) reportEvent(0x44000000, 0x44505244) reportEvent(0x04000000, 0x445053ad) reportEvent(0x04000000, 0x44505a10) reportEvent(0x20000000, 0x44505a2b) reportEvent(0x60000000, 0x44505c1a) reportEvent(0x40000000, 0x44505c20) reportEvent(0x44000000, 0x44505c37) reportEvent(0x04000000, 0x44505e13) reportEvent(0x44000000, 0x4450600c) reportEvent(0x04000000, 0x44506205) reportEvent(0x24000000, 0x4450620b) reportEvent(0x44000000, 0x445063fe) reportEvent(0x44000000, 0x44506423) reportEvent(0x00000000, 0x445065f7) reportEvent(0x20000000, 0x445065fd) reportEvent(0x40000000, 0x445067f0) reportEvent(0x20000000, 0x445069ee) reportEvent(0x60000000, 0x44506be1) reportEvent(0x40000000, 0x44506be7) reportEvent(0x04000000, 0x44506dda) reportEvent(0x64000000, 0x44506fd3) reportEvent(0x44000000, 0x44506fd9) reportEvent(0x44000000, 0x44506ff8) reportEvent(0x00000000, 0x445071cc) reportEvent(0x40000000, 0x445073c5) reportEvent(0x44000000, 0x445073e2) reportEvent(0x04000000, 0x445075be) reportEvent(0x24000000, 0x445075c4) reportEvent(0x44000000, 0x445077b7) reportEvent(0x4c000000, 0x44507840) reportEvent(0x48000000, 0x44507846) reportEvent(0x28000000, 0x445079b4) reportEvent(0x48000000, 0x44507ba9) reportEvent(0x40000000, 0x44507c32) reportEvent(0x04000000, 0x445083ff) reportEvent(0x20000000, 0x4450841c) reportEvent(0x40000000, 0x4450860f) reportEvent(0x44000000, 0x4450862c) reportEvent(0x04000000, 0x44508808) reportEvent(0x24000000, 0x4450880e) reportEvent(0x44000000, 0x44508a01) reportEvent(0x24000000, 0x44508bff) reportEvent(0x64000000, 0x44508df2) reportEvent(0x44000000, 0x44508df8) reportEvent(0x04000000, 0x44508feb) reportEvent(0x64000000, 0x445091e4) reportEvent(0x44000000, 0x445091ea) reportEvent(0x00000000, 0x445093dd) reportEvent(0x40000000, 0x445095d6) reportEvent(0x00000000, 0x445097cf) reportEvent(0x20000000, 0x445097d5) reportEvent(0x40000000, 0x445099c8) reportEvent(0x44000000, 0x445099e5) reportEvent(0x04000000, 0x44509bc1) reportEvent(0x24000000, 0x44509bc7) reportEvent(0x44000000, 0x44509dba) reportEvent(0x24000000, 0x44509fb8) reportEvent(0x64000000, 0x4450a1ab) reportEvent(0x44000000, 0x4450a1b1) reportEvent(0x4c000000, 0x4450a235) reportEvent(0x48000000, 0x4450a23b) reportEvent(0x08000000, 0x4450a3a4) reportEvent(0x68000000, 0x4450a59d) reportEvent(0x48000000, 0x4450a5a3) reportEvent(0x40000000, 0x4450a627) reportEvent(0x44000000, 0x4450a62d) reportEvent(0x04000000, 0x4450a796) reportEvent(0x24000000, 0x4450ae0d) reportEvent(0x64000000, 0x4450b003) reportEvent(0x44000000, 0x4450b009) reportEvent(0x04000000, 0x4450b1fc) reportEvent(0x64000000, 0x4450b3f5) reportEvent(0x44000000, 0x4450b3fb) reportEvent(0x04000000, 0x4450b418) reportEvent(0x00000000, 0x4450b5ee) reportEvent(0x40000000, 0x4450b7e7) reportEvent(0x00000000, 0x4450b9e0) reportEvent(0x20000000, 0x4450b9e6) reportEvent(0x40000000, 0x4450bbd9) reportEvent(0x44000000, 0x4450bbf6) reportEvent(0x24000000, 0x4450bdd6) reportEvent(0x44000000, 0x4450bfcb) reportEvent(0x40000000, 0x4450bfef) reportEvent(0x20000000, 0x4450c1c9) reportEvent(0x60000000, 0x4450c3bc) reportEvent(0x40000000, 0x4450c3c2) reportEvent(0x04000000, 0x4450c5b5) reportEvent(0x64000000, 0x4450c7ae) reportEvent(0x44000000, 0x4450c7b4) reportEvent(0x04000000, 0x4450c9a7) reportEvent(0x44000000, 0x4450cba0) reportEvent(0x48000000, 0x4450cc2a) reportEvent(0x08000000, 0x4450cd99) reportEvent(0x28000000, 0x4450cd9f) reportEvent(0x48000000, 0x4450cf92) reportEvent(0x44000000, 0x4450d020) reportEvent(0x04000000, 0x4450d7ec) reportEvent(0x00000000, 0x4450d7f2) reportEvent(0x40000000, 0x4450d9f8) reportEvent(0x44000000, 0x4450da15) reportEvent(0x04000000, 0x4450dbf1) reportEvent(0x24000000, 0x4450dbf7) reportEvent(0x44000000, 0x4450ddea) reportEvent(0x44000000, 0x4450de0f) reportEvent(0x20000000, 0x4450dfe7) reportEvent(0x40000000, 0x4450e1dc) reportEvent(0x20000000, 0x4450e3da) reportEvent(0x60000000, 0x4450e5cd) reportEvent(0x40000000, 0x4450e5d3) reportEvent(0x00000000, 0x4450e7c6) reportEvent(0x60000000, 0x4450e9bf) reportEvent(0x40000000, 0x4450e9c5) reportEvent(0x44000000, 0x4450e9dc) reportEvent(0x04000000, 0x4450ebb8) reportEvent(0x44000000, 0x4450edb1) reportEvent(0x04000000, 0x4450efaa) reportEvent(0x24000000, 0x4450efb0) reportEvent(0x44000000, 0x4450f1a3) reportEvent(0x44000000, 0x4450f1c8) reportEvent(0x20000000, 0x4450f3a0) reportEvent(0x40000000, 0x4450f595) reportEvent(0x44000000, 0x4450f5b2) reportEvent(0x4c000000, 0x4450f61e) reportEvent(0x48000000, 0x4450f624) reportEvent(0x28000000, 0x4450f793) reportEvent(0x68000000, 0x4450f986) reportEvent(0x48000000, 0x4450f98c) reportEvent(0x40000000, 0x4450fa10) reportEvent(0x04000000, 0x4450fb7f) reportEvent(0x40000000, 0x445103ed) reportEvent(0x44000000, 0x4451040a) reportEvent(0x24000000, 0x445105eb) reportEvent(0x64000000, 0x445107de) reportEvent(0x44000000, 0x445107e4) reportEvent(0x40000000, 0x44510805) reportEvent(0x00000000, 0x445109d7) reportEvent(0x60000000, 0x44510bd0) reportEvent(0x40000000, 0x44510bd6) reportEvent(0x00000000, 0x44510dc9) reportEvent(0x40000000, 0x44510fc2) reportEvent(0x44000000, 0x44510fdf) reportEvent(0x04000000, 0x445111bb) reportEvent(0x24000000, 0x445111c1) reportEvent(0x44000000, 0x445113b4) reportEvent(0x04000000, 0x445115ad) reportEvent(0x24000000, 0x445115b3) reportEvent(0x44000000, 0x445117a6) reportEvent(0x44000000, 0x445117c9) reportEvent(0x20000000, 0x445119a4) reportEvent(0x60000000, 0x44511b97) reportEvent(0x40000000, 0x44511b9d) reportEvent(0x04000000, 0x44511d90) reportEvent(0x64000000, 0x44511f89) reportEvent(0x44000000, 0x44511f8f) reportEvent(0x48000000, 0x44512013) reportEvent(0x08000000, 0x44512182) reportEvent(0x48000000, 0x4451237b) reportEvent(0x40000000, 0x44512405) reportEvent(0x44000000, 0x4451240b) reportEvent(0x04000000, 0x44512574) reportEvent(0x40000000, 0x444af8cb) reportEvent(0x20000000, 0x44512bee) reportEvent(0x60000000, 0x44512de1) reportEvent(0x40000000, 0x44512de7) reportEvent(0x44000000, 0x44512dfe) reportEvent(0x04000000, 0x44512fda) reportEvent(0x44000000, 0x445131d3) reportEvent(0x40000000, 0x445131f9) reportEvent(0x00000000, 0x445133cc) reportEvent(0x20000000, 0x445133d2) reportEvent(0x40000000, 0x445135c5) reportEvent(0x00000000, 0x445137be) reportEvent(0x20000000, 0x445137c4) reportEvent(0x40000000, 0x445139b7) reportEvent(0x20000000, 0x44513bb5) reportEvent(0x60000000, 0x44513da8) reportEvent(0x40000000, 0x44513dae) reportEvent(0x00000000, 0x44513fa1) reportEvent(0x60000000, 0x4451419a) reportEvent(0x40000000, 0x445141a0) reportEvent(0x44000000, 0x445141b7) reportEvent(0x04000000, 0x44514393) reportEvent(0x44000000, 0x4451458c) reportEvent(0x04000000, 0x44514785) reportEvent(0x24000000, 0x4451478b) reportEvent(0x44000000, 0x4451497e) reportEvent(0x4c000000, 0x44514a07) reportEvent(0x48000000, 0x44514a0d) reportEvent(0x28000000, 0x44514b7b) reportEvent(0x48000000, 0x44514d70) reportEvent(0x40000000, 0x44514df9) reportEvent(0x04000000, 0x445155c4) reportEvent(0x20000000, 0x445155e1) reportEvent(0x40000000, 0x445157d6) reportEvent(0x20000000, 0x445159d3) reportEvent(0x40000000, 0x44515bc8) reportEvent(0x44000000, 0x44515be5) reportEvent(0x24000000, 0x44515dc6) reportEvent(0x64000000, 0x44515fb9) reportEvent(0x44000000, 0x44515fbf) reportEvent(0x28000000, 0x44515fde) reportEvent(0x00000000, 0x445161b2) reportEvent(0x60000000, 0x445163ab) reportEvent(0x40000000, 0x445163b1) reportEvent(0x00000000, 0x445165a4) reportEvent(0x40000000, 0x4451679d) reportEvent(0x00000000, 0x44516996) reportEvent(0x20000000, 0x4451699c) reportEvent(0x40000000, 0x44516b8f) reportEvent(0x20000000, 0x44516d8c) reportEvent(0x40000000, 0x44516f81) reportEvent(0x20000000, 0x4451717f) reportEvent(0x60000000, 0x44517372) reportEvent(0x40000000, 0x44517378) reportEvent(0x44000000, 0x4451738f) reportEvent(0x4c000000, 0x445173fc) reportEvent(0x48000000, 0x44517402) reportEvent(0x08000000, 0x4451756b) reportEvent(0x68000000, 0x44517764) reportEvent(0x48000000, 0x4451776a) reportEvent(0x40000000, 0x445177ee) reportEvent(0x00000000, 0x4451795d) reportEvent(0x20000000, 0x44517fd5) reportEvent(0x60000000, 0x445181ca) reportEvent(0x40000000, 0x445181d0) reportEvent(0x44000000, 0x445181e7) reportEvent(0x04000000, 0x445183c3) reportEvent(0x64000000, 0x445185bc) reportEvent(0x44000000, 0x445185c2) reportEvent(0x44000000, 0x445185df) reportEvent(0x00000000, 0x445187b5) reportEvent(0x40000000, 0x445189ae) reportEvent(0x00000000, 0x44518ba7) reportEvent(0x20000000, 0x44518bad) reportEvent(0x40000000, 0x44518da0) reportEvent(0x20000000, 0x44518f9d) reportEvent(0x40000000, 0x44519192) reportEvent(0x20000000, 0x44519390) reportEvent(0x60000000, 0x44519583) reportEvent(0x40000000, 0x44519589) reportEvent(0x04000000, 0x4451977c) reportEvent(0x64000000, 0x44519975) reportEvent(0x44000000, 0x4451997b) reportEvent(0x04000000, 0x44519b6e) reportEvent(0x44000000, 0x44519d67) reportEvent(0x48000000, 0x44519df1) reportEvent(0x08000000, 0x44519f60) reportEvent(0x28000000, 0x44519f66) reportEvent(0x48000000, 0x4451a159) reportEvent(0x44000000, 0x4451a1e7) reportEvent(0x04000000, 0x4451a352) reportEvent(0x04000000, 0x4451a9b4) reportEvent(0x40000000, 0x4451abbf) reportEvent(0x44000000, 0x4451abdc) reportEvent(0x04000000, 0x4451adb8) reportEvent(0x24000000, 0x4451adbe) reportEvent(0x44000000, 0x4451afb1) reportEvent(0x04000000, 0x4451b1aa) reportEvent(0x24000000, 0x4451b1b0) reportEvent(0x44000000, 0x4451b3a3) reportEvent(0x44000000, 0x4451b3c6) reportEvent(0x20000000, 0x4451b5a1) reportEvent(0x60000000, 0x4451b794) reportEvent(0x40000000, 0x4451b79a) reportEvent(0x04000000, 0x4451b98d) reportEvent(0x64000000, 0x4451bb86) reportEvent(0x44000000, 0x4451bb8c) reportEvent(0x04000000, 0x4451bd7f) reportEvent(0x44000000, 0x4451bf78) reportEvent(0x04000000, 0x4451c171) reportEvent(0x24000000, 0x4451c177) reportEvent(0x44000000, 0x4451c36a) reportEvent(0x24000000, 0x4451c567) reportEvent(0x44000000, 0x4451c75c) reportEvent(0x4c000000, 0x4451c7e5) reportEvent(0x48000000, 0x4451c7eb) reportEvent(0x28000000, 0x4451c95a) reportEvent(0x68000000, 0x4451cb4d) reportEvent(0x48000000, 0x4451cb53) reportEvent(0x40000000, 0x4451cbd7) reportEvent(0x04000000, 0x4451cd46) reportEvent(0x20000000, 0x4451d3c1) reportEvent(0x40000000, 0x4451d5b4) reportEvent(0x44000000, 0x4451d5d1) reportEvent(0x24000000, 0x4451d7b2) reportEvent(0x64000000, 0x4451d9a5) reportEvent(0x44000000, 0x4451d9ab) reportEvent(0x04000000, 0x4451db9e) reportEvent(0x64000000, 0x4451dd97) reportEvent(0x44000000, 0x4451dd9d) reportEvent(0x44000000, 0x4451ddbb) reportEvent(0x00000000, 0x4451df90) reportEvent(0x40000000, 0x4451e189) reportEvent(0x44000000, 0x4451e1a6) reportEvent(0x04000000, 0x4451e382) reportEvent(0x24000000, 0x4451e388) reportEvent(0x44000000, 0x4451e57b) reportEvent(0x24000000, 0x4451e778) reportEvent(0x44000000, 0x4451e96d) reportEvent(0x40000000, 0x444b98ba) reportEvent(0x20000000, 0x4451eb6b) reportEvent(0x60000000, 0x4451ed5e) reportEvent(0x40000000, 0x4451ed64) reportEvent(0x04000000, 0x4451ef57) reportEvent(0x64000000, 0x4451f150) reportEvent(0x44000000, 0x4451f156) reportEvent(0x48000000, 0x4451f1da) reportEvent(0x08000000, 0x4451f349) reportEvent(0x48000000, 0x4451f542) reportEvent(0x40000000, 0x4451f5cc) reportEvent(0x44000000, 0x4451f5d2) reportEvent(0x04000000, 0x4451f73b) reportEvent(0x04000000, 0x4451fd97) reportEvent(0x20000000, 0x4451fdb4) reportEvent(0x60000000, 0x4451ffa8) reportEvent(0x40000000, 0x4451ffae) reportEvent(0x44000000, 0x4451ffc5) reportEvent(0x04000000, 0x445201a1) reportEvent(0x44000000, 0x4452039a) reportEvent(0x04000000, 0x44520593) reportEvent(0x24000000, 0x44520599) reportEvent(0x44000000, 0x4452078c) reportEvent(0x44000000, 0x445207b0) reportEvent(0x40000000, 0x445207b6) reportEvent(0x20000000, 0x44520989) reportEvent(0x40000000, 0x44520b7e) reportEvent(0x44000000, 0x44520b9b) reportEvent(0x24000000, 0x44520d7c) reportEvent(0x64000000, 0x44520f6f) reportEvent(0x44000000, 0x44520f75) reportEvent(0x04000000, 0x44521168) reportEvent(0x64000000, 0x44521361) reportEvent(0x44000000, 0x44521367) reportEvent(0x44000000, 0x44521384) reportEvent(0x00000000, 0x4452155a) reportEvent(0x40000000, 0x44521753) reportEvent(0x44000000, 0x44521770) reportEvent(0x04000000, 0x4452194c) reportEvent(0x24000000, 0x44521952) reportEvent(0x44000000, 0x44521b45) reportEvent(0x4c000000, 0x44521bce) reportEvent(0x48000000, 0x44521bd4) reportEvent(0x08000000, 0x44521d3e) reportEvent(0x28000000, 0x44521d44) reportEvent(0x48000000, 0x44521f37) reportEvent(0x40000000, 0x44521fc0) reportEvent(0x04000000, 0x4452212f) reportEvent(0x20000000, 0x445227ad) reportEvent(0x40000000, 0x4452299d) reportEvent(0x44000000, 0x445229ba) reportEvent(0x24000000, 0x44522b9a) reportEvent(0x44000000, 0x44522d8f) reportEvent(0x24000000, 0x44522f8d) reportEvent(0x64000000, 0x44523180) reportEvent(0x44000000, 0x44523186) reportEvent(0x04000000, 0x44523379) reportEvent(0x64000000, 0x44523572) reportEvent(0x44000000, 0x44523578) reportEvent(0x44000000, 0x44523595) reportEvent(0x00000000, 0x4452376b) reportEvent(0x40000000, 0x44523964) reportEvent(0x00000000, 0x44523b5d) reportEvent(0x20000000, 0x44523b63) reportEvent(0x40000000, 0x44523d56) reportEvent(0x44000000, 0x44523d73) reportEvent(0x04000000, 0x44523f4f) reportEvent(0x24000000, 0x44523f55) reportEvent(0x44000000, 0x44524148) reportEvent(0x24000000, 0x44524346) reportEvent(0x64000000, 0x44524539) reportEvent(0x44000000, 0x4452453f) reportEvent(0x4c000000, 0x445245c3) reportEvent(0x48000000, 0x445245c9) reportEvent(0x08000000, 0x44524732) reportEvent(0x68000000, 0x4452492b) reportEvent(0x48000000, 0x44524931) reportEvent(0x40000000, 0x445249b5) reportEvent(0x44000000, 0x445249bb) reportEvent(0x04000000, 0x44524b24) reportEvent(0x04000000, 0x44525180) reportEvent(0x20000000, 0x4452519d) reportEvent(0x60000000, 0x44525391) reportEvent(0x40000000, 0x44525397) reportEvent(0x00000000, 0x4452558a) reportEvent(0x60000000, 0x44525783) reportEvent(0x40000000, 0x44525789) reportEvent(0x44000000, 0x445257a0) reportEvent(0x04000000, 0x4452597c) reportEvent(0x44000000, 0x44525b75) reportEvent(0x24000000, 0x444c04d8) reportEvent(0x44000000, 0x44525b9a) reportEvent(0x40000000, 0x44525ba0) reportEvent(0x00000000, 0x44525d6e) reportEvent(0x20000000, 0x44525d74) reportEvent(0x40000000, 0x44525f67) reportEvent(0x20000000, 0x44526164) reportEvent(0x40000000, 0x44526359) reportEvent(0x20000000, 0x44526557) reportEvent(0x60000000, 0x4452674a) reportEvent(0x40000000, 0x44526750) reportEvent(0x00000000, 0x44526943) reportEvent(0x60000000, 0x44526b3c) reportEvent(0x40000000, 0x44526b42) reportEvent(0x00000000, 0x44526d35) reportEvent(0x40000000, 0x44526f2e) reportEvent(0x44000000, 0x44526f4b) reportEvent(0x48000000, 0x44526fb8) reportEvent(0x08000000, 0x44527127) reportEvent(0x28000000, 0x4452712d) reportEvent(0x48000000, 0x44527320) reportEvent(0x20000000, 0x44527b95) reportEvent(0x40000000, 0x44527d86) reportEvent(0x00000000, 0x44527f7f) reportEvent(0x20000000, 0x44527f85) reportEvent(0x40000000, 0x44528178) reportEvent(0x44000000, 0x44528195) reportEvent(0x04000000, 0x44528371) reportEvent(0x24000000, 0x44528377) reportEvent(0x44000000, 0x4452856a) reportEvent(0x24000000, 0x44528768) reportEvent(0x64000000, 0x4452895b) reportEvent(0x44000000, 0x44528961) reportEvent(0x44000000, 0x444c30c5) reportEvent(0x44000000, 0x44528980) reportEvent(0x40000000, 0x44528986) reportEvent(0x00000000, 0x44528b54) reportEvent(0x60000000, 0x44528d4d) reportEvent(0x40000000, 0x44528d53) reportEvent(0x00000000, 0x44528f46) reportEvent(0x40000000, 0x4452913f) reportEvent(0x00000000, 0x44529338) reportEvent(0x20000000, 0x4452933e) reportEvent(0x40000000, 0x44529531) reportEvent(0x44000000, 0x4452954e) reportEvent(0x24000000, 0x4452972e) reportEvent(0x44000000, 0x44529923) reportEvent(0x4c000000, 0x445299ac) reportEvent(0x48000000, 0x445299b2) reportEvent(0x28000000, 0x44529b21) reportEvent(0x68000000, 0x44529d14) reportEvent(0x48000000, 0x44529d1a) reportEvent(0x40000000, 0x44529d9e) reportEvent(0x00000000, 0x44529f0d) reportEvent(0x04000000, 0x4452a563) reportEvent(0x24000000, 0x4452a586) reportEvent(0x44000000, 0x4452a77b) reportEvent(0x24000000, 0x4452a979) reportEvent(0x64000000, 0x4452ab6c) reportEvent(0x44000000, 0x4452ab72) reportEvent(0x40000000, 0x4452ab90) reportEvent(0x40000000, 0x4452ab96) reportEvent(0x00000000, 0x4452ad65) reportEvent(0x60000000, 0x4452af5e) reportEvent(0x40000000, 0x4452af64) reportEvent(0x00000000, 0x4452b157) reportEvent(0x40000000, 0x4452b350) reportEvent(0x00000000, 0x4452b549) reportEvent(0x20000000, 0x4452b54f) reportEvent(0x40000000, 0x4452b742) reportEvent(0x44000000, 0x4452b75f) reportEvent(0x24000000, 0x4452b93f) reportEvent(0x44000000, 0x4452bb34) reportEvent(0x24000000, 0x4452bd32) reportEvent(0x64000000, 0x4452bf25) reportEvent(0x44000000, 0x4452bf2b) reportEvent(0x04000000, 0x4452c11e) reportEvent(0x64000000, 0x4452c317) reportEvent(0x44000000, 0x4452c31d) reportEvent(0x48000000, 0x4452c3a1) reportEvent(0x08000000, 0x4452c510) reportEvent(0x48000000, 0x4452c709) reportEvent(0x40000000, 0x4452c793) reportEvent(0x44000000, 0x4452c799) reportEvent(0x04000000, 0x4452c902) reportEvent(0x04000000, 0x4452cf5e) reportEvent(0x60000000, 0x4452d16f) reportEvent(0x40000000, 0x4452d175) reportEvent(0x44000000, 0x4452d18c) reportEvent(0x04000000, 0x4452d368) reportEvent(0x44000000, 0x4452d561) reportEvent(0x44000000, 0x4452d586) reportEvent(0x00000000, 0x4452d75a) reportEvent(0x20000000, 0x4452d760) reportEvent(0x40000000, 0x4452d953) reportEvent(0x00000000, 0x4452db4c) reportEvent(0x20000000, 0x4452db52) reportEvent(0x40000000, 0x4452dd45) reportEvent(0x20000000, 0x4452df43) reportEvent(0x60000000, 0x4452e136) reportEvent(0x40000000, 0x4452e13c) reportEvent(0x44000000, 0x4452e153) reportEvent(0x04000000, 0x4452e32f) reportEvent(0x64000000, 0x4452e528) reportEvent(0x44000000, 0x4452e52e) reportEvent(0x44000000, 0x4452e54c) reportEvent(0x00000000, 0x4452e721) reportEvent(0x40000000, 0x4452e91a) reportEvent(0x00000000, 0x4452eb13) reportEvent(0x20000000, 0x4452eb19) reportEvent(0x40000000, 0x4452ed0c) reportEvent(0x44000000, 0x4452ed29) reportEvent(0x4c000000, 0x4452ed95) reportEvent(0x48000000, 0x4452ed9b) reportEvent(0x28000000, 0x4452ef09) reportEvent(0x48000000, 0x4452f0fe) reportEvent(0x40000000, 0x4452f187) reportEvent(0x04000000, 0x4452f958) reportEvent(0x20000000, 0x4452f973) reportEvent(0x40000000, 0x4452fb64) reportEvent(0x20000000, 0x4452fd61) reportEvent(0x40000000, 0x4452ff56) reportEvent(0x44000000, 0x4452ff73) reportEvent(0x24000000, 0x44530154) reportEvent(0x64000000, 0x44530347) reportEvent(0x44000000, 0x4453034d) reportEvent(0x04000000, 0x44530540) reportEvent(0x64000000, 0x44530739) reportEvent(0x44000000, 0x4453073f) reportEvent(0x04000000, 0x44530932) reportEvent(0x44000000, 0x44530b2b) reportEvent(0x44000000, 0x44530b4e) reportEvent(0x00000000, 0x44530d24) reportEvent(0x20000000, 0x44530d2a) reportEvent(0x40000000, 0x44530f1d) reportEvent(0x00000000, 0x44531116) reportEvent(0x20000000, 0x4453111c) reportEvent(0x40000000, 0x4453130f) reportEvent(0x20000000, 0x4453150d) reportEvent(0x60000000, 0x44531700) reportEvent(0x40000000, 0x44531706) reportEvent(0x4c000000, 0x4453178a) reportEvent(0x48000000, 0x44531790) reportEvent(0x08000000, 0x445318f9) reportEvent(0x68000000, 0x44531af2) reportEvent(0x48000000, 0x44531af8) reportEvent(0x40000000, 0x44531b7c) reportEvent(0x00000000, 0x44531ceb) reportEvent(0x20000000, 0x44532365) reportEvent(0x60000000, 0x44532558) reportEvent(0x40000000, 0x4453255e) reportEvent(0x00000000, 0x44532751) reportEvent(0x60000000, 0x4453294a) reportEvent(0x40000000, 0x44532950) reportEvent(0x44000000, 0x44532967) reportEvent(0x04000000, 0x44532b43) reportEvent(0x44000000, 0x44532d3c) reportEvent(0x04000000, 0x44532f35) reportEvent(0x24000000, 0x44532f3b) reportEvent(0x44000000, 0x4453312e) reportEvent(0x44000000, 0x44533153) reportEvent(0x20000000, 0x4453332b) reportEvent(0x40000000, 0x44533520) reportEvent(0x20000000, 0x4453371e) reportEvent(0x60000000, 0x44533911) reportEvent(0x40000000, 0x44533917) reportEvent(0x44000000, 0x4453392e) reportEvent(0x04000000, 0x44533b0a) reportEvent(0x64000000, 0x44533d03) reportEvent(0x44000000, 0x44533d09) reportEvent(0x04000000, 0x44533efc) reportEvent(0x44000000, 0x445340f5) reportEvent(0x48000000, 0x4453417f) reportEvent(0x08000000, 0x445342ee) reportEvent(0x28000000, 0x445342f4) reportEvent(0x48000000, 0x445344e7) reportEvent(0x00000000, 0x445346e0) reportEvent(0x40000000, 0x44534f4d) reportEvent(0x00000000, 0x44535146) reportEvent(0x20000000, 0x4453514c) reportEvent(0x40000000, 0x4453533f) reportEvent(0x44000000, 0x4453535c) reportEvent(0x04000000, 0x44535538) reportEvent(0x24000000, 0x4453553e) reportEvent(0x44000000, 0x44535731) reportEvent(0x24000000, 0x4453592f) reportEvent(0x64000000, 0x44535b22) reportEvent(0x44000000, 0x44535b28) reportEvent(0x44000000, 0x44535b48) reportEvent(0x00000000, 0x44535d1b) reportEvent(0x60000000, 0x44535f14) reportEvent(0x40000000, 0x44535f1a) reportEvent(0x44000000, 0x44535f31) reportEvent(0x04000000, 0x4453610d) reportEvent(0x44000000, 0x44536306) reportEvent(0x04000000, 0x445364ff) reportEvent(0x24000000, 0x44536505) reportEvent(0x44000000, 0x445366f8) reportEvent(0x44000000, 0x4453671d) reportEvent(0x20000000, 0x445368f5) reportEvent(0x40000000, 0x44536aea) reportEvent(0x4c000000, 0x44536b73) reportEvent(0x48000000, 0x44536b79) reportEvent(0x28000000, 0x44536ce8) reportEvent(0x68000000, 0x44536edb) reportEvent(0x48000000, 0x44536ee1) reportEvent(0x40000000, 0x44536f65) reportEvent(0x00000000, 0x445370d4) reportEvent(0x20000000, 0x4453774f) reportEvent(0x40000000, 0x44537942) reportEvent(0x20000000, 0x44537b40) reportEvent(0x60000000, 0x44537d33) reportEvent(0x40000000, 0x44537d39) reportEvent(0x04000000, 0x44537f2c) reportEvent(0x64000000, 0x44538125) reportEvent(0x44000000, 0x4453812b) reportEvent(0x04000000, 0x4453831e) reportEvent(0x44000000, 0x44538517) reportEvent(0x44000000, 0x4453853a) reportEvent(0x00000000, 0x44538710) reportEvent(0x20000000, 0x44538716) reportEvent(0x40000000, 0x44538909) reportEvent(0x20000000, 0x44538b06) reportEvent(0x40000000, 0x44538cfb) reportEvent(0x20000000, 0x44538ef9) reportEvent(0x60000000, 0x445390ec) reportEvent(0x40000000, 0x445390f2) reportEvent(0x04000000, 0x445392e5) reportEvent(0x64000000, 0x445394de) reportEvent(0x44000000, 0x445394e4) reportEvent(0x48000000, 0x44539568) reportEvent(0x08000000, 0x445396d7) reportEvent(0x48000000, 0x445398d0) reportEvent(0x40000000, 0x4453995a) reportEvent(0x00000000, 0x44539ac9) reportEvent(0x20000000, 0x4453a147) reportEvent(0x60000000, 0x4453a336) reportEvent(0x40000000, 0x4453a33c) reportEvent(0x00000000, 0x4453a52f) reportEvent(0x40000000, 0x4453a728) reportEvent(0x44000000, 0x4453a745) reportEvent(0x04000000, 0x4453a921) reportEvent(0x24000000, 0x4453a927) reportEvent(0x44000000, 0x4453ab1a) reportEvent(0x24000000, 0x4453ad17) reportEvent(0x44000000, 0x4453af0c) reportEvent(0x04000000, 0x444e627c) reportEvent(0x20000000, 0x4453b10a) reportEvent(0x60000000, 0x4453b2fd) reportEvent(0x40000000, 0x4453b303) reportEvent(0x44000000, 0x4453b31a) reportEvent(0x04000000, 0x4453b4f6) reportEvent(0x64000000, 0x4453b6ef) reportEvent(0x44000000, 0x4453b6f5) reportEvent(0x44000000, 0x4453b714) reportEvent(0x00000000, 0x4453b8e8) reportEvent(0x40000000, 0x4453bae1) reportEvent(0x44000000, 0x4453bafe) reportEvent(0x04000000, 0x4453bcda) reportEvent(0x24000000, 0x4453bce0) reportEvent(0x44000000, 0x4453bed3) reportEvent(0x4c000000, 0x4453bf5c) reportEvent(0x48000000, 0x4453bf62) reportEvent(0x28000000, 0x4453c0d0) reportEvent(0x48000000, 0x4453c2c5) reportEvent(0x40000000, 0x4453c34e) reportEvent(0x20000000, 0x4453cb3a) reportEvent(0x40000000, 0x4453cd2b) reportEvent(0x00000000, 0x4453cf24) reportEvent(0x20000000, 0x4453cf2a) reportEvent(0x40000000, 0x4453d11d) reportEvent(0x44000000, 0x4453d13a) reportEvent(0x24000000, 0x4453d31b) reportEvent(0x64000000, 0x4453d50e) reportEvent(0x44000000, 0x4453d514) reportEvent(0x04000000, 0x4453d707) reportEvent(0x64000000, 0x4453d900) reportEvent(0x44000000, 0x4453d906) reportEvent(0x44000000, 0x4453d923) reportEvent(0x00000000, 0x4453daf9) reportEvent(0x40000000, 0x4453dcf2) reportEvent(0x00000000, 0x4453deeb) reportEvent(0x20000000, 0x4453def1) reportEvent(0x40000000, 0x4453e0e4) reportEvent(0x00000000, 0x4453e2dd) reportEvent(0x20000000, 0x4453e2e3) reportEvent(0x40000000, 0x4453e4d6) reportEvent(0x44000000, 0x4453e4f3) reportEvent(0x24000000, 0x4453e6d4) reportEvent(0x64000000, 0x4453e8c7) reportEvent(0x44000000, 0x4453e8cd) reportEvent(0x04000000, 0x4453eac0) reportEvent(0x64000000, 0x4453ecb9) reportEvent(0x44000000, 0x4453ecbf) reportEvent(0x48000000, 0x4453ed43) reportEvent(0x08000000, 0x4453eeb2) reportEvent(0x20000000, 0x4453f135) reportEvent(0x24000000, 0x4453f13b) reportEvent(0x28000000, 0x4454ca28) reportEvent(0x48000000, 0x4454cb97) reportEvent(0x44000000, 0x4454ce1e) reportEvent(0x24000000, 0x4454cf8d) reportEvent(0x44000000, 0x4454d182) reportEvent(0x4c000000, 0x4454d20b) reportEvent(0x48000000, 0x4454d211) reportEvent(0x28000000, 0x4454d380) reportEvent(0x68000000, 0x4454d573) reportEvent(0x48000000, 0x4454d579) reportEvent(0x40000000, 0x4454d5fd) reportEvent(0x04000000, 0x4454d76c) reportEvent(0x64000000, 0x4454d965) reportEvent(0x44000000, 0x4454d96b) reportEvent(0x48000000, 0x4454d9ef) reportEvent(0x08000000, 0x4454db5e) reportEvent(0x48000000, 0x4454dd57) reportEvent(0x08000000, 0x4454df50) reportEvent(0x28000000, 0x4454df56) reportEvent(0x48000000, 0x4454e149) reportEvent(0x28000000, 0x4454e346) reportEvent(0x48000000, 0x4454e53b) reportEvent(0x28000000, 0x4454e739) reportEvent(0x68000000, 0x4454e92c) reportEvent(0x48000000, 0x4454e932) reportEvent(0x08000000, 0x4454eb25) reportEvent(0x68000000, 0x4454ed1e) reportEvent(0x48000000, 0x4454ed24) reportEvent(0x40000000, 0x4454eda8) reportEvent(0x00000000, 0x4454ef17) reportEvent(0x40000000, 0x4454f110) reportEvent(0x44000000, 0x4454f12d) reportEvent(0x48000000, 0x4454f19a) reportEvent(0x08000000, 0x4454f309) reportEvent(0x28000000, 0x4454f30f) reportEvent(0x48000000, 0x4454f502) reportEvent(0x08000000, 0x4454f6fb) reportEvent(0x28000000, 0x4454f701) reportEvent(0x48000000, 0x4454f8f4) reportEvent(0x40000000, 0x4454f97d) reportEvent(0x24000000, 0x4454faf2) reportEvent(0x64000000, 0x4454fce5) reportEvent(0x44000000, 0x4454fceb) reportEvent(0x4c000000, 0x4454fd6f) reportEvent(0x48000000, 0x4454fd75) reportEvent(0x08000000, 0x4454fede) reportEvent(0x68000000, 0x445500d7) reportEvent(0x48000000, 0x445500dd) reportEvent(0x08000000, 0x445502d0) reportEvent(0x48000000, 0x445504c9) reportEvent(0x08000000, 0x445506c2) reportEvent(0x28000000, 0x445506c8) reportEvent(0x48000000, 0x445508bb) reportEvent(0x28000000, 0x44550ab8) reportEvent(0x48000000, 0x44550cad) reportEvent(0x28000000, 0x44550eab) reportEvent(0x68000000, 0x4455109e) reportEvent(0x48000000, 0x445510a4) reportEvent(0x40000000, 0x44551128) reportEvent(0x00000000, 0x44551297) reportEvent(0x60000000, 0x44551490) reportEvent(0x40000000, 0x44551496) reportEvent(0x44000000, 0x445514ad) reportEvent(0x48000000, 0x4455151a) reportEvent(0x08000000, 0x44551689) reportEvent(0x20000000, 0x4455190c) reportEvent(0x24000000, 0x44551912) reportEvent(0x2c000000, 0x4455954c) reportEvent(0x28000000, 0x44559552) reportEvent(0x48000000, 0x445596bc) reportEvent(0x40000000, 0x4455993e) reportEvent(0x04000000, 0x44559aad) reportEvent(0x24000000, 0x44559ab3) reportEvent(0x64000000, 0x44559ca6) reportEvent(0x44000000, 0x44559cac) reportEvent(0x48000000, 0x44559d30) reportEvent(0x08000000, 0x44559e9f) reportEvent(0x68000000, 0x4455a098) reportEvent(0x40000000, 0x4455a122) reportEvent(0x44000000, 0x4455a128) reportEvent(0x04000000, 0x4455a291) reportEvent(0x24000000, 0x4455a297) reportEvent(0x44000000, 0x4455a48a) reportEvent(0x48000000, 0x4455a514) reportEvent(0x08000000, 0x4455a683) reportEvent(0x28000000, 0x4455a689) reportEvent(0x48000000, 0x4455a87c) reportEvent(0x28000000, 0x4455aa79) reportEvent(0x68000000, 0x4455ac6d) reportEvent(0x48000000, 0x4455ac73) reportEvent(0x08000000, 0x4455ae66) reportEvent(0x28000000, 0x4455ae6c) reportEvent(0x68000000, 0x4455b05f) reportEvent(0x48000000, 0x4455b065) reportEvent(0x08000000, 0x4455b258) reportEvent(0x68000000, 0x4455b451) reportEvent(0x40000000, 0x4455b4db) reportEvent(0x44000000, 0x4455b4e1) reportEvent(0x04000000, 0x4455b64a) reportEvent(0x24000000, 0x4455b650) reportEvent(0x44000000, 0x4455b843) reportEvent(0x44000000, 0x4455b868) reportEvent(0x00000000, 0x4455ba3c) reportEvent(0x20000000, 0x4455ba42) reportEvent(0x40000000, 0x4455bc35) reportEvent(0x40000000, 0x4455c6c9) reportEvent(0x44000000, 0x4455c6e6) reportEvent(0x24000000, 0x4455c8c6) reportEvent(0x44000000, 0x4455cabb) reportEvent(0x44000000, 0x4455cae0) reportEvent(0x20000000, 0x4455ccb9) reportEvent(0x60000000, 0x4455ceac) reportEvent(0x40000000, 0x4455ceb2) reportEvent(0x00000000, 0x4455d0a5) reportEvent(0x60000000, 0x4455d29e) reportEvent(0x40000000, 0x4455d2a4) reportEvent(0x00000000, 0x4455d497) reportEvent(0x40000000, 0x4455d690) reportEvent(0x00000000, 0x4455d889) reportEvent(0x20000000, 0x4455d88f) reportEvent(0x40000000, 0x4455da82) reportEvent(0x44000000, 0x4455da9f) reportEvent(0x04000000, 0x4455dc7b) reportEvent(0x24000000, 0x4455dc81) reportEvent(0x44000000, 0x4455de74) reportEvent(0x24000000, 0x4455e072) reportEvent(0x64000000, 0x4455e265) reportEvent(0x44000000, 0x4455e26b) reportEvent(0x4c000000, 0x4455e2ef) reportEvent(0x48000000, 0x4455e2f5) reportEvent(0x08000000, 0x4455e45e) reportEvent(0x68000000, 0x4455e657) reportEvent(0x48000000, 0x4455e65d) reportEvent(0x40000000, 0x4455e6e1) reportEvent(0x44000000, 0x4455e6e7) reportEvent(0x04000000, 0x4455e850) reportEvent(0x04000000, 0x4455eeb0) reportEvent(0x20000000, 0x4455eecd) reportEvent(0x60000000, 0x4455f0bd) reportEvent(0x40000000, 0x4455f0c3) reportEvent(0x00000000, 0x4455f2b6) reportEvent(0x60000000, 0x4455f4af) reportEvent(0x40000000, 0x4455f4b5) reportEvent(0x44000000, 0x4455f4cc) reportEvent(0x04000000, 0x4455f6a8) reportEvent(0x24000000, 0x4455f6ae) reportEvent(0x44000000, 0x4455f8a1) reportEvent(0x40000000, 0x4455f8c5) reportEvent(0x40000000, 0x4455f8cb) reportEvent(0x00000000, 0x4455fa9a) reportEvent(0x20000000, 0x4455faa0) reportEvent(0x40000000, 0x4455fc93) reportEvent(0x20000000, 0x4455fe90) reportEvent(0x40000000, 0x44560085) reportEvent(0x20000000, 0x44560283) reportEvent(0x60000000, 0x44560476) reportEvent(0x40000000, 0x4456047c) reportEvent(0x00000000, 0x4456066f) reportEvent(0x60000000, 0x44560868) reportEvent(0x40000000, 0x4456086e) reportEvent(0x00000000, 0x44560a61) reportEvent(0x40000000, 0x44560c5a) reportEvent(0x44000000, 0x44560c77) reportEvent(0x48000000, 0x44560ce4) reportEvent(0x08000000, 0x44560e53) reportEvent(0x28000000, 0x44560e59) reportEvent(0x48000000, 0x4456104c) reportEvent(0x20000000, 0x445618bf) reportEvent(0x40000000, 0x44561ab2) reportEvent(0x44000000, 0x44561acf) reportEvent(0x04000000, 0x44561cab) reportEvent(0x24000000, 0x44561cb1) reportEvent(0x44000000, 0x44561ea4) reportEvent(0x44000000, 0x44561ec9) reportEvent(0x00000000, 0x4456209d) reportEvent(0x20000000, 0x445620a3) reportEvent(0x40000000, 0x44562296) reportEvent(0x20000000, 0x44562494) reportEvent(0x60000000, 0x44562687) reportEvent(0x40000000, 0x4456268d) reportEvent(0x00000000, 0x44562880) reportEvent(0x60000000, 0x44562a79) reportEvent(0x40000000, 0x44562a7f) reportEvent(0x00000000, 0x44562c72) reportEvent(0x40000000, 0x44562e6b) reportEvent(0x44000000, 0x44562e88) reportEvent(0x04000000, 0x44563064) reportEvent(0x24000000, 0x4456306a) reportEvent(0x44000000, 0x4456325d) reportEvent(0x24000000, 0x4456345a) reportEvent(0x44000000, 0x4456364f) reportEvent(0x4c000000, 0x445636d8) reportEvent(0x48000000, 0x445636de) reportEvent(0x28000000, 0x4456384d) reportEvent(0x68000000, 0x44563a40) reportEvent(0x48000000, 0x44563a46) reportEvent(0x40000000, 0x44563aca) reportEvent(0x04000000, 0x44563c39) reportEvent(0x04000000, 0x44564294) reportEvent(0x20000000, 0x445642b1) reportEvent(0x40000000, 0x445644a7) reportEvent(0x24000000, 0x445646a5) reportEvent(0x64000000, 0x44564898) reportEvent(0x44000000, 0x4456489e) reportEvent(0x04000000, 0x44564a91) reportEvent(0x64000000, 0x44564c8a) reportEvent(0x44000000, 0x44564c90) reportEvent(0x40000000, 0x44564cae) reportEvent(0x40000000, 0x44564cb4) reportEvent(0x00000000, 0x44564e83) reportEvent(0x40000000, 0x4456507c) reportEvent(0x44000000, 0x44565099) reportEvent(0x04000000, 0x44565275) reportEvent(0x24000000, 0x4456527b) reportEvent(0x44000000, 0x4456546e) reportEvent(0x24000000, 0x4456566b) reportEvent(0x44000000, 0x44565860) reportEvent(0x24000000, 0x44565a5e) reportEvent(0x64000000, 0x44565c51) reportEvent(0x44000000, 0x44565c57) reportEvent(0x04000000, 0x44565e4a) reportEvent(0x64000000, 0x44566043) reportEvent(0x44000000, 0x44566049) reportEvent(0x48000000, 0x445660cd) reportEvent(0x08000000, 0x4456623c) reportEvent(0x48000000, 0x44566435) reportEvent(0x40000000, 0x445664bf) reportEvent(0x44000000, 0x445664c5) reportEvent(0x04000000, 0x4456662e) reportEvent(0x64000000, 0x44566c8d) reportEvent(0x00000000, 0x44566c93) reportEvent(0x20000000, 0x44566ca9) reportEvent(0x60000000, 0x44566e9b) reportEvent(0x40000000, 0x44566ea1) reportEvent(0x44000000, 0x44566eb8) reportEvent(0x04000000, 0x44567094) reportEvent(0x44000000, 0x4456728d) reportEvent(0x04000000, 0x44567486) reportEvent(0x24000000, 0x4456748c) reportEvent(0x44000000, 0x4456767f) reportEvent(0x44000000, 0x445676a3) reportEvent(0x40000000, 0x445676a9) reportEvent(0x20000000, 0x4456787c) reportEvent(0x40000000, 0x44567a71) reportEvent(0x44000000, 0x44567a8e) reportEvent(0x24000000, 0x44567c6f) reportEvent(0x64000000, 0x44567e62) reportEvent(0x44000000, 0x44567e68) reportEvent(0x04000000, 0x4456805b) reportEvent(0x64000000, 0x44568254) reportEvent(0x44000000, 0x4456825a) reportEvent(0x00000000, 0x4456844d) reportEvent(0x40000000, 0x44568646) reportEvent(0x44000000, 0x44568663) reportEvent(0x04000000, 0x4456883f) reportEvent(0x24000000, 0x44568845) reportEvent(0x44000000, 0x44568a38) reportEvent(0x4c000000, 0x44568ac1) reportEvent(0x48000000, 0x44568ac7) reportEvent(0x28000000, 0x44568c35) reportEvent(0x48000000, 0x44568e2a) reportEvent(0x40000000, 0x44568eb3) reportEvent(0x20000000, 0x4456969a) reportEvent(0x40000000, 0x44569890) reportEvent(0x44000000, 0x445698ad) reportEvent(0x24000000, 0x44569a8d) reportEvent(0x44000000, 0x44569c82) reportEvent(0x24000000, 0x44569e80) reportEvent(0x64000000, 0x4456a073) reportEvent(0x44000000, 0x4456a079) reportEvent(0x44000000, 0x4456a099) reportEvent(0x40000000, 0x4456a09f) reportEvent(0x00000000, 0x4456a26c) reportEvent(0x60000000, 0x4456a465) reportEvent(0x40000000, 0x4456a46b) reportEvent(0x44000000, 0x4456a482) reportEvent(0x04000000, 0x4456a65e) reportEvent(0x44000000, 0x4456a857) reportEvent(0x04000000, 0x4456aa50) reportEvent(0x24000000, 0x4456aa56) reportEvent(0x44000000, 0x4456ac49) reportEvent(0x40000000, 0x4456ac72) reportEvent(0x20000000, 0x4456ae46) reportEvent(0x40000000, 0x4456b03b) reportEvent(0x24000000, 0x4456b239) reportEvent(0x64000000, 0x4456b42c) reportEvent(0x44000000, 0x4456b432) reportEvent(0x4c000000, 0x4456b4b6) reportEvent(0x48000000, 0x4456b4bc) reportEvent(0x08000000, 0x4456b625) reportEvent(0x68000000, 0x4456b81e) reportEvent(0x48000000, 0x4456b824) reportEvent(0x40000000, 0x4456b8a8) reportEvent(0x44000000, 0x4456b8ae) reportEvent(0x04000000, 0x4456ba17) reportEvent(0x00000000, 0x44501de3) reportEvent(0x20000000, 0x4456c093) reportEvent(0x60000000, 0x4456c284) reportEvent(0x40000000, 0x4456c28a) reportEvent(0x04000000, 0x4456c47d) reportEvent(0x64000000, 0x4456c676) reportEvent(0x44000000, 0x4456c67c) reportEvent(0x04000000, 0x4456c86f) reportEvent(0x44000000, 0x4456ca68) reportEvent(0x04000000, 0x4456cc61) reportEvent(0x24000000, 0x4456cc67) reportEvent(0x44000000, 0x4456ce5a) reportEvent(0x44000000, 0x4456ce7d) reportEvent(0x00000000, 0x4456d053) reportEvent(0x20000000, 0x4456d059) reportEvent(0x40000000, 0x4456d24c) reportEvent(0x20000000, 0x4456d44a) reportEvent(0x60000000, 0x4456d63d) reportEvent(0x40000000, 0x4456d643) reportEvent(0x04000000, 0x4456d836) reportEvent(0x64000000, 0x4456da2f) reportEvent(0x44000000, 0x4456da35) reportEvent(0x04000000, 0x4456dc28) reportEvent(0x44000000, 0x4456de21) reportEvent(0x48000000, 0x4456deab) reportEvent(0x08000000, 0x4456e01a) reportEvent(0x28000000, 0x4456e020) reportEvent(0x48000000, 0x4456e213) reportEvent(0x44000000, 0x4456e2a1) reportEvent(0x00000000, 0x4456ea69) reportEvent(0x20000000, 0x4456ea83) reportEvent(0x40000000, 0x4456ec79) reportEvent(0x00000000, 0x4456ee72) reportEvent(0x20000000, 0x4456ee78) reportEvent(0x40000000, 0x4456f06b) reportEvent(0x44000000, 0x4456f088) reportEvent(0x24000000, 0x4456f268) reportEvent(0x44000000, 0x4456f45d) reportEvent(0x44000000, 0x4456f480) reportEvent(0x20000000, 0x4456f65b) reportEvent(0x60000000, 0x4456f84e) reportEvent(0x40000000, 0x4456f854) reportEvent(0x00000000, 0x4456fa47) reportEvent(0x60000000, 0x4456fc40) reportEvent(0x40000000, 0x4456fc46) reportEvent(0x00000000, 0x4456fe39) reportEvent(0x40000000, 0x44570032) reportEvent(0x00000000, 0x4457022b) reportEvent(0x20000000, 0x44570231) reportEvent(0x40000000, 0x44570424) reportEvent(0x20000000, 0x44570621) reportEvent(0x40000000, 0x44570816) reportEvent(0x4c000000, 0x4457089f) reportEvent(0x48000000, 0x445708a5) reportEvent(0x28000000, 0x44570a14) reportEvent(0x68000000, 0x44570c07) reportEvent(0x48000000, 0x44570c0d) reportEvent(0x40000000, 0x44570c91) reportEvent(0x00000000, 0x44570e00) reportEvent(0x20000000, 0x4457147c) reportEvent(0x40000000, 0x4457166e) reportEvent(0x20000000, 0x4457186c) reportEvent(0x60000000, 0x44571a5f) reportEvent(0x40000000, 0x44571a65) reportEvent(0x04000000, 0x44571c58) reportEvent(0x64000000, 0x44571e51) reportEvent(0x44000000, 0x44571e57) reportEvent(0x04000000, 0x4457204a) reportEvent(0x44000000, 0x44572243) reportEvent(0x24000000, 0x445075c4) reportEvent(0x44000000, 0x44572268) reportEvent(0x40000000, 0x4457226e) reportEvent(0x00000000, 0x4457243c) reportEvent(0x20000000, 0x44572442) reportEvent(0x40000000, 0x44572635) reportEvent(0x20000000, 0x44572832) reportEvent(0x40000000, 0x44572a27) reportEvent(0x00000000, 0x44572c1f) reportEvent(0x20000000, 0x44572c25) reportEvent(0x60000000, 0x44572e18) reportEvent(0x40000000, 0x44572e1e) reportEvent(0x44000000, 0x44572e35) reportEvent(0x04000000, 0x44573011) reportEvent(0x64000000, 0x4457320a) reportEvent(0x44000000, 0x44573210) reportEvent(0x48000000, 0x44573294) reportEvent(0x08000000, 0x44573403) reportEvent(0x48000000, 0x445735fc) reportEvent(0x40000000, 0x44573686) reportEvent(0x00000000, 0x445737f5) reportEvent(0x04000000, 0x44573e4a) reportEvent(0x64000000, 0x44574062) reportEvent(0x44000000, 0x44574068) reportEvent(0x04000000, 0x4457425b) reportEvent(0x44000000, 0x44574454) reportEvent(0x40000000, 0x44574478) reportEvent(0x40000000, 0x4457447e) reportEvent(0x00000000, 0x4457464d) reportEvent(0x20000000, 0x44574653) reportEvent(0x40000000, 0x44574846) reportEvent(0x20000000, 0x44574a43) reportEvent(0x40000000, 0x44574c38) reportEvent(0x00000000, 0x44574e30) reportEvent(0x20000000, 0x44574e36) reportEvent(0x60000000, 0x44575029) reportEvent(0x40000000, 0x4457502f) reportEvent(0x04000000, 0x44575222) reportEvent(0x64000000, 0x4457541b) reportEvent(0x44000000, 0x44575421) reportEvent(0x04000000, 0x44575614) reportEvent(0x44000000, 0x4457580d) reportEvent(0x04000000, 0x44575a06) reportEvent(0x24000000, 0x44575a0c) reportEvent(0x44000000, 0x44575bff) reportEvent(0x4c000000, 0x44575c88) reportEvent(0x48000000, 0x44575c8e) reportEvent(0x28000000, 0x44575dfc) reportEvent(0x48000000, 0x44575ff1) reportEvent(0x40000000, 0x4457607a) reportEvent(0x04000000, 0x4457684b) reportEvent(0x00000000, 0x44576851) reportEvent(0x20000000, 0x44576866) reportEvent(0x40000000, 0x44576a57) reportEvent(0x44000000, 0x44576a74) reportEvent(0x24000000, 0x44576c54) reportEvent(0x44000000, 0x44576e49) reportEvent(0x44000000, 0x44576e6c) reportEvent(0x20000000, 0x44577047) reportEvent(0x60000000, 0x4457723a) reportEvent(0x40000000, 0x44577240) reportEvent(0x00000000, 0x44577433) reportEvent(0x60000000, 0x4457762c) reportEvent(0x40000000, 0x44577632) reportEvent(0x00000000, 0x44577825) reportEvent(0x40000000, 0x44577a1e) reportEvent(0x44000000, 0x44577a3b) reportEvent(0x04000000, 0x44577c17) reportEvent(0x24000000, 0x44577c1d) reportEvent(0x44000000, 0x44577e10) reportEvent(0x44000000, 0x44577e33) reportEvent(0x20000000, 0x4457800d) reportEvent(0x40000000, 0x44578202) reportEvent(0x20000000, 0x44578400) reportEvent(0x60000000, 0x445785f3) reportEvent(0x40000000, 0x445785f9) reportEvent(0x4c000000, 0x4457867d) reportEvent(0x48000000, 0x44578683) reportEvent(0x08000000, 0x445787ec) reportEvent(0x68000000, 0x445789e5) reportEvent(0x48000000, 0x445789eb) reportEvent(0x40000000, 0x44578a6f) reportEvent(0x44000000, 0x44578a75) reportEvent(0x04000000, 0x44578bde) reportEvent(0x40000000, 0x4457923a) reportEvent(0x20000000, 0x44579257) reportEvent(0x60000000, 0x4457944b) reportEvent(0x40000000, 0x44579451) reportEvent(0x00000000, 0x44579644) reportEvent(0x60000000, 0x4457983d) reportEvent(0x40000000, 0x44579843) reportEvent(0x44000000, 0x4457985a) reportEvent(0x04000000, 0x44579a36) reportEvent(0x44000000, 0x44579c2f) reportEvent(0x04000000, 0x44579e28) reportEvent(0x24000000, 0x44579e2e) reportEvent(0x44000000, 0x4457a021) reportEvent(0x24000000, 0x4457a21e) reportEvent(0x44000000, 0x4457a413) reportEvent(0x44000000, 0x4457a436) reportEvent(0x20000000, 0x4457a611) reportEvent(0x60000000, 0x4457a804) reportEvent(0x40000000, 0x4457a80a) reportEvent(0x00000000, 0x4457a9fd) reportEvent(0x60000000, 0x4457abf6) reportEvent(0x40000000, 0x4457abfc) reportEvent(0x00000000, 0x4457adef) reportEvent(0x40000000, 0x4457afe8) reportEvent(0x44000000, 0x4457b005) reportEvent(0x48000000, 0x4457b072) reportEvent(0x08000000, 0x4457b1e1) reportEvent(0x28000000, 0x4457b1e7) reportEvent(0x48000000, 0x4457b3da) reportEvent(0x40000000, 0x4457be40) reportEvent(0x00000000, 0x4457c039) reportEvent(0x20000000, 0x4457c03f) reportEvent(0x40000000, 0x4457c232) reportEvent(0x44000000, 0x4457c24f) reportEvent(0x04000000, 0x4457c42b) reportEvent(0x24000000, 0x4457c431) reportEvent(0x44000000, 0x4457c624) reportEvent(0x24000000, 0x4457c822) reportEvent(0x64000000, 0x4457ca15) reportEvent(0x44000000, 0x4457ca1b) reportEvent(0x04000000, 0x44511d90) reportEvent(0x44000000, 0x4457ca3a) reportEvent(0x40000000, 0x4457ca40) reportEvent(0x00000000, 0x4457cc0e) reportEvent(0x60000000, 0x4457ce07) reportEvent(0x40000000, 0x4457ce0d) reportEvent(0x00000000, 0x4457d000) reportEvent(0x40000000, 0x4457d1f9) reportEvent(0x44000000, 0x4457d216) reportEvent(0x04000000, 0x4457d3f2) reportEvent(0x24000000, 0x4457d3f8) reportEvent(0x44000000, 0x4457d5eb) reportEvent(0x04000000, 0x4457d7e4) reportEvent(0x24000000, 0x4457d7ea) reportEvent(0x44000000, 0x4457d9dd) reportEvent(0x4c000000, 0x4457da66) reportEvent(0x48000000, 0x4457da6c) reportEvent(0x28000000, 0x4457dbdb) reportEvent(0x68000000, 0x4457ddce) reportEvent(0x48000000, 0x4457ddd4) reportEvent(0x40000000, 0x4457de58) reportEvent(0x00000000, 0x4457dfc7) reportEvent(0x40000000, 0x4457e835) reportEvent(0x20000000, 0x4457ea33) reportEvent(0x60000000, 0x4457ec26) reportEvent(0x40000000, 0x4457ec2c) reportEvent(0x04000000, 0x4457ee1f) reportEvent(0x64000000, 0x4457f018) reportEvent(0x44000000, 0x4457f01e) reportEvent(0x04000000, 0x4457f211) reportEvent(0x44000000, 0x4457f40a) reportEvent(0x44000000, 0x4457f42d) reportEvent(0x00000000, 0x4457f603) reportEvent(0x20000000, 0x4457f609) reportEvent(0x40000000, 0x4457f7fc) reportEvent(0x44000000, 0x4457f819) reportEvent(0x24000000, 0x4457f9f9) reportEvent(0x44000000, 0x4457fbee) reportEvent(0x24000000, 0x4457fdec) reportEvent(0x64000000, 0x4457ffdf) reportEvent(0x44000000, 0x4457ffe5) reportEvent(0x40000000, 0x44580006) reportEvent(0x00000000, 0x445801d8) reportEvent(0x60000000, 0x445803d1) reportEvent(0x40000000, 0x445803d7) reportEvent(0x44000000, 0x445803ee) reportEvent(0x48000000, 0x4458045b) reportEvent(0x08000000, 0x445805ca) reportEvent(0x48000000, 0x445807c3) reportEvent(0x40000000, 0x4458084d) reportEvent(0x00000000, 0x445809bc) reportEvent(0x20000000, 0x44581039) reportEvent(0x60000000, 0x44581229) reportEvent(0x40000000, 0x4458122f) reportEvent(0x00000000, 0x44581422) reportEvent(0x40000000, 0x4458161b) reportEvent(0x44000000, 0x44581638) reportEvent(0x04000000, 0x44581814) reportEvent(0x24000000, 0x4458181a) reportEvent(0x44000000, 0x44581a0d) reportEvent(0x24000000, 0x44581c0a) reportEvent(0x44000000, 0x44581dff) reportEvent(0x40000000, 0x44581e23) reportEvent(0x20000000, 0x44581ffd) reportEvent(0x60000000, 0x445821f0) reportEvent(0x40000000, 0x445821f6) reportEvent(0x00000000, 0x445823e9) reportEvent(0x60000000, 0x445825e2) reportEvent(0x40000000, 0x445825e8) reportEvent(0x00000000, 0x445827db) reportEvent(0x40000000, 0x445829d4) reportEvent(0x44000000, 0x445829f1) reportEvent(0x04000000, 0x44582bcd) reportEvent(0x24000000, 0x44582bd3) reportEvent(0x44000000, 0x44582dc6) reportEvent(0x4c000000, 0x44582e4f) reportEvent(0x48000000, 0x44582e55) reportEvent(0x28000000, 0x44582fc3) reportEvent(0x48000000, 0x445831b8) reportEvent(0x40000000, 0x44583241) reportEvent(0x20000000, 0x44583a2b) reportEvent(0x40000000, 0x44583c1e) reportEvent(0x20000000, 0x44583e1b) reportEvent(0x40000000, 0x44584010) reportEvent(0x44000000, 0x4458402d) reportEvent(0x24000000, 0x4458420e) reportEvent(0x64000000, 0x44584401) reportEvent(0x44000000, 0x44584407) reportEvent(0x04000000, 0x445845fa) reportEvent(0x64000000, 0x445847f3) reportEvent(0x44000000, 0x445847f9) reportEvent(0x44000000, 0x44584817) reportEvent(0x00000000, 0x445849ec) reportEvent(0x40000000, 0x44584be5) reportEvent(0x44000000, 0x44584c02) reportEvent(0x04000000, 0x44584dde) reportEvent(0x24000000, 0x44584de4) reportEvent(0x44000000, 0x44584fd7) reportEvent(0x40000000, 0x44584ffc) reportEvent(0x20000000, 0x445851d4) reportEvent(0x40000000, 0x445853c9) reportEvent(0x44000000, 0x445853e6) reportEvent(0x24000000, 0x445855c7) reportEvent(0x64000000, 0x445857ba) reportEvent(0x44000000, 0x445857c0) reportEvent(0x4c000000, 0x44585844) reportEvent(0x48000000, 0x4458584a) reportEvent(0x08000000, 0x445859b3) reportEvent(0x68000000, 0x44585bac) reportEvent(0x48000000, 0x44585bb2) reportEvent(0x40000000, 0x44585c36) reportEvent(0x00000000, 0x44585da5) reportEvent(0x20000000, 0x4458641e) reportEvent(0x60000000, 0x44586612) reportEvent(0x40000000, 0x44586618) reportEvent(0x00000000, 0x4458680b) reportEvent(0x60000000, 0x44586a04) reportEvent(0x40000000, 0x44586a0a) reportEvent(0x44000000, 0x44586a21) reportEvent(0x04000000, 0x44586bfd) reportEvent(0x44000000, 0x44586df6) reportEvent(0x04000000, 0x44586fef) reportEvent(0x24000000, 0x44586ff5) reportEvent(0x44000000, 0x445871e8) reportEvent(0x44000000, 0x4458720d) reportEvent(0x20000000, 0x445873e5) reportEvent(0x40000000, 0x445875da) reportEvent(0x20000000, 0x445877d8) reportEvent(0x60000000, 0x445879cb) reportEvent(0x40000000, 0x445879d1) reportEvent(0x00000000, 0x44587bc4) reportEvent(0x60000000, 0x44587dbd) reportEvent(0x40000000, 0x44587dc3) reportEvent(0x44000000, 0x44587dda) reportEvent(0x04000000, 0x44587fb6) reportEvent(0x44000000, 0x445881af) reportEvent(0x48000000, 0x44588239) reportEvent(0x08000000, 0x445883a8) reportEvent(0x28000000, 0x445883ae) reportEvent(0x48000000, 0x445885a1) reportEvent(0x04000000, 0x44588df4) reportEvent(0x24000000, 0x44588e17) reportEvent(0x44000000, 0x44589007) reportEvent(0x04000000, 0x44589200) reportEvent(0x24000000, 0x44589206) reportEvent(0x44000000, 0x445893f9) reportEvent(0x44000000, 0x4458941e) reportEvent(0x20000000, 0x445895f6) reportEvent(0x40000000, 0x445897eb) reportEvent(0x20000000, 0x445899e9) reportEvent(0x60000000, 0x44589bdc) reportEvent(0x40000000, 0x44589be2) reportEvent(0x44000000, 0x44589bf9) reportEvent(0x04000000, 0x44589dd5) reportEvent(0x64000000, 0x44589fce) reportEvent(0x44000000, 0x44589fd4) reportEvent(0x04000000, 0x4458a1c7) reportEvent(0x44000000, 0x4458a3c0) reportEvent(0x04000000, 0x4458a5b9) reportEvent(0x24000000, 0x4458a5bf) reportEvent(0x44000000, 0x4458a7b2) reportEvent(0x24000000, 0x4458a9af) reportEvent(0x44000000, 0x4458aba4) reportEvent(0x4c000000, 0x4458ac2d) reportEvent(0x48000000, 0x4458ac33) reportEvent(0x28000000, 0x4458ada2) reportEvent(0x68000000, 0x4458af95) reportEvent(0x48000000, 0x4458af9b) reportEvent(0x40000000, 0x4458b01f) reportEvent(0x04000000, 0x4458b18e) reportEvent(0x00000000, 0x4458b7ec) reportEvent(0x20000000, 0x4458b808) reportEvent(0x40000000, 0x4458b9fc) reportEvent(0x44000000, 0x4458ba19) reportEvent(0x24000000, 0x4458bbfa) reportEvent(0x64000000, 0x4458bded) reportEvent(0x44000000, 0x4458bdf3) reportEvent(0x44000000, 0x4458be13) reportEvent(0x00000000, 0x4458bfe6) reportEvent(0x60000000, 0x4458c1df) reportEvent(0x40000000, 0x4458c1e5) reportEvent(0x00000000, 0x4458c3d8) reportEvent(0x40000000, 0x4458c5d1) reportEvent(0x00000000, 0x4458c7ca) reportEvent(0x20000000, 0x4458c7d0) reportEvent(0x40000000, 0x4458c9c3) reportEvent(0x00000000, 0x4458cbbc) reportEvent(0x20000000, 0x4458cbc2) reportEvent(0x40000000, 0x4458cdb5) reportEvent(0x20000000, 0x4458cfb3) reportEvent(0x60000000, 0x4458d1a6) reportEvent(0x40000000, 0x4458d1ac) reportEvent(0x04000000, 0x4458d39f) reportEvent(0x64000000, 0x4458d598) reportEvent(0x44000000, 0x4458d59e) reportEvent(0x48000000, 0x4458d622) reportEvent(0x08000000, 0x4458d791) reportEvent(0x48000000, 0x4458d98a) reportEvent(0x40000000, 0x4458da14) reportEvent(0x44000000, 0x4458da1a) reportEvent(0x04000000, 0x4458db83) reportEvent(0x04000000, 0x4458e1e3) reportEvent(0x60000000, 0x4458e3f0) reportEvent(0x40000000, 0x4458e3f6) reportEvent(0x44000000, 0x4458e40d) reportEvent(0x04000000, 0x4458e5e9) reportEvent(0x44000000, 0x4458e7e2) reportEvent(0x44000000, 0x4458e805) reportEvent(0x00000000, 0x4458e9db) reportEvent(0x20000000, 0x4458e9e1) reportEvent(0x40000000, 0x4458ebd4) reportEvent(0x00000000, 0x4458edcd) reportEvent(0x20000000, 0x4458edd3) reportEvent(0x40000000, 0x4458efc6) reportEvent(0x20000000, 0x4458f1c4) reportEvent(0x60000000, 0x4458f3b7) reportEvent(0x40000000, 0x4458f3bd) reportEvent(0x04000000, 0x4458f5b0) reportEvent(0x64000000, 0x4458f7a9) reportEvent(0x44000000, 0x4458f7af) reportEvent(0x4c000000, 0x445245c3) reportEvent(0x48000000, 0x4458f7cf) reportEvent(0x00000000, 0x4458f9a2) reportEvent(0x40000000, 0x4458fb9b) reportEvent(0x00000000, 0x4458fd94) reportEvent(0x20000000, 0x4458fd9a) reportEvent(0x40000000, 0x4458ff8d) reportEvent(0x44000000, 0x4458ffaa) reportEvent(0x4c000000, 0x44590016) reportEvent(0x48000000, 0x4459001c) reportEvent(0x08000000, 0x44590186) reportEvent(0x28000000, 0x4459018c) reportEvent(0x48000000, 0x4459037f) reportEvent(0x40000000, 0x44590408) reportEvent(0x04000000, 0x44590bd2) reportEvent(0x20000000, 0x44590bef) reportEvent(0x40000000, 0x44590de5) reportEvent(0x20000000, 0x44590fe2) reportEvent(0x40000000, 0x445911d7) reportEvent(0x24000000, 0x445913d5) reportEvent(0x64000000, 0x445915c8) reportEvent(0x44000000, 0x445915ce) reportEvent(0x44000000, 0x445915ee) reportEvent(0x00000000, 0x445917c1) reportEvent(0x60000000, 0x445919ba) reportEvent(0x40000000, 0x445919c0) reportEvent(0x44000000, 0x445919d7) reportEvent(0x04000000, 0x44591bb3) reportEvent(0x44000000, 0x44591dac) reportEvent(0x04000000, 0x44591fa5) reportEvent(0x24000000, 0x44591fab) reportEvent(0x44000000, 0x4459219e) reportEvent(0x44000000, 0x445921c3) reportEvent(0x00000000, 0x44592397) reportEvent(0x20000000, 0x4459239d) reportEvent(0x40000000, 0x44592590) reportEvent(0x24000000, 0x4459278e) reportEvent(0x64000000, 0x44592981) reportEvent(0x44000000, 0x44592987) reportEvent(0x4c000000, 0x44592a0b) reportEvent(0x48000000, 0x44592a11) reportEvent(0x08000000, 0x44592b7a) reportEvent(0x68000000, 0x44592d73) reportEvent(0x48000000, 0x44592d79) reportEvent(0x40000000, 0x44592dfd) reportEvent(0x00000000, 0x44592f6c) reportEvent(0x20000000, 0x445935e7) reportEvent(0x60000000, 0x445937d9) reportEvent(0x40000000, 0x445937df) reportEvent(0x04000000, 0x445939d2) reportEvent(0x64000000, 0x44593bcb) reportEvent(0x44000000, 0x44593bd1) reportEvent(0x44000000, 0x44593bef) reportEvent(0x00000000, 0x44593dc4) reportEvent(0x40000000, 0x44593fbd) reportEvent(0x00000000, 0x445941b6) reportEvent(0x20000000, 0x445941bc) reportEvent(0x40000000, 0x445943af) reportEvent(0x00000000, 0x445945a8) reportEvent(0x20000000, 0x445945ae) reportEvent(0x40000000, 0x445947a1) reportEvent(0x44000000, 0x445947be) reportEvent(0x24000000, 0x4459499f) reportEvent(0x64000000, 0x44594b92) reportEvent(0x44000000, 0x44594b98) reportEvent(0x04000000, 0x44594d8b) reportEvent(0x24000000, 0x44594d91) reportEvent(0x64000000, 0x44594f84) reportEvent(0x44000000, 0x44594f8a) reportEvent(0x44000000, 0x44594fa8) reportEvent(0x00000000, 0x4459517d) reportEvent(0x40000000, 0x44595376) reportEvent(0x44000000, 0x44595393) reportEvent(0x48000000, 0x44595400) reportEvent(0x08000000, 0x4459556f) reportEvent(0x28000000, 0x44595575) reportEvent(0x48000000, 0x44595768) reportEvent(0x44000000, 0x445957f6) reportEvent(0x04000000, 0x44595961) reportEvent(0x40000000, 0x44595fc3) reportEvent(0x00000000, 0x44595fc9) reportEvent(0x20000000, 0x44595fdf) reportEvent(0x40000000, 0x445961ce) reportEvent(0x44000000, 0x445961eb) reportEvent(0x04000000, 0x445963c7) reportEvent(0x24000000, 0x445963cd) reportEvent(0x44000000, 0x445965c0) reportEvent(0x44000000, 0x445965e3) reportEvent(0x40000000, 0x445965e9) reportEvent(0x20000000, 0x445967bd) reportEvent(0x40000000, 0x445969b2) reportEvent(0x20000000, 0x44596bb0) reportEvent(0x60000000, 0x44596da3) reportEvent(0x40000000, 0x44596da9) reportEvent(0x04000000, 0x44596f9c) reportEvent(0x64000000, 0x44597195) reportEvent(0x44000000, 0x4459719b) reportEvent(0x04000000, 0x4459738e) reportEvent(0x44000000, 0x44597587) reportEvent(0x44000000, 0x445975aa) reportEvent(0x00000000, 0x44597780) reportEvent(0x20000000, 0x44597786) reportEvent(0x40000000, 0x44597979) reportEvent(0x44000000, 0x44597996) reportEvent(0x04000000, 0x44597b72) reportEvent(0x24000000, 0x44597b78) reportEvent(0x44000000, 0x44597d6b) reportEvent(0x4c000000, 0x44597df4) reportEvent(0x48000000, 0x44597dfa) reportEvent(0x28000000, 0x44597f69) reportEvent(0x68000000, 0x4459815c) reportEvent(0x48000000, 0x44598162) reportEvent(0x40000000, 0x445981e6) reportEvent(0x04000000, 0x44598355) reportEvent(0x20000000, 0x445989b2) reportEvent(0x20000000, 0x445989cf) reportEvent(0x40000000, 0x44598bc3) reportEvent(0x44000000, 0x44598be0) reportEvent(0x24000000, 0x44598dc1) reportEvent(0x64000000, 0x44598fb4) reportEvent(0x44000000, 0x44598fba) reportEvent(0x44000000, 0x44598fda) reportEvent(0x00000000, 0x445991ad) reportEvent(0x60000000, 0x445993a6) reportEvent(0x40000000, 0x445993ac) reportEvent(0x00000000, 0x4459959f) reportEvent(0x40000000, 0x44599798) reportEvent(0x00000000, 0x44599991) reportEvent(0x20000000, 0x44599997) reportEvent(0x40000000, 0x44599b8a) reportEvent(0x00000000, 0x44599d83) reportEvent(0x20000000, 0x44599d89) reportEvent(0x40000000, 0x44599f7c) reportEvent(0x24000000, 0x4459a17a) reportEvent(0x64000000, 0x4459a36d) reportEvent(0x44000000, 0x4459a373) reportEvent(0x04000000, 0x4459a566) reportEvent(0x64000000, 0x4459a75f) reportEvent(0x44000000, 0x4459a765) reportEvent(0x48000000, 0x4459a7e9) reportEvent(0x08000000, 0x4459a958) reportEvent(0x48000000, 0x4459ab51) reportEvent(0x40000000, 0x4459abdb) reportEvent(0x44000000, 0x4459abe1) reportEvent(0x04000000, 0x4459ad4a) reportEvent(0x04000000, 0x4459b3aa) reportEvent(0x20000000, 0x4459b3c7) reportEvent(0x60000000, 0x4459b5b7) reportEvent(0x40000000, 0x4459b5bd) reportEvent(0x44000000, 0x4459b5d4) reportEvent(0x04000000, 0x4459b7b0) reportEvent(0x44000000, 0x4459b9a9) reportEvent(0x44000000, 0x4459b9cc) reportEvent(0x00000000, 0x4459bba2) reportEvent(0x20000000, 0x4459bba8) reportEvent(0x40000000, 0x4459bd9b) reportEvent(0x00000000, 0x4459bf94) reportEvent(0x20000000, 0x4459bf9a) reportEvent(0x40000000, 0x4459c18d) reportEvent(0x24000000, 0x4459c38b) reportEvent(0x64000000, 0x4459c57e) reportEvent(0x44000000, 0x4459c584) reportEvent(0x04000000, 0x4459c777) reportEvent(0x64000000, 0x4459c970) reportEvent(0x44000000, 0x4459c976) reportEvent(0x04000000, 0x4459cb69) reportEvent(0x44000000, 0x4459cd62) reportEvent(0x04000000, 0x4459cf5b) reportEvent(0x24000000, 0x4459cf61) reportEvent(0x44000000, 0x4459d154) reportEvent(0x4c000000, 0x4459d1dd) reportEvent(0x48000000, 0x4459d1e3) reportEvent(0x08000000, 0x4459d34d) reportEvent(0x28000000, 0x4459d353) reportEvent(0x48000000, 0x4459d546) reportEvent(0x40000000, 0x4459d5cf) reportEvent(0x00000000, 0x4459dda0) reportEvent(0x20000000, 0x4459ddb7) reportEvent(0x40000000, 0x4459dfac) reportEvent(0x44000000, 0x4459dfc9) reportEvent(0x24000000, 0x4459e1a9) reportEvent(0x44000000, 0x4459e39e) reportEvent(0x60000000, 0x4459e3c1) reportEvent(0x20000000, 0x4459e59c) reportEvent(0x60000000, 0x4459e78f) reportEvent(0x40000000, 0x4459e795) reportEvent(0x00000000, 0x4459e988) reportEvent(0x60000000, 0x4459eb81) reportEvent(0x40000000, 0x4459eb87) reportEvent(0x44000000, 0x4459eb9e) reportEvent(0x04000000, 0x4459ed7a) reportEvent(0x44000000, 0x4459ef73) reportEvent(0x04000000, 0x4459f16c) reportEvent(0x24000000, 0x4459f172) reportEvent(0x44000000, 0x4459f365) reportEvent(0x40000000, 0x4459f388) reportEvent(0x40000000, 0x4459f38e) reportEvent(0x00000000, 0x4459f55e) reportEvent(0x20000000, 0x4459f564) reportEvent(0x40000000, 0x4459f757) reportEvent(0x44000000, 0x4459f774) reportEvent(0x24000000, 0x4459f955) reportEvent(0x64000000, 0x4459fb48) reportEvent(0x44000000, 0x4459fb4e) reportEvent(0x4c000000, 0x4459fbd2) reportEvent(0x48000000, 0x4459fbd8) reportEvent(0x08000000, 0x4459fd41) reportEvent(0x68000000, 0x4459ff3a) reportEvent(0x48000000, 0x4459ff40) reportEvent(0x40000000, 0x4459ffc4) reportEvent(0x44000000, 0x4459ffca) reportEvent(0x04000000, 0x445a0133) reportEvent(0x20000000, 0x445a07b0) reportEvent(0x60000000, 0x445a09a0) reportEvent(0x40000000, 0x445a09a6) reportEvent(0x04000000, 0x445a0b99) reportEvent(0x64000000, 0x445a0d92) reportEvent(0x44000000, 0x445a0d98) reportEvent(0x44000000, 0x445a0db7) reportEvent(0x00000000, 0x445a0f8b) reportEvent(0x40000000, 0x445a1184) reportEvent(0x00000000, 0x445a137d) reportEvent(0x20000000, 0x445a1383) reportEvent(0x40000000, 0x445a1576) reportEvent(0x44000000, 0x445a1593) reportEvent(0x04000000, 0x445a176f) reportEvent(0x24000000, 0x445a1775) reportEvent(0x44000000, 0x445a1968) reportEvent(0x24000000, 0x445a1b66) reportEvent(0x64000000, 0x445a1d59) reportEvent(0x44000000, 0x445a1d5f) reportEvent(0x04000000, 0x445a1d7d) reportEvent(0x40000000, 0x445a1d83) reportEvent(0x00000000, 0x445a1f52) reportEvent(0x60000000, 0x445a214b) reportEvent(0x40000000, 0x445a2151) reportEvent(0x44000000, 0x445a2168) reportEvent(0x04000000, 0x445a2344) reportEvent(0x44000000, 0x445a253d) reportEvent(0x48000000, 0x445a25c7) reportEvent(0x08000000, 0x445a2736) reportEvent(0x28000000, 0x445a273c) reportEvent(0x48000000, 0x445a292f) reportEvent(0x44000000, 0x445a29bd) reportEvent(0x04000000, 0x445a3185) reportEvent(0x20000000, 0x445a31a0) reportEvent(0x40000000, 0x445a3395) reportEvent(0x44000000, 0x445a33b2) reportEvent(0x04000000, 0x445a358e) reportEvent(0x24000000, 0x445a3594) reportEvent(0x44000000, 0x445a3787) reportEvent(0x44000000, 0x445a37aa) reportEvent(0x20000000, 0x445a3984) reportEvent(0x40000000, 0x445a3b79) reportEvent(0x44000000, 0x445a3b96) reportEvent(0x24000000, 0x445a3d77) reportEvent(0x64000000, 0x445a3f6a) reportEvent(0x44000000, 0x445a3f70) reportEvent(0x44000000, 0x4453a745) reportEvent(0x44000000, 0x445a3f8f) reportEvent(0x40000000, 0x445a3f95) reportEvent(0x00000000, 0x445a4163) reportEvent(0x60000000, 0x445a435c) reportEvent(0x40000000, 0x445a4362) reportEvent(0x00000000, 0x445a4555) reportEvent(0x40000000, 0x445a474e) reportEvent(0x44000000, 0x445a476b) reportEvent(0x04000000, 0x445a4947) reportEvent(0x24000000, 0x445a494d) reportEvent(0x44000000, 0x445a4b40) reportEvent(0x24000000, 0x445a4d3d) reportEvent(0x44000000, 0x445a4f32) reportEvent(0x4c000000, 0x445a4fbb) reportEvent(0x48000000, 0x445a4fc1) reportEvent(0x28000000, 0x445a5130) reportEvent(0x68000000, 0x445a5323) reportEvent(0x48000000, 0x445a5329) reportEvent(0x40000000, 0x445a53ad) reportEvent(0x04000000, 0x445a551c) reportEvent(0x00000000, 0x445a5b7e) reportEvent(0x20000000, 0x445a5b98) reportEvent(0x40000000, 0x445a5d8a) reportEvent(0x20000000, 0x445a5f88) reportEvent(0x60000000, 0x445a617b) reportEvent(0x40000000, 0x445a6181) reportEvent(0x04000000, 0x445a6374) reportEvent(0x64000000, 0x445a656d) reportEvent(0x44000000, 0x445a6573) reportEvent(0x04000000, 0x445a6766) reportEvent(0x44000000, 0x445a695f) reportEvent(0x24000000, 0x4453d31b) reportEvent(0x00000000, 0x445a6b58) reportEvent(0x20000000, 0x445a6b5e) reportEvent(0x40000000, 0x445a6d51) reportEvent(0x20000000, 0x445a6f4e) reportEvent(0x40000000, 0x445a7143) reportEvent(0x20000000, 0x445a7341) reportEvent(0x60000000, 0x445a7534) reportEvent(0x40000000, 0x445a753a) reportEvent(0x04000000, 0x445a772d) reportEvent(0x64000000, 0x445a7926) reportEvent(0x44000000, 0x445a792c) reportEvent(0x48000000, 0x445a79b0) reportEvent(0x08000000, 0x445a7b1f) reportEvent(0x48000000, 0x445a7d18) reportEvent(0x40000000, 0x445a7da2) reportEvent(0x00000000, 0x445a7f11) reportEvent(0x60000000, 0x445a877e) reportEvent(0x40000000, 0x445a8784) reportEvent(0x00000000, 0x445a8977) reportEvent(0x40000000, 0x445a8b70) reportEvent(0x44000000, 0x445a8b8d) reportEvent(0x04000000, 0x445a8d69) reportEvent(0x24000000, 0x445a8d6f) reportEvent(0x44000000, 0x445a8f62) reportEvent(0x40000000, 0x445a8f86) reportEvent(0x40000000, 0x445a8f8c) reportEvent(0x00000000, 0x445a915b) reportEvent(0x20000000, 0x445a9161) reportEvent(0x40000000, 0x445a9354) reportEvent(0x44000000, 0x445a9371) reportEvent(0x24000000, 0x445a9552) reportEvent(0x64000000, 0x445a9745) reportEvent(0x44000000, 0x445a974b) reportEvent(0x04000000, 0x445a993e) reportEvent(0x64000000, 0x445a9b37) reportEvent(0x44000000, 0x445a9b3d) reportEvent(0x44000000, 0x445a9b5c) reportEvent(0x40000000, 0x445a9b62) reportEvent(0x00000000, 0x445a9d30) reportEvent(0x40000000, 0x445a9f29) reportEvent(0x44000000, 0x445a9f46) reportEvent(0x04000000, 0x445aa122) reportEvent(0x24000000, 0x445aa128) reportEvent(0x44000000, 0x445aa31b) reportEvent(0x4c000000, 0x445aa3a4) reportEvent(0x48000000, 0x445aa3aa) reportEvent(0x28000000, 0x445aa518) reportEvent(0x48000000, 0x445aa70d) reportEvent(0x40000000, 0x445aa796) reportEvent(0x00000000, 0x445aa905) reportEvent(0x20000000, 0x445aaf81) reportEvent(0x40000000, 0x445ab173) reportEvent(0x44000000, 0x445ab190) reportEvent(0x04000000, 0x445ab36c) reportEvent(0x24000000, 0x445ab372) reportEvent(0x44000000, 0x445ab565) reportEvent(0x44000000, 0x445ab588) reportEvent(0x20000000, 0x445ab763) reportEvent(0x60000000, 0x445ab956) reportEvent(0x40000000, 0x445ab95c) reportEvent(0x00000000, 0x445abb4f) reportEvent(0x60000000, 0x445abd48) reportEvent(0x40000000, 0x445abd4e) reportEvent(0x00000000, 0x445abf41) reportEvent(0x40000000, 0x445ac13a) reportEvent(0x44000000, 0x445ac157) reportEvent(0x04000000, 0x445ac333) reportEvent(0x24000000, 0x445ac339) reportEvent(0x44000000, 0x445ac52c) reportEvent(0x44000000, 0x445ac551) reportEvent(0x00000000, 0x445ac725) reportEvent(0x20000000, 0x445ac72b) reportEvent(0x40000000, 0x445ac91e) reportEvent(0x44000000, 0x445ac93b) reportEvent(0x24000000, 0x445acb1c) reportEvent(0x64000000, 0x445acd0f) reportEvent(0x44000000, 0x445acd15) reportEvent(0x4c000000, 0x445acd99) reportEvent(0x48000000, 0x445acd9f) reportEvent(0x08000000, 0x445acf08) reportEvent(0x68000000, 0x445ad101) reportEvent(0x48000000, 0x445ad107) reportEvent(0x40000000, 0x445ad18b) reportEvent(0x44000000, 0x445ad191) reportEvent(0x04000000, 0x445ad2fa) reportEvent(0x00000000, 0x445ad959) reportEvent(0x20000000, 0x445ad973) reportEvent(0x60000000, 0x445adb67) reportEvent(0x40000000, 0x445adb6d) reportEvent(0x44000000, 0x445adb84) reportEvent(0x04000000, 0x445add60) reportEvent(0x64000000, 0x445adf59) reportEvent(0x44000000, 0x445adf5f) reportEvent(0x44000000, 0x445adf7c) reportEvent(0x00000000, 0x445ae152) reportEvent(0x40000000, 0x445ae34b) reportEvent(0x00000000, 0x445ae544) reportEvent(0x20000000, 0x445ae54a) reportEvent(0x40000000, 0x445ae73d) reportEvent(0x00000000, 0x445ae936) reportEvent(0x20000000, 0x445ae93c) reportEvent(0x40000000, 0x445aeb2f) reportEvent(0x20000000, 0x445aed2d) reportEvent(0x60000000, 0x445aef20) reportEvent(0x40000000, 0x445aef26) reportEvent(0x04000000, 0x445af119) reportEvent(0x64000000, 0x445af312) reportEvent(0x44000000, 0x445af318) reportEvent(0x44000000, 0x445af336) reportEvent(0x00000000, 0x445af50b) reportEvent(0x40000000, 0x445af704) reportEvent(0x44000000, 0x445af721) reportEvent(0x48000000, 0x445af78e) reportEvent(0x08000000, 0x445af8fd) reportEvent(0x28000000, 0x445af903) reportEvent(0x48000000, 0x445afaf6) reportEvent(0x44000000, 0x445afb84) reportEvent(0x04000000, 0x445afcef) reportEvent(0x48000000, 0x445f124f) reportEvent(0x20000000, 0x445f127a) reportEvent(0x40000000, 0x445b055c) reportEvent(0x44000000, 0x445b0579) reportEvent(0x04000000, 0x445b0755) reportEvent(0x24000000, 0x445b075b) reportEvent(0x44000000, 0x445b094e) reportEvent(0x44000000, 0x4455b843) reportEvent(0x40000000, 0x445b0974) reportEvent(0x20000000, 0x445b0b4b) reportEvent(0x40000000, 0x445b0d40) reportEvent(0x44000000, 0x445b0d5d) reportEvent(0x24000000, 0x445b0f3e) reportEvent(0x64000000, 0x445b1131) reportEvent(0x44000000, 0x445b1137) reportEvent(0x04000000, 0x445b132a) reportEvent(0x64000000, 0x445b1523) reportEvent(0x44000000, 0x445b1529) reportEvent(0x44000000, 0x445b1547) reportEvent(0x00000000, 0x445b171c) reportEvent(0x40000000, 0x445b1915) reportEvent(0x44000000, 0x445b1932) reportEvent(0x04000000, 0x445b1b0e) reportEvent(0x24000000, 0x445b1b14) reportEvent(0x44000000, 0x445b1d07) reportEvent(0x40000000, 0x445b1d30) reportEvent(0x00000000, 0x445b1f00) reportEvent(0x20000000, 0x445b1f06) reportEvent(0x40000000, 0x445b20f9) reportEvent(0x44000000, 0x445b2116) reportEvent(0x24000000, 0x445b22f7) reportEvent(0x64000000, 0x445b24ea) reportEvent(0x44000000, 0x445b24f0) reportEvent(0x4c000000, 0x445b2574) reportEvent(0x48000000, 0x445b257a) reportEvent(0x08000000, 0x445b26e3) reportEvent(0x20000000, 0x445b2966) reportEvent(0x24000000, 0x445b296c) reportEvent(0x2c000000, 0x445bf87c) reportEvent(0x28000000, 0x445bf882) reportEvent(0x48000000, 0x445bf9ec) reportEvent(0x40000000, 0x445bfc6e) reportEvent(0x04000000, 0x445bfddd) reportEvent(0x24000000, 0x445bfde3) reportEvent(0x64000000, 0x445bffd6) reportEvent(0x44000000, 0x445bffdc) reportEvent(0x48000000, 0x445c0060) reportEvent(0x08000000, 0x445c01cf) reportEvent(0x68000000, 0x445c03c8) reportEvent(0x40000000, 0x445c0452) reportEvent(0x44000000, 0x445c0458) reportEvent(0x04000000, 0x445c05c1) reportEvent(0x24000000, 0x445c05c7) reportEvent(0x44000000, 0x445c07ba) reportEvent(0x48000000, 0x445c0844) reportEvent(0x08000000, 0x445c09b3) reportEvent(0x28000000, 0x445c09b9) reportEvent(0x48000000, 0x445c0bac) reportEvent(0x28000000, 0x445c0da9) reportEvent(0x68000000, 0x445c0f9d) reportEvent(0x48000000, 0x445c0fa3) reportEvent(0x08000000, 0x445c1196) reportEvent(0x28000000, 0x445c119c) reportEvent(0x68000000, 0x445c138f) reportEvent(0x48000000, 0x445c1395) reportEvent(0x08000000, 0x445c1588) reportEvent(0x68000000, 0x445c1781) reportEvent(0x08000000, 0x445c197a) reportEvent(0x28000000, 0x445c1980) reportEvent(0x48000000, 0x445c1b73) reportEvent(0x00000000, 0x445c1d6c) reportEvent(0x20000000, 0x445c1d72) reportEvent(0x40000000, 0x445c1f65) reportEvent(0x44000000, 0x445c1f82) reportEvent(0x4c000000, 0x445c1fee) reportEvent(0x48000000, 0x445c1ff4) reportEvent(0x28000000, 0x445c2162) reportEvent(0x68000000, 0x445c2356) reportEvent(0x48000000, 0x445c235c) reportEvent(0x08000000, 0x445c254f) reportEvent(0x28000000, 0x445c2555) reportEvent(0x68000000, 0x445c2748) reportEvent(0x48000000, 0x445c274e) reportEvent(0x40000000, 0x445c27d2) reportEvent(0x44000000, 0x445c27d8) reportEvent(0x04000000, 0x445c2941) reportEvent(0x64000000, 0x445c2b3a) reportEvent(0x04000000, 0x445c2d33) reportEvent(0x24000000, 0x445c2d39) reportEvent(0x44000000, 0x445c2f2c) reportEvent(0x48000000, 0x445c2fb6) reportEvent(0x08000000, 0x445c3125) reportEvent(0x28000000, 0x445c312b) reportEvent(0x48000000, 0x445c331e) reportEvent(0x28000000, 0x445c351b) reportEvent(0x68000000, 0x445c370f) reportEvent(0x48000000, 0x445c3715) reportEvent(0x08000000, 0x445c3908) reportEvent(0x28000000, 0x445c390e) reportEvent(0x68000000, 0x445c3b01) reportEvent(0x48000000, 0x445c3b07) reportEvent(0x08000000, 0x445c3cfa) reportEvent(0x68000000, 0x445c3ef3) reportEvent(0x40000000, 0x445c3f7d) reportEvent(0x00000000, 0x445c40ec) reportEvent(0x20000000, 0x445c40f2) reportEvent(0x40000000, 0x445c42e5) reportEvent(0x44000000, 0x445c4302) reportEvent(0x48000000, 0x445c436f) reportEvent(0x08000000, 0x445c44de) reportEvent(0x28000000, 0x445c44e4) reportEvent(0x20000000, 0x445c4760) reportEvent(0x24000000, 0x445c4766) reportEvent(0x28000000, 0x445cb9c5) reportEvent(0x48000000, 0x445cbb34) reportEvent(0x40000000, 0x445cbdb6) reportEvent(0x44000000, 0x445cbdbc) reportEvent(0x24000000, 0x445cbf2a) reportEvent(0x64000000, 0x445cc11e) reportEvent(0x44000000, 0x445cc124) reportEvent(0x4c000000, 0x445cc1a8) reportEvent(0x48000000, 0x445cc1ae) reportEvent(0x08000000, 0x445cc317) reportEvent(0x28000000, 0x445cc31d) reportEvent(0x68000000, 0x445cc510) reportEvent(0x48000000, 0x445cc516) reportEvent(0x40000000, 0x445cc59a) reportEvent(0x44000000, 0x445cc5a0) reportEvent(0x04000000, 0x445cc709) reportEvent(0x64000000, 0x445cc902) reportEvent(0x48000000, 0x445cc98c) reportEvent(0x08000000, 0x445ccafb) reportEvent(0x28000000, 0x445ccb01) reportEvent(0x48000000, 0x445cccf4) reportEvent(0x08000000, 0x445cceed) reportEvent(0x28000000, 0x445ccef3) reportEvent(0x48000000, 0x445cd0e6) reportEvent(0x28000000, 0x445cd2e3) reportEvent(0x68000000, 0x445cd4d7) reportEvent(0x48000000, 0x445cd4dd) reportEvent(0x08000000, 0x445cd6d0) reportEvent(0x28000000, 0x445cd6d6) reportEvent(0x68000000, 0x445cd8c9) reportEvent(0x48000000, 0x445cd8cf) reportEvent(0x40000000, 0x445cd953) reportEvent(0x44000000, 0x445cd959) reportEvent(0x04000000, 0x445cdac2) reportEvent(0x64000000, 0x445cdcbb) reportEvent(0x44000000, 0x445cdcde) reportEvent(0x00000000, 0x445cdeb4) reportEvent(0x20000000, 0x445cdeba) reportEvent(0x40000000, 0x445ce0ad) reportEvent(0x00000000, 0x445ce2a6) reportEvent(0x20000000, 0x445ce947) reportEvent(0x40000000, 0x445ceb41) reportEvent(0x00000000, 0x445ced3a) reportEvent(0x20000000, 0x445ced40) reportEvent(0x40000000, 0x445cef33) reportEvent(0x44000000, 0x445cef50) reportEvent(0x04000000, 0x445cf12c) reportEvent(0x24000000, 0x445cf132) reportEvent(0x44000000, 0x445cf325) reportEvent(0x24000000, 0x445cf523) reportEvent(0x64000000, 0x445cf716) reportEvent(0x44000000, 0x445cf71c) reportEvent(0x44000000, 0x445cf73b) reportEvent(0x40000000, 0x445cf741) reportEvent(0x00000000, 0x445cf90f) reportEvent(0x60000000, 0x445cfb08) reportEvent(0x40000000, 0x445cfb0e) reportEvent(0x00000000, 0x445cfd01) reportEvent(0x40000000, 0x445cfefa) reportEvent(0x00000000, 0x445d00f3) reportEvent(0x20000000, 0x445d00f9) reportEvent(0x40000000, 0x445d02ec) reportEvent(0x44000000, 0x445d0309) reportEvent(0x24000000, 0x445d04e9) reportEvent(0x44000000, 0x445d06de) reportEvent(0x4c000000, 0x445d0767) reportEvent(0x48000000, 0x445d076d) reportEvent(0x28000000, 0x445d08dc) reportEvent(0x68000000, 0x445d0acf) reportEvent(0x48000000, 0x445d0ad5) reportEvent(0x40000000, 0x445d0b59) reportEvent(0x00000000, 0x445d0cc8) reportEvent(0x04000000, 0x445d131d) reportEvent(0x44000000, 0x445d1536) reportEvent(0x24000000, 0x445d1734) reportEvent(0x64000000, 0x445d1927) reportEvent(0x44000000, 0x445d192d) reportEvent(0x40000000, 0x4456b03b) reportEvent(0x44000000, 0x445d194c) reportEvent(0x40000000, 0x445d1952) reportEvent(0x00000000, 0x445d1b20) reportEvent(0x60000000, 0x445d1d19) reportEvent(0x40000000, 0x445d1d1f) reportEvent(0x00000000, 0x445d1f12) reportEvent(0x40000000, 0x445d210b) reportEvent(0x44000000, 0x445d2128) reportEvent(0x04000000, 0x445d2304) reportEvent(0x24000000, 0x445d230a) reportEvent(0x44000000, 0x445d24fd) reportEvent(0x04000000, 0x445d26f6) reportEvent(0x24000000, 0x445d26fc) reportEvent(0x44000000, 0x445d28ef) reportEvent(0x24000000, 0x445d2aed) reportEvent(0x64000000, 0x445d2ce0) reportEvent(0x44000000, 0x445d2ce6) reportEvent(0x04000000, 0x445d2ed9) reportEvent(0x64000000, 0x445d30d2) reportEvent(0x44000000, 0x445d30d8) reportEvent(0x48000000, 0x445d315c) reportEvent(0x08000000, 0x445d32cb) reportEvent(0x48000000, 0x445d34c4) reportEvent(0x40000000, 0x445d354e) reportEvent(0x44000000, 0x445d3554) reportEvent(0x04000000, 0x445d36bd) reportEvent(0x60000000, 0x445d3f2a) reportEvent(0x40000000, 0x445d3f30) reportEvent(0x44000000, 0x445d3f47) reportEvent(0x04000000, 0x445d4123) reportEvent(0x44000000, 0x445d431c) reportEvent(0x44000000, 0x445d433f) reportEvent(0x00000000, 0x445d4515) reportEvent(0x20000000, 0x445d451b) reportEvent(0x40000000, 0x445d470e) reportEvent(0x20000000, 0x445d490b) reportEvent(0x40000000, 0x445d4b00) reportEvent(0x20000000, 0x445d4cfe) reportEvent(0x60000000, 0x445d4ef1) reportEvent(0x40000000, 0x445d4ef7) reportEvent(0x00000000, 0x445d50ea) reportEvent(0x60000000, 0x445d52e3) reportEvent(0x40000000, 0x445d52e9) reportEvent(0x00000000, 0x445d54dc) reportEvent(0x40000000, 0x445d56d5) reportEvent(0x44000000, 0x445d56f2) reportEvent(0x04000000, 0x445d58ce) reportEvent(0x24000000, 0x445d58d4) reportEvent(0x44000000, 0x445d5ac7) reportEvent(0x4c000000, 0x445d5b50) reportEvent(0x48000000, 0x445d5b56) reportEvent(0x28000000, 0x445d5cc4) reportEvent(0x48000000, 0x445d5eb9) reportEvent(0x40000000, 0x445d5f42) reportEvent(0x00000000, 0x445d670d) reportEvent(0x00000000, 0x445d6713) reportEvent(0x20000000, 0x445d6729) reportEvent(0x40000000, 0x445d691f) reportEvent(0x44000000, 0x445d693c) reportEvent(0x24000000, 0x445d6b1c) reportEvent(0x44000000, 0x445d6d11) reportEvent(0x20000000, 0x445d6d35) reportEvent(0x40000000, 0x445d6d3b) reportEvent(0x20000000, 0x445d6f0f) reportEvent(0x60000000, 0x445d7102) reportEvent(0x40000000, 0x445d7108) reportEvent(0x00000000, 0x445d72fb) reportEvent(0x60000000, 0x445d74f4) reportEvent(0x40000000, 0x445d74fa) reportEvent(0x00000000, 0x445d76ed) reportEvent(0x40000000, 0x445d78e6) reportEvent(0x44000000, 0x445d7903) reportEvent(0x04000000, 0x445d7adf) reportEvent(0x24000000, 0x445d7ae5) reportEvent(0x44000000, 0x445d7cd8) reportEvent(0x44000000, 0x445d7cfd) reportEvent(0x00000000, 0x445d7ed1) reportEvent(0x20000000, 0x445d7ed7) reportEvent(0x40000000, 0x445d80ca) reportEvent(0x20000000, 0x445d82c8) reportEvent(0x60000000, 0x445d84bb) reportEvent(0x40000000, 0x445d84c1) reportEvent(0x44000000, 0x445d84d8) reportEvent(0x4c000000, 0x445d8545) reportEvent(0x48000000, 0x445d854b) reportEvent(0x08000000, 0x445d86b4) reportEvent(0x68000000, 0x445d88ad) reportEvent(0x48000000, 0x445d88b3) reportEvent(0x40000000, 0x445d8937) reportEvent(0x44000000, 0x445d893d) reportEvent(0x04000000, 0x445d8aa6) reportEvent(0x04000000, 0x445d9106) reportEvent(0x00000000, 0x445d910c) reportEvent(0x20000000, 0x445d9121) reportEvent(0x60000000, 0x445d9313) reportEvent(0x40000000, 0x445d9319) reportEvent(0x00000000, 0x445d950c) reportEvent(0x60000000, 0x445d9705) reportEvent(0x40000000, 0x445d970b) reportEvent(0x44000000, 0x445d9722) reportEvent(0x04000000, 0x445d98fe) reportEvent(0x44000000, 0x445d9af7) reportEvent(0x40000000, 0x445d9b1d) reportEvent(0x00000000, 0x445d9cf0) reportEvent(0x20000000, 0x445d9cf6) reportEvent(0x40000000, 0x445d9ee9) reportEvent(0x44000000, 0x445d9f06) reportEvent(0x24000000, 0x445da0e6) reportEvent(0x44000000, 0x445da2db) reportEvent(0x24000000, 0x445da4d9) reportEvent(0x64000000, 0x445da6cc) reportEvent(0x44000000, 0x445da6d2) reportEvent(0x44000000, 0x445da6f2) reportEvent(0x00000000, 0x445da8c5) reportEvent(0x60000000, 0x445daabe) reportEvent(0x40000000, 0x445daac4) reportEvent(0x44000000, 0x445daadb) reportEvent(0x04000000, 0x445dacb7) reportEvent(0x44000000, 0x445daeb0) reportEvent(0x48000000, 0x445daf3a) reportEvent(0x08000000, 0x445db0a9) reportEvent(0x28000000, 0x445db0af) reportEvent(0x48000000, 0x445db2a2) reportEvent(0x00000000, 0x445db49b) reportEvent(0x20000000, 0x445dbb11) reportEvent(0x40000000, 0x445dbd08) reportEvent(0x44000000, 0x445dbd25) reportEvent(0x04000000, 0x445dbf01) reportEvent(0x24000000, 0x445dbf07) reportEvent(0x44000000, 0x445dc0fa) reportEvent(0x44000000, 0x445dc11d) reportEvent(0x00000000, 0x445dc2f3) reportEvent(0x20000000, 0x445dc2f9) reportEvent(0x40000000, 0x445dc4ec) reportEvent(0x20000000, 0x445dc6ea) reportEvent(0x60000000, 0x445dc8dd) reportEvent(0x40000000, 0x445dc8e3) reportEvent(0x00000000, 0x445dcad6) reportEvent(0x60000000, 0x445dcccf) reportEvent(0x40000000, 0x445dccd5) reportEvent(0x44000000, 0x445dccec) reportEvent(0x04000000, 0x445dcec8) reportEvent(0x44000000, 0x445dd0c1) reportEvent(0x04000000, 0x445dd2ba) reportEvent(0x24000000, 0x445dd2c0) reportEvent(0x44000000, 0x445dd4b3) reportEvent(0x44000000, 0x445dd4d8) reportEvent(0x00000000, 0x445dd6ac) reportEvent(0x20000000, 0x445dd6b2) reportEvent(0x40000000, 0x445dd8a5) reportEvent(0x44000000, 0x445dd8c2) reportEvent(0x4c000000, 0x445dd92e) reportEvent(0x48000000, 0x445dd934) reportEvent(0x28000000, 0x445ddaa3) reportEvent(0x68000000, 0x445ddc96) reportEvent(0x48000000, 0x445ddc9c) reportEvent(0x40000000, 0x445ddd20) reportEvent(0x04000000, 0x445dde8f) reportEvent(0x04000000, 0x445de4ed) reportEvent(0x20000000, 0x445de50a) reportEvent(0x40000000, 0x445de6fd) reportEvent(0x44000000, 0x445de71a) reportEvent(0x24000000, 0x445de8fb) reportEvent(0x64000000, 0x445deaee) reportEvent(0x44000000, 0x445deaf4) reportEvent(0x44000000, 0x445deb14) reportEvent(0x00000000, 0x445dece7) reportEvent(0x60000000, 0x445deee0) reportEvent(0x40000000, 0x445deee6) reportEvent(0x00000000, 0x445df0d9) reportEvent(0x40000000, 0x445df2d2) reportEvent(0x44000000, 0x445df2ef) reportEvent(0x04000000, 0x445df4cb) reportEvent(0x24000000, 0x445df4d1) reportEvent(0x44000000, 0x445df6c4) reportEvent(0x04000000, 0x445df8bd) reportEvent(0x24000000, 0x445df8c3) reportEvent(0x44000000, 0x445dfab6) reportEvent(0x44000000, 0x445dfad9) reportEvent(0x20000000, 0x445dfcb4) reportEvent(0x60000000, 0x445dfea7) reportEvent(0x40000000, 0x445dfead) reportEvent(0x04000000, 0x445e00a0) reportEvent(0x64000000, 0x445e0299) reportEvent(0x44000000, 0x445e029f) reportEvent(0x48000000, 0x445e0323) reportEvent(0x08000000, 0x445e0492) reportEvent(0x48000000, 0x445e068b) reportEvent(0x40000000, 0x445e0715) reportEvent(0x44000000, 0x445e071b) reportEvent(0x04000000, 0x445e0884) reportEvent(0x28000000, 0x4457b1e7) reportEvent(0x00000000, 0x445e0ee0) reportEvent(0x20000000, 0x445e0efa) reportEvent(0x60000000, 0x445e10f1) reportEvent(0x40000000, 0x445e10f7) reportEvent(0x44000000, 0x445e110e) reportEvent(0x04000000, 0x445e12ea) reportEvent(0x44000000, 0x445e14e3) reportEvent(0x24000000, 0x4457c431) reportEvent(0x44000000, 0x445e1508) reportEvent(0x40000000, 0x445e150e) reportEvent(0x00000000, 0x445e16dc) reportEvent(0x20000000, 0x445e16e2) reportEvent(0x40000000, 0x445e18d5) reportEvent(0x20000000, 0x445e1ad2) reportEvent(0x40000000, 0x445e1cc7) reportEvent(0x20000000, 0x445e1ec5) reportEvent(0x60000000, 0x445e20b8) reportEvent(0x40000000, 0x445e20be) reportEvent(0x00000000, 0x445e22b1) reportEvent(0x60000000, 0x445e24aa) reportEvent(0x40000000, 0x445e24b0) reportEvent(0x44000000, 0x445e24c7) reportEvent(0x04000000, 0x445e26a3) reportEvent(0x44000000, 0x445e289c) reportEvent(0x04000000, 0x445e2a95) reportEvent(0x24000000, 0x445e2a9b) reportEvent(0x44000000, 0x445e2c8e) reportEvent(0x4c000000, 0x445e2d17) reportEvent(0x48000000, 0x445e2d1d) reportEvent(0x28000000, 0x445e2e8b) reportEvent(0x48000000, 0x445e3080) reportEvent(0x40000000, 0x445e3109) reportEvent(0x00000000, 0x445e38d9) reportEvent(0x20000000, 0x445e38f3) reportEvent(0x40000000, 0x445e3ae6) reportEvent(0x44000000, 0x445e3b03) reportEvent(0x04000000, 0x445e3cdf) reportEvent(0x24000000, 0x445e3ce5) reportEvent(0x44000000, 0x445e3ed8) reportEvent(0x64000000, 0x445e3efb) reportEvent(0x20000000, 0x445e40d6) reportEvent(0x60000000, 0x445e42c9) reportEvent(0x40000000, 0x445e42cf) reportEvent(0x00000000, 0x445e44c2) reportEvent(0x60000000, 0x445e46bb) reportEvent(0x40000000, 0x445e46c1) reportEvent(0x44000000, 0x445e46d8) reportEvent(0x04000000, 0x445e48b4) reportEvent(0x44000000, 0x445e4aad) reportEvent(0x04000000, 0x445e4ca6) reportEvent(0x24000000, 0x445e4cac) reportEvent(0x44000000, 0x445e4e9f) reportEvent(0x04000000, 0x445e5098) reportEvent(0x24000000, 0x445e509e) reportEvent(0x44000000, 0x445e5291) reportEvent(0x24000000, 0x445e548f) reportEvent(0x64000000, 0x445e5682) reportEvent(0x44000000, 0x445e5688) reportEvent(0x4c000000, 0x445e570c) reportEvent(0x48000000, 0x445e5712) reportEvent(0x08000000, 0x445e587b) reportEvent(0x68000000, 0x445e5a74) reportEvent(0x48000000, 0x445e5a7a) reportEvent(0x40000000, 0x445e5afe) reportEvent(0x44000000, 0x445e5b04) reportEvent(0x04000000, 0x445e5c6d) reportEvent(0x00000000, 0x44581422) reportEvent(0x00000000, 0x445e62cb) reportEvent(0x20000000, 0x445e62e5) reportEvent(0x60000000, 0x445e64da) reportEvent(0x40000000, 0x445e64e0) reportEvent(0x44000000, 0x445e64f7) reportEvent(0x04000000, 0x445e66d3) reportEvent(0x64000000, 0x445e68cc) reportEvent(0x44000000, 0x445e68d2) reportEvent(0x44000000, 0x445e68ef) reportEvent(0x00000000, 0x445e6ac5) reportEvent(0x40000000, 0x445e6cbe) reportEvent(0x00000000, 0x445e6eb7) reportEvent(0x20000000, 0x445e6ebd) reportEvent(0x40000000, 0x445e70b0) reportEvent(0x44000000, 0x445e70cd) reportEvent(0x24000000, 0x445e72ad) reportEvent(0x44000000, 0x445e74a2) reportEvent(0x24000000, 0x445e76a0) reportEvent(0x64000000, 0x445e7893) reportEvent(0x44000000, 0x445e7899) reportEvent(0x44000000, 0x445e78b9) reportEvent(0x40000000, 0x445e78bf) reportEvent(0x00000000, 0x445e7a8c) reportEvent(0x60000000, 0x445e7c85) reportEvent(0x40000000, 0x445e7c8b) reportEvent(0x44000000, 0x445e7ca2) reportEvent(0x04000000, 0x445e7e7e) reportEvent(0x44000000, 0x445e8077) reportEvent(0x48000000, 0x445e8101) reportEvent(0x08000000, 0x445e8270) reportEvent(0x28000000, 0x445e8276) reportEvent(0x48000000, 0x445e8469) reportEvent(0x44000000, 0x445e84f7) reportEvent(0x00000000, 0x445e8cc2) reportEvent(0x00000000, 0x445e8cc8) reportEvent(0x40000000, 0x445e8ecf) reportEvent(0x44000000, 0x445e8eec) reportEvent(0x04000000, 0x445e90c8) reportEvent(0x24000000, 0x445e90ce) reportEvent(0x44000000, 0x445e92c1) reportEvent(0x44000000, 0x445e92e6) reportEvent(0x20000000, 0x445e94be) reportEvent(0x40000000, 0x445e96b3) reportEvent(0x20000000, 0x445e98b1) reportEvent(0x60000000, 0x445e9aa4) reportEvent(0x40000000, 0x445e9aaa) reportEvent(0x04000000, 0x445e9c9d) reportEvent(0x64000000, 0x445e9e96) reportEvent(0x44000000, 0x445e9e9c) reportEvent(0x04000000, 0x445ea08f) reportEvent(0x44000000, 0x445ea288) reportEvent(0x48000000, 0x4458584a) reportEvent(0x00000000, 0x445ea481) reportEvent(0x20000000, 0x445ea487) reportEvent(0x40000000, 0x445ea67a) reportEvent(0x44000000, 0x445ea697) reportEvent(0x04000000, 0x445ea873) reportEvent(0x24000000, 0x445ea879) reportEvent(0x44000000, 0x445eaa6c) reportEvent(0x4c000000, 0x445eaaf5) reportEvent(0x48000000, 0x445eaafb) reportEvent(0x28000000, 0x445eac6a) reportEvent(0x68000000, 0x445eae5d) reportEvent(0x48000000, 0x445eae63) reportEvent(0x40000000, 0x445eaee7) reportEvent(0x04000000, 0x445eb056) reportEvent(0x04000000, 0x445eb6b3) reportEvent(0x20000000, 0x445eb6d0) reportEvent(0x40000000, 0x445eb8c4) reportEvent(0x44000000, 0x445eb8e1) reportEvent(0x24000000, 0x445ebac2) reportEvent(0x64000000, 0x445ebcb5) reportEvent(0x44000000, 0x445ebcbb) reportEvent(0x44000000, 0x445ebcdb) reportEvent(0x00000000, 0x445ebeae) reportEvent(0x60000000, 0x445ec0a7) reportEvent(0x40000000, 0x445ec0ad) reportEvent(0x44000000, 0x445ec0c4) reportEvent(0x04000000, 0x445ec2a0) reportEvent(0x44000000, 0x445ec499) reportEvent(0x44000000, 0x445ec4bc) reportEvent(0x00000000, 0x445ec692) reportEvent(0x20000000, 0x445ec698) reportEvent(0x40000000, 0x445ec88b) reportEvent(0x20000000, 0x445eca88) reportEvent(0x40000000, 0x445ecc7d) reportEvent(0x24000000, 0x445ece7b) reportEvent(0x64000000, 0x445ed06e) reportEvent(0x44000000, 0x445ed074) reportEvent(0x04000000, 0x445ed267) reportEvent(0x64000000, 0x445ed460) reportEvent(0x44000000, 0x445ed466) reportEvent(0x48000000, 0x445ed4ea) reportEvent(0x08000000, 0x445ed659) reportEvent(0x48000000, 0x445ed852) reportEvent(0x40000000, 0x445ed8dc) reportEvent(0x44000000, 0x445ed8e2) reportEvent(0x04000000, 0x445eda4b) reportEvent(0x04000000, 0x445ee0a6) reportEvent(0x00000000, 0x445ee0ac) reportEvent(0x60000000, 0x445ee2b8) reportEvent(0x40000000, 0x445ee2be) reportEvent(0x00000000, 0x445ee4b1) reportEvent(0x40000000, 0x445ee6aa) reportEvent(0x44000000, 0x445ee6c7) reportEvent(0x04000000, 0x445ee8a3) reportEvent(0x24000000, 0x445ee8a9) reportEvent(0x44000000, 0x445eea9c) reportEvent(0x24000000, 0x445eec99) reportEvent(0x44000000, 0x445eee8e) reportEvent(0x44000000, 0x445eeeb1) reportEvent(0x20000000, 0x445ef08c) reportEvent(0x60000000, 0x445ef27f) reportEvent(0x40000000, 0x445ef285) reportEvent(0x00000000, 0x445ef478) reportEvent(0x60000000, 0x445ef671) reportEvent(0x40000000, 0x445ef677) reportEvent(0x00000000, 0x445ef86a) reportEvent(0x40000000, 0x445efa63) reportEvent(0x44000000, 0x445efa80) reportEvent(0x04000000, 0x445efc5c) reportEvent(0x24000000, 0x445efc62) reportEvent(0x44000000, 0x445efe55) reportEvent(0x4c000000, 0x445efede) reportEvent(0x48000000, 0x445efee4) reportEvent(0x08000000, 0x445f004e) reportEvent(0x28000000, 0x445f0054) reportEvent(0x48000000, 0x445f0247) reportEvent(0x40000000, 0x445f02d0) reportEvent(0x20000000, 0x445f0aba) reportEvent(0x40000000, 0x445f0cad) reportEvent(0x00000000, 0x445f0ea6) reportEvent(0x20000000, 0x445f0eac) reportEvent(0x40000000, 0x445f109f) reportEvent(0x44000000, 0x445f10bc) reportEvent(0x24000000, 0x445f129d) reportEvent(0x64000000, 0x445f1490) reportEvent(0x44000000, 0x445f1496) reportEvent(0x64000000, 0x4458d598) reportEvent(0x44000000, 0x445f14b5) reportEvent(0x40000000, 0x445f14bb) reportEvent(0x00000000, 0x445f1689) reportEvent(0x60000000, 0x445f1882) reportEvent(0x40000000, 0x445f1888) reportEvent(0x44000000, 0x445f189f) reportEvent(0x04000000, 0x445f1a7b) reportEvent(0x44000000, 0x445f1c74) reportEvent(0x04000000, 0x445f1e6d) reportEvent(0x24000000, 0x445f1e73) reportEvent(0x44000000, 0x445f2066) reportEvent(0x44000000, 0x445f2089) ================================================ FILE: examples/fmcomms1/testfmcomms1.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "dmaManager.h" #include "FMComms1Request.h" #include "FMComms1Indication.h" #include "BlueScopeEventPIORequest.h" #include "BlueScopeEventPIOIndication.h" #include "fmci2c.h" sem_t read_sem; sem_t write_sem; sem_t cv_sem; int readBurstLen = 16; int writeBurstLen = 16; #define WHERE(x) fprintf(stdout, "at %s:%d\n",__FILE__, __LINE__) #ifndef SIMULATION int numWords = 0x4096; // make sure to allocate at least one entry of each size #else int numWords = 0x4096; #endif size_t test_sz = numWords*sizeof(unsigned int); size_t alloc_sz = test_sz; class FMComms1Indication : public FMComms1IndicationWrapper { public: FMComms1Indication(unsigned int id) : FMComms1IndicationWrapper(id){} virtual void readStatus(unsigned iterCount, unsigned running){ fprintf(stdout, "read %d %d\n", iterCount, running); sem_post(&read_sem); } virtual void writeStatus(unsigned iterCount, unsigned running){ fprintf(stdout, "write %d %d\n", iterCount, running); sem_post(&write_sem); } }; #define NUMEVENTS 4096 uint32_t counter_value = 0; uint32_t events[NUMEVENTS]; uint32_t timestamps[NUMEVENTS]; int eventcount = 0; class BlueScopeEventPIOIndication : public BlueScopeEventPIOIndicationWrapper { public: BlueScopeEventPIOIndication(unsigned int id) : BlueScopeEventPIOIndicationWrapper(id){} virtual void reportEvent(uint32_t v, uint32_t timestamp ){ if (eventcount < NUMEVENTS) { events[eventcount] = v; timestamps[eventcount] = timestamp; eventcount += 1; } } virtual void counterValue(uint32_t v){ counter_value = v; sem_post(&cv_sem); fprintf(stdout, "BlueScopeEventPIO::counterValue value=%u\n", v); } }; int main(int argc, const char **argv) { int i; int srcAlloc; int dstAlloc; unsigned int *srcBuffer = 0; unsigned int *dstBuffer = 0; FMComms1RequestProxy *device = 0; FMComms1Indication *deviceIndication = 0; BlueScopeEventPIORequestProxy *bluescope = 0; BlueScopeEventPIOIndication *bluescopeIndication = 0; fprintf(stdout, "Main::%s %s\n", __DATE__, __TIME__); if(sem_init(&cv_sem, 1, 0)){ fprintf(stdout, "failed to init cv_sem\n"); exit(1); } if(sem_init(&read_sem, 1, 0)){ fprintf(stdout, "failed to init read_sem\n"); exit(1); } if(sem_init(&write_sem, 1, 0)){ fprintf(stdout, "failed to init write_sem\n"); exit(1); } device = new FMComms1RequestProxy(IfcNames_FMComms1Request); DmaManager *dma = platformInit(); deviceIndication = new FMComms1Indication(IfcNames_FMComms1Indication); bluescope = new BlueScopeEventPIORequestProxy(IfcNames_BlueScopeEventPIORequest); bluescopeIndication = new BlueScopeEventPIOIndication(IfcNames_BlueScopeEventPIOIndication); fprintf(stdout, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); if ((char *) srcBuffer == MAP_FAILED) perror("srcBuffer mmap failed"); assert ((char *) srcBuffer != MAP_FAILED); dstAlloc = portalAlloc(alloc_sz, 0); dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); if ((char *) dstBuffer == MAP_FAILED) perror("dstBuffer mmap failed"); assert ((char *) dstBuffer != MAP_FAILED); int status; status = setClockFrequency(0, 100000000, 0); /* FMComms1 refclk should be 30 MHz */ status = setClockFrequency(1, 30000000, 0); portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stdout, "Main::flush and invalidate complete\n"); bluescope->doReset(); WHERE(); bluescope->setTriggerMask (0xFFFFFFFF); WHERE(); bluescope->getCounterValue(); WHERE(); bluescope->enableIndications(1); WHERE(); sem_wait(&cv_sem); fprintf(stdout, "Main::initial BlueScopeEventPIO counterValue: %d\n", counter_value); device->getReadStatus(); device->getWriteStatus(); sem_wait(&read_sem); sem_wait(&write_sem); fprintf(stdout, "Main::after getStateDbg\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); fprintf(stdout, "ref_srcAlloc=%d\n", ref_srcAlloc); unsigned int ref_dstAlloc = dma->reference(dstAlloc); fprintf(stdout, "ref_dstAlloc=%d\n", ref_dstAlloc); fprintf(stdout, "Main::starting read %08x\n", numWords); device->startRead(ref_srcAlloc, numWords, readBurstLen, 1); device->startWrite(ref_dstAlloc, numWords, writeBurstLen, 1); sem_wait(&read_sem); sleep(5); device->getReadStatus(); device->getWriteStatus(); sem_wait(&read_sem); sem_wait(&write_sem); sleep(5); fprintf(stdout, "Main::stopping reads\n"); device->startRead(ref_srcAlloc, numWords, readBurstLen, 0); fprintf(stdout, "Main::stopping writes\n"); device->startWrite(ref_dstAlloc, numWords, writeBurstLen, 0); device->getReadStatus(); device->getWriteStatus(); sem_wait(&read_sem); sem_wait(&write_sem); testi2c("/dev/i2c-1", 0x58); bluescope->getCounterValue(); fprintf(stdout, "Main::getCounter\n"); sem_wait(&cv_sem); fprintf(stdout, "Main::final BlueScopeEventPIO counterValue: %d\n", counter_value); fprintf(stdout, "received %d events\n", eventcount); for (i = 0; i < eventcount; i += 1) { fprintf(stdout, "reportEvent(0x%08x, 0x%08x)\n", events[i], timestamps[i]); } exit(0); } ================================================ FILE: examples/fmcomms1/testi2c.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* copied from jca's i2chdmi.h */ #include #include #include #include #include "/usr/include/linux/i2c.h" #include "/usr/include/linux/i2c-dev.h" #include #include #include int fmcomms1_read_eeprom(int fd, int device, unsigned char *datap, int size) { int status; int i; struct i2c_msg msgs[2]; unsigned char command[2] = { 0, 0 }; struct i2c_rdwr_ioctl_data arg; msgs[0].addr = device; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = &command[0]; msgs[1].addr = device; msgs[1].flags = I2C_M_RD; msgs[1].len = 1; msgs[1].buf = datap; arg.msgs = msgs; arg.nmsgs = 1; datap[0] = 1; status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stderr, "[%s:%d]: ioctl I2C_RW write status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } msgs[0] = msgs[1]; for (i = 0; i < 16; i += 1) { msgs[0].buf = &datap[i]; status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stderr, "[%s:%d]: loop %d ioctl I2C_RW read status=%d errno=%d [%]\n", __FILE__, __LINE__, i, status, errno, strerror(errno)); } } return status; } int fmcomms1_get_version(int fd, int device, unsigned char *datap, int size) { int status; struct i2c_msg msgs[2]; unsigned char command = 1; struct i2c_rdwr_ioctl_data arg; msgs[0].addr = device; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = &command; msgs[1].addr = device; msgs[1].flags = I2C_M_RD | I2C_M_RECV_LEN; msgs[1].len = 33; msgs[1].buf = datap; arg.msgs = msgs; arg.nmsgs = 2; datap[0] = 1; status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stderr, "[%s:%d]: ioctl I2C_RW write status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } msgs[0] = msgs[1]; status = ioctl(fd, I2C_RDWR, &arg); if (status != 0) { fprintf(stderr, "[%s:%d]: ioctl I2C_RW read status=%d errno=%d [%s]\n", __FILE__, __LINE__, status, errno, strerror(errno)); } return status; } unsigned char version_data[128]; int main(int argc, char *argv[]) { int fd; int i; int res; printf("argv[1] is %s, argv[2] is 0x%02lx\n", argv[1], strtol(argv[2], NULL, 0)); fd = open(argv[1], O_RDWR); if (fd < 0) { printf("[%s:%d] open failed\n", __FILE__, __LINE__); exit(1); } // start version query memset(version_data, 0, 128); res = fmcomms1_read_eeprom(fd, 0x50, version_data, 128); printf ("getversion result %d\n", res); for (i = 0; i < 16; i += 1) { if ((i != 0) && ((i % 16) == 0)) printf("\n"); printf(" %2x", version_data[i]); } printf("\n"); memset(version_data, 0, 128); res = fmcomms1_get_version(fd, (int) strtol(argv[2], NULL, 0), version_data, 128); printf ("getversion result %d\n", res); for (i = 0; i < 32; i += 1) { if ((i != 0) && ((i % 16) == 0)) printf("\n"); printf(" %2x", version_data[i]); } printf("\n"); } ================================================ FILE: examples/gyro_simple/Makefile ================================================ CONNECTALDIR ?= ../.. S2H_INTERFACES = GyroCtrlRequest:GyroController.req H2S_INTERFACES = GyroController:GyroCtrlIndication MEM_WRITE_INTERFACES = cons\(lGyroController.dmaClient,nil\) INTERFACES = GyroSampleStream AUTOTOP = --interface pins:GyroController.pins --portname IfcNames_GyroSampleStream ZBR = $(CONNECTALDIR)/lib/zedboard_robot BSVFILES = $(ZBR)/bsv/GyroController.bsv CPPFILES = test_gyro.cpp $(ZBR)/cpp/read_buffer.cpp PIN_TYPE = GyroSimplePins PIN_TYPE_INCLUDE = GyroController PINOUT_FILE = pinout.json PIN_BINDINGS = pmod:pmodd include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/gyro_simple/clock.tcl ================================================ ## disconnect unused CLK and RST ports inserted by bsc foreach {pat} {CLK_GATE_* CLK_clock} { foreach {net} [get_nets $pat] { puts "disconnecting net $net" disconnect_net -net $net -objects [get_pins -of_objects $net] } } ================================================ FILE: examples/gyro_simple/gyro.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #define WHO_AM_I 0x0F #define CTRL_REG1 0x20 #define CTRL_REG2 0x21 #define CTRL_REG3 0x22 #define CTRL_REG4 0x23 #define CTRL_REG5 0x24 #define REFERENCE 0x25 #define OUT_TEMP 0x26 #define STATUS_REG 0x27 #define OUT_X_L 0x28 #define OUT_X_H 0x29 #define OUT_Y_L 0x2A #define OUT_Y_H 0x2B #define OUT_Z_L 0x2C #define OUT_Z_H 0x2D #define FIFO_CTRL_REG 0x2E #define FIFO_SRC_REG 0x2F #define INT1_CFG 0x30 #define INT1_SRC 0x31 #define INT1_THS_XH 0x32 #define INT1_THS_XL 0x33 #define INT1_THS_YH 0x34 #define INT1_THS_YL 0x35 #define INT1_THS_ZH 0x36 #define INT1_THS_ZL 0x37 #define INT1_DURATION 0x38 ================================================ FILE: examples/gyro_simple/gyroVisualize.py ================================================ ## ## Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, copy, ## modify, merge, publish, distribute, sublicense, and/or sell copies ## of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## The above copyright notice and this permission notice shall be ## included in all copies or substantial portions of the Software. ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ## BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ## ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ## SOFTWARE. from visual import * class gv: def __init__(self): self.roll_bar = [] self.pitch_bar = [] self.main_window=display(title="Board Orientation", forward = (1,0,-0.25), width=500, up=(0,0,1), y=200, range=(1.2,1.2,1.2)) self.aux_window = display(title='Roll/Pitch/Yaw',x=0, y=0, width=500, height=200,center=(0,0,0), background=(0,0,0), range=(1,1,1)) self.aux_window.select() self.roll_bar.append(cylinder(pos=(-0.4,0,0),axis=(0.2,0,0),radius=0.01,color=color.red)) self.roll_bar.append(cylinder(pos=(-0.4,0,0),axis=(-0.2,0,0),radius=0.01,color=color.red)) self.pitch_bar.append(cylinder(pos=(0.1,0,0),axis=(0.2,0,0),radius=0.01,color=color.green)) self.pitch_bar.append(cylinder(pos=(0.1,0,0),axis=(-0.2,0,0),radius=0.01,color=color.green)) self.yaw_arrow = arrow(pos=(0.6,0,0),color=color.cyan,axis=(-0.2,0,0), shaftwidth=0.02, fixedwidth=1) label(pos=(-0.4,0.3,0),text="Roll",box=0,opacity=0) label(pos=(0.1,0.3,0),text="Pitch",box=0,opacity=0) label(pos=(0.55,0.3,0),text="Yaw",box=0,opacity=0) label(pos=(0.6,0.22,0),height=8,text="N",box=0,opacity=0,color=color.yellow) label(pos=(0.6,-0.22,0),height=8,text="S",box=0,opacity=0,color=color.yellow) label(pos=(0.38,0,0),height=8,text="W",box=0,opacity=0,color=color.yellow) label(pos=(0.82,0,0),height=8,text="E",box=0,opacity=0,color=color.yellow) self.main_window.select() arrow(color=color.green,axis=(1,0,0), shaftwidth=0.02, fixedwidth=1) arrow(color=color.green,axis=(0,-1,0), shaftwidth=0.02 , fixedwidth=1) arrow(color=color.green,axis=(0,0,-1), shaftwidth=0.02, fixedwidth=1) label(pos=(0,0,0.8),text="Board Orientation",box=0,opacity=0) label(pos=(1,0,0),text="X",box=0,opacity=0) label(pos=(0,-1,0),text="Y",box=0,opacity=0) label(pos=(0,0,-1),text="Z",box=0,opacity=0) self.platform = box(length=1, height=0.05, width=1, color=color.red) self.p_line = box(length=1,height=0.08,width=0.1,color=color.yellow) self.plat_arrow = arrow(color=color.green,axis=(1,0,0), shaftwidth=0.06, fixedwidth=1) def update(self, direction, sampling_period): (roll,pitch,yaw) = direction axis=(cos(pitch)*cos(yaw),-cos(pitch)*sin(yaw),sin(pitch)) up=(sin(roll)*sin(yaw)+cos(roll)*sin(pitch)*cos(yaw),sin(roll)*cos(yaw)-cos(roll)*sin(pitch)*sin(yaw),-cos(roll)*cos(pitch)) self.platform.axis=axis self.platform.up=up self.platform.length=1.0 self.platform.width=0.65 self.plat_arrow.axis=axis self.plat_arrow.up=up self.plat_arrow.length=0.8 self.p_line.axis=axis self.p_line.up=up self.roll_bar[0].axis=(-0.2*cos(roll),0.2*sin(roll),0) self.roll_bar[1].axis=(0.2*cos(roll),-0.2*sin(roll),0) self.pitch_bar[0].axis=(-0.2*cos(pitch),0.2*sin(pitch),0) self.pitch_bar[1].axis=(0.2*cos(pitch),-0.2*sin(pitch),0) self.yaw_arrow.axis=(0.2*sin(yaw),0.2*cos(yaw),0) rate(sampling_period) if __name__ == "__main__": v = gv() for i in range(1,1000): v.update(i,i,i) time.sleep(0.01) ================================================ FILE: examples/gyro_simple/gyro_simple.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include #include #include "GyroCtrlRequest.h" #include "GyroCtrlIndication.h" #include "GeneratedTypes.h" #include "GyroSampleStream.h" #include "gyro.h" class GyroCtrlIndication : public GyroCtrlIndicationWrapper { public: sem_t status_sem; sem_t read_sem; sem_t write_sem; uint32_t read_reg_val; uint32_t write_addr; int write_wrap_cnt; GyroCtrlIndication(int id) : GyroCtrlIndicationWrapper(id) { sem_init(&status_sem,1,0); sem_init(&read_sem,1,0); sem_init(&write_sem,1,0); write_addr = 0; write_wrap_cnt = 0; } virtual void read_reg_resp ( const uint8_t v){ //fprintf(stderr, "GyroCtrlIndication::read_reg_resp(v=%x)\n", v); read_reg_val = v; sem_post(&read_sem); } virtual void write_reg_resp ( const uint8_t v){ //fprintf(stderr, "GyroCtrlIndication::write_reg_resp(v=%x)\n", v); sem_post(&write_sem); } virtual void memwrite_status(const uint32_t addr, const uint32_t wrap_cnt){ //fprintf(stderr, "GyroCtrlIndication::memwrite_status(addr=%08x, wrap_cnt=%d)\n", addr, wrap_cnt); write_addr = addr; write_wrap_cnt = wrap_cnt; sem_post(&status_sem); } }; void read_reg(GyroCtrlIndication *ind, GyroCtrlRequestProxy *device, unsigned short addr) { device->read_reg_req(addr); sem_wait(&(ind->read_sem)); } void write_reg(GyroCtrlIndication *ind, GyroCtrlRequestProxy *device, unsigned short addr, unsigned short val) { device->write_reg_req(addr,val); sem_wait(&(ind->write_sem)); } void set_en(GyroCtrlIndication *ind, GyroCtrlRequestProxy *device, unsigned int v) { device->set_en(v); if(!v) sem_wait(&(ind->status_sem)); } int send(GyroSampleStreamProxy *gssp, void*b, int len, int drop, int spew, int send) { int16_t *ss = (int16_t*)b; int i = 3+drop; while(i < len/2){ if (send) gssp->sample(ss[(i-3)+0], ss[(i-3)+1], ss[(i-3)+2]); if (spew) fprintf(stderr, "%8d %8d %8d\n", ss[(i-3)+0], ss[(i-3)+1], ss[(i-3)+2]); i+=3; } int missing = i-(len/2); return missing; } //#define HIGH_SAMPLE_RATE void setup_registers(GyroCtrlIndication *ind, GyroCtrlRequestProxy *device, int ref_dstAlloc, int alloc_sz) { #ifdef HIGH_SAMPLE_RATE write_reg(ind,device, CTRL_REG1, 0b11001111); // ODR:800Hz Cutoff:30 #else write_reg(ind,device, CTRL_REG1, 0b00001111); // ODR:100Hz Cutoff:12.5 #endif write_reg(ind,device, CTRL_REG2, 0b00000000); write_reg(ind,device, CTRL_REG3, 0b00000000); write_reg(ind,device, CTRL_REG4, 0b10100000); // BDU:1, Range:2000 dps write_reg(ind,device, CTRL_REG5, 0b00000000); // make sure the memwrite is disabled before we start set_en(ind,device,0); #ifdef SIMULATION device->sample(ref_dstAlloc, alloc_sz, 10); #else #ifdef HIGH_SAMPLE_RATE // sampling rate of 800Hz. Model running at 100 MHz. device->sample(ref_dstAlloc, alloc_sz, 1000000/8); #else // sampling rate of 100Hz. Model running at 100 MHz. device->sample(ref_dstAlloc, alloc_sz, 1000000); #endif #endif } ================================================ FILE: examples/gyro_simple/pinout.json ================================================ { "spi_mosi": { "PIO_DIRECTION": "OUTPUT", "pmod": "J2" }, "spi_miso_v": { "PIO_DIRECTION": "INPUT", "pmod": "J3" }, "spi_sel_n": { "PIO_DIRECTION": "OUTPUT", "pmod": "J1" }, "CLK_spi_clock": { "PIO_DIRECTION": "OUTPUT", "pmod": "J4" }, "leds_leds[0]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L0" }, "leds_leds[1]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L1" }, "leds_leds[2]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L2" }, "leds_leds[3]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L3" }, "leds_leds[4]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L4" }, "leds_leds[5]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L5" }, "leds_leds[6]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L6" }, "leds_leds[7]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L7" } } ================================================ FILE: examples/gyro_simple/test_gyro.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include "dmaManager.h" #include "sock_utils.h" #include "GyroSampleStream.h" #include "gyro_simple.h" #include "read_buffer.h" static int spew = 1; static int host_sw = 1; #ifdef SIMULATION static int alloc_sz = 1<<7; #else static int alloc_sz = 1<<10; #endif int main(int argc, const char **argv) { // this is because I don't want the server to abort when the client goes offline signal(SIGPIPE, SIG_IGN); GyroCtrlIndication *ind = new GyroCtrlIndication(IfcNames_GyroCtrlIndicationH2S); GyroCtrlRequestProxy *device = new GyroCtrlRequestProxy(IfcNames_GyroCtrlRequestS2H); DmaManager *dma = platformInit(); PortalSocketParam param; getaddrinfo("0.0.0.0", "5000", NULL, ¶m.addr); GyroSampleStreamProxy *gssp = new GyroSampleStreamProxy(IfcNames_GyroSampleStream, &transportSocketResp, ¶m, &GyroSampleStreamJsonProxyReq, 1000); int dstAlloc = portalAlloc(alloc_sz, 0); char *dstBuffer = (char *)portalMmap(dstAlloc, alloc_sz); unsigned int ref_dstAlloc = dma->reference(dstAlloc); long req_freq = 100000000; // 100 mHz long freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); char* snapshot = (char*)malloc(alloc_sz); reader* r = new reader(); // setup gyro registers and dma infra setup_registers(ind,device, ref_dstAlloc, alloc_sz); int drop = 0; while(true){ #ifdef SIMULATION sleep(5); #else usleep(80000); #endif set_en(ind,device, 0); int datalen = r->read_circ_buff(alloc_sz, ref_dstAlloc, dstAlloc, dstBuffer, snapshot, ind->write_addr, ind->write_wrap_cnt); set_en(ind,device, 2); drop = send(gssp, snapshot, datalen, drop, spew, host_sw); } } ================================================ FILE: examples/gyro_simple/test_gyro.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import sys import socket import struct import time import ctypes import os import numpy import pandas as pd import math from gyroVisualize import * import argparse import json sys.path.append(os.path.abspath('../../scripts')) import portalJson class gyro_stream: def __init__(self, lpf=False): self.times = 0 self.tails = [[],[],[]] self.means = [0,0,0] self.calibrate_window = 0 self.sample_freq_hz = 100 self.lpf = lpf def radians(self, sample): # sensitivity of sample is 70 milli-degrees-per-second/digit. # multiply sample by 70 to get milli-degrees-per-second # divide by sample_freq_hz to get milli-degrees # divide by 1000 to get degrees return (math.radians(sample[0]*70.0/self.sample_freq_hz/1000.0), math.radians(-sample[1]*70.0/self.sample_freq_hz/1000.0), math.radians(-sample[2]*70.0/self.sample_freq_hz/1000.0)) def next_samples(self,samples): self.times = self.times+1 octave_length = 20 window_sz = 10 rv = [] write_octave = True if (write_octave): octave_file = open("x.m", "w"); octave_file.write("#! /usr/bin/octave --persist \nv = ["); num_samples = len(samples) if (self.lpf): x = numpy.concatenate((self.tails[0],samples[0::3]),0) y = numpy.concatenate((self.tails[1],samples[1::3]),0) z = numpy.concatenate((self.tails[2],samples[2::3]),0) xs = pd.rolling_mean(pd.Series(x),window=window_sz)[window_sz:] ys = pd.rolling_mean(pd.Series(y),window=window_sz)[window_sz:] zs = pd.rolling_mean(pd.Series(z),window=window_sz)[window_sz:] self.tails[0] = x[-window_sz:] self.tails[1] = y[-window_sz:] self.tails[2] = z[-window_sz:] else: xs = samples[0::3] ys = samples[1::3] zs = samples[2::3] if (self.times <= octave_length): print(self.times) for x,y,z in zip(xs,ys,zs): #print "%d %d %d" % (x,y,z) if (self.times <= octave_length): self.calibrate_window += 1 self.means[0] += x; self.means[1] += y; self.means[2] += z; if (write_octave): octave_file.write("%d, %d, %d; \n" % (x,y,z)); else: pos = (x-self.means[0],y-self.means[1],z-self.means[2]) rv.append(self.radians(pos)) #print "%d %d %d" %(pos[0],pos[1],pos[2]) if (self.times == octave_length): for i in range (0,len(self.means)): self.means[i] = self.means[i]/self.calibrate_window print("x_mean:%d y_mean:%d, z_mean:%d\n" % (self.means[0],self.means[1],self.means[2])) if (write_octave): octave_file.write("];\n"); octave_file.write("plot(v(:,1),color=\"r\");\n"); octave_file.write("hold on;\n"); octave_file.write("plot(v(:,2),color=\"g\");\n"); octave_file.write("plot(v(:,3),color=\"b\");\n"); octave_file.close() print("done writing octave_file") if (self.times > octave_length): return rv smoothe = False if __name__ == "__main__": argparser = argparse.ArgumentParser('Display gyroscope data') argparser.add_argument('-v', '--visualize', help='Display gyro orientation in 3D rendering', default=False, action='store_true') argparser.add_argument('-a', '--address', help='Device address', default=None) options = argparser.parse_args() spew = not options.visualize; visualize = options.visualize; print(options.address) if not options.address: options.address = os.environ['RUNPARAM'] if (visualize): v = gv() gs = gyro_stream() jp = portalJson.portal(options.address, 5000) summ = [0,0,0] try: while (True): samples = [] for i in range(0,48): d = json.loads(jp.recv()) samples.append(d['x']) samples.append(d['y']) samples.append(d['z']) poss = gs.next_samples(samples) if poss is not None: for pos in poss: if (spew): print("%f %f %f" % (pos[0],pos[1],pos[2])) summ[0] = summ[0]+pos[0] summ[1] = summ[1]+pos[1] summ[2] = summ[2]+pos[2] if (visualize and smoothe): v.update(summ, gs.sample_freq_hz) time.sleep(1/gs.sample_freq_hz) if (visualize and (not smoothe)): v.update(summ, gs.sample_freq_hz) if (not spew): print("%f %f %f" % (summ[0], summ[1], summ[2])) except KeyboardInterrupt: jp.shutdown() sys.exit() ================================================ FILE: examples/gyrospi/Makefile ================================================ CONNECTALDIR ?= ../.. S2H_INTERFACES = STestRequest:STest.request H2S_INTERFACES = STest:STestIndication BSVFILES = STest.bsv CPPFILES = testspi.cpp PIN_TYPE = STestPins PIN_TYPE_INCLUDE = STest PINOUT_FILE = pinout.json PIN_BINDINGS = pmod:pmodd AUTOTOP = --interface pins:STest.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/gyrospi/STest.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalSpi::*; import GetPut::*; interface STestRequest; method Action request(Bit#(16) addr_data); endinterface interface STestIndication; method Action result(Bit#(16) val); endinterface interface STestPins; interface SpiMasterPins#(1) spi; endinterface interface STest; interface STestRequest request; interface STestPins pins; endinterface module mkSTest#(STestIndication indication)(STest); SPIMaster#(Bit#(16),1) spiMaster <- mkSPIMaster(1000, True); Reg#(Bool) inUse <- mkReg(False); rule read_reg_resp; let rv <- spiMaster.response[0].get; indication.result(rv); inUse <= False; endrule interface STestRequest request; method Action request(Bit#(16) addr_data) if (!inUse); spiMaster.request[0].put(addr_data); inUse <= True; endmethod endinterface interface STestPins pins; interface SpiMasterPins spi = spiMaster.pins; endinterface endmodule ================================================ FILE: examples/gyrospi/gyro.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #define WHO_AM_I 0x0F #define CTRL_REG1 0x20 #define CTRL_REG2 0x21 #define CTRL_REG3 0x22 #define CTRL_REG4 0x23 #define CTRL_REG5 0x24 #define REFERENCE 0x25 #define OUT_TEMP 0x26 #define STATUS_REG 0x27 #define OUT_X_L 0x28 #define OUT_X_H 0x29 #define OUT_Y_L 0x2A #define OUT_Y_H 0x2B #define OUT_Z_L 0x2C #define OUT_Z_H 0x2D #define FIFO_CTRL_REG 0x2E #define FIFO_SRC_REG 0x2F #define INT1_CFG 0x30 #define INT1_SRC 0x31 #define INT1_THS_XH 0x32 #define INT1_THS_XL 0x33 #define INT1_THS_YH 0x34 #define INT1_THS_YL 0x35 #define INT1_THS_ZH 0x36 #define INT1_THS_ZL 0x37 #define INT1_DURATION 0x38 ================================================ FILE: examples/gyrospi/pinout.json ================================================ { "spi_sel_n": { "PIO_DIRECTION": "OUTPUT", "pmod": "J1" }, "spi_mosi": { "PIO_DIRECTION": "OUTPUT", "pmod": "J2" }, "spi_miso_v": { "PIO_DIRECTION": "INPUT", "pmod": "J3" }, "CLK_spi_clock": { "PIO_DIRECTION": "OUTPUT", "pmod": "J4" } } ================================================ FILE: examples/gyrospi/testspi.cpp ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "STestRequest.h" #include "STestIndication.h" #include "gyro.h" #include static STestRequestProxy *device; static sem_t semp; static int indication_return_value; class STestIndication: public STestIndicationWrapper { public: STestIndication(int id): STestIndicationWrapper(id) {} void result(uint16_t val ) { indication_return_value = val & 0xff; sem_post(&semp); } }; int read_reg(int addr) { device->request((addr << 8) | (1 << 15)); sem_wait(&semp); printf("[%s:%d] addr %x = %x\n", __FUNCTION__, __LINE__, addr, indication_return_value); return indication_return_value; } void write_reg(int addr, int data) { device->request((addr << 8) | data); sem_wait(&semp); } int main(int argc, const char **argv) { STestIndication ind(IfcNames_STestIndicationH2S); device = new STestRequestProxy(IfcNames_STestRequestS2H); read_reg(WHO_AM_I); //while(1) // read_reg(WHO_AM_I); write_reg(CTRL_REG1, 0x0f); // ODR:100Hz Cutoff:12.5 write_reg(CTRL_REG2, 0); write_reg(CTRL_REG3, 0); write_reg(CTRL_REG4, 0xa0); // BDU:1, Range:2000 dps write_reg(CTRL_REG5, 0); sleep(1); printf("[%s:%d] done\n", __FUNCTION__, __LINE__); return 0; } ================================================ FILE: examples/hbridge_simple/Makefile ================================================ CONNECTALDIR ?= ../.. S2H_INTERFACES = HBridgeCtrlRequest:HBridgeController.req H2S_INTERFACES = HBridgeController:HBridgeCtrlIndication ZBLD = $(CONNECTALDIR)/lib/zedboard_robot/bsv BSVFILES = $(ZBLD)/HBridgeController.bsv CPPFILES= test_hbridge.cpp PIN_TYPE = HBridgeSimplePins PIN_TYPE_INCLUDE = HBridgeController PINOUT_FILE = pinout.json PIN_BINDINGS = pmod:pmodc AUTOTOP = --interface pins:HBridgeController.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/hbridge_simple/hbridge_simple.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "HBridgeCtrlIndication.h" #include "GeneratedTypes.h" uint8_t direction[2]; uint16_t power[2]; #define RIGHT 1 #define LEFT 0 #define CW 0 #define CCW 1 #define POWER_0 0x0000 #define POWER_1 0x0200 #define POWER_2 0x0400 #define POWER_3 0x0500 #define POWER_4 0x0600 #define POWER_5 0x0680 #define POWER_6 0x0700 #define POWER_7 0x0780 #define POWER_8 0x07FF #define STOP {power[RIGHT] = POWER_0; power[LEFT] = POWER_0; device->ctrl(power,direction);} #define MOVE_FOREWARD(p) { direction[RIGHT] = CW; direction[LEFT] = CCW; power[RIGHT] = (p); power[LEFT] = (p); device->ctrl(power,direction);} #define MOVE_BACKWARD(p) { direction[RIGHT] = CCW; direction[LEFT] = CW; power[RIGHT] = (p); power[LEFT] = (p); device->ctrl(power,direction);} #define TURN_RIGHT(p) { direction[RIGHT] = CCW; direction[LEFT] = CCW; power[RIGHT] = (p); power[LEFT] = (p); device->ctrl(power,direction);} #define TURN_LEFT(p) { direction[RIGHT] = CW; direction[LEFT] = CW; power[RIGHT] = (p); power[LEFT] = (p); device->ctrl(power,direction);} class HBridgeCtrlIndication : public HBridgeCtrlIndicationWrapper { private: int hbc_event_cnt; public: HBridgeCtrlIndication(int id) : HBridgeCtrlIndicationWrapper(id), hbc_event_cnt(0){} virtual void hbc_event( uint32_t e){ hbc_event_cnt++; fprintf(stderr, "(%d) hbc_event: {", hbc_event_cnt); if (e & (1 << HBridgeCtrlEvent_Started)) fprintf(stderr, "Started"); if (e & (1 << HBridgeCtrlEvent_Stopped)) fprintf(stderr, "Stopped"); fprintf(stderr, "}\n"); } }; ================================================ FILE: examples/hbridge_simple/pinout.json ================================================ { "hbridge_hbridge0_direction" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J1" }, "hbridge_hbridge0_enabled" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J2" }, "hbridge_hbridge1_direction" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J7" }, "hbridge_hbridge1_enabled" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J8" }, "leds_leds[0]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L0" }, "leds_leds[1]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L1" }, "leds_leds[2]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L2" }, "leds_leds[3]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L3" }, "leds_leds[4]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L4" }, "leds_leds[5]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L5" }, "leds_leds[6]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L6" }, "leds_leds[7]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L7" } } ================================================ FILE: examples/hbridge_simple/test_hbridge.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "HBridgeCtrlRequest.h" #include "hbridge_simple.h" int main(int argc, const char **argv) { HBridgeCtrlIndication ind(IfcNames_HBridgeCtrlIndicationH2S); HBridgeCtrlRequestProxy *device = new HBridgeCtrlRequestProxy(IfcNames_HBridgeCtrlRequestS2H); sleep(2); for(int i = 0; i < 2; i++){ MOVE_FOREWARD(POWER_5); usleep(1000000); STOP; MOVE_BACKWARD(POWER_5); usleep(1000000); STOP; TURN_RIGHT(POWER_5); usleep(1000000); STOP; TURN_LEFT(POWER_5); usleep(1000000); STOP; sleep(1); } } ================================================ FILE: examples/hdmidisplay/BsimHdmi.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include //#define LIBNAME EXECDIRECTORY "/libHdmi.so" static int run_xwindows = 1; typedef int (*qtmain_t)(void *param); typedef void (*show_data_t)(unsigned int vsync, unsigned int hsync, unsigned int de, unsigned int data); static show_data_t show_data; static pthread_t threaddata; static unsigned int vsync, hsync, de; static int trace_data;//= 1; static void startmeup() { void* handle = dlopen(LIBNAME, RTLD_LAZY); if (!handle) { printf( "Cannot open library\n"); exit(-1); } printf("Loading library for qtmain...\n"); dlerror(); if (!run_xwindows) { printf( "Not calling qtmain...\n"); return; } qtmain_t qtmain = (qtmain_t) dlsym(handle, "qtmain"); const char *dlsym_error = dlerror(); if (dlsym_error) { printf( "Cannot load symbol 'qtmain': %s\n", dlsym_error); dlclose(handle); exit(-1); } show_data = (show_data_t) dlsym(handle, "show_data"); dlsym_error = dlerror(); if (dlsym_error) { printf( "Cannot load symbol 'show_data': %s\n", dlsym_error); dlclose(handle); exit(-1); } printf( "Calling qtmain...\n"); pthread_create(&threaddata, NULL, (void* (*)(void*))qtmain, (void*)NULL); //dlclose(handle); } extern "C" void bdpi_hdmi_vsync(unsigned int v) { vsync = v; } extern "C" void bdpi_hdmi_hsync(unsigned int v) { hsync = v; } extern "C" void bdpi_hdmi_de(unsigned int v) { de = v; } extern "C" void bdpi_hdmi_data(unsigned int v) { static int once = 1; if (once) startmeup(); once = 0; if (show_data) show_data(vsync, hsync, de, v); else if (trace_data) printf("bdpi_hdmi_data: v %x; h %x; e %x = %4x\n", vsync, hsync, de, v); } ================================================ FILE: examples/hdmidisplay/HDMI16.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import HDMI::*; typedef HDMI#(Bit#(16)) HDMI16; import "BDPI" function Action bdpi_hdmi_vsync(Bit#(1) v); import "BDPI" function Action bdpi_hdmi_hsync(Bit#(1) v); import "BDPI" function Action bdpi_hdmi_de(Bit#(1) v); import "BDPI" function Action bdpi_hdmi_data(Bit#(16) v); module mkResponder#(HDMI#(Bit#(16)) pins)(Empty); rule hvconv; bdpi_hdmi_vsync(pins.hdmi_vsync); endrule rule hvconh; bdpi_hdmi_hsync(pins.hdmi_hsync); endrule rule hvconde; bdpi_hdmi_de(pins.hdmi_de); endrule rule hvcond; bdpi_hdmi_data(pins.hdmi_data); endrule endmodule ================================================ FILE: examples/hdmidisplay/Makefile ================================================ CONNECTALDIR?=../.. ifeq ($(BOARD),bluesim) H2S_INTERFACES = HdmiDisplay:HdmiDisplayIndication,HdmiGeneratorIndication:defaultClock else H2S_INTERFACES = HdmiDisplay:HdmiDisplayIndication,HdmiGeneratorIndication:host.ps7.fclkclk\[1\] endif S2H_INTERFACES = HdmiDisplayRequest:HdmiDisplay.displayRequest HdmiGeneratorRequest:HdmiDisplay.internalRequest MEM_READ_INTERFACES = lHdmiDisplay.dmaClient LIBBSVDIR=$(CONNECTALDIR)/lib/bsv BSVFILES = $(LIBBSVDIR)/HdmiDisplay.bsv $(LIBBSVDIR)/HDMI.bsv $(CONNECTALDIR)/lib/deprecated/DmaUtils.bsv HDMI16.bsv CPPFILES= testhdmidisplay.cpp CONNECTALFLAGS = -C hdmidisplay-$(BOARD).xdc -D IMPORT_HOSTIF PIN_TYPE = HDMI16 PIN_TYPE_INCLUDE = HDMI16 ifeq ($(BOARD),zedboard) CONNECTALFLAGS += -D USE_I2C0 I2C_JSON_FILE = --pinoutfile i2c.json endif REALCONNECTALDIR=$(realpath ../..) CONNECTALFLAGS += -q -D LIBNAME=\\\"$(REALCONNECTALDIR)/examples/hdmidisplay/bluesim/jni/libHdmi.so\\\" CONNECTALFLAGS += -D SIMULATIONRESPONDER=mkResponder -m $(CONNECTALDIR)/examples/hdmidisplay/BsimHdmi.cpp CONNECTALFLAGS += -C $(BOARD)/sources/hdmi.xdc CONNECTALFLAGS += -D SIM_DMA_READ_LATENCY=1 -D SIM_DMA_WRITE_LATENCY=1 AUTOTOP = --importfiles HDMI --importfiles PS7LIB --interface pins:HdmiDisplay.hdmi gentarget:: $(BOARD)/sources/hdmi.xdc $(BOARD)/sources/hdmi.xdc: hdmi.json $(CONNECTALDIR)/boardinfo/$(BOARD).json mkdir -p $(BOARD)/sources ifneq ($(BOARD),bluesim) $(CONNECTALDIR)/scripts/generate-constraints.py $(PIN_BINDINGS) -o $(BOARD)/sources/hdmi.xdc --boardfile $(CONNECTALDIR)/boardinfo/$(BOARD).json --pinoutfile hdmi.json $(I2C_JSON_FILE) endif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/hdmidisplay/TestHdmi.pro ================================================ QT += core gui TARGET = Hdmi TEMPLATE = lib CONFIG += sharedlib HEADERS += worker.h SOURCES += qtmain.cpp ================================================ FILE: examples/hdmidisplay/hdmi.json ================================================ { "CLK_hdmi_clock_if": { "hdmi": "clock" }, "hdmi_hsync": { "hdmi": "hsync" }, "hdmi_vsync": { "hdmi": "vsync" }, "hdmi_de": { "hdmi": "de" }, "hdmi_data[0]": { "hdmi": "data[0]" }, "hdmi_data[1]": { "hdmi": "data[1]" }, "hdmi_data[2]": { "hdmi": "data[2]" }, "hdmi_data[3]": { "hdmi": "data[3]" }, "hdmi_data[4]": { "hdmi": "data[4]" }, "hdmi_data[5]": { "hdmi": "data[5]" }, "hdmi_data[6]": { "hdmi": "data[6]" }, "hdmi_data[7]": { "hdmi": "data[7]" }, "hdmi_data[8]": { "hdmi": "data[8]" }, "hdmi_data[9]": { "hdmi": "data[9]" }, "hdmi_data[10]": { "hdmi": "data[10]" }, "hdmi_data[11]": { "hdmi": "data[11]" }, "hdmi_data[12]": { "hdmi": "data[12]" }, "hdmi_data[13]": { "hdmi": "data[13]" }, "hdmi_data[14]": { "hdmi": "data[14]" }, "hdmi_data[15]": { "hdmi": "data[15]" } } ================================================ FILE: examples/hdmidisplay/hdmidisplay-bluesim.xdc ================================================ ## intentionally blank ================================================ FILE: examples/hdmidisplay/hdmidisplay-vc707.xdc ================================================ ================================================ FILE: examples/hdmidisplay/hdmidisplay-zc702.xdc ================================================ set_property LOC L16 [get_ports "hdmi_clk"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_clk"] set_property slew "SLOW" [get_ports "hdmi_clk"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_clk"] set_property LOC H15 [get_ports "hdmi_vsync"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_vsync"] set_property slew "SLOW" [get_ports "hdmi_vsync"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_vsync"] set_property LOC R18 [get_ports "hdmi_hsync"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_hsync"] set_property slew "SLOW" [get_ports "hdmi_hsync"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_hsync"] set_property LOC T18 [get_ports "hdmi_de"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_de"] set_property slew "SLOW" [get_ports "hdmi_de"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_de"] set_property LOC AB21 [get_ports "hdmi_data[0]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[0]"] set_property slew "SLOW" [get_ports "hdmi_data[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[0]"] set_property LOC AA21 [get_ports "hdmi_data[1]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[1]"] set_property slew "SLOW" [get_ports "hdmi_data[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[1]"] set_property LOC AB22 [get_ports "hdmi_data[2]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[2]"] set_property slew "SLOW" [get_ports "hdmi_data[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[2]"] set_property LOC AA22 [get_ports "hdmi_data[3]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[3]"] set_property slew "SLOW" [get_ports "hdmi_data[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[3]"] set_property LOC V19 [get_ports "hdmi_data[4]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[4]"] set_property slew "SLOW" [get_ports "hdmi_data[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[4]"] set_property LOC V18 [get_ports "hdmi_data[5]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[5]"] set_property slew "SLOW" [get_ports "hdmi_data[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[5]"] set_property LOC V20 [get_ports "hdmi_data[6]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[6]"] set_property slew "SLOW" [get_ports "hdmi_data[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[6]"] set_property LOC U20 [get_ports "hdmi_data[7]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[7]"] set_property slew "SLOW" [get_ports "hdmi_data[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[7]"] set_property LOC W21 [get_ports "hdmi_data[8]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[8]"] set_property slew "SLOW" [get_ports "hdmi_data[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[8]"] set_property LOC W20 [get_ports "hdmi_data[9]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[9]"] set_property slew "SLOW" [get_ports "hdmi_data[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[9]"] set_property LOC W18 [get_ports "hdmi_data[10]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[10]"] set_property slew "SLOW" [get_ports "hdmi_data[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[10]"] set_property LOC T19 [get_ports "hdmi_data[11]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[11]"] set_property slew "SLOW" [get_ports "hdmi_data[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[11]"] set_property LOC U19 [get_ports "hdmi_data[12]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[12]"] set_property slew "SLOW" [get_ports "hdmi_data[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[12]"] set_property LOC R19 [get_ports "hdmi_data[13]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[13]"] set_property slew "SLOW" [get_ports "hdmi_data[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[13]"] set_property LOC T17 [get_ports "hdmi_data[14]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[14]"] set_property slew "SLOW" [get_ports "hdmi_data[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[14]"] set_property LOC T16 [get_ports "hdmi_data[15]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[15]"] set_property slew "SLOW" [get_ports "hdmi_data[15]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[15]"] ================================================ FILE: examples/hdmidisplay/hdmidisplay-zedboard.xdc ================================================ ## ## put the constraints for the HDMI pins here ## set_property LOC W18 [get_ports "hdmi_clk"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_clk"] set_property slew "SLOW" [get_ports "hdmi_clk"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_clk"] set_property LOC W17 [get_ports "hdmi_vsync"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_vsync"] set_property slew "SLOW" [get_ports "hdmi_vsync"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_vsync"] set_property LOC V17 [get_ports "hdmi_hsync"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_hsync"] set_property slew "SLOW" [get_ports "hdmi_hsync"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_hsync"] set_property LOC U16 [get_ports "hdmi_de"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_de"] set_property slew "SLOW" [get_ports "hdmi_de"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_de"] set_property LOC Y13 [get_ports "hdmi_data[0]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[0]"] set_property slew "SLOW" [get_ports "hdmi_data[0]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[0]"] set_property LOC AA13 [get_ports "hdmi_data[1]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[1]"] set_property slew "SLOW" [get_ports "hdmi_data[1]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[1]"] set_property LOC AA14 [get_ports "hdmi_data[2]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[2]"] set_property slew "SLOW" [get_ports "hdmi_data[2]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[2]"] set_property LOC Y14 [get_ports "hdmi_data[3]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[3]"] set_property slew "SLOW" [get_ports "hdmi_data[3]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[3]"] set_property LOC AB15 [get_ports "hdmi_data[4]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[4]"] set_property slew "SLOW" [get_ports "hdmi_data[4]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[4]"] set_property LOC AB16 [get_ports "hdmi_data[5]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[5]"] set_property slew "SLOW" [get_ports "hdmi_data[5]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[5]"] set_property LOC AA16 [get_ports "hdmi_data[6]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[6]"] set_property slew "SLOW" [get_ports "hdmi_data[6]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[6]"] set_property LOC AB17 [get_ports "hdmi_data[7]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[7]"] set_property slew "SLOW" [get_ports "hdmi_data[7]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[7]"] set_property LOC AA17 [get_ports "hdmi_data[8]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[8]"] set_property slew "SLOW" [get_ports "hdmi_data[8]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[8]"] set_property LOC Y15 [get_ports "hdmi_data[9]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[9]"] set_property slew "SLOW" [get_ports "hdmi_data[9]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[9]"] set_property LOC W13 [get_ports "hdmi_data[10]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[10]"] set_property slew "SLOW" [get_ports "hdmi_data[10]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[10]"] set_property LOC W15 [get_ports "hdmi_data[11]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[11]"] set_property slew "SLOW" [get_ports "hdmi_data[11]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[11]"] set_property LOC V15 [get_ports "hdmi_data[12]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[12]"] set_property slew "SLOW" [get_ports "hdmi_data[12]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[12]"] set_property LOC U17 [get_ports "hdmi_data[13]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[13]"] set_property slew "SLOW" [get_ports "hdmi_data[13]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[13]"] set_property LOC V14 [get_ports "hdmi_data[14]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[14]"] set_property slew "SLOW" [get_ports "hdmi_data[14]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[14]"] set_property LOC V13 [get_ports "hdmi_data[15]"] set_property IOSTANDARD LVCMOS25 [get_ports "hdmi_data[15]"] set_property slew "SLOW" [get_ports "hdmi_data[15]"] set_property PIO_DIRECTION "OUTPUT" [get_ports "hdmi_data[15]"] ================================================ FILE: examples/hdmidisplay/i2c.json ================================================ { "I2C0_scl": { "i2c0": "scl" }, "I2C0_sda": { "i2c0": "sda" } } ================================================ FILE: examples/hdmidisplay/qtmain.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include #include #include "worker.h" //#define SIZE 300 #define SIZE 600//300 static int vpos, hpos; static int once = 1; static PinsUpdate *pinsglobal; static QImage image; extern "C" void show_data(unsigned int vsync, unsigned int hsync, unsigned int de, unsigned int data) { //printf("qtshowdata: v %x; h %x; e %x = %4x\n", vsync, hsync, de, data); if (once) image = QImage(SIZE, SIZE, QImage::Format_RGB32); once = 0; if (de) { if (vpos == 0 && hpos == 0 && !once) pinsglobal->newpix(image); if (hpos < SIZE && vpos < SIZE) image.setPixel(hpos, vpos, data); hpos++; } if (vsync) vpos = 0; if (hsync) { if (hpos) vpos++; hpos = 0; } } void Worker::newpix(QImage image) { label.setPixmap(QPixmap::fromImage(image)); if (once) { label.show(); once = 0; } }; extern "C" int qtmain(void *param) { int argc = 1; static char *fakeargv[] = {(char *)"HA", NULL}; QApplication app(argc, fakeargv); Worker worker; PinsUpdate pins; (void)param; printf("[%s:%d]\n", __FUNCTION__, __LINE__); pinsglobal = &pins; QObject::connect(&pins, SIGNAL(updatepix(QImage)), &worker, SLOT(newpix(QImage))); printf("[%s:%d] starting app.exec thread %lx\n", __FUNCTION__, __LINE__, QThread::currentThreadId()); return app.exec(); } ================================================ FILE: examples/hdmidisplay/testhdmidisplay.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "dmaManager.h" #include "HdmiDisplayRequest.h" #include "HdmiDisplayIndication.h" #include "HdmiGeneratorIndication.h" #include "HdmiGeneratorRequest.h" #include "i2chdmi.h" #ifndef BOARD_bluesim #include "edid.h" #endif #define FRAME_COUNT 2 #define MAX_PIXEL 256 #define INCREMENT_PIXEL 2 static HdmiGeneratorRequestProxy *hdmiGenerator; static HdmiDisplayRequestProxy *device; static int allocFrame[FRAME_COUNT]; static unsigned int ref_srcAlloc[FRAME_COUNT]; static int *dataptr[FRAME_COUNT]; static int frame_index; static int nlines = 1080; static int npixels = 1920; static int fbsize; void memdump(unsigned char *p, int len, char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) fprintf(stdout, "\n"); fprintf(stdout, "%s: ",title); } fprintf(stdout, "%02x ", *p++); i++; len--; } fprintf(stdout, "\n"); } static int corner[] = {0, -1, 0xf00f, 0x0fff}; static int corner_index; static void fill_pixels(int offset) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); int *ptr = dataptr[frame_index]; for (int line = 0; line < nlines; line++) for (int pixel = 0; pixel < npixels; pixel++) { int v = ((((MAX_PIXEL * line) / nlines)+offset) % MAX_PIXEL) << 16 | ((((MAX_PIXEL * pixel) / npixels)+offset) % MAX_PIXEL); if (!v) v = 1; if (line < 20 && pixel < 20) v = corner[(corner_index+0) % 4]; if (line < 30 && pixel > npixels - 40) v = corner[(corner_index+1) % 4]; if (line > nlines - 20 && pixel < 20) v = corner[(corner_index+2) % 4]; if (line > nlines - 30 && pixel > npixels - 40) v = corner[(corner_index+3) % 4]; if (line < 20 && pixel % 20 < 2) v = corner[(corner_index+0) % 4]; if (line % 30 < 2 && pixel > npixels - 40) v = corner[(corner_index+1) % 4]; ptr[line * npixels + pixel] = v; } corner_index = offset/16; portalCacheFlush(allocFrame[frame_index], dataptr[frame_index], fbsize, 1); hdmiGenerator->setTestPattern(0); device->startFrameBuffer(ref_srcAlloc[frame_index], fbsize); hdmiGenerator->waitForVsync(0); frame_index = 1 - frame_index; } static int synccount = 0; static long long totalcount; static int number; class HdmiIndication : public HdmiGeneratorIndicationWrapper { public: HdmiIndication(int id) : HdmiGeneratorIndicationWrapper(id) {} virtual void vsync ( uint64_t v, uint32_t w ) { static int base = 0; printf("[%s:%d]\n", __FUNCTION__, __LINE__); totalcount += v; number += w; fill_pixels(base); base += INCREMENT_PIXEL; if (synccount++ >= 20) { synccount = 0; uint32_t zeros = v & 0xffffffff, pix = v >> 32; fprintf(stderr, "[%s] v %"PRIx64" pix=%x:%d. zero=%x:%d. w=%x:%d.\n", __FUNCTION__,v,pix,pix,zeros,zeros,w,w); } } }; class DisplayIndication : public HdmiDisplayIndicationWrapper { public: DisplayIndication(int id) : HdmiDisplayIndicationWrapper(id) {} virtual void transferStarted ( uint32_t v ) { fprintf(stderr, "[%s:%d] v=%d\n", __FUNCTION__, __LINE__, v); } virtual void transferFinished ( uint32_t v, uint32_t len ) { fprintf(stderr, "[%s:%d] v=%d len=%d\n", __FUNCTION__, __LINE__, v, len); } virtual void transferStats ( uint32_t count, uint32_t cycles, uint64_t sumcycles ) { fprintf(stderr, "[%s:%d] count=%d cycles=%d sumcycles=%"PRIx64" avgcycles=%f\n", __FUNCTION__, __LINE__, count, cycles, sumcycles, (double)sumcycles / count); } }; int main(int argc, const char **argv) { device = new HdmiDisplayRequestProxy(IfcNames_HdmiDisplayRequestS2H); DmaManager *dma = platformInit(); HdmiIndication hdmiIndication(IfcNames_HdmiGeneratorIndicationH2S); DisplayIndication displayIndication(IfcNames_HdmiDisplayIndicationH2S); hdmiGenerator = new HdmiGeneratorRequestProxy(IfcNames_HdmiGeneratorRequestS2H); //device->setTraceTransfers(1); device->stopFrameBuffer(); //setClockFrequency(0, 100000000, 0); int vblank, hblank, vsyncoff, hsyncoff, vsyncwidth, hsyncwidth; #ifdef BOARD_bluesim nlines = 300; npixels = 500; vblank = 10; hblank = 10; vsyncoff = 2; hsyncoff = 2; vsyncwidth = 3; hsyncwidth = 3; hblank--; // needed on zc702 #else // read out monitor EDID from ADV7511 struct edid edid; init_i2c_hdmi(); int i2cfd = open("/dev/i2c-0", O_RDWR); fprintf(stderr, "Monitor EDID:\n"); for (int i = 0; i < 256; i++) { edid.raw[i] = i2c_read_reg(i2cfd, 0x3f, i); fprintf(stderr, " %02x", edid.raw[i]); if ((i % 16) == 15) { fprintf(stderr, " "); for (int j = i-15; j <= i; j++) { unsigned char c = edid.raw[j]; fprintf(stderr, "%c", (isprint(c) && isascii(c)) ? c : '.'); } fprintf(stderr, "\n"); } } close(i2cfd); parseEdid(edid); long actualFrequency = 0; int status; status = setClockFrequency(0, 100000000, &actualFrequency); printf("[%s:%d] setClockFrequency 0 100000000 status=%d actualfreq=%ld\n", __FUNCTION__, __LINE__, status, actualFrequency); status = setClockFrequency(1, 160000000, &actualFrequency); printf("[%s:%d] setClockFrequency 1 160000000 status=%d actualfreq=%ld\n", __FUNCTION__, __LINE__, status, actualFrequency); status = setClockFrequency(3, 200000000, &actualFrequency); printf("[%s:%d] setClockFrequency 3 200000000 status=%d actualfreq=%ld\n", __FUNCTION__, __LINE__, status, actualFrequency); for (int i = 0; i < 4; i++) { int pixclk = (long)edid.timing[i].pixclk * 10000; if ((pixclk > 0) && (pixclk < 148000000)) { nlines = edid.timing[i].nlines; // number of visible lines npixels = edid.timing[i].npixels; vblank = edid.timing[i].blines; // number of blanking lines hblank = edid.timing[i].bpixels; vsyncoff = edid.timing[i].vsyncoff; // number of lines in FrontPorch (within blanking) hsyncoff = edid.timing[i].hsyncoff; vsyncwidth = edid.timing[i].vsyncwidth; // width of Sync (within blanking) hsyncwidth = edid.timing[i].hsyncwidth; fprintf(stderr, "Using pixclk %d calc_pixclk %ld npixels %d nlines %d\n", pixclk, 60l * (long)(hblank + npixels) * (long)(vblank + nlines), npixels, nlines); setClockFrequency(1, pixclk, 0); //hblank--; // needed on zc702 break; } } #endif fprintf(stderr, "lines %d, pixels %d, vblank %d, hblank %d, vwidth %d, hwidth %d\n", nlines, npixels, vblank, hblank, vsyncwidth, hsyncwidth); hdmiGenerator->setDeLine(vsyncoff, // End of FrontPorch vsyncoff+vsyncwidth,// End of Sync vblank-1, // Start of Visible (start of BackPorch) vblank + nlines, vblank + nlines / 2); // End hdmiGenerator->setDePixel(hsyncoff, hsyncoff+hsyncwidth, hblank, hblank + npixels, hblank + npixels / 2); #if 0 // horiz: frontPorch:87, sync: 44, backPorch:148, (blank=87+44+148=279) pixel:1920 // vert: frontPorch:3, sync:5, backPorch:36, (blank = 36+5+8=49) lines:1080 dePixelStartSync <- mkSyncReg( 87 dePixelEndSync <- mkSyncReg( 44 + 87 dePixelStartVisible <- mkSyncReg(148 + 44 + 87 dePixelEnd <- mkSyncReg( 1920 + 148 + 44 + 87 dePixelMid <- mkSyncReg((1920/2) + 148 + 44 deLineStartSync <- mkSyncReg( 3 deLineEndSync <- mkSyncReg( 5 + 3 deLineStartVisible <- mkSyncReg( 36 + 5 + 3 deLineEnd <- mkSyncReg( 1080 + 36 + 5 + 3 deLineMid <- mkSyncReg((1080/2) + 41 #endif fbsize = nlines*npixels*sizeof(uint32_t); for (int i = 0; i < FRAME_COUNT; i++) { allocFrame[i] = portalAlloc(fbsize, 0); dataptr[i] = (int*)portalMmap(allocFrame[i], fbsize); memset(dataptr[i], i ? 0xff : 0, fbsize); fprintf(stderr, "hdmidisplay: calling dma->reference %d/%d\n", i, FRAME_COUNT); ref_srcAlloc[i] = dma->reference(allocFrame[i]); } //uint64_t beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); //fprintf(stderr, "first mem_stats=%"PRIx64"\n", beats); fprintf(stderr, "hdmidisplay: sleep 3\n"); sleep(3); fprintf(stderr, "hdmidisplay: Starting frame buffer ref=%d...", ref_srcAlloc[0]); fill_pixels(0); fprintf(stderr, "hdmidisplay: run test\n"); sleep(60); fprintf(stderr, "hdmidisplay: done\n"); } ================================================ FILE: examples/hdmidisplay/worker.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include class Worker: public QObject { Q_OBJECT int once; QLabel label; public: Worker(): once(1) { } private slots: void newpix(QImage image); }; class PinsUpdate: public QObject { Q_OBJECT public: void newpix(QImage image) { emit updatepix(image); }; signals: void updatepix(QImage image); }; ================================================ FILE: examples/imageon/ImageonCapture.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Vector::*; import GetPut::*; import Clocks :: *; import BRAMFIFO::*; import ConnectalMemTypes::*; import ClientServer::*; import Pipe::*; import MemWriteEngine::*; import IserdesDatadeser::*; import IserdesDatadeserIF::*; import Connectable :: *; import FIFO::*; import MemServer::*; import ConnectalMMU::*; import Portal::*; import XilinxCells::*; import ConnectalClocks::*; import Gearbox::*; import ConnectalSpi::*; import ImageonVita::*; import HDMI::*; import YUV::*; import ConnectalXilinxCells::*; import ImageonCapturePins::*; Bit#(10) imageDataTag = 10'h035; Bit#(10) otherDataTag = 10'h015; typedef struct { Bit#(2) monitor; Bit#(32) count; } MonitorCount deriving (Bits, Eq); interface ImageonCaptureIndication; method Action spi_response(Bit#(32) v); endinterface interface ImageonCaptureRequest; method Action set_trigger_cnt(Bit#(32) v); method Action startWrite(Bit#(32) pointer, Bit#(32) numBytes); method Action set_host_oe(Bit#(1) v); method Action put_spi_request(Bit#(32) v); method Action set_i2c_mux_reset_n(Bit#(1) v); endinterface interface ImageonCapture; interface ImageonSerdesRequest serdes_request; interface HdmiGeneratorRequest hdmi_request; interface Vector#(1, MemWriteClient#(64)) dmaClient; interface ImageonCaptureRequest capture_request; interface ImageonCapturePins pins; endinterface module mkImageonCapture#(ImageonSerdesIndication serdes_indication, HdmiGeneratorIndication hdmi_ind, ImageonCaptureIndication cap_ind)(ImageonCapture); `ifndef SIMULATION B2C1 iclock <- mkB2C1(); Clock fmc_imageon_clk1 <- mkClockBUFG(clocked_by iclock.c); `else Clock fmc_imageon_clk1 <- exposeCurrentClock(); `endif Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); ImageClocks clk <- mkImageClocks(fmc_imageon_clk1); Clock hdmi_clock = clk.hdmi; Clock imageon_clock = clk.imageon; Reset hdmi_reset <- mkAsyncReset(2, defaultReset, hdmi_clock); Reset imageon_reset <- mkAsyncReset(2, defaultReset, imageon_clock); SPIMaster#(Bit#(26), 1) spiController <- mkSPIMaster(1000, True); Reg#(Bit#(1)) i2c_mux_reset_n_reg <- mkReg(0); Reg#(Bool) dmaRun <- mkSyncReg(False, defaultClock, defaultReset, imageon_clock); Reg#(Bit#(32)) trigger_cnt_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock); Reg#(Bit#(1)) imageon_oe <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock); Vector#(3, ReadOnly#(Bit#(1))) vita_trigger_wire; Reg#(Bool) remapKernel <- mkReg(False, clocked_by imageon_clock, reset_by imageon_reset); Gearbox#(4, 1, Bit#(10)) dataGearbox <- mkNto1Gearbox(imageon_clock, imageon_reset, hdmi_clock, hdmi_reset); function ReadOnly#(Bit#(1)) roval(Bit#(1) val); return (interface ReadOnly; method Bit#(1) _read(); return val; endmethod endinterface); endfunction // serdes: serial line protocol for wires from sensor (nothing sensor specific) ISerdes serdes <- mkISerdes(defaultClock, defaultReset, serdes_indication, clocked_by imageon_clock, reset_by imageon_reset); // mem capture MemWriteEngine#(64,64,1,1) we <- mkMemWriteEngine(); SyncFIFOIfc#(Bit#(64)) synchronizer <- mkSyncBRAMFIFO(10, imageon_clock, imageon_reset, defaultClock, defaultReset); rule sync_data if (dmaRun); synchronizer.enq(serdes.data.capture); endrule rule send_data; we.writeServers[0].data.enq(synchronizer.first); synchronizer.deq; endrule rule dma_response; let rv <- we.writeServers[0].done.get; serdes_indication.iserdes_dma('hffffffff); // request is all finished endrule SyncPulseIfc vsyncPulse <- mkSyncHandshake(hdmi_clock, hdmi_reset, imageon_clock); Reg#(Bool) triggerOutput <- mkReg(True, clocked_by imageon_clock, reset_by imageon_reset); Reg#(Bit#(32)) tcounter <- mkReg(0, clocked_by imageon_clock, reset_by imageon_reset); rule calcTrigger; if (triggerOutput && vsyncPulse.pulse()) begin tcounter <= trigger_cnt_reg; triggerOutput <= False; end else tcounter <= tcounter - 1; if (!triggerOutput && tcounter == 0) triggerOutput <= True; endrule // fromSensor: sensor specific processing of serdes input, resulting in pixels `ifndef SIMULATION ConnectalODDR#(Bit#(1)) pll_out <- mkConnectalODDR(ODDRParams{ddr_clk_edge:"SAME_EDGE", init:1, srtype:"ASYNC"}, clocked_by imageon_clock, reset_by imageon_reset); ConnectalODDR#(Bit#(1)) pll_t <- mkConnectalODDR(ODDRParams{ddr_clk_edge:"SAME_EDGE", init:1, srtype:"ASYNC"}, clocked_by imageon_clock, reset_by imageon_reset); ReadOnly#(Bit#(1)) vita_clk_pll <- mkOBUFT(roval(pll_out.q()), roval(pll_t.q()), clocked_by imageon_clock, reset_by imageon_reset); vita_trigger_wire[2] <- mkOBUFT(roval(0), regToReadOnly(imageon_oe), clocked_by imageon_clock, reset_by imageon_reset); vita_trigger_wire[1] <- mkOBUFT(roval(1), regToReadOnly(imageon_oe), clocked_by imageon_clock, reset_by imageon_reset); vita_trigger_wire[0] <- mkOBUFT(regToReadOnly(triggerOutput), regToReadOnly(imageon_oe), clocked_by imageon_clock, reset_by imageon_reset); ReadOnly#(Bit#(1)) vita_reset_n_wire <- mkOBUFT(regToReadOnly(serdes.data.reset), regToReadOnly(imageon_oe), clocked_by imageon_clock, reset_by imageon_reset); rule pll_rule; pll_t.s(False); pll_out.s(False); pll_out.d1(0); pll_out.d2(1); pll_out.ce(True); pll_t.d1(imageon_oe); pll_t.d2(imageon_oe); pll_t.ce(True); endrule `else let vita_clk_pll = 0; let vita_reset_n_wire = 0; vita_trigger_wire = replicate(interface ReadOnly; method Bit#(1) _read(); return 0; endmethod endinterface); `endif rule frameData; Vector#(5, Bit#(10)) v = serdes.data.raw_data(); if (v[0] == imageDataTag || v[0] == otherDataTag) begin Vector#(4, Bit#(10)) dor; for (Integer i = 0; i < 4; i = i + 1) if (!remapKernel) dor[i] = v[i+1]; else dor[i] = v[4-i]; remapKernel <= !remapKernel; dataGearbox.enq(dor); end else remapKernel <= False; endrule rule spiResponse; Bit#(26) v <- spiController.response[0].get(); cap_ind.spi_response(extend(v)); endrule // hdmi: output to display HdmiGenerator#(Rgb888) lHdmiGenerator <- mkHdmiGenerator(defaultClock, defaultReset, vsyncPulse, hdmi_ind, clocked_by hdmi_clock, reset_by hdmi_reset); Rgb888ToYyuv converter <- mkRgb888ToYyuv(clocked_by hdmi_clock, reset_by hdmi_reset); mkConnection(lHdmiGenerator.rgb888, converter.rgb888); HDMI#(Bit#(HdmiBits)) hdmisignals <- mkHDMI(converter.yyuv, clocked_by hdmi_clock, reset_by hdmi_reset); Reg#(Bool) frameStart <- mkReg(False, clocked_by imageon_clock, reset_by imageon_reset); Reg#(Bit#(32)) frameCount <- mkReg(0, clocked_by imageon_clock, reset_by imageon_reset); SyncFIFOIfc#(MonitorCount) frameStartSynchronizer <- mkSyncFIFO(2, imageon_clock, imageon_reset, defaultClock); Wire#(Bit#(2)) monitor_wires <- mkDWire(0, clocked_by imageon_clock, reset_by imageon_reset); rule frameStartRule; Bool fs = unpack(monitor_wires[0]); if (fs && !frameStart) begin // start of frame? // need to cross the clock domain frameStartSynchronizer.enq(MonitorCount{monitor:monitor_wires, count:frameCount}); frameCount <= frameCount + 1; end frameStart <= fs; endrule rule frameStartIndication; let tpl = frameStartSynchronizer.first(); frameStartSynchronizer.deq(); //captureIndicationProxy.ifc.frameStart(tpl.monitor, tpl.count); endrule Reg#(Bit#(10)) xsvi <- mkReg(0, clocked_by hdmi_clock, reset_by hdmi_reset); rule xsviConnection; // copy data from sensor to hdmi output dataGearbox.deq; xsvi <= dataGearbox.first[0]; endrule rule xsviput; Bit#(32) pixel = {8'b0, xsvi[9:2], xsvi[9:2], xsvi[9:2]}; lHdmiGenerator.pdata.put(pixel); endrule interface serdes_request = serdes.request; interface hdmi_request = lHdmiGenerator.request; interface dmaClient = cons(we.dmaClient, nil); interface ImageonCaptureRequest capture_request; method Action set_trigger_cnt(Bit#(32) v); trigger_cnt_reg <= v; serdes.data.start_capture(); endmethod method Action startWrite(Bit#(32) pointer, Bit#(32) numBytes); we.writeServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:truncate(numBytes), burstLen:8, tag:0}); dmaRun <= True; endmethod method Action set_host_oe(Bit#(1) v); imageon_oe <= ~v; endmethod method Action put_spi_request(Bit#(32) v); spiController.request[0].put(truncate(v)); endmethod method Action set_i2c_mux_reset_n(Bit#(1) v); i2c_mux_reset_n_reg <= v; endmethod endinterface interface ImageonCapturePins pins; `ifndef SIMULATION method Action fmc_video_clk1(Bit#(1) v); iclock.inputclock(v); endmethod `endif method Action io_vita_monitor(Bit#(2) v); monitor_wires <= v; endmethod method Bit#(1) io_vita_clk_pll(); return vita_clk_pll; endmethod method Bit#(1) io_vita_reset_n(); return vita_reset_n_wire; endmethod method Vector#(3, ReadOnly#(Bit#(1))) io_vita_trigger(); return vita_trigger_wire; endmethod method Bit#(1) i2c_mux_reset_n(); return i2c_mux_reset_n_reg; endmethod interface SpiMasterPins spi = spiController.pins; interface imageon_deleteme_unused_clock = imageon_clock; interface imageon_deleteme_unused_reset = imageon_reset; interface ImageonSerdesPins serpins = serdes.pins; interface HDMI hdmi = hdmisignals; endinterface endmodule ================================================ FILE: examples/imageon/ImageonCapturePins.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import IserdesDatadeserIF::*; import ConnectalSpi::*; import HDMI::*; interface ImageonCapturePins; method Bit#(1) io_vita_clk_pll(); method Bit#(1) io_vita_reset_n(); method Vector#(3, ReadOnly#(Bit#(1))) io_vita_trigger(); method Action io_vita_monitor(Bit#(2) v); interface SpiMasterPins#(1) spi; method Bit#(1) i2c_mux_reset_n(); interface Clock imageon_deleteme_unused_clock; interface Reset imageon_deleteme_unused_reset; interface ImageonSerdesPins serpins; (* prefix="" *) interface HDMI#(Bit#(HdmiBits)) hdmi; method Action fmc_video_clk1(Bit#(1) v); endinterface ================================================ FILE: examples/imageon/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ImageonSerdesRequest:ImageonCapture.serdes_request HdmiGeneratorRequest:ImageonCapture.hdmi_request ImageonCaptureRequest:ImageonCapture.capture_request H2S_INTERFACES = ImageonCapture:ImageonSerdesIndication,HdmiGeneratorIndication,ImageonCaptureIndication MEM_WRITE_INTERFACES = lImageonCapture.dmaClient BSVFILES = $(CONNECTALDIR)/lib/bsv/IserdesDatadeserIF.bsv $(CONNECTALDIR)/lib/bsv/HDMI.bsv ImageonCapture.bsv CPPFILES=testimagecapture.cpp CONNECTALFLAGS = -D USE_I2C1 PINOUT_FILE += imageon-fmc.json PIN_TYPE = ImageonCapturePins PIN_TYPE_INCLUDE = ImageonCapturePins ifeq ($(BOARD),zedboard) CONNECTALFLAGS += -D USE_I2C0 PINOUT_FILE += imageon-zedboard.json PIN_BINDINGS ?= fmc:fmc1 else PIN_BINDINGS ?= fmc:fmc2 endif CONNECTALFLAGS += -C imageon-clocks.xdc --tcl clock.tcl AUTOTOP = --interface pins:ImageonCapture.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/imageon/Makefile.dump ================================================ all: gcc -Wall -o dump_image dump_image.cpp fetchdata: adb -s 172.17.1.165:5555 pull /mnt/sdcard/tmp.outfile pixeldata.dat ================================================ FILE: examples/imageon/clock.tcl ================================================ ## disconnect unused CLK and RST ports inserted by bsc foreach {pat} {CLK_GATE_* CLK_pins_spi_clock} { foreach {net} [get_nets $pat] { puts "disconnecting net $net" disconnect_net -net $net -objects [get_pins -of_objects $net] } } ================================================ FILE: examples/imageon/dump_image.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include static struct { int len; /* number of bits of field */ const char *name; /* name of field */ uint64_t default_value; /* value to skip when dumping */ } *dumpptr, *dumpend, dumpitem[] = { {10, "ei", 0}, {5, "wc", 0}, {4, "a", 0}, {10, "cdata", 0x3a6}, {16, "gen", 0}, {3, "csam", 0}, {1, "astart", 0}, {1, "autoa", 0}, {1, "sinc", 0}, {1, "sbit", 0}, {1, "sce", 0}, {1, "wren", 1}, {10, "sdata", -1}, //64 {}}; //return {edge_int, windowcount[4:0], pack(astate), ctrl_data, gencounter, ctrl_sample, align_start, autoalign, //serdes_capture.send({pack(syncparam), pack(fifo_wren_sync), serdes_data}); #define STRING_LEN 10000 static char last_string[STRING_LEN], current_string[STRING_LEN]; int main(int argc, char *argv[]) { int repeat_count = 0; if (argc != 2) { printf("dump_pixel \n"); return -1; } int fd = open(argv[1], O_RDONLY); int len = lseek(fd, 0, SEEK_END); printf("dump_pixel: filename '%s' len %d\n", argv[1], len); lseek(fd, 0, SEEK_SET); uint64_t *data = (uint64_t *)malloc(len); read(fd, data, len); close(fd); dumpend = dumpitem; while((dumpend+1)->len) /* get last value in list to be dumped (LSB bits) */ dumpend++; for (unsigned int i = 0; i < len/sizeof(uint64_t); i++) { uint64_t ditem = data[i]; dumpptr = dumpend; char *p = current_string; do { uint64_t val = ditem & ((1 << dumpptr->len) - 1); ditem >>= dumpptr->len; if (val != dumpptr->default_value) { sprintf(p, " %s=%llx", dumpptr->name, (long long)val); p += strlen(p); } } while (dumpptr-- != dumpitem); if (!strcmp(last_string, current_string)) repeat_count++; else { if (repeat_count) printf("repeat %d\n", repeat_count); printf("%s\n", current_string); repeat_count = 0; strcpy(last_string, current_string); } } return 0; } ================================================ FILE: examples/imageon/i2ccamera.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #define BYTE_OPERATION 0x80 // to use BYTE_READ/WRITE instead of BLOCK_READ/WRITE (cdce913 datasheet, table 8) static void init_i2c_camera(void) { // PCA9546A Mux: // Channel 0: HDMIO_DDC 0x01 // Channel 1: HDMIO 0x02 // Channel 2: HDMII 0x04 // Channel 3: PLL-IO 0x08 static unsigned char cmuxdata[] = {8, 8}; static unsigned char cdce913_data[] = { 0x00, 0x81, 0x01, 0x01, // [1:0] - Slave Address A[1:0]=01b //0x02, 0xB4, //0x03, 0x01, 0x02, 0xB4, // [ 7] = M1 = 1 (PLL1 Clock) // [1:0] = PDIV1[9:8] = 0 0x03, 0x02, // [7:0] = PDIV1[7:0] = 2 0x04, 0x02, 0x05, 0x50, 0x06, 0x60, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, //0x14, 0xED, 0x14, 0x6D, // [ 7] = MUX1 = 0 (PLL1) // [ 6] = M2 = 1 (PDIV2) // [5:4] = M3 = 2 (PDIV3) 0x15, 0x02, //0x16, 0x01, //0x17, 0x01, 0x16, 0x00, // [6:0] = PDIV2 = 0 (reset and stand-by) 0x17, 0x00, // [6:0] = PDIV3 = 0 (reset and stand-by) //0x18, 0x00, //0x19, 0x40, //0x1A, 0x02, //0x1B, 0x08, // PLL1 : Fin=27MHz, M=2, N=11, PDIV=2 Fout=74.25MHz // Fvco = 148.5 MHz // P = 4 - int(log2(11/2)) = 4 - 2 = 2 // N'= 11 * 2^2 = 44 // Q = int(44/2) = 22 // R = 44 - 2*22 = 0 0x18, 0x00, // [7:0] = PLL1_0N[11:4] = 00000000 0x19, 0xB0, // [7:4] = PLL1_0N[3:0] = 1011 // [3:0] = PLL1_0R[8:5] = 0000 0x1A, 0x02, // [7:3] = PLL1_0R[4:0] = 00000 // [2:0] = PLL1_0Q[5:3] = 010 0x1B, 0xC9, // [7:5] = PLL1_0Q[2:0] = 110 // [4:2] = PLL1_0P[2:0] = 010 // [1:0] = VC01_0_RANGE[1:0] = 01 (125 MHz < Fvco1 < 150 MHz) //0x1C, 0x00, //0x1D, 0x40, //0x1E, 0x02, //0x1F, 0x08, // PLL1 : Fin=27MHz, M=2, N=11, PDIV=2 Fout=74.25MHz // Fvco = 148.5 MHz // P = 4 - int(log2(11/2)) = 4 - 2 = 2 // N'= 11 * 2^2 = 44 // Q = int(44/2) = 22 // R = 44 - 2*22 = 0 0x1C, 0x00, // [7:0] = PLL1_1N[11:4] = 00000000 0x1D, 0xB0, // [7:4] = PLL1_1N[3:0] = 1011 // [3:0] = PLL1_1R[8:5] = 0000 0x1E, 0x02, // [7:3] = PLL1_1R[4:0] = 00000 // [2:0] = PLL1_1Q[5:3] = 010 0x1F, 0xC9, // [7:5] = PLL1_1Q[2:0] = 110 // [4:2] = PLL1_1P[2:0] = 010 // [1:0] = VC01_1_RANGE[1:0] = 01 (125 MHz < Fvco1 < 150 MHz) // 148.500000 MHz // PLL1: M = 2, N = 11, Pdiv = 1 // Fin = 27.000000MHz // Fvco = Fin * N/M = 148.500000MHz // Range = 1 (125 MHz <= Fvco < 150 MHz) // Fout = Fvco / Pdiv = 148.500000MHz // P = 4 - int(log2(M/N)) = 2 // Np = N * 2^P = 44 // Q = int(Np/M) = 22 // R = Np - M*Q = 0 0x02, 0xB4, // [ 7] = M1 = 1 (PLL1 clock) // [1:0] = Pdiv1[9:8] 0x03, 0x01, // [7:0] = Pdiv1[7:0] 0x18, 0x00, // [7:0] = PLL1_0N[11:4] 0x19, 0xB0, // [7:4] = PLL1_0N[3:0] // [3:0] = PLL1_0R[8:5] 0x1A, 0x02, // [7:3] = PLL1_0R[4:0] // [2:0] = PLL1_0Q[5:3] 0x1B, 0xC9}; // [7:5] = PLL1_0Q[2:0] // [4:2] = PLL1_0P[2:0] // [1:0] = VCO1_0_RANGE[1:0] int fd = open("/dev/i2c-1", O_RDWR); printf("[%s:%d] /dev/i2c-1 open fd %d\n", __FUNCTION__, __LINE__, fd); if (fd < 0) printf("[%s] /dev/i2c-1 open failed\n", __FUNCTION__); // setup mux for enabling clock generator if (i2c_write_array(fd, 0x70, cmuxdata, sizeof(cmuxdata), 0)) printf("[%s] write mux failed\n", __FUNCTION__); int version = i2c_read_reg(fd, 0x65, 0x00 | BYTE_OPERATION); printf("[%s:%d] pllversion %x\n", __FUNCTION__, __LINE__, version); // initialize clock generator if (i2c_write_array(fd, 0x65, cdce913_data, sizeof(cdce913_data), BYTE_OPERATION)) printf("[%s] write data failed\n", __FUNCTION__); close(fd); } ================================================ FILE: examples/imageon/imageon-clocks.xdc ================================================ create_clock -name video_clk -period "10" [get_ports "fmc_video_clk1_v"] create_clock -name serpins_clk -period "10" [get_ports "serpins_io_vita_clk_p_v"] create_clock -name spi_clk -period "100" [get_pins "ts_0/lImageonCapture_spiController_clockDivider/cntr_reg[9]/Q"] ================================================ FILE: examples/imageon/imageon-fmc.json ================================================ { "*io_vita_clk_pll": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA13_P" }, "*io_vita_reset_n": { "PIO_DIRECTION": "OUTPUT", "fmc": "CLK0_M2C_N" }, "*io_vita_trigger_0*": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA14_N" }, "*io_vita_trigger_1*": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA14_P" }, "*io_vita_trigger_2*": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA13_N" }, "*io_vita_monitor*[0]": { "PIO_DIRECTION": "INPUT", "fmc": "LA15_P" }, "*io_vita_monitor*[1]": { "PIO_DIRECTION": "INPUT", "fmc": "LA15_N" }, "CLK_spi_clock": { "original_name": "io_vita_spi_sclk", "PIO_DIRECTION": "OUTPUT", "fmc": "LA12_P" }, "*spi_*sel_n": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA12_N" }, "*spi_mosi": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA11_P" }, "*miso_v": { "PIO_DIRECTION": "INPUT", "fmc": "LA11_N" }, "*io_vita_clk_p_v": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA00_CC_P" }, "*io_vita_clk_n_v": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA00_CC_N" }, "*io_vita_sync_p*": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA10_P" }, "*io_vita_sync_n*": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA10_N" }, "*io_vita_data_p_v[0]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA09_P" }, "*io_vita_data_n_v[0]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA09_N" }, "*io_vita_data_p_v[1]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA07_P" }, "*io_vita_data_n_v[1]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA07_N" }, "*io_vita_data_p_v[2]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA08_P" }, "*io_vita_data_n_v[2]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA08_N" }, "*io_vita_data_p_v[3]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA05_P" }, "*io_vita_data_n_v[3]": { "PIO_DIRECTION": "INPUT", "IOSTANDARD": "LVDS_25", "DIFF_TERM": "TRUE", "fmc": "LA05_N" }, "fmc_video_clk1_v": { "PIO_DIRECTION": "INPUT", "fmc": "CLK0_M2C_P" }, "*i2c_mux_reset_n": { "PIO_DIRECTION": "OUTPUT", "fmc": "LA01_CC_N" }, "I2C1_scl": { "PIO_DIRECTION": "BIDIR", "fmc": "LA16_P" }, "I2C1_sda": { "PIO_DIRECTION": "BIDIR", "fmc": "LA16_N" }, "CLK_hdmi_clock_if": { "hdmi": "clock" }, "hdmi_hsync": { "hdmi": "hsync" }, "hdmi_vsync": { "hdmi": "vsync" }, "hdmi_de": { "hdmi": "de" }, "hdmi_data[0]": { "hdmi": "data[0]" }, "hdmi_data[1]": { "hdmi": "data[1]" }, "hdmi_data[2]": { "hdmi": "data[2]" }, "hdmi_data[3]": { "hdmi": "data[3]" }, "hdmi_data[4]": { "hdmi": "data[4]" }, "hdmi_data[5]": { "hdmi": "data[5]" }, "hdmi_data[6]": { "hdmi": "data[6]" }, "hdmi_data[7]": { "hdmi": "data[7]" }, "hdmi_data[8]": { "hdmi": "data[8]" }, "hdmi_data[9]": { "hdmi": "data[9]" }, "hdmi_data[10]": { "hdmi": "data[10]" }, "hdmi_data[11]": { "hdmi": "data[11]" }, "hdmi_data[12]": { "hdmi": "data[12]" }, "hdmi_data[13]": { "hdmi": "data[13]" }, "hdmi_data[14]": { "hdmi": "data[14]" }, "hdmi_data[15]": { "hdmi": "data[15]" } } ================================================ FILE: examples/imageon/imageon-zedboard.json ================================================ { "I2C0_scl": { "i2c0": "scl" }, "I2C0_sda": { "i2c0": "sda" } } ================================================ FILE: examples/imageon/testimagecapture.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include // isprint, isascii #include "dmaManager.h" #include "ImageonCaptureRequest.h" #include "ImageonCaptureIndication.h" #include "ImageonSerdesRequest.h" #include "ImageonSerdesIndication.h" #include "HdmiGeneratorRequest.h" #include "HdmiGeneratorIndication.h" #include "i2chdmi.h" #include "i2ccamera.h" #include "edid.h" static ImageonSerdesRequestProxy *serdesdevice; static HdmiGeneratorRequestProxy *hdmidevice; static ImageonCaptureRequestProxy *idevice; static int trace_spi = 0; static int nlines = 1080; static int npixels = 1920; static int fbsize = nlines*npixels*4; #define DECL(A) \ static sem_t sem_ ## A; \ static uint32_t cv_ ## A; DECL(iserdes_control) DECL(spi_response) #define GETFN(A) \ static uint32_t read_ ## A (void) \ { \ serdesdevice->get_ ## A(); \ sem_wait(&sem_ ## A); \ return cv_ ## A; \ } class ImageonSerdesIndication : public ImageonSerdesIndicationWrapper { public: ImageonSerdesIndication(int id) : ImageonSerdesIndicationWrapper(id) {} void iserdes_control_value ( const uint32_t v ){ cv_iserdes_control = v; sem_post(&sem_iserdes_control); } void iserdes_dma ( const uint32_t v ){ printf("[%s:%d] 0x%x ***************************************************************** \n", __FUNCTION__, __LINE__, v); } }; class ImageonCaptureIndication : public ImageonCaptureIndicationWrapper { public: ImageonCaptureIndication(int id) : ImageonCaptureIndicationWrapper(id) {} void spi_response(uint32_t v){ //fprintf(stderr, "spi_response: %x\n", v); cv_spi_response = v; sem_post(&sem_spi_response); } }; class HdmiGeneratorIndication: public HdmiGeneratorIndicationWrapper { HdmiGeneratorRequestProxy *hdmiRequest; public: HdmiGeneratorIndication(int id, HdmiGeneratorRequestProxy *proxy) : HdmiGeneratorIndicationWrapper(id), hdmiRequest(proxy) {} virtual void vsync ( uint64_t v, uint32_t w ) { fprintf(stderr, "[%s:%d] v=%d w=%d\n", __FUNCTION__, __LINE__, (uint32_t) v, w); hdmiRequest->waitForVsync(v+1); } }; static void memdump(unsigned char *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printf("\n"); printf("%s: ",title); } printf("%02x ", *p++); i++; len--; } printf("\n"); } static void init_local_semaphores(void) { sem_init(&sem_iserdes_control, 0, 0); sem_init(&sem_spi_response, 0, 0); } GETFN(iserdes_control) //#define VITA_ISERDES_CONTROL_REG 0x10 #define VITA_ISERDES_RESET_BIT 0x01 #define VITA_ISERDES_AUTO_ALIGN_BIT 0x02 #define VITA_ISERDES_ALIGN_START_BIT 0x04 #define VITA_ISERDES_FIFO_ENABLE_BIT 0x08 //#define VITA_DECODER_CONTROL_REG 0x20 #define VITA_DECODER_RESET_BIT 0x01 #define VITA_DECODER_ENABLE_BIT 0x02 #define VITA_SPI_SEQ1_QTY 8 /* Table 6. enable clock management register upload - part 1 */ static uint16_t vita_spi_seq1[VITA_SPI_SEQ1_QTY][3] = { // Enable Clock Management - Part 1 // V1/SN/SE 10-bit mode with PLL { 2, 0xFFFF, 0}, // Monochrome Sensor // { 2, 0xFFFF, 0x0001}, // Color Sensor { 32, 0xFFFF, 0x2004}, // Configure clock management { 20, 0xFFFF, 0}, // Configure clock management { 17, 0xFFFF, 0x2113}, // Configure PLL { 26, 0xFFFF, 0x2280}, // Configure PLL lock detector { 27, 0xFFFF, 0x3D2D}, // Configure PLL lock detector { 8, 0xFFFF, 0}, // Release PLL soft reset { 16, 0xFFFF, 0x0003} // Enable PLL }; #define VITA_SPI_SEQ3_QTY 3 /* Table 7. enable clock management register upload - part 2 */ static uint16_t vita_spi_seq3[VITA_SPI_SEQ3_QTY][3] = { // Enable Clock Management - Part 2 // V1/SN/SE 10-bit mode with PLL { 9, 0xFFFF, 0}, // Release clock generator soft reset { 32, 0xFFFF, 0x2006}, // Enable logic clock { 34, 0xFFFF, 0x0001} // Enable logic blocks }; #define VITA_SPI_SEQ4_QTY 17 /* Table 8. required register upload */ static uint16_t vita_spi_seq4[VITA_SPI_SEQ4_QTY][3] = { // Required Register Upload // V1/SN/SE 10-bit mode with PLL { 41, 0xFFFF, 0}, // Configure image core {129, 0x2000, 0}, // [13] 10-bit mode { 65, 0xFFFF, 0x288B}, // Configure CP biasing { 66, 0xFFFF, 0x53C6}, // Configure AFE biasing { 67, 0xFFFF, 0x0344}, // Configure MUX biasing { 68, 0xFFFF, 0x0085}, // Configure LVDS biasing { 70, 0xFFFF, 0x4888}, // Configure reserved register { 81, 0xFFFF, 0x86A1}, // Configure reserved register {128, 0xFFFF, 0x460F}, // Configure calibration {176, 0xFFFF, 0x00F5}, // Configure AEC {180, 0xFFFF, 0x00FD}, // Configure AEC {181, 0xFFFF, 0x0144}, // Configure AEC {194, 0xFFFF, 0x0404}, // Configure sequencer {218, 0xFFFF, 0x160B}, // Configure sequencer {224, 0xFFFF, 0x3E13}, // Configure sequencer {391, 0xFFFF, 0x1010}, // Configure sequencer {456, 0xFFFF, 0x0386} // Configure sequencer }; #define VITA_SPI_SEQ5_QTY 7 /* Table 9. soft power up register uploads for mode dependent registers */ static uint16_t vita_spi_seq5[VITA_SPI_SEQ5_QTY][3] = { // Soft Power-Up // V1/SN/SE 10-bit mode with PLL { 32, 0xFFFF, 0x2007}, // Enable analog clock distribution { 10, 0xFFFF, 0}, // Release soft reset state { 64, 0xFFFF, 0x0001}, // Enable biasing block { 72, 0xFFFF, 0x0203}, // Enable charge pump { 40, 0xFFFF, 0x0003}, // Enable column multiplexer { 48, 0xFFFF, 0x0001}, // Enable AFE {112, 0xFFFF, 0x0007} // Enable LVDS transmitters }; //#define VITA_SPI_SEQ6_QTY 1 #define VITA_SPI_SEQ6_QTY 2 /* Table 10. enable sequencer register upload */ static uint16_t vita_spi_seq6[VITA_SPI_SEQ6_QTY][3] = { // {192, 0x0001, 0x0001} // [0] Enable Sequencer #if defined(TRIGGERED_MASTER_MODE) {192, 0x0051, 0x0011}, // [0] Enable Sequencer // [4] triggered_mode = on // [6] xsm_delay_enable = off {193, 0xFF00, 0} // [15:8] xsm_delay = 0x00 #elif defined(STRETCH_VITA_HTIMING) {192, 0x3841, 0x3841}, // {192, 0x0041, 0x0041}, // [0] Enable Sequencer // [6] xsm_delay_enable = on {193, 0xFF00, 0x0400} // [15:8] xsm_delay = 0x04 #else {192, 0x0001, 0x0001}, // [0] Enable Sequencer // [6] xsm_delay_enable = off {193, 0xFF00, 0} // [15:8] xsm_delay = 0x00 #endif }; #define VITA_AUTOEXP_ON_QTY 1 static uint16_t vita_autoexp_on_seq[VITA_AUTOEXP_ON_QTY][3] = { // Auto-Exposure ON {160, 0x0001, 0x0001} // [4] Auto Exposure enable }; #define VITA_ROI0_CROP_1080P_QTY 2 static uint16_t vita_roi0_crop_1080p_seq[VITA_ROI0_CROP_1080P_QTY][3] = { // Crop ROI0 from 1920x1200 to 1920x1080 // R257[10:0] y_start = 60 (0x3C) // R258[10:0] y_end = 60+1080 = 1140 (0x474) {257, 0xFFFF, 0x003C}, {258, 0xFFFF, 0x0474} }; #define VITA_MULT_TIMER_LINE_RESOLUTION_QTY 1 static uint16_t vita_mult_timer_line_resolution_seq[VITA_MULT_TIMER_LINE_RESOLUTION_QTY][3] = { // R199[15:0] mult_timer = (1920+88+44+148)/4 = 2200/4 = 550 (0x0226) //199, 0xFFFF, 0x0226 // R199[15:0] mult_timer = (1920+88+44+132)/4 = 2184/4 = 546 (0x0222) {199, 0xFFFF, 0x0222} }; static uint32_t spi_transfer (uint32_t v) { if (trace_spi) printf("SPITRANSFER: %x\n", v); idevice->put_spi_request(v); sem_wait(&sem_spi_response); return cv_spi_response; } static uint32_t vita_spi_read_internal(uint32_t uAddr) { return spi_transfer(uAddr<<17); } static int vita_spi_write(uint32_t uAddr, uint16_t uData) { uint32_t prev = 0; if (trace_spi) prev = vita_spi_read_internal(uAddr); spi_transfer(uAddr<<17 | 1 <<16 | uData); if (trace_spi) printf("SPIWRITE: [%x] %x -> %x %x\n", uAddr, prev, uData, vita_spi_read_internal(uAddr)); return 1; } static uint16_t vita_spi_read(uint32_t uAddr) { uint32_t ret = vita_spi_read_internal(uAddr); if (trace_spi) printf("SPIREAD: [%x] %x\n", uAddr, ret); //printf("[%s:%d] return %x\n", __FUNCTION__, __LINE__, ret); return ret; } /****************************************************************************** * This function performs a sequence of SPI write transactions. ******************************************************************************/ static void vita_spi_write_sequence(uint16_t pConfig[][3], uint32_t uLength) { uint16_t uData; int i; for ( i = 0; i < (int)uLength; i++) { if ( pConfig[i][1] != 0xFFFF) { uData = vita_spi_read(pConfig[i][0]) & ~pConfig[i][1]; printf( "\t 0x%04X\n", pConfig[i][1]); } } for ( i = 0; i < (int)uLength; i++) { if ( pConfig[i][1] == 0xFFFF) uData = pConfig[i][2]; else { uData = vita_spi_read(pConfig[i][0]) & ~pConfig[i][1]; uData |= pConfig[i][2]; } vita_spi_write(pConfig[i][0], uData); usleep(100); } } static void fmc_imageon_demo_enable_ipipe( void) { // VITA-2000 Initialization printf( "FMC-IMAGEON VITA Initialization ...\n"); uint16_t uData; uint32_t uStatus; int timeout; serdesdevice->set_serdes_training(0x03A6); uint32_t uManualTap = 25; printf( "VITA ISERDES - Setting Manual Tap to 0x%08X\n", uManualTap); serdesdevice->set_serdes_manual_tap(uManualTap); printf("VITA SPI Sequence 0 - Assert RESET_N pin\n"); serdesdevice->set_iserdes_control( VITA_ISERDES_RESET_BIT); serdesdevice->set_decoder_control( VITA_DECODER_RESET_BIT); usleep(10); // 10 usec serdesdevice->set_iserdes_control( 0); serdesdevice->set_decoder_control( 0); //jca sleep(1); // 1 sec (time to get clocks to lock) uData = vita_spi_read(0); printf("[%s:%d] %x\n", __FUNCTION__, __LINE__, uData); switch ( uData) { case 0: printf( "\tVITA Sensor absent\n"); break; case 0x560D: printf( "\tVITA-1300 Sensor detected\n"); break; case 0x5614: printf( "\tVITA-2000 Sensor detected\n"); break; case 0x5632: printf( "\tVITA-5000 Sensor detected\n"); break; case 0x56FA: printf( "\tVITA-25K Sensor detected\n"); break; default: printf( "\tERROR: Unknown CHIP_ID !!!\n"); break; } if ( uData != 0x5614) { printf( "\tERROR: Absent or unsupported VITA sensor !!!\n"); return; } printf("VITA SPI Sequence 1 - Enable Clock Management - Part 1\n"); vita_spi_write_sequence(vita_spi_seq1, VITA_SPI_SEQ1_QTY); { uint16_t uLock = 0; printf("VITA SPI Sequence 2 - Verify PLL Lock Indicator\n"); timeout = 10; while ( !(uLock) && --timeout) { usleep(100000); uLock = vita_spi_read(24); } if ( !timeout) { printf( "\tERROR: Timed Out while waiting for PLL lock to assert !!!\n"); return; } } printf("VITA SPI Sequence 3 - Enable Clock Management - Part 2\n"); vita_spi_write_sequence(vita_spi_seq3, VITA_SPI_SEQ3_QTY); printf("VITA SPI Sequence 4 - Required Register Upload\n"); vita_spi_write_sequence(vita_spi_seq4, VITA_SPI_SEQ4_QTY); printf("VITA SPI Sequence 5 - Soft Power-Up\n"); vita_spi_write_sequence(vita_spi_seq5, VITA_SPI_SEQ5_QTY); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); printf( "VITA ISERDES - Align Start\n"); serdesdevice->set_iserdes_control( VITA_ISERDES_ALIGN_START_BIT); printf( "VITA ISERDES - Waiting for ALIGN_BUSY to assert\n"); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); timeout = 9; while ( !(uStatus & 0x0200) && --timeout) { uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); //usleep(1); } if ( !timeout) { printf( "\tTimed Out !!!\n"); return; } serdesdevice->set_iserdes_control( 0); printf( "VITA ISERDES - Waiting for ALIGN_BUSY to de-assert\n"); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); timeout = 9; while ( (uStatus & 0x0200) && --timeout) { uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); usleep(1); } if ( !timeout) printf( "\tTimed Out !!!\n"); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n", uStatus); vita_spi_write_sequence(vita_roi0_crop_1080p_seq, VITA_ROI0_CROP_1080P_QTY); vita_spi_write_sequence(vita_mult_timer_line_resolution_seq, VITA_MULT_TIMER_LINE_RESOLUTION_QTY); vita_spi_write_sequence(vita_autoexp_on_seq, VITA_AUTOEXP_ON_QTY); vita_spi_write_sequence(vita_spi_seq6, VITA_SPI_SEQ6_QTY); serdesdevice->set_iserdes_control( VITA_ISERDES_FIFO_ENABLE_BIT); serdesdevice->set_decoder_control(VITA_DECODER_ENABLE_BIT); //jca sleep(1); vita_spi_write(192, 0); usleep(100); vita_spi_write(193, 0x0400); usleep(100); vita_spi_write(192, 0x40); usleep(100); vita_spi_write(199, 1); usleep(100); vita_spi_write(200, 0); usleep(100); vita_spi_write(194, 0); usleep(100); vita_spi_write(257, 0x3C); usleep(100); vita_spi_write(258, 0x0474); usleep(100); vita_spi_write(160, 0x10); usleep(100); uint32_t trigDutyCycle = 90; // exposure time is 90% of frame time (ie. 15msec) uint32_t vitaTrigGenDefaultFreq = (((1920+88+44+148)*(1080+4+5+36))>>2) - 2; idevice->set_trigger_cnt((vitaTrigGenDefaultFreq * (100-trigDutyCycle))/100 + 1); vita_spi_write(194, 0x0400); vita_spi_write(0x29, 0x0700); uint16_t vspi_data = vita_spi_read(192) | 0x71; usleep(100); vspi_data |= (4 << 11); // monitor0 Frame Start, monitor1 row-overhead-time (ROT) vita_spi_write(192, vspi_data); usleep(100); fprintf(stderr, "VITA SPI 192 %x\n", vspi_data); //jca usleep(10000); } #define DMA_BUFFER_SIZE 0x1240000 int main(int argc, const char **argv) { init_local_semaphores(); DmaManager *dma = platformInit(); serdesdevice = new ImageonSerdesRequestProxy(IfcNames_ImageonSerdesRequestS2H); hdmidevice = new HdmiGeneratorRequestProxy(IfcNames_HdmiGeneratorRequestS2H); idevice = new ImageonCaptureRequestProxy(IfcNames_ImageonCaptureRequestS2H); ImageonSerdesIndication imageonSerdesIndication(IfcNames_ImageonSerdesIndicationH2S); ImageonCaptureIndication imageonCaptureIndication(IfcNames_ImageonCaptureIndicationH2S); HdmiGeneratorIndication hdmiIndication(IfcNames_HdmiGeneratorIndicationH2S, hdmidevice); // read out monitor EDID from ADV7511 struct edid edid; init_i2c_hdmi(); int i2cfd = open("/dev/i2c-0", O_RDWR); fprintf(stderr, "Monitor EDID:\n"); for (int i = 0; i < 256; i++) { edid.raw[i] = i2c_read_reg(i2cfd, 0x3f, i); fprintf(stderr, " %02x", edid.raw[i]); if ((i % 16) == 15) { fprintf(stderr, " "); for (int j = i-15; j <= i; j++) { unsigned char c = edid.raw[j]; fprintf(stderr, "%c", (isprint(c) && isascii(c)) ? c : '.'); } fprintf(stderr, "\n"); } } close(i2cfd); parseEdid(edid); // for surfaceflinger long actualFrequency = 0; int status; status = setClockFrequency(0, 100000000, &actualFrequency); printf("[%s:%d] setClockFrequency 0 100000000 status=%d actualfreq=%ld\n", __FUNCTION__, __LINE__, status, actualFrequency); status = setClockFrequency(1, 160000000, &actualFrequency); printf("[%s:%d] setClockFrequency 1 160000000 status=%d actualfreq=%ld\n", __FUNCTION__, __LINE__, status, actualFrequency); status = setClockFrequency(3, 200000000, &actualFrequency); printf("[%s:%d] setClockFrequency 3 200000000 status=%d actualfreq=%ld\n", __FUNCTION__, __LINE__, status, actualFrequency); printf("[%s:%d] before set_i2c_mux_reset_n\n", __FUNCTION__, __LINE__); idevice->set_i2c_mux_reset_n(1); printf("[%s:%d] before setDeLine/Pixel\n", __FUNCTION__, __LINE__); for (int i = 0; i < 4; i++) { int pixclk = (long)edid.timing[i].pixclk * 10000; nlines = edid.timing[i].nlines; // number of visible lines npixels = edid.timing[i].npixels; int vblank = edid.timing[i].blines; // number of blanking lines int hblank = edid.timing[i].bpixels; int vsyncoff = edid.timing[i].vsyncoff; // number of lines in FrontPorch (within blanking) int hsyncoff = edid.timing[i].hsyncoff; int vsyncwidth = edid.timing[i].vsyncwidth; // width of Sync (within blanking) int hsyncwidth = edid.timing[i].hsyncwidth; fprintf(stderr, "lines %d, pixels %d, vblank %d, hblank %d, vwidth %d, hwidth %d\n", nlines, npixels, vblank, hblank, vsyncwidth, hsyncwidth); fprintf(stderr, "Using pixclk %d calc_pixclk %ld npixels %d nlines %d\n", pixclk, 60l * (long)(hblank + npixels) * (long)(vblank + nlines), npixels, nlines); if ((pixclk > 0) && (pixclk < 148000000)) { status = setClockFrequency(1, pixclk, 0); hblank--; // needed on zc702 hdmidevice->setDeLine(vsyncoff, // End of FrontPorch vsyncoff+vsyncwidth,// End of Sync vblank, // Start of Visible (start of BackPorch) vblank + nlines, vblank + nlines / 2); // End hdmidevice->setDePixel(hsyncoff, hsyncoff+hsyncwidth, hblank, hblank + npixels, hblank + npixels / 2); i2c_hdmi_start(); break; } } fbsize = nlines*npixels*4; int srcAlloc = portalAlloc(DMA_BUFFER_SIZE, 0); unsigned int *srcBuffer = (unsigned int *)portalMmap(srcAlloc, DMA_BUFFER_SIZE); printf("[%s:%d] before dma->reference\n", __FUNCTION__, __LINE__); memset(srcBuffer, 0xff, 16); portalCacheFlush(srcAlloc, srcBuffer, DMA_BUFFER_SIZE, 1); unsigned int ref_srcAlloc = dma->reference(srcAlloc); printf("[%s:%d] before setTestPattern\n", __FUNCTION__, __LINE__); hdmidevice->setTestPattern(1); //ret = fmc_iic_axi_init(uBaseAddr_IIC_FmcImageon); //fmc_iic_axi_GpoWrite(uBaseAddr_IIC_FmcImageon, fmc_iic_axi_GpoRead(uBaseAddr_IIC_FmcImageon) | 2); idevice->set_host_oe(1); printf("[%s:%d] before i2c_camera\n", __FUNCTION__, __LINE__); init_i2c_camera(); printf("[%s:%d] before i2c_hdmi\n", __FUNCTION__, __LINE__); init_i2c_hdmi(); printf("[%s:%d] after i2c_hdmi\n", __FUNCTION__, __LINE__); //init_vclk(); //jca sleep(5); printf("[%s:%d] now displaying test pattern\n", __FUNCTION__, __LINE__); sleep(20); hdmidevice->setTestPattern(0); // Reset DCMs /* puts the DCM_0 PCORE into reset */ //fmc_iic_axi_GpoWrite(uBaseAddr_IIC_FmcImageon, fmc_iic_axi_GpoRead(uBaseAddr_IIC_FmcImageon) | 4); //jca usleep(200000); /* releases the DCM_0 PCORE from reset */ //fmc_iic_axi_GpoWrite(uBaseAddr_IIC_FmcImageon, fmc_iic_axi_GpoRead(uBaseAddr_IIC_FmcImageon) & ~4); //jca usleep(500000); // FMC-IMAGEON VITA Receiver Initialization printf( "FMC-IMAGEON VITA Receiver Initialization ...\n"); idevice->startWrite(ref_srcAlloc, DMA_BUFFER_SIZE); fmc_imageon_demo_enable_ipipe(); printf("[%s:%d] passed fmc_imageon_demo_init\n", __FUNCTION__, __LINE__); //usleep(200000); hdmidevice->waitForVsync(0); //jca usleep(2000000); printf("[%s:%d] before startWrite\n", __FUNCTION__, __LINE__); //idevice->startWrite(ref_srcAlloc, DMA_BUFFER_SIZE); int counter = 0; while (1/*getchar() != EOF*/) { printf("[%s:%d] iserdes %x\n", __FUNCTION__, __LINE__, read_iserdes_control()); static int regids[] = {24, 97, 186, 0}; int i; for (i = 0; regids[i]; i++) printf("[%s:%d] spi %d. %x\n", __FUNCTION__, __LINE__, regids[i], vita_spi_read(regids[i])); printf("counter %d\n", counter); if (counter == 1 && argc > 1) { portalCacheFlush(srcAlloc, srcBuffer, DMA_BUFFER_SIZE, 1); int fd = creat("tmp.outfile", 0666); int cnt = write(fd, srcBuffer, DMA_BUFFER_SIZE); printf("[%s:%d] length written %d.\n", __FUNCTION__, __LINE__, cnt); close(fd); } counter++; memdump((unsigned char *)srcBuffer, 32, "MEM"); usleep(1000000); } return 0; } ================================================ FILE: examples/leds/LedController.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import GetPut::*; import Leds::*; typedef struct { Bit#(8) leds; Bit#(32) duration; } LedControllerCmd deriving (Bits); interface LedControllerRequest; method Action setLeds(Bit#(8) v, Bit#(32) duration); endinterface interface LedPins; interface LEDS leds; interface Clock deleteme_unused_clock; interface Reset deleteme_unused_reset; endinterface interface LedController; interface LedControllerRequest request; interface LedPins leds; endinterface module mkLedController(LedController); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reg#(Bit#(8)) ledsValue <- mkReg(0); Reg#(Bit#(32)) remainingDuration <- mkReg(0); FIFO#(LedControllerCmd) ledsCmdFifo <- mkSizedFIFO(32); rule updateLeds; let duration = remainingDuration; if (duration == 0) begin let cmd <- toGet(ledsCmdFifo).get(); $display("ledsValue <= %b", cmd.leds); ledsValue <= cmd.leds; duration = cmd.duration; end else begin duration = duration - 1; end remainingDuration <= duration; endrule interface LedControllerRequest request; method Action setLeds(Bit#(8) v, Bit#(32) duration); $display("Enqueing v=%d duration=%d", v, duration); ledsCmdFifo.enq(LedControllerCmd { leds: v, duration: duration }); endmethod endinterface interface LedPins leds; interface LEDS leds; method leds = truncate(ledsValue._read); endinterface interface deleteme_unused_clock = defaultClock; interface deleteme_unused_reset = defaultReset; endinterface endmodule ================================================ FILE: examples/leds/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = LedControllerRequest:LedController.request BSVFILES = LedController.bsv CPPFILES= testleds.cpp PIN_TYPE = LedPins PIN_TYPE_INCLUDE = LedController PINOUT_FILE = pinout.json AUTOTOP = --interface pins:LedController.leds include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/leds/pinout.json ================================================ { "leds[0]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L0" }, "leds[1]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L1" }, "leds[2]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L2" }, "leds[3]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L3" }, "leds[4]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L4" }, "leds[5]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L5" }, "leds[6]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L6" }, "leds[7]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L7" } } ================================================ FILE: examples/leds/testleds.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "LedControllerRequest.h" int main(int argc, const char **argv) { LedControllerRequestProxy *device = new LedControllerRequestProxy(IfcNames_LedControllerRequestS2H); printf("Starting LED test"); #ifdef SIMULATION // SIMULATION does not run very many cycles per second int blinkinterval = 10; #else int blinkinterval = 100000000; // 100MHz cycles #endif int blinkon = 10; // 1010 int blinkoff = 5; // 0101 int sleepinterval = 1; // seconds for (int i = 0; i < 20; i++) { printf("blink %d", blinkon); device->setLeds(blinkon, blinkinterval); sleep(sleepinterval); printf("blink off %d", blinkoff); device->setLeds(blinkoff, blinkinterval); sleep(sleepinterval); } printf("Done.\n"); } ================================================ FILE: examples/linking/GetInverse.v ================================================ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module GetInverse(CLK, RST, get, EN_get, RDY_get, put, EN_put, RDY_put ); parameter DATA_WIDTH = 1; input CLK; input RST; output [DATA_WIDTH-1,0] get; input [DATA_WIDTH-1,0] put; input EN_get; input EN_put; output RDY_get; output RDY_put; // will this work? assign get = put; assign RDY_get = EN_put; assign RDY_put = EN_get; endmodule // GetInverse ================================================ FILE: examples/linking/LinkerLib.bsv ================================================ // Generic definitions that should go in a shared library. typeclass InverseIFC#(type a, type b) dependencies (a determines b, b determines a); endtypeclass interface GetInverse#(type a); interface Get#(a) mod; interface Put#(a) inverse; endinterface interface PutInverse#(type a); interface Put#(a) mod; interface Get#(a) inverse; endinterface import "BVI" GetInverse = module mkGetInverseBvi(GetInverse#(Bits#(asz))); parameter DATA_SIZE = asz; default_clock (CLK); default_reset (RST); interface Get mod; method get get() enable(EN_get) ready (RDY_get); endinterface interface Put inverse; method put(put) enable (EN_put) ready (RDY_put); endinterface endmodule module mkGetInverse(GetInverse#(a)) provisos (Bits#(a, asz)); inverter <- mkGetInverseBvi(); interface Get mod; method a get(); let v <- inverter.mod.get(); return unpack(v); endmethod endinterface interface Put inverse; method Action put(a v); inverter.inverse.put(pack(v)); endmethod endinterface endmodule import "BVI" PutInverse = module mkPutInverseBvi(PutInverse#(Bits#(asz))); parameter DATA_SIZE = asz; default_clock (CLK); default_reset (RST); interface Put mod; method put(put) enable(EN_put) ready (RDY_put); endinterface interface Get inverse; method get get() enable (EN_get) ready (RDY_get); endinterface endmodule module mkPutInverse(PutInverse#(a)) provisos (Bits#(a, asz)); inverter <- mkPutInverseBvi(); interface Put mod; method Action put(a v); inverter.mod.put(pack(v)); endmethod endinterface interface Get inverse; method a get(); let v <- inverter.inverse.get(); return unpack(v); endmethod endinterface endmodule interface Inverter#(type ifcType, type invifcType); interface ifcType mod; interface invifcType inverse; endinterface interface SynthInverter0IFC#(type ifcType); interface ifcType mod; endinterface interface SynthInverter1IFC#(type param1, type ifcType); interface param1 arg1; interface ifcType mod; endinterface interface SynthInverter2IFC#(type param1, type param2, type ifcType); interface param1 arg1; interface param2 arg2; interface ifcType mod; endinterface interface SynthInverter3IFC#(type param1, type param2, type param3, type ifcType); interface param1 arg1; interface param2 arg2; interface param3 arg3; interface ifcType mod; endinterface ================================================ FILE: examples/linking/Makefile ================================================ clean: rm -f mk*.v *.b[iao] ================================================ FILE: examples/linking/Processor.bsv ================================================ interface Cache; interface Put#(CacheRequest) request; interface Get#(CacheResponse) response; endinterface // we want to be able to synthesize this, but it has interface parameters module mkProcessor#(Cache cache, Peripherals peripherals)(Processor); rule foo; cache.request.put(req); endrule rule bar; let response <- cache.response.get(); endrule endmodule // original top level module mkTopLevel(Pins); Memory memory <- mkMemory(); Cache cache <- mkCache(memory); // standard parameter use example Vector#(NumProcessors,Processor) processors <- replicateM(mkProcessor(cache)); // Vector#(NumCaches, Memory) mems <- replicateM(mkMemory); Vector#(NumCaches, Cache) caches <- mapM(mkCache, mems); interface pins = memory.pins; endmodule ================================================ FILE: examples/linking/ProcessorTop.bsv ================================================ import Processor_Generated::*; //==================================================================================================================== module mkProcessorTop(Pins); Memory memory <- mkMemory(); Cache cache <- mkCache(memory); // actually uses the wrapper from Processor_Generated.bsv Vector#(NumProcessors,Processor) processors <- replicateM(mkProcessor(cache)); // same here Vector#(NumCaches, Memory) mems <- replicateM(mkMemory); Vector#(NumCaches, Cache) caches <- mapM(mkCache, mems); // and here interface mod; interface Pins pins = memory.pins; endinterface endmodule ================================================ FILE: examples/linking/Processor_Generated.bsv ================================================ // To be auto generated from Linking.bsv import LinkerLib::*; import Processor::*; //================================================================================ // Parts corresponding to Cache interface interface CacheInverse; interface GetInverse#(CacheRequest) request; interface PutInverse#(CacheResponse) response; endinterface instance InverseIFC#(Cache, CacheInverse); endinstance //define how to connect Cache and it's inverse instance Connectable#(Cache, CacheInverse); module mkConnection#(Cache x, CacheInverse y)(Empty); mkConnection( x.request, y.request); mkConnection(x.response, y.response); endmodule endinstance // module to create Cache Inverter. This needs to have the same schedulign restrictions as the // initial parameter module mkCacheInverter(Inverter#(Cache, CacheInverse)); GetInverse requestlink <- mkGetInverter(); // one for each sub component in Cache interface PutInverse responselink <- mkPutInverter(); interface Cache mod; interface Get request = requestlink.mod; interface Put response = responselink.mod; endinterface interface CacheInverse inverse; interface GetInverse request = requestlink.inverse; interface PutInverse response = responselink.inverse; endinterface endmodule //================================================================================ // Parts corresponding to mkCache //linked version of mkCache. Hooks ups missing memory module module mkCacheSynth(SynthInverter1IFC#(MemoryInverse, Cache)); // parameter setup let memoryInverter <- mkMemoryInverter(); // build base module (use original version) let cache <- Cache::mkCache(memoryInverter.mod); // hook up interface interface arg1 = memoryInverter.inverse; interface mod = cache; endmodule import "BVI" mkCacheSynth = module mkCacheBVI(Cache); //... endmodule module mkCache#(Memory arg1)(Cache); let x <- mkCacheBVI; // It would be great if we could check schedule here. mkConnection(x.arg1, arg1); return x.mod; endmodule //============================================================================================================= // Parts Corresponding to mkProcessor // This is the module we can synthesize module mkProcessorSynth(SynthInverter2IFC#(CacheInverse, PeripheralsInverse, Processor)); //instantiate param versions of modules let cacheparam <- mkCacheInverter(); let cache = cacheparam.mod; let peripheralsparam <- mkPeripheralsInverter(); let peripherals = peripheralsparam.mod; //instantiate actual module let processor <- Processor::mkProcessor(cache, peripherals); //hook params and return ifc interface mod = processor; interface arg1 = cacheparam.inverse; interface arg2 = peripheralsparam.inverse; endmodule // to enable separate compilation import "BVI" mkProcessorSynth = module mkProcessorBVI(ProcessorBvi); endmodule module mkProcessor#(Cache arg1, Peripherals arg2)(Processor); let x <- mkProcessorBVI(); mkConnection(cache, x.arg1); mkConnection(peripherals, x.arg2); return x.mod; endmodule ================================================ FILE: examples/matmul/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=../matmul RBMDIR=../rbm TESTCPPFILES=testmm.cpp CONNECTALFLAGS = -D J_VALUE=1 -D K_VALUE=1 -D N_VALUE=1 -D DataBusWidth=32 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/matmul/Makefile.mm ================================================ BSVFILES += $(CONNECTALDIR)/lib/rbm/bsv/RbmTypes.bsv $(CONNECTALDIR)/lib/rbm/bsv/Timer.bsv CPPFILES += $(CONNECTALDIR)/lib/matmul/cpp/portalmat.cpp $(TESTCPPFILES) CONNECTALFLAGS += -D IMPORT_HOSTIF -D MATRIX_TN -D MATMUL_HACK CONNECTALFLAGS += --bscflags="+RTS -K26777216 -RTS" CONNECTALFLAGS += --bsvpath $(CONNECTALDIR)/lib/matmul/bsv CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/matmul/cpp Dma = Dma PINS = Std FAMILY=$(shell echo $(BOARD) | sed 's/z.*/zynq/' | sed 's/k.*/kintex/' | sed 's/v.*/virtex/' | sed 's/miniitx.*/zynq/') ## ## To build testmm for Android on Zynq ## cd $(CONNECTALDIR); cd ..; git clone git://github.com:cambridgehackers/opencv-android-sdk.git ## ifdef CUDA_PERF_TEST OPENCVDIR=/scratch/opencv-cuda/opencv-2.4.9/install/ CONNECTALFLAGS += -I$(OPENCVDIR)/include CONNECTALFLAGS += -L$(OPENCVDIR)/lib CONNECTALFLAGS += -L/usr/local/cuda-5.5/lib64 CONNECTALFLAGS += --stl=stlport_static CONNECTALFLAGS += --clib z CONNECTALFLAGS += --clib cuda CONNECTALFLAGS += --clib cudart CONNECTALFLAGS += --clib nppi CONNECTALFLAGS += --clib nppc CONNECTALFLAGS += --clib npps CONNECTALFLAGS += --clib cufft CONNECTALFLAGS += --clib opencv_core CONNECTALFLAGS += --clib opencv_gpu CONNECTALFLAGS += --clib opencv_imgproc CONNECTALFLAGS += --clib opencv_core CONNECTALFLAGS += --clib opencv_objdetect CONNECTALFLAGS += --clib opencv_imgproc CONNECTALFLAGS += --clib cublas CPPFILES += $(CONNECTALDIR)/lib/matmul/cpp/cuda.cpp else CONNECTALFLAGS += --clib opencv_core --stl=stlport_static endif ifeq (zynq,$(FAMILY)) NDK_DIR=$(shell ndk-which gcc | sed 's:toolchains.*::') OPENCVDIR=$(CONNECTALDIR)/../opencv-android-sdk/sdk/native/ CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/matmul/cpp -I$(OPENCVDIR)/jni/include -L$(OPENCVDIR)/libs/armeabi-v7a -lz CONNECTALFLAGS += -S$(NDK_DIR)/sources/cxx-stl/stlport/libs/armeabi-v7a/libstlport_static.a PLATFORM_NUMBER_OF_MASTERS=2 endif ifeq (bluesim,$(FAMILY)) PLATFORM_NUMBER_OF_MASTERS=2 endif synth-ip.tcl: ln -svf $(CONNECTALDIR)/examples/matmul/synth-ip.tcl . prebuild:: synth-ip.tcl if [ "$(BOARD)" != "bluesim" -a "$(BOARD)" != verilator ] ; then cd $(BOARD); BUILDCACHE_CACHEDIR=$(BUILDCACHE_CACHEDIR) $(BUILDCACHE) vivado -notrace -mode batch -source ../synth-ip.tcl; fi FPGAMAKE_CONNECTALFLAGS += -P mkMmTile --xci=$(IPDIR)/$(BOARD)/fp_add/fp_add.xci --xci=$(IPDIR)/$(BOARD)/fp_mul/fp_mul.xci ================================================ FILE: examples/matmul/Makefile.mmif ================================================ S2H_INTERFACES += MmRequestTN:MatrixTN.mmRequest:host TimerRequest:MatrixTN.timerRequest H2S_INTERFACES += MatrixTN\#\(TDiv\#\(DataBusWidth,32\)\):MmIndication,TimerIndication:host MEM_READ_INTERFACES = lMatrixTN.readClients MEM_WRITE_INTERFACES = lMatrixTN.writeClients ================================================ FILE: examples/matmul/clocks.tcl ================================================ foreach {pat} {CLK_GATE_hdmi_clock_if CLK_*deleteme_unused_clock* CLK_GATE_*deleteme_unused_clock* RST_N_*deleteme_unused_reset*} { foreach {net} [get_nets $pat] { disconnect_net -net $net -objects [get_pins -of_objects $net] } } ================================================ FILE: examples/matmul/design-vc707.tcl ================================================ ############################################################### ### Tcl Variables ############################################################### #set tclParams [list ... ] set tclParams [list place.closeImportedSites 1 \ hd.StrictContainRouting 1 \ ] #Define location for "Tcl" directory. Defaults to "../Tcl" set tclHome "../Tcl" if {[file exists $tclHome]} { set tclDir $tclHome } elseif {[file exists "./Tcl"]} { set tclDir "./Tcl" } else { error "ERROR: No valid location found for required Tcl scripts. Set \$tclDir in design.tcl to a valid location." } ############################################################### ### Part Variables - Define Device, Package, Speedgrade ############################################################### set device "xc7vx485t" set package "ffg1761" set speed "-2" set part $device$package$speed ############################################################### ### Setup Variables ############################################################### ####flow control set run.topSynth 1 set run.oocSynth 1 set run.tdImpl 1 set run.oocImpl 0 set run.topImpl 0 set run.flatImpl 0 ####Report and DCP controls - values: 0-required min; 1-few extra; 2-all set verbose 1 set dcpLevel 1 ####Output Directories set synthDir "./Synth" set implDir "./Implement" set dcpDir "./Checkpoint" ####Input Directories set srcDir "./vc707" set rtlDir "$srcDir/verilog" set prjDir "$srcDir/prj" set xdcDir "$srcDir/constraints" set coreDir "$srcDir/cores" set netlistDir "$srcDir/netlist" ####Source required Tcl Procs source $tclDir/design_utils.tcl source $tclDir/synth_utils.tcl source $tclDir/impl_utils.tcl source $tclDir/hd_floorplan_utils.tcl ############################################################### ### Top Definition ############################################################### set top "mkPcieTop" add_module $top set_attribute module $top top_level 1 set_attribute module $top vlog [concat [glob $rtlDir/top/*.v] [glob $rtlDir/lib/*.v] ] set_attribute module $top ip [glob /scratch/jamey/connectal/generated/xilinx/zc706/*/*.xci] #set_attribute module $top vlog_headers [glob $rtlDir/top/*Stub.v] set_attribute module $top synth ${run.topSynth} add_implementation $top set_attribute impl $top top $top set_attribute impl $top implXDC [glob $xdcDir/*.xdc] set_attribute impl $top impl ${run.topImpl} set_attribute impl $top hd.impl 1 #################################################################### ### OOC Module Definition and OOC Implementation for each instance #################################################################### set module1 "pcie_7x_0" add_module $module1 set_attribute module $module1 vlog [concat [glob $rtlDir/lib/*.v] [glob $rtlDir/mmtile/*.v]] set_attribute module $module1 ip [glob /scratch/jamey/connectal/generated/xilinx/vc707/*/*.xci] set_attribute module $module1 synth ${run.oocSynth} set instance "top_top_mm_dmaMMF_dmaMMF_mmTiles_0" add_ooc_implementation $instance set_attribute ooc $instance module $module1 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing #################################################################### ### Create TopDown implementation run #################################################################### set module1File "$synthDir/$module1/${module1}_synth.dcp" add_implementation TopDown set_attribute impl TopDown top $top set_attribute impl TopDown implXDC [list $xdcDir/${top}_flpn.xdc] set_attribute impl TopDown td.impl 1 set_attribute impl TopDown cores [list $module1File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ ] set_attribute impl TopDown impl ${run.tdImpl} set_attribute impl TopDown route 0 #################################################################### ### Create Flat implementation run #################################################################### add_implementation Flat set_attribute impl Flat top $top set_attribute impl Flat implXDC [list $xdcDir/${top}_flpn.xdc] set_attribute impl Flat cores [list $module1File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ ] set_attribute impl Flat impl ${run.flatImpl} ######################################################################## ### Task / flow portion ######################################################################## # Build the designs source $tclDir/run.tcl exit ================================================ FILE: examples/matmul/design.tcl ================================================ ############################################################### ### Tcl Variables ############################################################### #set tclParams [list ... ] set tclParams [list place.closeImportedSites 1 \ hd.StrictContainRouting 1 \ ] #Define location for "Tcl" directory. Defaults to "../Tcl" set tclHome "../Tcl" if {[file exists $tclHome]} { set tclDir $tclHome } elseif {[file exists "./Tcl"]} { set tclDir "./Tcl" } else { error "ERROR: No valid location found for required Tcl scripts. Set \$tclDir in design.tcl to a valid location." } ############################################################### ### Part Variables - Define Device, Package, Speedgrade ############################################################### set device "xc7z045" set package "ffg900" set speed "-2" set part $device$package$speed ############################################################### ### Setup Variables ############################################################### ####flow control set run.topSynth 0 set run.oocSynth 0 set run.tdImpl 0 set run.oocImpl 1 set run.topImpl 1 set run.flatImpl 0 ####Report and DCP controls - values: 0-required min; 1-few extra; 2-all set verbose 1 set dcpLevel 1 ####Output Directories set synthDir "./Synth" set implDir "./Implement" set dcpDir "./Checkpoint" ####Input Directories set srcDir "./zc706" set rtlDir "$srcDir/verilog" set prjDir "$srcDir/prj" set xdcDir "$srcDir/constraints" set coreDir "$srcDir/cores" set netlistDir "$srcDir/netlist" ####Source required Tcl Procs source $tclDir/design_utils.tcl source $tclDir/synth_utils.tcl source $tclDir/impl_utils.tcl source $tclDir/hd_floorplan_utils.tcl ############################################################### ### Top Definition ############################################################### set top "mkZynqTop" add_module $top set_attribute module $top top_level 1 set_attribute module $top vlog [concat [glob $rtlDir/top/*.v] [glob $rtlDir/lib/*.v] ] set_attribute module $top ip [glob /scratch/jamey/connectal/generated/xilinx/zc706/*/*.xci] #set_attribute module $top vlog_headers [glob $rtlDir/top/*Stub.v] set_attribute module $top synth ${run.topSynth} add_implementation $top set_attribute impl $top top $top set_attribute impl $top implXDC [glob $xdcDir/*.xdc] set_attribute impl $top impl ${run.topImpl} set_attribute impl $top hd.impl 1 #################################################################### ### OOC Module Definition and OOC Implementation for each instance #################################################################### set module1 "mkMmTile" add_module $module1 set_attribute module $module1 vlog [concat [glob $rtlDir/lib/*.v] [glob $rtlDir/mmtile/*.v]] set_attribute module $module1 ip [glob /scratch/jamey/connectal/generated/xilinx/zc706/*/*.xci] set_attribute module $module1 synth ${run.oocSynth} set instance "top_top_mm_dmaMMF_dmaMMF_mmTiles_0" add_ooc_implementation $instance set_attribute ooc $instance module $module1 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing #################################################################### ### Create TopDown implementation run #################################################################### set module1File "$synthDir/$module1/${module1}_synth.dcp" add_implementation TopDown set_attribute impl TopDown top $top set_attribute impl TopDown implXDC [list $xdcDir/${top}_flpn.xdc] set_attribute impl TopDown td.impl 1 set_attribute impl TopDown cores [list $module1File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ ] set_attribute impl TopDown impl ${run.tdImpl} set_attribute impl TopDown route 0 #################################################################### ### Create Flat implementation run #################################################################### add_implementation Flat set_attribute impl Flat top $top set_attribute impl Flat implXDC [list $xdcDir/${top}_flpn.xdc] set_attribute impl Flat cores [list $module1File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ ] set_attribute impl Flat impl ${run.flatImpl} ######################################################################## ### Task / flow portion ######################################################################## # Build the designs source $tclDir/run.tcl exit ================================================ FILE: examples/matmul/mkZynqTop_flpn.xdc ================================================ create_pblock mmtile_0 resize_pblock mmtile_0 -add {SLICE_X96Y270:SLICE_X171Y335 DSP48_X4Y108:DSP48_X6Y133 RAMB18_X5Y108:RAMB18_X8Y133 RAMB36_X5Y54:RAMB36_X8Y66} endgroup add_cells_to_pblock mmtile_0 [get_cells [list top_top_mm_dmaMMF_dmaMMF_mmTiles_0]] -clear_locs ================================================ FILE: examples/matmul/perf.txt ================================================ These measurements based on * dbn 9587023178c555dc8028cabb910e4571ae910798 * connectal 53a86e0d2e5dfbe6a034d166c99aa39b999afd71 Bluesim: N=2, J=1, K=4 MemLatency=1, FPLatency=1 NumMasters=1 64x64 * 64x64 mmfDone cycles=183352 macs 262144 cycles 183352.000000 macs/cycle: 1.429731 memory read beats 163840 utilization (beats/cycle): 0.893582 memory write beats 2048 utilization (beats/cycle): 0.011170 N=2, J=1, K=4 MemLatency=1, FPLatency=1 NumMasters=5 64x64 * 64x64 mmfDone cycles=147480 macs 262144 cycles 147480.000000 macs/cycle: 1.777488 memory read beats 163840 utilization (beats/cycle): 1.110930 memory write beats 2048 utilization (beats/cycle): 0.013887 N=4, J=1, K=16 MemLatency=1, FPLatency=1 NumMasters=17 64x64 * 64x64 mmfDone cycles=147483 macs 262144 cycles 147483.000000 macs/cycle: 1.777452 memory read beats 69632 utilization (beats/cycle): 0.472136 memory write beats 1024 utilization (beats/cycle): 0.006943 N=4, J=1, K=16 MemLatency=1, FPLatency=1 NumMasters=1 64x64 * 64x64 mmfDone cycles=79674 macs 262144 cycles 79674.000000 macs/cycle: 3.290208 memory read beats 69632 utilization (beats/cycle): 0.873961 memory write beats 1024 utilization (beats/cycle): 0.012852 N=4, J=1, K=32 MemLatency=1, FPLatency=1 NumMasters=1 64x64 * 64x64 mmfDone cycles=76689 macs 262144 cycles 76689.000000 macs/cycle: 3.418274 memory read beats 67584 utilization (beats/cycle): 0.881274 memory write beats 1024 utilization (beats/cycle): 0.013353 ZC702, 100MHz: N=2, J=1, K=4 MemLatency=?, FPLatency=5 NumMasters=1 64x64 * 64x64 mmfDone cycles=189029 macs 262144 cycles 189029.000000 macs/cycle: 1.386793 memory read beats 163840 utilization (beats/cycle): 0.866745 memory write beats 2048 utilization (beats/cycle): 0.010834 ============================================================ Bluesim N=2, J=4, K=4 MemLatency=1, NumMasters=1 mmfDone cycles=19876 macs 262144 cycles 19876.000000 macs/cycle: 13.188972 memory read beats 16384 utilization (beats/cycle): 0.824311 memory write beats 1024 utilization (beats/cycle): 0.051519 N=2, J=8, K=8 MemLatency=1, NumMasters=1 mmfDone cycles=34715 macs 262144 cycles 34715.000000 macs/cycle: 7.551318 memory read beats 32768 utilization (beats/cycle): 0.943915 memory write beats 2048 utilization (beats/cycle): 0.058995 N=2, J=16, K=16 MemLatency=1, NumMasters=1 mmfDone cycles=17291 macs 262144 cycles 17291.000000 macs/cycle: 15.160720 memory read beats 16384 utilization (beats/cycle): 0.947545 memory write beats 2048 utilization (beats/cycle): 0.118443 N=4, J=4, K=4 MemLatency=1, NumMasters=1 mmfDone cycles=36942 macs 262144 cycles 36942.000000 macs/cycle: 7.096097 memory read beats 32768 utilization (beats/cycle): 0.887012 memory write beats 1024 utilization (beats/cycle): 0.027719 N=4, J=8, K=8 MemLatency=1, NumMasters=1 mmfDone cycles=18793 macs 262144 cycles 18793.000000 macs/cycle: 13.949023 memory read beats 16384 utilization (beats/cycle): 0.871814 memory write beats 1024 utilization (beats/cycle): 0.054488 N=4, J=16, K=16 MemLatency=1, NumMasters=1 *failed to build* ZC706, 100MHz: N=2, J=4, K=4 MemLatency=?, NumMasters=1 mmfDone cycles=195439 macs 262144 cycles 195439.000000 macs/cycle: 1.341309, 134 MFLOPs memory read beats 163840 utilization (beats/cycle): 0.838318 memory write beats 2048 utilization (beats/cycle): 0.010479 N=2, J=4, K=4 MemLatency=?, NumMasters=4 mmfDone cycles=68374 macs 262144 cycles 68374.000000 macs/cycle: 3.833972, 383 MFLOPs memory read beats 65536 utilization (beats/cycle): 0.958493 memory write beats 2048 utilization (beats/cycle): 0.029953 N=2, J=8, K=4 MemLatency=?, NumMasters=4 mmfDone cycles=46017 macs 262144 cycles 46017.000000 macs/cycle: 5.696677, 570 MFLOPS memory read beats 49152 utilization (beats/cycle): 1.068127 memory write beats 2048 utilization (beats/cycle): 0.044505 N=2, J=8, K=4 MemLatency=?, NumMasters=4 mmfDone cycles=41844 macs 262144 cycles 41844.000000 macs/cycle: 6.264793, 626 MFLOPS memory read beats 32768 utilization (beats/cycle): 0.783099 memory write beats 2048 utilization (beats/cycle): 0.048944 ============================================================ Bluesim: N=2, J=8, K=8 MemLatency=1, NumMasters=4 N=2, J=16, K=16, 64x64 MemLatency=1, NumMasters=4 mmfDone cycles=21048 macs 262144 cycles 21048.000000 macs/cycle: 12.454580 memory read beats 16384 utilization (beats/cycle): 0.778411 memory write beats 2048 utilization (beats/cycle): 0.097301 N=2, J=16, K=16, 256x256 MemLatency=1, NumMasters=4 mmfDone cycles=1131864 macs 16777216 cycles 1131864.000000 macs/cycle: 14.822643 memory read beats 1048576 utilization (beats/cycle): 0.926415 memory write beats 32768 utilization (beats/cycle): 0.028950 ZC706, 100MHz: N=2, J=8, K=8 MemLatency=?, NumMasters=4 mmfDone cycles=61676 macs 262144 cycles 61676.000000 macs/cycle: 4.250340 425 MFLOPs memory read beats 32768 utilization (beats/cycle): 0.531293 memory write beats 2048 utilization (beats/cycle): 0.033206 ================================================ FILE: examples/matmul/synth-ip.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" connectal_synth_ip floating_point 7.0 fp_add [list CONFIG.Axi_Optimize_Goal {Performance} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] connectal_synth_ip floating_point 7.0 fp_mul [list CONFIG.Operation_Type {Multiply} CONFIG.Axi_Optimize_Goal {Resources} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] ================================================ FILE: examples/matmul/testmm.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifdef MATRIX_NT #include "MmRequestNT.h" MmRequestNTProxy *mmdevice = 0; #else #ifdef MATRIX_TN #include "MmRequestTN.h" MmRequestTNProxy *mmdevice = 0; #endif #endif #include #include #include #include // frexp(), fabs() #include #include "portalmat.h" static int verbose = 0; #ifdef CUDA_PERF_TEST void cuda_test(); long int cuda_mm(cv::Mat& src1, cv::Mat& src2, cv::Mat& dst); #endif void *dbgThread(void *) { while (1) { sleep(2); mmdevice->debug(); } return 0; } bool compare(cv::Mat& m1, cv::Mat& m2, float epsilon) { bool rv = (m1.rows == m2.rows); rv &= (m1.cols == m2.cols); for(int i = 0; i < m1.rows; i++){ for(int j = 0; j < m1.cols; j++) { float err = fabs(m1.at(i,j)-m2.at(i,j))/m1.at(i,j); bool pass = (epsilon > err); if (verbose && !pass) fprintf(stderr, "%f %f\n", m1.at(i,j), m2.at(i,j)); rv &= pass; } } return rv; } int main(int argc, const char **argv) { fprintf(stderr, "%s %s\n", __DATE__, __TIME__); bool sane = 1; #define LARGE_MAT #ifdef LARGE_MAT #ifdef SIMULATION int A = 64; int B = 256; #else int A = 256; int B = 2048; #endif if (argc > 1) { B = strtoul(argv[1], 0, 0); A = 2*B; } srand(A*B); cv::Mat m1(A,B,CV_32F); cv::Mat m2(B,A,CV_32F); for(int a = 0; a < A; a++){ for(int b = 0; b < B; b++){ float v = (float)(rand() % 10); m2.at(b,a) = (A*B)+v; m1.at(a,b) = v; } } #else cv::Mat m1 = (cv::Mat_(4,8) << 11,12,13,14,15,16,17,18, 21,22,23,24,25,26,27,28, 31,32,33,34,35,36,37,38, 41,42,43,44,45,46,47,48 ); cv::Mat m2 = (cv::Mat_(8,4) << 51,62,53,54, 55,56,57,58, 61,62,63,64, 65,66,67,68, 71,72,73,74, 75,76,77,78, 81,82,83,84, 85,86,87,88 ); #endif #ifndef CUDA_PERF_TEST #ifdef MATRIX_NT mmdevice = new MmRequestNTProxy(IfcNames_MmRequestNTS2H); #else #ifdef MATRIX_TN mmdevice = new MmRequestTNProxy(IfcNames_MmRequestTNS2H); #endif #endif MmIndication *mmdeviceIndication = new MmIndication(IfcNames_MmIndicationH2S); //TimerRequestProxy *timerdevice = new TimerRequestProxy(IfcNames_TimerRequestPortalS2H); TimerIndication timerdeviceIndication(IfcNames_TimerIndicationH2S); DmaManager *dma = platformInit(); if(sem_init(&mul_sem, 1, 0)){ fprintf(stderr, "failed to init mul_sem\n"); return -1; } long req_freq = 100000000; long freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); matAllocator = new PortalMatAllocator(dma); FILE *octave_file = fopen("foo.m", "w"); fprintf(stderr, "OpenCV matmul\n"); portalTimerStart(0); cv::Mat m3 = m1 * m2; //uint64_t opencv_hw_cycles = portalTimerLap(0); PortalMat tm3; fprintf(stderr, "Naive matmul\n"); portalTimerStart(0); tm3.naive_mul(m1,m2, octave_file); //uint64_t naive_hw_cycles = portalTimerLap(0); if (1) { fprintf(stderr, "DumpMat\n"); dumpMatOctave("m1", "%10.5f", m1, octave_file); dumpMatOctave("m2", "%10.5f", m2, octave_file); dumpMatOctave("m3", "%10.5f", m3, octave_file); dumpMatOctave("tm3", "%10.5f", tm3, octave_file); fclose(octave_file); sane = tm3.compare(m3, 0, 0, 0.0001, 0, false); fprintf(stderr, "sane=%d\n", sane); fflush(stdout); } #ifdef MATRIX_TN fprintf(stderr, "pm1t\n"); PortalMat pm1t(m1.t()); fprintf(stderr, "pm2\n"); PortalMat pm2(m2); pm1t.reference(); pm2.reference(); #else #ifdef MATRIX_NT fprintf(stderr, "pm1\n"); PortalMat pm1(m1); fprintf(stderr, "pm2t\n"); PortalMat pm2t(m2.t()); pm1.reference(); pm2t.reference(); #endif #endif PortalMat pm3; pm3.create(m1.rows, m2.cols, CV_32F); pm3.reference(); // we invoke .reference on the matrices in advance // in order to avoid counting the elapsed time for // performance analysis. This is not strictly necessary // as all the portalmat methods make sure a valid // reference is available before invoking the hardware pthread_t dbgtid; fprintf(stderr, "creating debug thread\n"); if(pthread_create(&dbgtid, NULL, dbgThread, NULL)){ fprintf(stderr, "error creating debug thread\n"); exit(1); } fprintf(stderr, "HW matmul\n"); portalTimerStart(0); #ifdef MATRIX_TN pm3.multf(pm1t, pm2, mmdeviceIndication); #else #ifdef MATRIX_NT pm3.multf(pm1, pm2t, mmdeviceIndication); #endif #endif #if 0 //uint64_t hw_cycles = portalTimerLap(0); uint64_t read_beats = hostMemServerIndication.getMemoryTraffic(ChannelType_Read); uint64_t write_beats = hostMemServerIndication.getMemoryTraffic(ChannelType_Write); float read_util = (float)read_beats/(float)mmdeviceIndication->ccnt; float write_util = (float)write_beats/(float)mmdeviceIndication->ccnt; float read_bw = read_util * N_VALUE * 4 * (float)freq / 1.0e9; float write_bw = write_util * N_VALUE * 4 * (float)freq / 1.0e9; float macs = m1.rows * m2.rows * m2.cols; fprintf(stderr, "Bus frequency %f MHz\n", (float)freq / 1.0e6); fprintf(stderr, "memory read beats %f utilization %f (beats/cycle), bandwidth %f (GB/s)\n", (float)read_beats, read_util, read_bw); fprintf(stderr, "memory write beats %f utilization %f (beats/cycle), bandwidth %f (GB/s)\n", (float)write_beats, write_util, write_bw); fprintf(stderr, "Throughput %f macs/cycle %f GFLOP/s\n", (float)macs / (float)mmdeviceIndication->ccnt, 2.0 * (float)macs / (float)mmdeviceIndication->ccnt * freq / 1.0e9); fprintf(stderr, "Time %f cycles, opencv matmul %f cycles (speedup %f), naive matmul %f cycles (speedup %f)\n", (float)mmdeviceIndication->ccnt, (float)opencv_hw_cycles, (float)opencv_hw_cycles/(float)mmdeviceIndication->ccnt, (float)naive_hw_cycles, (float)naive_hw_cycles/(float)mmdeviceIndication->ccnt); #endif if (0) { dumpMat("pm3", "%5.1f", pm3); dumpMat(" m3", "%5.1f", m3); } bool eq = pm3.compare(m3); #else // CUDA_PERF_TEST cv::Mat cm3(m1.rows,m2.cols, CV_32F); cuda_mm(m1, m2, cm3); cv::Mat m3 = m1 * m2; bool eq = compare(m3, cm3, 0.01); #endif // CUDA_PERF_TEST fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXX eq=%d\n", eq); return(!(eq&&sane)); } ================================================ FILE: examples/maxsonar_simple/Makefile ================================================ CONNECTALDIR ?= ../.. S2H_INTERFACES = MaxSonarCtrlRequest:MaxSonarController.req H2S_INTERFACES = MaxSonarController:MaxSonarCtrlIndication ZBR = $(CONNECTALDIR)/lib/zedboard_robot BSVFILES = $(ZBR)/bsv/MaxSonarController.bsv CPPFILES= test_maxsonar.cpp $(ZBR)/cpp/read_buffer.cpp AUTOTOP = --interface pins:MaxSonarController.pins PIN_TYPE = MaxSonarSimplePins PIN_TYPE_INCLUDE = MaxSonarController PINOUT_FILE = pinout.json PIN_BINDINGS = pmod:pmodb include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/maxsonar_simple/maxsonar_simple.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include "MaxSonarCtrlIndication.h" #include "GeneratedTypes.h" class MaxSonarCtrlIndication : public MaxSonarCtrlIndicationWrapper { public: sem_t status_sem; sem_t pulse_width_sem; uint32_t write_addr; int write_wrap_cnt; int verbose; int useconds; MaxSonarCtrlIndication(int id) : MaxSonarCtrlIndicationWrapper(id) { sem_init(&status_sem,1,0); sem_init(&pulse_width_sem,1,0); write_addr = 0; write_wrap_cnt = 0; verbose = 0; } virtual void range_ctrl ( const uint8_t v){ if (verbose) fprintf(stderr, "MaxSonarCtrlIndication::range_ctrl(v=%x)\n", v); } virtual void pulse_width ( const uint32_t v){ if (verbose) fprintf(stderr, "MaxSonarCtrlIndication::pulse_width(v=%x)\n", v); useconds = v/100; sem_post(&pulse_width_sem); } virtual void memwrite_status(const uint32_t addr, const uint32_t wrap_cnt){ if (verbose) fprintf(stderr, "MaxSonarCtrlIndication::memwrite_status(addr=%08x, wrap_cnt=%d)\n", addr, wrap_cnt); write_addr = addr; write_wrap_cnt = wrap_cnt; sem_post(&status_sem); } }; ================================================ FILE: examples/maxsonar_simple/pinout.json ================================================ { "maxsonar_range_ctrl" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J2" }, "maxsonar_pulse_v" : { "PIO_DIRECTION": "INPUT", "pmod" : "J4" }, "leds_leds[0]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L0" }, "leds_leds[1]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L1" }, "leds_leds[2]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L2" }, "leds_leds[3]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L3" }, "leds_leds[4]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L4" }, "leds_leds[5]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L5" }, "leds_leds[6]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L6" }, "leds_leds[7]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L7" } } ================================================ FILE: examples/maxsonar_simple/test_maxsonar.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "maxsonar_simple.h" #include "MaxSonarCtrlRequest.h" #include "read_buffer.h" int main(int argc, const char **argv) { MaxSonarCtrlIndication *ind = new MaxSonarCtrlIndication(IfcNames_MaxSonarCtrlIndicationH2S); MaxSonarCtrlRequestProxy *device = new MaxSonarCtrlRequestProxy(IfcNames_MaxSonarCtrlRequestS2H); long req_freq = 100000000; // 100 mHz long freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); device->range_ctrl(1); while(true){ usleep(50000); device->pulse_width(); sem_wait(&(ind->pulse_width_sem)); float distance = ((float)ind->useconds)/147.0; fprintf(stderr, "(%8d microseconds == %8f inches)\n", ind->useconds, distance); } } ================================================ FILE: examples/memcpy/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemcpyRequest:Memcpy.request H2S_INTERFACES = Memcpy:MemcpyIndication MEM_READ_INTERFACES = lMemcpy.dmaReadClient MEM_WRITE_INTERFACES = lMemcpy.dmaWriteClient BSVFILES = ../memcpy/Memcpy.bsv CPPFILES= ../memcpy/testmemcpy.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memcpy/Memcpy.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import FIFOF::*; import FIFO::*; import BRAMFIFO::*; import GetPut::*; import ClientServer::*; import ConnectalConfig::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; interface MemcpyRequest; method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) iterCnt); endinterface interface MemcpyIndication; method Action started; method Action done; endinterface interface Memcpy; interface MemcpyRequest request; interface Vector#(1, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaWriteClient; endinterface // NOTE: this test doesn't rely on mkDma[Read|Write]Buffer to ensure that // speculative read/write requests are not unsafely issued. As a // result this must be enforced manually (mdk) typedef 8 CmdQDepth; typedef TDiv#(DataBusWidth,32) WordsPerBeat; module mkMemcpy#(MemcpyIndication indication)(Memcpy); MemReadEngine#(DataBusWidth,DataBusWidth,CmdQDepth,1) re <- mkMemReadEngineBuff(valueOf(CmdQDepth)*512); MemWriteEngine#(DataBusWidth,DataBusWidth,CmdQDepth,1) we <- mkMemWriteEngineBuff(valueOf(CmdQDepth)*512); Integer wordsPerBeat = valueOf(WordsPerBeat); Reg#(Bit#(32)) rdIterCnt <- mkReg(0); Reg#(Bit#(32)) wrIterCnt <- mkReg(0); Reg#(SGLId) rdPointer <- mkReg(0); Reg#(SGLId) wrPointer <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); FIFOF#(Bit#(DataBusWidth)) buffer <- mkSizedBRAMFIFOF(valueOf(CmdQDepth)*32); Bool verbose = False; //True; rule start_read(rdIterCnt > 0); if (verbose) $display("start_read obj %d numWords %d wordsPerBeat %d", rdPointer, numWords, wordsPerBeat); re.readServers[0].request.put(MemengineCmd{sglId:rdPointer, base:0, len:extend(numWords*4), burstLen:truncate(burstLen*4), tag:0}); rdIterCnt <= rdIterCnt-1; endrule rule start_write(wrIterCnt > 0); if (verbose) $display(" start_write obj %d numWords %d", wrPointer, numWords); we.writeServers[0].request.put(MemengineCmd{sglId:wrPointer, base:0, len:extend(numWords*4), burstLen:truncate(burstLen*4), tag:0}); wrIterCnt <= wrIterCnt-1; endrule rule write_finish; if (verbose) $display(" write_finish %d", wrIterCnt); let rv1 <- we.writeServers[0].done.get; if(wrIterCnt==0) indication.done; endrule rule fill_buffer; let v <- toGet(re.readServers[0].data).get; buffer.enq(v.data); if (verbose) $display("fill_buffer %h", v.data); if (v.last && verbose) $display("read_finish %d", rdIterCnt); endrule rule drain_buffer; let v <- toGet(buffer).get(); we.writeServers[0].data.enq(v); //$display(" drain_buffer %h", buffer.first); endrule interface MemcpyRequest request; method Action startCopy(Bit#(32) wp, Bit#(32) rp, Bit#(32) nw, Bit#(32) bl, Bit#(32) ic); $display("startCopy wrPointer=%d rdPointer=%d numWords=%h burstLen=%d iterCnt=%d", wp, rp, nw, bl, ic); indication.started; // initialized wrPointer <= wp; rdPointer <= rp; numWords <= nw; wrIterCnt <= ic; rdIterCnt <= ic; burstLen <= bl; endmethod endinterface interface MemReadClient dmaReadClient = vec(re.dmaClient); interface MemWriteClient dmaWriteClient = vec(we.dmaClient); endmodule ================================================ FILE: examples/memcpy/testmemcpy.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "MemcpyIndication.h" #include "MemcpyRequest.h" sem_t done_sem; sem_t memcmp_sem; int srcAlloc; int dstAlloc; unsigned int *srcBuffer = 0; unsigned int *dstBuffer = 0; #ifndef SIMULATION int numWords = 16 << 18; #else int numWords = 1 << 10; #endif size_t alloc_sz = numWords*sizeof(unsigned int); bool finished = false; volatile int memcmp_fail = 0; unsigned int memcmp_count = 0; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (size_t i = 0; i < len ; i++) { fprintf(stderr, "%02x", (unsigned char)buf[i]); if (i % 32 == 31) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } class MemcpyIndication : public MemcpyIndicationWrapper { public: MemcpyIndication(unsigned int id) : MemcpyIndicationWrapper(id){} virtual void started(){ fprintf(stderr, "started\n"); } virtual void done() { sem_post(&done_sem); fprintf(stderr, "done\n"); finished = true; memcmp_fail = memcmp(srcBuffer, dstBuffer, numWords*sizeof(unsigned int)); for (int i = 0; i < numWords; i++) { int *s = (int *)srcBuffer; int *d = (int *)dstBuffer; if (s[i] != i) fprintf(stderr, "bad data src[%x]=%x\n", i, s[i]); if (d[i] != i) fprintf(stderr, "bad data dst[%x]=%x\n", i, d[i]); } if (memcmp_fail) { memcmp_fail=0; for (int i = 0; i < numWords; i++) { int *s = (int *)srcBuffer; int *d = (int *)dstBuffer; if (s[i] != d[i]) { fprintf(stderr, "mismatch %d %08x %08x\n", i, s[i], d[i]); memcmp_fail++; } } } fprintf(stderr, "memcmp=%x\n", memcmp_fail); sem_post(&memcmp_sem); } }; // we can use the data synchronization barrier instead of flushing the // cache only because the ps7 is configured to run in buffered-write mode // // an opc2 of '4' and CRm of 'c10' encodes "CP15DSB, Data Synchronization Barrier // operation". this is a legal instruction to execute in non-privileged mode (mdk) // // #define DATA_SYNC_BARRIER __asm __volatile( "MCR p15, 0, %0, c7, c10, 4" :: "r" (0) ); MemcpyIndication *deviceIndication = 0; int main(int argc, const char **argv) { if(sem_init(&done_sem, 1, 0)){ fprintf(stderr, "failed to init done_sem\n"); exit(1); } if(sem_init(&memcmp_sem, 1, 0)){ fprintf(stderr, "failed to init memcmp_sem\n"); exit(1); } fprintf(stderr, "%s %s\n", __DATE__, __TIME__); MemcpyRequestProxy *device = new MemcpyRequestProxy(IfcNames_MemcpyRequestS2H); deviceIndication = new MemcpyIndication(IfcNames_MemcpyIndicationH2S); DmaManager *dma = platformInit(); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); dstAlloc = portalAlloc(alloc_sz, 0); // for(int i = 0; i < srcAlloc->header.numEntries; i++) // fprintf(stderr, "%lx %lx\n", srcAlloc->entries[i].dma_address, srcAlloc->entries[i].length); // for(int i = 0; i < dstAlloc->header.numEntries; i++) // fprintf(stderr, "%lx %lx\n", dstAlloc->entries[i].dma_address, dstAlloc->entries[i].length); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (int i = 0; i < numWords; i++){ srcBuffer[i] = i; dstBuffer[i] = 0x5a5abeef; } portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); unsigned int ref_dstAlloc = dma->reference(dstAlloc); fprintf(stderr, "ref_srcAlloc=%d\n", ref_srcAlloc); fprintf(stderr, "ref_dstAlloc=%d\n", ref_dstAlloc); // unsigned int refs[2] = {ref_srcAlloc, ref_dstAlloc}; // for(int j = 0; j < 2; j++){ // unsigned int ref = refs[j]; // for(int i = 0; i < numWords; i = i+(numWords/4)){ // dmap->addrRequest(ref, i*sizeof(unsigned int)); // sleep(1); // } // dmap->addrRequest(ref, (1<<16)*sizeof(unsigned int)); // sleep(1); // } fprintf(stderr, "Main::starting memcpy numWords:%d\n", numWords); int burstLen = 32; #ifndef SIMULATION int iterCnt = 128; #else int iterCnt = 2; #endif portalTimerStart(0); device->startCopy(ref_dstAlloc, ref_srcAlloc, numWords, burstLen, iterCnt); sem_wait(&done_sem); platformStatistics(); //float read_util = (float)read_beats/(float)cycles; //float write_util = (float)write_beats/(float)cycles; //fprintf(stderr, " iters: %d\n", iterCnt); //fprintf(stderr, "wr_beats: %"PRIx64" %08lx\n", write_beats, (long)write_beats); //fprintf(stderr, "rd_beats: %"PRIx64" %08lx\n", read_beats, (long)read_beats); //fprintf(stderr, "numWords: %x\n", numWords); //fprintf(stderr, " wr_est: %"PRIx64"\n", (write_beats*2)/iterCnt); //fprintf(stderr, " rd_est: %"PRIx64"\n", (read_beats*2)/iterCnt); //fprintf(stderr, "memory read utilization (beats/cycle): %f\n", read_util); //fprintf(stderr, "memory write utilization (beats/cycle): %f\n", write_util); #if 0 MonkitFile pmf("perf.monkit"); pmf.setHwCycles(cycles) .setReadBwUtil(read_util) .setWriteBwUtil(write_util) .writeFile(); fprintf(stderr, "After updating perf.monkit\n"); #endif sem_wait(&memcmp_sem); fprintf(stderr, "after memcmp_sem memcmp_fail=%d\n", memcmp_fail); return memcmp_fail; } ================================================ FILE: examples/memcpyslow/Makefile ================================================ include ../memcpy/Makefile CONNECTALFLAGS += --mainclockperiod=30 ================================================ FILE: examples/memlatency/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemlatencyRequest:Memlatency.request H2S_INTERFACES = Memlatency:MemlatencyIndication MEM_READ_INTERFACES = lMemlatency.dmaReadClient MEM_WRITE_INTERFACES = lMemlatency.dmaWriteClient BSVFILES = Memlatency.bsv CPPFILES = testmemlatency.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memlatency/Memlatency.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import FIFO::*; import ClientServer::*; import GetPut::*; import BRAMFIFO::*; import Vector::*; import Pipe::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; interface MemlatencyRequest; method Action start(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) burstLen); endinterface interface MemlatencyIndication; method Action started; method Action readDone; method Action writeDone; method Action readLatency(Bit#(32) l); method Action writeLatency(Bit#(32) l); endinterface interface Memlatency; interface MemlatencyRequest request; interface Vector#(1, MemReadClient#(64)) dmaReadClient; interface Vector#(1, MemWriteClient#(64)) dmaWriteClient; endinterface module mkMemlatency#(MemlatencyIndication indication)(Memlatency); MemReadEngine#(64,64,1,1) re <- mkMemReadEngine; MemWriteEngine#(64,64,2,1) we <- mkMemWriteEngine; Reg#(Bit#(32)) rdIterCnt <- mkReg(0); Reg#(Bit#(32)) wrIterCnt <- mkReg(0); Reg#(SGLId) rdPointer <- mkReg(0); Reg#(SGLId) wrPointer <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) cycles <- mkReg(0); FIFO#(Bit#(32)) rdStartFifo <- mkSizedBRAMFIFO(16); FIFO#(Bit#(32)) wrStartFifo <- mkSizedBRAMFIFO(16); FIFO#(Bit#(32)) rdLatFifo <- mkSizedBRAMFIFO(16); FIFO#(Bit#(32)) wrLatFifo <- mkSizedBRAMFIFO(16); rule cycle; cycles <= cycles+1; endrule rule startRead(rdIterCnt > 0); re.readServers[0].request.put(MemengineCmd{sglId:rdPointer, base:0, len:burstLen*4, burstLen:truncate(burstLen*4), tag:0}); rdIterCnt <= rdIterCnt-1; rdStartFifo.enq(cycles); endrule rule readConsume; let v <- toGet(re.readServers[0].data).get; if (v.last) begin let rdStart <- toGet(rdStartFifo).get(); rdLatFifo.enq(cycles-rdStart); end endrule rule startWrite(wrIterCnt > 0); we.writeServers[0].request.put(MemengineCmd{sglId:wrPointer, base:0, len:burstLen*4, burstLen:truncate(burstLen*4), tag:0}); wrIterCnt <= wrIterCnt-1; wrStartFifo.enq(cycles); endrule rule finishWrite; let rv0 <- we.writeServers[0].done.get; let wrStart <- toGet(wrStartFifo).get(); wrLatFifo.enq(cycles-wrStart); endrule rule writeProduce; we.writeServers[0].data.enq(1); endrule rule report; let wl <- toGet(wrLatFifo).get; let rl <- toGet(rdLatFifo).get; indication.readLatency(rl); indication.writeLatency(wl); if(wrIterCnt==0) indication.writeDone; if(rdIterCnt==0) indication.readDone; endrule interface MemlatencyRequest request; method Action start(Bit#(32) wp, Bit#(32) rp, Bit#(32) bl) if (rdIterCnt == 0 && wrIterCnt == 0); $display("start wrPointer=%d rdPointer=%d burstLen=%d", wp, rp, bl); indication.started; // initialized wrPointer <= wp; rdPointer <= rp; rdIterCnt <= 16; wrIterCnt <= 16; burstLen <= bl; endmethod endinterface interface MemReadClient dmaReadClient = cons(re.dmaClient, nil); interface MemWriteClient dmaWriteClient = cons(we.dmaClient, nil); endmodule ================================================ FILE: examples/memlatency/testmemlatency.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "dmaManager.h" #include "MemlatencyIndication.h" #include "MemlatencyRequest.h" sem_t read_done_sem; sem_t write_done_sem; int srcAlloc; int dstAlloc; unsigned int *srcBuffer = 0; unsigned int *dstBuffer = 0; int numWords = 16 << 10; size_t alloc_sz = numWords*sizeof(unsigned int); unsigned int rd_latency = 0; unsigned int num_reads = 0; unsigned int wr_latency = 0; unsigned int num_writes = 0; class MemlatencyIndication : public MemlatencyIndicationWrapper { public: MemlatencyIndication(unsigned int id) : MemlatencyIndicationWrapper(id){} virtual void started(){ fprintf(stderr, "started\n"); } virtual void readLatency(uint32_t l) { fprintf(stderr, "readLatency %d\n", l); rd_latency += l; num_reads++; } virtual void writeLatency(uint32_t l){ fprintf(stderr, "writeLatency %d\n", l); wr_latency += l; num_writes++; } virtual void readDone() { sem_post(&read_done_sem); fprintf(stderr, "readDone\n"); } virtual void writeDone() { sem_post(&write_done_sem); fprintf(stderr, "writeDone\n"); } }; MemlatencyIndication *deviceIndication = 0; int main(int argc, const char **argv) { if(sem_init(&read_done_sem, 1, 0)){ fprintf(stderr, "failed to init read_done_sem\n"); exit(1); } if(sem_init(&write_done_sem, 1, 0)){ fprintf(stderr, "failed to init write_done_sem\n"); exit(1); } fprintf(stderr, "%s %s\n", __DATE__, __TIME__); MemlatencyRequestProxy device(IfcNames_MemlatencyRequestS2H); DmaManager *dma = platformInit(); deviceIndication = new MemlatencyIndication(IfcNames_MemlatencyIndicationH2S); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); dstAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (int i = 0; i < numWords; i++){ srcBuffer[i] = i; dstBuffer[i] = 0x5a5abeef; } portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); unsigned int ref_dstAlloc = dma->reference(dstAlloc); fprintf(stderr, "Main::starting mempcy numWords:%d\n", numWords); int burstLen = 16; device.start(ref_dstAlloc, ref_srcAlloc, burstLen); sem_wait(&read_done_sem); sem_wait(&write_done_sem); fprintf(stderr, "average read latency: %d\n", (unsigned int)(((float)rd_latency)/((float)num_reads))); fprintf(stderr, "average write latency: %d\n", (unsigned int)(((float)wr_latency)/((float)num_writes))); return 0; } ================================================ FILE: examples/memread/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest:ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClient BSVFILES = ReadTest.bsv CPPFILES=testmemread.cpp ifeq ($(BOARD),zedboard) CONNECTALFLAGS += -DBSV_POSITIVE_RESET endif ifeq ($(BOARD),xsim) CONNECTALFLAGS += -DBSV_POSITIVE_RESET endif #CONNECTALFLAGS += -DTLP32 CONNECTALFLAGS += -DMEMENGINE_REQUEST_CYCLES include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memread/ReadTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import Vector::*; import BuildVector::*; import GetPut::*; import ClientServer::*; import Pipe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import ConnectalConfig::*; interface ReadTestRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numBytes, Bit#(32) burstLen, Bit#(32) iterCnt); endinterface interface ReadTest; interface ReadTestRequest request; interface Vector#(1,MemReadClient#(DataBusWidth)) dmaClient; endinterface interface ReadTestIndication; method Action readDone(Bit#(32) mismatchCount); endinterface typedef 14 NumOutstandingRequests; typedef TMul#(NumOutstandingRequests,TMul#(32,4)) BufferSizeBytes; module mkReadTest#(ReadTestIndication indication) (ReadTest); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numBytes <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenBytes <- mkReg(0); Reg#(Bit#(32)) itersToFinish <- mkReg(0); Reg#(Bit#(32)) itersToStart <- mkReg(0); Reg#(Bit#(32)) bytesRead <- mkReg(0); Reg#(Bit#(32)) mismatchCounts <- mkReg(0); MemReadEngine#(DataBusWidth,DataBusWidth,NumOutstandingRequests,1) re <- mkMemReadEngineBuff(valueOf(BufferSizeBytes)); FIFO#(Bit#(32)) checkDoneFifo <- mkFIFO(); rule start (itersToStart > 0); $display("Test: request.put"); re.readServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:numBytes, tag:0, burstLen:burstLenBytes}); itersToStart <= itersToStart-1; endrule Reg#(Bit#(DataBusWidth)) vReg <- mkReg(0); Reg#(Bit#(DataBusWidth)) vExpectedReg <- mkReg(0); Reg#(Bool) validReg <- mkReg(False); Reg#(Bit#(32)) bytesToRead <- mkReg(0); Reg#(Bool) lastReg <- mkReg(False); FIFO#(void) doneFifo <- mkFIFO; rule check; // first pipeline stage if (re.readServers[0].data.notEmpty()) begin let md <- toGet(re.readServers[0].data).get; //$display("md v=%h tag=%d first=%d last=%d", md.data, md.tag, md.first, md.last); let v = md.data; let rval = bytesRead/4; function Bit#(32) expectedVal(Integer i); return rval+fromInteger(i); endfunction let expectedV = pack(genWith(expectedVal)); vReg <= v; vExpectedReg <= expectedV; validReg <= True; let next_bytesRead = bytesRead + fromInteger(valueOf(DataBusWidth))/8; let next_bytesToRead = bytesToRead - fromInteger(valueOf(DataBusWidth))/8; //$display("check next_bytesRead=%d next_bytesToRead=%d last=%d", next_bytesRead, next_bytesToRead, last); if (md.last) begin next_bytesRead = 0; next_bytesToRead = numBytes; end lastReg <= md.last; bytesRead <= next_bytesRead; bytesToRead <= next_bytesToRead; if (md.last) doneFifo.enq(?); end else begin validReg <= False; end // second pipeline stage if (validReg) begin let v = vReg; let expectedV = vExpectedReg; let misMatch = v != expectedV; mismatchCounts <= mismatchCounts + (misMatch ? 1 : 0); //$display("Test: check new=%x numBytes=%x bytesRead=%x misMatch=%x read=%x expect=%x", new_bytesRead, numBytes, bytesRead, misMatch, v, expectedV); if (lastReg) begin checkDoneFifo.enq(mismatchCounts); end end endrule `ifdef MEMENGINE_REQUEST_CYCLES rule request_cycles; let reqcycles <- toGet(re.readServers[0].requestCycles).get(); $display("request %d took %d cycles", reqcycles.tag, reqcycles.cycles); endrule `endif rule finish if (itersToFinish > 0); $display("Test: response.get itersToFinish %x", itersToFinish); let mc <- toGet(checkDoneFifo).get(); doneFifo.deq; if (itersToFinish == 1) begin indication.readDone(mismatchCounts); end itersToFinish <= itersToFinish - 1; endrule interface dmaClient = vec(re.dmaClient); interface ReadTestRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nb, Bit#(32) bl, Bit#(32) ic) if (itersToStart == 0 && itersToFinish == 0); $display("startRead pointer=%x numBytes %x burstLen %x iteration %x", rp, nb, bl, ic); pointer <= rp; numBytes <= nb; bytesToRead <= nb; burstLenBytes <= truncate(bl); itersToFinish <= ic; itersToStart <= ic; mismatchCounts <= 0; bytesRead <= 0; endmethod endinterface endmodule ================================================ FILE: examples/memread/design_vc707.tcl ================================================ ############################################################### ### Tcl Variables ############################################################### #set tclParams [list ... ] set tclParams [list place.closeImportedSites 1 \ hd.StrictContainRouting 1 \ ] #Define location for "Tcl" directory. Defaults to "../Tcl" set tclHome "../../scripts/xilinx/tcl" if {[file exists $tclHome]} { set tclDir $tclHome } elseif {[file exists "./Tcl"]} { set tclDir "./Tcl" } else { error "ERROR: No valid location found for required Tcl scripts. Set \$tclDir in design.tcl to a valid location." } ############################################################### ### Part Variables - Define Device, Package, Speedgrade ############################################################### set device "xc7vx485t" set package "ffg1761" set speed "-2" set part $device$package$speed ############################################################### ### Setup Variables ############################################################### ####flow control set run.topSynth 0 set run.oocSynth 1 set run.tdImpl 1 set run.oocImpl 1 set run.topImpl 1 set run.flatImpl 0 ####Report and DCP controls - values: 0-required min; 1-few extra; 2-all set verbose 1 set dcpLevel 1 ####Output Directories set synthDir "./Synth" set implDir "./Implement" set dcpDir "./Checkpoint" ####Input Directories set srcDir "./vc707" set rtlDir "$srcDir/verilog" set prjDir "$srcDir/prj" set xdcDir "$srcDir/constraints" set coreDir "$srcDir/cores" set netlistDir "$srcDir/netlist" ####Source required Tcl Procs source $tclDir/design_utils.tcl source $tclDir/synth_utils.tcl source $tclDir/impl_utils.tcl source $tclDir/hd_floorplan_utils.tcl ############################################################### ### Top Definition ############################################################### set top "mkPcieTop" add_module $top set_attribute module $top top_level 1 set_attribute module $top vlog [concat [glob $rtlDir/top/*.v] [glob $rtlDir/lib/*.v] ] set_attribute module $top ip [] #set_attribute module $top vlog_headers [glob $rtlDir/top/*Stub.v] set_attribute module $top synth ${run.topSynth} add_implementation $top set_attribute impl $top top $top set_attribute impl $top implXDC [glob $xdcDir/vc707.xdc] set_attribute impl $top impl ${run.topImpl} set_attribute impl $top hd.impl 1 #################################################################### ### OOC Module Definition and OOC Implementation for each instance #################################################################### set module1 "mkPcieHost" add_module $module1 set_attribute module $module1 vlog [concat [glob $rtlDir/lib/*.v] [glob $rtlDir/pciehost/*.v]] set_attribute module $module1 ip [] set_attribute module $module1 synth ${run.oocSynth} set instance "pciehost" add_ooc_implementation $instance set_attribute ooc $instance module $module1 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing set module2 "mkPCIExpressEndpointX7" add_module $module2 set_attribute module $module2 vlog [concat [glob $rtlDir/lib/*.v] [list $rtlDir/ep7/mkPCIExpressEndpointX7.v]] set_attribute module $module2 ip [glob /scratch/jamey/connectal/generated/xilinx/vc707/*/*.xci] set_attribute module $module2 synth ${run.oocSynth} set instance "ep7" add_ooc_implementation $instance set_attribute ooc $instance module $module2 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing # set module3 "mkSynthesizeableConnectalTop" # add_module $module3 # set_attribute module $module3 vlog [concat [glob $rtlDir/lib/*.v] [list $rtlDir/portal/mkSynthesizeableConnectalTop.v]] # set_attribute module $module3 ip [] # set_attribute module $module3 synth ${run.oocSynth} # set instance "portalTop" # add_ooc_implementation $instance # set_attribute ooc $instance module $module3 # set_attribute ooc $instance inst $instance # set_attribute ooc $instance hierInst $instance # set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ # $xdcDir/${instance}_ooc_timing.xdc \ # $xdcDir/${instance}_ooc_budget.xdc \ # $xdcDir/${instance}_ooc_optimize.xdc \ # ] # set_attribute ooc $instance impl ${run.oocImpl} # set_attribute ooc $instance preservation routing #################################################################### ### Create TopDown implementation run #################################################################### set module1File "$synthDir/$module1/${module1}_synth.dcp" set module2File "$synthDir/$module2/${module2}_synth.dcp" #set module3File "$synthDir/$module3/${module3}_synth.dcp" add_implementation TopDown set_attribute impl TopDown top $top set_attribute impl TopDown implXDC [list $xdcDir/floorplan_vc707.xdc $xdcDir/vc707.xdc] set_attribute impl TopDown td.impl 1 set_attribute impl TopDown cores [list $module1File \ $module2File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ [get_attribute module $module2 cores] \ ] set_attribute impl TopDown impl ${run.tdImpl} set_attribute impl TopDown route 0 #################################################################### ### Create Flat implementation run #################################################################### add_implementation Flat set_attribute impl Flat top $top set_attribute impl Flat implXDC [list $xdcDir/${top}_flpn.xdc $xdcDir/vc707.xdc] set_attribute impl Flat cores [list $module1File \ $module2File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ [get_attribute module $module2 cores] \ ] set_attribute impl Flat impl ${run.flatImpl} ######################################################################## ### Task / flow portion ######################################################################## set_property SEVERITY {Warning} [get_drc_checks HDOOC-4] # Build the designs source $tclDir/run.tcl exit ================================================ FILE: examples/memread/testmemread.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "dmaManager.h" #include "ReadTestRequest.h" #include "ReadTestIndication.h" #if defined(PCIE) int burstLen = 32; #elif defined(ZynqUltrascale) int burstLen = 64; // ZynqUltrascale supports upto burstLenByte=4*64=256 (16 beats of 128bit transfer) #else int burstLen = 16; #endif #if defined(BOARD_xsim) int numWords = 0x40/4; int iterCnt = 1; #elif defined(SIMULATION) int numWords = 0x124000/4; int iterCnt = 3; #else int numWords = 0x1240000/4; // make sure to allocate at least one entry of each size int iterCnt = 64; #endif static sem_t test_sem; static size_t test_sz = numWords*sizeof(unsigned int); static size_t alloc_sz = test_sz; static int mismatchCount = 0; class ReadTestIndication : public ReadTestIndicationWrapper { public: void readDone(uint32_t v) { fprintf(stderr, "ReadTest::readDone(%x)\n", v); mismatchCount += v; sem_post(&test_sem); } // memread_4m void started ( const uint32_t numWords ) { } void reportStateDbg ( const uint32_t streamRdCnt, const uint32_t mismatchCount ) { } ReadTestIndication(int id, int tile=DEFAULT_TILE) : ReadTestIndicationWrapper(id,tile){} }; int main(int argc, const char **argv) { int test_result = 0; int srcAlloc; unsigned int *srcBuffer = 0; fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); DmaManager *dma = platformInit(); ReadTestRequestProxy *device = new ReadTestRequestProxy(IfcNames_ReadTestRequestS2H); ReadTestIndication memReadIndication(IfcNames_ReadTestIndicationH2S); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); for (int i = 0; i < numWords; i++) srcBuffer[i] = i; portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); /* Test 1: check that match is ok */ unsigned int ref_srcAlloc = dma->reference(srcAlloc); fprintf(stderr, "ref_srcAlloc=%d\n", ref_srcAlloc); fprintf(stderr, "Main::orig_test read numWords=%d burstLen=%d iterCnt=%d\n", numWords, burstLen, iterCnt); portalTimerStart(0); device->startRead(ref_srcAlloc, numWords * 4, burstLen * 4, iterCnt); sem_wait(&test_sem); platformStatistics(); if (mismatchCount) { fprintf(stderr, "Main::first test failed to match %d.\n", mismatchCount); test_result++; // failed } /* Test 2: check that mismatch is detected */ srcBuffer[0] = -1; srcBuffer[numWords/2] = -1; srcBuffer[numWords-1] = -1; portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); fprintf(stderr, "Starting second read, mismatches expected\n"); mismatchCount = 0; device->startRead(ref_srcAlloc, numWords * 4 / NumberOfMasters, burstLen * 4, iterCnt); sem_wait(&test_sem); if (mismatchCount != 3/*number of errors introduced above*/ * iterCnt) { fprintf(stderr, "Main::second test failed to match mismatchCount=%d (expected %d) iterCnt=%d numWords=%d.\n", mismatchCount, 3*iterCnt, iterCnt, numWords); test_result++; // failed } #if 0 MonkitFile pmf("perf.monkit"); pmf.setHwCycles(cycles) .setReadBwUtil(read_util) .writeFile(); #endif return test_result; } ================================================ FILE: examples/memread/vc707_floorplan.xdc ================================================ startgroup create_pblock pblock_ep7 resize_pblock pblock_ep7 -add {SLICE_X184Y54:SLICE_X221Y166 DSP48_X18Y22:DSP48_X19Y65 RAMB18_X12Y22:RAMB18_X14Y65 RAMB36_X12Y11:RAMB36_X14Y32} add_cells_to_pblock pblock_ep7 [get_cells [list ep7]] -clear_locs endgroup startgroup create_pblock pblock_pciehost resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X171Y197 DSP48_X9Y22:DSP48_X16Y77 RAMB18_X7Y22:RAMB18_X10Y77 RAMB36_X7Y11:RAMB36_X10Y38 BUFGCTRL_X0Y16} add_cells_to_pblock pblock_pciehost [get_cells [list pciehost]] -clear_locs endgroup startgroup create_pblock pblock_portalTop resize_pblock pblock_portalTop -add {SLICE_X0Y25:SLICE_X101Y247 DSP48_X0Y10:DSP48_X7Y97 RAMB18_X0Y10:RAMB18_X6Y97 RAMB36_X0Y5:RAMB36_X6Y48} add_cells_to_pblock pblock_portalTop [get_cells [list portalTop]] -clear_locs endgroup ================================================ FILE: examples/memread128/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest:ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClient BSVFILES = ../memread/ReadTest.bsv CPPFILES= ../memread/testmemread.cpp CONNECTALFLAGS += -D DataBusWidth=128 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memread2/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = Memread2Request:Memread2.request H2S_INTERFACES = Memread2:Memread2Indication MEM_READ_INTERFACES = lMemread2.dmaClients BSVFILES = Memread2.bsv CPPFILES=testmemread2.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memread2/Memread2.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import Vector::*; import GetPut::*; import ClientServer::*; import Connectable::*; import ConnectalMemTypes::*; import MemReadEngine::*; import Pipe::*; interface Memread2Request; method Action startRead(Bit#(32) pointer, Bit#(32) pointer2, Bit#(32) numWords, Bit#(32) burstLen); method Action getStateDbg(); endinterface interface Memread2; interface Memread2Request request; interface Vector#(2, MemReadClient#(64)) dmaClients; endinterface interface Memread2Indication; method Action started(Bit#(32) numWords); method Action rData(Bit#(64) v); method Action reportStateDbg(Bit#(32) x, Bit#(32) y); method Action readReq(Bit#(32) v); method Action readDone(Bit#(32) mismatchCount); method Action mismatch(Bit#(32) offset, Bit#(64) expectedValue, Bit#(64) value); endinterface module mkMemread2#(Memread2Indication indication) (Memread2); Reg#(Bit#(32)) srcGen0 <- mkReg(0); Reg#(Bit#(32)) srcGen1 <- mkReg(0); Reg#(Bit#(32)) mismatchCount0 <- mkReg(0); Reg#(Bit#(32)) mismatchCount1 <- mkReg(0); MemReadEngine#(64,64,1,1) re0 <- mkMemReadEngine; MemReadEngine#(64,64,1,1) re1 <- mkMemReadEngine; FIFOF#(Bit#(64)) outReg0 <- mkFIFOF; FIFOF#(Bit#(64)) outReg1 <- mkFIFOF; PipeIn#(Bit#(64)) pi0 = toPipeIn(outReg0); PipeIn#(Bit#(64)) pi1 = toPipeIn(outReg1); FIFOF#(Bit#(1)) doneReg0 <- mkFIFOF; FIFOF#(Bit#(1)) doneReg1 <- mkFIFOF; rule re0_read; let v <- toGet(re0.readServers[0].data).get; toPut(pi0).put(v.data); if (v.last) doneReg0.enq(0); endrule rule re1_read; let v <- toGet(re1.readServers[0].data).get; toPut(pi1).put(v.data); if (v.last) doneReg1.enq(0); endrule Reg#(Bool) valid0Reg <- mkReg(False); Reg#(Bit#(64)) v0Reg <- mkReg(0); Reg#(Bit#(64)) v0ExpectedReg <- mkReg(0); rule read0; // first stage of pipeline if (outReg0.notEmpty) begin srcGen0 <= srcGen0+2; v0ExpectedReg <= {srcGen0+1,srcGen0}; let v0 <- toGet(outReg0).get; v0Reg <= v0; valid0Reg <= True; end else begin valid0Reg <= False; end // second stage of pipeline if (valid0Reg) begin let mm = v0Reg != v0ExpectedReg; mismatchCount0 <= mismatchCount0 + (mm ? 1 : 0); if (mm) indication.mismatch(0, v0ExpectedReg, v0Reg); end endrule Reg#(Bool) valid1Reg <- mkReg(False); Reg#(Bit#(64)) v1Reg <- mkReg(0); Reg#(Bit#(64)) v1ExpectedReg <- mkReg(0); rule read1; // first stage of pipeline if (outReg1.notEmpty) begin srcGen1 <= srcGen1+2; v1ExpectedReg <= {(srcGen1+1)*3,srcGen1*3}; let v1 <- toGet(outReg1).get; v1Reg <= v1; valid1Reg <= True; end else begin valid1Reg <= False; end // second stage of pipeline if (valid1Reg) begin let mm = v1Reg != v1ExpectedReg; mismatchCount1 <= mismatchCount1 + (mm ? 1 : 0); if (mm) indication.mismatch(1, v1ExpectedReg, v1Reg); end endrule rule done; doneReg0.deq; doneReg1.deq; indication.readDone(mismatchCount1+mismatchCount0); endrule interface Memread2Request request; method Action startRead(Bit#(32) pointer, Bit#(32) pointer2, Bit#(32) numWords, Bit#(32) bl); $display("startRead(%d %d %d %d)", pointer, pointer2, numWords, bl); re0.readServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:numWords*4, burstLen:truncate(bl*4), tag:0}); re1.readServers[0].request.put(MemengineCmd{sglId:pointer2, base:0, len:numWords*4, burstLen:truncate(bl*4), tag:0}); indication.started(numWords); endmethod method Action getStateDbg(); Bit#(16) sg0 = truncate(srcGen0); Bit#(16) sg1 = truncate(srcGen1); Bit#(16) mm0 = truncate(mismatchCount0); Bit#(16) mm1 = truncate(mismatchCount1); indication.reportStateDbg({sg0,sg1}, {mm0,mm1}); endmethod endinterface interface MemReadClient dmaClients = cons(re0.dmaClient, cons(re1.dmaClient, nil)); endmodule ================================================ FILE: examples/memread2/testmemread2.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "Memread2Indication.h" #include "Memread2Request.h" int srcAlloc, srcAlloc2; unsigned int *srcBuffer = 0; unsigned int *srcBuffer2 = 0; int numWords = 16 << 8; size_t test_sz = numWords*sizeof(unsigned int); size_t alloc_sz = test_sz; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (size_t i = 0; i < (len > 16 ? 16 : len) ; i++) fprintf(stderr, "%02x", (unsigned char)buf[i]); fprintf(stderr, "\n"); } class Memread2Indication : public Memread2IndicationWrapper { public: unsigned int rDataCnt; virtual void readReq(uint32_t v){ //fprintf(stderr, "Memread2::readReq %lx\n", v); } virtual void readDone(uint32_t v){ fprintf(stderr, "Memread2::readDone mismatch=%x\n", v); mismatchCount = v; // if (mismatchesReceived == mismatchCount) // exit(v ? 1 : 0); } virtual void started(uint32_t words){ fprintf(stderr, "Memread2::started: words=%x\n", words); } virtual void rData ( uint64_t v ){ fprintf(stderr, "rData (%08x): ", rDataCnt++); dump("", (char*)&v, sizeof(v)); } virtual void reportStateDbg(uint32_t x, uint32_t y){ fprintf(stderr, "Memread2::reportStateDbg: x=%08x y=%08x\n", x, y); } virtual void mismatch(uint32_t offset, uint64_t ev, uint64_t v) { fprintf(stderr, "Mismatch at %x %llx != %llx\n", offset, (long long)ev, (long long)v); mismatchesReceived++; if (mismatchesReceived == mismatchCount) exit(1); } Memread2Indication(int id) : Memread2IndicationWrapper(id), mismatchCount(0), mismatchesReceived(0){} private: int mismatchCount; int mismatchesReceived; }; int main(int argc, const char **argv) { unsigned int srcGen = 0; int limit = 20; Memread2RequestProxy *device = 0; fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); device = new Memread2RequestProxy(IfcNames_Memread2RequestS2H); DmaManager *dma = platformInit(); Memread2Indication deviceIndication(IfcNames_Memread2IndicationH2S); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); srcAlloc2 = portalAlloc(alloc_sz, 0); srcBuffer2 = (unsigned int *)portalMmap(srcAlloc2, alloc_sz); for (int i = 0; i < numWords; i++){ int v = srcGen++; srcBuffer[i] = v; srcBuffer2[i] = v*3; } portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); fprintf(stderr, "ref_srcAlloc=%d\n", ref_srcAlloc); unsigned int ref_srcAlloc2 = dma->reference(srcAlloc2); fprintf(stderr, "ref_srcAlloc2=%d\n", ref_srcAlloc2); fprintf(stderr, "Main::starting read %08x\n", numWords); device->startRead(ref_srcAlloc, ref_srcAlloc2, 32, 16); fprintf(stderr, "Main::sleeping\n"); while(limit-- > 0){ sleep(3); device->getStateDbg(); //uint64_t beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); uint64_t beats = 0; fprintf(stderr, " beats: %"PRIx64"\n", beats); //hostMemServerRequest->stateDbg(ChannelType_Read); platformStatistics(); } return 0; } ================================================ FILE: examples/memread256/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest:ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClient BSVFILES = ../memread/ReadTest.bsv CPPFILES= ../memread/testmemread.cpp CONNECTALFLAGS += -D DataBusWidth=256 CONNECTALFLAGS += --mainclockperiod=8 -D USE_WIDE_WIDTH include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memread_4m/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest\#\(\`NumberOfMasters\):ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClients BSVFILES = ReadTest.bsv CPPFILES=../memread/testmemread.cpp PLATFORM_NUMBER_OF_MASTERS =4 #CONNECTALFLAGS += -I$(CONNECTALDIR)/examples/memread include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memread_4m/ReadTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import StmtFSM::*; import GetPut::*; import ClientServer::*; import Pipe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import ConnectalConfig::*; interface ReadTestRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numBytes, Bit#(32) burstLen, Bit#(32) iterCnt); method Action getStateDbg(); endinterface interface ReadTest#(numeric type nClients); interface ReadTestRequest request; interface Vector#(nClients,MemReadClient#(DataBusWidth)) dmaClients; endinterface interface ReadTestIndication; method Action started(Bit#(32) numBytes); method Action reportStateDbg(Bit#(32) streamRdCnt, Bit#(32) mismatchCount); method Action readDone(Bit#(32) mismatchCount); endinterface module mkReadTest#(ReadTestIndication indication) (ReadTest#(4)); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numBytes <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenBytes <- mkReg(0); Reg#(Bit#(32)) itersToStart <- mkReg(0); Reg#(Bit#(32)) startBase <- mkReg(0); Reg#(Bit#(3)) startPtr <- mkReg(0); Reg#(Bit#(3)) finishPtr <- mkReg(0); Reg#(Bit#(32)) mismatchAccum <- mkReg(0); Vector#(4,MemReadEngine#(DataBusWidth,DataBusWidth,1,1)) res <- replicateM(mkMemReadEngine); FIFO#(void) startFifo <- mkFIFO; Vector#(4,Reg#(Bit#(32))) srcGens <- replicateM(mkReg(0)); Vector#(4,Reg#(Bit#(32))) mismatchCounts <- replicateM(mkReg(0)); Vector#(4,FIFO#(void)) doneFifo <- replicateM(mkFIFO); Stmt startStmt = seq startBase <= 0; for(startPtr <= 0; startPtr < 4; startPtr <= startPtr+1) (action let cmd = MemengineCmd{sglId:pointer, base:extend(startBase), len:numBytes, burstLen:burstLenBytes, tag:0}; res[startPtr].readServers[0].request.put(cmd); startBase <= startBase+numBytes; //$display("start:%d %h %d %h (%d)", startPtr, startBase, numBytes, burstLenBytes, itersToStart); endaction); endseq; FSM startFSM <- mkFSM(startStmt); Stmt finishStmt = seq mismatchAccum <= 0; for(finishPtr <= 0; finishPtr < 4; finishPtr <= finishPtr+1) mismatchAccum <= mismatchAccum + mismatchCounts[finishPtr]; indication.readDone(mismatchAccum); //$display("finishStmt: %h", mismatchAccum); endseq; FSM finishFSM <- mkFSM(finishStmt); rule start (itersToStart > 0); startFifo.deq; startFSM.start; itersToStart <= itersToStart-1; endrule rule finish; for(Integer i = 0; i < 4; i=i+1) doneFifo[i].deq; if (itersToStart == 0) finishFSM.start; else startFifo.enq(?); endrule for(Integer i = 0; i < 4; i=i+1) rule check; let v <- toGet(res[i].readServers[0].data).get; let expectedV = {srcGens[i]+1,srcGens[i]}; let misMatch = v.data != expectedV; mismatchCounts[i] <= mismatchCounts[i] + (misMatch ? 1 : 0); if (srcGens[i]+2 == fromInteger(i+1)*(numBytes>>2)) begin //$display("check %d %d", i, srcGens[i]+1); srcGens[i] <= fromInteger(i)*(numBytes>>2); end else srcGens[i] <= srcGens[i]+2; if (v.last) begin //$display("finish: %d (%d)", i, itersToStart); doneFifo[i].enq(?); end endrule function MemReadClient#(DataBusWidth) dc(MemReadEngine#(DataBusWidth,DataBusWidth,1,1) re) = re.dmaClient; interface dmaClients = map(dc,res); interface ReadTestRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nb, Bit#(32) bl, Bit#(32) ic); //$display("startRead rdPointer=%d numBytes=%h burstLenBytes=%d itersToStart=%d", rp, nb, bl, ic); indication.started(nb); pointer <= rp; numBytes <= nb; burstLenBytes <= truncate(bl); itersToStart <= ic; for(Integer i = 0; i < 4; i=i+1) begin mismatchCounts[i] <= 0; srcGens[i] <= fromInteger(i)*(nb>>2); end startFifo.enq(?); endmethod method Action getStateDbg(); indication.reportStateDbg(itersToStart, mismatchCounts[0]); endmethod endinterface endmodule ================================================ FILE: examples/memread_simple/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest:ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClient BSVFILES = ReadTest.bsv CPPFILES=testmemread.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memread_simple/ReadTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import GetPut::*; import ClientServer::*; import Pipe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import Pipe::*; import ConnectalConfig::*; // for DataBusWidth interface ReadTestRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numBytes, Bit#(32) burstLenInBytes, Bit#(32) iterCnt); endinterface interface ReadTest; interface ReadTestRequest request; interface Vector#(1,MemReadClient#(DataBusWidth)) dmaClient; endinterface interface ReadTestIndication; method Action readDone(Bit#(32) mismatchCount); endinterface module mkReadTest#(ReadTestIndication indication) (ReadTest); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numBytes <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenInBytes <- mkReg(0); Reg#(Bit#(32)) itersToFinish <- mkReg(0); Reg#(Bit#(32)) itersToStart <- mkReg(0); Reg#(Bit#(32)) bytesRead <- mkReg(0); Reg#(Bit#(32)) mismatchCounts <- mkReg(0); MemReadEngine#(DataBusWidth,DataBusWidth,2,1) re <- mkMemReadEngine; rule start (itersToStart > 0); re.readServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:numBytes, burstLen:burstLenInBytes, tag: 0}); itersToStart <= itersToStart-1; endrule function Bit#(32) expectedVal(Integer i); return (bytesRead/4)+fromInteger(i); endfunction rule check; let v <- toGet(re.readServers[0].data).get; if (v.data != pack(genWith(expectedVal))) mismatchCounts <= mismatchCounts + 1; let new_bytesRead = bytesRead + fromInteger(valueOf(DataBusWidth))/8; if (v.last) begin new_bytesRead = 0; if (itersToFinish == 1) indication.readDone(mismatchCounts); itersToFinish <= itersToFinish - 1; end bytesRead <= new_bytesRead; endrule interface dmaClient = cons(re.dmaClient, nil); interface ReadTestRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nb, Bit#(32) bl, Bit#(32) ic) if (itersToFinish == 0); pointer <= rp; numBytes <= nb; burstLenInBytes <= truncate(bl); itersToFinish <= ic; itersToStart <= ic; mismatchCounts <= 0; bytesRead <= 0; endmethod endinterface endmodule ================================================ FILE: examples/memread_simple/design_vc707.tcl ================================================ ############################################################### ### Tcl Variables ############################################################### #set tclParams [list ... ] set tclParams [list place.closeImportedSites 1 \ hd.StrictContainRouting 1 \ ] #Define location for "Tcl" directory. Defaults to "../Tcl" set tclHome "../../scripts/xilinx/tcl" if {[file exists $tclHome]} { set tclDir $tclHome } elseif {[file exists "./Tcl"]} { set tclDir "./Tcl" } else { error "ERROR: No valid location found for required Tcl scripts. Set \$tclDir in design.tcl to a valid location." } ############################################################### ### Part Variables - Define Device, Package, Speedgrade ############################################################### set device "xc7vx485t" set package "ffg1761" set speed "-2" set part $device$package$speed ############################################################### ### Setup Variables ############################################################### ####flow control set run.topSynth 0 set run.oocSynth 1 set run.tdImpl 1 set run.oocImpl 1 set run.topImpl 1 set run.flatImpl 0 ####Report and DCP controls - values: 0-required min; 1-few extra; 2-all set verbose 1 set dcpLevel 1 ####Output Directories set synthDir "./Synth" set implDir "./Implement" set dcpDir "./Checkpoint" ####Input Directories set srcDir "./vc707" set rtlDir "$srcDir/verilog" set prjDir "$srcDir/prj" set xdcDir "$srcDir/constraints" set coreDir "$srcDir/cores" set netlistDir "$srcDir/netlist" ####Source required Tcl Procs source $tclDir/design_utils.tcl source $tclDir/synth_utils.tcl source $tclDir/impl_utils.tcl source $tclDir/hd_floorplan_utils.tcl ############################################################### ### Top Definition ############################################################### set top "mkPcieTop" add_module $top set_attribute module $top top_level 1 set_attribute module $top vlog [concat [glob $rtlDir/top/*.v] [glob $rtlDir/lib/*.v] ] set_attribute module $top ip [] #set_attribute module $top vlog_headers [glob $rtlDir/top/*Stub.v] set_attribute module $top synth ${run.topSynth} add_implementation $top set_attribute impl $top top $top set_attribute impl $top implXDC [glob $xdcDir/vc707.xdc] set_attribute impl $top impl ${run.topImpl} set_attribute impl $top hd.impl 1 #################################################################### ### OOC Module Definition and OOC Implementation for each instance #################################################################### set module1 "mkPcieHost" add_module $module1 set_attribute module $module1 vlog [concat [glob $rtlDir/lib/*.v] [glob $rtlDir/pciehost/*.v]] set_attribute module $module1 ip [] set_attribute module $module1 synth ${run.oocSynth} set instance "pciehost" add_ooc_implementation $instance set_attribute ooc $instance module $module1 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing set module2 "mkPCIExpressEndpointX7" add_module $module2 set_attribute module $module2 vlog [concat [glob $rtlDir/lib/*.v] [list $rtlDir/ep7/mkPCIExpressEndpointX7.v]] set_attribute module $module2 ip [glob /scratch/jamey/connectal/generated/xilinx/vc707/*/*.xci] set_attribute module $module2 synth ${run.oocSynth} set instance "ep7" add_ooc_implementation $instance set_attribute ooc $instance module $module2 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing # set module3 "mkSynthesizeableConnectalTop" # add_module $module3 # set_attribute module $module3 vlog [concat [glob $rtlDir/lib/*.v] [list $rtlDir/portal/mkSynthesizeableConnectalTop.v]] # set_attribute module $module3 ip [] # set_attribute module $module3 synth ${run.oocSynth} # set instance "portalTop" # add_ooc_implementation $instance # set_attribute ooc $instance module $module3 # set_attribute ooc $instance inst $instance # set_attribute ooc $instance hierInst $instance # set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ # $xdcDir/${instance}_ooc_timing.xdc \ # $xdcDir/${instance}_ooc_budget.xdc \ # $xdcDir/${instance}_ooc_optimize.xdc \ # ] # set_attribute ooc $instance impl ${run.oocImpl} # set_attribute ooc $instance preservation routing #################################################################### ### Create TopDown implementation run #################################################################### set module1File "$synthDir/$module1/${module1}_synth.dcp" set module2File "$synthDir/$module2/${module2}_synth.dcp" #set module3File "$synthDir/$module3/${module3}_synth.dcp" add_implementation TopDown set_attribute impl TopDown top $top set_attribute impl TopDown implXDC [list $xdcDir/floorplan_vc707.xdc $xdcDir/vc707.xdc] set_attribute impl TopDown td.impl 1 set_attribute impl TopDown cores [list $module1File \ $module2File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ [get_attribute module $module2 cores] \ ] set_attribute impl TopDown impl ${run.tdImpl} set_attribute impl TopDown route 0 #################################################################### ### Create Flat implementation run #################################################################### add_implementation Flat set_attribute impl Flat top $top set_attribute impl Flat implXDC [list $xdcDir/${top}_flpn.xdc $xdcDir/vc707.xdc] set_attribute impl Flat cores [list $module1File \ $module2File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ [get_attribute module $module2 cores] \ ] set_attribute impl Flat impl ${run.flatImpl} ######################################################################## ### Task / flow portion ######################################################################## set_property SEVERITY {Warning} [get_drc_checks HDOOC-4] # Build the designs source $tclDir/run.tcl exit ================================================ FILE: examples/memread_simple/testmemread.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "ReadTestRequest.h" #include "ReadTestIndication.h" #ifdef SIMULATION static size_t test_sz = 0x124000; // make sure to allocate at least one entry of each size #else static size_t test_sz = 0x1240000; // make sure to allocate at least one entry of each size #endif sem_t test_sem; static int burstLen = 16 * 4; class ReadTestIndication : public ReadTestIndicationWrapper { public: void readDone(uint32_t v){ printf( "ReadTest::readDone(mismatch = %x)\n", v); sem_post(&test_sem); } ReadTestIndication(int id) : ReadTestIndicationWrapper(id){} }; int main(int argc, const char **argv) { ReadTestRequestProxy *device = new ReadTestRequestProxy(IfcNames_ReadTestRequestS2H); ReadTestIndication deviceIndication(IfcNames_ReadTestIndicationH2S); DmaManager *dma = platformInit(); int srcAlloc; srcAlloc = portalAlloc(test_sz, 0); unsigned int *srcBuffer = (unsigned int *)portalMmap(srcAlloc, test_sz); for (unsigned int i = 0; i < test_sz/sizeof(unsigned int); i++) srcBuffer[i] = i; portalCacheFlush(srcAlloc, srcBuffer, test_sz, 1); unsigned int ref_srcAlloc = dma->reference(srcAlloc); printf( "Main::starting read %lx\n", test_sz); device->startRead(ref_srcAlloc, test_sz, burstLen, 1); sem_wait(&test_sem); return 0; } ================================================ FILE: examples/memread_simple/vc707_floorplan.xdc ================================================ startgroup create_pblock pblock_ep7 resize_pblock pblock_ep7 -add {SLICE_X184Y54:SLICE_X221Y166 DSP48_X18Y22:DSP48_X19Y65 RAMB18_X12Y22:RAMB18_X14Y65 RAMB36_X12Y11:RAMB36_X14Y32} add_cells_to_pblock pblock_ep7 [get_cells [list ep7]] -clear_locs endgroup startgroup create_pblock pblock_pciehost resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X171Y197 DSP48_X9Y22:DSP48_X16Y77 RAMB18_X7Y22:RAMB18_X10Y77 RAMB36_X7Y11:RAMB36_X10Y38 BUFGCTRL_X0Y16} add_cells_to_pblock pblock_pciehost [get_cells [list pciehost]] -clear_locs endgroup startgroup create_pblock pblock_portalTop resize_pblock pblock_portalTop -add {SLICE_X0Y25:SLICE_X101Y247 DSP48_X0Y10:DSP48_X7Y97 RAMB18_X0Y10:RAMB18_X6Y97 RAMB36_X0Y5:RAMB36_X6Y48} add_cells_to_pblock pblock_portalTop [get_cells [list portalTop]] -clear_locs endgroup ================================================ FILE: examples/memwrite/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = Memwrite.bsv CPPFILES=testmemwrite.cpp CONNECTALFLAGS += --bscflags " -show-schedule" CONNECTALFLAGS += -DMEMENGINE_REQUEST_CYCLES include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memwrite/Memwrite.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import Vector::*; import ClientServer::*; import GetPut::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import Pipe::*; import Arith::*; import ConnectalConfig::*; `ifdef NumEngineServers typedef `NumEngineServers NumEngineServers; `else typedef 1 NumEngineServers; `endif typedef TDiv#(DataBusWidth,32) DataBusWords; interface MemwriteRequest; method Action startWrite(Bit#(32) pointer, Bit#(32) offset, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) iterCnt); method Action getStateDbg(); endinterface interface Memwrite; interface MemwriteRequest request; interface Vector#(1,MemWriteClient#(DataBusWidth)) dmaClient; endinterface interface MemwriteIndication; method Action started(Bit#(32) numWords); method Action reportStateDbg(Bit#(32) wrCnt, Bit#(32) srcGen); method Action writeDone(Bit#(32) v); endinterface module mkMemwrite#(MemwriteIndication indication) (Memwrite); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); FIFOF#(void) cf <- mkSizedFIFOF(1); Vector#(NumEngineServers, Reg#(Bit#(32))) srcGens <- replicateM(mkReg(0)); Reg#(Bit#(32)) writeOffset <- mkReg(0); Reg#(Bit#(32)) iterCnt <- mkReg(0); Vector#(NumEngineServers, Reg#(Bit#(32))) iterCnts <- replicateM(mkReg(0)); Vector#(NumEngineServers, FIFOF#(void)) cfs <- replicateM(mkSizedFIFOF(1)); Vector#(NumEngineServers, FIFOF#(Bool)) finishFifos <- replicateM(mkFIFOF); MemWriteEngine#(DataBusWidth,DataBusWidth,8,NumEngineServers) we <- mkMemWriteEngine; Bit#(32) chunk = extend(numWords)*4; for(Integer i = 0; i < valueOf(NumEngineServers); i=i+1) begin rule start (iterCnts[i] > 0); we.writeServers[i].request.put(MemengineCmd{tag:0, sglId:pointer, base:extend(writeOffset)+(fromInteger(i)*chunk), len:truncate(chunk), burstLen:truncate(burstLen*4)}); Bit#(32) srcGen = (fromInteger(i) << 28); srcGens[i] <= srcGen; $display("start %d/%d, %h 0x%x %h chunk=%h", i, valueOf(NumEngineServers), srcGen, iterCnts[i], writeOffset, chunk); cfs[i].enq(?); iterCnts[i] <= iterCnts[i]-1; endrule `ifdef MEMENGINE_REQUEST_CYCLES rule requestCycles; let reqcycles <- toGet(we.writeServers[i].requestCycles).get(); $display("request %d took %d cycles", reqcycles.tag, reqcycles.cycles); endrule `endif rule finish; $display("finish %d 0x%x", i, iterCnts[i]); let rv <- we.writeServers[i].done.get; finishFifos[i].enq(rv); endrule rule src if (cfs[i].notEmpty); Vector#(DataBusWords, Bit#(32)) v; for (Integer j = 0; j < valueOf(DataBusWords); j = j + 1) v[j] = srcGens[i]+fromInteger(j); we.writeServers[i].data.enq(pack(v)); let new_srcGen = srcGens[i]+fromInteger(valueOf(DataBusWords)); srcGens[i] <= new_srcGen; if (new_srcGen[27:0] >= truncate(numWords)) cfs[i].deq; endrule end PipeOut#(Vector#(NumEngineServers, Bool)) finishPipe <- mkJoinVector(id, map(toPipeOut, finishFifos)); PipeOut#(Bool) finishReducePipe <- mkReducePipe(uncurry(booland), finishPipe); rule indicate_finish; let rv <- toGet(finishReducePipe).get(); $display("indicate_finish rv=%d iterCnt=%d", rv, iterCnt); if (iterCnt == 1) begin cf.deq; indication.writeDone(0); end iterCnt <= iterCnt - 1; endrule interface MemWriteClient dmaClient = cons(we.dmaClient, nil); interface MemwriteRequest request; method Action startWrite(Bit#(32) wp, Bit#(32) off, Bit#(32) nw, Bit#(32) bl, Bit#(32) ic); $display("startWrite pointer=%d offset=%d numWords=%h burstLen=%d iterCnt=%d", wp, off, nw, bl, ic); indication.started(nw); pointer <= wp; cf.enq(?); numWords <= nw; burstLen <= bl; iterCnt <= ic; writeOffset <= off*4; for(Integer i = 0; i < valueOf(NumEngineServers); i=i+1) iterCnts[i] <= ic; endmethod endinterface endmodule ================================================ FILE: examples/memwrite/testmemwrite.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "monkit.h" #include "dmaManager.h" #include "MemwriteIndication.h" #include "MemwriteRequest.h" #ifdef BOARD_xsim static int numWords = 0x5000/4; static int iterCnt = 1; #elif defined(SIMULATION) static int numWords = 4096; static int iterCnt = 8; #else static int numWords = 0x1240000/4; // make sure to allocate at least one entry of each size static int iterCnt = 8; #endif #ifdef PCIE static int burstLen = 32; static int burstLenMin = 32; static int burstLenMax = 32; #elif defined(ZynqUltrascale) static int burstLen = 16; static int burstLenMin = 4; static int burstLenMax = 64; // 256byte = 16beats of 128bit #else static int burstLen = 16; static int burstLenMin = 16; static int burstLenMax = 16; #endif #ifdef NumEngineServers int numEngineServers = NumEngineServers; #else int numEngineServers = 1; #endif static sem_t test_sem; static size_t alloc_sz = numWords*sizeof(unsigned int); class MemwriteIndication : public MemwriteIndicationWrapper { public: MemwriteIndication(int id, int tile=DEFAULT_TILE) : MemwriteIndicationWrapper(id,tile) {} void started(uint32_t words) { fprintf(stderr, "Memwrite::started: words=%x\n", words); } void writeDone ( uint32_t srcGen ) { fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen); sem_post(&test_sem); } void reportStateDbg(uint32_t streamWrCnt, uint32_t srcGen) { fprintf(stderr, "Memwrite::reportStateDbg: streamWrCnt=%08x srcGen=%d\n", streamWrCnt, srcGen); } }; int main(int argc, const char **argv) { int mismatch = 0; uint32_t sg = 0; int max_error = 10; if (sem_init(&test_sem, 1, 0)) { fprintf(stderr, "error: failed to init test_sem\n"); exit(1); } fprintf(stderr, "testmemwrite: start %s %s\n", __DATE__, __TIME__); DmaManager *dma = platformInit(); MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H); MemwriteIndication deviceIndication(IfcNames_MemwriteIndicationH2S); alloc_sz *= numEngineServers; fprintf(stderr, "main::allocating %lx bytes of memory...\n", (long)alloc_sz); int dstAlloc = portalAlloc(alloc_sz, 0); unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); #ifdef FPGA0_CLOCK_FREQ long req_freq = FPGA0_CLOCK_FREQ, freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); #endif unsigned int ref_dstAlloc = dma->reference(dstAlloc); for (int i = 0; i < numWords*numEngineServers; i++) dstBuffer[i] = 0xDEADBEEF; portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "testmemwrite: flush and invalidate complete\n"); burstLen = burstLenMin; // words while (burstLen <= burstLenMax) { fprintf(stderr, "testmemwrite: starting write %#08x words burstLen=%d words\n", numWords, burstLen); portalTimerStart(0); device->startWrite(ref_dstAlloc, 0, numWords, burstLen, iterCnt); sem_wait(&test_sem); mismatch = 0; sg = 0; for (int i = 0; i < numWords; i++) { if (dstBuffer[i] != sg) { mismatch++; if (max_error-- > 0) fprintf(stderr, "testmemwrite: [%d] actual %08x expected %08x\n", i, dstBuffer[i], sg); } sg++; } platformStatistics(); fprintf(stderr, "testmemwrite: mismatch count %d.\n", mismatch); burstLen *= 2; if (mismatch) exit(mismatch); // now try with larger burstLen burstLen *= 2; } } ================================================ FILE: examples/memwrite128/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = ../memwrite/Memwrite.bsv CPPFILES=../memwrite/testmemwrite.cpp CONNECTALFLAGS += --bscflags " -show-schedule" CONNECTALFLAGS += -D DataBusWidth=128 CONNECTALFLAGS += -D USE_ACP include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memwrite256/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = ../memwrite/Memwrite.bsv CPPFILES=../memwrite/testmemwrite.cpp CONNECTALFLAGS += --bscflags " -show-schedule" CONNECTALFLAGS += -D DataBusWidth=256 CONNECTALFLAGS += -D USE_ACP # CONNECTALFLAGS += -D NumEngineServers=4 CONNECTALFLAGS += --mainclockperiod=8 -D USE_WIDE_WIDTH include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memwrite_4m/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite\#\(\`NumberOfMasters\):MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClients BSVFILES = Memwrite.bsv CPPFILES = ../memwrite/testmemwrite.cpp PLATFORM_NUMBER_OF_MASTERS =4 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/memwrite_4m/Memwrite.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import ClientServer::*; import GetPut::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import Pipe::*; import Arith::*; import ConnectalMemUtils::*; import ConnectalConfig::*; import StmtFSM ::*; interface MemwriteRequest; method Action startWrite(Bit#(32) pointer, Bit#(32) offset, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) iterCnt); method Action getStateDbg(); endinterface interface Memwrite#(numeric type nClients); interface MemwriteRequest request; interface Vector#(nClients,MemWriteClient#(64)) dmaClients; endinterface interface MemwriteIndication; method Action started(Bit#(32) numWords); method Action reportStateDbg(Bit#(32) wrCnt, Bit#(32) srcGen); method Action writeDone(Bit#(32) v); endinterface module mkMemwrite#(MemwriteIndication indication) (Memwrite#(4)); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) iterCnt <- mkReg(0); Reg#(Bit#(32)) startBase <- mkReg(0); Reg#(Bit#(3)) startPtr <- mkReg(0); Reg#(Bit#(3)) finishPtr <- mkReg(0); FIFO#(void) startFifo <- mkFIFO; Vector#(4,Reg#(Bit#(32))) srcGens <- replicateM(mkReg(0)); Vector#(4,MemWriteEngine#(64,64,2,1)) wes <- replicateM(mkMemWriteEngine); Stmt startStmt = seq startBase <= 0; for(startPtr <= 0; startPtr < 4; startPtr <= startPtr+1) (action $display("start:%d %h %d %h (%d)", startPtr, startBase, numWords, burstLen*4, iterCnt); wes[startPtr].writeServers[0].request.put(MemengineCmd{sglId:pointer, base:extend(startBase), len:numWords, burstLen:truncate(burstLen*4), tag:0}); startBase <= startBase+numWords; endaction); endseq; FSM startFSM <- mkFSM(startStmt); rule start (iterCnt > 0); startFifo.deq; startFSM.start; iterCnt <= iterCnt-1; endrule rule finish; for(Integer i = 0; i < 4; i=i+1) begin $display("finish: %d (%d)", i, iterCnt); let rv <- wes[i].writeServers[0].done.get; end if (iterCnt == 0) indication.writeDone(0); else startFifo.enq(?); endrule for(Integer i = 0; i < 4; i=i+1) rule src; wes[i].writeServers[0].data.enq({srcGens[i]+1,srcGens[i]}); if (srcGens[i]+2 == fromInteger(i+1)*(numWords>>2)) begin //$display("src %d %d", i, srcGens[i]+1); srcGens[i] <= fromInteger(i)*(numWords>>2); end else srcGens[i] <= srcGens[i]+2; endrule function MemWriteClient#(64) dc(MemWriteEngine#(64,64,2,1) we) = we.dmaClient; interface dmaClients = map(dc,wes); interface MemwriteRequest request; method Action startWrite(Bit#(32) wp, Bit#(32) ofs, Bit#(32) nw, Bit#(32) bl, Bit#(32) ic); $display("startWrite pointer=%d numWords=%h burstLen=%d iterCnt=%d", pointer, nw, bl, ic); indication.started(nw); pointer <= wp; numWords <= nw; burstLen <= bl; iterCnt <= ic; for(Integer i = 0; i < 4; i=i+1) srcGens[i] <= fromInteger(i)*(nw>>2); startFifo.enq(?); endmethod method Action getStateDbg(); indication.reportStateDbg(iterCnt, srcGens[0]); endmethod endinterface endmodule ================================================ FILE: examples/nandsim/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = NandCfgRequest:NandSim.request H2S_INTERFACES = NandSim:NandCfgIndication MEM_READ_INTERFACES = lNandSim.readClient MEM_WRITE_INTERFACES = lNandSim.writeClient BSVFILES = $(CONNECTALDIR)/lib/nandsim/bsv/NandSim.bsv CPPFILES=testnandsim.cpp CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/nandsim/cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/nandsim/testnandsim.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "dmaManager.h" #include "NandCfgIndication.h" #include "NandCfgRequest.h" #include "nandsim.h" static int trace_memory = 1; extern "C" { #include "userReference.h" } using namespace std; class NandCfgIndication : public NandCfgIndicationWrapper { public: unsigned int rDataCnt; virtual void readDone(uint32_t v){ fprintf(stderr, "NandSim::readDone v=%x\n", v); sem_post(&sem); } virtual void writeDone(uint32_t v){ fprintf(stderr, "NandSim::writeDone v=%x\n", v); sem_post(&sem); } virtual void eraseDone(uint32_t v){ fprintf(stderr, "NandSim::eraseDone v=%x\n", v); sem_post(&sem); } virtual void configureNandDone(){ fprintf(stderr, "NandSim::configureNandDone\n"); sem_post(&sem); } NandCfgIndication(int id) : NandCfgIndicationWrapper(id) { sem_init(&sem, 0, 0); } void wait() { fprintf(stderr, "NandSim::wait for semaphore\n"); sem_wait(&sem); } private: sem_t sem; }; int main(int argc, const char **argv) { #ifndef BOARD_bluesim size_t nandBytes = 1 << 12; #else size_t nandBytes = 1 << 18; #endif fprintf(stderr, "testnandsim::%s %s\n", __DATE__, __TIME__); DmaManager *hostDma = platformInit(); NandCfgRequestProxy *nandcfgRequest = new NandCfgRequestProxy(IfcNames_NandCfgRequestS2H); NandCfgIndication *nandcfgIndication = new NandCfgIndication(IfcNames_NandCfgIndicationH2S); int nandAlloc = portalAlloc(nandBytes, 0); fprintf(stderr, "testnandsim::nandAlloc=%d\n", nandAlloc); int ref_nandAlloc = hostDma->reference(nandAlloc); fprintf(stderr, "ref_nandAlloc=%d\n", ref_nandAlloc); fprintf(stderr, "testnandsim::NAND alloc fd=%d ref=%d\n", nandAlloc, ref_nandAlloc); nandcfgRequest->configureNand(ref_nandAlloc, nandBytes); nandcfgIndication->wait(); #ifndef ALGO_NANDSIM if (argc == 1) { fprintf(stderr, "testnandsim::allocating memory...\n"); size_t srcBytes = nandBytes>>2; int srcAlloc = portalAlloc(srcBytes, 0); unsigned int *srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcBytes); unsigned int ref_srcAlloc = hostDma->reference(srcAlloc); fprintf(stderr, "testnandsim::fd=%d, srcBuffer=%p\n", srcAlloc, srcBuffer); /* do tests */ fprintf(stderr, "testnandsim::chamdoo-test\n"); unsigned long loop = 0; unsigned long match = 0, mismatch = 0; while (loop < nandBytes) { fprintf(stderr, "testnandsim::starting write ref=%d, len=%08zx (%lu)\n", ref_srcAlloc, srcBytes, loop); for (unsigned int i = 0; i < srcBytes/sizeof(srcBuffer[0]); i++) { srcBuffer[i] = loop+i; } portalCacheFlush(srcAlloc, srcBuffer, srcBytes, 1); nandcfgRequest->startWrite(ref_srcAlloc, 0, loop, srcBytes, 16); nandcfgIndication->wait(); loop+=srcBytes; } fprintf(stderr, "testnandsim:: write phase complete\n"); loop = 0; while (loop < nandBytes) { fprintf(stderr, "testnandsim::starting read %08zx (%lu)\n", srcBytes, loop); for (unsigned int i = 0; i < srcBytes/sizeof(srcBuffer[0]); i++) { srcBuffer[i] = 5; } portalCacheFlush(srcAlloc, srcBuffer, srcBytes, 1); nandcfgRequest->startRead(ref_srcAlloc, 0, loop, srcBytes, 16); nandcfgIndication->wait(); for (unsigned int i = 0; i < srcBytes/sizeof(srcBuffer[0]); i++) { if (srcBuffer[i] != loop+i) { fprintf(stderr, "testnandsim::mismatch [%08ld] != [%08d] (%d,%zu)\n", loop+i, srcBuffer[i], i, srcBytes/sizeof(srcBuffer[0])); mismatch++; } else { match++; } } loop+=srcBytes; } /* end */ //uint64_t beats_r = hostDma->show_mem_stats(ChannelType_Read); //uint64_t beats_w = hostDma->show_mem_stats(ChannelType_Write); fprintf(stderr, "testnandsim::Summary: match=%lu mismatch:%lu (%lu) (%f percent)\n", match, mismatch, match+mismatch, (float)mismatch/(float)(match+mismatch)*100.0); //fprintf(stderr, "(%"PRIx64", %"PRIx64")\n", beats_r, beats_w); return (mismatch > 0); } else #endif { // else we were invoked by alg1_nandsim const char *filename = "../test.bin"; fprintf(stderr, "testnandsim::opening %s\n", filename); // open up the text file and read it into an allocated memory buffer int dataFile = open(filename, O_RDONLY); off_t data_len = lseek(dataFile, 0, SEEK_END); data_len = data_len & ~15; // because we are using a burst length of 16 lseek(dataFile, 0, SEEK_SET); int dataAlloc = portalAlloc(data_len, 0); int ref_dataAlloc = hostDma->reference(dataAlloc); char *data = (char *)portalMmap(dataAlloc, data_len); ssize_t read_len = read(dataFile, data, data_len); if(read_len != data_len) { fprintf(stderr, "testnandsim::error reading %s %ld %ld\n", filename, (long)data_len, (long) read_len); exit(-1); } // write the contents of data into "flash" memory portalCacheFlush(ref_dataAlloc, data, data_len, 1); fprintf(stderr, "testnandsim::invoking write %08x %08lx\n", ref_dataAlloc, (long)data_len); nandcfgRequest->startWrite(ref_dataAlloc, 0, 0, data_len, 16); nandcfgIndication->wait(); fprintf(stderr, "testnandsim::connecting to algo_exe...\n"); connect_to_algo_exe(); fprintf(stderr, "testnandsim::connected to algo_exe\n"); // send the offset and length (in nandsim) of the text write_to_algo_exe(0); write_to_algo_exe(data_len); printf("[%s:%d] sleep, waiting for search\n", __FUNCTION__, __LINE__); sleep(200); printf("[%s:%d] now closing down\n", __FUNCTION__, __LINE__); } } ================================================ FILE: examples/portal-synth-boundary/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SimpleRequest SimpleIndication BSVFILES = Simple.bsv Top.bsv CPPFILES=testsimple.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/portal-synth-boundary/Simple.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; interface SimpleIndication; method Action heard1(Bit#(32) v); endinterface interface SimpleResponse; method ActionValue#(Bit#(32)) heard1(); endinterface interface SimpleRequest; method Action say1(Bit#(32) v); endinterface interface Simple; interface SimpleRequest request; interface SimpleResponse response; endinterface // Because mkSimple has a synthesis boundary, it cannot take // SimpleIndication as an interface parameter. Therefore, it exports a // complementary interface: SimpleResponse, where each Action method // from SimpleIndication has a corresponding ActionValue method. (* synthesize *) module mkSimple(Simple); FIFO#(Bit#(32)) vFifo <- mkFIFO(); interface SimpleRequest request; method Action say1(Bit#(32) v); vFifo.enq(v); endmethod endinterface interface SimpleResponse response; method ActionValue#(Bit#(32)) heard1(); vFifo.deq(); return vFifo.first(); endmethod endinterface endmodule ================================================ FILE: examples/portal-synth-boundary/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import Connectable::*; import CtrlMux::*; import Portal::*; import ConnectalConfig::*; import SimpleIndication::*; import SimpleRequest::*; import Simple::*; typedef enum {IfcNames_SimpleIndication, IfcNames_SimpleRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); SimpleIndicationProxy simpleIndicationProxy <- mkSimpleIndicationProxy(IfcNames_SimpleIndication); Simple simpleRequest <- mkSimple(); SimpleRequestWrapper simpleRequestWrapper <- mkSimpleRequestWrapper(IfcNames_SimpleRequest,simpleRequest.request); // connect the ActionValue heard1 to the Action method heard1 mkConnection(simpleRequest.response.heard1, simpleIndicationProxy.ifc.heard1); Vector#(2,StdPortal) portals; portals[0] = simpleRequestWrapper.portalIfc; portals[1] = simpleIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: examples/portal-synth-boundary/testsimple.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "SimpleIndication.h" #include "SimpleRequest.h" #include "GeneratedTypes.h" int v1a = 42; class SimpleIndication : public SimpleIndicationWrapper { public: uint32_t cnt; void incr_cnt(){ if (++cnt == 1) exit(0); } virtual void heard1(uint32_t a) { fprintf(stderr, "heard1(%d)\n", a); assert(a == v1a); incr_cnt(); } SimpleIndication(unsigned int id) : SimpleIndicationWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { SimpleIndication *indication = new SimpleIndication(IfcNames_SimpleIndication); SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequest); fprintf(stderr, "Main::calling say1(%d)\n", v1a); device->say1(v1a); fprintf(stderr, "Main::about to go to sleep\n"); while(true){sleep(2);} } ================================================ FILE: examples/printf/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import DisplayInd::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface EchoRequestInternal; interface EchoRequest ifc; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); module mkEchoRequestInternal#(EchoIndication indication, DisplayInd printfInd)(EchoRequestInternal); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface EchoRequest ifc; method Action say(Bit#(32) v); $display("Echo: say %x", v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); //$display("Echo: say2 %x %x", extend(a), extend(b)); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: examples/printf/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = Swallow EchoRequest EchoIndication DisplayInd BSVFILES = Echo.bsv SwallowIF.bsv Top.bsv CPPFILES=testecho.cpp USE_PRINTF = 1 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/printf/SwallowIF.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface Swallow; method Action swallow(Bit#(32) v); endinterface module mkSwallow (Swallow); Reg#(Bit#(32)) sink <- mkReg(0); method Action swallow(Bit#(32) v); sink <= v; endmethod endmodule ================================================ FILE: examples/printf/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import CtrlMux::*; import ConnectalConfig::*; import EchoIndication::*; import EchoRequest::*; import Swallow::*; import Echo::*; import SwallowIF::*; import DisplayInd::*; typedef enum {IfcNames_EchoIndication, IfcNames_EchoRequest, IfcNames_Swallow, IfcNames_DisplayInd} IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); EchoIndicationProxy echoIndicationProxy <- mkEchoIndicationProxy(IfcNames_EchoIndication); DisplayIndProxy displayIndProxy <- mkDisplayIndProxy(IfcNames_DisplayInd); EchoRequestInternal echoRequestInternal <- mkEchoRequestInternal(echoIndicationProxy.ifc, displayIndProxy.ifc); EchoRequestWrapper echoRequestWrapper <- mkEchoRequestWrapper(IfcNames_EchoRequest,echoRequestInternal.ifc); Swallow swallow <- mkSwallow(); SwallowWrapper swallowWrapper <- mkSwallowWrapper(IfcNames_Swallow, swallow); Vector#(4,StdPortal) portals; portals[0] = echoIndicationProxy.portalIfc; portals[1] = echoRequestWrapper.portalIfc; portals[2] = swallowWrapper.portalIfc; portals[3] = displayIndProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: examples/printf/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "EchoIndication.h" #include "DisplayInd.h" #include "EchoRequest.h" #include "GeneratedTypes.h" #include "Swallow.h" #define LOOP_COUNT 1//000 #define SEPARATE_EVENT_THREAD //#define USE_MUTEX_SYNC EchoRequestProxy *echoRequestProxy = 0; #ifndef SEPARATE_EVENT_THREAD typedef int SEM_TYPE; #define SEMPOST(A) (*(A))++ #define SEMWAIT pthread_worker #elif defined(USE_MUTEX_SYNC) typedef pthread_mutex_t SEM_TYPE; #define SEMINIT(A) pthread_mutex_lock(A); #define SEMWAIT(A) pthread_mutex_lock(A); #define SEMPOST(A) pthread_mutex_unlock(A); #else // use semaphores typedef sem_t SEM_TYPE; #define SEMINIT(A) sem_init(A, 0, 0); #define SEMWAIT(A) sem_wait(A); #define SEMPOST(A) sem_post(A) #endif #ifdef SEPARATE_EVENT_THREAD #define PREPAREWAIT(A) #define CHECKSEM(A) 1 #else // use inline sync #define PREPAREWAIT(A) (A) = 0 #define CHECKSEM(A) (!(A)) #endif static SEM_TYPE sem_heard2; PortalPoller *poller = 0; static void *pthread_worker(void *p) { void *rc = NULL; while (CHECKSEM(sem_heard2) && !rc && !poller->stopping) { rc = poller->pollFn(poller->timeout); if ((long)rc >= 0) rc = poller->event(); } return rc; } static void init_thread() { #ifdef SEPARATE_EVENT_THREAD pthread_t threaddata; SEMINIT(&sem_heard2); pthread_create(&threaddata, NULL, &pthread_worker, (void*)poller); #endif } class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { fprintf(stderr, "heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { portalTimerCatch(20); SEMPOST(&sem_heard2); //fprintf(stderr, "heard an echo2: %ld %ld\n", a, b); //portalTimerCatch(25); } EchoIndication(unsigned int id, PortalPoller *poller) : EchoIndicationWrapper(id, poller) {} }; #include "printfInd.h" static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); portalTimerStart(0); PREPAREWAIT(sem_heard2); echoRequestProxy->say(v); SEMWAIT(&sem_heard2); printf("call_say: elapsed %" PRIu64 "\n", portalTimerLap(0)); } static void call_say2(int v, int v2) { portalTimerStart(0); PREPAREWAIT(sem_heard2); portalTimerCatch(0); echoRequestProxy->say2(v, v2); portalTimerCatch(19); SEMWAIT(&sem_heard2); portalTimerCatch(30); } int main(int argc, const char **argv) { poller = new PortalPoller(); EchoIndication *echoIndication = new EchoIndication(IfcNames_EchoIndication, poller); DisplayInd *dispIndication = new DisplayInd(IfcNames_DisplayInd, poller); // these use the default poller SwallowProxy *swallowProxy = new SwallowProxy(IfcNames_Swallow); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequest); poller->init(); init_thread(); #if 0 printf("Timer tests\n"); portalTimerInit(); for (int i = 0; i < 1000; i++) { portalTimerStart(0); portalTimerCatch(1); portalTimerCatch(2); portalTimerCatch(3); portalTimerCatch(4); portalTimerCatch(5); portalTimerCatch(6); portalTimerCatch(7); portalTimerCatch(8); } portalTimerPrint(1000); #endif int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); printf("[%s:%d] run %d loops\n\n", __FUNCTION__, __LINE__, LOOP_COUNT); portalTimerInit(); portalTimerStart(1); for (int i = 0; i < LOOP_COUNT; i++) call_say2(v, v*3); uint64_t elapsed = portalTimerLap(1); printf("TEST TYPE: " #ifndef SEPARATE_EVENT_THREAD "INLINE" #elif defined(USE_MUTEX_SYNC) "MUTEX" #else "SEM" #endif "\n"); portalTimerPrint(LOOP_COUNT); printf("call_say: elapsed %g average %g\n", (double) elapsed, (double) elapsed/ (double) LOOP_COUNT); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: examples/rbm/LICENSE.txt ================================================ Copyright (c) 2013,2014 Quanta Research Cambridge, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: examples/rbm/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib CONNECTALFLAGS = -D J_VALUE=1 -D K_VALUE=1 -D N_VALUE=1 -D DataBusWidth=32 MMDIR=../matmul RBMDIR=../rbm TESTCPPFILES= testrbm.cpp include $(MMDIR)/Makefile.mm include $(RBMDIR)/Makefile.rbm include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/rbm/Makefile.rbm ================================================ S2H_INTERFACES += RbmRequest:Rbm.rbmRequest MmRequestTN:Rbm.mmRequest SigmoidRequest:Rbm.sigmoidRequest TimerRequest:Rbm.timerRequest H2S_INTERFACES += Rbm\#\(TDiv\#\(DataBusWidth,32\)\):RbmIndication,SigmoidIndication,MmIndication,TimerIndication:host MEM_READ_INTERFACES = lRbm.readClients MEM_WRITE_INTERFACES = lRbm.writeClients gen:: $(RBMDIR)/datasets $(RBMDIR)/datasets: mkdir -p $(RBMDIR)/datasets (cd $(RBMDIR)/datasets; curl -O http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz) (cd $(RBMDIR)/datasets; curl -O http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz) (cd $(RBMDIR)/datasets; curl -O http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz) (cd $(RBMDIR)/datasets; curl -O http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz) cd $(RBMDIR)/datasets; gunzip *.gz CONNECTALFLAGS += -D RBMDIR='\"'$(RBMDIR)'\"' CONNECTALFLAGS += -I$(RBMDIR)/cpp BSVFILES += $(CONNECTALDIR)/lib/rbm/bsv/Rbm.bsv CPPFILES += $(CONNECTALDIR)/lib/rbm/cpp/rbm.cpp prebuild:: $(RBMDIR)/datasets cp -fv $(RBMDIR)/datasets/train-images-idx3-ubyte . ================================================ FILE: examples/rbm/Readme.md ================================================ BSV implementation of Restricted Boltzmann Machine modeled on git://github.com/echen/restricted-boltzmann-machines MNIST numeric digit data from: http://yann.lecun.com/exdb/mnist/ ================================================ FILE: examples/rbm/testrbm.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include "MemServerRequest.h" #include "MMURequest.h" #include #include #include #include #include #include #include #include #include // frexp(), fabs() #include #include "portalmat.h" #include "rbm.h" #include "mnist.h" MmRequestTNProxy *mmdevice = 0; MemServerRequestProxy *hostMemServerRequest; MmIndication *mmdeviceIndication = 0; SigmoidIndication *sigmoidindication = 0; SigmoidRequestProxy *sigmoiddevice = 0; RbmIndication *rbmDeviceIndication = 0; RbmRequestProxy *rbmdevice = 0; TimerIndication *timerdeviceIndication = 0; TimerRequestProxy *timerdevice = 0; long dotprod = 0; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (unsigned int i = 0; i < (len > 64 ? 64 : len) ; i++) { fprintf(stderr, "%02x", (unsigned char)buf[i]); if (i % 4 == 3) fprintf(stderr, " "); } fprintf(stderr, "\n"); } void *dbgThread(void *) { while (1) { sleep(1); mmdevice->debug(); //rbmdevice->sumOfErrorSquaredDebug(); if (hostMemServerRequest) hostMemServerRequest->stateDbg(ChannelType_Read); sleep(5); } return 0; } int main(int argc, const char **argv) { fprintf(stderr, "%s %s\n", __DATE__, __TIME__); mmdevice = new MmRequestTNProxy(IfcNames_MmRequestTNS2H); rbmdevice = new RbmRequestProxy(IfcNames_RbmRequestS2H); rbmDeviceIndication = new RbmIndication(IfcNames_RbmIndicationH2S); mmdeviceIndication = new MmIndication(IfcNames_MmIndicationH2S); sigmoiddevice = new SigmoidRequestProxy(IfcNames_SigmoidRequestS2H); sigmoidindication = new SigmoidIndication(IfcNames_SigmoidIndicationH2S); timerdevice = new TimerRequestProxy(IfcNames_TimerRequestS2H); timerdeviceIndication = new TimerIndication(IfcNames_TimerIndicationH2S); DmaManager *dma = platformInit(); if(sem_init(&mul_sem, 1, 0)){ fprintf(stderr, "failed to init mul_sem\n"); return -1; } pthread_t dbgtid; fprintf(stderr, "creating debug thread\n"); if(pthread_create(&dbgtid, NULL, dbgThread, NULL)){ fprintf(stderr, "error creating debug thread\n"); exit(1); } matAllocator = new PortalMatAllocator(dma); configureSigmoidTable(); int rv = 0; RBM rbm(dma); rbm.run(); rbmdevice->finish(); exit(rv); } ================================================ FILE: examples/readbw/ReadBW.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import GetPut::*; import PcieToAxiBridge::*; import ConnectalMemory::*; import ConnectalMMU::*; interface CoreIndication; method Action loadValue(Bit#(128) value, Bit#(32) cycles); method Action storeAddress(Bit#(64) addr); method Action loadMultipleLatency(Bit#(32) busWidth, Bit#(32) length, Bit#(32) count, Bit#(32) startTime, Bit#(32) endTime); endinterface interface CoreRequest; method Action loadMultiple(Bit#(64) addr, Bit#(32) length, Bit#(32) repetitions); method Action load(Bit#(64) addr, Bit#(32) length); method Action store(Bit#(64) addr, Bit#(128) value); //method Action sglist(Bit#(32) off, Bit#(40) addr, Bit#(32) len); method Action paref(Bit#(32) addr, Bit#(32) len); endinterface interface ReadBWIndication; interface CoreIndication coreIndication; endinterface interface ReadBWRequest; interface CoreRequest coreRequest; interface Axi4Master#(40,128,12) m_axi; interface TlpTrace trace; endinterface instance ConnectalMemory#(CoreRequest); endinstance instance ConnectalMemory#(ReadBWRequest); endinstance module mkReadBWRequest#(ReadBWIndication ind)(ReadBWRequest); FIFO#(Bit#(40)) readAddrFifo <- mkFIFO; FIFO#(Bit#(8)) readLenFifo <- mkFIFO; FIFO#(Bit#(40)) writeAddrFifo <- mkFIFO; FIFO#(Bit#(128)) writeDataFifo <- mkFIFO; FIFO#(TimestampedTlpData) ttdFifo <- mkFIFO; Reg#(Bit#(9)) readBurstCount <- mkReg(0); FIFO#(Tuple2#(Bit#(9),Bit#(32))) readBurstCountStartTimeFifo <- mkSizedFIFO(4); Reg#(Bit#(40)) readMultipleAddr <- mkReg(0); Reg#(Bit#(8)) readMultipleLen <- mkReg(0); Reg#(Bit#(8)) readMultipleCount <- mkReg(0); Reg#(Bit#(32)) timer <- mkReg(0); rule updateTimer; timer <= timer + 1; endrule Reg#(Bit#(16)) addrCount <- mkReg(0); rule readMultipleAddrGenerator if (addrCount > 0); readAddrFifo.enq(readMultipleAddr); readLenFifo.enq(readMultipleLen); addrCount <= addrCount - 1; endrule Reg#(Bit#(32)) loadMultipleStartTime <- mkReg(0); Reg#(Bit#(16)) completedCount <- mkReg(0); FIFO#(Tuple2#(Bit#(128),Bit#(32))) readDataFifo <- mkSizedFIFO(32); rule receivedData; let v = readDataFifo.first; readDataFifo.deq; ind.coreIndication.loadValue(tpl_1(v), tpl_2(v)); endrule interface CoreRequest coreRequest; method Action load(Bit#(64) addr, Bit#(32) len); readAddrFifo.enq(truncate(addr)); readLenFifo.enq(truncate(len)); endmethod: load method Action loadMultiple(Bit#(64) addr, Bit#(32) len, Bit#(32) count) if (completedCount == 0); loadMultipleStartTime <= timer; readMultipleAddr <= truncate(addr); readMultipleLen <= truncate(len); readMultipleCount <= truncate(count); addrCount <= truncate(count); completedCount <= truncate(count); endmethod: loadMultiple method Action store(Bit#(64) addr, Bit#(128) value); writeAddrFifo.enq(truncate(addr)); writeDataFifo.enq(value); endmethod: store endinterface: coreRequest interface Axi4Master m_axi; interface Axi4WriteClient write; method ActionValue#(Axi4WriteRequest#(40, 12)) address(); writeAddrFifo.deq; ind.coreIndication.storeAddress(zeroExtend(writeAddrFifo.first)); return Axi4WriteRequest { address: writeAddrFifo.first, burstLen: 0, id: 0 }; endmethod method ActionValue#(Axi4WriteData#(128, 16, 12)) data(); writeDataFifo.deq; return Axi4WriteData { data: writeDataFifo.first, byteEnable: 16'hffff, last: 1, id: 0 }; endmethod method Action response(Axi4WriteResponse#(12) r); endmethod endinterface: write interface Axi4ReadClient read; method ActionValue#(Axi4ReadRequest#(40, 12)) address(); Bit#(9) numWords = zeroExtend(readLenFifo.first) + 1; TimestampedTlpData ttd = unpack(0); ttd.unused = 1; Bit#(153) trace = 0; trace[127:64] = zeroExtend(numWords); trace[31:0] = readAddrFifo.first[31:0]; ttd.tlp = unpack(trace); ttdFifo.enq(ttd); readAddrFifo.deq; readLenFifo.deq; readBurstCountStartTimeFifo.enq(tuple2(numWords, timer)); return Axi4ReadRequest { address: readAddrFifo.first, burstLen: readLenFifo.first, id: 0}; endmethod method Action data(Axi4ReadResponse#(128, 12) response); let rbc = readBurstCount; if (rbc == 0) begin rbc = tpl_1(readBurstCountStartTimeFifo.first); end let readStartTime = tpl_2(readBurstCountStartTimeFifo.first); let latency = timer - readStartTime; TimestampedTlpData ttd = unpack(0); ttd.unused = 2; Bit#(153) trace = 0; trace[127:96] = response.data[127:96]; trace[95:64] = latency; trace[31:0] = zeroExtend(rbc); ttd.tlp = unpack(trace); if (rbc == 1) begin ttdFifo.enq(ttd); readDataFifo.enq(tuple2(response.data, latency)); // this request is done, dequeue its information readBurstCountStartTimeFifo.deq; if (completedCount == 1) ind.coreIndication.loadMultipleLatency(128, zeroExtend(readMultipleLen), zeroExtend(readMultipleCount), loadMultipleStartTime, timer); if (completedCount > 0) completedCount <= completedCount - 1; end readBurstCount <= rbc - 1; endmethod endinterface: read endinterface: m_axi interface TlpTrace trace; interface Get tlp; method ActionValue#(TimestampedTlpData) get(); ttdFifo.deq; return ttdFifo.first(); endmethod endinterface: tlp endinterface: trace endmodule: mkReadBWRequest ================================================ FILE: examples/readbw/testreadbw.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "ReadBW.h" #include #include #include #include #include #include //#include #include #include "../../drivers/pcie/bluenoc.h" CoreRequest *device = 0; int srcAlloc; unsigned int *srcBuffer = 0; size_t alloc_sz = 8192; int storeCount = 0; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (int i = 0; i < (len > 16 ? 16 : len) ; i++) fprintf(stderr, "%02x", (unsigned char)buf[i]); fprintf(stderr, "\n"); } class TestCoreIndication : public CoreIndication { virtual void storeAddress ( uint64_t addr ) { fprintf(stderr, "storeAddress addr=%08llx *(long*)srcBuffer=%lx\n", addr, *(long*)srcBuffer); if (storeCount < 16) { std::bitset<128> value128(0xD00DF00DDEADBEEFul); value128 |= (std::bitset<128>(0xAAAABBBBCCCCDDDDul) << 64); device->store(srcAlloc.entries[0].dma_address+storeCount*8, value128); storeCount++; } else { device->loadMultiple(srcAlloc.entries[0].dma_address, 7, 32); } } virtual void loadAddress ( uint64_t addr ) { fprintf(stderr, "loadAddress addr=%08llx\n", addr); } virtual void loadValue ( std::bitset<128> &value, uint32_t cycles ) { if (!srcBuffer) { srcBuffer = (unsigned int *)mmap(NULL, 1<<16, PROT_READ|PROT_WRITE, MAP_SHARED, device->fd, 1<<16); } fprintf(stderr, "loadValue value=%08lx%08lx cycles=%ld\n", ((value >> 64) & std::bitset<128>(0xFFFFFFFFFFFFFFFFul)).to_ulong(), (value & std::bitset<128>(0xFFFFFFFFFFFFFFFFul)).to_ulong(), cycles); fprintf(stderr, "srcBuffer[0] = %08lx\n", *(long *)srcBuffer); } virtual void loadMultipleLatency ( uint32_t busWidth, uint32_t beatsPerRead, uint32_t numReads, uint32_t startTime, uint32_t endTime ) { uint32_t numBytes = beatsPerRead * numReads * busWidth / 8; uint32_t numCycles = endTime - startTime; double numMicroSeconds = numCycles / 125.0; double megabytesPerSecond = numBytes / numMicroSeconds; fprintf(stderr, "loadMultiple %ld bytes latency=%ld cycles %f us %f MB/s\n", numBytes, numCycles, numMicroSeconds, megabytesPerSecond); } }; class TestCoreRequest : public CoreRequest { public: virtual void sglist(uint32_t off, uint64_t addr, uint32_t len) { } virtual void paref(uint32_t off, uint32_t ref, uint32_t foo) { } static TestCoreRequest *createTestCoreRequest(CoreIndication *indication) { const char *instanceName = "fpga0"; TestCoreRequest *instance = new TestCoreRequest(instanceName, indication); return instance; } protected: TestCoreRequest(const char *instanceName, CoreIndication *indication) : CoreRequest(instanceName, indication) { } ~TestCoreRequest() {} }; int main(int argc, const char **argv) { unsigned int srcGen = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); device = TestCoreRequest::createTestCoreRequest(new TestCoreIndication); fprintf(stderr, "allocating memory...\n"); memset(&srcAlloc, 0, sizeof(srcAlloc)); // use PortalAlloc if (1) { int rc = 0; srcAlloc = device->alloc(alloc_sz); fprintf(stderr, "alloc rc=%d fd=%d\n", rc, srcAlloc); srcBuffer = (unsigned int *)device->mmap(&srcAlloc); fprintf(stderr, "srcBuffer=%p\n", srcBuffer); memset(srcBuffer, 0xba, alloc_sz); fprintf(stderr, "srcBuffer[0]=%x\n", srcBuffer[0]); // flush cache not needed on x86 #ifdef __arm__ rc = device->dCacheFlushInval(srcAlloc, alloc_sz, srcBuffer); fprintf(stderr, "cache flushed rc=%d\n", rc); #endif // map the Dma buf into PCIe. Seems not to be needed. //rc = ioctl(device->fd, BNOC_DMA_BUF_MAP, srcAlloc.header.fd); //fprintf(stderr, "BNOC_DMA_BUF_MAP rc=%d errno=%d\n", rc, errno); } else { // use bluenoc driver to allocate memory coherent with PCIe tDmaMap dmaMap; srcBuffer = (unsigned int *)mmap(NULL, 1<<16, PROT_READ|PROT_WRITE, MAP_SHARED, device->fd, 1<<16); int rc = ioctl(device->fd, BNOC_DMA_MAP, &dmaMap); fprintf(stderr, "BNOC_PCI_ALLOC rc=%d errno=%d\n", rc, errno); fprintf(stderr, "srcBuffer=%p virt=%p dma_handle=%lx\n", srcBuffer, dmaMap.virt, dmaMap.dma_handle); srcAlloc.entries[0].dma_address = dmaMap.dma_handle; memset(srcBuffer, 0xda, 8192); } std::bitset<128> value128(0xD00DF00DDEADBEEFul); value128 |= (std::bitset<128>(0xAAAABBBBCCCCDDDDul) << 64); device->store(srcAlloc.entries[0].dma_address, value128); //device->loadMultiple(srcAlloc.entries[0].dma_address, 3, 1); portalExec(0); } ================================================ FILE: examples/regexp/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = RegexpRequest:Regexp.request H2S_INTERFACES = Regexp\#\(64\):RegexpIndication MEM_READ_INTERFACES = "append(lRegexp.config_read_client,lRegexp.haystack_read_client)" BSVFILES = $(CONNECTALDIR)/lib/regexp/bsv/Regexp.bsv CPPFILES=testregexp.cpp CONNECTALFLAGS = -D DEGPAR=4 -D MAX_NUM_STATES=32 -D MAX_NUM_CHARS=32 CONNECTALFLAGS += --stl=gnustl_static RUN_ARGS = test.bin CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/regexp/cpp CONNECTALFLAGS += --run-args="$(addprefix $(PWD)/, jregexp.charMap jregexp.stateMap jregexp.stateTransitions test.bin)" include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/regexp/testregexp.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include //#include //#include //#include #include "dmaManager.h" #include "RegexpIndication.h" #include "RegexpRequest.h" #include "regexp_utils.h" int main(int argc, const char **argv) { fprintf(stderr, "%s %s\n", __DATE__, __TIME__); const char *charMapFilename = "../jregexp.charMap"; const char *stateMapFilename = "../jregexp.stateMap"; const char *stateTransitionsFilename = "../jregexp.stateTransitions"; const char *testFilename = "../test.bin"; if (argc >= 4) { charMapFilename = argv[1]; stateMapFilename = argv[2]; stateTransitionsFilename = argv[3]; testFilename = argv[4]; } fprintf(stderr, "Using charMap %s stateMap %s stateTransitions %s test %s\n", charMapFilename, stateMapFilename, stateTransitionsFilename, testFilename); RegexpRequestProxy *device = new RegexpRequestProxy(IfcNames_RegexpRequestS2H); DmaManager *hostDma = platformInit(); RegexpIndication *deviceIndication = new RegexpIndication(IfcNames_RegexpIndicationH2S); haystack_dma = hostDma; //haystack_mmu = hostMMURequest; regexp = device; if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } // this is hard-coded into the REParser.java assert(32 == MAX_NUM_STATES); assert(32 == MAX_NUM_CHARS); if(1){ P charMapP; P stateMapP; P stateTransitionsP; readfile(charMapFilename, &charMapP); readfile(stateMapFilename, &stateMapP); readfile(stateTransitionsFilename, &stateTransitionsP); portalCacheFlush(charMapP.alloc, charMapP.mem, charMapP.length, 1); portalCacheFlush(stateMapP.alloc, stateMapP.mem, stateMapP.length, 1); portalCacheFlush(stateTransitionsP.alloc, stateTransitionsP.mem, stateTransitionsP.length, 1); for(int i = 0; i < num_tests; i++){ device->setup(charMapP.ref, charMapP.length); device->setup(stateMapP.ref, stateMapP.length); device->setup(stateTransitionsP.ref, stateTransitionsP.length); readfile(testFilename, &haystackP[i]); portalCacheFlush(haystackP[i].alloc, haystackP[i].mem, haystackP[i].length, 1); if(i==0) sw_match_cnt = num_tests*sw_ref(&haystackP[0], &charMapP, &stateMapP, &stateTransitionsP); sem_wait(&test_sem); int token = deviceIndication->token; assert(token < max_num_tokens); token_map[token] = i; // Regexp uses a data-bus width of 8 bytes. length must be a multiple of this dimension device->search(token, haystackP[i].ref, haystackP[i].length & ~((1<<3)-1)); } sem_wait(&test_sem); close(charMapP.alloc); close(stateMapP.alloc); close(stateTransitionsP.alloc); } fprintf(stderr, " testregexp: Done, hw_match_cnt=%d, sw_match_cnt=%d\n", hw_match_cnt, sw_match_cnt); sleep(1); return (hw_match_cnt == sw_match_cnt ? 0 : -1); } ================================================ FILE: examples/sdcard_spi/Makefile ================================================ CONNECTALDIR?=../.. BSVFILES = SPITest.bsv CPPFILES = sdcard_spi.cpp S2H_INTERFACES = SPIRequest:SPITest.spiRequest H2S_INTERFACES = SPITest:SPIIndication MEM_READ_INTERFACES = MEM_WRITE_INTERFACES = PINOUT_FILE += pin_translation.json PIN_TYPE = SPIMasterPins PIN_TYPE_INCLUDE = SPI AUTOTOP = --interface pins:SPITest.spiMasterPins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/sdcard_spi/SPI.bsv ================================================ // This is a simple SPI Master module. // This has only been tested with cpol == 0 and cpha == 0 // For information about SPI, check wikipedia: // https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus (* always_ready, always_enabled *) interface SPIMasterPins; // serial clock (* prefix = "", result = "spi_sclk" *) method Bit#(1) sclk; // master-out slave-in (* prefix = "", result = "spi_mosi" *) method Bit#(1) mosi; // master-in slave-out (* prefix = "" *) method Action miso((* port = "spi_miso" *)Bit#(1) x); // active-low chip select (* prefix = "", result = "spi_ncs" *) method Bit#(1) ncs; interface Clock deleteme_unused_clock; endinterface interface SPIMaster; // configuration method Action setSclkDiv(Bit#(16) d); method Action setNcs(Bit#(1) new_ncs); // Warning: mkSPIMaster untested for cpol == 1 method Action setCpol(Bit#(1) new_cpol); // idle value of clock // Warning: mkSPIMaster untesetd for cpha == 1 method Action setCpha(Bit#(1) new_cpha); // which clock transition captures data // cpha = 0 => odd transitions (1st, 3rd, etc.) // cpha = 1 => even transitions (2nd, 4th, etc.) // status method Bool isChipSelectEnabled(); // data method Action put(Bit#(8) x); method ActionValue#(Bit#(8)) get(); // pins (* prefix = "" *) interface SPIMasterPins pins; endinterface module mkSPIMaster(SPIMaster); let clock <- exposeCurrentClock(); // registers for the interface pins Reg#(Bit#(1)) sclkReg <- mkReg(0); Reg#(Bit#(16)) sclkDiv <- mkReg(1); Wire#(Bit#(1)) misoWire <- mkDWire(0); Reg#(Bit#(1)) misoReg <- mkReg(0); Reg#(Bit#(1)) ncsReg <- mkReg(1); // MSB gets shifted out Reg#(Bit#(8)) shiftReg <- mkReg(0); // SPI configuration Reg#(Bit#(1)) cpol <- mkReg(0); Reg#(Bit#(1)) cpha <- mkReg(0); // 17 ticks per SPI cycle, between each tick is a clock transition Reg#(Bool) running <- mkReg(False); Reg#(Bool) resultReady <- mkReg(False); Reg#(Bit#(5)) tickCount <- mkReg(0); // sclkReg determines how many mini ticks make up a tick Reg#(Bit#(16)) miniTickCount <- mkReg(0); (* fire_when_enabled, no_implicit_conditions *) rule run(running); let nextMiniTickCount = miniTickCount + 1; if ((nextMiniTickCount == sclkDiv) || sclkDiv == 0) begin miniTickCount <= 0; if (tickCount == 16) begin // done running <= False; resultReady <= True; tickCount <= 0; end else begin // tick clock sclkReg <= ~sclkReg; // increment tickCount tickCount <= tickCount + 1; // either capture input or shift output if (tickCount[0] == cpha) begin // capture input misoReg <= misoWire; end else begin // shift output if (tickCount == 0) begin // but never on the first tick end else begin shiftReg <= {shiftReg[6:0], misoReg}; end end end end else begin miniTickCount <= nextMiniTickCount; end endrule method Action setSclkDiv(Bit#(16) d) if (ncsReg == 1); sclkDiv <= d; endmethod method Action setNcs(Bit#(1) new_ncs); ncsReg <= new_ncs; endmethod method Action setCpol(Bit#(1) new_cpol) if (ncsReg == 1); cpol <= new_cpol; endmethod method Action setCpha(Bit#(1) new_cpha) if (ncsReg == 1); cpha <= new_cpha; endmethod method Bool isChipSelectEnabled(); return ncsReg == 0; endmethod method Action put(Bit#(8) x) if (!running); resultReady <= False; running <= True; tickCount <= 0; miniTickCount <= 0; shiftReg <= x; endmethod method ActionValue#(Bit#(8)) get() if (resultReady); resultReady <= False; return shiftReg; endmethod interface SPIMasterPins pins; method Bit#(1) sclk; return sclkReg; endmethod method Bit#(1) mosi; return running ? shiftReg[7] : 1; endmethod method Action miso(Bit#(1) x); misoWire <= x; endmethod method Bit#(1) ncs; return ncsReg; endmethod interface Clock deleteme_unused_clock = clock; endinterface endmodule ================================================ FILE: examples/sdcard_spi/SPITest.bsv ================================================ import SPI::*; interface SPITest; interface SPIRequest spiRequest; (* prefix = "" *) interface SPIMasterPins spiMasterPins; endinterface interface SPIRequest; method Action setSclkDiv(Bit#(16) d); method Action setNcs(Bit#(1) x); method Action put(Bit#(8) x); endinterface interface SPIIndication; method Action get(Bit#(8) x); endinterface module mkSPITest#(SPIIndication spiIndication)(SPITest); SPIMaster spi <- mkSPIMaster; Reg#(Bool) init <- mkReg(False); Reg#(Bool) active <- mkReg(False); Bool verbose = False; rule doInit(!init); spi.setNcs(1); spi.setCpol(0); spi.setCpha(0); spi.setSclkDiv(2); init <= True; endrule rule doComplete; active <= False; let x <- spi.get; spiIndication.get(x); if (verbose) $display("get: ", fshow(x)); endrule rule doDisplay(active); let sclk = spi.pins.sclk; let mosi = spi.pins.mosi; if (verbose) $display("sclk: %0d, mosi: %0d", sclk, mosi); endrule interface SPIRequest spiRequest; method Action setSclkDiv(Bit#(16) d); spi.setSclkDiv(d); endmethod method Action setNcs(Bit#(1) x); spi.setNcs(x); endmethod method Action put(Bit#(8) x); if (verbose) $display("put: ", fshow(x)); active <= True; spi.put(x); endmethod endinterface interface SPIMasterPins spiMasterPins = spi.pins; endmodule ================================================ FILE: examples/sdcard_spi/pin_translation.json ================================================ { "spi_sclk": { "PIO_DIRECTION": "OUTPUT", "sdio": "clk" }, "spi_mosi": { "PIO_DIRECTION": "OUTPUT", "sdio": "cmd" }, "spi_miso": { "PIO_DIRECTION": "INPUT", "sdio": "dat0" }, "spi_ncs": { "PIO_DIRECTION": "OUTPUT", "sdio": "cd_dat3" } } ================================================ FILE: examples/sdcard_spi/readme.txt ================================================ sdcard_spi example ------------------ This example uses SPI mode on an SD card to read the first block of data. This example was initially designed for the kc705g2 FPGA platform using an 8 GB SDHC card. Due to differences in initialization, this will not work on older, smaller SD cards, and it may not work on larger, newer SD* cards. The mkSPIMaster module in SPI.bsv has not been well tested. Currently this example is the only time it has been used. You may find bugs if you try to use it in a different situation (especially if SPI mode isn't 0). ================================================ FILE: examples/sdcard_spi/sdcard_spi.cpp ================================================ #include #include #include #include "SPIIndication.h" #include "SPIRequest.h" #include "GeneratedTypes.h" #include "portal.h" // x is {2'b01, cmd, arg} uint8_t getCRC7(uint64_t x) { uint8_t crc = 0; for (int i = 39 ; i >= 0 ; i--) { if (((crc >> 6) ^ (x >> i)) & 1) { crc = (0x7F & (crc << 1)) ^ 0x09; } else { crc = 0x7F & (crc << 1); } } return crc; } void printR1Resp( uint8_t resp ) { std::cout << "R1 Resp:"; if (resp != 0) { if (resp & (1 << 7)) std::cout << " ERROR_first_bit_not_zero"; if (resp & (1 << 6)) std::cout << " parameter_error"; if (resp & (1 << 5)) std::cout << " address_error"; if (resp & (1 << 4)) std::cout << " erase_sequence_error"; if (resp & (1 << 3)) std::cout << " com_crc_error"; if (resp & (1 << 2)) std::cout << " illegal_command"; if (resp & (1 << 1)) std::cout << " erase_reset"; if (resp & (1 << 0)) std::cout << " in_idle_state"; } else { std::cout << " (all zero)"; } std::cout << std::endl; } class SPI : public SPIIndicationWrapper { private: SPIRequestProxy spiRequest; sem_t sem; uint8_t data; public: SPI(unsigned int indicationId, unsigned int requestId) : SPIIndicationWrapper(indicationId), spiRequest(requestId) { sem_init(&sem, 1, 0); } void setSclkDiv(uint16_t x) { spiRequest.setSclkDiv(x); } void enableChip(bool x) { // ncs is active-low, so true => 0 and false => 1 if (x) { spiRequest.setNcs(0); } else { spiRequest.setNcs(1); } } uint8_t req(uint8_t x) { spiRequest.put(x); sem_wait(&sem); return data; } void get(uint8_t x) { data = x; sem_post(&sem); } }; class SD_SPIMode { private: SPI *spi; bool verbose; static const int cmd_resp_no_resp_flag = 0x200; // set if SD card never sent a valid response static const int cmd_resp_error_flag = 0x100; // set if there is a critical error in the response static const int cmd_resp_crc_error = 0x008; static const int cmd_resp_illegal_cmd = 0x004; public: SD_SPIMode(SPI* myspi) { spi = myspi; verbose = true; } // If this returns a value greater than 0xFF, then any further response // bytes will not be sent. int sendSDReq(uint8_t cmdIndx, uint32_t arg) { // This extra request is needed for some reason. This is not part // of the actual command. spi->req(0xFF); // Calculate crc uint64_t crc_in = 0x4000000000ull; crc_in = crc_in | ((0x3F & ((uint64_t) cmdIndx)) << 32) | ((uint64_t) arg); uint8_t crc = getCRC7(crc_in); // Send command if (verbose) std::cout << "Sending CMD" << std::dec << (int) cmdIndx << " with argument 0x" << std::hex << arg << std::endl; spi->req(0x40 | (0x3F & cmdIndx)); spi->req(0xFF & (arg >> (3*8))); spi->req(0xFF & (arg >> (2*8))); spi->req(0xFF & (arg >> (1*8))); spi->req(0xFF & arg); spi->req(0x01 | ((0x7F & crc) << 1)); // Get initial R1 response int resp; for (int i = 0 ; i <= 8 ; i++) { resp = (int) spi->req(0xFF); if ((resp & 0x80) == 0) { // This is a valid response if (resp & cmd_resp_illegal_cmd) { std::cerr << "ERROR: CMD" << std::dec << (int) cmdIndx << " is not supported by this SD card" << std::endl; // Set error flag resp |= cmd_resp_error_flag; } if (resp & cmd_resp_crc_error) { std::cerr << "ERROR: sendSDReq() for CMD" << std::dec << (int) cmdIndx << " had a CRC error" << std::endl; // Set error flag resp |= cmd_resp_error_flag; } return resp; } } std::cerr << "ERROR: sendSDReq() for CMD" << std::dec << (int) cmdIndx << " failed to get an R1 response after 9 tries" << std::endl; return cmd_resp_no_resp_flag; } uint8_t getByteResp() { return spi->req(0xFF); } uint32_t getWordResp() { uint32_t resp = (0xFF & ((uint32_t) spi->req(0xFF))) << (8*3); resp = resp | (0xFF & ((uint32_t) spi->req(0xFF))) << (8*2); resp = resp | (0xFF & ((uint32_t) spi->req(0xFF))) << (8*1); resp = resp | (0xFF & ((uint32_t) spi->req(0xFF))); return resp; } // This follows the SDHC portion of figure 7-2 in the Physical Layer // Specification Version 5.00 bool init(uint16_t d) { spi->enableChip(false); spi->setSclkDiv(d); usleep(100000); spi->enableChip(true); usleep(100000); for (int i = 0 ; i < 10 ; i++) { spi->req(0xFF); } // CMD0 if (verbose) std::cout << "init(): sending CMD0" << std::endl; int resp = sendSDReq(0, 0); if (resp > 0xFF) { return false; } if (resp != 1) { std::cerr << "ERROR: Unexpected R1 response from CMD0 during init()" << std::endl; printR1Resp(resp); return false; } // CMD8 - specifying 2.7-2.6 V and using 0x5B as the check pattern if (verbose) std::cout << "init(): sending CMD8" << std::endl; uint8_t echo_back = 0x5B; resp = sendSDReq(8, 0x100 | ((uint32_t) echo_back)); if (resp > 0xFF) { if (resp & cmd_resp_illegal_cmd) { std::cerr << "INFO: CMD8 is not supported by this SD card (SD card Ver 1.X)" << std::endl; std::cerr << "ERROR: This code does not support SD card Ver 1.X" << std::endl; printR1Resp(0xFF & resp); } return false; } uint32_t r7 = getWordResp(); if (r7 != (0x100 | ((uint32_t) echo_back))) { std::cerr << "ERROR: CMD8 echo failed. r7 = " << std::hex << r7 << std::endl; return false; } // CMD58 (optional) - read OCR if (verbose) std::cout << "init(): sending CMD58" << std::endl; resp = sendSDReq(58, 0); if (resp > 0xFF) { return false; } uint32_t ocr = getWordResp(); bool ccs = (bool) (ocr & (1ull << 30)); bool ready = (bool) (ocr & (1ull << 31)); if (verbose) { std::cout << "OCR: 0x" << std::hex << ocr << std::dec << std::endl; std::cout << "ccs: " << (ccs ? "yes" : "no") << std::endl; std::cout << "ready: " << (ready ? "yes" : "no") << std::endl; } // CMD55 -> ACMD41 if (verbose) std::cout << "init(): sending CMD55 and ACMD41" << std::endl; do { resp = sendSDReq(55, 0); if (resp > 0xFF) { return false; } resp = sendSDReq(41, 0x1u << 30); // HCS = 1 if (resp > 0xFF) { return false; } usleep(1000); } while (resp == 1); // CMD58 - read OCR (again) if (verbose) std::cout << "init(): sending CMD58" << std::endl; resp = sendSDReq(58, 0); if (resp > 0xFF) { return false; } ocr = getWordResp(); ccs = (bool) (ocr & (1ull << 30)); ready = (bool) (ocr & (1ull << 31)); if (verbose) { std::cout << "OCR: 0x" << std::hex << ocr << std::dec << std::endl; std::cout << "ccs: " << (ccs ? "yes" : "no") << std::endl; std::cout << "ready: " << (ready ? "yes" : "no") << std::endl; } if (!ready) { std::cerr << "ERROR: ready bit in OCR is not set" << std::endl; return false; } if (!ccs) { std::cerr << "INFO: ccs bit in OCR is not set." << std::endl; std::cerr << "ERROR: This code does not suport normal SD cards at the moment" << std::endl; return false; } if (verbose) { std::cout << "init(): made it to the end without failing" << std::endl; } return true; } // The block is 512 bytes bool readBlock(uint32_t blockAddr, void* data) { uint8_t resp = sendSDReq(17, blockAddr); if (resp > 0xFF) { std::cerr << "ERROR: readBlock failed" << std::endl; return false; } if (resp != 0) { printR1Resp(0xFF & resp); } uint8_t byte = 0; do { byte = spi->req(0xFF); } while (byte == 0xFF); // the first byte of the data response should be 0xFE if (byte != 0xFE) { std::cerr << "ERROR: Unexpected start of write block. resp = 0x" << std::hex << (int) resp << std::endl; return false; } uint8_t *dataChar = (uint8_t*) data; for (int i = 0 ; i < 512 ; i++) { dataChar[i] = spi->req(0xFF); } // Ignore the 16-bit CRC for now spi->req(0xFF); spi->req(0xFF); // Read was successful return true; } }; int main(int argc, char* argv[]) { simulator_dump_vcd = 1; SPI spi(IfcNames_SPIIndicationH2S, IfcNames_SPIRequestS2H); SD_SPIMode sd(&spi); // 2500 is the argument for setSclkDiv if (!sd.init(2500)) { std::cerr << "ERROR: sd.init() failed" << std::endl; return -1; } else { std::cout << "sd.init() successful" << std::endl; } // much faster clock spi.setSclkDiv(2); uint8_t data[512]; std::cout << "reading block 0" << std::endl; sd.readBlock(0, (void*) data); std::cout << "printing block 0" << std::endl; for (int i = 0 ; i < 512 ; i++) { if (((i % 16) == 0) && (i != 0)) { std::cout << std::endl; } else if (((i % 2) == 0) && (i != 0)) { std::cout << " "; } std::cout << std::setfill('0') << std::setw(2) << std::hex << (int) data[i]; } std::cout << std::endl; return 0; } ================================================ FILE: examples/simple/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = SimpleRequest:Simple.request H2S_INTERFACES = Simple:SimpleRequest BSVFILES = Simple.bsv CPPFILES = testsimple.cpp ifeq ($(BOARD), $(filter $(BOARD), de5 htg4)) PIN_BINDINGS?=PCIE:PCIE LED:LED OSC:OSC endif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/simple/Simple.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; typedef struct{ Bit#(32) a; Bit#(32) b; } S1 deriving (Bits); typedef struct{ Bit#(32) a; Bit#(16) b; Bit#(7) c; } S2 deriving (Bits); typedef enum { E1Choice1, E1Choice2, E1Choice3, E1ChoiceBig = 33554432, E1ChoiceBig2 = 33554433 } E1 deriving (Bits,Eq); typedef struct{ Bit#(32) a; E1 e1; } S3 deriving (Bits); typedef Bit#(24) Address; typedef Bit#(32) Intptr; typedef Bit#(8) Byte; interface SimpleRequest; method Action say1(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action say3(S1 v); method Action say4(S2 v); method Action say5(Bit#(32)a, Bit#(64) b, Bit#(32) c); method Action say6(Bit#(32)a, Bit#(40) b, Bit#(32) c); method Action say7(S3 v); method Action say8(Vector#(128, Bit#(32)) v); method Action say9(E1 v, E1 w); method Action sayv1 (Vector#(4, Int#(32)) arg1, Vector#(4, Int#(32)) arg2); method Action sayv2 (Vector#(16, Int#(16)) v); method Action sayv3 (Vector#(16, Int#(16)) v, Int#(16) count); method Action saypixels(Vector#(2, Bit#(32)) xs, Vector#(2, Bit#(32)) ys, Vector#(2, Bit#(32)) zs); method Action reftest1(Address dst, Intptr dst_stride, Address src1, Intptr i_src_stride1, Address src2, Intptr i_src_stride2, Byte i_width, Byte i_height, Bool qpelInt, Bool hasWeight, Byte i_offset, Byte i_scale, Byte i_denom); endinterface typedef struct { Bit#(32) a; Bit#(40) b; Bit#(32) c; } Say6ReqSimple deriving (Bits); interface Simple; interface SimpleRequest request; endinterface module mkSimple#(SimpleRequest indication)(Simple); let verbose = False; interface SimpleRequest request; method Action say1(Bit#(32) v); if (verbose) $display("mkSimple::say1"); indication.say1(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); if (verbose) $display("mkSimple::say2"); indication.say2(a,b); endmethod method Action say3(S1 v); if (verbose) $display("mkSimple::say3"); indication.say3(v); endmethod method Action say4(S2 v); if (verbose) $display("mkSimple::say4"); indication.say4(v); endmethod method Action say5(Bit#(32) a, Bit#(64) b, Bit#(32) c); if (verbose) $display("mkSimple::say5"); indication.say5(a, b, c); endmethod method Action say6(Bit#(32) a, Bit#(40) b, Bit#(32) c); if (verbose) $display("mkSimple::say6"); indication.say6(a, b, c); endmethod method Action say7(S3 v); if (verbose) $display("mkSimple::say7"); indication.say7(v); endmethod method Action say8(Vector#(128, Bit#(32)) v); if (verbose) $display("mkSimple::say8"); indication.say8(v); endmethod method Action say9(E1 v, E1 w); if (verbose) $display("mkSimple::say9", v, w); indication.say9(v, w); endmethod method Action sayv1 (Vector#(4, Int#(32)) arg1, Vector#(4, Int#(32)) arg2); if (verbose) $display("mkSimple::sayv1"); indication.sayv1(arg1, arg2); endmethod method Action sayv2 (Vector#(16, Int#(16)) v); if (verbose) $display("mkSimple::sayv2"); indication.sayv2(v); endmethod method Action sayv3 (Vector#(16, Int#(16)) v, Int#(16) count); if (verbose) $display("mkSimple::sayv3"); indication.sayv3(v, count); endmethod method Action saypixels(Vector#(2, Bit#(32)) xs, Vector#(2, Bit#(32)) ys, Vector#(2, Bit#(32)) zs); if (verbose) $display("mkSimple::saypixels"); indication.saypixels(xs, ys, zs); endmethod method Action reftest1(Address dst, Intptr dst_stride, Address src1, Intptr i_src_stride1, Address src2, Intptr i_src_stride2, Byte i_width, Byte i_height, Bool qpelInt, Bool hasWeight, Byte i_offset, Byte i_scale, Byte i_denom); //if (verbose) $display("mkSimple::reftest1 dst %x dst_stride %x src1 %x i_src_stride1 %x src2 %x i_src_stride2 %x i_width %x i_height %x qpelInt %x hasWeight %x i_offset %x i_scale %x i_denom %x\n", dst, dst_stride, src1, i_src_stride1, src2, i_src_stride2, i_width, i_height, qpelInt, hasWeight, i_offset, i_scale, i_denom); indication.reftest1(dst, dst_stride, src1, i_src_stride1, src2, i_src_stride2, i_width, i_height, qpelInt, hasWeight, i_offset, i_scale, i_denom); endmethod endinterface endmodule ================================================ FILE: examples/simple/boards/de5.json ================================================ { "PCIE_tx_p[0]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[0]" }, "PCIE_tx_p[1]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[1]" }, "PCIE_tx_p[2]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[2]" }, "PCIE_tx_p[3]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[3]" }, "PCIE_tx_p[4]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[4]" }, "PCIE_tx_p[5]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[5]" }, "PCIE_tx_p[6]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[6]" }, "PCIE_tx_p[7]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[7]" }, "PCIE_rx_p[0]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[0]" }, "PCIE_rx_p[1]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[1]" }, "PCIE_rx_p[2]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[2]" }, "PCIE_rx_p[3]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[3]" }, "PCIE_rx_p[4]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[4]" }, "PCIE_rx_p[5]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[5]" }, "PCIE_rx_p[6]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[6]" }, "PCIE_rx_p[7]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[7]" }, "pcie_refclk_p": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_REFCLK_p" }, "pcie_perst_n": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_PERST_n" }, "osc_50_b3b": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B3B" }, "leds[0]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[0]" }, "leds[1]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[1]" }, "leds[2]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[2]" }, "leds[3]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[3]" } } ================================================ FILE: examples/simple/boards/htg4.json ================================================ { "PCIE_tx_p[0]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[0]" }, "PCIE_tx_p[1]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[1]" }, "PCIE_tx_p[2]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[2]" }, "PCIE_tx_p[3]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[3]" }, "PCIE_tx_p[4]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[4]" }, "PCIE_tx_p[5]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[5]" }, "PCIE_tx_p[6]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[6]" }, "PCIE_tx_p[7]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[7]" }, "PCIE_rx_p[0]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[0]" }, "PCIE_rx_p[1]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[1]" }, "PCIE_rx_p[2]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[2]" }, "PCIE_rx_p[3]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[3]" }, "PCIE_rx_p[4]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[4]" }, "PCIE_rx_p[5]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[5]" }, "PCIE_rx_p[6]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[6]" }, "PCIE_rx_p[7]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[7]" }, "pcie_refclk_p": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_REFCLK_p" }, "pcie_perst_n": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_PERST_n" }, "clk_100Mhz": { "PIO_DIRECTION": "INPUT", "OSC": "CLK100" }, "leds[0]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[0]" }, "leds[1]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[1]" }, "leds[2]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[2]" }, "leds[3]": { "PIO_DIRECTION": "OUTPUT", "LED": "LED[3]" } } ================================================ FILE: examples/simple/simple.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * Copyright (c) 2016 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "SimpleRequest.h" #if 1 #define TEST_ASSERT(A) assert(A) #else #define TEST_ASSERT(A) {} #endif #define NUMBER_OF_TESTS 13 uint32_t v1a = 42; uint32_t v2a = 2; uint32_t v2b = 4; S2 s2 = {7, 8, 9}; S1 s1 = {3, 6}; uint32_t v5a = 0x00000000; uint64_t v5b = 0xDEADBEEFFECAFECA; uint32_t v5c = 0x00000001; uint32_t v6a = 0xBBBBBBBB; uint64_t v6b = 0x000000EFFECAFECA; uint32_t v6c = 0xCCCCCCCC; uint32_t v7a = 0xDADADADA; E1 v7b = E1Choice2; S3 s3 = { a: v7a, e1: v7b }; E1 v9v = E1Choice2; E1 v9w = E1ChoiceBig; bsvvector_Luint32_t_L2 xs = { 0xa1, 0xa2 }; bsvvector_Luint32_t_L2 ys = { 0xb1, 0xb2 }; bsvvector_Luint32_t_L2 zs = { 0xc1, 0xc2 }; class Simple : public SimpleRequestWrapper { public: uint32_t cnt; uint32_t times; void incr_cnt(){ if (++cnt == NUMBER_OF_TESTS) exit(0); } void say1(uint32_t a) { fprintf(stderr, "say1(%d)\n", a); TEST_ASSERT(a == v1a); incr_cnt(); } void say2(uint16_t a, uint16_t b) { fprintf(stderr, "say2(%d %d)\n", a, b); TEST_ASSERT(a == v2a); TEST_ASSERT(b == v2b); incr_cnt(); } void say3(S1 s){ fprintf(stderr, "say3(S1{a:%d,b:%d})\n", s.a, s.b); TEST_ASSERT(s.a == s1.a); TEST_ASSERT(s.b == s1.b); incr_cnt(); } void say4(S2 s){ fprintf(stderr, "say4(S2{a:%d,b:%d,c:%d})\n", s.a,s.b,s.c); TEST_ASSERT(s.a == s2.a); TEST_ASSERT(s.b == s2.b); TEST_ASSERT(s.c == s2.c); incr_cnt(); } void say5(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say5(%08x, %016llx, %08x)\n", a, (long long)b, c); TEST_ASSERT(a == v5a); TEST_ASSERT(b == v5b); TEST_ASSERT(c == v5c); incr_cnt(); } void say6(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say6(%08x, %016llx, %08x)\n", a, (long long)b, c); TEST_ASSERT(a == v6a); TEST_ASSERT(b == v6b); TEST_ASSERT(c == v6c); incr_cnt(); } void say7(S3 v) { fprintf(stderr, "say7(%08x, %08x)\n", v.a, v.e1); TEST_ASSERT(v.a == v7a); TEST_ASSERT(v.e1 == v7b); incr_cnt(); } void say8 ( const bsvvector_Luint32_t_L128 v ) { fprintf(stderr, "say8\n"); for (int i = 0; i < 128; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i]); incr_cnt(); } void say9(E1 v, E1 w) { fprintf(stderr, "say9(%08x, %08x)\n", v, w); TEST_ASSERT(v == v9v); TEST_ASSERT(w == v9w); incr_cnt(); } void sayv1(const int32_t*arg1, const int32_t*arg2) { fprintf(stderr, "sayv1\n"); for (int i = 0; i < 4; i++) fprintf(stderr, " [%d] = 0x%x, 0x%x\n", i, arg1[i], arg2[i]); incr_cnt(); } void sayv2(const int16_t* v) { fprintf(stderr, "sayv2\n"); for (int i = 0; i < 16; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i] & 0xffff); incr_cnt(); } void sayv3(const int16_t* v, int16_t count) { fprintf(stderr, "sayv3: count 0x%x\n", count); for (int i = 0; i < 16; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i] & 0xffff); incr_cnt(); } void saypixels ( const bsvvector_Luint32_t_L2 indxs, const bsvvector_Luint32_t_L2 indys, const bsvvector_Luint32_t_L2 indzs ) { fprintf(stderr, "saypixels\n"); for (int i = 0; i < 2; i++) { fprintf(stderr, "xs[%d] = %08x ys[%d] = %08x zs[%d] = %08x\n", i, indxs[i], i, indys[i], i, indzs[i]); } incr_cnt(); } void reftest1 ( const Address dst, const Intptr dst_stride, const Address src1, const Intptr i_src_stride1, const Address src2, const Intptr i_src_stride2, const Byte i_width, const Byte i_height, const int qpelInt, const int hasWeight, const Byte i_offset, const Byte i_scale, const Byte i_denom ) { fprintf(stderr, "reftest1: %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x\n", (uint32_t)dst, (uint32_t)dst_stride, (uint32_t)src1, (uint32_t)i_src_stride1, (uint32_t)src2, (uint32_t)i_src_stride2, (uint32_t)i_width, (uint32_t)i_height, (uint32_t)qpelInt, (uint32_t)hasWeight, (uint32_t)i_offset, (uint32_t)i_scale, (uint32_t)i_denom ); incr_cnt(); } Simple(unsigned int id, PortalTransportFunctions *transport = 0, void *param = 0, PortalPoller *poller = 0) : SimpleRequestWrapper(id, transport, param, poller), cnt(0){} }; ================================================ FILE: examples/simple/testsimple.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * Copyright (c) 2016 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "SimpleRequest.h" #include "simple.h" int main(int argc, const char **argv) { int32_t testval = 0x1234abcd, v1arg1[4], v1arg2[4]; int16_t v2v[16]; Simple indication(IfcNames_SimpleRequestH2S); SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequestS2H); device->pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ fprintf(stderr, "Main::calling say1(%d)\n", v1a); device->say1(v1a); fprintf(stderr, "Main::calling say2(%d, %d)\n", v2a,v2b); device->say2(v2a,v2b); fprintf(stderr, "Main::calling say3(S1{a:%d,b:%d})\n", s1.a,s1.b); device->say3(s1); fprintf(stderr, "Main::calling say4(S2{a:%d,b:%d,c:%d})\n", s2.a,s2.b,s2.c); device->say4(s2); fprintf(stderr, "Main::calling say5(%08x, %016llx, %08x)\n", v5a, (long long)v5b, v5c); device->say5(v5a, v5b, v5c); fprintf(stderr, "Main::calling say6(%08x, %016llx, %08x)\n", v6a, (long long)v6b, v6c); device->say6(v6a, v6b, v6c); fprintf(stderr, "Main::calling say7(%08x, %08x)\n", s3.a, s3.e1); device->say7(s3); bsvvector_Luint32_t_L128 vect; for (int i = 0; i < 128; i++) vect[i] = -i*32; fprintf(stderr, "Main::calling say8\n"); device->say8(vect); for (int i = 0; i < 4; i++) { v1arg1[i] = testval; v1arg2[i] = ~testval; testval = (testval << 4) | ((testval >> 28) & 0xf); } fprintf(stderr, "Main::calling say9\n"); device->say9(v9v, v9w); device->sayv1(v1arg1, v1arg2); testval = 0x12349876; for (int i = 0; i < 16; i++) { v2v[i] = testval; testval = (testval << 4) | ((testval >> 28) & 0xf); } device->sayv2(v2v); device->sayv3(v2v, 44); device->saypixels(xs, ys, zs); device->reftest1 ( 0xaabbcc, 0x11223344, 0xddeeff, 0x44332211, 0x123456, 0x87654321, 0x12, 0x34, 0x123456, 0x7654321, 0x34, 0x56, 0x77); fprintf(stderr, "Main::about to go to sleep\n"); while(1) sleep(10); } ================================================ FILE: examples/simplemultibluesim/Link.bsv ================================================ /* Copyright (c) 2015 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import Vector::*; import FIFO::*; import GetPut::*; import Pipe::*; import Connectable::*; import CtrlMux::*; import Portal::*; import ConnectalConfig::*; import CnocPortal::*; import SimLink::*; import LinkIF::*; import Simple::*; import SimpleRequest::*; import LinkRequest::*; module mkLink#(SimpleRequest simple2IndicationProxy)(Link); // the indications from simpleRequest will be connected to the request interface to simpleReuqest2 Reg#(Bit#(1)) listening <- mkReg(0); Bool useLink = True; Integer linknumber = 17; SimpleRequestOutput simple1Output <- mkSimpleRequestOutput(); Simple simple1 <- mkSimple(simple1Output.ifc); Simple simple2 <- mkSimple(simple2IndicationProxy); SimpleRequestInput simple2Input <- mkSimpleRequestInput(); mkConnection(simple2Input.pipes, simple2.request); // now connect them via a Cnoc link SimLink#(32) link <- mkSimLink(); let msgIndication <- mkPortalMsgIndication(22, simple1Output.portalIfc.indications, simple1Output.portalIfc.messageSize); let msgRequest <- mkPortalMsgRequest(23, simple2Input.portalIfc.requests); if (useLink) begin rule tx; let msg <- toGet(msgIndication.message).get(); $display("%d.%d transmitting msg %h", linknumber, listening, msg); link.tx.enq(msg); endrule rule rx; let v <- toGet(link.rx).get(); msgRequest.message.enq(v); $display("%d.%d received msg %h", linknumber, listening, v); endrule end if (!useLink) rule connect if (!useLink); let v <- toGet(msgIndication.message).get(); msgRequest.message.enq(v); $display("message value %h", v); endrule interface SimpleRequest simpleRequest = simple1.request; interface LinkRequest linkRequest; method Action start(Bit#(32) l); $display("Link.start linknumber=%d l=%d", linknumber,l); if (useLink) link.start(fromInteger(linknumber), unpack(truncate(l))); listening <= truncate(l); endmethod endinterface endmodule : mkLink export mkLink; export Link; ================================================ FILE: examples/simplemultibluesim/LinkIF.bsv ================================================ /* Copyright (c) 2015 Connectal Project. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import ConnectalConfig::*; import Simple::*; interface LinkRequest; method Action start(Bit#(32) listening); endinterface interface Link; interface LinkRequest linkRequest; interface SimpleRequest simpleRequest; endinterface ================================================ FILE: examples/simplemultibluesim/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = LinkRequest:Link.linkRequest SimpleRequest:Link.simpleRequest H2S_INTERFACES = Link:SimpleRequest BSVFILES = ../simple/Simple.bsv LinkIF.bsv CPPFILES=testsimple.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/simplemultibluesim/run.sh ================================================ #!/bin/sh cd bluesim BLUESIM_SOCKET_NAME=socket1 ./bin/bsim & bsim1_pid=$! BLUESIM_SOCKET_NAME=socket2 ./bin/bsim & bsim2_pid=$! BLUESIM_SOCKET_NAME=socket1 ./bin/bsim_exe & bsimexe1_pid=$! BLUESIM_SOCKET_NAME=socket2 ./bin/bsim_exe & bsimexe2_pid=$! wait $bsimexe1_pid $bsimexe2_pid kill $bsim1_pid $bsim2_pid ================================================ FILE: examples/simplemultibluesim/testsimple.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include "SimpleRequest.h" #include "LinkRequest.h" #define NUMBER_OF_TESTS 8 uint32_t v1a = 42; int v2a = 2; int v2b = 4; S2 s2 = {7, 8, 9}; S1 s1 = {3, 6}; uint32_t v5a = 0x00000000; uint64_t v5b = 0xDEADBEEFFECAFECA; uint32_t v5c = 0x00000001; uint32_t v6a = 0xBBBBBBBB; uint64_t v6b = 0x000000EFFECAFECA; uint32_t v6c = 0xCCCCCCCC; uint32_t v7a = 0xDADADADA; E1 v7b = E1Choice2; S3 s3 = { a: v7a, e1: v7b }; class SimpleRequest : public SimpleRequestWrapper { public: uint32_t cnt; void incr_cnt(){ cnt++; fprintf(stderr, "saw %d responses\n", cnt); if (cnt == NUMBER_OF_TESTS) exit(0); } virtual void say1(uint32_t a) { fprintf(stderr, "say1(%d)\n", a); assert(a == v1a); incr_cnt(); } virtual void say2(uint16_t a, uint16_t b) { fprintf(stderr, "say2(%d %d)\n", a, b); assert(a == v2a); assert(b == v2b); incr_cnt(); } virtual void say3(S1 s){ fprintf(stderr, "say3(S1{a:%d,b:%d})\n", s.a, s.b); assert(s.a == s1.a); assert(s.b == s1.b); incr_cnt(); } virtual void say4(S2 s){ fprintf(stderr, "say4(S2{a:%d,b:%d,c:%d})\n", s.a,s.b,s.c); assert(s.a == s2.a); assert(s.b == s2.b); assert(s.c == s2.c); incr_cnt(); } virtual void say5(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say5(%08x, %016llx, %08x)\n", a, (long long)b, c); assert(a == v5a); assert(b == v5b); assert(c == v5c); incr_cnt(); } virtual void say6(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say6(%08x, %016llx, %08x)\n", a, (long long)b, c); assert(a == v6a); assert(b == v6b); assert(c == v6c); incr_cnt(); } virtual void say7(S3 v) { fprintf(stderr, "say7(%08x, %08x)\n", v.a, v.e1); assert(v.a == v7a); assert(v.e1 == v7b); incr_cnt(); } virtual void say8 ( const bsvvector_Luint32_t_L128 v ) { fprintf(stderr, "say8\n"); for (int i = 0; i < 128; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i]); incr_cnt(); } void sayv1(const int32_t*arg1, const int32_t*arg2) { fprintf(stderr, "sayv1\n"); for (int i = 0; i < 4; i++) fprintf(stderr, " [%d] = 0x%x, 0x%x\n", i, arg1[i], arg2[i]); incr_cnt(); } void sayv2(const int16_t* v) { fprintf(stderr, "sayv2\n"); for (int i = 0; i < 16; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i] & 0xffff); incr_cnt(); } void sayv3(const int16_t* v, int16_t count) { fprintf(stderr, "sayv3: count 0x%x\n", count); for (int i = 0; i < 16; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i] & 0xffff); incr_cnt(); } void reftest1 ( const Address dst, const Intptr dst_stride, const Address src1, const Intptr i_src_stride1, const Address src2, const Intptr i_src_stride2, const Byte i_width, const Byte i_height, const int qpelInt, const int hasWeight, const Byte i_offset, const Byte i_scale, const Byte i_denom ) { fprintf(stderr, "reftest1: %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x\n", (uint32_t)dst, (uint32_t)dst_stride, (uint32_t)src1, (uint32_t)i_src_stride1, (uint32_t)src2, (uint32_t)i_src_stride2, (uint32_t)i_width, (uint32_t)i_height, (uint32_t)qpelInt, (uint32_t)hasWeight, (uint32_t)i_offset, (uint32_t)i_scale, (uint32_t)i_denom ); incr_cnt(); } SimpleRequest(unsigned int id) : SimpleRequestWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { LinkRequestProxy linkRequest(IfcNames_LinkRequestS2H); SimpleRequest indication(IfcNames_SimpleRequestH2S); SimpleRequestProxy device(IfcNames_SimpleRequestS2H); linkRequest.pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ device.pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ const char *socketName = getenv("BLUESIM_SOCKET_NAME"); if (!socketName) { fprintf(stderr, "Specify name of link socket to use BLUESIM_SOCKET_NAME"); exit(1); } int listening = (strcmp(socketName, "socket1") == 0); fprintf(stderr, "linkRequest.start(%d) [socketName=%s]\n", listening, socketName); linkRequest.start(listening); if (1) { fprintf(stderr, "Main::calling say1(%d)\n", v1a); device.say1(v1a); fprintf(stderr, "Main::calling say2(%d, %d)\n", v2a,v2b); device.say2(v2a,v2b); fprintf(stderr, "Main::calling say3(S1{a:%d,b:%d})\n", s1.a,s1.b); device.say3(s1); fprintf(stderr, "Main::calling say4(S2{a:%d,b:%d,c:%d})\n", s2.a,s2.b,s2.c); device.say4(s2); fprintf(stderr, "Main::calling say5(%08x, %016llx, %08x)\n", v5a, (long long)v5b, v5c); device.say5(v5a, v5b, v5c); fprintf(stderr, "Main::calling say6(%08x, %016llx, %08x)\n", v6a, (long long)v6b, v6c); device.say6(v6a, v6b, v6c); fprintf(stderr, "Main::calling say7(%08x, %08x)\n", s3.a, s3.e1); device.say7(s3); bsvvector_Luint32_t_L128 vect; for (int i = 0; i < 128; i++) vect[i] = -i*32; fprintf(stderr, "Main::calling say8\n"); device.say8(vect); } fprintf(stderr, "Main::about to go to sleep\n"); while(true){sleep(2);} } ================================================ FILE: examples/simplemultibluesim/xsimrun.sh ================================================ #!/bin/sh cd xsim SOFTWARE_SOCKET_NAME=node1. xsim -R work.xsimtop & xsim1_pid=$! SOFTWARE_SOCKET_NAME=node2. xsim -R work.xsimtop & xsim2_pid=$! sleep 10 SOFTWARE_SOCKET_NAME=node1. ./bin/ubuntu.exe & xsimexe1_pid=$! SOFTWARE_SOCKET_NAME=node2. ./bin/ubuntu.exe & xsimexe2_pid=$! wait $xsimexe1_pid $xsimexe2_pid kill $xsim1_pid $xsim2_pid ================================================ FILE: examples/simplesharedhw/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SharedMemoryPortalConfig S2H_INTERFACES = /SimpleRequest:Simple.request H2S_INTERFACES = /Simple:SimpleRequest MEM_READ_INTERFACES = "cons(lSharereadEngine.dmaClient,nil)" MEM_WRITE_INTERFACES = "cons(lSharewriteEngine.dmaClient,nil)" CONNECTALFLAGS += -D USE_ACP -D USE_DUAL_CLOCK_FIFOF BSVFILES = Simple.bsv $(CONNECTALDIR)/bsv/Portal.bsv CPPFILES=testsimple.cpp CONNECTALFLAGS += -D USE_ACP AUTOTOP = --importfiles SharedMemoryPortal --importfiles SharedMemoryPortalConfig --importfiles MemTypes --importfiles MemReadEngine --importfiles MemWriteEngine include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/simplesharedhw/Simple.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; typedef struct{ Bit#(32) a; Bit#(32) b; } S1 deriving (Bits); typedef struct{ Bit#(32) a; Bit#(16) b; Bit#(7) c; } S2 deriving (Bits); typedef enum { E1Choice1, E1Choice2, E1Choice3 } E1 deriving (Bits,Eq); typedef struct{ Bit#(32) a; E1 e1; } S3 deriving (Bits); interface SimpleRequest; method Action say1(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action say3(S1 v); method Action say4(S2 v); method Action say5(Bit#(32)a, Bit#(64) b, Bit#(32) c); method Action say6(Bit#(32)a, Bit#(40) b, Bit#(32) c); method Action say7(S3 v); method Action say8(Vector#(128, Bit#(32)) v); method Action sayv1 (Vector#(4, Int#(32)) arg1, Vector#(4, Int#(32)) arg2); method Action sayv2 (Vector#(16, Int#(16)) v); method Action sayv3 (Vector#(16, Int#(16)) v, Int#(16) count); endinterface typedef struct { Bit#(32) a; Bit#(40) b; Bit#(32) c; } Say6ReqSimple deriving (Bits); interface Simple; interface SimpleRequest request; endinterface module mkSimple#(SimpleRequest indication)(Simple); let verbose = False; interface SimpleRequest request; method Action say1(Bit#(32) v); if (verbose) $display("mkSimple::say1"); indication.say1(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); if (verbose) $display("mkSimple::say2"); indication.say2(a,b); endmethod method Action say3(S1 v); if (verbose) $display("mkSimple::say3"); indication.say3(v); endmethod method Action say4(S2 v); if (verbose) $display("mkSimple::say4"); indication.say4(v); endmethod method Action say5(Bit#(32) a, Bit#(64) b, Bit#(32) c); if (verbose) $display("mkSimple::say5"); indication.say5(a, b, c); endmethod method Action say6(Bit#(32) a, Bit#(40) b, Bit#(32) c); if (verbose) $display("mkSimple::say6"); indication.say6(a, b, c); endmethod method Action say7(S3 v); if (verbose) $display("mkSimple::say7"); indication.say7(v); endmethod method Action say8(Vector#(128, Bit#(32)) v); if (verbose) $display("mkSimple::say8"); indication.say8(v); endmethod method Action sayv1 (Vector#(4, Int#(32)) arg1, Vector#(4, Int#(32)) arg2); if (verbose) $display("mkSimple::sayv1"); indication.sayv1(arg1, arg2); endmethod method Action sayv2 (Vector#(16, Int#(16)) v); if (verbose) $display("mkSimple::sayv2"); indication.sayv2(v); endmethod method Action sayv3 (Vector#(16, Int#(16)) v, Int#(16) count); if (verbose) $display("mkSimple::sayv3"); indication.sayv3(v, count); endmethod endinterface endmodule ================================================ FILE: examples/simplesharedhw/testsimple.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "SimpleRequest.h" #include "dmaManager.h" #include "manualMMUIndication.h" #if 1 #define TEST_ASSERT(A) assert(A) #else #define TEST_ASSERT(A) {} #endif uint32_t v1a = 42; int v2a = 2; int v2b = 4; S2 s2 = {7, 8, 9}; S1 s1 = {3, 6}; uint32_t v5a = 0x00000000; uint64_t v5b = 0xDEADBEEFFECAFECA; uint32_t v5c = 0x00000001; uint32_t v6a = 0xBBBBBBBB; uint64_t v6b = 0x000000EFFECAFECA; uint32_t v6c = 0xCCCCCCCC; uint32_t v7a = 0xDADADADA; E1 v7b = E1Choice2; S3 s3 = { a: v7a, e1: v7b }; class Simple : public SimpleRequestWrapper { public: uint32_t cnt; uint32_t times; sem_t sem; void wait() { sem_wait(&sem); cnt = 0; } void incr_cnt(){ if (++cnt == 7*times) sem_post(&sem); } void say1(uint32_t a) { fprintf(stderr, "say1(%d)\n", a); TEST_ASSERT(a == v1a); incr_cnt(); } void say2(uint16_t a, uint16_t b) { fprintf(stderr, "say2(%d %d)\n", a, b); TEST_ASSERT(a == v2a); TEST_ASSERT(b == v2b); incr_cnt(); } void say3(S1 s){ fprintf(stderr, "say3(S1{a:%d,b:%d})\n", s.a, s.b); TEST_ASSERT(s.a == s1.a); TEST_ASSERT(s.b == s1.b); incr_cnt(); } void say4(S2 s){ fprintf(stderr, "say4(S2{a:%d,b:%d,c:%d})\n", s.a,s.b,s.c); TEST_ASSERT(s.a == s2.a); TEST_ASSERT(s.b == s2.b); TEST_ASSERT(s.c == s2.c); incr_cnt(); } void say5(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say5(%08x, %016llx, %08x)\n", a, (long long)b, c); TEST_ASSERT(a == v5a); TEST_ASSERT(b == v5b); TEST_ASSERT(c == v5c); incr_cnt(); } void say6(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say6(%08x, %016llx, %08x)\n", a, (long long)b, c); TEST_ASSERT(a == v6a); TEST_ASSERT(b == v6b); TEST_ASSERT(c == v6c); incr_cnt(); } void say7(S3 v) { fprintf(stderr, "say7(%08x, %08x)\n", v.a, v.e1); TEST_ASSERT(v.a == v7a); TEST_ASSERT(v.e1 == v7b); incr_cnt(); } void say8 ( const bsvvector_Luint32_t_L128 v ) { fprintf(stderr, "say8\n"); for (int i = 0; i < 128; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i]); incr_cnt(); } void sayv1(const int32_t*arg1, const int32_t*arg2) { fprintf(stderr, "sayv1\n"); for (int i = 0; i < 4; i++) fprintf(stderr, " [%d] = 0x%x, 0x%x\n", i, arg1[i], arg2[i]); incr_cnt(); } void sayv2(const int16_t* v) { fprintf(stderr, "sayv2\n"); for (int i = 0; i < 16; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i] & 0xffff); incr_cnt(); } void sayv3(const int16_t* v, int16_t count) { fprintf(stderr, "sayv3: count 0x%x\n", count); for (int i = 0; i < 16; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i] & 0xffff); incr_cnt(); } Simple(unsigned int id, unsigned int numtimes=1, PortalTransportFunctions *item=0, void *param = 0) : SimpleRequestWrapper(id, item, param), cnt(0), times(numtimes) { sem_init(&sem, 0, 0); } }; DmaManager *dma; Simple *indication; int main(int argc, const char **argv) { int verbose = 1; int numtimes = 10; int wait_per_iter = 1; uint32_t alloc_sz = 32768; dma = platformInit(); //#define FF {dma} #define FF SHARED_DMA(PlatformIfcNames_MMURequestS2H, PlatformIfcNames_MMUIndicationH2S) PortalSharedParam parami = {FF, alloc_sz, SHARED_HARDWARE(IfcNames_SimpleRequestPipesH2S)}; indication = new Simple(IfcNames_SimpleRequestH2S, (wait_per_iter) ? 1 : numtimes , &transportShared, ¶mi ); PortalSharedParam paramr = {FF, alloc_sz, SHARED_HARDWARE(IfcNames_SimpleRequestPipesS2H)}; SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequestS2H, &transportShared, ¶mr); // currently no interrupts on shared memory portals, so timeout after 1ms defaultPoller->timeout = 100; for (int i = 0; i < numtimes; i++) { if (verbose) fprintf(stderr, "Main::calling say1(%d)\n", v1a); device->say1(v1a); if (verbose) fprintf(stderr, "Main::calling say2(%d, %d)\n", v2a,v2b); device->say2(v2a,v2b); if (verbose) fprintf(stderr, "Main::calling say3(S1{a:%d,b:%d})\n", s1.a,s1.b); device->say3(s1); if (verbose) fprintf(stderr, "Main::calling say4(S2{a:%d,b:%d,c:%d})\n", s2.a,s2.b,s2.c); device->say4(s2); if (verbose) fprintf(stderr, "Main::calling say5(%08x, %016llx, %08x)\n", v5a, (long long)v5b, v5c); device->say5(v5a, v5b, v5c); if (verbose) fprintf(stderr, "Main::calling say6(%08x, %016llx, %08x)\n", v6a, (long long)v6b, v6c); device->say6(v6a, v6b, v6c); if (verbose) fprintf(stderr, "Main::calling say7(%08x, %08x)\n", s3.a, s3.e1); device->say7(s3); if (wait_per_iter) fprintf(stderr, "Waiting for iter %d responses\n", i); indication->wait(); fprintf(stderr, "Received iter %d responses\n", i); } if (!wait_per_iter) indication->wait(); return 0; } ================================================ FILE: examples/strstr/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = StrstrRequest:StrstrExample.request H2S_INTERFACES = StrstrExample:StrstrIndication MEM_READ_INTERFACES = lStrstrExample.readClients BSVFILES = $(CONNECTALDIR)/lib/strstr/bsv/Strstr.bsv StrstrExample.bsv CPPFILES=teststrstr.cpp CONNECTALFLAGS += -I $(CONNECTALDIR)/lib/strstr/cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/strstr/StrstrExample.bsv ================================================ // Copyright (c) 2016 Accelerated Tech, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Strstr::*; import Vector::*; import BuildVector::*; import ConnectalMemTypes::*; interface StrstrExample; interface StrstrRequest request; interface Vector#(2, MemReadClient#(64)) readClients; endinterface module mkStrstrExample#(StrstrIndication ind)(StrstrExample); Strstr#(64,64) strstr <- mkStrstr(ind); interface request = strstr.request; interface readClients = append(strstr.config_read_client, strstr.haystack_read_client); endmodule ================================================ FILE: examples/strstr/teststrstr.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "dmaManager.h" #include "StrstrIndication.h" #include "StrstrRequest.h" #include "strstr.h" #include "mp.h" int sw_match_cnt = 0; int main(int argc, const char **argv) { StrstrRequestProxy *device = 0; StrstrIndication *deviceIndication = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); device = new StrstrRequestProxy(IfcNames_StrstrRequestS2H); deviceIndication = new StrstrIndication(IfcNames_StrstrIndicationH2S); DmaManager *dma = platformInit(); if(1){ fprintf(stderr, "simple tests\n"); int needleAlloc; int haystackAlloc; int mpNextAlloc; unsigned int alloc_len = 4096; needleAlloc = portalAlloc(alloc_len, 0); mpNextAlloc = portalAlloc(alloc_len, 0); haystackAlloc = portalAlloc(alloc_len, 0); char *needle = (char *)portalMmap(needleAlloc, alloc_len); char *haystack = (char *)portalMmap(haystackAlloc, alloc_len); struct MP *mpNext = (struct MP *)portalMmap(mpNextAlloc, alloc_len); const char *needle_text = "ababab"; const char *haystack_text = "acabcabacababacababababababcacabcabacababacabababc"; const int hmul = 1; assert(strlen(haystack_text)*hmul < alloc_len); assert(strlen(needle_text)*4 < alloc_len); strncpy(needle, needle_text, alloc_len); for (int i = 0; i < hmul; i++) strcpy(haystack+(i*strlen(haystack_text)), haystack_text); int needle_len = strlen(needle); int haystack_len = strlen(haystack); int border[needle_len+1]; compute_borders(needle, border, needle_len); compute_MP_next(needle, mpNext, needle_len); assert(mpNext[1].index == 0); assert(border[1] == 0); for (int i = 2; i < needle_len+1; i++) assert(mpNext[i].index == border[i-1]+1); for (int i = 0; i < needle_len; i++) fprintf(stderr, "needle[%d]=%x mpNext[%d]=%d\n", i, needle[i], i+1, ((int *)mpNext)[i+1]); portalTimerStart(0); MP(needle, haystack, mpNext, needle_len, haystack_len, &sw_match_cnt); fprintf(stderr, "elapsed time (hw cycles): %lld\n", (long long)portalTimerLap(0)); for (int i = 0; i < needle_len; i++) fprintf(stderr, "needle[%d]=%x mpNext[%d]=%x\n", i, needle[i], i+1, ((int *)mpNext)[i+1]); portalCacheFlush(needleAlloc, needle, alloc_len, 1); portalCacheFlush(mpNextAlloc, mpNext, alloc_len, 1); unsigned int ref_needle = dma->reference(needleAlloc); unsigned int ref_mpNext = dma->reference(mpNextAlloc); unsigned int ref_haystack = dma->reference(haystackAlloc); fprintf(stderr, "about to invoke device ref_needle=%d ref_mpNext=%d ref_haystack=%d\n", ref_needle, ref_mpNext, ref_haystack); device->setup(ref_needle, ref_mpNext, needle_len); sleep(2); portalTimerStart(0); device->search(ref_haystack, haystack_len); deviceIndication->wait(); //uint64_t cycles = portalTimerLap(0); //uint64_t beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); //fprintf(stderr, "memory read utilization (beats/cycle): %f\n", ((float)beats)/((float)cycles)); close(needleAlloc); close(haystackAlloc); close(mpNextAlloc); } if(1){ fprintf(stderr, "benchmarks\n"); int needleAlloc; int haystackAlloc; int mpNextAlloc; const char *needle_text = "I have control\n"; #ifdef SIMULATION int BENCHMARK_INPUT_SIZE = 16 << 15; #else int BENCHMARK_INPUT_SIZE = 16 << 18; #endif int haystack_alloc_len = BENCHMARK_INPUT_SIZE; int needle_alloc_len = (strlen(needle_text)+4095)&~4095l; int mpNext_alloc_len = needle_alloc_len*4; needleAlloc = portalAlloc(needle_alloc_len, 0); haystackAlloc = portalAlloc(haystack_alloc_len, 0); mpNextAlloc = portalAlloc(mpNext_alloc_len, 0); char *needle = (char *)portalMmap(needleAlloc, needle_alloc_len); char *haystack = (char *)portalMmap(haystackAlloc, haystack_alloc_len); struct MP *mpNext = (struct MP *)portalMmap(mpNextAlloc, mpNext_alloc_len); int ref_needle = dma->reference(needleAlloc); int ref_haystack = dma->reference(haystackAlloc); int ref_mpNext = dma->reference(mpNextAlloc); int fp = open("/dev/urandom", O_RDONLY); int rv = read(fp, haystack, BENCHMARK_INPUT_SIZE); if (rv != BENCHMARK_INPUT_SIZE) { printf("[%s:%d] /dev/urandom failed?\n", __FUNCTION__, __LINE__); } strncpy(needle, needle_text, needle_alloc_len); int needle_len = strlen(needle); int haystack_len = haystack_alloc_len; int border[needle_len+1]; compute_borders(needle, border, needle_len); compute_MP_next(needle, mpNext, needle_len); assert(mpNext[1].index == 0); assert(border[1] == 0); for (int i = 2; i < needle_len+1; i++) assert(mpNext[i].index == border[i-1]+1); fprintf(stderr, "about to invoke device ref_needle=%d ref_mpNext=%d ref_haystack=%d needle_len=%d needle_alloc_len=%d haystack_len=%d\n", ref_needle, ref_mpNext, ref_haystack, needle_len, needle_alloc_len, haystack_len); portalTimerStart(0); MP(needle, haystack, mpNext, needle_len, haystack_len, &sw_match_cnt); uint64_t sw_cycles = portalTimerLap(0); fprintf(stderr, "sw_cycles:%llx\n", (long long)sw_cycles); portalCacheFlush(needleAlloc, needle, needle_alloc_len, 1); portalCacheFlush(mpNextAlloc, mpNext, mpNext_alloc_len, 1); device->setup(ref_needle, ref_mpNext, needle_len); portalTimerStart(0); device->search(ref_haystack, haystack_len); deviceIndication->wait(); //uint64_t hw_cycles = portalTimerLap(0); //uint64_t beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); //float read_util = (float)beats/(float)hw_cycles; //fprintf(stderr, "hw_cycles:%llx\n", (long long)hw_cycles); //fprintf(stderr, "memory read utilization (beats/cycle): %f\n", read_util); //fprintf(stderr, "speedup: %f\n", ((float)sw_cycles)/((float)hw_cycles)); //MonkitFile("perf.monkit") //.setHwCycles(hw_cycles) //.setSwCycles(sw_cycles) //.setReadBwUtil(read_util) //.writeFile(); } int hw_match_cnt = deviceIndication->match_cnt; fprintf(stderr, "teststrstr: Done, sw_match_cnt=%d, hw_match_cnt=%d\n", sw_match_cnt, hw_match_cnt); return (sw_match_cnt != hw_match_cnt); } ================================================ FILE: examples/swmemcpy/Makefile ================================================ BASEDIR = ../../ UTILDIR = ../../cpp/ testpa: g++ -I$(BASEDIR) testpa.cpp $(UTILDIR)/portal.c $(UTILDIR)/sock_utils.c -pthread clean: rm a.out ================================================ FILE: examples/swmemcpy/SWmemcpy.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface CoreRequest; endinterface interface CoreIndication; endinterface interface SWmemcpyRequest; interface CoreRequest coreRequest; endinterface interface SWmemcpyIndication; interface CoreIndication coreIndication; endinterface module mkSWmemcpyRequest#(SWmemcpyIndication indication)(SWmemcpyRequest); interface CoreRequest coreRequest = ?; endmodule ================================================ FILE: examples/swmemcpy/testswmemcpy.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include "portal.h" #include "dmaManager.h" #include "sock_utils.h" int numWords = 16; size_t test_sz = numWords*sizeof(unsigned int); size_t alloc_sz = test_sz; class TestPM : public ConnectalMemory { public: virtual void sglist(uint32_t off, uint64_t addr, uint32_t len) {} virtual void paref(uint32_t off, uint32_t ref) {} TestPM() : ConnectalMemory(){} }; void* child(void* prd_sock) { int fd; int rd_sock = *((int*)prd_sock); sock_fd_read(rd_sock, &fd); unsigned int *dstBuffer = (unsigned int *)DmaManager_mmap(fd, alloc_sz); //fprintf(stderr, "child::mmap %08x\n", dstBuffer); unsigned int sg = 0; bool mismatch = false; for (int i = 0; i < numWords; i++){ mismatch |= (dstBuffer[i] != sg++); fprintf(stderr, "%08x, %08x\n", dstBuffer[i], sg-1); } fprintf(stderr, "child::writeDone mismatch=%d\n", mismatch); munmap(dstBuffer, alloc_sz); close(fd); return NULL; } void* parent(void* pwr_sock) { int wr_sock = *((int*)pwr_sock); int dstAlloc; unsigned int *dstBuffer = 0; unsigned int *dba = 0; class TestPM *pm = new TestPM(); fprintf(stderr, "parent::allocating memory...\n"); dstAlloc = pm->alloc(alloc_sz); dstBuffer = (unsigned int *)DmaManager_mmap(dstAlloc.header.fd, alloc_sz); fprintf(stderr, "parent::mmap %p\n", dstBuffer); for (int i = 0; i < numWords; i++){ dstBuffer[i] = i; } pm->dCacheFlushInval(dstAlloc, alloc_sz, dstBuffer); fprintf(stderr, "parent::flush and invalidate complete\n"); int rc = ioctl(pm->pa_fd, PA_DEBUG_PK, &dstAlloc); fprintf(stderr, "parent::debug ioctl complete (%d)\n",rc); dba = (unsigned int *)DmaManager_mmap(dstAlloc.header.fd, alloc_sz); fprintf(stderr, "parent::mmap %p\n", dba); unsigned int sg = 0; bool mismatch = false; for (int i = 0; i < numWords; i++){ mismatch |= (dba[i] != sg++); fprintf(stderr, "%08x, %08x\n", dba[i], dstBuffer[i]); } fprintf(stderr, "parent::writeDone mismatch=%d\n", mismatch); sock_fd_write(wr_sock, NULL, 0, dstAlloc.header.fd); munmap(dstBuffer, alloc_sz); close(dstAlloc.header.fd); return NULL; } int main(int argc, const char **argv) { int sv[2]; int pid; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) < 0) { perror("socketpair"); exit(1); } switch ((pid = fork())) { case 0: close(sv[0]); child(&sv[1]); break; case -1: perror("fork"); exit(1); default: close(sv[1]); parent(&sv[0]); break; } } ================================================ FILE: examples/vectoradd_hls/Makefile ================================================ CONNECTALDIR?=../../ S2H_INTERFACES = VaddRequest:Vadd.request H2S_INTERFACES = Vadd:VaddResponse BSVFILES = bsv/Vadd.bsv CPPFILES = testvadd.cpp CONNECTALFLAGS += -V solution1/impl/verilog include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/vectoradd_hls/README.md ================================================ # Vector Add HLS Example This is a very simple example showing how to integrate Verilog modules generated Vivado HLS into BSV. ## TL;DR: Having installed connectal, verilator and bluespec, to build and run this example: make -j22 build.verilator ; make run.verilator ## Description of the code structure The HLS source code is: void vectoradd(const int in0[64], const int in1[64], int out[64]) { #pragma HLS interface ap_hs port=in0 #pragma HLS interface ap_hs port=in1 #pragma HLS interface ap_hs port=out for (int i = 0; i < 64; i++) #pragma unroll 4 out[i] = in0[i] + in1[i]; } The Makefile does not currently run vivado_hls, but the generated verilog is in the repo. The `HLS interface ap_hs` pragma directs Vivado HLS to generate a port with valid/ack handshaking. It's similar to AXI stream, but I chose this option because it's easier to remember that `ack` is the response than `ready`. The generated Verilog module has the following interface: module vectoradd ( input ap_clk, input ap_rst, input ap_start, output ap_done, output ap_idle, output ap_ready, input [31:0] in0, input in0_ap_vld, output in0_ap_ack, input [31:0] in1, input in1_ap_vld, output in1_ap_ack, output [31:0] out_r, output out_r_ap_vld, input out_r_ap_ack); Connectal's importbvi.py script produces a basic `import "BVI"` definition for the module so we can invoke it from BSV. Matching the port declarations against the Vivado HLS conventions, importbvi.py could generate the following BSV interface for the module: interface Vaddhls; interface Put#(Bit#(32)) in0; interface Put#(Bit#(32)) in1; interface Get#(Bit#(32)) out; method Action start(); method ActionValue#(Bit#(1)) done(); endinterface I write my test benches in software, which is quite easy to do with Connectal. So even though this is about the slowest way possible to run this "accelerator", I wrapped it up in the following top level BSV module: // requests from software to hardware interface VaddRequest; method Action data(Bit#(32) in0, Bit#(32) in1); method Action start(); endinterface // responses from hardware to software interface VaddResponse; method Action data(Bit#(32) out); method Action done(); endinterface interface Vadd; interface VaddRequest request; endinterface module mkVadd#(VaddResponse response)(Vadd); Vaddhls vaddhls <- mkVaddhls(64); rule rl_response; let v <- vaddhls.out.get(); response.data(v); endrule rule rl_done; let v <- vaddhls.done(); response.done(); endrule interface VaddRequest request; method Action data(Bit#(32) in0, Bit#(32) in1); vaddhls.in0.put(in0); vaddhls.in1.put(in1); endmethod method Action start(); vaddhls.start(); endmethod endinterface endmodule And finally the test driver: #include #include #include volatile int finished = 0; class VaddResponse : public VaddResponseWrapper { private: int i; int received_done; public: virtual void data ( const uint32_t out ) { fprintf(stderr, "data[%d] = %d\n", i, out); i = i + 1; if (i >= 64 && received_done) finished = 1; } virtual void done() { fprintf(stderr, "done\n"); received_done = 1; if (i >= 64 && received_done) finished = 1; } void clear() { i = 0; received_done = 0; finished = 0; } VaddResponse(unsigned int id, PortalTransportFunctions *transport = 0, void *param = 0, PortalPoller *poller = 0) : VaddResponseWrapper(id, transport, param, poller) { i = 0; received_done = 0; } }; int main(int argc, const char **argv) { // Instantiate response handler, which will run in a second thread VaddResponse response(IfcNames_VaddResponseH2S); // Instantiate the request proxy VaddRequestProxy *request = new VaddRequestProxy(IfcNames_VaddRequestS2H); // [1] Batch processing mode // send the data to the logic for (int i = 0; i < 64; i++) { request->data(i, i*2); } // start the computation request->start(); // wait for responses while (!finished) sleep(1); // clear the response handler so we can use it again response.clear(); // [2] Pipelined processing mode // start the computation request->start(); // send the data for (int i = 0; i < 64; i++) { request->data(i, i*2); } // wait for responses while (!finished) sleep(1); return 0; } ================================================ FILE: examples/vectoradd_hls/bsv/Vadd.bsv ================================================ import GetPut::*; import FIFOF::*; import VaddBvi::*; // requests from software to hardware interface VaddRequest; method Action data(Bit#(32) in0, Bit#(32) in1); method Action start(); endinterface // responses from hardware to software interface VaddResponse; method Action data(Bit#(32) out); method Action done(); endinterface interface Vadd; interface VaddRequest request; endinterface module mkVadd#(VaddResponse response)(Vadd); Vaddhls vaddhls <- mkVaddhls(64); rule rl_response; let v <- vaddhls.out.get(); response.data(v); endrule rule rl_done; let v <- vaddhls.done(); response.done(); endrule interface VaddRequest request; method Action data(Bit#(32) in0, Bit#(32) in1); vaddhls.in0.put(in0); vaddhls.in1.put(in1); endmethod method Action start(); vaddhls.start(); endmethod endinterface endmodule ================================================ FILE: examples/vectoradd_hls/bsv/VaddBvi.bsv ================================================ /* /home/jamey/connectal/generated/scripts/importbvi.py -o VaddBvi.bsv -P VaddBvi -I VaddBvi -c ap_clk -r ap_rst verilog/vectoradd.v -n in0 -n in1 -n out -n ap */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import FIFOF::*; (* always_ready, always_enabled *) interface VaddBvi; method Bit#(1) ap_done(); method Bit#(1) ap_idle(); method Bit#(1) ap_ready(); method Action ap_start(Bit#(1) v); method Action in0(Bit#(32) v); method Bit#(1) in0_ap_ack(); method Action in0_ap_vld(Bit#(1) v); method Action in1(Bit#(32) v); method Bit#(1) in1_ap_ack(); method Action in1_ap_vld(Bit#(1) v); method Bit#(32) out_r(); method Action out_r_ap_ack(Bit#(1) v); method Bit#(1) out_r_ap_vld(); endinterface import "BVI" vectoradd = module mkVaddBvi(VaddBvi); Clock ap_clk <- exposeCurrentClock; Reset reset <- exposeCurrentReset; Reset ap_rst <- mkResetInverter(reset); default_clock ap_clk(ap_clk) = ap_clk; default_reset ap_rst(ap_rst) = ap_rst; method ap_done ap_done(); method ap_idle ap_idle(); method ap_ready ap_ready(); method ap_start(ap_start) enable((*inhigh*) EN_ap_start); method in0(in0) enable((*inhigh*) EN_in0); method in0_ap_ack in0_ap_ack(); method in0_ap_vld(in0_ap_vld) enable((*inhigh*) EN_in0_ap_vld); method in1(in1) enable((*inhigh*) EN_in1); method in1_ap_ack in1_ap_ack(); method in1_ap_vld(in1_ap_vld) enable((*inhigh*) EN_in1_ap_vld); method out_r out_r(); method out_r_ap_ack(out_r_ap_ack) enable((*inhigh*) EN_out_r_ap_ack); method out_r_ap_vld out_r_ap_vld(); schedule (ap_done, ap_idle, ap_ready, ap_start, in0, in0_ap_ack, in0_ap_vld, in1, in1_ap_ack, in1_ap_vld, out_r, out_r_ap_ack, out_r_ap_vld) CF (ap_done, ap_idle, ap_ready, ap_start, in0, in0_ap_ack, in0_ap_vld, in1, in1_ap_ack, in1_ap_vld, out_r, out_r_ap_ack, out_r_ap_vld); endmodule // This wrapper was written by hand but could be generated from the // HLS-generated Verilog by knowing its conventions for generating // module interfaces interface Vaddhls; interface Put#(Bit#(32)) in0; interface Put#(Bit#(32)) in1; interface Get#(Bit#(32)) out; method Action start(); method ActionValue#(Bit#(1)) done(); endinterface module mkVaddhls#(Integer fifoDepth)(Vaddhls); VaddBvi vadd <- mkVaddBvi(); FIFOF#(Bit#(32)) in0Fifo <- mkSizedFIFOF(fifoDepth); FIFOF#(Bit#(32)) in1Fifo <- mkSizedFIFOF(fifoDepth); FIFOF#(Bit#(32)) outFifo <- mkSizedFIFOF(fifoDepth); rule rl_in0_data; $display("in0 %d", in0Fifo.first); vadd.in0(in0Fifo.first); endrule rule rl_in0_hs; vadd.in0_ap_vld(pack(in0Fifo.notEmpty())); if (vadd.in0_ap_ack() == 1) in0Fifo.deq(); endrule rule rl_in1_data; $display("in1 %d", in1Fifo.first); vadd.in1(in1Fifo.first); endrule rule rl_in1_hs; vadd.in1_ap_vld(pack(in1Fifo.notEmpty())); if (vadd.in1_ap_ack() == 1) in1Fifo.deq(); endrule rule rl_out_data; if (vadd.out_r_ap_vld() == 1) begin outFifo.enq(vadd.out_r()); $display("out %d", vadd.out_r()); end endrule rule rl_out_hs; vadd.out_r_ap_ack(pack(vadd.out_r_ap_vld() == 1 && outFifo.notFull())); endrule interface Put in0 = toPut(in0Fifo); interface Put in1 = toPut(in1Fifo); interface Get out = toGet(outFifo); method Action start() if (vadd.ap_ready == 1); vadd.ap_start(1); endmethod method ActionValue#(Bit#(1)) done() if (vadd.ap_done == 1); return 1; endmethod endmodule ================================================ FILE: examples/vectoradd_hls/solution1/impl/verilog/vectoradd.v ================================================ // ============================================================== // RTL generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC // Version: 2017.4 // Copyright (C) 1986-2017 Xilinx, Inc. All Rights Reserved. // // =========================================================== `timescale 1 ns / 1 ps (* CORE_GENERATION_INFO="vectoradd,hls_ip_2017_4,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z020clg484-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=2.552000,HLS_SYN_LAT=65,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=10,HLS_SYN_LUT=149}" *) module vectoradd ( ap_clk, ap_rst, ap_start, ap_done, ap_idle, ap_ready, in0, in0_ap_vld, in0_ap_ack, in1, in1_ap_vld, in1_ap_ack, out_r, out_r_ap_vld, out_r_ap_ack ); parameter ap_ST_fsm_state1 = 2'd1; parameter ap_ST_fsm_state2 = 2'd2; input ap_clk; input ap_rst; input ap_start; output ap_done; output ap_idle; output ap_ready; input [31:0] in0; input in0_ap_vld; output in0_ap_ack; input [31:0] in1; input in1_ap_vld; output in1_ap_ack; output [31:0] out_r; output out_r_ap_vld; input out_r_ap_ack; reg ap_done; reg ap_idle; reg ap_ready; reg in0_ap_ack; reg in1_ap_ack; reg out_r_ap_vld; (* fsm_encoding = "none" *) reg [1:0] ap_CS_fsm; wire ap_CS_fsm_state1; reg in0_blk_n; wire ap_CS_fsm_state2; wire [0:0] exitcond_fu_64_p2; reg in1_blk_n; reg out_r_blk_n; wire [6:0] i_1_fu_70_p2; reg ap_block_state2; reg ap_sig_ioackin_out_r_ap_ack; reg ap_block_state2_io; reg [6:0] i_reg_53; reg ap_reg_ioackin_out_r_ap_ack; reg [1:0] ap_NS_fsm; reg ap_condition_100; reg ap_condition_57; // power-on initialization initial begin #0 ap_CS_fsm = 2'd1; #0 ap_reg_ioackin_out_r_ap_ack = 1'b0; end always @ (posedge ap_clk) begin if (ap_rst == 1'b1) begin ap_CS_fsm <= ap_ST_fsm_state1; end else begin ap_CS_fsm <= ap_NS_fsm; end end always @ (posedge ap_clk) begin if (ap_rst == 1'b1) begin ap_reg_ioackin_out_r_ap_ack <= 1'b0; end else begin if (((exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin if ((1'b1 == ap_condition_57)) begin ap_reg_ioackin_out_r_ap_ack <= 1'b0; end else if ((1'b1 == ap_condition_100)) begin ap_reg_ioackin_out_r_ap_ack <= 1'b1; end end end end always @ (posedge ap_clk) begin if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin i_reg_53 <= i_1_fu_70_p2; end else if (((ap_start == 1'b1) & (1'b1 == ap_CS_fsm_state1))) begin i_reg_53 <= 7'd0; end end always @ (*) begin if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd1) & (1'b1 == ap_CS_fsm_state2))) begin ap_done = 1'b1; end else begin ap_done = 1'b0; end end always @ (*) begin if (((ap_start == 1'b0) & (1'b1 == ap_CS_fsm_state1))) begin ap_idle = 1'b1; end else begin ap_idle = 1'b0; end end always @ (*) begin if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd1) & (1'b1 == ap_CS_fsm_state2))) begin ap_ready = 1'b1; end else begin ap_ready = 1'b0; end end always @ (*) begin if ((ap_reg_ioackin_out_r_ap_ack == 1'b0)) begin ap_sig_ioackin_out_r_ap_ack = out_r_ap_ack; end else begin ap_sig_ioackin_out_r_ap_ack = 1'b1; end end always @ (*) begin if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin in0_ap_ack = 1'b1; end else begin in0_ap_ack = 1'b0; end end always @ (*) begin if (((exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin in0_blk_n = in0_ap_vld; end else begin in0_blk_n = 1'b1; end end always @ (*) begin if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin in1_ap_ack = 1'b1; end else begin in1_ap_ack = 1'b0; end end always @ (*) begin if (((exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin in1_blk_n = in1_ap_vld; end else begin in1_blk_n = 1'b1; end end always @ (*) begin if ((~(((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd0) & (ap_reg_ioackin_out_r_ap_ack == 1'b0) & (1'b1 == ap_CS_fsm_state2))) begin out_r_ap_vld = 1'b1; end else begin out_r_ap_vld = 1'b0; end end always @ (*) begin if (((exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin out_r_blk_n = out_r_ap_ack; end else begin out_r_blk_n = 1'b1; end end always @ (*) begin case (ap_CS_fsm) ap_ST_fsm_state1 : begin if (((ap_start == 1'b1) & (1'b1 == ap_CS_fsm_state1))) begin ap_NS_fsm = ap_ST_fsm_state2; end else begin ap_NS_fsm = ap_ST_fsm_state1; end end ap_ST_fsm_state2 : begin if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd1) & (1'b1 == ap_CS_fsm_state2))) begin ap_NS_fsm = ap_ST_fsm_state1; end else if ((~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (exitcond_fu_64_p2 == 1'd0) & (1'b1 == ap_CS_fsm_state2))) begin ap_NS_fsm = ap_ST_fsm_state2; end else begin ap_NS_fsm = ap_ST_fsm_state2; end end default : begin ap_NS_fsm = 'bx; end endcase end assign ap_CS_fsm_state1 = ap_CS_fsm[32'd0]; assign ap_CS_fsm_state2 = ap_CS_fsm[32'd1]; always @ (*) begin ap_block_state2 = (((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))); end always @ (*) begin ap_block_state2_io = ((exitcond_fu_64_p2 == 1'd0) & (ap_sig_ioackin_out_r_ap_ack == 1'b0)); end always @ (*) begin ap_condition_100 = (~(((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))) & (out_r_ap_ack == 1'b1)); end always @ (*) begin ap_condition_57 = ~((1'b1 == ap_block_state2_io) | ((exitcond_fu_64_p2 == 1'd0) & (in1_ap_vld == 1'b0)) | ((exitcond_fu_64_p2 == 1'd0) & (in0_ap_vld == 1'b0))); end assign exitcond_fu_64_p2 = ((i_reg_53 == 7'd64) ? 1'b1 : 1'b0); assign i_1_fu_70_p2 = (i_reg_53 + 7'd1); assign out_r = (in0 + in1); endmodule //vectoradd ================================================ FILE: examples/vectoradd_hls/src/vectoradd.cpp ================================================ void vectoradd(const int in0[64], const int in1[64], int out[64]) { #pragma HLS interface ap_hs port=in0 #pragma HLS interface ap_hs port=in1 #pragma HLS interface ap_hs port=out for (int i = 0; i < 64; i++) #pragma unroll 4 out[i] = in0[i] + in1[i]; } ================================================ FILE: examples/vectoradd_hls/testvadd.cpp ================================================ #include #include #include volatile int finished = 0; class VaddResponse : public VaddResponseWrapper { private: int i; int received_done; public: virtual void data ( const uint32_t out ) { fprintf(stderr, "data[%d] = %d\n", i, out); i = i + 1; if (i >= 64 && received_done) finished = 1; } virtual void done() { fprintf(stderr, "done\n"); received_done = 1; if (i >= 64 && received_done) finished = 1; } void clear() { i = 0; received_done = 0; finished = 0; } VaddResponse(unsigned int id, PortalTransportFunctions *transport = 0, void *param = 0, PortalPoller *poller = 0) : VaddResponseWrapper(id, transport, param, poller) { i = 0; received_done = 0; } }; int main(int argc, const char **argv) { // Instantiate response handler, which will run in a second thread VaddResponse response(IfcNames_VaddResponseH2S); // Instantiate the request proxy VaddRequestProxy *request = new VaddRequestProxy(IfcNames_VaddRequestS2H); // [1] Batch processing mode // send the data to the logic for (int i = 0; i < 64; i++) { request->data(i, i*2); } // start the computation request->start(); // wait for responses while (!finished) sleep(1); // clear the response handler so we can use it again response.clear(); // [2] Pipelined processing mode // start the computation request->start(); // send the data for (int i = 0; i < 64; i++) { request->data(i, i*2); } // wait for responses while (!finished) sleep(1); return 0; } ================================================ FILE: examples/zedboard_robot/Controller.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import MaxSonarController::*; import GyroController::*; import HBridgeController::*; import ConnectalSpi::*; import ConnectalMemTypes::*; import Leds::*; interface ZedboardRobotPins; interface MaxSonarPins maxsonar; interface SpiMasterPins#(1) spi; interface HBridge2Pins hbridge; interface LEDS leds; endinterface interface Controller; interface MaxSonarCtrlRequest maxsonar_req; interface GyroCtrlRequest gyro_req; interface HBridgeCtrlRequest hbridge_req; interface ZedboardRobotPins pins; interface MemWriteClient#(64) dmaClient; endinterface module mkController#(MaxSonarCtrlIndication maxsonar_ind, GyroCtrlIndication gyro_ind, HBridgeCtrlIndication hbridge_ind)(Controller); MaxSonarController msc <- mkMaxSonarController(maxsonar_ind); GyroController gc <- mkGyroController(gyro_ind); HBridgeController hbc <- mkHBridgeController(hbridge_ind); interface HBridgeCtrlRequest hbridge_req = hbc.req; interface MaxSonarCtrlRequest maxsonar_req = msc.req; interface GyroCtrlRequest gyro_req = gc.req; interface ZedboardRobotPins pins; interface maxsonar = msc.pins.maxsonar; interface spi = gc.pins.spi; interface hbridge = hbc.pins.hbridge; interface leds = hbc.pins.leds; endinterface interface dmaClient = gc.dmaClient; endmodule ================================================ FILE: examples/zedboard_robot/Makefile ================================================ CONNECTALDIR ?= ../.. S2H_INTERFACES += MaxSonarCtrlRequest:Controller.maxsonar_req S2H_INTERFACES += HBridgeCtrlRequest:Controller.hbridge_req S2H_INTERFACES += GyroCtrlRequest:Controller.gyro_req H2S_INTERFACES = Controller:MaxSonarCtrlIndication,GyroCtrlIndication,HBridgeCtrlIndication MEM_WRITE_INTERFACES = cons\(lController.dmaClient,nil\) INTERFACES += GyroSampleStream MaxSonarSampleStream ZBR = $(CONNECTALDIR)/lib/zedboard_robot BSVFILES = Controller.bsv $(ZBR)/bsv/GyroController.bsv $(ZBR)/bsv/MaxSonarController.bsv $(ZBR)/bsv/HBridgeController.bsv CPPFILES= test_zedboard_robot.cpp ../maxsonar_simple/maxsonar_simple.h ../hbridge_simple/hbridge_simple.h ../gyro_simple/gyro_simple.h $(ZBR)/cpp/read_buffer.cpp PIN_TYPE = ZedboardRobotPins PIN_TYPE_INCLUDE = Controller PINOUT_FILE = pinout.json PIN_BINDINGS ?= pmod_sonar:pmodb pmod_gyro:pmodd pmod_hbridge:pmodc AUTOTOP = --interface pins:Controller.pins --portname IfcNames_GyroSampleStream --portname IfcNames_MaxSonarSampleStream include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/zedboard_robot/pinout.json ================================================ { "maxsonar_range_ctrl" : { "PIO_DIRECTION": "OUTPUT", "pmod_sonar" : "J2" }, "maxsonar_pulse_v" : { "PIO_DIRECTION": "INPUT", "pmod_sonar" : "J4" }, "spi_mosi": { "PIO_DIRECTION": "OUTPUT", "pmod_gyro": "J2" }, "spi_miso_v": { "PIO_DIRECTION": "INPUT", "pmod_gyro": "J3" }, "spi_sel_n": { "PIO_DIRECTION": "OUTPUT", "pmod_gyro": "J1" }, "CLK_spi_clock": { "PIO_DIRECTION": "OUTPUT", "pmod_gyro": "J4" }, "hbridge_hbridge0_direction" : { "PIO_DIRECTION": "OUTPUT", "pmod_hbridge" : "J1" }, "hbridge_hbridge0_enabled" : { "PIO_DIRECTION": "OUTPUT", "pmod_hbridge" : "J2" }, "hbridge_hbridge1_direction" : { "PIO_DIRECTION": "OUTPUT", "pmod_hbridge" : "J7" }, "hbridge_hbridge1_enabled" : { "PIO_DIRECTION": "OUTPUT", "pmod_hbridge" : "J8" }, "leds_leds[0]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L0" }, "leds_leds[1]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L1" }, "leds_leds[2]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L2" }, "leds_leds[3]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L3" }, "leds_leds[4]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L4" }, "leds_leds[5]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L5" }, "leds_leds[6]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L6" }, "leds_leds[7]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L7" } } ================================================ FILE: examples/zedboard_robot/sonarVisualize.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from visual import * import math class sv: def __init__(self): self.main_window=display(title="test_maxsonar", forward=(0,0,-1), width=500, up=(0,1,0), range=(1.2,1.2,1.2)) self.main_window.select() self.cnt = 0 def label_last(self): label(pos=self.last,text="%d"%(self.cnt),box=0,opacity=0) self.cnt = self.cnt+1 def add_line(self,start,end): curve(pos=[start,end]) self.last = end self.label_last() def extend_line(self,end): curve(pos=[self.last,end]) self.last = end self.label_last() def add_ray(self,heading,length): end_point_x = length*math.cos(heading) end_point_y = length*math.sin(heading) curve(pos=[(0,0), (end_point_x/100,end_point_y/50)]) if __name__ == "__main__": v = sv() v.add_line((0,0,0),(1,1,0)) v.extend_line((1,0,0)) v.extend_line((0,0,0)) v.add_ray(0.1,1); v.add_ray(0.1,1); v.add_ray(0.1,1); v.add_ray(0.1,1); v.add_ray(0.1,1); v.add_ray(0.1,1); ================================================ FILE: examples/zedboard_robot/test_zedboard_robot.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include "maxsonar_simple.h" #include "gyro_simple.h" #include "hbridge_simple.h" #include "sock_utils.h" #include "MaxSonarSampleStream.h" #include "GyroSampleStream.h" #include "HBridgeCtrlRequest.h" #include "MaxSonarCtrlRequest.h" #include "GyroCtrlRequest.h" #include "dmaManager.h" #include "read_buffer.h" static int spew = 1; static int host_sw = 1; static int alloc_sz = 1<<10; void* drive_hbridges(void *_x) { HBridgeCtrlRequestProxy *device = (HBridgeCtrlRequestProxy*)_x; sleep(20); // for(int i = 0; i < 2; i++){ // MOVE_FOREWARD(POWER_5); // sleep(1); // STOP; // MOVE_BACKWARD(POWER_5); // sleep(1); // STOP; // TURN_RIGHT(POWER_5); // sleep(1); // STOP; // TURN_LEFT(POWER_5); // sleep(1); // STOP; // sleep(1); // } for(int i = 0; i < 30; i++){ TURN_RIGHT(POWER_4); usleep(100000); STOP; sleep(1); } STOP; return NULL; } int send_aux(GyroSampleStreamProxy *gssp, void*b, int len, int drop, int spew, int send, MaxSonarSampleStreamProxy *msssp, int usecs) { int16_t *ss = (int16_t*)b; int i = 3+drop; while(i < len/2){ if (send) { gssp->sample(ss[(i-3)+0], ss[(i-3)+1], ss[(i-3)+2]); // this is a bit wasteful, but it simplifies test_zedboard_robot.py msssp->sample(usecs); } if (spew) fprintf(stderr, "%8d %8d %8d\n", ss[(i-3)+0], ss[(i-3)+1], ss[(i-3)+2]); i+=3; } int missing = i-(len/2); return missing; } int main(int argc, const char **argv) { // portals communicating between "main" running on the ARM and the logic running in the FPGA HBridgeCtrlIndication hbridge_ind(IfcNames_HBridgeCtrlIndicationH2S); HBridgeCtrlRequestProxy *hbridge_ctrl = new HBridgeCtrlRequestProxy(IfcNames_HBridgeCtrlRequestS2H); MaxSonarCtrlIndication *maxsonar_ind = new MaxSonarCtrlIndication(IfcNames_MaxSonarCtrlIndicationH2S); MaxSonarCtrlRequestProxy *maxsonar_ctrl = new MaxSonarCtrlRequestProxy(IfcNames_MaxSonarCtrlRequestS2H); GyroCtrlIndication *gyro_ind = new GyroCtrlIndication(IfcNames_GyroCtrlIndicationH2S); GyroCtrlRequestProxy *gyro_ctrl = new GyroCtrlRequestProxy(IfcNames_GyroCtrlRequestS2H); DmaManager *dma = platformInit(); // portals communicating between "main" running on the ARM and SW running on a server somewhere on the network (HOST_SW) PortalSocketParam param0; getaddrinfo("0.0.0.0", "5000", NULL, ¶m0.addr); GyroSampleStreamProxy *gssp = new GyroSampleStreamProxy(IfcNames_GyroSampleStream, &transportSocketResp, ¶m0, &GyroSampleStreamJsonProxyReq, 1000); PortalSocketParam param1; getaddrinfo("0.0.0.0", "5001", NULL, ¶m1.addr); MaxSonarSampleStreamProxy *msssp = new MaxSonarSampleStreamProxy(IfcNames_MaxSonarSampleStream, &transportSocketResp, ¶m1, &MaxSonarSampleStreamJsonProxyReq, 1000); // allocate memory for the gyro controller to write samples to int dstAlloc = portalAlloc(alloc_sz, 0); char *dstBuffer = (char *)portalMmap(dstAlloc, alloc_sz); unsigned int ref_dstAlloc = dma->reference(dstAlloc); // set design clock frequency (this is important since our PW modulators depend on this number) long req_freq = 100000000; // 100 mHz long freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); char* snapshot = (char*)malloc(alloc_sz); reader* r = new reader(); //r->verbose = 1; // setup gyro registers and dma infra (setup_registers defined gyro_simple.h) setup_registers(gyro_ind,gyro_ctrl, ref_dstAlloc, alloc_sz); maxsonar_ctrl->range_ctrl(1); int drop = 0; // start up the thread to drive the hbridges pthread_t threaddata; pthread_create(&threaddata, NULL, &drive_hbridges, (void*)hbridge_ctrl); while(true){ #ifdef SIMULATION sleep(5); #else usleep(50000*2); #endif // first read the "current" sonar distance maxsonar_ctrl->pulse_width(); sem_wait(&(maxsonar_ind->pulse_width_sem)); float distance = ((float)maxsonar_ind->useconds)/147.0; // now get the latest window of gyro samples. begin by disabling gyro writes to the memory buffer set_en(gyro_ind,gyro_ctrl, 0); // read the memory from the circular buffer into "snapshot" int datalen = r->read_circ_buff(alloc_sz, ref_dstAlloc, dstAlloc, dstBuffer, snapshot, gyro_ind->write_addr, gyro_ind->write_wrap_cnt); // re-enable the gyro memwrite set_en(gyro_ind,gyro_ctrl, 2); if (spew) fprintf(stderr, "(%d microseconds == %f inches)\n", maxsonar_ind->useconds, distance); // 'datalen' corresponds to the amount of "new" samples the gyro controller has written to memory. drop = send_aux(gssp, snapshot, datalen, drop, spew, host_sw, msssp, maxsonar_ind->useconds); } } ================================================ FILE: examples/zedboard_robot/test_zedboard_robot.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import struct import sys import os sys.path.append(os.path.abspath('../gyro_simple')) from sonarVisualize import * from gyroVisualize import * from test_gyro import * sys.path.append(os.path.abspath('../../scripts')) import portalJson import json smoothe = False if __name__ == "__main__": argparser = argparse.ArgumentParser('Display gyroscope data') argparser.add_argument('-vg', '--visualize_gyro', help='Display gyro orientation in 3D rendering', default=False, action='store_true') argparser.add_argument('-vs', '--visualize_sonar', help='Display maxsonar output in X/Y plane', default=False, action='store_true') argparser.add_argument('-a', '--address', help='Device address', default=None) options = argparser.parse_args() spew_gyro = not options.visualize_gyro; spew_sonar = not options.visualize_sonar; visualize_gyro = options.visualize_gyro; visualize_sonar = options.visualize_sonar; print(options.address) if not options.address: options.address = os.environ['RUNPARAM'] if (visualize_gyro): g_v = gv() if (visualize_sonar): s_v = sv() gs = gyro_stream(smoothe) gjp = portalJson.portal(options.address, 5000) msjp = portalJson.portal(options.address, 5001) summ = [0,0,0] try: while (True): samples = [] for i in range(0,48): d = json.loads(gjp.recv()) samples.append(d['x']) samples.append(d['y']) samples.append(d['z']) d = json.loads(msjp.recv()) sonar_distance = d['v'] poss = gs.next_samples(samples) sonar_distance = sonar_distance/147.0 if (spew_sonar): print("sonar_distance: %f" % (sonar_distance)) if poss is not None: for pos in poss: if (spew_gyro): print("%f %f %f" % (pos[0],pos[1],pos[2])) summ[0] = summ[0]+pos[0] summ[1] = summ[1]+pos[1] summ[2] = summ[2]+pos[2] if (visualize_gyro and smoothe): g_v.update(pos, gs.sample_freq_hz) if (visualize_gyro and (not smoothe)): g_v.update(summ, gs.sample_freq_hz) if (visualize_sonar): s_v.add_ray(summ[2],sonar_distance) except KeyboardInterrupt: sc.s.close() sys.exit() ================================================ FILE: examples/zynqpcie/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = Simple ZynqPcieTestIndication ZynqPcieTestRequest BSVFILES = SimpleIF.bsv ZynqPcieTestIF.bsv Top.bsv CPPFILES=testzynqpcie.cpp PIN_TYPE=ZynqPcie PIN_TYPE_INCLUDE = ZynqPcieTestIF CONNECTALFLAGS += -D PcieHostIF=1 -D PCIE_NO_BSCAN=1 --bscflags="+RTS -K96000000 -RTS" CONNECTALFLAGS += --xci=$(CONNECTALDIR)/out/$(BOARD)/pcie_7x_0/pcie_7x_0.xci -C $(BOARD)/sources/zynqpcie.xdc CONNECTALFLAGS += -P mkPcieHostTopSynth -P mkMemToPcie ## this design would work on a Virtex board with a second PCIE port PIN_BINDINGS ?= -b pcie:pcie gentarget:: $(BOARD)/sources/zynqpcie.xdc prebuild:: synth-ip.tcl (cd $(BOARD); vivado -mode batch -source ../synth-ip.tcl) $(BOARD)/sources/zynqpcie.xdc: zynqpcie.json $(CONNECTALDIR)/boardinfo/$(BOARD).json mkdir -p $(BOARD)/sources $(CONNECTALDIR)/scripts/generate-constraints.py $(PIN_BINDINGS) -o $(BOARD)/sources/zynqpcie.xdc --boardfile $(CONNECTALDIR)/boardinfo/$(BOARD).json --pinoutfile zynqpcie.json include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: examples/zynqpcie/SimpleIF.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; typedef struct{ Bit#(32) a; Bit#(32) b; } S1 deriving (Bits); typedef struct{ Bit#(32) a; Bit#(16) b; Bit#(7) c; } S2 deriving (Bits); typedef enum { E1Choice1, E1Choice2, E1Choice3 } E1 deriving (Bits,Eq); typedef struct{ Bit#(32) a; E1 e1; } S3 deriving (Bits); interface Simple; method Action say1(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action say3(S1 v); method Action say4(S2 v); method Action say5(Bit#(32)a, Bit#(64) b, Bit#(32) c); method Action say6(Bit#(32)a, Bit#(40) b, Bit#(32) c); method Action say7(S3 v); method Action say8(Vector#(128, Bit#(32)) v); endinterface typedef struct { Bit#(32) a; Bit#(40) b; Bit#(32) c; } Say6ReqSimple deriving (Bits); module mkSimple#(Simple indication)(Simple); let verbose = False; method Action say1(Bit#(32) v); if (verbose) $display("mkSimple::say1"); indication.say1(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); if (verbose) $display("mkSimple::say2"); indication.say2(a,b); endmethod method Action say3(S1 v); if (verbose) $display("mkSimple::say3"); indication.say3(v); endmethod method Action say4(S2 v); if (verbose) $display("mkSimple::say4"); indication.say4(v); endmethod method Action say5(Bit#(32) a, Bit#(64) b, Bit#(32) c); if (verbose) $display("mkSimple::say5"); indication.say5(a, b, c); endmethod method Action say6(Bit#(32) a, Bit#(40) b, Bit#(32) c); if (verbose) $display("mkSimple::say6"); indication.say6(a, b, c); endmethod method Action say7(S3 v); if (verbose) $display("mkSimple::say7"); indication.say7(v); endmethod method Action say8(Vector#(128, Bit#(32)) v); if (verbose) $display("mkSimple::say8"); indication.say8(v); endmethod endmodule ================================================ FILE: examples/zynqpcie/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ `include "ConnectalProjectConfig.bsv" import Clocks::*; import Vector::*; import FIFO::*; import Connectable::*; import GetPutWithClocks::*; import CtrlMux::*; import Portal::*; import ConnectalConfig::*; import ConnectalMemTypes::*; import PcieHost ::*; `ifndef SIMULATION import PCIEWRAPPER ::*; import PcieEndpointX7 ::*; import ConnectalXilinxCells ::*; `endif import Simple::*; import ZynqPcieTestRequest::*; import ZynqPcieTestIndication::*; import ZynqPcieTestIF::*; import SimpleIF::*; typedef enum {IfcNames_SimpleRequest, IfcNames_SimpleIndication, IfcNames_ZynqPcieTestRequest, IfcNames_ZynqPcieTestIndication} IfcNames deriving (Eq,Bits); interface ZynqPcie; (* prefix="PCIE" *) interface PciewrapPci_exp#(PcieLanes) pcie; method Action pcie_sys_clk(Bit#(1) p, Bit#(1) n); method Action sys_clk(Bit#(1) p, Bit#(1) n); method Action pcie_sys_reset(Bit#(1) n); interface Clock deleteme_unused_clockFoo; interface Clock deleteme_unused_clockPortal; interface Clock deleteme_unused_clock100mhz; endinterface // // This module is just to put a synthesis boundary around // mkPcieHostTop, which does not currently have one. The Makefile // uses this line to synthesize this module into its own // netlist. We're not going to change it, so on subsequent rebuilds, // buildcache will use the previous synthesis result. // // CONNECTALFLAGS += -P mkPcieHostTopSynth // (* synthesize *) module mkPcieHostTopSynth#(Clock pcie_sys_clk_p, Clock pcie_sys_clk_n, Clock sys_clk_p, Clock sys_clk_n, Reset pcie_sys_reset_n)(PcieHostTop); (*hide*) let host <- mkPcieHostTop(pcie_sys_clk_p, pcie_sys_clk_n, sys_clk_p, sys_clk_n, pcie_sys_reset_n); return host; endmodule // // This design exposes a PCIe interface via its "pins" // module mkConnectalTop(ConnectalTop); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); // Clock laundering facility: // // Bluespec does have a way for exposed interfaces to be a source // for clocks so we use B2C (bit to clock) to convert bits to // clocks. B2C1 b2c_pcie_sys_clk_p <- mkB2C1(); B2C1 b2c_pcie_sys_clk_n <- mkB2C1(); B2C b2c_pcie_sys_reset_n <- mkB2C(); B2C1 b2c_sys_clk_p <- mkB2C1(); B2C1 b2c_sys_clk_n <- mkB2C1(); // // Instantiate a PcieHostTop, so that we can connect it to a set of portals. // PcieHostTop host <- mkPcieHostTopSynth(b2c_pcie_sys_clk_p.c, b2c_pcie_sys_clk_n.c, b2c_sys_clk_p.c, b2c_sys_clk_n.c, b2c_pcie_sys_reset_n.r); // The PCIe portals and Zynq portals are in different clock domains, so synchronize bits that are provided to mkZynqPcieTest SyncBitIfc#(Bit#(1)) resetBit <- mkSyncBit(b2c_pcie_sys_reset_n.c, b2c_pcie_sys_reset_n.r, defaultClock); SyncBitIfc#(Bit#(1)) resetSeenBit <- mkSyncBit(b2c_pcie_sys_reset_n.c, b2c_pcie_sys_reset_n.r, defaultClock); SyncBitIfc#(Bit#(1)) linkUpBit <- mkSyncBit(host.portalClock, host.portalReset, defaultClock); // This register is in the PCIe portal clock domain Reg#(Bit#(1)) resetSeenReg <- mkReg(0, clocked_by b2c_pcie_sys_reset_n.c, reset_by b2c_pcie_sys_reset_n.r); // instantiate zynq-side user portals ZynqPcieTestIndicationProxy zynqPcieTestIndicationProxy <- mkZynqPcieTestIndicationProxy(IfcNames_ZynqPcieTestIndication); ZynqPcieTest zynqPcieTest <- mkZynqPcieTest(linkUpBit, resetBit, resetSeenBit, zynqPcieTestIndicationProxy.ifc); ZynqPcieTestRequestWrapper zynqPcieTestRequestWrapper <- mkZynqPcieTestRequestWrapper(IfcNames_ZynqPcieTestRequest,zynqPcieTest.request); // Connect the exposed BRAM client to the trace BRAM server in the PcieHost mkConnectionWithClocks2(zynqPcieTest.traceBramClient, host.tpciehost.traceBramServer); // send the value of the lnk_up signal from the PCIE endpoint to the Zynq portal clock domain rule updateLinkBit; linkUpBit.send(host.tep7.user.lnk_up()); endrule // Construct the vector of zynq portals Vector#(2,StdPortal) zynqPortals; zynqPortals[0] = zynqPcieTestIndicationProxy.portalIfc; zynqPortals[1] = zynqPcieTestRequestWrapper.portalIfc; let ctrl_mux <- mkSlaveMux(zynqPortals); // LED values // led0: toggles once a second as a board heartbeat // led1: Indicates PCIE link is up // led2: Indicates current value of the PCIE reset signal from the host // led3: Indicates that a 0-to-1 transition was detected on the PCIE reset signal from the host Reg#(Bit#(4)) ledsValue <- mkReg(5); Reg#(Bit#(32)) remainingDuration <- mkReg(100000000); rule updateLeds; let duration = remainingDuration; let bits = ledsValue; bits[3] = resetSeenBit.read(); bits[2] = resetBit.read(); bits[1] = linkUpBit.read(); if (duration == 0) begin bits[0] = ~bits[0]; duration = 100000000; end else begin duration = duration - 1; end ledsValue <= bits; remainingDuration <= duration; endrule // // Instantiate Simple portals as the test case connected to the x86 host via PCIe // SimpleProxy simpleIndicationProxy <- mkSimpleProxy(IfcNames_SimpleIndication, clocked_by host.portalClock, reset_by host.portalReset); Simple simpleRequest <- mkSimple(simpleIndicationProxy.ifc, clocked_by host.portalClock, reset_by host.portalReset); SimpleWrapper simpleRequestWrapper <- mkSimpleWrapper(IfcNames_SimpleRequest,simpleRequest, clocked_by host.portalClock, reset_by host.portalReset); Vector#(2,StdPortal) pcieportals; pcieportals[0] = simpleIndicationProxy.portalIfc; pcieportals[1] = simpleRequestWrapper.portalIfc; PhysMemSlave#(32,32) pcie_ctrl_mux <- mkSlaveMux(pcieportals, clocked_by host.portalClock, reset_by host.portalReset); // manually connect the PCIe host PhysMemMaster to the pcie_ctrl_mux PhysMemSlave mkConnection(host.tpciehost.master, pcie_ctrl_mux, clocked_by host.portalClock, reset_by host.portalReset); // Construct the ZynqPcie interface ZynqPcie zpcie = (interface ZynqPcie; method Action pcie_sys_clk(Bit#(1) p, Bit#(1) n); // This is a bit of sleight of hand. We depend // on the way the bluespec compiler generates // verilog for the following method invocation // to connect the input clock signals via the // B2C to the 100Mhz pcie system clock input // of the PcieHost. b2c_pcie_sys_clk_p.inputclock(p); b2c_pcie_sys_clk_n.inputclock(n); endmethod method Action sys_clk(Bit#(1) p, Bit#(1) n); // same for the 200MHz system clock b2c_sys_clk_p.inputclock(p); b2c_sys_clk_n.inputclock(n); endmethod method Action pcie_sys_reset(Bit#(1) n); if (n == 1) resetSeenReg <= 1; resetSeenBit.send(resetSeenReg); resetBit.send(n); // same for the reset b2c_pcie_sys_reset_n.inputreset(n); endmethod interface pcie = host.tep7.pcie; // The Bluespec compiler requires that the clocks // used by exported methods/pins also be // exposed. Because of the b2c, some of the clock // pins were not visible to the compiler, so we // export them here. // // We do not have FPGA pins to which we want to // connect them, so we rename them // "deleteme_unused_clock..." so that the // synthesis script will disconnect them from the // ports of the toplevel netlist. interface Clock deleteme_unused_clockFoo = b2c_pcie_sys_reset_n.c; interface Clock deleteme_unused_clockPortal = host.portalClock; interface Clock deleteme_unused_clock100mhz = host.tpci_clk_100mhz_buf; endinterface); // connect the standard LEDS interface //LEDS ledsIF = (interface LEDS; method Bit#(LedsWidth) leds(); return truncate(ledsValue); endmethod endinterface); // export the interfaces from the Zynq portals interface interrupt = getInterruptVector(zynqPortals); interface slave = ctrl_mux; interface masters = nil; //interface leds = ledsIF; // expose the pcie interface as pins interface pins = zpcie; endmodule : mkConnectalTop ================================================ FILE: examples/zynqpcie/ZynqPcieTestIF.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import Vector::*; import Clocks::*; import BRAM::*; import PCIE::*; import PcieTracer::*; interface ZynqPcieTestRequest; method Action getStatus(Bit#(32) v); method Action getTrace(Bit#(32) offset); endinterface interface ZynqPcieTestIndication; method Action status(Bit#(32) v); method Action trace(Vector#(6, Bit#(32)) offset); endinterface interface ZynqPcieTest; interface ZynqPcieTestRequest request; interface BRAMClient#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData) traceBramClient; endinterface module mkZynqPcieTest#(SyncBitIfc#(Bit#(1)) lnk_up, SyncBitIfc#(Bit#(1)) resetBit, SyncBitIfc#(Bit#(1)) resetSeenBit, ZynqPcieTestIndication indication)(ZynqPcieTest); FIFO#(BRAMRequest#(Bit#(TAdd#(TlpTraceAddrSize,1)), TimestampedTlpData)) requestFifo <- mkFIFO(); FIFO#(TimestampedTlpData) responseFifo <- mkFIFO(); rule respond; let v <- toGet(responseFifo).get(); indication.trace(unpack(pack(v))); endrule interface ZynqPcieTestRequest request; method Action getStatus(Bit#(32) v); indication.status(extend({lnk_up.read(), resetBit.read(), resetSeenBit.read()})); endmethod method Action getTrace(Bit#(32) v); requestFifo.enq(BRAMRequest { write: False, responseOnWrite: False, address: truncate(v), datain: unpack(0) }); endmethod endinterface interface BRAMClient traceBramClient; interface Get request = fifoToGet(requestFifo); interface Put response = fifoToPut(responseFifo); endinterface endmodule ================================================ FILE: examples/zynqpcie/synth-ip.tcl ================================================ source board.tcl source $connectaldir/scripts/connectal-synth-pcie.tcl set needspcie 1 if $needspcie { set pcieversion {3.0} set maxlinkwidth {X8} if {$boardname == {zc706}} { set maxlinkwidth {X4} } if {$boardname == {ac701}} { set maxlinkwidth {X4} } if {[version -short] == "2013.2"} { set pcieversion {2.1} } connectal_synth_ip pcie_7x $pcieversion pcie_7x_0 [list CONFIG.mode_selection {Advanced} CONFIG.ASPM_Optionality {true} CONFIG.Disable_Tx_ASPM_L0s {true} CONFIG.Buf_Opt_BMA {true} CONFIG.Bar0_64bit {true} CONFIG.Bar0_Size {16} CONFIG.Bar0_Scale {Kilobytes} CONFIG.Bar2_64bit {true} CONFIG.Bar2_Enabled {true} CONFIG.Bar2_Scale {Megabytes} CONFIG.Bar2_Size {1} CONFIG.Base_Class_Menu {Memory_controller} CONFIG.Device_ID {c100} CONFIG.IntX_Generation {false} CONFIG.MSI_Enabled {false} CONFIG.MSIx_Enabled {true} CONFIG.MSIx_PBA_Offset {1f0} CONFIG.MSIx_Table_Offset {200} CONFIG.MSIx_Table_Size {10} CONFIG.Maximum_Link_Width $maxlinkwidth CONFIG.Subsystem_ID {a705} CONFIG.Subsystem_Vendor_ID {1be7} CONFIG.Use_Class_Code_Lookup_Assistant {false} CONFIG.Vendor_ID {1be7} CONFIG.Trgt_Link_Speed {4'h2} CONFIG.Link_Speed {5.0_GT/s}] } ================================================ FILE: examples/zynqpcie/testsimple.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "Simple.h" #include "GeneratedTypes.h" int v1a = 42; int v2a = 2; int v2b = 4; S2 s2 = {7, 8, 9}; S1 s1 = {3, 6}; uint32_t v5a = 0x00000000; uint64_t v5b = 0xDEADBEEFFECAFECA; uint32_t v5c = 0x00000001; uint32_t v6a = 0xBBBBBBBB; uint64_t v6b = 0x000000EFFECAFECA; uint32_t v6c = 0xCCCCCCCC; uint32_t v7a = 0xDADADADA; E1 v7b = E1_E1Choice2; S3 s3 = { a: v7a, e1: v7b }; class Simple : public SimpleWrapper { public: uint32_t cnt; void incr_cnt(){ if (++cnt == 7) exit(0); } virtual void say1(uint32_t a) { fprintf(stderr, "say1(%d)\n", a); assert(a == v1a); incr_cnt(); } virtual void say2(uint32_t a, uint32_t b) { fprintf(stderr, "say2(%d %d)\n", a, b); assert(a == v2a); assert(b == v2b); incr_cnt(); } virtual void say3(S1 s){ fprintf(stderr, "say3(S1{a:%d,b:%d})\n", s.a, s.b); assert(s.a == s1.a); assert(s.b == s1.b); incr_cnt(); } virtual void say4(S2 s){ fprintf(stderr, "say4(S2{a:%d,b:%d,c:%d})\n", s.a,s.b,s.c); assert(s.a == s2.a); assert(s.b == s2.b); assert(s.c == s2.c); incr_cnt(); } virtual void say5(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say5(%08x, %016llx, %08x)\n", a, (long long)b, c); assert(a == v5a); assert(b == v5b); assert(c == v5c); incr_cnt(); } virtual void say6(uint32_t a, uint64_t b, uint32_t c) { fprintf(stderr, "say6(%08x, %016llx, %08x)\n", a, (long long)b, c); assert(a == v6a); assert(b == v6b); assert(c == v6c); incr_cnt(); } virtual void say7(S3 v) { fprintf(stderr, "say7(%08x, %08x)\n", v.a, v.e1); assert(v.a == v7a); assert(v.e1 == v7b); incr_cnt(); } virtual void say8 ( const bsvvector_Luint32_t_L128 v ) { fprintf(stderr, "say8\n"); for (int i = 0; i < 128; i++) fprintf(stderr, " [%d] = 0x%x\n", i, v[i]); incr_cnt(); } Simple(unsigned int id) : SimpleWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { Simple *indication = new Simple(IfcNames_SimpleIndication); SimpleProxy *device = new SimpleProxy(IfcNames_SimpleRequest); device->pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ fprintf(stderr, "Main::calling say1(%d)\n", v1a); device->say1(v1a); fprintf(stderr, "Main::calling say2(%d, %d)\n", v2a,v2b); device->say2(v2a,v2b); fprintf(stderr, "Main::calling say3(S1{a:%d,b:%d})\n", s1.a,s1.b); device->say3(s1); fprintf(stderr, "Main::calling say4(S2{a:%d,b:%d,c:%d})\n", s2.a,s2.b,s2.c); device->say4(s2); fprintf(stderr, "Main::calling say5(%08x, %016llx, %08x)\n", v5a, (long long)v5b, v5c); device->say5(v5a, v5b, v5c); fprintf(stderr, "Main::calling say6(%08x, %016llx, %08x)\n", v6a, (long long)v6b, v6c); device->say6(v6a, v6b, v6c); fprintf(stderr, "Main::calling say7(%08x, %08x)\n", s3.a, s3.e1); device->say7(s3); bsvvector_Luint32_t_L128 vect; for (int i = 0; i < 128; i++) vect[i] = -i*32; fprintf(stderr, "Main::calling say8\n"); device->say8(vect); fprintf(stderr, "Main::about to go to sleep\n"); while(true){sleep(2);} } ================================================ FILE: examples/zynqpcie/testzynqpcie.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include "ZynqPcieTestIndication.h" #include "ZynqPcieTestRequest.h" #include "GeneratedTypes.h" class ZynqPcieTestIndication : public ZynqPcieTestIndicationWrapper { public: ZynqPcieTestIndication(int id, PortalPoller *poller = 0) : ZynqPcieTestIndicationWrapper(id, poller) { }; ZynqPcieTestIndication(int id, PortalTransportFunctions *item, void *param, PortalPoller *poller = 0) : ZynqPcieTestIndicationWrapper(id, item, param, poller) { }; virtual void status ( const uint32_t v ) { fprintf(stderr, "ZynqPcieTestIndicationWrapper.status v=%x\n", v); } virtual void trace ( const uint32_t *v ) { fprintf(stderr, "ZynqPcieTestIndicationWrapper.trace %08x %08x %08x %08x %08x %08x\n", v[0], v[1], v[2], v[3], v[4], v[5]); } }; int main(int argc, const char **argv) { ZynqPcieTestIndication *indication = new ZynqPcieTestIndication(IfcNames_ZynqPcieTestIndication); ZynqPcieTestRequestProxy *device = new ZynqPcieTestRequestProxy(IfcNames_ZynqPcieTestRequest); device->pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ for (int i = 0; i < 2; i++) { device->getStatus(0); sleep(2); } for (int i = 0; i < 100; i++) { device->getTrace(i); sleep(1); } } ================================================ FILE: examples/zynqpcie/zynqpcie.json ================================================ { "*PCIE_txp[0]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx0_p" }, "*PCIE_txn[0]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx0_n" }, "*PCIE_txp[1]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx1_p" }, "*PCIE_txn[1]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx1_n" }, "*PCIE_txp[1]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx1_p" }, "*PCIE_txn[2]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx2_n" }, "*PCIE_txp[3]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx3_p" }, "*PCIE_txn[3]": { "PIO_DIRECTION": "OUTPUT", "pcie": "PCIE_tx3_n" }, "*PCIE_rxp[0]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx0_n" }, "*PCIE_rxn[0]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx0_n" }, "*PCIE_rxp[1]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx1_n" }, "*PCIE_rxn[1]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx1_n" }, "*PCIE_rxp[2]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx2_n" }, "*PCIE_rxn[2]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx2_n" }, "*PCIE_rxp[3]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx3_n" }, "*PCIE_rxn[3]": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_rx3_n" }, "pcie_sys_clk_p": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_clk_q0_p" }, "pcie_sys_clk_n": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_clk_q0_n" }, "pcie_sys_reset_n": { "PIO_DIRECTION": "INPUT", "pcie": "PCIE_perst" } } ================================================ FILE: generated/altera/ALTERA_DDR3_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_DDR3_WRAPPER.bsv -I AvalonDdr3 -P AvalonDdr3 -c pll_ref_clk -r global_reset_n -r soft_reset_n -c afi_clk -c afi_half_clk -r afi_reset_n -r afi_reset_export_n -f mem -f avl -f status -f oct -f pll /home/hwang/dev/connectal/out/de5/synthesis/altera_mem_if_ddr3_emif_wrapper/altera_mem_if_ddr3_emif_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import Vector::*; (* always_ready, always_enabled *) interface Avalonddr3Afi; interface Clock clk; interface Clock half_clk; method Reset reset_export_n(); method Reset reset_n(); endinterface (* always_ready, always_enabled *) interface Avalonddr3Avl; method Action addr(Bit#(25) v); method Action be(Bit#(64) v); method Action burstbegin(Bit#(1) v); method Bit#(512) rdata(); method Bit#(1) rdata_valid(); method Action read_req(Bit#(1) v); method Bit#(1) wait_request(); method Action size(Bit#(3) v); method Action wdata(Bit#(512) v); method Action write_req(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Avalonddr3status; method Bit#(1) cal_fail(); method Bit#(1) cal_success(); method Bit#(1) init_done(); endinterface (* always_ready, always_enabled *) interface Avalonddr3Mem; method Bit#(15) a(); method Bit#(3) ba(); method Bit#(1) cas_n(); method Vector#(1, Bit#(1)) ck(); method Bit#(1) ck_n(); method Bit#(1) cke(); method Bit#(1) cs_n(); method Bit#(8) dm(); interface Inout#(Bit#(64)) dq; interface Inout#(Bit#(8)) dqs; interface Inout#(Bit#(8)) dqs_n; method Bit#(1) odt(); method Bit#(1) ras_n(); method Bit#(1) reset_n(); method Bit#(1) we_n(); endinterface (* always_ready, always_enabled *) interface Avalonddr3Oct; (* prefix="" *) method Action rzqin( (* port="rzq_4" *) Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Avalonddr3Pll; method Bit#(1) addr_cmd_clk(); method Bit#(1) avl_clk(); method Bit#(1) c2p_write_clk(); method Bit#(1) config_clk(); method Bit#(1) hr_clk(); method Bit#(1) locked(); method Bit#(1) mem_clk(); method Bit#(1) p2c_read_clk(); method Bit#(1) write_clk(); method Bit#(1) write_clk_pre_phy_clk(); endinterface (* always_ready, always_enabled *) interface AvalonDdr3; interface Avalonddr3Afi afi; interface Avalonddr3Avl avl; interface Avalonddr3status status; interface Avalonddr3Mem mem; interface Avalonddr3Oct oct; interface Avalonddr3Pll pll; endinterface import "BVI" altera_mem_if_ddr3_emif_wrapper = module mkAvalonDdr3#(Clock pll_ref_clk, Reset global_reset_n, Reset soft_reset_n)(AvalonDdr3); default_clock clk(); default_reset rst(); input_reset global_reset_n(global_reset_n) = global_reset_n; input_clock pll_ref_clk(pll_ref_clk) = pll_ref_clk; input_reset soft_reset_n(soft_reset_n) = soft_reset_n; interface Avalonddr3Afi afi; output_clock clk(afi_clk); output_clock half_clk(afi_half_clk); output_reset reset_export_n(afi_reset_export_n); output_reset reset_n(afi_reset_n); endinterface interface Avalonddr3Avl avl; method addr(avl_addr) enable((*inhigh*) EN_avl_addr); method be(avl_be) enable((*inhigh*) EN_avl_be); method burstbegin(avl_burstbegin) enable((*inhigh*) EN_avl_burstbegin); method avl_rdata rdata(); method avl_rdata_valid rdata_valid(); method read_req(avl_read_req) enable((*inhigh*) EN_avl_read_req); method avl_ready wait_request(); method size(avl_size) enable((*inhigh*) EN_avl_size); method wdata(avl_wdata) enable((*inhigh*) EN_avl_wdata); method write_req(avl_write_req) enable((*inhigh*) EN_avl_write_req); endinterface interface Avalonddr3status status; method status_cal_fail cal_fail(); method status_cal_success cal_success(); method status_init_done init_done(); endinterface interface Avalonddr3Mem mem; method mem_a a(); method mem_ba ba(); method mem_cas_n cas_n(); method mem_ck ck(); method mem_ck_n ck_n(); method mem_cke cke(); method mem_cs_n cs_n(); method mem_dm dm(); ifc_inout dq(mem_dq); ifc_inout dqs(mem_dqs); ifc_inout dqs_n(mem_dqs_n); method mem_odt odt(); method mem_ras_n ras_n(); method mem_reset_n reset_n(); method mem_we_n we_n(); endinterface interface Avalonddr3Oct oct; method rzqin(oct_rzqin) enable((*inhigh*) EN_oct_rzqin); endinterface interface Avalonddr3Pll pll; method pll_addr_cmd_clk addr_cmd_clk() clocked_by (pll_ref_clk); method pll_avl_clk avl_clk() clocked_by (pll_ref_clk); method pll_c2p_write_clk c2p_write_clk() clocked_by (pll_ref_clk); method pll_config_clk config_clk() clocked_by (pll_ref_clk); method pll_hr_clk hr_clk() clocked_by (pll_ref_clk); method pll_locked locked() clocked_by (pll_ref_clk); method pll_mem_clk mem_clk() clocked_by (pll_ref_clk); method pll_p2c_read_clk p2c_read_clk() clocked_by (pll_ref_clk); method pll_write_clk write_clk() clocked_by (pll_ref_clk); method pll_write_clk_pre_phy_clk write_clk_pre_phy_clk() clocked_by (pll_ref_clk); endinterface schedule (avl.addr, avl.be, avl.burstbegin, avl.rdata, avl.rdata_valid, avl.read_req, avl.wait_request, avl.size, avl.wdata, avl.write_req, status.cal_fail, status.cal_success, status.init_done, mem.a, mem.ba, mem.cas_n, mem.ck, mem.ck_n, mem.cke, mem.cs_n, mem.dm, mem.odt, mem.ras_n, mem.reset_n, mem.we_n, oct.rzqin, pll.addr_cmd_clk, pll.avl_clk, pll.c2p_write_clk, pll.config_clk, pll.hr_clk, pll.locked, pll.mem_clk, pll.p2c_read_clk, pll.write_clk, pll.write_clk_pre_phy_clk) CF (avl.addr, avl.be, avl.burstbegin, avl.rdata, avl.rdata_valid, avl.read_req, avl.wait_request, avl.size, avl.wdata, avl.write_req, status.cal_fail, status.cal_success, status.init_done, mem.a, mem.ba, mem.cas_n, mem.ck, mem.ck_n, mem.cke, mem.cs_n, mem.dm, mem.odt, mem.ras_n, mem.reset_n, mem.we_n, oct.rzqin, pll.addr_cmd_clk, pll.avl_clk, pll.c2p_write_clk, pll.config_clk, pll.hr_clk, pll.locked, pll.mem_clk, pll.p2c_read_clk, pll.write_clk, pll.write_clk_pre_phy_clk); endmodule ================================================ FILE: generated/altera/ALTERA_ETH_PMA_RECONFIG_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_ETH_PMA_RECONFIG_WRAPPER.bsv -I EthXcvrReconfigWrap -P EthXcvrReconfigWrap -c mgmt_clk_clk -r mgmt_rst_reset -f reconfig ../../out/de5/synthesis/altera_xgbe_pma_reconfig_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface EthxcvrreconfigwrapReconfig; method Bit#(1) busy(); method Action from_xcvr(Bit#(368) v); method Action mgmt_address(Bit#(7) v); method Action mgmt_read(Bit#(1) v); method Bit#(32) mgmt_readdata(); method Bit#(1) mgmt_waitrequest(); method Action mgmt_write(Bit#(1) v); method Action mgmt_writedata(Bit#(32) v); method Bit#(560) to_xcvr(); endinterface (* always_ready, always_enabled *) interface EthXcvrReconfigWrap; interface EthxcvrreconfigwrapReconfig reconfig; endinterface import "BVI" altera_xgbe_pma_reconfig_wrapper = module mkEthXcvrReconfigWrap#(Clock mgmt_clk_clk, Reset mgmt_clk_clk_reset, Reset mgmt_rst_reset)(EthXcvrReconfigWrap); default_clock clk(); default_reset rst(); input_clock mgmt_clk_clk(mgmt_clk_clk) = mgmt_clk_clk; input_reset mgmt_clk_clk_reset() = mgmt_clk_clk_reset; /* from clock*/ input_reset mgmt_rst_reset(mgmt_rst_reset) = mgmt_rst_reset; interface EthxcvrreconfigwrapReconfig reconfig; method reconfig_busy busy(); method from_xcvr(reconfig_from_xcvr) enable((*inhigh*) EN_reconfig_from_xcvr); method mgmt_address(reconfig_mgmt_address) enable((*inhigh*) EN_reconfig_mgmt_address); method mgmt_read(reconfig_mgmt_read) enable((*inhigh*) EN_reconfig_mgmt_read); method reconfig_mgmt_readdata mgmt_readdata(); method reconfig_mgmt_waitrequest mgmt_waitrequest(); method mgmt_write(reconfig_mgmt_write) enable((*inhigh*) EN_reconfig_mgmt_write); method mgmt_writedata(reconfig_mgmt_writedata) enable((*inhigh*) EN_reconfig_mgmt_writedata); method reconfig_to_xcvr to_xcvr(); endinterface schedule (reconfig.busy, reconfig.from_xcvr, reconfig.mgmt_address, reconfig.mgmt_read, reconfig.mgmt_readdata, reconfig.mgmt_waitrequest, reconfig.mgmt_write, reconfig.mgmt_writedata, reconfig.to_xcvr) CF (reconfig.busy, reconfig.from_xcvr, reconfig.mgmt_address, reconfig.mgmt_read, reconfig.mgmt_readdata, reconfig.mgmt_waitrequest, reconfig.mgmt_write, reconfig.mgmt_writedata, reconfig.to_xcvr); endmodule ================================================ FILE: generated/altera/ALTERA_ETH_PMA_RESET_CONTROL_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_ETH_PMA_RESET_CONTROL_WRAPPER.bsv -I EthXcvrResetWrap -P EthXcvrResetWrap -c clock -r reset -f pll -f rx_r -f tx_r -f tx -f rx ../../out/de5/synthesis/altera_xcvr_reset_control_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface EthxcvrresetwrapPll; method Action locked(Bit#(4) v); method Bit#(4) powerdown(); method Action select(Bit#(2) v); endinterface (* always_ready, always_enabled *) interface EthxcvrresetwrapRx; method Bit#(4) analogreset(); method Action cal_busy(Bit#(4) v); method Bit#(4) digitalreset(); method Action is_lockedtodata(Bit#(4) v); endinterface (* always_ready, always_enabled *) interface EthxcvrresetwrapRx_r; method Bit#(4) eady(); endinterface (* always_ready, always_enabled *) interface EthxcvrresetwrapTx; method Bit#(4) analogreset(); method Action cal_busy(Bit#(4) v); method Bit#(4) digitalreset(); endinterface (* always_ready, always_enabled *) interface EthxcvrresetwrapTx_r; method Bit#(4) eady(); endinterface (* always_ready, always_enabled *) interface EthXcvrResetWrap; interface EthxcvrresetwrapPll pll; interface EthxcvrresetwrapRx rx; interface EthxcvrresetwrapRx_r rx_r; interface EthxcvrresetwrapTx tx; interface EthxcvrresetwrapTx_r tx_r; endinterface import "BVI" altera_xcvr_reset_control_wrapper = module mkEthXcvrResetWrap#(Clock clock, Reset clock_reset, Reset reset)(EthXcvrResetWrap); default_clock clk(); default_reset rst(); input_clock clock(clock) = clock; input_reset clock_reset() = clock_reset; /* from clock*/ input_reset reset(reset) = reset; interface EthxcvrresetwrapPll pll; method locked(pll_locked) enable((*inhigh*) EN_pll_locked); method pll_powerdown powerdown(); method select(pll_select) enable((*inhigh*) EN_pll_select); endinterface interface EthxcvrresetwrapRx rx; method rx_analogreset analogreset(); method cal_busy(rx_cal_busy) enable((*inhigh*) EN_rx_cal_busy); method rx_digitalreset digitalreset(); method is_lockedtodata(rx_is_lockedtodata) enable((*inhigh*) EN_rx_is_lockedtodata); endinterface interface EthxcvrresetwrapRx_r rx_r; method rx_ready eady(); endinterface interface EthxcvrresetwrapTx tx; method tx_analogreset analogreset(); method cal_busy(tx_cal_busy) enable((*inhigh*) EN_tx_cal_busy); method tx_digitalreset digitalreset(); endinterface interface EthxcvrresetwrapTx_r tx_r; method tx_ready eady(); endinterface schedule (pll.locked, pll.powerdown, pll.select, rx.analogreset, rx.cal_busy, rx.digitalreset, rx.is_lockedtodata, rx_r.eady, tx.analogreset, tx.cal_busy, tx.digitalreset, tx_r.eady) CF (pll.locked, pll.powerdown, pll.select, rx.analogreset, rx.cal_busy, rx.digitalreset, rx.is_lockedtodata, rx_r.eady, tx.analogreset, tx.cal_busy, tx.digitalreset, tx_r.eady); endmodule ================================================ FILE: generated/altera/ALTERA_ETH_PMA_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_ETH_PMA_WRAPPER.bsv -I EthXcvrWrap -P EthXcvrWrap -f pll -f tx -f rx -f reconfig ../../out/de5/synthesis/altera_xcvr_native_sv_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface EthxcvrwrapPll; method Bit#(4) locked(); method Action powerdown(Bit#(4) v); endinterface (* always_ready, always_enabled *) interface EthxcvrwrapReconfig; method Bit#(368) from_xcvr(); method Action to_xcvr(Bit#(560) v); endinterface (* always_ready, always_enabled *) interface EthxcvrwrapRx; method Action analogreset(Bit#(4) v); method Bit#(4) cal_busy(); method Action cdr_refclk(Bit#(1) v); method Action digitalreset(Bit#(4) v); method Bit#(4) is_lockedtodata(); method Bit#(4) is_lockedtoref(); method Bit#(4) pma_clkout(); method Bit#(160) pma_parallel_data(); method Action serial_data(Bit#(4) v); method Action seriallpbken(Bit#(4) v); endinterface (* always_ready, always_enabled *) interface EthxcvrwrapTx; method Action analogreset(Bit#(4) v); method Bit#(4) cal_busy(); method Action digitalreset(Bit#(4) v); method Action pll_refclk(Bit#(1) v); method Bit#(4) pma_clkout(); method Action pma_parallel_data(Bit#(160) v); method Bit#(4) serial_data(); endinterface (* always_ready, always_enabled *) interface EthxcvrwrapUnused; method Bit#(160) rx_pma_parallel_data(); method Action tx_pma_parallel_data(Bit#(160) v); endinterface (* always_ready, always_enabled *) interface EthXcvrWrap; interface EthxcvrwrapPll pll; interface EthxcvrwrapReconfig reconfig; interface EthxcvrwrapRx rx; interface EthxcvrwrapTx tx; interface EthxcvrwrapUnused unused; endinterface import "BVI" altera_xcvr_native_sv_wrapper = module mkEthXcvrWrap(EthXcvrWrap); default_clock clk(); default_reset rst(); interface EthxcvrwrapPll pll; method pll_locked locked(); method powerdown(pll_powerdown) enable((*inhigh*) EN_pll_powerdown); endinterface interface EthxcvrwrapReconfig reconfig; method reconfig_from_xcvr from_xcvr(); method to_xcvr(reconfig_to_xcvr) enable((*inhigh*) EN_reconfig_to_xcvr); endinterface interface EthxcvrwrapRx rx; method analogreset(rx_analogreset) enable((*inhigh*) EN_rx_analogreset); method rx_cal_busy cal_busy(); method cdr_refclk(rx_cdr_refclk) enable((*inhigh*) EN_rx_cdr_refclk); method digitalreset(rx_digitalreset) enable((*inhigh*) EN_rx_digitalreset); method rx_is_lockedtodata is_lockedtodata(); method rx_is_lockedtoref is_lockedtoref(); method rx_pma_clkout pma_clkout(); method rx_pma_parallel_data pma_parallel_data(); method serial_data(rx_serial_data) enable((*inhigh*) EN_rx_serial_data); method seriallpbken(rx_seriallpbken) enable((*inhigh*) EN_rx_seriallpbken); endinterface interface EthxcvrwrapTx tx; method analogreset(tx_analogreset) enable((*inhigh*) EN_tx_analogreset); method tx_cal_busy cal_busy(); method digitalreset(tx_digitalreset) enable((*inhigh*) EN_tx_digitalreset); method pll_refclk(tx_pll_refclk) enable((*inhigh*) EN_tx_pll_refclk); method tx_pma_clkout pma_clkout(); method pma_parallel_data(tx_pma_parallel_data) enable((*inhigh*) EN_tx_pma_parallel_data); method tx_serial_data serial_data(); endinterface interface EthxcvrwrapUnused unused; method unused_rx_pma_parallel_data rx_pma_parallel_data(); method tx_pma_parallel_data(unused_tx_pma_parallel_data) enable((*inhigh*) EN_unused_tx_pma_parallel_data); endinterface schedule (pll.locked, pll.powerdown, reconfig.from_xcvr, reconfig.to_xcvr, rx.analogreset, rx.cal_busy, rx.cdr_refclk, rx.digitalreset, rx.is_lockedtodata, rx.is_lockedtoref, rx.pma_clkout, rx.pma_parallel_data, rx.serial_data, rx.seriallpbken, tx.analogreset, tx.cal_busy, tx.digitalreset, tx.pll_refclk, tx.pma_clkout, tx.pma_parallel_data, tx.serial_data, unused.rx_pma_parallel_data, unused.tx_pma_parallel_data) CF (pll.locked, pll.powerdown, reconfig.from_xcvr, reconfig.to_xcvr, rx.analogreset, rx.cal_busy, rx.cdr_refclk, rx.digitalreset, rx.is_lockedtodata, rx.is_lockedtoref, rx.pma_clkout, rx.pma_parallel_data, rx.serial_data, rx.seriallpbken, tx.analogreset, tx.cal_busy, tx.digitalreset, tx.pll_refclk, tx.pma_clkout, tx.pma_parallel_data, tx.serial_data, unused.rx_pma_parallel_data, unused.tx_pma_parallel_data); endmodule ================================================ FILE: generated/altera/ALTERA_PCIE_ED_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_PCIE_ED_WRAPPER.bsv -I PcieEdWrap -P PcieEdWrap -c coreclkout_hip -c pld_clk_hip -f serdes -f reset -f pld -f dl -f ev128 -f ev1 -f hotrst -f l2 -f current -f derr -f lane -f ltssm -f reconfig -f int_s -f aer -f pex -f serr -f cpl -f tl -f pm_e -f pme -f pm -f tx_s -f rx_s -f tx_cred -f tx_par -f rx_par -f cfg_par ../../out/de5/synthesis/altera_pcie_hip_ast_ed.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface PcieedwrapApp; method Action int_ack(Bit#(1) v); method Bit#(1) int_sts(); method Action msi_ack(Bit#(1) v); method Bit#(5) msi_num(); method Bit#(1) msi_req(); method Bit#(3) msi_tc(); endinterface (* always_ready, always_enabled *) interface PcieedwrapCfg_par; method Action err(Bit#(1) v); method Bit#(1) err_drv(); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface PcieedwrapCpl; method Bit#(7) err(); method Bit#(1) pending(); endinterface (* always_ready, always_enabled *) interface PcieedwrapDerr; method Action cor_ext_rcv(Bit#(1) v); method Bit#(1) cor_ext_rcv_drv(); method Action cor_ext_rpl(Bit#(1) v); method Bit#(1) cor_ext_rpl_drv(); method Action rpl(Bit#(1) v); method Bit#(1) rpl_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapDl; method Action up(Bit#(1) v); method Bit#(1) up_drv(); method Action up_exit(Bit#(1) v); method Bit#(1) up_exit_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapEv1; method Action us(Bit#(1) v); method Bit#(1) us_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapEv128; method Action ns(Bit#(1) v); method Bit#(1) ns_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapHotrst; method Action exit(Bit#(1) v); method Bit#(1) exit_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapHpg; method Bit#(5) ctrler(); endinterface (* always_ready, always_enabled *) interface PcieedwrapInt_s; method Action tatus(Bit#(4) v); method Bit#(4) tatus_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapKo; method Action cpl_spc_data(Bit#(12) v); method Bit#(12) cpl_spc_data_drv(); method Action cpl_spc_header(Bit#(8) v); method Bit#(8) cpl_spc_header_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapL2; method Action exit(Bit#(1) v); method Bit#(1) exit_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapLane; method Action act(Bit#(4) v); method Bit#(4) act_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapLmi; method Action ack(Bit#(1) v); method Bit#(12) addr(); method Bit#(32) din(); method Action dout(Bit#(32) v); method Bit#(1) rden(); method Bit#(1) wren(); endinterface (* always_ready, always_enabled *) interface PcieedwrapLtssm; method Action state(Bit#(5) v); method Bit#(5) state_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapPld; interface Clock clk_hip; method Action clk_inuse(Bit#(1) v); method Bit#(1) core_ready(); endinterface (* always_ready, always_enabled *) interface PcieedwrapPm; method Bit#(1) auxpwr(); method Bit#(10) data(); endinterface (* always_ready, always_enabled *) interface PcieedwrapPm_e; method Bit#(1) vent(); endinterface (* always_ready, always_enabled *) interface PcieedwrapPme; method Bit#(1) to_cr(); method Action to_sr(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapReset; method Action status(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapRx_par; method Action err(Bit#(1) v); method Bit#(1) err_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapRx_s; method Action t_bar(Bit#(8) v); method Action t_be(Bit#(16) v); method Action t_data(Bit#(128) v); method Action t_empty(Bit#(2) v); method Action t_eop(Bit#(1) v); method Action t_err(Bit#(1) v); method Bit#(1) t_mask(); method Bit#(1) t_ready(); method Action t_sop(Bit#(1) v); method Action t_valid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapSerdes; method Action pll_locked(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapTestin; method Action zero(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapTl; method Action cfg_add(Bit#(4) v); method Action cfg_ctl(Bit#(32) v); method Action cfg_sts(Bit#(53) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapTx_cred; method Action datafccp(Bit#(12) v); method Action datafcnp(Bit#(12) v); method Action datafcp(Bit#(12) v); method Action fchipcons(Bit#(6) v); method Action fcinfinite(Bit#(6) v); method Action hdrfccp(Bit#(8) v); method Action hdrfcnp(Bit#(8) v); method Action hdrfcp(Bit#(8) v); endinterface (* always_ready, always_enabled *) interface PcieedwrapTx_par; method Action err(Bit#(2) v); method Bit#(2) err_drv(); endinterface (* always_ready, always_enabled *) interface PcieedwrapTx_s; method Bit#(128) t_data(); method Bit#(2) t_empty(); method Bit#(1) t_eop(); method Bit#(1) t_err(); method Action t_ready(Bit#(1) v); method Bit#(1) t_sop(); method Bit#(1) t_valid(); endinterface (* always_ready, always_enabled *) interface PcieEdWrap; interface PcieedwrapApp app; interface PcieedwrapCfg_par cfg_par; interface PcieedwrapCpl cpl; interface PcieedwrapDerr derr; interface PcieedwrapDl dl; interface PcieedwrapEv128 ev128; interface PcieedwrapEv1 ev1; interface PcieedwrapHotrst hotrst; interface PcieedwrapHpg hpg; interface PcieedwrapInt_s int_s; interface PcieedwrapKo ko; interface PcieedwrapL2 l2; interface PcieedwrapLane lane; interface PcieedwrapLmi lmi; interface PcieedwrapLtssm ltssm; interface PcieedwrapPld pld; interface PcieedwrapPm pm; interface PcieedwrapPm_e pm_e; interface PcieedwrapPme pme; interface PcieedwrapReset reset; interface PcieedwrapRx_par rx_par; interface PcieedwrapRx_s rx_s; interface PcieedwrapSerdes serdes; interface PcieedwrapTestin testin; interface PcieedwrapTl tl; interface PcieedwrapTx_cred tx_cred; interface PcieedwrapTx_par tx_par; interface PcieedwrapTx_s tx_s; endinterface import "BVI" altera_pcie_hip_ast_ed = module mkPcieEdWrap#(Clock coreclkout_hip, Reset coreclkout_hip_reset)(PcieEdWrap); default_clock clk(); default_reset rst(); input_clock coreclkout_hip(coreclkout_hip) = coreclkout_hip; input_reset coreclkout_hip_reset() = coreclkout_hip_reset; /* from clock*/ interface PcieedwrapApp app; method int_ack(app_int_ack) clocked_by(coreclkout_hip) enable((*inhigh*) EN_app_int_ack); method app_int_sts int_sts() clocked_by(coreclkout_hip); method msi_ack(app_msi_ack) clocked_by(coreclkout_hip) enable((*inhigh*) EN_app_msi_ack); method app_msi_num msi_num() clocked_by(coreclkout_hip); method app_msi_req msi_req() clocked_by(coreclkout_hip); method app_msi_tc msi_tc() clocked_by(coreclkout_hip); endinterface interface PcieedwrapCfg_par cfg_par; method err(cfg_par_err)clocked_by(coreclkout_hip) enable((*inhigh*) EN_cfg_par_err); method cfg_par_err_drv err_drv(); endinterface interface PcieedwrapCpl cpl; method cpl_err err()clocked_by(coreclkout_hip); method cpl_pending pending()clocked_by(coreclkout_hip); endinterface interface PcieedwrapDerr derr; method cor_ext_rcv(derr_cor_ext_rcv) clocked_by(coreclkout_hip)enable((*inhigh*) EN_derr_cor_ext_rcv); method derr_cor_ext_rcv_drv cor_ext_rcv_drv(); method cor_ext_rpl(derr_cor_ext_rpl) clocked_by(coreclkout_hip)enable((*inhigh*) EN_derr_cor_ext_rpl); method derr_cor_ext_rpl_drv cor_ext_rpl_drv(); method rpl(derr_rpl)clocked_by(coreclkout_hip) enable((*inhigh*) EN_derr_rpl); method derr_rpl_drv rpl_drv(); endinterface interface PcieedwrapDl dl; method up(dlup) clocked_by(coreclkout_hip)enable((*inhigh*) EN_dlup); method dlup_drv up_drv(); method up_exit(dlup_exit)clocked_by(coreclkout_hip) enable((*inhigh*) EN_dlup_exit); method dlup_exit_drv up_exit_drv(); endinterface interface PcieedwrapEv128 ev128; method ns(ev128ns) clocked_by(coreclkout_hip)enable((*inhigh*) EN_ev128ns); method ev128ns_drv ns_drv(); endinterface interface PcieedwrapEv1 ev1; method us(ev1us) clocked_by(coreclkout_hip)enable((*inhigh*) EN_ev1us); method ev1us_drv us_drv(); endinterface interface PcieedwrapHotrst hotrst; method exit(hotrst_exit) clocked_by(coreclkout_hip)enable((*inhigh*) EN_hotrst_exit); method hotrst_exit_drv exit_drv(); endinterface interface PcieedwrapHpg hpg; method hpg_ctrler ctrler() clocked_by(coreclkout_hip); endinterface interface PcieedwrapInt_s int_s; method tatus(int_status) clocked_by(coreclkout_hip) enable((*inhigh*) EN_int_status); method int_status_drv tatus_drv(); endinterface interface PcieedwrapKo ko; method cpl_spc_data(ko_cpl_spc_data) clocked_by(coreclkout_hip) enable((*inhigh*) EN_ko_cpl_spc_data); method ko_cpl_spc_data_drv cpl_spc_data_drv(); method cpl_spc_header(ko_cpl_spc_header) clocked_by(coreclkout_hip) enable((*inhigh*) EN_ko_cpl_spc_header); method ko_cpl_spc_header_drv cpl_spc_header_drv(); endinterface interface PcieedwrapL2 l2; method exit(l2_exit) clocked_by(coreclkout_hip) enable((*inhigh*) EN_l2_exit); method l2_exit_drv exit_drv(); endinterface interface PcieedwrapLane lane; method act(lane_act) clocked_by(coreclkout_hip) enable((*inhigh*) EN_lane_act); method lane_act_drv act_drv(); endinterface interface PcieedwrapLmi lmi; method ack(lmi_ack) clocked_by(coreclkout_hip) enable((*inhigh*) EN_lmi_ack); method lmi_addr addr() clocked_by(coreclkout_hip); method lmi_din din() clocked_by(coreclkout_hip); method dout(lmi_dout) clocked_by(coreclkout_hip) enable((*inhigh*) EN_lmi_dout); method lmi_rden rden() clocked_by(coreclkout_hip); method lmi_wren wren() clocked_by(coreclkout_hip); endinterface interface PcieedwrapLtssm ltssm; method state(ltssmstate) clocked_by(coreclkout_hip) enable((*inhigh*) EN_ltssmstate); method ltssmstate_drv state_drv(); endinterface interface PcieedwrapPld pld; output_clock clk_hip(pld_clk_hip); method clk_inuse(pld_clk_inuse) clocked_by(coreclkout_hip) enable((*inhigh*) EN_pld_clk_inuse); method pld_core_ready core_ready() clocked_by(coreclkout_hip); endinterface interface PcieedwrapPm pm; method pm_auxpwr auxpwr() clocked_by(coreclkout_hip); method pm_data data() clocked_by(coreclkout_hip); endinterface interface PcieedwrapPm_e pm_e; method pm_event vent() clocked_by(coreclkout_hip); endinterface interface PcieedwrapPme pme; method pme_to_cr to_cr(); method to_sr(pme_to_sr) clocked_by(coreclkout_hip) enable((*inhigh*) EN_pme_to_sr); endinterface interface PcieedwrapReset reset; method status(reset_status) clocked_by(coreclkout_hip) enable((*inhigh*) EN_reset_status); endinterface interface PcieedwrapRx_par rx_par; method err(rx_par_err) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_par_err); method rx_par_err_drv err_drv(); endinterface interface PcieedwrapRx_s rx_s; method t_bar(rx_st_bar) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_bar); method t_be(rx_st_be) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_be); method t_data(rx_st_data) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_data); method t_empty(rx_st_empty) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_empty); method t_eop(rx_st_eop) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_eop); method t_err(rx_st_err) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_err); method rx_st_mask t_mask()clocked_by(coreclkout_hip) ; method rx_st_ready t_ready()clocked_by(coreclkout_hip) ; method t_sop(rx_st_sop) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_sop); method t_valid(rx_st_valid) clocked_by(coreclkout_hip) enable((*inhigh*) EN_rx_st_valid); endinterface interface PcieedwrapSerdes serdes; method pll_locked(serdes_pll_locked) clocked_by(coreclkout_hip) enable((*inhigh*) EN_serdes_pll_locked); endinterface interface PcieedwrapTestin testin; method zero(testin_zero) clocked_by(coreclkout_hip) enable((*inhigh*) EN_testin_zero); endinterface interface PcieedwrapTl tl; method cfg_add(tl_cfg_add) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tl_cfg_add); method cfg_ctl(tl_cfg_ctl) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tl_cfg_ctl); method cfg_sts(tl_cfg_sts) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tl_cfg_sts); endinterface interface PcieedwrapTx_cred tx_cred; method datafccp(tx_cred_datafccp) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_datafccp); method datafcnp(tx_cred_datafcnp) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_datafcnp); method datafcp(tx_cred_datafcp) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_datafcp); method fchipcons(tx_cred_fchipcons) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_fchipcons); method fcinfinite(tx_cred_fcinfinite) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_fcinfinite); method hdrfccp(tx_cred_hdrfccp) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_hdrfccp); method hdrfcnp(tx_cred_hdrfcnp) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_hdrfcnp); method hdrfcp(tx_cred_hdrfcp) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_cred_hdrfcp); endinterface interface PcieedwrapTx_par tx_par; method err(tx_par_err) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_par_err); method tx_par_err_drv err_drv(); endinterface interface PcieedwrapTx_s tx_s; method tx_st_data t_data() clocked_by(coreclkout_hip); method tx_st_empty t_empty() clocked_by(coreclkout_hip); method tx_st_eop t_eop() clocked_by(coreclkout_hip); method tx_st_err t_err() clocked_by(coreclkout_hip); method t_ready(tx_st_ready) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_st_ready); method tx_st_sop t_sop() clocked_by(coreclkout_hip); method tx_st_valid t_valid() clocked_by(coreclkout_hip); endinterface schedule (app.int_ack, app.int_sts, app.msi_ack, app.msi_num, app.msi_req, app.msi_tc, cfg_par.err, cfg_par.err_drv, cpl.err, cpl.pending, derr.cor_ext_rcv, derr.cor_ext_rcv_drv, derr.cor_ext_rpl, derr.cor_ext_rpl_drv, derr.rpl, derr.rpl_drv, dl.up, dl.up_drv, dl.up_exit, dl.up_exit_drv, ev128.ns, ev128.ns_drv, ev1.us, ev1.us_drv, hotrst.exit, hotrst.exit_drv, hpg.ctrler, int_s.tatus, int_s.tatus_drv, ko.cpl_spc_data, ko.cpl_spc_data_drv, ko.cpl_spc_header, ko.cpl_spc_header_drv, l2.exit, l2.exit_drv, lane.act, lane.act_drv, lmi.ack, lmi.addr, lmi.din, lmi.dout, lmi.rden, lmi.wren, ltssm.state, ltssm.state_drv, pld.clk_inuse, pld.core_ready, pm.auxpwr, pm.data, pm_e.vent, pme.to_cr, pme.to_sr, reset.status, rx_par.err, rx_par.err_drv, rx_s.t_bar, rx_s.t_be, rx_s.t_data, rx_s.t_empty, rx_s.t_eop, rx_s.t_err, rx_s.t_mask, rx_s.t_ready, rx_s.t_sop, rx_s.t_valid, serdes.pll_locked, testin.zero, tl.cfg_add, tl.cfg_ctl, tl.cfg_sts, tx_cred.datafccp, tx_cred.datafcnp, tx_cred.datafcp, tx_cred.fchipcons, tx_cred.fcinfinite, tx_cred.hdrfccp, tx_cred.hdrfcnp, tx_cred.hdrfcp, tx_par.err, tx_par.err_drv, tx_s.t_data, tx_s.t_empty, tx_s.t_eop, tx_s.t_err, tx_s.t_ready, tx_s.t_sop, tx_s.t_valid) CF (app.int_ack, app.int_sts, app.msi_ack, app.msi_num, app.msi_req, app.msi_tc, cfg_par.err, cfg_par.err_drv, cpl.err, cpl.pending, derr.cor_ext_rcv, derr.cor_ext_rcv_drv, derr.cor_ext_rpl, derr.cor_ext_rpl_drv, derr.rpl, derr.rpl_drv, dl.up, dl.up_drv, dl.up_exit, dl.up_exit_drv, ev128.ns, ev128.ns_drv, ev1.us, ev1.us_drv, hotrst.exit, hotrst.exit_drv, hpg.ctrler, int_s.tatus, int_s.tatus_drv, ko.cpl_spc_data, ko.cpl_spc_data_drv, ko.cpl_spc_header, ko.cpl_spc_header_drv, l2.exit, l2.exit_drv, lane.act, lane.act_drv, lmi.ack, lmi.addr, lmi.din, lmi.dout, lmi.rden, lmi.wren, ltssm.state, ltssm.state_drv, pld.clk_inuse, pld.core_ready, pm.auxpwr, pm.data, pm_e.vent, pme.to_cr, pme.to_sr, reset.status, rx_par.err, rx_par.err_drv, rx_s.t_bar, rx_s.t_be, rx_s.t_data, rx_s.t_empty, rx_s.t_eop, rx_s.t_err, rx_s.t_mask, rx_s.t_ready, rx_s.t_sop, rx_s.t_valid, serdes.pll_locked, testin.zero, tl.cfg_add, tl.cfg_ctl, tl.cfg_sts, tx_cred.datafccp, tx_cred.datafcnp, tx_cred.datafcp, tx_cred.fchipcons, tx_cred.fcinfinite, tx_cred.hdrfccp, tx_cred.hdrfcnp, tx_cred.hdrfcp, tx_par.err, tx_par.err_drv, tx_s.t_data, tx_s.t_empty, tx_s.t_eop, tx_s.t_err, tx_s.t_ready, tx_s.t_sop, tx_s.t_valid); endmodule ================================================ FILE: generated/altera/ALTERA_PCIE_RECONFIG_DRIVER_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_PCIE_RECONFIG_DRIVER_WRAPPER.bsv -I PcieReconfigWrap -P PcieReconfigWrap -c reconfig_xcvr_clk -c pld_clk -r reconfig_xcvr_rst -f reconfig_mgmt -f reconfig_b -f current -f derr -f dlup -f ev128ns -f ev1us -f hotrst -f int_s -f l2 -f lane -f ltssmstate -f dlup -f rx -f tx -f tx -f rx -f cfg -f ko ../../out/de5/synthesis/altera_pcie_reconfig_driver_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface PciereconfigwrapCfg; method Action par_err_drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapCurrent; method Action speed(Bit#(2) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapDerr; method Action cor_ext_rcv_drv(Bit#(1) v); method Action cor_ext_rpl_drv(Bit#(1) v); method Action rpl_drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapDlup; method Action drv(Bit#(1) v); method Action exit_drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapEv128ns; method Action drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapEv1us; method Action drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapHotrst; method Action exit_drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapInt_s; method Action tatus_drv(Bit#(4) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapKo; method Action cpl_spc_data_drv(Bit#(12) v); method Action cpl_spc_header_drv(Bit#(8) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapL2; method Action exit_drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapLane; method Action act_drv(Bit#(4) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapLtssmstate; method Action drv(Bit#(5) v); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface PciereconfigwrapReconfig_b; method Action usy(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapReconfig_mgmt; method Bit#(7) address(); method Bit#(1) read(); method Action readdata(Bit#(32) v); method Action waitrequest(Bit#(1) v); method Bit#(1) write(); method Bit#(32) writedata(); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapRx; method Action par_err_drv(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciereconfigwrapTx; method Action par_err_drv(Bit#(2) v); endinterface (* always_ready, always_enabled *) interface PcieReconfigWrap; interface PciereconfigwrapCfg cfg; interface PciereconfigwrapCurrent current; interface PciereconfigwrapDerr derr; interface PciereconfigwrapDlup dlup; interface PciereconfigwrapEv128ns ev128ns; interface PciereconfigwrapEv1us ev1us; interface PciereconfigwrapHotrst hotrst; interface PciereconfigwrapInt_s int_s; interface PciereconfigwrapKo ko; interface PciereconfigwrapL2 l2; interface PciereconfigwrapLane lane; interface PciereconfigwrapLtssmstate ltssmstate; interface PciereconfigwrapReconfig_b reconfig_b; interface PciereconfigwrapReconfig_mgmt reconfig_mgmt; interface PciereconfigwrapRx rx; interface PciereconfigwrapTx tx; endinterface import "BVI" altera_pcie_reconfig_driver_wrapper = module mkPcieReconfigWrap#(Clock pld_clk, Clock reconfig_xcvr_clk, Reset pld_clk_reset, Reset reconfig_xcvr_clk_reset, Reset reconfig_xcvr_rst)(PcieReconfigWrap); default_clock clk(); default_reset rst(); input_clock pld_clk(pld_clk) = pld_clk; input_reset pld_clk_reset() = pld_clk_reset; /* from clock*/ input_clock reconfig_xcvr_clk(reconfig_xcvr_clk) = reconfig_xcvr_clk; input_reset reconfig_xcvr_clk_reset() = reconfig_xcvr_clk_reset; /* from clock*/ input_reset reconfig_xcvr_rst(reconfig_xcvr_rst) = reconfig_xcvr_rst; interface PciereconfigwrapCfg cfg; method par_err_drv(cfg_par_err_drv) clocked_by(pld_clk) enable((*inhigh*) EN_cfg_par_err_drv); endinterface interface PciereconfigwrapCurrent current; method speed(currentspeed) clocked_by(pld_clk) enable((*inhigh*) EN_currentspeed); endinterface interface PciereconfigwrapDerr derr; method cor_ext_rcv_drv(derr_cor_ext_rcv_drv) clocked_by(pld_clk) enable((*inhigh*) EN_derr_cor_ext_rcv_drv); method cor_ext_rpl_drv(derr_cor_ext_rpl_drv) clocked_by(pld_clk) enable((*inhigh*) EN_derr_cor_ext_rpl_drv); method rpl_drv(derr_rpl_drv) clocked_by(pld_clk) enable((*inhigh*) EN_derr_rpl_drv); endinterface interface PciereconfigwrapDlup dlup; method drv(dlup_drv) clocked_by(pld_clk) enable((*inhigh*) EN_dlup_drv); method exit_drv(dlup_exit_drv) clocked_by(pld_clk) enable((*inhigh*) EN_dlup_exit_drv); endinterface interface PciereconfigwrapEv128ns ev128ns; method drv(ev128ns_drv) clocked_by(pld_clk) enable((*inhigh*) EN_ev128ns_drv); endinterface interface PciereconfigwrapEv1us ev1us; method drv(ev1us_drv) clocked_by(pld_clk) enable((*inhigh*) EN_ev1us_drv); endinterface interface PciereconfigwrapHotrst hotrst; method exit_drv(hotrst_exit_drv) clocked_by(pld_clk) enable((*inhigh*) EN_hotrst_exit_drv); endinterface interface PciereconfigwrapInt_s int_s; method tatus_drv(int_status_drv) clocked_by(pld_clk) enable((*inhigh*) EN_int_status_drv); endinterface interface PciereconfigwrapKo ko; method cpl_spc_data_drv(ko_cpl_spc_data_drv) clocked_by(pld_clk) enable((*inhigh*) EN_ko_cpl_spc_data_drv); method cpl_spc_header_drv(ko_cpl_spc_header_drv) clocked_by(pld_clk) enable((*inhigh*) EN_ko_cpl_spc_header_drv); endinterface interface PciereconfigwrapL2 l2; method exit_drv(l2_exit_drv) clocked_by(pld_clk) enable((*inhigh*) EN_l2_exit_drv); endinterface interface PciereconfigwrapLane lane; method act_drv(lane_act_drv) clocked_by(pld_clk) enable((*inhigh*) EN_lane_act_drv); endinterface interface PciereconfigwrapLtssmstate ltssmstate; method drv(ltssmstate_drv) clocked_by(pld_clk) enable((*inhigh*) EN_ltssmstate_drv); endinterface interface PciereconfigwrapReconfig_b reconfig_b; method usy(reconfig_busy) enable((*inhigh*) EN_reconfig_busy); endinterface interface PciereconfigwrapReconfig_mgmt reconfig_mgmt; method reconfig_mgmt_address address(); method reconfig_mgmt_read read(); method readdata(reconfig_mgmt_readdata) enable((*inhigh*) EN_reconfig_mgmt_readdata); method waitrequest(reconfig_mgmt_waitrequest) enable((*inhigh*) EN_reconfig_mgmt_waitrequest); method reconfig_mgmt_write write(); method reconfig_mgmt_writedata writedata(); endinterface interface PciereconfigwrapRx rx; method par_err_drv(rx_par_err_drv) clocked_by(pld_clk) enable((*inhigh*) EN_rx_par_err_drv); endinterface interface PciereconfigwrapTx tx; method par_err_drv(tx_par_err_drv) clocked_by(pld_clk) enable((*inhigh*) EN_tx_par_err_drv); endinterface schedule (cfg.par_err_drv, current.speed, derr.cor_ext_rcv_drv, derr.cor_ext_rpl_drv, derr.rpl_drv, dlup.drv, dlup.exit_drv, ev128ns.drv, ev1us.drv, hotrst.exit_drv, int_s.tatus_drv, ko.cpl_spc_data_drv, ko.cpl_spc_header_drv, l2.exit_drv, lane.act_drv, ltssmstate.drv, reconfig_b.usy, reconfig_mgmt.address, reconfig_mgmt.read, reconfig_mgmt.readdata, reconfig_mgmt.waitrequest, reconfig_mgmt.write, reconfig_mgmt.writedata, rx.par_err_drv, tx.par_err_drv) CF (cfg.par_err_drv, current.speed, derr.cor_ext_rcv_drv, derr.cor_ext_rpl_drv, derr.rpl_drv, dlup.drv, dlup.exit_drv, ev128ns.drv, ev1us.drv, hotrst.exit_drv, int_s.tatus_drv, ko.cpl_spc_data_drv, ko.cpl_spc_header_drv, l2.exit_drv, lane.act_drv, ltssmstate.drv, reconfig_b.usy, reconfig_mgmt.address, reconfig_mgmt.read, reconfig_mgmt.readdata, reconfig_mgmt.waitrequest, reconfig_mgmt.write, reconfig_mgmt.writedata, rx.par_err_drv, tx.par_err_drv); endmodule ================================================ FILE: generated/altera/ALTERA_PCIE_SIV_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_PCIE_SIV_WRAPPER.bsv -I PcieS4Wrap -P PcieS4Wrap -r pin_perst -r npor -r reset_status -r pcie_rstn -r srstn -c refclk -c core_clk_out -c pclk_in -c reconfig_clk -c clk250_out -f app -f pex_msi -f cpl -f rx_st -f tx_st -f fixedclk -f lmi -f tx -f rx -f phystatus -f pipe -f pm -f pme -f reconfig -f test -f lane -f ltssm -f powerdown -f rate -f rc_pll -f tl_cfg ../../out/htg4/siv_gen2x8/siv_gen2x8_examples/chaining_dma/siv_gen2x8_plus.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface Pcies4wrapApp; method Bit#(1) int_ack(); method Action int_sts(Bit#(1) v); method Bit#(1) msi_ack(); method Action msi_num(Bit#(5) v); method Action msi_req(Bit#(1) v); method Action msi_tc(Bit#(3) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapClk250; method Bit#(1) out; endinterface (* always_ready, always_enabled *) interface Pcies4wrapClk500; method Bit#(1) out; endinterface (* always_ready, always_enabled *) interface Pcies4wrapCore; interface Clock clk_out; endinterface (* always_ready, always_enabled *) interface Pcies4wrapCpl; method Action err(Bit#(7) v); method Action pending(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapSrstn; method Reset stn(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapLane; method Bit#(4) act(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapLmi; method Bit#(1) ack(); method Action addr(Bit#(12) v); method Action din(Bit#(32) v); method Bit#(32) dout(); method Action rden(Bit#(1) v); method Action wren(Bit#(1) v); endinterface interface Pcies4wrapPclk; method Action in(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapLtssm; method Bit#(5) sm(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapPex_msi; method Action num(Bit#(5) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapPhystatus; method Action ext(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapPipe; method Action mode(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapPld; method Action clk(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciewrapPm_e; method Action vent(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapPm; method Action auxpwr(Bit#(1) v); method Action data(Bit#(10) v); method Action e_to_cr(Bit#(1) v); method Bit#(1) e_to_sr(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapPowerdown; method Bit#(2) ext(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapRate; method Bit#(1) ext(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapRc_pll; method Bit#(1) locked(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapReconfig; method Action clk_locked(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapRx; method Action in0(Bit#(1) v); method Action in1(Bit#(1) v); method Action in2(Bit#(1) v); method Action in3(Bit#(1) v); method Action in4(Bit#(1) v); method Action in5(Bit#(1) v); method Action in6(Bit#(1) v); method Action in7(Bit#(1) v); method Action data0_ext(Bit#(8) v); method Action data1_ext(Bit#(8) v); method Action data2_ext(Bit#(8) v); method Action data3_ext(Bit#(8) v); method Action data4_ext(Bit#(8) v); method Action data5_ext(Bit#(8) v); method Action data6_ext(Bit#(8) v); method Action data7_ext(Bit#(8) v); method Action datak0_ext(Bit#(1) v); method Action datak1_ext(Bit#(1) v); method Action datak2_ext(Bit#(1) v); method Action datak3_ext(Bit#(1) v); method Action datak4_ext(Bit#(1) v); method Action datak5_ext(Bit#(1) v); method Action datak6_ext(Bit#(1) v); method Action datak7_ext(Bit#(1) v); method Action elecidle0_ext(Bit#(1) v); method Action elecidle1_ext(Bit#(1) v); method Action elecidle2_ext(Bit#(1) v); method Action elecidle3_ext(Bit#(1) v); method Action elecidle4_ext(Bit#(1) v); method Action elecidle5_ext(Bit#(1) v); method Action elecidle6_ext(Bit#(1) v); method Action elecidle7_ext(Bit#(1) v); method Bit#(1) polarity0_ext(); method Bit#(1) polarity1_ext(); method Bit#(1) polarity2_ext(); method Bit#(1) polarity3_ext(); method Bit#(1) polarity4_ext(); method Bit#(1) polarity5_ext(); method Bit#(1) polarity6_ext(); method Bit#(1) polarity7_ext(); method Action status0_ext(Bit#(3) v); method Action status1_ext(Bit#(3) v); method Action status2_ext(Bit#(3) v); method Action status3_ext(Bit#(3) v); method Action status4_ext(Bit#(3) v); method Action status5_ext(Bit#(3) v); method Action status6_ext(Bit#(3) v); method Action status7_ext(Bit#(3) v); method Action valid0_ext(Bit#(1) v); method Action valid1_ext(Bit#(1) v); method Action valid2_ext(Bit#(1) v); method Action valid3_ext(Bit#(1) v); method Action valid4_ext(Bit#(1) v); method Action valid5_ext(Bit#(1) v); method Action valid6_ext(Bit#(1) v); method Action valid7_ext(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapRx_st; method Bit#(8) bardec0(); method Bit#(16) be0(); method Bit#(128) data0(); method Bit#(1) empty0(); method Bit#(1) eop0(); method Bit#(1) err0(); method Action mask0(Bit#(1) v); method Action ready0(Bit#(1) v); method Bit#(1) sop0(); method Bit#(1) valid0(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapTest; method Action in(Bit#(40) v); endinterface (* always_ready, always_enabled *) interface Pcies4wrapTl_cfg; method Bit#(4) add(); method Bit#(32) ctl(); method Bit#(1) ctl_wr(); method Bit#(53) sts(); method Bit#(1) sts_wr(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapTx; method Bit#(36) cred0(); method Bit#(1) fifo_empty0(); method Bit#(1) out0(); method Bit#(1) out1(); method Bit#(1) out2(); method Bit#(1) out3(); method Bit#(1) out4(); method Bit#(1) out5(); method Bit#(1) out6(); method Bit#(1) out7(); method Bit#(1) compl0_ext(); method Bit#(1) compl1_ext(); method Bit#(1) compl2_ext(); method Bit#(1) compl3_ext(); method Bit#(1) compl4_ext(); method Bit#(1) compl5_ext(); method Bit#(1) compl6_ext(); method Bit#(1) compl7_ext(); method Bit#(8) data0_ext(); method Bit#(8) data1_ext(); method Bit#(8) data2_ext(); method Bit#(8) data3_ext(); method Bit#(8) data4_ext(); method Bit#(8) data5_ext(); method Bit#(8) data6_ext(); method Bit#(8) data7_ext(); method Bit#(1) datak0_ext(); method Bit#(1) datak1_ext(); method Bit#(1) datak2_ext(); method Bit#(1) datak3_ext(); method Bit#(1) datak4_ext(); method Bit#(1) datak5_ext(); method Bit#(1) datak6_ext(); method Bit#(1) datak7_ext(); method Bit#(1) detectrx_ext(); method Bit#(1) elecidle0_ext(); method Bit#(1) elecidle1_ext(); method Bit#(1) elecidle2_ext(); method Bit#(1) elecidle3_ext(); method Bit#(1) elecidle4_ext(); method Bit#(1) elecidle5_ext(); method Bit#(1) elecidle6_ext(); method Bit#(1) elecidle7_ext(); endinterface (* always_ready, always_enabled *) interface Pcies4wrapTx_st; method Action data0(Bit#(128) v); method Action empty0(Bit#(1) v) ; method Action eop0(Bit#(1) v) ; method Action err0(Bit#(1) v) ; method Bit#(1) ready0() ; method Action sop0(Bit#(1) v) ; method Action valid0(Bit#(1) v) ; endinterface (* always_ready, always_enabled *) interface PcieS4Wrap; interface Pcies4wrapApp app; interface Pcies4wrapClk250 clk250; interface Pcies4wrapClk500 clk500; interface Pcies4wrapCore core; interface Pcies4wrapCpl cpl; interface Pcies4wrapSrstn sr; interface Pcies4wrapLane lane; interface Pcies4wrapPclk pclk; interface Pcies4wrapLmi lmi; interface Pcies4wrapLtssm lts; interface Pcies4wrapPex_msi pex_msi; interface Pcies4wrapPhystatus phystatus; interface Pcies4wrapPipe pipe; interface Pcies4wrapPld pld; interface PciewrapPm_e pm_e; interface Pcies4wrapPm pm; interface Pcies4wrapPowerdown powerdown; interface Pcies4wrapRate rate; interface Pcies4wrapRc_pll rc_pll; interface Pcies4wrapReconfig reconfig; interface Pcies4wrapRx rx; interface Pcies4wrapRx_st rx_st; interface Pcies4wrapTest test; interface Pcies4wrapTl_cfg tl_cfg; interface Pcies4wrapTx tx; interface Pcies4wrapTx_st tx_st; endinterface import "BVI" siv_gen2x8_plus = module mkPPS4Wrap#(Clock refclk, Clock reconfig_clk, Clock fixedclk_serdes, Reset pcie_rstn, Reset local_rstn)(PcieS4Wrap); default_clock clk(); default_reset rst(); input_reset pcie_rstn(pcie_rstn) = pcie_rstn; input_reset local_rstn(local_rstn) = local_rstn; input_clock fixedclk_serdes(fixedclk_serdes) = fixedclk_serdes; input_clock reconfig_clk(reconfig_clk) = reconfig_clk; input_clock refclk(refclk) = refclk; interface Pcies4wrapApp app; method app_int_ack int_ack(); method int_sts(app_int_sts) enable((*inhigh*) EN_app_int_sts); method app_msi_ack msi_ack(); method msi_num(app_msi_num) enable((*inhigh*) EN_app_msi_num); method msi_req(app_msi_req) enable((*inhigh*) EN_app_msi_req); method msi_tc(app_msi_tc) enable((*inhigh*) EN_app_msi_tc); endinterface interface Pcies4wrapClk250 clk250; method clk250_out out(); endinterface interface Pcies4wrapClk500 clk500; method clk500_out out(); endinterface interface Pcies4wrapCore core; output_clock clk_out(core_clk_out); endinterface interface Pcies4wrapCpl cpl; method err(cpl_err) enable((*inhigh*) EN_cpl_err); method pending(cpl_pending) enable((*inhigh*) EN_cpl_pending); endinterface interface Pcies4wrapLane lane; method lane_act act(); endinterface interface Pcies4wrapLmi lmi; method lmi_ack ack(); method addr(lmi_addr) enable((*inhigh*) EN_lmi_addr); method din(lmi_din) enable((*inhigh*) EN_lmi_din); method lmi_dout dout(); method rden(lmi_rden) enable((*inhigh*) EN_lmi_rden); method wren(lmi_wren) enable((*inhigh*) EN_lmi_wren); endinterface interface Pcies4wrapPclk pclk; method in(pclk_in) enable((*inhigh*) EN_pclk_in); endinterface interface Pcies4wrapLtssm lts; method ltssm sm(); endinterface interface Pcies4wrapPex_msi pex_msi; method num(pex_msi_num) enable((*inhigh*) EN_pex_msi_num); endinterface interface Pcies4wrapPhystatus phystatus; method ext(phystatus_ext) enable((*inhigh*) EN_phystatus_ext); endinterface interface Pcies4wrapPipe pipe; method mode(pipe_mode) enable((*inhigh*) EN_pipe_mode); endinterface interface Pcies4wrapPld pld; method clk(pld_clk) enable((*inhigh*) EN_pld_clk); endinterface interface PciewrapPm_e pm_e; method vent(pm_event) enable((*inhigh*) EN_pm_event); endinterface interface Pcies4wrapPm pm; method auxpwr(pm_auxpwr) enable((*inhigh*) EN_pm_auxpwr); method data(pm_data) enable((*inhigh*) EN_pm_data); method e_to_cr(pme_to_cr) enable((*inhigh*) EN_pme_to_cr); method pme_to_sr e_to_sr(); endinterface interface Pcies4wrapPowerdown powerdown; method powerdown_ext ext(); endinterface interface Pcies4wrapRate rate; method rate_ext ext(); endinterface interface Pcies4wrapRc_pll rc_pll; method rc_pll_locked locked(); endinterface interface Pcies4wrapReconfig reconfig; method clk_locked(reconfig_clk_locked) clocked_by (reconfig_clk) enable((*inhigh*) EN_reconfig_clk_locked); endinterface interface Pcies4wrapRx rx; method in0(rx_in0) enable((*inhigh*) EN_rx_in0); method in1(rx_in1) enable((*inhigh*) EN_rx_in1); method in2(rx_in2) enable((*inhigh*) EN_rx_in2); method in3(rx_in3) enable((*inhigh*) EN_rx_in3); method in4(rx_in4) enable((*inhigh*) EN_rx_in4); method in5(rx_in5) enable((*inhigh*) EN_rx_in5); method in6(rx_in6) enable((*inhigh*) EN_rx_in6); method in7(rx_in7) enable((*inhigh*) EN_rx_in7); method data0_ext(rxdata0_ext) enable((*inhigh*) EN_rxdata0_ext); method data1_ext(rxdata1_ext) enable((*inhigh*) EN_rxdata1_ext); method data2_ext(rxdata2_ext) enable((*inhigh*) EN_rxdata2_ext); method data3_ext(rxdata3_ext) enable((*inhigh*) EN_rxdata3_ext); method data4_ext(rxdata4_ext) enable((*inhigh*) EN_rxdata4_ext); method data5_ext(rxdata5_ext) enable((*inhigh*) EN_rxdata5_ext); method data6_ext(rxdata6_ext) enable((*inhigh*) EN_rxdata6_ext); method data7_ext(rxdata7_ext) enable((*inhigh*) EN_rxdata7_ext); method datak0_ext(rxdatak0_ext) enable((*inhigh*) EN_rxdatak0_ext); method datak1_ext(rxdatak1_ext) enable((*inhigh*) EN_rxdatak1_ext); method datak2_ext(rxdatak2_ext) enable((*inhigh*) EN_rxdatak2_ext); method datak3_ext(rxdatak3_ext) enable((*inhigh*) EN_rxdatak3_ext); method datak4_ext(rxdatak4_ext) enable((*inhigh*) EN_rxdatak4_ext); method datak5_ext(rxdatak5_ext) enable((*inhigh*) EN_rxdatak5_ext); method datak6_ext(rxdatak6_ext) enable((*inhigh*) EN_rxdatak6_ext); method datak7_ext(rxdatak7_ext) enable((*inhigh*) EN_rxdatak7_ext); method elecidle0_ext(rxelecidle0_ext) enable((*inhigh*) EN_rxelecidle0_ext); method elecidle1_ext(rxelecidle1_ext) enable((*inhigh*) EN_rxelecidle1_ext); method elecidle2_ext(rxelecidle2_ext) enable((*inhigh*) EN_rxelecidle2_ext); method elecidle3_ext(rxelecidle3_ext) enable((*inhigh*) EN_rxelecidle3_ext); method elecidle4_ext(rxelecidle4_ext) enable((*inhigh*) EN_rxelecidle4_ext); method elecidle5_ext(rxelecidle5_ext) enable((*inhigh*) EN_rxelecidle5_ext); method elecidle6_ext(rxelecidle6_ext) enable((*inhigh*) EN_rxelecidle6_ext); method elecidle7_ext(rxelecidle7_ext) enable((*inhigh*) EN_rxelecidle7_ext); method rxpolarity0_ext polarity0_ext(); method rxpolarity1_ext polarity1_ext(); method rxpolarity2_ext polarity2_ext(); method rxpolarity3_ext polarity3_ext(); method rxpolarity4_ext polarity4_ext(); method rxpolarity5_ext polarity5_ext(); method rxpolarity6_ext polarity6_ext(); method rxpolarity7_ext polarity7_ext(); method status0_ext(rxstatus0_ext) enable((*inhigh*) EN_rxstatus0_ext); method status1_ext(rxstatus1_ext) enable((*inhigh*) EN_rxstatus1_ext); method status2_ext(rxstatus2_ext) enable((*inhigh*) EN_rxstatus2_ext); method status3_ext(rxstatus3_ext) enable((*inhigh*) EN_rxstatus3_ext); method status4_ext(rxstatus4_ext) enable((*inhigh*) EN_rxstatus4_ext); method status5_ext(rxstatus5_ext) enable((*inhigh*) EN_rxstatus5_ext); method status6_ext(rxstatus6_ext) enable((*inhigh*) EN_rxstatus6_ext); method status7_ext(rxstatus7_ext) enable((*inhigh*) EN_rxstatus7_ext); method valid0_ext(rxvalid0_ext) enable((*inhigh*) EN_rxvalid0_ext); method valid1_ext(rxvalid1_ext) enable((*inhigh*) EN_rxvalid1_ext); method valid2_ext(rxvalid2_ext) enable((*inhigh*) EN_rxvalid2_ext); method valid3_ext(rxvalid3_ext) enable((*inhigh*) EN_rxvalid3_ext); method valid4_ext(rxvalid4_ext) enable((*inhigh*) EN_rxvalid4_ext); method valid5_ext(rxvalid5_ext) enable((*inhigh*) EN_rxvalid5_ext); method valid6_ext(rxvalid6_ext) enable((*inhigh*) EN_rxvalid6_ext); method valid7_ext(rxvalid7_ext) enable((*inhigh*) EN_rxvalid7_ext); endinterface interface Pcies4wrapRx_st rx_st; method rx_st_bardec0 bardec0() clocked_by(core_clk_out) reset_by(no_reset); method rx_st_be0 be0() clocked_by(core_clk_out) reset_by(no_reset); method rx_st_data0 data0() clocked_by(core_clk_out) reset_by(no_reset); method rx_st_empty0 empty0() clocked_by(core_clk_out) reset_by(no_reset); method rx_st_eop0 eop0() clocked_by(core_clk_out) reset_by(no_reset); method rx_st_err0 err0() clocked_by(core_clk_out) reset_by(no_reset); method mask0(rx_st_mask0) enable((*inhigh*) EN_rx_st_mask0) clocked_by(core_clk_out) reset_by(no_reset); method ready0(rx_st_ready0) enable((*inhigh*) EN_rx_st_ready0) clocked_by(core_clk_out) reset_by(no_reset); method rx_st_sop0 sop0() clocked_by(core_clk_out) reset_by(no_reset); method rx_st_valid0 valid0() clocked_by(core_clk_out) reset_by(no_reset); endinterface interface Pcies4wrapSrstn sr; output_reset stn(srstn); endinterface interface Pcies4wrapTest test; method in(test_in) enable((*inhigh*) EN_test_in); endinterface interface Pcies4wrapTl_cfg tl_cfg; method tl_cfg_add add() clocked_by(core_clk_out) reset_by(no_reset); method tl_cfg_ctl ctl() clocked_by(core_clk_out) reset_by(no_reset); method tl_cfg_ctl_wr ctl_wr() clocked_by(core_clk_out) reset_by(no_reset); method tl_cfg_sts sts() clocked_by(core_clk_out) reset_by(no_reset); method tl_cfg_sts_wr sts_wr() clocked_by(core_clk_out) reset_by(no_reset); endinterface interface Pcies4wrapTx tx; method tx_cred0 cred0(); method tx_fifo_empty0 fifo_empty0(); method tx_out0 out0(); method tx_out1 out1(); method tx_out2 out2(); method tx_out3 out3(); method tx_out4 out4(); method tx_out5 out5(); method tx_out6 out6(); method tx_out7 out7(); method txcompl0_ext compl0_ext(); method txcompl1_ext compl1_ext(); method txcompl2_ext compl2_ext(); method txcompl3_ext compl3_ext(); method txcompl4_ext compl4_ext(); method txcompl5_ext compl5_ext(); method txcompl6_ext compl6_ext(); method txcompl7_ext compl7_ext(); method txdata0_ext data0_ext(); method txdata1_ext data1_ext(); method txdata2_ext data2_ext(); method txdata3_ext data3_ext(); method txdata4_ext data4_ext(); method txdata5_ext data5_ext(); method txdata6_ext data6_ext(); method txdata7_ext data7_ext(); method txdatak0_ext datak0_ext(); method txdatak1_ext datak1_ext(); method txdatak2_ext datak2_ext(); method txdatak3_ext datak3_ext(); method txdatak4_ext datak4_ext(); method txdatak5_ext datak5_ext(); method txdatak6_ext datak6_ext(); method txdatak7_ext datak7_ext(); method txdetectrx_ext detectrx_ext(); method txelecidle0_ext elecidle0_ext(); method txelecidle1_ext elecidle1_ext(); method txelecidle2_ext elecidle2_ext(); method txelecidle3_ext elecidle3_ext(); method txelecidle4_ext elecidle4_ext(); method txelecidle5_ext elecidle5_ext(); method txelecidle6_ext elecidle6_ext(); method txelecidle7_ext elecidle7_ext(); endinterface interface Pcies4wrapTx_st tx_st; method data0(tx_st_data0) enable((*inhigh*) EN_tx_st_data0) clocked_by(core_clk_out) reset_by(no_reset); method empty0(tx_st_empty0) enable((*inhigh*) EN_tx_st_empty0) clocked_by(core_clk_out) reset_by(no_reset); method eop0(tx_st_eop0) enable((*inhigh*) EN_tx_st_eop0) clocked_by(core_clk_out) reset_by(no_reset); method err0(tx_st_err0) enable((*inhigh*) EN_tx_st_err0) clocked_by(core_clk_out) reset_by(no_reset); method tx_st_ready0 ready0() clocked_by(core_clk_out) reset_by(no_reset); method sop0(tx_st_sop0) enable((*inhigh*) EN_tx_st_sop0) clocked_by(core_clk_out) reset_by(no_reset); method valid0(tx_st_valid0) enable((*inhigh*) EN_tx_st_valid0) clocked_by(core_clk_out) reset_by(no_reset); endinterface schedule (app.int_ack, app.int_sts, app.msi_ack, app.msi_num, app.msi_req, app.msi_tc, cpl.err, cpl.pending, lane.act, lmi.ack, lmi.addr, lmi.din, lmi.dout, lmi.rden, lmi.wren, lts.sm, clk250.out, clk500.out, pclk.in, pex_msi.num, phystatus.ext, pipe.mode, pld.clk, pm.auxpwr, pm.data, pm_e.vent, pm.e_to_cr, pm.e_to_sr, powerdown.ext, rate.ext, rc_pll.locked, reconfig.clk_locked, rx.in0, rx.in1, rx.in2, rx.in3, rx.in4, rx.in5, rx.in6, rx.in7, rx.data0_ext, rx.data1_ext, rx.data2_ext, rx.data3_ext, rx.data4_ext, rx.data5_ext, rx.data6_ext, rx.data7_ext, rx.datak0_ext, rx.datak1_ext, rx.datak2_ext, rx.datak3_ext, rx.datak4_ext, rx.datak5_ext, rx.datak6_ext, rx.datak7_ext, rx.elecidle0_ext, rx.elecidle1_ext, rx.elecidle2_ext, rx.elecidle3_ext, rx.elecidle4_ext, rx.elecidle5_ext, rx.elecidle6_ext, rx.elecidle7_ext, rx.polarity0_ext, rx.polarity1_ext, rx.polarity2_ext, rx.polarity3_ext, rx.polarity4_ext, rx.polarity5_ext, rx.polarity6_ext, rx.polarity7_ext, rx.status0_ext, rx.status1_ext, rx.status2_ext, rx.status3_ext, rx.status4_ext, rx.status5_ext, rx.status6_ext, rx.status7_ext, rx.valid0_ext, rx.valid1_ext, rx.valid2_ext, rx.valid3_ext, rx.valid4_ext, rx.valid5_ext, rx.valid6_ext, rx.valid7_ext, rx_st.bardec0, rx_st.be0, rx_st.data0, rx_st.empty0, rx_st.eop0, rx_st.err0, rx_st.mask0, rx_st.ready0, rx_st.sop0, rx_st.valid0, test.in, tl_cfg.add, tl_cfg.ctl, tl_cfg.ctl_wr, tl_cfg.sts, tl_cfg.sts_wr, tx.cred0, tx.fifo_empty0, tx.out0, tx.out1, tx.out2, tx.out3, tx.out4, tx.out5, tx.out6, tx.out7, tx.compl0_ext, tx.compl1_ext, tx.compl2_ext, tx.compl3_ext, tx.compl4_ext, tx.compl5_ext, tx.compl6_ext, tx.compl7_ext, tx.data0_ext, tx.data1_ext, tx.data2_ext, tx.data3_ext, tx.data4_ext, tx.data5_ext, tx.data6_ext, tx.data7_ext, tx.datak0_ext, tx.datak1_ext, tx.datak2_ext, tx.datak3_ext, tx.datak4_ext, tx.datak5_ext, tx.datak6_ext, tx.datak7_ext, tx.detectrx_ext, tx.elecidle0_ext, tx.elecidle1_ext, tx.elecidle2_ext, tx.elecidle3_ext, tx.elecidle4_ext, tx.elecidle5_ext, tx.elecidle6_ext, tx.elecidle7_ext, tx_st.data0, tx_st.empty0, tx_st.eop0, tx_st.err0, tx_st.ready0, tx_st.sop0, tx_st.valid0) CF (app.int_ack, app.int_sts, app.msi_ack, app.msi_num, app.msi_req, app.msi_tc, cpl.err, cpl.pending, lane.act, lmi.ack, lmi.addr, lmi.din, lmi.dout, lmi.rden, lmi.wren, lts.sm, clk250.out, clk500.out, pclk.in, pex_msi.num, phystatus.ext, pipe.mode, pld.clk, pm.auxpwr, pm.data, pm_e.vent, pm.e_to_cr, pm.e_to_sr, powerdown.ext, rate.ext, rc_pll.locked, reconfig.clk_locked, rx.in0, rx.in1, rx.in2, rx.in3, rx.in4, rx.in5, rx.in6, rx.in7, rx.data0_ext, rx.data1_ext, rx.data2_ext, rx.data3_ext, rx.data4_ext, rx.data5_ext, rx.data6_ext, rx.data7_ext, rx.datak0_ext, rx.datak1_ext, rx.datak2_ext, rx.datak3_ext, rx.datak4_ext, rx.datak5_ext, rx.datak6_ext, rx.datak7_ext, rx.elecidle0_ext, rx.elecidle1_ext, rx.elecidle2_ext, rx.elecidle3_ext, rx.elecidle4_ext, rx.elecidle5_ext, rx.elecidle6_ext, rx.elecidle7_ext, rx.polarity0_ext, rx.polarity1_ext, rx.polarity2_ext, rx.polarity3_ext, rx.polarity4_ext, rx.polarity5_ext, rx.polarity6_ext, rx.polarity7_ext, rx.status0_ext, rx.status1_ext, rx.status2_ext, rx.status3_ext, rx.status4_ext, rx.status5_ext, rx.status6_ext, rx.status7_ext, rx.valid0_ext, rx.valid1_ext, rx.valid2_ext, rx.valid3_ext, rx.valid4_ext, rx.valid5_ext, rx.valid6_ext, rx.valid7_ext, rx_st.bardec0, rx_st.be0, rx_st.data0, rx_st.empty0, rx_st.eop0, rx_st.err0, rx_st.mask0, rx_st.ready0, rx_st.sop0, rx_st.valid0, test.in, tl_cfg.add, tl_cfg.ctl, tl_cfg.ctl_wr, tl_cfg.sts, tl_cfg.sts_wr, tx.cred0, tx.fifo_empty0, tx.out0, tx.out1, tx.out2, tx.out3, tx.out4, tx.out5, tx.out6, tx.out7, tx.compl0_ext, tx.compl1_ext, tx.compl2_ext, tx.compl3_ext, tx.compl4_ext, tx.compl5_ext, tx.compl6_ext, tx.compl7_ext, tx.data0_ext, tx.data1_ext, tx.data2_ext, tx.data3_ext, tx.data4_ext, tx.data5_ext, tx.data6_ext, tx.data7_ext, tx.datak0_ext, tx.datak1_ext, tx.datak2_ext, tx.datak3_ext, tx.datak4_ext, tx.datak5_ext, tx.datak6_ext, tx.datak7_ext, tx.detectrx_ext, tx.elecidle0_ext, tx.elecidle1_ext, tx.elecidle2_ext, tx.elecidle3_ext, tx.elecidle4_ext, tx.elecidle5_ext, tx.elecidle6_ext, tx.elecidle7_ext, tx_st.data0, tx_st.empty0, tx_st.eop0, tx_st.err0, tx_st.ready0, tx_st.sop0, tx_st.valid0); endmodule ================================================ FILE: generated/altera/ALTERA_PCIE_SV_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_PCIE_SV_WRAPPER.bsv -I PcieWrap -P PcieWrap -r pin_perst -r npor -r reset_status -c refclk -c coreclkout_hip -f serdes -f pld -f dl -f ev128 -f ev1 -f hotrst -f l2 -f current -f derr -f lane -f ltssm -f reconfig -f tx_cred -f tx_par -f tx_s -f txd -f txe -f txc -f txm -f txs -f tx -f tx_cred -f rx_par -f rx_s -f rxd -f rxr -f rxe -f rxp -f rxs -f rxv -f rx -f cfg_par -f eidle -f power -f phy -f int_s -f cpl -f tl -f pm_e -f pme -f pm -f simu -f sim -f test_in ../../out/de5/synthesis/altera_pcie_sv_hip_ast_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface PciewrapApp; method Bit#(1) int_ack(); method Action int_sts(Bit#(1) v); method Bit#(1) msi_ack(); method Action msi_num(Bit#(5) v); method Action msi_req(Bit#(1) v); method Action msi_tc(Bit#(3) v); endinterface (* always_ready, always_enabled *) interface PciewrapCfg_par; method Bit#(1) err(); endinterface (* always_ready, always_enabled *) interface PciewrapCoreclkout; interface Clock hip; endinterface (* always_ready, always_enabled *) interface PciewrapCpl; method Action err(Bit#(7) v); method Action pending(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciewrapCurrent; method Bit#(2) speed(); endinterface (* always_ready, always_enabled *) interface PciewrapDerr; method Bit#(1) cor_ext_rcv(); method Bit#(1) cor_ext_rpl(); method Bit#(1) rpl(); endinterface (* always_ready, always_enabled *) interface PciewrapDl; method Bit#(1) up(); method Bit#(1) up_exit(); endinterface (* always_ready, always_enabled *) interface PciewrapEidle; method Bit#(3) infersel0(); method Bit#(3) infersel1(); method Bit#(3) infersel2(); method Bit#(3) infersel3(); method Bit#(3) infersel4(); method Bit#(3) infersel5(); method Bit#(3) infersel6(); method Bit#(3) infersel7(); endinterface (* always_ready, always_enabled *) interface PciewrapEv1; method Bit#(1) us(); endinterface (* always_ready, always_enabled *) interface PciewrapEv128; method Bit#(1) ns(); endinterface (* always_ready, always_enabled *) interface PciewrapHotrst; method Bit#(1) exit(); endinterface (* always_ready, always_enabled *) interface PciewrapHpg; method Action ctrler(Bit#(5) v); endinterface (* always_ready, always_enabled *) interface PciewrapInt_s; method Bit#(4) tatus(); endinterface (* always_ready, always_enabled *) interface PciewrapKo; method Bit#(12) cpl_spc_data(); method Bit#(8) cpl_spc_header(); endinterface (* always_ready, always_enabled *) interface PciewrapL2; method Bit#(1) exit(); endinterface (* always_ready, always_enabled *) interface PciewrapLane; method Bit#(4) act(); endinterface (* always_ready, always_enabled *) interface PciewrapLtssm; method Bit#(5) state(); endinterface (* always_ready, always_enabled *) interface PciewrapPhy; method Action status0(Bit#(1) v); method Action status1(Bit#(1) v); method Action status2(Bit#(1) v); method Action status3(Bit#(1) v); method Action status4(Bit#(1) v); method Action status5(Bit#(1) v); method Action status6(Bit#(1) v); method Action status7(Bit#(1) v); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface PciewrapPld; method Action clk(Bit#(1) v); method Bit#(1) clk_inuse(); method Action core_ready(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciewrapPm; method Action auxpwr(Bit#(1) v); method Action data(Bit#(10) v); endinterface (* always_ready, always_enabled *) interface PciewrapPm_e; method Action vent(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciewrapPme; method Action to_cr(Bit#(1) v); method Bit#(1) to_sr(); endinterface (* always_ready, always_enabled *) interface PciewrapPower; method Bit#(2) down0(); method Bit#(2) down1(); method Bit#(2) down2(); method Bit#(2) down3(); method Bit#(2) down4(); method Bit#(2) down5(); method Bit#(2) down6(); method Bit#(2) down7(); endinterface (* always_ready, always_enabled *) interface PciewrapReconfig; method Bit#(460) from_xcvr(); method Action to_xcvr(Bit#(700) v); endinterface (* always_ready, always_enabled *) interface PciewrapReset; method Reset status(); endinterface (* always_ready, always_enabled *) interface PciewrapRx; method Action in0(Bit#(1) v); method Action in1(Bit#(1) v); method Action in2(Bit#(1) v); method Action in3(Bit#(1) v); method Action in4(Bit#(1) v); method Action in5(Bit#(1) v); method Action in6(Bit#(1) v); method Action in7(Bit#(1) v); method Action data0(Bit#(8) v); method Action data1(Bit#(8) v); method Action data2(Bit#(8) v); method Action data3(Bit#(8) v); method Action data4(Bit#(8) v); method Action data5(Bit#(8) v); method Action data6(Bit#(8) v); method Action data7(Bit#(8) v); method Action datak0(Bit#(1) v); method Action datak1(Bit#(1) v); method Action datak2(Bit#(1) v); method Action datak3(Bit#(1) v); method Action datak4(Bit#(1) v); method Action datak5(Bit#(1) v); method Action datak6(Bit#(1) v); method Action datak7(Bit#(1) v); method Action elecidle0(Bit#(1) v); method Action elecidle1(Bit#(1) v); method Action elecidle2(Bit#(1) v); method Action elecidle3(Bit#(1) v); method Action elecidle4(Bit#(1) v); method Action elecidle5(Bit#(1) v); method Action elecidle6(Bit#(1) v); method Action elecidle7(Bit#(1) v); method Bit#(1) polarity0(); method Bit#(1) polarity1(); method Bit#(1) polarity2(); method Bit#(1) polarity3(); method Bit#(1) polarity4(); method Bit#(1) polarity5(); method Bit#(1) polarity6(); method Bit#(1) polarity7(); method Action status0(Bit#(3) v); method Action status1(Bit#(3) v); method Action status2(Bit#(3) v); method Action status3(Bit#(3) v); method Action status4(Bit#(3) v); method Action status5(Bit#(3) v); method Action status6(Bit#(3) v); method Action status7(Bit#(3) v); method Action valid0(Bit#(1) v); method Action valid1(Bit#(1) v); method Action valid2(Bit#(1) v); method Action valid3(Bit#(1) v); method Action valid4(Bit#(1) v); method Action valid5(Bit#(1) v); method Action valid6(Bit#(1) v); method Action valid7(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PciewrapRx_par; method Bit#(1) err(); endinterface (* always_ready, always_enabled *) interface PciewrapRx_st; method Bit#(8) bar0(); method Bit#(16) be0(); method Bit#(128) data0(); method Bit#(2) empty0(); method Bit#(1) eop0(); method Bit#(1) err0(); method Action mask0(Bit#(1) v); method Action ready0(Bit#(1) v); method Bit#(1) sop0(); method Bit#(1) valid0(); endinterface (* always_ready, always_enabled *) interface PciewrapSerdes; method Bit#(1) pll_locked(); endinterface (* always_ready, always_enabled *) interface PciewrapSim; method Bit#(5) ltssmstate(); method Bit#(2) pipe_rate(); endinterface (* always_ready, always_enabled *) interface PciewrapTest; method Action in(Bit#(32) v); endinterface (* always_ready, always_enabled *) interface PciewrapTestin; method Bit#(1) zero(); endinterface (* always_ready, always_enabled *) interface PciewrapTl; method Bit#(4) cfg_add(); method Bit#(32) cfg_ctl(); method Bit#(53) cfg_sts(); endinterface (* always_ready, always_enabled *) interface PciewrapTx; method Bit#(1) out0(); method Bit#(1) out1(); method Bit#(1) out2(); method Bit#(1) out3(); method Bit#(1) out4(); method Bit#(1) out5(); method Bit#(1) out6(); method Bit#(1) out7(); method Bit#(1) compl0(); method Bit#(1) compl1(); method Bit#(1) compl2(); method Bit#(1) compl3(); method Bit#(1) compl4(); method Bit#(1) compl5(); method Bit#(1) compl6(); method Bit#(1) compl7(); method Bit#(8) data0(); method Bit#(8) data1(); method Bit#(8) data2(); method Bit#(8) data3(); method Bit#(8) data4(); method Bit#(8) data5(); method Bit#(8) data6(); method Bit#(8) data7(); method Bit#(1) datak0(); method Bit#(1) datak1(); method Bit#(1) datak2(); method Bit#(1) datak3(); method Bit#(1) datak4(); method Bit#(1) datak5(); method Bit#(1) datak6(); method Bit#(1) datak7(); method Bit#(1) deemph0(); method Bit#(1) deemph1(); method Bit#(1) deemph2(); method Bit#(1) deemph3(); method Bit#(1) deemph4(); method Bit#(1) deemph5(); method Bit#(1) deemph6(); method Bit#(1) deemph7(); method Bit#(1) detectrx0(); method Bit#(1) detectrx1(); method Bit#(1) detectrx2(); method Bit#(1) detectrx3(); method Bit#(1) detectrx4(); method Bit#(1) detectrx5(); method Bit#(1) detectrx6(); method Bit#(1) detectrx7(); method Bit#(1) elecidle0(); method Bit#(1) elecidle1(); method Bit#(1) elecidle2(); method Bit#(1) elecidle3(); method Bit#(1) elecidle4(); method Bit#(1) elecidle5(); method Bit#(1) elecidle6(); method Bit#(1) elecidle7(); method Bit#(3) margin0(); method Bit#(3) margin1(); method Bit#(3) margin2(); method Bit#(3) margin3(); method Bit#(3) margin4(); method Bit#(3) margin5(); method Bit#(3) margin6(); method Bit#(3) margin7(); method Bit#(1) swing0(); method Bit#(1) swing1(); method Bit#(1) swing2(); method Bit#(1) swing3(); method Bit#(1) swing4(); method Bit#(1) swing5(); method Bit#(1) swing6(); method Bit#(1) swing7(); endinterface (* always_ready, always_enabled *) interface PciewrapTx_cred; method Bit#(12) datafccp(); method Bit#(12) datafcnp(); method Bit#(12) datafcp(); method Bit#(6) fchipcons(); method Bit#(6) fcinfinite(); method Bit#(8) hdrfccp(); method Bit#(8) hdrfcnp(); method Bit#(8) hdrfcp(); endinterface (* always_ready, always_enabled *) interface PciewrapTx_par; method Bit#(2) err(); endinterface (* always_ready, always_enabled *) interface PciewrapTx_st; method Action data0(Bit#(128) v); method Action empty0(Bit#(2) v); method Action eop0(Bit#(1) v); method Action err0(Bit#(1) v); method Bit#(1) ready0(); method Action sop0(Bit#(1) v); method Action valid0(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface PcieS5Wrap; interface PciewrapApp app; interface PciewrapCfg_par cfg_par; interface PciewrapCoreclkout coreclkout; interface PciewrapCpl cpl; interface PciewrapCurrent current; interface PciewrapDerr derr; interface PciewrapDl dl; interface PciewrapEidle eidle; interface PciewrapEv128 ev128; interface PciewrapEv1 ev1; interface PciewrapHotrst hotrst; interface PciewrapHpg hpg; interface PciewrapInt_s int_s; interface PciewrapKo ko; interface PciewrapL2 l2; interface PciewrapLane lane; interface PciewrapLtssm ltssm; interface PciewrapPhy phy; interface PciewrapPld pld; interface PciewrapPm pm; interface PciewrapPm_e pm_e; interface PciewrapPme pme; interface PciewrapPower power; interface PciewrapReconfig reconfig; interface PciewrapReset reset; interface PciewrapRx rx; interface PciewrapRx_par rx_par; interface PciewrapRx_st rx_st; interface PciewrapSerdes serdes; interface PciewrapSim sim; interface PciewrapTest test; interface PciewrapTestin testin; interface PciewrapTl tl; interface PciewrapTx_cred tx_cred; interface PciewrapTx tx; interface PciewrapTx_par tx_par; interface PciewrapTx_st tx_st; endinterface import "BVI" altera_pcie_sv_hip_ast_wrapper = module mkPPS5Wrap#(Clock refclk, Reset npor, Reset pin_perst, Reset refclk_reset)(PcieS5Wrap); default_clock clk(); default_reset rst(); input_reset npor(npor) = npor; input_reset pin_perst(pin_perst) = pin_perst; input_clock refclk(refclk) = refclk; input_reset refclk_reset() = refclk_reset; /* from clock*/ interface PciewrapApp app; method app_int_ack int_ack() clocked_by(coreclkout.hip); method int_sts(app_int_sts) clocked_by(coreclkout.hip) enable((*inhigh*) EN_app_int_sts); method app_msi_ack msi_ack() clocked_by(coreclkout.hip); method msi_num(app_msi_num) clocked_by(coreclkout.hip) enable((*inhigh*) EN_app_msi_num); method msi_req(app_msi_req) clocked_by(coreclkout.hip) enable((*inhigh*) EN_app_msi_req); method msi_tc(app_msi_tc) clocked_by(coreclkout.hip) enable((*inhigh*) EN_app_msi_tc); endinterface interface PciewrapCfg_par cfg_par; method cfg_par_err err() clocked_by(coreclkout.hip); endinterface interface PciewrapCoreclkout coreclkout; output_clock hip(coreclkout_hip); endinterface interface PciewrapCpl cpl; method err(cpl_err) clocked_by(coreclkout.hip) enable((*inhigh*) EN_cpl_err); method pending(cpl_pending) clocked_by(coreclkout_hip) enable((*inhigh*) EN_cpl_pending); endinterface interface PciewrapCurrent current; method currentspeed speed() clocked_by(coreclkout.hip) reset_by(no_reset); endinterface interface PciewrapDerr derr; method derr_cor_ext_rcv cor_ext_rcv()clocked_by(coreclkout.hip); method derr_cor_ext_rpl cor_ext_rpl()clocked_by(coreclkout.hip); method derr_rpl rpl() clocked_by(coreclkout.hip) reset_by(no_reset); endinterface interface PciewrapDl dl; method dlup up() clocked_by(coreclkout.hip) reset_by(no_reset); method dlup_exit up_exit() clocked_by(coreclkout.hip) reset_by(no_reset); endinterface interface PciewrapEidle eidle; method eidleinfersel0 infersel0(); method eidleinfersel1 infersel1(); method eidleinfersel2 infersel2(); method eidleinfersel3 infersel3(); method eidleinfersel4 infersel4(); method eidleinfersel5 infersel5(); method eidleinfersel6 infersel6(); method eidleinfersel7 infersel7(); endinterface interface PciewrapEv128 ev128; method ev128ns ns()clocked_by(coreclkout.hip); endinterface interface PciewrapEv1 ev1; method ev1us us()clocked_by(coreclkout.hip); endinterface interface PciewrapHotrst hotrst; method hotrst_exit exit() clocked_by(coreclkout.hip) reset_by(no_reset); endinterface interface PciewrapHpg hpg; method ctrler(hpg_ctrler) enable((*inhigh*) EN_hpg_ctrler); endinterface interface PciewrapInt_s int_s; method int_status tatus() clocked_by(coreclkout.hip); endinterface interface PciewrapKo ko; method ko_cpl_spc_data cpl_spc_data()clocked_by(coreclkout.hip); method ko_cpl_spc_header cpl_spc_header()clocked_by(coreclkout.hip); endinterface interface PciewrapL2 l2; method l2_exit exit()clocked_by(coreclkout.hip) reset_by (no_reset); endinterface interface PciewrapLane lane; method lane_act act()clocked_by(coreclkout.hip) reset_by (no_reset); endinterface interface PciewrapLtssm ltssm; method ltssmstate state() clocked_by(coreclkout.hip) reset_by(no_reset); endinterface interface PciewrapPhy phy; method status0(phystatus0) enable((*inhigh*) EN_phystatus0); method status1(phystatus1) enable((*inhigh*) EN_phystatus1); method status2(phystatus2) enable((*inhigh*) EN_phystatus2); method status3(phystatus3) enable((*inhigh*) EN_phystatus3); method status4(phystatus4) enable((*inhigh*) EN_phystatus4); method status5(phystatus5) enable((*inhigh*) EN_phystatus5); method status6(phystatus6) enable((*inhigh*) EN_phystatus6); method status7(phystatus7) enable((*inhigh*) EN_phystatus7); endinterface interface PciewrapPld pld; method clk(pld_clk) enable((*inhigh*) EN_pld_clk); method pld_clk_inuse clk_inuse() clocked_by(coreclkout.hip); method core_ready(pld_core_ready) clocked_by(coreclkout_hip) enable((*inhigh*) EN_pld_core_ready); endinterface interface PciewrapPm pm; method auxpwr(pm_auxpwr) enable((*inhigh*) EN_pm_auxpwr); method data(pm_data) enable((*inhigh*) EN_pm_data); endinterface interface PciewrapPm_e pm_e; method vent(pm_event) enable((*inhigh*) EN_pm_event); endinterface interface PciewrapPme pme; method to_cr(pme_to_cr) enable((*inhigh*) EN_pme_to_cr); method pme_to_sr to_sr(); endinterface interface PciewrapPower power; method powerdown0 down0(); method powerdown1 down1(); method powerdown2 down2(); method powerdown3 down3(); method powerdown4 down4(); method powerdown5 down5(); method powerdown6 down6(); method powerdown7 down7(); endinterface interface PciewrapReconfig reconfig; method reconfig_from_xcvr from_xcvr(); method to_xcvr(reconfig_to_xcvr) enable((*inhigh*) EN_reconfig_to_xcvr); endinterface interface PciewrapReset reset; output_reset status(reset_status); endinterface interface PciewrapRx rx; method in0(rx_in0) enable((*inhigh*) EN_rx_in0); method in1(rx_in1) enable((*inhigh*) EN_rx_in1); method in2(rx_in2) enable((*inhigh*) EN_rx_in2); method in3(rx_in3) enable((*inhigh*) EN_rx_in3); method in4(rx_in4) enable((*inhigh*) EN_rx_in4); method in5(rx_in5) enable((*inhigh*) EN_rx_in5); method in6(rx_in6) enable((*inhigh*) EN_rx_in6); method in7(rx_in7) enable((*inhigh*) EN_rx_in7); method data0(rxdata0) enable((*inhigh*) EN_rxdata0); method data1(rxdata1) enable((*inhigh*) EN_rxdata1); method data2(rxdata2) enable((*inhigh*) EN_rxdata2); method data3(rxdata3) enable((*inhigh*) EN_rxdata3); method data4(rxdata4) enable((*inhigh*) EN_rxdata4); method data5(rxdata5) enable((*inhigh*) EN_rxdata5); method data6(rxdata6) enable((*inhigh*) EN_rxdata6); method data7(rxdata7) enable((*inhigh*) EN_rxdata7); method datak0(rxdatak0) enable((*inhigh*) EN_rxdatak0); method datak1(rxdatak1) enable((*inhigh*) EN_rxdatak1); method datak2(rxdatak2) enable((*inhigh*) EN_rxdatak2); method datak3(rxdatak3) enable((*inhigh*) EN_rxdatak3); method datak4(rxdatak4) enable((*inhigh*) EN_rxdatak4); method datak5(rxdatak5) enable((*inhigh*) EN_rxdatak5); method datak6(rxdatak6) enable((*inhigh*) EN_rxdatak6); method datak7(rxdatak7) enable((*inhigh*) EN_rxdatak7); method elecidle0(rxelecidle0) enable((*inhigh*) EN_rxelecidle0); method elecidle1(rxelecidle1) enable((*inhigh*) EN_rxelecidle1); method elecidle2(rxelecidle2) enable((*inhigh*) EN_rxelecidle2); method elecidle3(rxelecidle3) enable((*inhigh*) EN_rxelecidle3); method elecidle4(rxelecidle4) enable((*inhigh*) EN_rxelecidle4); method elecidle5(rxelecidle5) enable((*inhigh*) EN_rxelecidle5); method elecidle6(rxelecidle6) enable((*inhigh*) EN_rxelecidle6); method elecidle7(rxelecidle7) enable((*inhigh*) EN_rxelecidle7); method rxpolarity0 polarity0(); method rxpolarity1 polarity1(); method rxpolarity2 polarity2(); method rxpolarity3 polarity3(); method rxpolarity4 polarity4(); method rxpolarity5 polarity5(); method rxpolarity6 polarity6(); method rxpolarity7 polarity7(); method status0(rxstatus0) enable((*inhigh*) EN_rxstatus0); method status1(rxstatus1) enable((*inhigh*) EN_rxstatus1); method status2(rxstatus2) enable((*inhigh*) EN_rxstatus2); method status3(rxstatus3) enable((*inhigh*) EN_rxstatus3); method status4(rxstatus4) enable((*inhigh*) EN_rxstatus4); method status5(rxstatus5) enable((*inhigh*) EN_rxstatus5); method status6(rxstatus6) enable((*inhigh*) EN_rxstatus6); method status7(rxstatus7) enable((*inhigh*) EN_rxstatus7); method valid0(rxvalid0) enable((*inhigh*) EN_rxvalid0); method valid1(rxvalid1) enable((*inhigh*) EN_rxvalid1); method valid2(rxvalid2) enable((*inhigh*) EN_rxvalid2); method valid3(rxvalid3) enable((*inhigh*) EN_rxvalid3); method valid4(rxvalid4) enable((*inhigh*) EN_rxvalid4); method valid5(rxvalid5) enable((*inhigh*) EN_rxvalid5); method valid6(rxvalid6) enable((*inhigh*) EN_rxvalid6); method valid7(rxvalid7) enable((*inhigh*) EN_rxvalid7); endinterface interface PciewrapRx_par rx_par; method rx_par_err err()clocked_by(coreclkout.hip); endinterface interface PciewrapRx_st rx_st; method rx_st_bar bar0() clocked_by(coreclkout.hip); method rx_st_be be0() clocked_by(coreclkout.hip); method rx_st_data data0() clocked_by(coreclkout.hip); method rx_st_empty empty0() clocked_by(coreclkout.hip); method rx_st_eop eop0() clocked_by(coreclkout.hip); method rx_st_err err0() clocked_by(coreclkout.hip); method mask0(rx_st_mask) clocked_by(coreclkout.hip) enable((*inhigh*) EN_rx_st_mask); method ready0(rx_st_ready) clocked_by(coreclkout.hip) enable((*inhigh*) EN_rx_st_ready); method rx_st_sop sop0() clocked_by(coreclkout.hip); method rx_st_valid valid0() clocked_by(coreclkout.hip); endinterface interface PciewrapSerdes serdes; method serdes_pll_locked pll_locked()clocked_by(coreclkout_hip); endinterface interface PciewrapSim sim; method sim_ltssmstate ltssmstate(); method sim_pipe_rate pipe_rate(); endinterface interface PciewrapTest test; method in(test_in) enable((*inhigh*) EN_test_in); endinterface interface PciewrapTestin testin; method testin_zero zero(); endinterface interface PciewrapTl tl; method tl_cfg_add cfg_add() clocked_by(coreclkout_hip) reset_by (no_reset); method tl_cfg_ctl cfg_ctl() clocked_by(coreclkout_hip) reset_by (no_reset); method tl_cfg_sts cfg_sts() clocked_by(coreclkout_hip) reset_by (no_reset); endinterface interface PciewrapTx_cred tx_cred; method tx_cred_datafccp datafccp()clocked_by(coreclkout.hip); method tx_cred_datafcnp datafcnp()clocked_by(coreclkout.hip); method tx_cred_datafcp datafcp()clocked_by(coreclkout.hip); method tx_cred_fchipcons fchipcons()clocked_by(coreclkout.hip); method tx_cred_fcinfinite fcinfinite()clocked_by(coreclkout.hip); method tx_cred_hdrfccp hdrfccp()clocked_by(coreclkout.hip); method tx_cred_hdrfcnp hdrfcnp()clocked_by(coreclkout.hip); method tx_cred_hdrfcp hdrfcp()clocked_by(coreclkout.hip); endinterface interface PciewrapTx tx; method tx_out0 out0(); method tx_out1 out1(); method tx_out2 out2(); method tx_out3 out3(); method tx_out4 out4(); method tx_out5 out5(); method tx_out6 out6(); method tx_out7 out7(); method txcompl0 compl0(); method txcompl1 compl1(); method txcompl2 compl2(); method txcompl3 compl3(); method txcompl4 compl4(); method txcompl5 compl5(); method txcompl6 compl6(); method txcompl7 compl7(); method txdata0 data0(); method txdata1 data1(); method txdata2 data2(); method txdata3 data3(); method txdata4 data4(); method txdata5 data5(); method txdata6 data6(); method txdata7 data7(); method txdatak0 datak0(); method txdatak1 datak1(); method txdatak2 datak2(); method txdatak3 datak3(); method txdatak4 datak4(); method txdatak5 datak5(); method txdatak6 datak6(); method txdatak7 datak7(); method txdeemph0 deemph0(); method txdeemph1 deemph1(); method txdeemph2 deemph2(); method txdeemph3 deemph3(); method txdeemph4 deemph4(); method txdeemph5 deemph5(); method txdeemph6 deemph6(); method txdeemph7 deemph7(); method txdetectrx0 detectrx0(); method txdetectrx1 detectrx1(); method txdetectrx2 detectrx2(); method txdetectrx3 detectrx3(); method txdetectrx4 detectrx4(); method txdetectrx5 detectrx5(); method txdetectrx6 detectrx6(); method txdetectrx7 detectrx7(); method txelecidle0 elecidle0(); method txelecidle1 elecidle1(); method txelecidle2 elecidle2(); method txelecidle3 elecidle3(); method txelecidle4 elecidle4(); method txelecidle5 elecidle5(); method txelecidle6 elecidle6(); method txelecidle7 elecidle7(); method txmargin0 margin0(); method txmargin1 margin1(); method txmargin2 margin2(); method txmargin3 margin3(); method txmargin4 margin4(); method txmargin5 margin5(); method txmargin6 margin6(); method txmargin7 margin7(); method txswing0 swing0(); method txswing1 swing1(); method txswing2 swing2(); method txswing3 swing3(); method txswing4 swing4(); method txswing5 swing5(); method txswing6 swing6(); method txswing7 swing7(); endinterface interface PciewrapTx_par tx_par; method tx_par_err err()clocked_by(coreclkout.hip); endinterface interface PciewrapTx_st tx_st; method data0(tx_st_data) clocked_by(coreclkout.hip) enable((*inhigh*) EN_tx_st_data); method empty0(tx_st_empty) clocked_by(coreclkout.hip) enable((*inhigh*) EN_tx_st_empty); method eop0(tx_st_eop) clocked_by(coreclkout.hip) enable((*inhigh*) EN_tx_st_eop); method err0(tx_st_err) clocked_by(coreclkout_hip) enable((*inhigh*) EN_tx_st_err); method tx_st_ready ready0() clocked_by(coreclkout.hip); method sop0(tx_st_sop) clocked_by(coreclkout.hip) enable((*inhigh*) EN_tx_st_sop); method valid0(tx_st_valid) clocked_by(coreclkout.hip) enable((*inhigh*) EN_tx_st_valid); endinterface schedule (app.int_ack, app.int_sts, app.msi_ack, app.msi_num, app.msi_req, app.msi_tc, cfg_par.err, cpl.err, cpl.pending, current.speed, derr.cor_ext_rcv, derr.cor_ext_rpl, derr.rpl, dl.up, dl.up_exit, eidle.infersel0, eidle.infersel1, eidle.infersel2, eidle.infersel3, eidle.infersel4, eidle.infersel5, eidle.infersel6, eidle.infersel7, ev128.ns, ev1.us, hotrst.exit, hpg.ctrler, int_s.tatus, ko.cpl_spc_data, ko.cpl_spc_header, l2.exit, lane.act, ltssm.state, phy.status0, phy.status1, phy.status2, phy.status3, phy.status4, phy.status5, phy.status6, phy.status7, pld.clk, pld.clk_inuse, pld.core_ready, pm.auxpwr, pm.data, pm_e.vent, pme.to_cr, pme.to_sr, power.down0, power.down1, power.down2, power.down3, power.down4, power.down5, power.down6, power.down7, reconfig.from_xcvr, reconfig.to_xcvr, rx.in0, rx.in1, rx.in2, rx.in3, rx.in4, rx.in5, rx.in6, rx.in7, rx_par.err, rx_st.bar0, rx_st.be0, rx_st.data0, rx_st.empty0, rx_st.eop0, rx_st.err0, rx_st.mask0, rx_st.ready0, rx_st.sop0, rx_st.valid0, rx.data0, rx.data1, rx.data2, rx.data3, rx.data4, rx.data5, rx.data6, rx.data7, rx.datak0, rx.datak1, rx.datak2, rx.datak3, rx.datak4, rx.datak5, rx.datak6, rx.datak7, rx.elecidle0, rx.elecidle1, rx.elecidle2, rx.elecidle3, rx.elecidle4, rx.elecidle5, rx.elecidle6, rx.elecidle7, rx.polarity0, rx.polarity1, rx.polarity2, rx.polarity3, rx.polarity4, rx.polarity5, rx.polarity6, rx.polarity7, rx.status0, rx.status1, rx.status2, rx.status3, rx.status4, rx.status5, rx.status6, rx.status7, rx.valid0, rx.valid1, rx.valid2, rx.valid3, rx.valid4, rx.valid5, rx.valid6, rx.valid7, serdes.pll_locked, sim.ltssmstate, sim.pipe_rate, test.in, testin.zero, tl.cfg_add, tl.cfg_ctl, tl.cfg_sts, tx_cred.datafccp, tx_cred.datafcnp, tx_cred.datafcp, tx_cred.fchipcons, tx_cred.fcinfinite, tx_cred.hdrfccp, tx_cred.hdrfcnp, tx_cred.hdrfcp, tx.out0, tx.out1, tx.out2, tx.out3, tx.out4, tx.out5, tx.out6, tx.out7, tx_par.err, tx_st.data0, tx_st.empty0, tx_st.eop0, tx_st.err0, tx_st.ready0, tx_st.sop0, tx_st.valid0, tx.compl0, tx.compl1, tx.compl2, tx.compl3, tx.compl4, tx.compl5, tx.compl6, tx.compl7, tx.data0, tx.data1, tx.data2, tx.data3, tx.data4, tx.data5, tx.data6, tx.data7, tx.datak0, tx.datak1, tx.datak2, tx.datak3, tx.datak4, tx.datak5, tx.datak6, tx.datak7, tx.deemph0, tx.deemph1, tx.deemph2, tx.deemph3, tx.deemph4, tx.deemph5, tx.deemph6, tx.deemph7, tx.detectrx0, tx.detectrx1, tx.detectrx2, tx.detectrx3, tx.detectrx4, tx.detectrx5, tx.detectrx6, tx.detectrx7, tx.elecidle0, tx.elecidle1, tx.elecidle2, tx.elecidle3, tx.elecidle4, tx.elecidle5, tx.elecidle6, tx.elecidle7, tx.margin0, tx.margin1, tx.margin2, tx.margin3, tx.margin4, tx.margin5, tx.margin6, tx.margin7, tx.swing0, tx.swing1, tx.swing2, tx.swing3, tx.swing4, tx.swing5, tx.swing6, tx.swing7) CF (app.int_ack, app.int_sts, app.msi_ack, app.msi_num, app.msi_req, app.msi_tc, cfg_par.err, cpl.err, cpl.pending, current.speed, derr.cor_ext_rcv, derr.cor_ext_rpl, derr.rpl, dl.up, dl.up_exit, eidle.infersel0, eidle.infersel1, eidle.infersel2, eidle.infersel3, eidle.infersel4, eidle.infersel5, eidle.infersel6, eidle.infersel7, ev128.ns, ev1.us, hotrst.exit, hpg.ctrler, int_s.tatus, ko.cpl_spc_data, ko.cpl_spc_header, l2.exit, lane.act, ltssm.state, phy.status0, phy.status1, phy.status2, phy.status3, phy.status4, phy.status5, phy.status6, phy.status7, pld.clk, pld.clk_inuse, pld.core_ready, pm.auxpwr, pm.data, pm_e.vent, pme.to_cr, pme.to_sr, power.down0, power.down1, power.down2, power.down3, power.down4, power.down5, power.down6, power.down7, reconfig.from_xcvr, reconfig.to_xcvr, rx.in0, rx.in1, rx.in2, rx.in3, rx.in4, rx.in5, rx.in6, rx.in7, rx_par.err, rx_st.bar0, rx_st.be0, rx_st.data0, rx_st.empty0, rx_st.eop0, rx_st.err0, rx_st.mask0, rx_st.ready0, rx_st.sop0, rx_st.valid0, rx.data0, rx.data1, rx.data2, rx.data3, rx.data4, rx.data5, rx.data6, rx.data7, rx.datak0, rx.datak1, rx.datak2, rx.datak3, rx.datak4, rx.datak5, rx.datak6, rx.datak7, rx.elecidle0, rx.elecidle1, rx.elecidle2, rx.elecidle3, rx.elecidle4, rx.elecidle5, rx.elecidle6, rx.elecidle7, rx.polarity0, rx.polarity1, rx.polarity2, rx.polarity3, rx.polarity4, rx.polarity5, rx.polarity6, rx.polarity7, rx.status0, rx.status1, rx.status2, rx.status3, rx.status4, rx.status5, rx.status6, rx.status7, rx.valid0, rx.valid1, rx.valid2, rx.valid3, rx.valid4, rx.valid5, rx.valid6, rx.valid7, serdes.pll_locked, sim.ltssmstate, sim.pipe_rate, test.in, testin.zero, tl.cfg_add, tl.cfg_ctl, tl.cfg_sts, tx_cred.datafccp, tx_cred.datafcnp, tx_cred.datafcp, tx_cred.fchipcons, tx_cred.fcinfinite, tx_cred.hdrfccp, tx_cred.hdrfcnp, tx_cred.hdrfcp, tx.out0, tx.out1, tx.out2, tx.out3, tx.out4, tx.out5, tx.out6, tx.out7, tx_par.err, tx_st.data0, tx_st.empty0, tx_st.eop0, tx_st.err0, tx_st.ready0, tx_st.sop0, tx_st.valid0, tx.compl0, tx.compl1, tx.compl2, tx.compl3, tx.compl4, tx.compl5, tx.compl6, tx.compl7, tx.data0, tx.data1, tx.data2, tx.data3, tx.data4, tx.data5, tx.data6, tx.data7, tx.datak0, tx.datak1, tx.datak2, tx.datak3, tx.datak4, tx.datak5, tx.datak6, tx.datak7, tx.deemph0, tx.deemph1, tx.deemph2, tx.deemph3, tx.deemph4, tx.deemph5, tx.deemph6, tx.deemph7, tx.detectrx0, tx.detectrx1, tx.detectrx2, tx.detectrx3, tx.detectrx4, tx.detectrx5, tx.detectrx6, tx.detectrx7, tx.elecidle0, tx.elecidle1, tx.elecidle2, tx.elecidle3, tx.elecidle4, tx.elecidle5, tx.elecidle6, tx.elecidle7, tx.margin0, tx.margin1, tx.margin2, tx.margin3, tx.margin4, tx.margin5, tx.margin6, tx.margin7, tx.swing0, tx.swing1, tx.swing2, tx.swing3, tx.swing4, tx.swing5, tx.swing6, tx.swing7); endmodule ================================================ FILE: generated/altera/ALTERA_PLL_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_PLL_WRAPPER.bsv -I PciePllWrap -P PciePllWrap -c refclk -r rst -f out -f locked ../../out/de5/synthesis/altera_pll_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface PciepllwrapOut; method Bit#(1) clk_0(); endinterface (* always_ready, always_enabled *) interface PciePllWrap; method Bit#(1) locked(); interface PciepllwrapOut out; endinterface import "BVI" altera_pll_wrapper = module mkPciePllWrap#(Clock refclk, Reset refclk_reset, Reset rst)(PciePllWrap); default_clock clk(); default_reset rst(); input_clock refclk(refclk) = refclk; input_reset refclk_reset() = refclk_reset; /* from clock*/ input_reset reset(rst) = rst; method locked locked(); interface PciepllwrapOut out; method outclk_0 clk_0(); endinterface schedule (locked, out.clk_0) CF (locked, out.clk_0); endmodule ================================================ FILE: generated/altera/ALTERA_XCVR_RECONFIG_WRAPPER.bsv ================================================ /* ./importbvi.py -o ALTERA_XCVR_RECONFIG_WRAPPER.bsv -I XcvrReconfigWrap -P XcvrReconfigWrap -c mgmt_clk_clk -r mgmt_rst_reset -f reconfig_mgmt -f mgmt ../../out/de5/synthesis/alt_xcvr_reconfig_wrapper.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface XcvrreconfigwrapReconfig; method Bit#(1) busy(); method Action from_xcvr(Bit#(460) v); method Bit#(700) to_xcvr(); endinterface (* always_ready, always_enabled *) interface XcvrreconfigwrapReconfig_mgmt; method Action address(Bit#(7) v); method Action read(Bit#(1) v); method Bit#(32) readdata(); method Bit#(1) waitrequest(); method Action write(Bit#(1) v); method Action writedata(Bit#(32) v); endinterface (* always_ready, always_enabled *) interface XcvrReconfigWrap; interface XcvrreconfigwrapReconfig reconfig; interface XcvrreconfigwrapReconfig_mgmt reconfig_mgmt; endinterface import "BVI" alt_xcvr_reconfig_wrapper = module mkXcvrReconfigWrap#(Clock mgmt_clk_clk, Reset mgmt_clk_clk_reset, Reset mgmt_rst_reset)(XcvrReconfigWrap); default_clock clk(); default_reset rst(); input_clock mgmt_clk_clk(mgmt_clk_clk) = mgmt_clk_clk; input_reset mgmt_clk_clk_reset() = mgmt_clk_clk_reset; /* from clock*/ input_reset mgmt_rst_reset(mgmt_rst_reset) = mgmt_rst_reset; interface XcvrreconfigwrapReconfig reconfig; method reconfig_busy busy(); method from_xcvr(reconfig_from_xcvr) enable((*inhigh*) EN_reconfig_from_xcvr); method reconfig_to_xcvr to_xcvr(); endinterface interface XcvrreconfigwrapReconfig_mgmt reconfig_mgmt; method address(reconfig_mgmt_address) enable((*inhigh*) EN_reconfig_mgmt_address); method read(reconfig_mgmt_read) enable((*inhigh*) EN_reconfig_mgmt_read); method reconfig_mgmt_readdata readdata(); method reconfig_mgmt_waitrequest waitrequest(); method write(reconfig_mgmt_write) enable((*inhigh*) EN_reconfig_mgmt_write); method writedata(reconfig_mgmt_writedata) enable((*inhigh*) EN_reconfig_mgmt_writedata); endinterface schedule (reconfig.busy, reconfig.from_xcvr, reconfig.to_xcvr, reconfig_mgmt.address, reconfig_mgmt.read, reconfig_mgmt.readdata, reconfig_mgmt.waitrequest, reconfig_mgmt.write, reconfig_mgmt.writedata) CF (reconfig.busy, reconfig.from_xcvr, reconfig.to_xcvr, reconfig_mgmt.address, reconfig_mgmt.read, reconfig_mgmt.readdata, reconfig_mgmt.waitrequest, reconfig_mgmt.write, reconfig_mgmt.writedata); endmodule ================================================ FILE: generated/cpp/GeneratedTypes.h ================================================ #ifndef __GENERATED_TYPES__ #define __GENERATED_TYPES__ #include "portal.h" #ifdef __cplusplus extern "C" { #endif typedef enum ChannelType { ChannelType_Read, ChannelType_Write } ChannelType; typedef struct DmaDbgRec { uint32_t x : 32; uint32_t y : 32; uint32_t z : 32; uint32_t w : 32; } DmaDbgRec; typedef enum DmaErrorType { DmaErrorNone, DmaErrorSGLIdOutOfRange_r, DmaErrorSGLIdOutOfRange_w, DmaErrorMMUOutOfRange_r, DmaErrorMMUOutOfRange_w, DmaErrorOffsetOutOfRange, DmaErrorSGLIdInvalid, DmaErrorTileTagOutOfRange } DmaErrorType; typedef uint32_t SpecialTypeForSendingFd; typedef enum TileState { Idle, Stopped, Running } TileState; typedef struct TileControl { uint8_t tile : 2; TileState state; } TileControl; typedef enum IfcNames { NoInterface, IfcNames_ReadTestIndicationH2S, IfcNames_MMUIndicationH2S, IfcNames_MemServerIndicationH2S, IfcNames_ReadTestRequestS2H, IfcNames_MMURequestS2H, IfcNames_MemServerRequestS2H } IfcNames; int MemServerRequest_addrTrans ( struct PortalInternal *p, const uint32_t sglId, const uint32_t offset ); int MemServerRequest_setTileState ( struct PortalInternal *p, const TileControl tc ); int MemServerRequest_stateDbg ( struct PortalInternal *p, const ChannelType rc ); int MemServerRequest_memoryTraffic ( struct PortalInternal *p, const ChannelType rc ); enum { CHAN_NUM_MemServerRequest_addrTrans,CHAN_NUM_MemServerRequest_setTileState,CHAN_NUM_MemServerRequest_stateDbg,CHAN_NUM_MemServerRequest_memoryTraffic}; #define MemServerRequest_reqinfo 0x4000c typedef struct { uint32_t sglId; uint32_t offset; } MemServerRequest_addrTransData; typedef struct { TileControl tc; } MemServerRequest_setTileStateData; typedef struct { ChannelType rc; } MemServerRequest_stateDbgData; typedef struct { ChannelType rc; } MemServerRequest_memoryTrafficData; typedef union { MemServerRequest_addrTransData addrTrans; MemServerRequest_setTileStateData setTileState; MemServerRequest_stateDbgData stateDbg; MemServerRequest_memoryTrafficData memoryTraffic; } MemServerRequestData; int MemServerRequest_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); typedef struct { int (*addrTrans) ( struct PortalInternal *p, const uint32_t sglId, const uint32_t offset ); int (*setTileState) ( struct PortalInternal *p, const TileControl tc ); int (*stateDbg) ( struct PortalInternal *p, const ChannelType rc ); int (*memoryTraffic) ( struct PortalInternal *p, const ChannelType rc ); } MemServerRequestCb; extern MemServerRequestCb MemServerRequestProxyReq; int MemServerRequestJson_addrTrans ( struct PortalInternal *p, const uint32_t sglId, const uint32_t offset ); int MemServerRequestJson_setTileState ( struct PortalInternal *p, const TileControl tc ); int MemServerRequestJson_stateDbg ( struct PortalInternal *p, const ChannelType rc ); int MemServerRequestJson_memoryTraffic ( struct PortalInternal *p, const ChannelType rc ); int MemServerRequestJson_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); extern MemServerRequestCb MemServerRequestJsonProxyReq; int MMURequest_sglist ( struct PortalInternal *p, const uint32_t sglId, const uint32_t sglIndex, const uint64_t addr, const uint32_t len ); int MMURequest_region ( struct PortalInternal *p, const uint32_t sglId, const uint64_t barr12, const uint32_t index12, const uint64_t barr8, const uint32_t index8, const uint64_t barr4, const uint32_t index4, const uint64_t barr0, const uint32_t index0 ); int MMURequest_idRequest ( struct PortalInternal *p, const SpecialTypeForSendingFd fd ); int MMURequest_idReturn ( struct PortalInternal *p, const uint32_t sglId ); int MMURequest_setInterface ( struct PortalInternal *p, const uint32_t interfaceId, const uint32_t sglId ); enum { CHAN_NUM_MMURequest_sglist,CHAN_NUM_MMURequest_region,CHAN_NUM_MMURequest_idRequest,CHAN_NUM_MMURequest_idReturn,CHAN_NUM_MMURequest_setInterface}; #define MMURequest_reqinfo 0x5002c typedef struct { uint32_t sglId; uint32_t sglIndex; uint64_t addr; uint32_t len; } MMURequest_sglistData; typedef struct { uint32_t sglId; uint64_t barr12; uint32_t index12; uint64_t barr8; uint32_t index8; uint64_t barr4; uint32_t index4; uint64_t barr0; uint32_t index0; } MMURequest_regionData; typedef struct { SpecialTypeForSendingFd fd; } MMURequest_idRequestData; typedef struct { uint32_t sglId; } MMURequest_idReturnData; typedef struct { uint32_t interfaceId; uint32_t sglId; } MMURequest_setInterfaceData; typedef union { MMURequest_sglistData sglist; MMURequest_regionData region; MMURequest_idRequestData idRequest; MMURequest_idReturnData idReturn; MMURequest_setInterfaceData setInterface; } MMURequestData; int MMURequest_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); typedef struct { int (*sglist) ( struct PortalInternal *p, const uint32_t sglId, const uint32_t sglIndex, const uint64_t addr, const uint32_t len ); int (*region) ( struct PortalInternal *p, const uint32_t sglId, const uint64_t barr12, const uint32_t index12, const uint64_t barr8, const uint32_t index8, const uint64_t barr4, const uint32_t index4, const uint64_t barr0, const uint32_t index0 ); int (*idRequest) ( struct PortalInternal *p, const SpecialTypeForSendingFd fd ); int (*idReturn) ( struct PortalInternal *p, const uint32_t sglId ); int (*setInterface) ( struct PortalInternal *p, const uint32_t interfaceId, const uint32_t sglId ); } MMURequestCb; extern MMURequestCb MMURequestProxyReq; int MMURequestJson_sglist ( struct PortalInternal *p, const uint32_t sglId, const uint32_t sglIndex, const uint64_t addr, const uint32_t len ); int MMURequestJson_region ( struct PortalInternal *p, const uint32_t sglId, const uint64_t barr12, const uint32_t index12, const uint64_t barr8, const uint32_t index8, const uint64_t barr4, const uint32_t index4, const uint64_t barr0, const uint32_t index0 ); int MMURequestJson_idRequest ( struct PortalInternal *p, const SpecialTypeForSendingFd fd ); int MMURequestJson_idReturn ( struct PortalInternal *p, const uint32_t sglId ); int MMURequestJson_setInterface ( struct PortalInternal *p, const uint32_t interfaceId, const uint32_t sglId ); int MMURequestJson_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); extern MMURequestCb MMURequestJsonProxyReq; int MemServerIndication_addrResponse ( struct PortalInternal *p, const uint64_t physAddr ); int MemServerIndication_reportStateDbg ( struct PortalInternal *p, const DmaDbgRec rec ); int MemServerIndication_reportMemoryTraffic ( struct PortalInternal *p, const uint64_t words ); int MemServerIndication_error ( struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ); enum { CHAN_NUM_MemServerIndication_addrResponse,CHAN_NUM_MemServerIndication_reportStateDbg,CHAN_NUM_MemServerIndication_reportMemoryTraffic,CHAN_NUM_MemServerIndication_error}; #define MemServerIndication_reqinfo 0x4001c typedef struct { uint64_t physAddr; } MemServerIndication_addrResponseData; typedef struct { DmaDbgRec rec; } MemServerIndication_reportStateDbgData; typedef struct { uint64_t words; } MemServerIndication_reportMemoryTrafficData; typedef struct { uint32_t code; uint32_t sglId; uint64_t offset; uint64_t extra; } MemServerIndication_errorData; typedef union { MemServerIndication_addrResponseData addrResponse; MemServerIndication_reportStateDbgData reportStateDbg; MemServerIndication_reportMemoryTrafficData reportMemoryTraffic; MemServerIndication_errorData error; } MemServerIndicationData; int MemServerIndication_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); typedef struct { int (*addrResponse) ( struct PortalInternal *p, const uint64_t physAddr ); int (*reportStateDbg) ( struct PortalInternal *p, const DmaDbgRec rec ); int (*reportMemoryTraffic) ( struct PortalInternal *p, const uint64_t words ); int (*error) ( struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ); } MemServerIndicationCb; extern MemServerIndicationCb MemServerIndicationProxyReq; int MemServerIndicationJson_addrResponse ( struct PortalInternal *p, const uint64_t physAddr ); int MemServerIndicationJson_reportStateDbg ( struct PortalInternal *p, const DmaDbgRec rec ); int MemServerIndicationJson_reportMemoryTraffic ( struct PortalInternal *p, const uint64_t words ); int MemServerIndicationJson_error ( struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ); int MemServerIndicationJson_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); extern MemServerIndicationCb MemServerIndicationJsonProxyReq; int MMUIndication_idResponse ( struct PortalInternal *p, const uint32_t sglId ); int MMUIndication_configResp ( struct PortalInternal *p, const uint32_t sglId ); int MMUIndication_error ( struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ); enum { CHAN_NUM_MMUIndication_idResponse,CHAN_NUM_MMUIndication_configResp,CHAN_NUM_MMUIndication_error}; #define MMUIndication_reqinfo 0x3001c typedef struct { uint32_t sglId; } MMUIndication_idResponseData; typedef struct { uint32_t sglId; } MMUIndication_configRespData; typedef struct { uint32_t code; uint32_t sglId; uint64_t offset; uint64_t extra; } MMUIndication_errorData; typedef union { MMUIndication_idResponseData idResponse; MMUIndication_configRespData configResp; MMUIndication_errorData error; } MMUIndicationData; int MMUIndication_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); typedef struct { int (*idResponse) ( struct PortalInternal *p, const uint32_t sglId ); int (*configResp) ( struct PortalInternal *p, const uint32_t sglId ); int (*error) ( struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ); } MMUIndicationCb; extern MMUIndicationCb MMUIndicationProxyReq; int MMUIndicationJson_idResponse ( struct PortalInternal *p, const uint32_t sglId ); int MMUIndicationJson_configResp ( struct PortalInternal *p, const uint32_t sglId ); int MMUIndicationJson_error ( struct PortalInternal *p, const uint32_t code, const uint32_t sglId, const uint64_t offset, const uint64_t extra ); int MMUIndicationJson_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); extern MMUIndicationCb MMUIndicationJsonProxyReq; int ReadTestRequest_startRead ( struct PortalInternal *p, const uint32_t pointer, const uint32_t numBytes, const uint32_t burstLen, const uint32_t iterCnt ); enum { CHAN_NUM_ReadTestRequest_startRead}; #define ReadTestRequest_reqinfo 0x10014 typedef struct { uint32_t pointer; uint32_t numBytes; uint32_t burstLen; uint32_t iterCnt; } ReadTestRequest_startReadData; typedef union { ReadTestRequest_startReadData startRead; } ReadTestRequestData; int ReadTestRequest_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); typedef struct { int (*startRead) ( struct PortalInternal *p, const uint32_t pointer, const uint32_t numBytes, const uint32_t burstLen, const uint32_t iterCnt ); } ReadTestRequestCb; extern ReadTestRequestCb ReadTestRequestProxyReq; int ReadTestRequestJson_startRead ( struct PortalInternal *p, const uint32_t pointer, const uint32_t numBytes, const uint32_t burstLen, const uint32_t iterCnt ); int ReadTestRequestJson_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); extern ReadTestRequestCb ReadTestRequestJsonProxyReq; int ReadTestIndication_readDone ( struct PortalInternal *p, const uint32_t mismatchCount ); enum { CHAN_NUM_ReadTestIndication_readDone}; #define ReadTestIndication_reqinfo 0x10008 typedef struct { uint32_t mismatchCount; } ReadTestIndication_readDoneData; typedef union { ReadTestIndication_readDoneData readDone; } ReadTestIndicationData; int ReadTestIndication_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); typedef struct { int (*readDone) ( struct PortalInternal *p, const uint32_t mismatchCount ); } ReadTestIndicationCb; extern ReadTestIndicationCb ReadTestIndicationProxyReq; int ReadTestIndicationJson_readDone ( struct PortalInternal *p, const uint32_t mismatchCount ); int ReadTestIndicationJson_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd); extern ReadTestIndicationCb ReadTestIndicationJsonProxyReq; #ifdef __cplusplus } #endif #endif //__GENERATED_TYPES__ ================================================ FILE: generated/cpp/MMURequest.c ================================================ #include "GeneratedTypes.h" int MMURequest_sglist ( struct PortalInternal *p, const uint32_t sglId, const uint32_t sglIndex, const uint64_t addr, const uint32_t len ) { volatile unsigned int* temp_working_addr_start = p->transport->mapchannelReq(p, CHAN_NUM_MMURequest_sglist, 6); volatile unsigned int* temp_working_addr = temp_working_addr_start; if (p->transport->busywait(p, CHAN_NUM_MMURequest_sglist, "MMURequest_sglist")) return 1; p->transport->write(p, &temp_working_addr, sglId); p->transport->write(p, &temp_working_addr, sglIndex); p->transport->write(p, &temp_working_addr, (addr>>32)); p->transport->write(p, &temp_working_addr, addr); p->transport->write(p, &temp_working_addr, len); p->transport->send(p, temp_working_addr_start, (CHAN_NUM_MMURequest_sglist << 16) | 6, -1); return 0; }; int MMURequest_region ( struct PortalInternal *p, const uint32_t sglId, const uint64_t barr12, const uint32_t index12, const uint64_t barr8, const uint32_t index8, const uint64_t barr4, const uint32_t index4, const uint64_t barr0, const uint32_t index0 ) { volatile unsigned int* temp_working_addr_start = p->transport->mapchannelReq(p, CHAN_NUM_MMURequest_region, 11); volatile unsigned int* temp_working_addr = temp_working_addr_start; if (p->transport->busywait(p, CHAN_NUM_MMURequest_region, "MMURequest_region")) return 1; p->transport->write(p, &temp_working_addr, sglId); p->transport->write(p, &temp_working_addr, (barr12>>32)); p->transport->write(p, &temp_working_addr, barr12); p->transport->write(p, &temp_working_addr, index12); p->transport->write(p, &temp_working_addr, (barr8>>32)); p->transport->write(p, &temp_working_addr, barr8); p->transport->write(p, &temp_working_addr, index8); p->transport->write(p, &temp_working_addr, (barr4>>32)); p->transport->write(p, &temp_working_addr, barr4); p->transport->write(p, &temp_working_addr, index4); p->transport->write(p, &temp_working_addr, (barr0>>32)); p->transport->write(p, &temp_working_addr, barr0); p->transport->write(p, &temp_working_addr, index0); p->transport->send(p, temp_working_addr_start, (CHAN_NUM_MMURequest_region << 16) | 11, -1); return 0; }; int MMURequest_idRequest ( struct PortalInternal *p, const SpecialTypeForSendingFd fd ) { volatile unsigned int* temp_working_addr_start = p->transport->mapchannelReq(p, CHAN_NUM_MMURequest_idRequest, 2); volatile unsigned int* temp_working_addr = temp_working_addr_start; if (p->transport->busywait(p, CHAN_NUM_MMURequest_idRequest, "MMURequest_idRequest")) return 1; p->transport->writefd(p, &temp_working_addr, fd); p->transport->send(p, temp_working_addr_start, (CHAN_NUM_MMURequest_idRequest << 16) | 2, fd); return 0; }; int MMURequest_idReturn ( struct PortalInternal *p, const uint32_t sglId ) { volatile unsigned int* temp_working_addr_start = p->transport->mapchannelReq(p, CHAN_NUM_MMURequest_idReturn, 2); volatile unsigned int* temp_working_addr = temp_working_addr_start; if (p->transport->busywait(p, CHAN_NUM_MMURequest_idReturn, "MMURequest_idReturn")) return 1; p->transport->write(p, &temp_working_addr, sglId); p->transport->send(p, temp_working_addr_start, (CHAN_NUM_MMURequest_idReturn << 16) | 2, -1); return 0; }; int MMURequest_setInterface ( struct PortalInternal *p, const uint32_t interfaceId, const uint32_t sglId ) { volatile unsigned int* temp_working_addr_start = p->transport->mapchannelReq(p, CHAN_NUM_MMURequest_setInterface, 3); volatile unsigned int* temp_working_addr = temp_working_addr_start; if (p->transport->busywait(p, CHAN_NUM_MMURequest_setInterface, "MMURequest_setInterface")) return 1; p->transport->write(p, &temp_working_addr, interfaceId); p->transport->write(p, &temp_working_addr, sglId); p->transport->send(p, temp_working_addr_start, (CHAN_NUM_MMURequest_setInterface << 16) | 3, -1); return 0; }; MMURequestCb MMURequestProxyReq = { MMURequest_sglist, MMURequest_region, MMURequest_idRequest, MMURequest_idReturn, MMURequest_setInterface, }; int MMURequest_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd) { static int runaway = 0; int tmp __attribute__ ((unused)); int tmpfd __attribute__ ((unused)); MMURequestData tempdata __attribute__ ((unused)); volatile unsigned int* temp_working_addr = p->transport->mapchannelInd(p, channel); switch (channel) { case CHAN_NUM_MMURequest_sglist: { p->transport->recv(p, temp_working_addr, 5, &tmpfd); tmp = p->transport->read(p, &temp_working_addr); tempdata.sglist.sglId = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.sglist.sglIndex = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.sglist.addr = (uint64_t)(((uint64_t)(((tmp)&0xfffffffful))<<32)); tmp = p->transport->read(p, &temp_working_addr); tempdata.sglist.addr |= (uint64_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.sglist.len = (uint32_t)(((tmp)&0xfffffffful));((MMURequestCb *)p->cb)->sglist(p, tempdata.sglist.sglId, tempdata.sglist.sglIndex, tempdata.sglist.addr, tempdata.sglist.len); } break; case CHAN_NUM_MMURequest_region: { p->transport->recv(p, temp_working_addr, 10, &tmpfd); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.sglId = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr12 = (uint64_t)(((uint64_t)(((tmp)&0xfffffffful))<<32)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr12 |= (uint64_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.index12 = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr8 = (uint64_t)(((uint64_t)(((tmp)&0xfffffffful))<<32)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr8 |= (uint64_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.index8 = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr4 = (uint64_t)(((uint64_t)(((tmp)&0xfffffffful))<<32)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr4 |= (uint64_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.index4 = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr0 = (uint64_t)(((uint64_t)(((tmp)&0xfffffffful))<<32)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.barr0 |= (uint64_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.region.index0 = (uint32_t)(((tmp)&0xfffffffful));((MMURequestCb *)p->cb)->region(p, tempdata.region.sglId, tempdata.region.barr12, tempdata.region.index12, tempdata.region.barr8, tempdata.region.index8, tempdata.region.barr4, tempdata.region.index4, tempdata.region.barr0, tempdata.region.index0); } break; case CHAN_NUM_MMURequest_idRequest: { p->transport->recv(p, temp_working_addr, 1, &tmpfd); tmp = p->transport->read(p, &temp_working_addr); tempdata.idRequest.fd = messageFd;((MMURequestCb *)p->cb)->idRequest(p, tempdata.idRequest.fd); } break; case CHAN_NUM_MMURequest_idReturn: { p->transport->recv(p, temp_working_addr, 1, &tmpfd); tmp = p->transport->read(p, &temp_working_addr); tempdata.idReturn.sglId = (uint32_t)(((tmp)&0xfffffffful));((MMURequestCb *)p->cb)->idReturn(p, tempdata.idReturn.sglId); } break; case CHAN_NUM_MMURequest_setInterface: { p->transport->recv(p, temp_working_addr, 2, &tmpfd); tmp = p->transport->read(p, &temp_working_addr); tempdata.setInterface.interfaceId = (uint32_t)(((tmp)&0xfffffffful)); tmp = p->transport->read(p, &temp_working_addr); tempdata.setInterface.sglId = (uint32_t)(((tmp)&0xfffffffful));((MMURequestCb *)p->cb)->setInterface(p, tempdata.setInterface.interfaceId, tempdata.setInterface.sglId); } break; default: PORTAL_PRINTF("MMURequest_handleMessage: unknown channel 0x%x\n", channel); if (runaway++ > 10) { PORTAL_PRINTF("MMURequest_handleMessage: too many bogus indications, exiting\n"); #ifndef __KERNEL__ exit(-1); #endif } return 0; } return 0; } ================================================ FILE: generated/cpp/README ================================================ GeneratedTypes.h and MMURequest.c in this directory are taken from tests/memread_manual/bluesim/jni, without modification. They are only used when compiling dmaSendFd.h for drivers/pcieportal/pcieportal.c and drivers/zynqportal/zynqportal.c ================================================ FILE: generated/scripts/generate_altera_ddrbvi.sh ================================================ # # set -x set -e ./importbvi.py -o ALTERA_DDR3_WRAPPER.bsv -I AvalonDdr3 -P AvalonDdr3 \ -c pll_ref_clk -r global_reset_n -r soft_reset_n -c afi_clk -c afi_half_clk -r afi_reset_n -r afi_reset_export_n \ -f mem -f avl -f local -f oct -f pll \ /home/hwang/dev/connectal/out/de5/synthesis/altera_mem_if_ddr3_emif_wrapper/altera_mem_if_ddr3_emif_wrapper.v ================================================ FILE: generated/scripts/generate_altera_ethbvi.sh ================================================ # # set -x set -e #./importbvi.py -o ALTERA_ETH_PMA_WRAPPER.bsv -I EthXcvrWrap -P EthXcvrWrap \ # -f pll -f tx -f rx -f reconfig \ # ../../out/de5/synthesis/altera_xcvr_native_sv_wrapper.v # #./importbvi.py -o ALTERA_ETH_PMA_RECONFIG_WRAPPER.bsv -I EthXcvrReconfigWrap -P EthXcvrReconfigWrap \ # -c mgmt_clk_clk -r mgmt_rst_reset \ # -f reconfig \ # ../../out/de5/synthesis/altera_xgbe_pma_reconfig_wrapper.v # #./importbvi.py -o ALTERA_ETH_PMA_RESET_CONTROL_WRAPPER.bsv -I EthXcvrResetWrap -P EthXcvrResetWrap \ # -c clock -r reset \ # -f pll -f rx_r -f tx_r -f tx -f rx \ # ../../out/de5/synthesis/altera_xcvr_reset_control_wrapper.v #./importbvi.py -o ALTERA_ETH_10G_PHY.bsv -I Eth10GPhyWrap -P Eth10GPhyWrap \ # -c pll_ref_clk -r phy_mgmt_clk_reset -c phy_mgmt_clk \ # -f phy_mgmt -f tx_r -f rx_r -f tx -f rx -f reconfig \ # ../../out/de5/synthesis/sv_10g_phy/sv_10g_phy.v ./importbvi.py -o ALTERA_ETH_SONIC_PMA.bsv -I EthSonicPmaWrap -P EthSonicPmaWrap \ -c pll_ref_clk -r phy_mgmt_clk_reset -c phy_mgmt_clk \ -f phy_mgmt -f tx_r -f rx_r -f tx -f rx -f reconfig \ ../../verilog/altera/sonic_pma_v1_05.v ================================================ FILE: generated/scripts/generate_altera_macbvi.sh ================================================ # # set -x set -e ./importbvi.py -o ALTERA_MAC_WRAPPER.bsv -I MacWrap -P MacWrap \ -c p0_tx_clk_clk -c p1_tx_clk_clk -c p2_tx_clk_clk -c p3_tx_clk_clk \ -c p0_rx_clk_clk -c p1_rx_clk_clk -c p2_rx_clk_clk -c p3_rx_clk_clk \ -c mgmt_clk_clk \ -r mgmt_reset_reset_n -r jtag_reset_reset \ -r p0_tx_reset_reset_n -r p1_tx_reset_reset_n -r p2_tx_reset_reset_n -r p3_tx_reset_reset_n \ -r p0_rx_reset_reset_n -r p1_rx_reset_reset_n -r p2_rx_reset_reset_n -r p3_rx_reset_reset_n \ -f p0_tx -f p0_rx -f p1_tx -f p1_rx -f p2_tx -f p2_rx -f p3_tx -f p3_rx \ -f p0_xgmii -f p1_xgmii -f p2_xgmii -f p3_xgmii \ -f p0_link_fault -f p1_link_fault -f p2_link_fault -f p3_link_fault \ ../../out/de5/synthesis/altera_mac.v ================================================ FILE: generated/scripts/generate_altera_pciebvi.sh ================================================ # # set -x set -e #./importbvi.py -o ALTERA_PCIE_SV_WRAPPER.bsv -I PcieWrap -P PcieWrap \ # -r pin_perst -r npor -r reset_status \ # -c refclk -c coreclkout_hip \ # -f serdes -f pld -f dl -f ev128 -f ev1 -f hotrst -f l2 -f current \ # -f derr -f lane -f ltssm -f reconfig \ # -f tx_cred -f tx_par -f tx_s -f txd -f txe -f txc -f txm -f txs -f tx\ # -f tx_cred -f rx_par -f rx_s -f rxd -f rxr -f rxe -f rxp -f rxs -f rxv -f rx\ # -f cfg_par \ # -f eidle -f power -f phy \ # -f int_s -f cpl -f tl -f pm_e -f pme -f pm \ # -f simu -f sim \ # -f test_in \ # ../../out/de5/synthesis/altera_pcie_sv_hip_ast_wrapper.v # # #-f rxdata -f rxpolarity -f rxdatak -f rxelecidle -f rxstatus -f rxvalid \ # #-f txdata -f tx_cred -f tx_out -f txcompl -f txdatak -f txdetectrx -f txelecidle -f txdeemph -f txmargin -f txswing \ # #./importbvi.py -o ALTERA_PCIE_RECONFIG_DRIVER_WRAPPER.bsv -I PcieReconfigWrap -P PcieReconfigWrap \ # -c reconfig_xcvr_clk -c pld_clk -r reconfig_xcvr_rst \ # -f reconfig_mgmt -f reconfig_b -f current -f derr -f dlup -f ev128ns -f ev1us -f hotrst \ # -f int_s -f l2 -f lane -f ltssmstate -f dlup -f rx -f tx \ # -f tx -f rx -f cfg -f ko \ # ../../out/de5/synthesis/altera_pcie_reconfig_driver_wrapper.v # #./importbvi.py -o ALTERA_XCVR_RECONFIG_WRAPPER.bsv -I XcvrReconfigWrap -P XcvrReconfigWrap \ # -c mgmt_clk_clk -r mgmt_rst_reset \ # -f reconfig_mgmt -f mgmt \ # ../../out/de5/synthesis/alt_xcvr_reconfig_wrapper.v #./importbvi.py -o ALTERA_PCIE_ED_WRAPPER.bsv -I PcieEdWrap -P PcieEdWrap \ # -c coreclkout_hip -c pld_clk_hip \ # -f serdes -f reset -f pld -f dl -f ev128 -f ev1 -f hotrst -f l2 -f current \ # -f derr -f lane -f ltssm -f reconfig \ # -f int_s -f aer -f pex -f serr -f cpl -f tl -f pm_e -f pme -f pm\ # -f tx_s -f rx_s \ # -f tx_cred \ # -f tx_par -f rx_par -f cfg_par \ # ../../out/de5/synthesis/altera_pcie_hip_ast_ed.v #./importbvi.py -o ALTERA_PLL_WRAPPER.bsv -I PciePllWrap -P PciePllWrap \ # -c refclk -r rst \ # -f out -f locked \ # ../../out/de5/synthesis/altera_pll_wrapper.v ./importbvi.py -o ALTERA_PCIE_SIV_WRAPPER.bsv -I PcieS4Wrap -P PcieS4Wrap \ -r pin_perst -r npor -r reset_status -r pcie_rstn -r srstn \ -c refclk -c core_clk_out -c reconfig_clk -c fixedclk_serdes \ -f app -f pex_msi \ -f cpl \ -f pclk_in \ -f clk250_out \ -f clk500_out \ -f rx_st \ -f tx_st \ -f fixedclk \ -f lmi \ -f tx \ -f rx \ -f phystatus \ -f pipe \ -f pm \ -f pme \ -f reconfig \ -f test \ -f lane \ -f ltssm \ -f powerdown \ -f rate \ -f rc_pll \ -f tl_cfg \ ../../out/htg4/siv_gen2x8/siv_gen2x8_examples/chaining_dma/siv_gen2x8_plus.v ================================================ FILE: generated/scripts/generate_bscane2.sh ================================================ # set -x set -e scripts/importbvi.py -o BscanE2.bsv -C BSCANE2 -I BscanE2 -P PPS7 -c DRCK -c TCK --param=JTAG_CHAIN \ ../../import_components/Xilinx/Vivado/2013.2/data/parts/xilinx/zynq/zynq.lib ================================================ FILE: generated/scripts/generate_bufgcrtl.sh ================================================ # set -x set -e scripts/importbvi.py -o Bufgctrl.bsv -C BUFGCTRL -I Bufgctrl -P Bufgctrl \ -c I0 -c I1 -c O \ ../../import_components/Xilinx/Vivado/2013.2/data/parts/xilinx/zynq/zynq.lib ================================================ FILE: generated/scripts/generate_pcie2wrapper.sh ================================================ # set -x set -e ../scripts/importbvi.py -o PCIEWRAPPER2.bsv -I PcieWrap -P PcieWrap \ -n pl_link_partner_gen2_supported \ -n cfg_mgmt_wr_rw1c_as_rw \ -n pipe_gen3_out \ -n pipe_userclk1_in \ -n pipe_userclk2_in \ -n pl_link_gen2_cap \ -n int_userclk1_out \ -n int_userclk2_out \ -n int_ \ -c int_userclk1_out \ -c int_userclk2_out \ -c int_oobclk_out \ -c int_dclk_out \ -c int_pclk_out_slave \ -c int_pipe_rxuserclk_out \ -c int_qplloutclk_out \ -c int_qplloutrefclk_out \ -c int_rxoutclk_out \ -n user_clk_out \ -n user_reset_out \ -c user_clk_out -r user_reset_out \ -c sys_clk -r sys_rst_n \ -n cfg_dsn -n cfg_dstatus \ -f cfg_aer -f cfg_ds -f cfg_err -f cfg_interrupt \ -f cfg_mgmt -f cfg_msg -f cfg_pmcsr -f cfg_pm \ -f cfg_root_control \ -f pipe -f pl_link -f pci_exp -f pcie_drp \ -p lanes \ ../../out/vc707/pcie2_7x_0/pcie2_7x_0_stub.v # remove junk emitted into "import BVI =" sed -i 's/(pci_exp_txp,//' PCIEWRAPPER2.bsv # move user_clk_out and user_reset_out to top in place of boilerplate default_clock and default_reset sed -i 's/output_clock user_clk_out(user_clk_out);//' PCIEWRAPPER2.bsv sed -i 's/output_reset user_reset_out(user_reset_out);//' PCIEWRAPPER2.bsv sed -i 's/default_clock clk();/output_clock user_clk_out(user_clk_out);/' PCIEWRAPPER2.bsv sed -i 's/default_reset rst();/output_reset user_reset_out(user_reset_out);/' PCIEWRAPPER2.bsv # remove extra reset sed -i 's/Reset sys_clk_reset, //' PCIEWRAPPER2.bsv sed -i 's/input_reset sys_clk_reset() = sys_clk_reset;//' PCIEWRAPPER2.bsv # make sys_clk and sys_rst_n the default sed -i 's/input_clock sys_clk/default_clock sys_clk/' PCIEWRAPPER2.bsv sed -i 's/input_reset sys_rst_n/default_reset sys_rst_n/' PCIEWRAPPER2.bsv # add clocked_by reset_by to methods sed -i 's/method cfg[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method fc[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method m_axis[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method s_axis[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method pl_[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method np_[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method user_[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv sed -i 's/method[^;]*EN_[^;]*/& clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv # fix the double edited lines sed -i 's/clocked_by (user_clk_out) reset_by (user_reset_out) clocked_by (user_clk_out) reset_by (user_reset_out)/clocked_by (user_clk_out) reset_by (user_reset_out)/' PCIEWRAPPER2.bsv # now the pcie clocks sed -i 's/\(method rx[^;]*\)clocked_by[^;]*/\1 clocked_by (sys_clk) reset_by (sys_rst_n)/' PCIEWRAPPER2.bsv sed -i 's/method pci_exp_tx[^;]*/& clocked_by (sys_clk) reset_by (sys_rst_n)/' PCIEWRAPPER2.bsv ================================================ FILE: generated/scripts/generate_pcie3.sh ================================================ # set -x set -e ../scripts/importbvi.py \ -I \ PcieWrap \ -P \ pcieWrap \ -n sys_reset \ -r sys_reset \ -n sys_clk \ -c sys_clk \ -n user_clk \ -c user_clk \ -n user_reset \ -r user_reset \ -n int_dclk_out \ -c int_dclk_out \ -n int_oobclk_out \ -c int_oobclk_out \ -n int_pipe_rxusrclk_out \ -c int_pipe_rxusrclk_out \ -n int_qplloutclk_out \ -c int_qplloutclk_out \ -n int_rxoutclk_out \ -c int_rxoutclk_out \ -n int_userclk1_out \ -n int_userclk2_out \ -c int_userclk1_out \ -c int_userclk2_out \ -n int_pclk_out_slave \ -c int_pclk_out_slave \ -n int_qplloutrefclk_out \ -c int_qplloutrefclk_out \ -f \ common \ -f \ int_qplllock \ -f \ int_pclk_sel \ -f \ pipe_userclk1 \ -f \ pipe_userclk2 \ -f \ cfg_mgmt_type1 \ -f \ cfg_req_pm_transition \ -f \ pci_exp \ -f \ pipe \ -f \ user \ -o \ ../xilinx/PCIEWRAPPER3.bsv \ -p lanes \ ../../out/nfsume/pcie3_7x_0/pcie3_7x_0_stub.v # remove junk emitted into "import BVI =" sed -i 's/(pci_exp_txn,//' ../xilinx/PCIEWRAPPER3.bsv # move user_clk and user_reset to top in place of boilerplate default_clock and default_reset sed -i 's/output_clock user_clk(user_clk);//' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/output_reset user_reset(user_reset);//' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/default_clock clk();/output_clock user_clk(user_clk);/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/default_reset rst();/output_reset user_reset(user_reset);/' ../xilinx/PCIEWRAPPER3.bsv # remove extra reset sed -i 's/Reset sys_clk_reset, //' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/input_reset sys_clk_reset() = sys_clk_reset;//' ../xilinx/PCIEWRAPPER3.bsv # make sys_clk and sys_reset the default sed -i 's/input_clock sys_clk/default_clock sys_clk/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/input_reset sys_reset/default_reset sys_reset/' ../xilinx/PCIEWRAPPER3.bsv # add clocked_by user_clk sed -i 's/method cfg[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method ds[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method m_axis[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method s_axis[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method pcie_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method user_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method[^;]*EN_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv # fix the double edited lines sed -i 's/clocked_by (user_clk) reset_by (user_reset) clocked_by (user_clk) reset_by (user_reset)/clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3.bsv # now the pcie clocks sed -i 's/\(method rx[^;]*\)clocked_by[^;]*/\1 clocked_by (sys_clk) reset_by (sys_reset)/' ../xilinx/PCIEWRAPPER3.bsv sed -i 's/method pci_exp_tx[^;]*/& clocked_by (sys_clk) reset_by (sys_reset)/' ../xilinx/PCIEWRAPPER3.bsv #sed -i 's/PciewrapPci_exp/PciewrapPci_exp#\(numeric type lanes\)/' ../xilinx/PCIEWRAPPER3.bsv ================================================ FILE: generated/scripts/generate_pcie3u.sh ================================================ # set -x set -e ../scripts/importbvi.py \ -I \ PcieWrap \ -P \ pcieWrap \ -n sys_reset \ -r sys_reset \ -n sys_clk \ -c sys_clk \ -c sys_clk_gt \ -n user_clk \ -c user_clk \ -n user_reset \ -r user_reset \ -n int_dclk_out \ -c int_dclk_out \ -n int_oobclk_out \ -c int_oobclk_out \ -n int_pipe_rxusrclk_out \ -c int_pipe_rxusrclk_out \ -n int_qplloutclk_out \ -c int_qplloutclk_out \ -n int_rxoutclk_out \ -c int_rxoutclk_out \ -n int_userclk1_out \ -n int_userclk2_out \ -c int_userclk1_out \ -c int_userclk2_out \ -n int_pclk_out_slave \ -c int_pclk_out_slave \ -n int_qplloutrefclk_out \ -c int_qplloutrefclk_out \ -f \ common \ -f \ int_qpll1 \ -f pcie_perstn1 \ -f pcie_perstn0 \ -f \ int_pclk_sel \ -f \ pipe_userclk1 \ -f \ pipe_userclk2 \ -f \ cfg_mgmt_type1 \ -f \ cfg_req_pm_transition \ -f \ pci_exp \ -f \ pipe \ -f \ user \ -o \ ../xilinx/PCIEWRAPPER3u.bsv \ -p lanes \ ../../out/vcu108/pcie3_ultrascale_0/pcie3_ultrascale_0_stub.v # remove junk emitted into "import BVI =" sed -i 's/(pci_exp_txn,//' ../xilinx/PCIEWRAPPER3u.bsv # move user_clk and user_reset to top in place of boilerplate default_clock and default_reset sed -i 's/output_clock user_clk(user_clk);//' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/output_reset user_reset(user_reset);//' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/default_clock clk();/output_clock user_clk(user_clk);/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/default_reset rst();/output_reset user_reset(user_reset);/' ../xilinx/PCIEWRAPPER3u.bsv # remove extra reset sed -i 's/Reset sys_clk_reset, //' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/input_reset sys_clk_reset() = sys_clk_reset;//' ../xilinx/PCIEWRAPPER3u.bsv # make sys_clk and sys_reset the default sed -i 's/input_clock sys_clk/default_clock sys_clk/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/input_reset sys_reset/default_reset sys_reset/' ../xilinx/PCIEWRAPPER3u.bsv # add clocked_by user_clk sed -i 's/method cfg[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method ds[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method m_axis[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method s_axis[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method pcie_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method user_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method[^;]*EN_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv # fix the double edited lines sed -i 's/clocked_by (user_clk) reset_by (user_reset) clocked_by (user_clk) reset_by (user_reset)/clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3u.bsv # now the pcie clocks sed -i 's/\(method rx[^;]*\)clocked_by[^;]*/\1 clocked_by (sys_clk) reset_by (sys_reset)/' ../xilinx/PCIEWRAPPER3u.bsv sed -i 's/method pci_exp_tx[^;]*/& clocked_by (sys_clk) reset_by (sys_reset)/' ../xilinx/PCIEWRAPPER3u.bsv #sed -i 's/PciewrapPci_exp/PciewrapPci_exp#\(numeric type lanes\)/' ../xilinx/PCIEWRAPPER3u.bsv ================================================ FILE: generated/scripts/generate_pcie3uplus.sh ================================================ # set -x set -e ../scripts/importbvi.py \ -I \ PcieWrap \ -P \ pcieWrap \ -n sys_reset \ -r sys_reset \ -n sys_clk \ -c sys_clk \ -c sys_clk_gt \ -n user_clk \ -c user_clk \ -n user_reset \ -r user_reset \ -n int_dclk_out \ -c int_dclk_out \ -n int_oobclk_out \ -c int_oobclk_out \ -n int_pipe_rxusrclk_out \ -c int_pipe_rxusrclk_out \ -n int_qplloutclk_out \ -c int_qplloutclk_out \ -n int_rxoutclk_out \ -c int_rxoutclk_out \ -n int_userclk1_out \ -n int_userclk2_out \ -c int_userclk1_out \ -c int_userclk2_out \ -n int_pclk_out_slave \ -c int_pclk_out_slave \ -n int_qplloutrefclk_out \ -c int_qplloutrefclk_out \ -f \ common \ -f \ int_qpll1 \ -f pcie_perstn1 \ -f pcie_perstn0 \ -f \ int_pclk_sel \ -f \ pipe_userclk1 \ -f \ pipe_userclk2 \ -f \ cfg_mgmt_type1 \ -f \ cfg_req_pm_transition \ -f \ pci_exp \ -f \ pipe \ -f \ user \ -o \ ../xilinx/PCIEWRAPPER3uplus.bsv \ -p lanes \ ../../out/vcu118/pcie_uscale_plus_0/pcie_uscale_plus_0_stub.v # remove junk emitted into "import BVI =" sed -i 's/(pci_exp_txn,//' ../xilinx/PCIEWRAPPER3uplus.bsv # move user_clk and user_reset to top in place of boilerplate default_clock and default_reset sed -i 's/output_clock user_clk(user_clk);//' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/output_reset user_reset(user_reset);//' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/default_clock clk();/output_clock user_clk(user_clk);/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/default_reset rst();/output_reset user_reset(user_reset);/' ../xilinx/PCIEWRAPPER3uplus.bsv # remove extra reset sed -i 's/Reset sys_clk_reset, //' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/input_reset sys_clk_reset() = sys_clk_reset;//' ../xilinx/PCIEWRAPPER3uplus.bsv # make sys_clk and sys_reset the default sed -i 's/input_clock sys_clk/default_clock sys_clk/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/input_reset sys_reset/default_reset sys_reset/' ../xilinx/PCIEWRAPPER3uplus.bsv # add clocked_by user_clk sed -i 's/method cfg[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method ds[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method m_axis[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method s_axis[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method pcie_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method user_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method[^;]*EN_[^;]*/& clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv # fix the double edited lines sed -i 's/clocked_by (user_clk) reset_by (user_reset) clocked_by (user_clk) reset_by (user_reset)/clocked_by (user_clk) reset_by (user_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv # now the pcie clocks sed -i 's/\(method rx[^;]*\)clocked_by[^;]*/\1 clocked_by (sys_clk) reset_by (sys_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv sed -i 's/method pci_exp_tx[^;]*/& clocked_by (sys_clk) reset_by (sys_reset)/' ../xilinx/PCIEWRAPPER3uplus.bsv #sed -i 's/PciewrapPci_exp/PciewrapPci_exp#\(numeric type lanes\)/' ../xilinx/PCIEWRAPPER3uplus.bsv ================================================ FILE: generated/scripts/generate_pcie_2_1.sh ================================================ # set -x set -e scripts/importbvi.py -o PCIE_2_1.bsv -C PCIE_2_1 -P PCIE -I PcieIf \ -f LL2 -f PL2 -f TL2 -f PLLINK -f DBG -f DRP -f MIM -f PL -f TRN \ -f CFGAER -f CFGCOMMAND -f CFGDEV -f CFGPMR -f CFGDS -f CFGERR \ -f CFGFORCE -f CFGINTERRUPT -f CFGLINK -f CFGMGMT -f CFGMSG \ -f CFGPM -f CFGROOT -f CFGSUBSYS -f CFGTRANS \ -e C_DATA_WIDTH:64 \ -e "CFG_VEND_ID:16'h1BE7" -e "CFG_DEV_ID:16'hB100" -e "CFG_REV_ID:8'h00" \ -e "CFG_SUBSYS_VEND_ID:16'h1BE7" -e "CFG_SUBSYS_ID:16'hA705" \ -e "CLASS_CODE:24'h050000" -e "DSN_CAP_NEXTPTR:12'hffc" \ -e LINK_CAP_ASPM_SUPPORT:0 -e "LINK_CAP_MAX_LINK_WIDTH:6'h8" -e 'LINK_CAP_ASPM_OPTIONALITY:"TRUE"' \ -e 'LL_REPLAY_TIMEOUT_EN:"TRUE"' -e "LL_REPLAY_TIMEOUT:15'h001a" -e "LTSSM_MAX_LINK_WIDTH:6'h8" \ -e "MSIX_CAP_PBA_OFFSET:29'ha00" -e "MSIX_CAP_TABLE_OFFSET:29'h800" \ -e "MSIX_CAP_TABLE_SIZE:11'h003" -e 'MSIX_CAP_ON:"TRUE"' \ -e "PCIE_CAP_NEXTPTR:8'h9C" \ -e PIPE_PIPELINE_STAGES:1 -e PL_FAST_TRAIN:PL_FAST_TRAIN -e USER_CLK_FREQ:3 \ -e BAR0:BAR0 -e BAR1:BAR1 -e BAR2:BAR2 -e BAR3:BAR3 -e BAR4:BAR4 -e BAR5:BAR5 \ ../../import_components/Xilinx/Vivado/2013.2/data/parts/xilinx/zynq/zynq.lib ================================================ FILE: generated/scripts/generate_pciewrapper.sh ================================================ # set -x set -e ../scripts/importbvi.py -o PCIEWRAPPER.bsv -I PcieWrap -P PcieWrap \ -n pl_link_partner_gen2_supported \ -n cfg_mgmt_wr_rw1c_as_rw \ -n pipe_gen3_out \ -n pipe_userclk1_in \ -n pipe_userclk2_in \ -n pl_link_gen2_cap \ -c user_clk_out -r user_reset_out \ -c sys_clk -r sys_rst_n \ -f cfg_aer -f cfg_ds -f cfg_err -f cfg_interrupt \ -f cfg_mgmt -f cfg_msg -f cfg_pmcsr -f cfg_pm \ -f cfg_root_control \ -f pipe -f pl_link -f pci_exp -f pcie_drp \ -p lanes \ ../../out/vc707/pcie_7x_0/synth/pcie_7x_0.v # xilinx/pcie_7x_v2_1/synth/pcie_7x_0.v ================================================ FILE: generated/scripts/generate_pipeclock.sh ================================================ # set -e set -x ./scripts/importbvi.py -o PipeClock.bsv -P pclk -I pclk -p pcie_lane \ xilinx/7x/pcie/source/pcie_7x_0_pipe_clock.v ================================================ FILE: generated/scripts/generate_pps7.sh ================================================ # set -e set -x scripts/importbvi.py -o PPS7.bsv -I PPS7 -P PPS7 \ -p c_emio_gpio_width:gpio_width \ -p c_m_axi_gp0_thread_id_width:id_width \ -p c_m_axi_gp1_thread_id_width:id_width \ -p c_s_axi_gp0_id_width:id_width \ -p c_s_axi_gp1_id_width:id_width \ -p c_s_axi_acp_id_width:id_width \ -p c_s_axi_hp0_id_width:id_width \ -p c_s_axi_hp0_data_width:data_width \ -p c_s_axi_hp1_id_width:id_width \ -p c_s_axi_hp1_data_width:data_width \ -p c_s_axi_hp2_id_width:id_width \ -p c_s_axi_hp2_data_width:data_width \ -p c_s_axi_hp3_id_width:id_width \ -p c_s_axi_hp3_data_width:data_width \ -p c_mio_primitive:mio_width -p c_dm_width -p c_dq_width -p c_dqs_width \ -c M_AXI_GP1_ACLK \ -c M_AXI_GP0_ACLK -c FCLK_CLK0 \ -c S_AXI_GP0_ACLK -c S_AXI_GP1_ACLK \ -c S_AXI_ACP_ACLK \ -c S_AXI_HP0_ACLK -c S_AXI_HP1_ACLK -c S_AXI_HP2_ACLK -c S_AXI_HP3_ACLK \ -d DDR_ARB \ -e C_NUM_F2P_INTR_INPUTS:16 \ -i PS7EXTENDED:Pps7Can:Pps7Core:Pps7Dma:Pps7Enet:Pps7Event:Pps7Fclk_clktrig:Pps7Fpga:Pps7Ftmd:Pps7Ftmt:Pps7Pjtag:Pps7Sdio:Pps7Spi:Pps7Sram:Pps7Trace:Pps7Ttc:Pps7Uart:Pps7Usb:Pps7Wdt \ xilinx.unused/sources/processing_system7/processing_system7.v # -m DDR_DQS:DDR_DQS_p -m DDR_Clk:DDR_Clk_p \ # -c ENET0_GMII_RX_CLK -c ENET0_GMII_TX_CLK \ # -c ENET1_GMII_RX_CLK -c ENET1_GMII_TX_CLK \ # -c SDIO0_CLK -c SDIO0_CLK_FB \ # -c SDIO1_CLK -c SDIO1_CLK_FB \ # -c TTC0_CLK0_IN -c TTC0_CLK1_IN -c TTC0_CLK2_IN \ # -c TTC1_CLK0_IN -c TTC1_CLK1_IN -c TTC1_CLK2_IN \ # -c WDT_CLK_IN \ # -c TRACE_CLK \ # -c DMA0_ACLK -c DMA1_ACLK -c DMA2_ACLK -c DMA3_ACLK \ # -c FCLK_CLK3 -c FCLK_CLK2 -c FCLK_CLK1 \ # -c FTMD_TRACEIN_CLK \ # -c PS_CLK \ ================================================ FILE: generated/scripts/generate_pps7lib.sh ================================================ # set -x set -e scripts/importbvi.py -o PPS7LIB.bsv -C PS7 -I PPS7LIB -P PPS7 \ -f DDR -f FTMT -f FTMD -f IRQ \ -f EMIOGPIO -f EMIOPJTAG -f EMIOTRACE -f EMIOWDT -f EVENT -f PS -f SAXIACP \ -c MAXIGP0ACLK -c MAXIGP1ACLK -c SAXIACPACLK \ -c SAXIGP0ACLK -c SAXIGP1ACLK \ -c SAXIHP0ACLK -c SAXIHP1ACLK -c SAXIHP2ACLK -c SAXIHP3ACLK \ -i PS7EXTENDED:Pps7Emiocan:Pps7Emioenet:Pps7Emiopjtag:Pps7Emiosdio:Pps7Emiospi:Pps7Emiotrace:Pps7Emiottc:Pps7Emiouart:Pps7Emiousb:Pps7Emiowdt:Pps7Dma:Pps7Ftmd:Pps7Ftmt \ --notdef Pps7Maxigp --notdef Pps7Saxigp --notdef Pps7Saxihp --notdef Pps7Saxiacp \ ../../import_components/Xilinx/Vivado/2013.2/data/parts/xilinx/zynq/zynq.lib # -c DMA0ACLK -c DMA1ACLK -c DMA2ACLK -c DMA3ACLK \ # -c EMIOENET0GMIIRXCLK -c EMIOENET0GMIITXCLK \ # -c EMIOENET1GMIIRXCLK -c EMIOENET1GMIITXCLK \ # -c EMIOSDIO0CLKFB -c EMIOSDIO1CLKFB -c EMIOTRACECLK \ ================================================ FILE: generated/scripts/generate_zynq_mpsoc.sh ================================================ # -c pl_clk0 -c pl_clk1 -r pl_resetn0 ../scripts/importbvi.py -c maxihpm0_fpd_aclk -c maxihpm0_fpd_aclk -c saxihpc0_fpd_aclk -c saxiacp_fpd_aclk -c saxi_lpd_aclk -c saxihp0_fpd_aclk -c saxihp1_fpd_aclk -c saxihp2_fpd_aclk -c saxihp3_fpd_aclk -c sacefpd_aclk -c maxihpm0_lpd_aclk -I PS8 -P PS8 -o ZYNQ_ULTRA.bsv ../../out/zcu102/zynq_ultra_ps_e_0/zynq_ultra_ps_e_0_stub.v sed -i 's/zynq_ultra_ps_e_0(maxihpm0_fpd_aclk,/zynq_ultra_ps_e_0/' ZYNQ_ULTRA.bsv sed -i 's/default_clock clk()/default_clock no_clock/' ZYNQ_ULTRA.bsv sed -i 's/default_reset rst()/default_reset no_reset/' ZYNQ_ULTRA.bsv sed -i 's/input_reset.*;//' ZYNQ_ULTRA.bsv sed -i 's/, Reset .*reset//' ZYNQ_ULTRA.bsv ##sed -i 's/method maxigp0[^;]*/& clocked_by (maxihpm0_lpd_aclk) reset_by (no_reset)/' ZYNQ_ULTRA.bsv sed -i 's/method [a-z][^;]*/& clocked_by (maxihpm0_lpd_aclk) reset_by (no_reset)/' ZYNQ_ULTRA.bsv ================================================ FILE: generated/scripts/importbvi.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import copy, json, optparse, os, sys, re, tokenize #names of tokens: tokenize.tok_name masterlist = [] parammap = {} paramnames = [] ifdefmap = {} conditionalcf = {} clock_names = [] deleted_interface = [] commoninterfaces = {} tokgenerator = 0 clock_params = [] reset_params = [] toknum = 0 tokval = 0 modulename = '' class PinType(object): def __init__(self, mode, type, name, origname): self.mode = mode self.type = type self.name = name.lower() self.origname = origname self.comment = '' self.separator = '' #print('PNN', self.mode, self.type, self.name, self.origname) # # parser for .lib files # def parsenext(): global toknum, tokval while True: toknum, tokval, _, _, _ = next(tokgenerator) if toknum != tokenize.NL and toknum != tokenize.NEWLINE: break #print('Token:', toknum, tokval) if toknum == tokenize.ENDMARKER: return None, None return toknum, tokval def validate_token(testval): global toknum, tokval if not testval: print('Error:Got:', toknum, tokval) sys.exit(1) parsenext() def parseparam(): paramstr = '' validate_token(tokval == '(') while tokval != ')' and toknum != tokenize.ENDMARKER: paramstr = paramstr + tokval parsenext() validate_token(tokval == ')') validate_token(tokval == '{') return paramstr def parse_item(): global masterlist, modulename paramlist = {} while tokval != '}' and toknum != tokenize.ENDMARKER: paramname = tokval validate_token(toknum == tokenize.NAME) if paramname == 'default_intrinsic_fall' or paramname == 'default_intrinsic_rise': validate_token(tokval == ':') validate_token(toknum == tokenize.NUMBER) continue if paramname == 'bus_type': validate_token(tokval == ':') validate_token(toknum == tokenize.NAME) continue if tokval == '(': paramlist['attr'] = [] while True: paramstr = parseparam() plist = parse_item() if paramstr != '' and paramname != 'fpga_condition': if plist == {}: paramlist['attr'].append([paramstr]) else: paramlist['attr'].append([paramstr, plist]) if paramname == 'cell' and paramstr == options.cell: #print('CC', paramstr) modulename = paramstr pinlist = {} for item in plist['attr']: tname = item[0] tlist = item[1] tdir = 'unknowndir' if tlist.get('direction'): tdir = tlist['direction'] del tlist['direction'] tsub = '' ind = tname.find('[') if ind > 0: tsub = tname[ind+1:-1] tname = tname[:ind] titem = [tdir, tsub, tlist] ttemp = pinlist.get(tname) if not ttemp: pinlist[tname] = titem elif ttemp[0] != titem[0] or ttemp[2] != titem[2]: print('different', tname, ttemp, titem) elif ttemp[1] != titem[1]: if int(titem[1]) > int(ttemp[1]): ttemp[1] = titem[1] else: print('differentindex', tname, ttemp, titem) for k, v in sorted(pinlist.items()): if v[1] == '': ptemp = 'Bit#(1)' if options.clock and k in options.clock: ptemp = 'Clock' if options.reset and k in options.reset: ptemp = 'Reset' else: ptemp = 'Bit#(' + str(int(v[1])+1) + ')' ttemp = PinType(v[0], ptemp, k, k) if v[2] != {}: ttemp.comment = v[2] masterlist.append(ttemp) paramname = tokval if toknum != tokenize.NAME: break parsenext() if tokval != '(': break else: validate_token(tokval == ':') if paramname not in ['fpga_arc_condition', 'function', 'next_state']: paramlist[paramname] = tokval if toknum == tokenize.NUMBER or toknum == tokenize.NAME or toknum == tokenize.STRING: parsenext() else: validate_token(False) if tokval != '}': validate_token(tokval == ';') validate_token(tokval == '}') if paramlist.get('attr') == []: del paramlist['attr'] return paramlist def parse_lib(filename): global tokgenerator, masterlist tokgenerator = tokenize.generate_tokens(open(filename).readline) parsenext() if tokval != 'library': sys.exit(1) validate_token(toknum == tokenize.NAME) parseparam() parse_item() searchlist = [] for item in masterlist: ind = item.name.find('1') if ind > 0: searchstr = item.name[:ind] #print('II', item.name, searchstr) if searchstr not in searchlist: for iitem in masterlist: #print('VV', iitem.name, searchstr + '0') if iitem.name.startswith(searchstr + '0'): searchlist.append(searchstr) break for item in masterlist: for sitem in searchlist: tname = item.name if tname.startswith(sitem): tname = tname[len(sitem):] ind = 0 while tname[ind] >= '0' and tname[ind] <= '9' and ind < len(tname) - 1: ind = ind + 1 item.name = sitem + tname[:ind] + item.separator + tname[ind:] break # # parser for .v files # def processline(line, phase): global masterlist global paramnames, modulename ind = line.find('//') if ind >= 0: line = line[:ind] line = line.strip().strip(',').strip() ind = line.find('[') if ind >= 0: f = line[ind+1:].split(']') f.insert(0, line[:ind]) subs = f[1].translate(None,' ').lower() if subs[-2:] == ':0': subs = subs[:-2] m = re.match('([^:]+):([^:]+)', subs) if m: i1 = int(m.group(1)) i2 = int(m.group(2)) subs = '%d' % (max(i1,i2) - min(i1,i2) + 1) if subs.find('(') >= 0 and subs[-1] == ')': subs = subs[1:-1] if subs[-2:] == '-1': subs = subs[:-2] else: subs = str(int(subs) + 1) if subs.find('(') >= 0 and subs[-1] == ')': subs = subs[1:-1] ind = subs.find('/') if ind > 0: item = subs[:ind] newitem = parammap.get(item) if newitem: item = newitem subs = 'TDiv#('+item+','+subs[ind+1:]+')' else: newitem = parammap.get(subs) if newitem: subs = newitem f[1] = subs line = f else: line = line.split() f = [] for ind in range(len(line)): item = line[ind].strip() if item[-3:] == 'reg': item = item[:-3].strip() if item != '' and item != 'integer' and item != '=': f.append(item) #print("ARR", f, file=sys.stderr) if len(f) > 0: if f[0][-1] == ';': return True if f[-1][-1] == ';': f[-1] = f[-1][:-1] if f[0] == 'module': modulename = f[1] if f[0] == 'input' or f[0] == 'output' or f[0] == 'inout': if len(f) == 2: f = [f[0], '', '1', f[1]] if len(f) == 3: f = [f[0], '', f[1], f[2]] # check for parameterized declarations pname = f[2].strip('0123456789/') if len(pname) > 0 and pname not in paramnames and pname[:4] != 'TDiv': print('Missing parameter declaration', pname, file=sys.stderr) paramnames.append(pname) f[2] = 'Bit#(' + f[2] + ')' if options.delete and f[3] in options.delete: return False if options.clock and f[3] in options.clock: f[2] = 'Clock' if options.reset and f[3] in options.reset: f[2] = 'Reset' #print('FF', f, file=sys.stderr) elif f[0].startswith('input') or f[0].startswith('output') or f[0].startswith('inout'): if len(f) == 3: f = [f[0].split()[0], f[0].split()[1], f[1], f[2]] # check for parameterized declarations pname = f[2].strip('0123456789/') if len(pname) > 0 and pname not in paramnames and pname[:4] != 'TDiv': print('Missing parameter declaration', pname, file=sys.stderr) paramnames.append(pname) f[2] = 'Bit#(' + f[2] + ')' if options.delete and f[3] in options.delete: return False if options.clock and f[3] in options.clock: f[2] = 'Clock' if options.reset and f[3] in options.reset: f[2] = 'Reset' #print('FE', f, file=sys.stderr) elif phase == 2: return True if phase == 2: itemfound = False for item in masterlist: if item.origname == f[3]: item.mode = f[0] if options.clock and f[3] in options.clock: item.type = 'Clock' elif options.reset and f[3] in options.reset: item.type = 'Reset' else: item.type = f[2] itemfound = True break if not itemfound: print('UNK not found', f) return False if len(f) == 4: #print('FFDDDDD3', f, file=sys.stderr) masterlist.append(PinType(f[0], f[2], f[3], f[3])) elif len(f) == 2: #print('FFDDDDD2', f, file=sys.stderr) masterlist.append(PinType(f[0], '', f[1], f[1])) else: #print('FFDDDDDE', f, file=sys.stderr) masterlist.append(PinType('UNK', 'FOO', f[0], f[0])) return False def parse_verilog(filename): indata = open(filename).read().expandtabs().split('\n') phase = 1 for line in indata: if processline(line, phase): if phase == 2: break phase = 2 def generate_condition(interfacename): global ifdefmap for k, v in ifdefmap.items(): if interfacename in v: print('`ifdef', k, file=options.outfile) return k return None def generate_interface(interfacename, paramlist, paramval, ilist, cname): global clock_names, deleted_interface if interfacename in options.notdef: return cflag = generate_condition(interfacename) print('(* always_ready, always_enabled *)', file=options.outfile) methodfound = False for item in ilist: #print("GG", item.name, item.type, item.mode) if item.mode == 'input' and (item.type != 'Clock' and item.type != 'Reset'): methodfound = True elif item.mode == 'output': methodfound = True elif item.mode == 'inout': methodfound = True elif item.mode == 'interface': methodfound = True if not methodfound: deleted_interface.append(interfacename) return print('interface ' + interfacename + paramlist + ';', file=options.outfile) for item in ilist: if item.mode != 'input' and item.mode != 'output' and item.mode != 'inout' and item.mode != 'interface': continue if item.mode == 'input': if item.type != 'Clock' and item.type != 'Reset': print(' method Action '+item.name+'('+item.type+' v);', file=options.outfile) elif item.mode == 'output': if item.type == 'Clock' and item.type != 'Reset': print(' interface Clock '+item.name+';', file=options.outfile) clock_names.append(item) else: print(' method '+item.type+' '+item.name+'();', file=options.outfile) elif item.mode == 'inout': print(' interface Inout#('+item.type+') '+item.name+';', file=options.outfile) elif item.mode == 'interface' and item.type not in deleted_interface: cflag2 = generate_condition(item.type) print(' interface '+item.type+ paramval +' '+item.name+';', file=options.outfile) if cflag2: print('`endif', file=options.outfile) print('endinterface', file=options.outfile) if cflag: print('`endif', file=options.outfile) def fixname(arg): titem = arg.replace('ZZ', 'ZZA') titem = titem.replace('I2C', 'ZZB') titem = titem.replace('P2F', 'ZZC') titem = titem.replace('F2P', 'ZZD') titem = titem.replace('ev128', 'ZZE') titem = titem.replace('ev1', 'ZZF') titem = titem.replace('l2', 'ZZG') titem = titem.replace('l0', 'ZZH') titem = titem.replace('l1', 'ZZI') return titem def goback(arg): titem = arg.replace('ZZB', 'I2C') titem = titem.replace('ZZC', 'P2F') titem = titem.replace('ZZD', 'F2P') titem = titem.replace('ZZA', 'ZZ') titem = titem.replace('ZZE', 'ev128') titem = titem.replace('ZZF', 'ev1') titem = titem.replace('ZZG', 'l2') titem = titem.replace( 'ZZH','l0') titem = titem.replace( 'ZZI','l1') return titem def regroup_items(masterlist): global paramnames, commoninterfaces paramnames.sort() masterlist = sorted(masterlist, key=lambda item: item.type if item.mode == 'parameter' else item.name) newlist = [] currentgroup = '' prevlist = [] for item in masterlist: if item.mode != 'input' and item.mode != 'output' and item.mode != 'inout': newlist.append(item) #print("DD", item.name) else: litem = item.origname titem = fixname(litem) #m = re.search('(.+?)(\d+)_(.+)', litem) m = re.search('(.+?)(\d+)(_?)(.+)', titem) #print('OA', titem) separator = '_' indexname = '' skipParse = False; if prevlist != [] and not litem.startswith(currentgroup): print('UU', currentgroup, litem, prevlist, file=sys.stderr) if options.factor: for tstring in options.factor: if len(litem) > len(tstring) and litem.startswith(tstring): groupname = tstring fieldname = litem[len(tstring):] if fieldname[0] == '_': fieldname = fieldname[1:] separator = '_' else: separator = '' m = None skipParse = True #print('OM', titem, groupname, fieldname, separator) break if m: skipcheck = False for checkitem in options.notfactor: if litem.startswith(checkitem): skipcheck = True if skipcheck: newlist.append(item) #print('OB', item.name) continue groupname = goback(m.group(1)) indexname = goback(m.group(2)) separator = goback(m.group(3)) fieldname = goback(m.group(4)) #print('OO', item.name, [groupname, indexname, fieldname], file=sys.stderr) elif separator != '' and skipParse != True: m = re.search('(.+?)_(.+)', litem) if not m: newlist.append(item) #print('OD', item.name) continue if len(m.group(1)) == 1: # if only 1 character prefix, get more greedy m = re.search('(.+)_(.+)', litem) #print('OJ', item.name, m.groups(), file=sys.stderr) fieldname = m.group(2) groupname = m.group(1) skipcheck = False for checkitem in options.notfactor: if litem.startswith(checkitem): skipcheck = True if skipcheck: newlist.append(item) #print('OI', item.name, file=sys.stderr) continue itemname = (groupname + indexname).lower() if itemname in ['event']: itemname = itemname + '_' interfacename = options.ifprefix[0].upper() + options.ifprefix[1:].lower() + groupname[0].upper() + groupname[1:].lower() if not commoninterfaces.get(interfacename): commoninterfaces[interfacename] = {} if not commoninterfaces[interfacename].get(indexname): commoninterfaces[interfacename][indexname] = [] t = PinType('interface', interfacename, itemname, groupname+indexname+separator) #print('OZ', interfacename, itemname, groupname+indexname+separator, file=sys.stderr) t.separator = separator newlist.append(t) #print('OH', itemname, separator, file=sys.stderr) foo = copy.copy(item) foo.origname = fieldname lfield = fieldname.lower() if lfield in ['assert', 'do']: lfield = 'zz' + lfield # prefix prohibited names with 'zz' foo.name = lfield commoninterfaces[interfacename][indexname].append(foo) return newlist def generate_inter_declarations(paramlist, paramval): global commoninterfaces for k, v in sorted(commoninterfaces.items()): #print('interface', k, file=sys.stderr) for kuse, vuse in sorted(v.items()): if kuse == '' or kuse == '0': generate_interface(k, paramlist, paramval, vuse, []) #else: #print(' ', kuse, json.dumps(vuse), file=sys.stderr) def locate_clocks(item, prefix): global clock_params, reset_params pname = prefix + item.name if item.mode == 'input': if item.type == 'Clock': clock_params.append(pname.lower()) reset_params.append(pname.lower() + '_reset') if item.type == 'Reset': reset_params.append(pname.lower()) elif item.mode == 'interface': temp = commoninterfaces[item.type].get('0') if not temp: temp = commoninterfaces[item.type].get('') if not temp: print('Missing interface definition', item.type, commoninterfaces[item.type]) return for titem in temp: locate_clocks(titem, item.origname) def generate_clocks(item, indent, prefix): prefname = prefix + item.origname if item.mode == 'input': if item.type == 'Clock': print(indent + 'input_clock '+prefname.lower()+'('+ prefname+') = '+prefname.lower() + ';', file=options.outfile) print(indent + 'input_reset '+prefname.lower()+'_reset() = '+prefname.lower() + '_reset; /* from clock*/', file=options.outfile) if item.type == 'Reset': print(indent + 'input_reset '+prefname.lower()+'('+ prefname +') = '+prefname.lower() + ';', file=options.outfile) elif item.mode == 'interface': temp = commoninterfaces[item.type].get('0') if not temp: temp = commoninterfaces[item.type].get('') if not temp: print('Missing interface clock', item.type, commoninterfaces[item.type]) return for titem in temp: generate_clocks(titem, ' ', item.origname) def generate_instance(item, indent, prefix, clockedby_arg): global deleted_interface methodlist = '' pname = '' if prefix: pname = prefix.lower() if pname[-1] == '_': pname = pname[:-1] pname = pname + '.' if pname == 'event.': pname = 'event_.' prefname = prefix + item.origname if item.mode == 'input': if item.type != 'Clock' and item.type != 'Reset': print(indent + 'method '+item.name.lower()+'('+ prefname +')' + clockedby_arg + ' enable((*inhigh*) EN_'+prefname+');', file=options.outfile) methodlist = methodlist + ', ' + pname + item.name.lower() elif item.mode == 'output': if item.type == 'Clock': print(indent + 'output_clock '+ item.name.lower()+ '(' + prefname+');', file=options.outfile) elif item.type == 'Reset': print(indent + 'output_reset '+ item.name.lower()+ '(' + prefname+');', file=options.outfile) else: print(indent + 'method '+ prefname + ' ' + item.name.lower()+'()' + clockedby_arg + ';', file=options.outfile) methodlist = methodlist + ', ' + pname + item.name.lower() elif item.mode == 'inout': print(indent + 'ifc_inout '+item.name.lower()+'('+ prefname+');', file=options.outfile) elif item.mode == 'interface': if item.type in deleted_interface: return '' cflag = generate_condition(item.type) print(indent + 'interface '+item.type+' '+item.name.lower()+';', file=options.outfile) baseitem = commoninterfaces[item.type].get('0') if not baseitem: baseitem = commoninterfaces[item.type].get('') if not baseitem: print('Missing ifc', item.type) return '' clockedby_name = '' for titem in baseitem: #print("BB", titem.mode, titem.type, titem.name) if titem.mode == 'input' and titem.type == 'Clock': clockedby_name = ' clocked_by (' + (item.origname+titem.name).lower() + ') reset_by (' + (item.origname+titem.name).lower() + '_reset)' templist = '' for titem in baseitem: templist = templist + generate_instance(titem, ' ', item.origname, clockedby_name) if cflag: if not conditionalcf.get(cflag): conditionalcf[cflag] = '' conditionalcf[cflag] = conditionalcf[cflag] + templist else: methodlist = methodlist + templist print(' endinterface', file=options.outfile) if cflag: print('`endif', file=options.outfile) return methodlist def generate_bsv(): global paramnames, modulename, clock_names global clock_params, reset_params, options # generate output file print('\n/*', file=options.outfile) for item in sys.argv: print(' ' + item, file=options.outfile) print('*/\n', file=options.outfile) for item in ['Clocks', 'DefaultValue', 'XilinxCells', 'GetPut', 'AxiBits']: print('import ' + item + '::*;', file=options.outfile) print('', file=options.outfile) paramlist = '' for item in paramnames: paramlist = paramlist + ', numeric type ' + item if paramlist != '': paramlist = '#(' + paramlist[2:] + ')' paramval = paramlist.replace('numeric type ', '') generate_inter_declarations(paramlist, paramval) generate_interface(options.ifname, paramlist, paramval, masterlist, clock_names) print('import "BVI" '+modulename + ' =', file=options.outfile) temp = 'module mk' + options.ifname for item in masterlist: locate_clocks(item, '') if clock_params != [] or reset_params != []: sepstring = '#(' for item in clock_params: temp = temp + sepstring + 'Clock ' + item sepstring = ', ' for item in reset_params: temp = temp + sepstring + 'Reset ' + item temp = temp + ')' temp = temp + '(' + options.ifname + paramval + ');' print(temp, file=options.outfile) for item in paramnames: print(' let ' + item + ' = valueOf(' + item + ');', file=options.outfile) print(' default_clock clk();', file=options.outfile) print(' default_reset rst();', file=options.outfile) #for item in masterlist: # if item.mode == 'parameter': # print(' parameter ' + item.type + ' = ' + item.name + ';', file=options.outfile) if options.export: for item in options.export: colonind = item.find(':') if colonind > 0: print(' parameter ' + item[:colonind] + ' = ' + item[colonind+1:] + ';', file=options.outfile) methodlist = '' for item in masterlist: generate_clocks(item, ' ', '') for item in masterlist: methodlist = methodlist + generate_instance(item, ' ', '', '') if methodlist != '': methodlist = methodlist[2:] if conditionalcf != {}: for k, v in sorted(conditionalcf.items()): mtemp = '(' + methodlist + v + ')' print('`ifdef', k, file=options.outfile) print(' schedule '+mtemp + ' CF ' + mtemp + ';', file=options.outfile) print('`else', file=options.outfile) methodlist = '(' + methodlist + ')' print(' schedule '+methodlist + ' CF ' + methodlist + ';', file=options.outfile) if conditionalcf != {}: print('`endif', file=options.outfile) print('endmodule', file=options.outfile) if __name__=='__main__': parser = optparse.OptionParser("usage: %prog [options] arg") parser.add_option("-o", "--output", dest="filename", help="write data to FILENAME") parser.add_option("-p", "--param", action="append", dest="param") parser.add_option("-f", "--factor", action="append", dest="factor") parser.add_option("-c", "--clock", action="append", dest="clock") parser.add_option("-r", "--reset", action="append", dest="reset") parser.add_option("-d", "--delete", action="append", dest="delete") parser.add_option("-e", "--export", action="append", dest="export") parser.add_option("--notdef", action="append", dest="notdef") parser.add_option("-i", "--ifdef", action="append", dest="ifdef") parser.add_option("-n", "--notfactor", action="append", dest="notfactor") parser.add_option("-C", "--cell", dest="cell") parser.add_option("-P", "--ifprefix", dest="ifprefix") parser.add_option("-I", "--ifname", dest="ifname") (options, args) = parser.parse_args() print('KK', options, args, file=sys.stderr) if options.filename is None or len(args) == 0 or options.ifname is None or options.ifprefix is None: print('Missing "--o" option, missing input filenames, missing ifname or missing ifprefix. Run " importbvi.py -h " to see available options') sys.exit(1) options.outfile = open(options.filename, 'w') if options.notfactor == None: options.notfactor = [] if options.notdef == None: options.notdef = [] if options.param: for item in options.param: item2 = item.split(':') if len(item2) == 1: if item2[0] not in paramnames: paramnames.append(item2[0]) else: parammap[item2[0]] = item2[1] if item2[1] not in paramnames: paramnames.append(item2[1]) if options.ifdef: for item in options.ifdef: item2 = item.split(':') ifdefmap[item2[0]] = item2[1:] print('III', ifdefmap, file=sys.stderr) if len(args) != 1: print("incorrect number of arguments", file=sys.stderr) else: if args[0].endswith('.lib'): parse_lib(args[0]) else: parse_verilog(args[0]) masterlist = regroup_items(masterlist) generate_bsv() ================================================ FILE: gralloc/Android.mk ================================================ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_SHARED_LIBRARIES := libcutils liblog HDMI_SRC_FILES = DmaConfigProxy.cpp DmaIndicationWrapper.cpp HdmiDisplayRequestProxy.cpp HdmiDisplayIndicationWrapper.cpp HdmiInternalRequestProxy.cpp HdmiInternalIndicationWrapper.cpp LOCAL_SRC_FILES := \ ../cpp/portal.cpp ../cpp/dmaManager.cpp \ $(addprefix ../examples/hdmidisplay/zedboard/jni/, $(HDMI_SRC_FILES)) \ gralloc.cpp mapper.cpp LOCAL_MODULE_TAGS = optional LOCAL_MODULE := gralloc.portal LOCAL_CFLAGS:= -DZYNQ -DLOG_TAG=\"gralloc\" -I$(LOCAL_PATH)/../cpp -I$(LOCAL_PATH)/../lib/cpp -I$(LOCAL_PATH)/.. -I$(LOCAL_PATH)/../examples/hdmidisplay/zedboard/jni -I$(LOCAL_PATH)/../drivers/zynqportal include $(BUILD_SHARED_LIBRARY) ================================================ FILE: gralloc/Makefile ================================================ ## ## Usage: make BOARD=[zedboard,zc702] ANDROID_TOP=/path/to/android ## all: gralloc.portal.so ../examples/hdmidisplay/$(BOARD)/jni/HdmiDisplayRequestProxy.h: ../lib/bsv/HdmiDisplay.bsv (cd ../examples/hdmidisplay; make gen.$(BOARD) build.$(BOARD)) cp -v ../examples/hdmidisplay/$(BOARD)/bin/*.bin* . gralloc.portal.so: gralloc.cpp mapper.cpp Android.mk ../lib/bsv/HdmiDisplay.bsv ../examples/hdmidisplay/$(BOARD)/jni/HdmiDisplayRequestProxy.h pushd $(ANDROID_TOP); . ./build/envsetup.sh; lunch zedboard-userdebug; popd; TOP=$(ANDROID_TOP) mm showcommands cp -v $(ANDROID_TOP)/out/target/product/zedboard/system/lib/hw/gralloc.portal.so gralloc.portal.so ================================================ FILE: gralloc/README ================================================ To compile the gralloc library: 1. cd (to build this tree, see: https://github.com/cambridgehackers/zynq-android4/wiki/ZynqAndroid4.1 ) 2. set environment variables from that build tree: source ./build/envsetup.sh; lunch zedboard-userdebug 3. cd mm (Note that this will place the resulting library into the android build tree output directory, probably in the file: out/target/product/zedboard/system/lib/hw/gralloc.portal.so ) NOTE: the xilinx GLIBCXX libraries conflict with the gcc system libraries used by the GCC cross compiler (xilinx versions are bad). Because of this, the xilinx 'source xxxx' lines cannot be executed prior to compiling android. ================================================ FILE: gralloc/bitset ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ // bitset stub namespace std { template class bitset { public: bitset() {}; ~bitset() {}; private: char data[(size+7)/8]; }; } ================================================ FILE: gralloc/gr.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef GR_H_ #define GR_H_ #include #ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define # include #else # include #endif #include #include #include #include #include #include /*****************************************************************************/ struct private_module_t; struct private_handle_t; inline size_t roundUpToPageSize(size_t x) { return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); } int mapFrameBufferLocked(struct private_module_t* module); int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd); int mapBuffer(gralloc_module_t const* module, private_handle_t* hnd); /*****************************************************************************/ class Locker { pthread_mutex_t mutex; public: class Autolock { Locker& locker; public: inline Autolock(Locker& locker) : locker(locker) { locker.lock(); } inline ~Autolock() { locker.unlock(); } }; inline Locker() { pthread_mutex_init(&mutex, 0); } inline ~Locker() { pthread_mutex_destroy(&mutex); } inline void lock() { pthread_mutex_lock(&mutex); } inline void unlock() { pthread_mutex_unlock(&mutex); } }; #endif /* GR_H_ */ ================================================ FILE: gralloc/gralloc.cpp ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "gralloc_priv.h" #include "gr.h" #include "MemServerRequest.h" #include "SGListConfigRequest.h" #include "DmaIndication.h" #include "HdmiDisplayRequest.h" #include "HdmiInternalRequest.h" #include "HdmiInternalIndication.h" #include "dmaManager.h" #include "i2chdmi.h" class TestHdmiIndication : public HdmiInternalIndicationWrapper { public: virtual void vsync ( unsigned long long v ) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); } }; /*****************************************************************************/ struct gralloc_context_t { alloc_device_t device; /* our private data here */ volatile int vsync; pthread_mutex_t vsync_lock; pthread_cond_t vsync_cond; PortalPoller *poller; HdmiDisplayRequestProxy *hdmiDisplay; HdmiInternalRequestProxy *hdmiInternal; SGListConfigRequestProxy *dmap; DmaManager *dma; SGListConfigIndication *dmaIndication; unsigned int ref_srcAlloc; uint32_t nextSegmentNumber; }; static gralloc_context_t *gralloc_dev = 0; static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, size_t stride, int usage, buffer_handle_t* pHandle); /*****************************************************************************/ int fb_device_open(hw_module_t const* module, const char* name, hw_device_t** device); static int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device); extern int gralloc_lock(gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void** vaddr); extern int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle); extern int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle); extern int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle); /*****************************************************************************/ static struct hw_module_methods_t gralloc_module_methods = { open: gralloc_device_open }; struct private_gralloc_module_t HAL_MODULE_INFO_SYM = { base: { common: { tag: HARDWARE_MODULE_TAG, version_major: 1, version_minor: 0, id: GRALLOC_HARDWARE_MODULE_ID, name: "Graphics Memory Allocator Module", author: "The Android Open Source Project", methods: &gralloc_module_methods, dso: 0, reserved: {0} }, registerBuffer: gralloc_register_buffer, unregisterBuffer: gralloc_unregister_buffer, lock: gralloc_lock, unlock: gralloc_unlock, perform: 0, }, lock: PTHREAD_MUTEX_INITIALIZER, currentBuffer: 0, }; /*****************************************************************************/ static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, size_t stride, int usage, buffer_handle_t* pHandle) { int err = 0; int fd = -1; int segmentNumber = 0; size = roundUpToPageSize(size); struct gralloc_context_t *ctx = reinterpret_cast(dev); if (ctx->hdmiDisplay != 0) { fd = portalAlloc(size, 0); ctx->ref_srcAlloc = ctx->dma->reference(fd); //ptr = portalMmap(fd, size); } if (fd < 0) { ALOGE("couldn't create ashmem (%s)", strerror(-errno)); err = -errno; } if (err == 0) { private_handle_t* hnd = new private_handle_t(fd, size, 0); hnd->stride = stride; gralloc_module_t* module = reinterpret_cast( dev->common.module); hnd->segmentNumber = segmentNumber; err = mapBuffer(module, hnd); if (err == 0) { *pHandle = hnd; } } ALOGE_IF(err, "gralloc failed err=%s", strerror(-err)); return err; } /*****************************************************************************/ static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride) { if (!pHandle || !pStride) return -EINVAL; size_t size, stride; int align = 32; int bpp = 0; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: bpp = 4; break; case HAL_PIXEL_FORMAT_RGB_888: bpp = 3; break; case HAL_PIXEL_FORMAT_RGB_565: bpp = 2; break; default: ALOGE("unknown pixel format %x in gralloc_alloc\n", format); return -EINVAL; } size_t bpr = (w*bpp + (align-1)) & ~(align-1); size = bpr * h; stride = bpr / bpp; int err; err = gralloc_alloc_buffer(dev, size, stride, usage, pHandle); if (err < 0) { return err; } *pStride = stride; return 0; } static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); if (private_handle_t::validate(handle) < 0) return -EINVAL; private_handle_t const* hnd = reinterpret_cast(handle); gralloc_module_t* module = reinterpret_cast(dev->common.module); struct gralloc_context_t *ctx = reinterpret_cast(dev); private_handle_t *private_handle = const_cast(hnd); if (ctx->hdmiDisplay) { ALOGD("freeing portal buffer fd %d\n", private_handle->fd); close(private_handle->fd); } else { ALOGD("freeing ashmem buffer %p\n", private_handle); terminateBuffer(module, private_handle); } close(hnd->fd); delete hnd; return 0; } /*****************************************************************************/ static int gralloc_close(struct hw_device_t *dev) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); gralloc_context_t* ctx = reinterpret_cast(dev); if (ctx) { /* TODO: keep a list of all buffer_handle_t created, and free them * all here. */ free(ctx); } return 0; } static int fb_setSwapInterval(struct framebuffer_device_t* dev, int interval) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); framebuffer_device_t* ctx = (framebuffer_device_t*)dev; if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval) return -EINVAL; // FIXME: implement fb_setSwapInterval return 0; } class GrallocHdmiDisplayIndications : public HdmiInternalIndicationWrapper { virtual void vsync(unsigned long long v) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); if (1) ALOGD("vsync %llx\n", v); pthread_mutex_lock(&gralloc_dev->vsync_lock); gralloc_dev->vsync = 1; pthread_cond_signal(&gralloc_dev->vsync_cond); pthread_mutex_unlock(&gralloc_dev->vsync_lock); } }; static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); if (private_handle_t::validate(buffer) < 0) return -EINVAL; private_handle_t const* hnd = reinterpret_cast(buffer); private_gralloc_module_t* m = reinterpret_cast( dev->common.module); if (gralloc_dev && gralloc_dev->hdmiDisplay) { ALOGD("fb_post segmentNumber=%d\n", hnd->segmentNumber); pthread_mutex_lock(&gralloc_dev->vsync_lock); gralloc_dev->vsync = 0; gralloc_dev->hdmiInternal->waitForVsync(0); gralloc_dev->hdmiDisplay->startFrameBuffer(gralloc_dev->ref_srcAlloc, hnd->size/4); gralloc_dev->hdmiInternal->waitForVsync(0); while (!gralloc_dev->vsync) { pthread_cond_wait(&gralloc_dev->vsync_cond, &gralloc_dev->vsync_lock); } pthread_mutex_unlock(&gralloc_dev->vsync_lock); ALOGD("fb posted\n"); } return 0; } static pthread_t fb_thread; static void *fb_thread_routine(void *data) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); portalExec(0); return data; } static int fb_close(struct hw_device_t *dev) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); pthread_kill(fb_thread, SIGTERM); if (dev) { free(dev); } return 0; } int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); int status = -EINVAL; ALOGD( "gralloc_device_open: name=%s\n", name); init_i2c_hdmi(); if (!strcmp(name, "gpu0")) { gralloc_context_t *dev; dev = (gralloc_context_t*)malloc(sizeof(*dev)); gralloc_dev = dev; /* initialize our state here */ memset(dev, 0, sizeof(*dev)); /* initialize the procs */ dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = 0; dev->device.common.module = const_cast(module); dev->device.common.close = gralloc_close; dev->device.alloc = gralloc_alloc; dev->device.free = gralloc_free; *device = &dev->device.common; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutex_init(&dev->vsync_lock, &attr); pthread_condattr_t condattr; pthread_condattr_init(&condattr); pthread_cond_init(&dev->vsync_cond, &condattr); dev->poller = new PortalPoller(); dev->hdmiDisplay = new HdmiDisplayRequestProxy(IfcNames_HdmiDisplayRequest, dev->poller); dev->hdmiInternal = new HdmiInternalRequestProxy(IfcNames_HdmiInternalRequest, dev->poller); dev->dma = platformInit(); dev->nextSegmentNumber = 0; status = 0; } else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) { alloc_device_t* gralloc_device; status = gralloc_open(module, &gralloc_device); if (status < 0) return status; /* initialize our state here */ framebuffer_device_t *dev = (framebuffer_device_t*)malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); /* initialize the procs */ dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = const_cast(module); dev->common.close = fb_close; dev->setSwapInterval = fb_setSwapInterval; dev->post = fb_post; dev->setUpdateRect = 0; pthread_t thread; pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&thread, &attr, fb_thread_routine, 0); private_gralloc_module_t* m = (private_gralloc_module_t*)module; //status = mapFrameBuffer(m); status = 0; if (status >= 0) { /* This table is from CEA-861-D, Table 2: Video Format Timings */ static struct { int code; int hactive; int vactive; int hblank; int vblank; } screen_types[] = { /* table only contains progressive types */ { 1, 640, 480, 160, 45}, // Weird { 2, 720, 480, 138, 45}, { 3, 720, 480, 138, 45}, { 4, 1280, 720, 370, 30}, { 8, 1440, 240, 276, 22}, { 9, 1440, 240, 276, 22}, {12, 2880, 240, 552, 22}, {13, 2880, 240, 552, 22}, // Weird {14, 1440, 480, 276, 45}, {15, 1440, 480, 276, 45}, // Failed {16, 1920, 1080, 280, 45}, {17, 720, 576, 144, 49}, {18, 720, 576, 144, 49}, {19, 1280, 720, 700, 30}, // Failed {23, 1440, 288, 288, 24}, {24, 1440, 288, 288, 24}, // Weird {27, 2880, 288, 576, 24}, {28, 2880, 288, 576, 24}, {29, 1440, 576, 288, 49}, {30, 1440, 576, 288, 49}, {31, 1920, 1080, 720, 45}, {32, 1920, 1080, 830, 45}, {33, 1920, 1080, 720, 45}, {34, 1920, 1080, 280, 45}, {35, 2880, 480, 552, 45}, {36, 2880, 480, 552, 45}, // Failed {37, 2880, 576, 576, 49}, {38, 2880, 576, 576, 49}, // Failed {41, 1280, 720, 700, 30}, // Failed {42, 720, 576, 144, 49}, {43, 720, 576, 144, 49}, {47, 1280, 720, 370, 30}, // Weird {48, 720, 480, 138, 45}, {49, 720, 480, 138, 45}, {52, 720, 576, 144, 49}, {53, 720, 576, 144, 49}, {56, 720, 480, 138, 45}, {57, 720, 480, 138, 45}, {0, 0, 0, 0, 0}}; int format = HAL_PIXEL_FORMAT_RGBX_8888; unsigned short vsyncwidth = 5; static char screenprop[PROPERTY_VALUE_MAX]; int index = 0; unsigned short nlines = 480; unsigned short npixels = 720; unsigned short lmin = 45; unsigned short pmin = 138; property_get("rw.screencode", screenprop, "2"); int screen_code = atoi(screenprop); while (screen_types[index].code && screen_types[index].code != screen_code) index++; if (screen_types[index].code) { nlines = screen_types[index].vactive; npixels = screen_types[index].hactive; lmin = screen_types[index].vblank; pmin = screen_types[index].hblank; } ALOGD("[%s:%d] code %d: %d x %d blank %d x %d\n", __FUNCTION__, __LINE__, screen_types[index].code, nlines, npixels, lmin, pmin); unsigned short stridebytes = (npixels * 4 + 31) & ~31; const_cast(dev->flags) = 0; const_cast(dev->width) = npixels; const_cast(dev->height) = nlines; const_cast(dev->stride) = stridebytes; const_cast(dev->format) = format; const_cast(dev->xdpi) = 100; const_cast(dev->ydpi) = 100; const_cast(dev->fps) = 60; const_cast(dev->minSwapInterval) = 1; const_cast(dev->maxSwapInterval) = 1; vsyncwidth = 0; gralloc_dev->hdmiInternal->setDeLineCountMinMax (lmin - vsyncwidth, lmin + nlines - vsyncwidth, (lmin + lmin + nlines) / 2 - vsyncwidth); gralloc_dev->hdmiInternal->setDePixelCountMinMax (pmin, pmin + npixels, pmin + npixels / 2); ALOGD("setting clock frequency %ld\n", 60l * (long)(pmin + npixels) * (long)(lmin + nlines)); setClockFrequency(1, 60l * (long)(pmin + npixels) * (long)(lmin + nlines), 0); *device = &dev->common; } } return status; } ================================================ FILE: gralloc/gralloc_priv.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef GRALLOC_PRIV_H_ #define GRALLOC_PRIV_H_ #include #include #include #include #include #include #include #include #include /*****************************************************************************/ struct private_handle_t; struct private_gralloc_module_t { gralloc_module_t base; pthread_mutex_t lock; buffer_handle_t currentBuffer; }; /*****************************************************************************/ #ifdef __cplusplus struct private_handle_t : public native_handle { #else struct private_handle_t { struct native_handle nativeHandle; #endif enum { PRIV_FLAGS_FRAMEBUFFER = 0x00000001 }; // file-descriptors int fd; // ints int magic; int flags; int size; int offset; // FIXME: the attributes below should be out-of-line int base; int pid; int stride; int segmentNumber; #ifdef __cplusplus static const int sNumInts = 6; static const int sNumFds = 1; static const int sMagic = 0x11052012; private_handle_t(int fd, int size, int flags) : fd(fd), magic(sMagic), flags(flags), size(size), offset(0), base(0), pid(getpid()), stride(0), segmentNumber(0) { version = sizeof(native_handle); numInts = sNumInts; numFds = sNumFds; } ~private_handle_t() { magic = 0; } static int validate(const native_handle* h) { const private_handle_t* hnd = (const private_handle_t*)h; if (!h || h->version != sizeof(native_handle) || h->numInts != sNumInts || h->numFds != sNumFds || hnd->magic != sMagic) { ALOGE("invalid gralloc handle (at %p)", h); return -EINVAL; } return 0; } #endif }; #endif /* GRALLOC_PRIV_H_ */ ================================================ FILE: gralloc/mapper.cpp ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "gralloc_priv.h" /* desktop Linux needs a little help with gettid() */ #if defined(ARCH_X86) && !defined(HAVE_ANDROID_OS) #define __KERNEL__ # include pid_t gettid() { return syscall(__NR_gettid);} #undef __KERNEL__ #endif /*****************************************************************************/ static int gralloc_map(gralloc_module_t const* module, buffer_handle_t handle, void** vaddr) { private_handle_t* hnd = (private_handle_t*)handle; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { size_t size = hnd->size; void* mappedAddress = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0); if (mappedAddress == MAP_FAILED) { ALOGE("Could not mmap %s", strerror(errno)); return -errno; } hnd->base = intptr_t(mappedAddress) + hnd->offset; //ALOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p", // hnd->fd, hnd->offset, hnd->size, mappedAddress); } *vaddr = (void*)hnd->base; return 0; } static int gralloc_unmap(gralloc_module_t const* module, buffer_handle_t handle) { private_handle_t* hnd = (private_handle_t*)handle; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { void* base = (void*)hnd->base; size_t size = hnd->size; //ALOGD("unmapping from %p, size=%d", base, size); if (munmap(base, size) < 0) { ALOGE("Could not unmap %s", strerror(errno)); } } hnd->base = 0; return 0; } /*****************************************************************************/ static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; /*****************************************************************************/ int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle) { if (private_handle_t::validate(handle) < 0) return -EINVAL; // if this handle was created in this process, then we keep it as is. int err = 0; private_handle_t* hnd = (private_handle_t*)handle; if (hnd->pid != getpid()) { void *vaddr; err = gralloc_map(module, handle, &vaddr); } return err; } int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle) { if (private_handle_t::validate(handle) < 0) return -EINVAL; // never unmap buffers that were created in this process private_handle_t* hnd = (private_handle_t*)handle; if (hnd->pid != getpid()) { if (hnd->base) { gralloc_unmap(module, handle); } } return 0; } int mapBuffer(gralloc_module_t const* module, private_handle_t* hnd) { void* vaddr; return gralloc_map(module, hnd, &vaddr); } int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd) { if (hnd->base) { // this buffer was mapped, unmap it now gralloc_unmap(module, hnd); } return 0; } int gralloc_lock(gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void** vaddr) { // this is called when a buffer is being locked for software // access. in thin implementation we have nothing to do since // not synchronization with the h/w is needed. // typically this is used to wait for the h/w to finish with // this buffer if relevant. the data cache may need to be // flushed or invalidated depending on the usage bits and the // hardware. if (private_handle_t::validate(handle) < 0) return -EINVAL; private_handle_t* hnd = (private_handle_t*)handle; *vaddr = (void*)hnd->base; return 0; } int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle) { // we're done with a software buffer. nothing to do in this // implementation. typically this is used to flush the data cache. if (private_handle_t::validate(handle) < 0) return -EINVAL; return 0; } ================================================ FILE: jtag/README ================================================ # On Ubuntu 12.04: wget http://downloads.sourceforge.net/project/openocd/openocd/0.7.0/openocd-0.7.0.tar.bz2 sudo apt-get install libftdi-dev #? libftdipp-dev ./configure --enable-ft2232_libftdi # --enable-verbose --enable-verbose-jtag-io --enable-verbose-usb-io --enable-verbose-usb-comms \ On Mac: port install libftdi0 port install openocd For reference, the test machine has kc705 and zedboard plugged in: 1. lsusb Bus 001 Device 031: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC Bus 001 Device 013: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC 2. djtgcfg enum Found 2 device(s) Device: Zed Product Name: Digilent Zed User Name: Zed Serial Number: 210248446939 Device: JtagSmt1 Product Name: Digilent JTAG-SMT1 User Name: JtagSmt1 Serial Number: 210203339470 3. djtgcfg -d JtagSmt1 init Initializing scan chain... Found Device ID: 43651093 Found 1 device(s): Device 0: UNKNOWN 4. djtgcfg -d Zed init Initializing scan chain... Found Device ID: 03727093 Found Device ID: 4ba00477 Found 2 device(s): Device 0: UNKNOWN Device 1: UNKNOWN # Reference info: # http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,923&Prod=JTAG-SMT1 # http://wiki.analog.com/resources/eval/user-guides/ad-fmcomms1-ebz/quickstart/microblaze_kc705 ================================================ FILE: jtag/bsd/xc7k325t_ffg900.bsd ================================================ -- (c) Copyright 2010 - 2011 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- releated to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitiations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. -- -- BSDL file for device XC7K325T, package FFG900 -- Generated by bsdlnet Version 1.7 -- Generated on Wed Dec 07, 2011 08:15:59 PST -- Generated using schematic at v32_top/xc7k325t/schematic -- Schematic date = 2011-06-29 14:44:39 -- Schematic ICM_VARIANT = 28t_n1 -- Package File date = # Date : 2011-06-01 11:13:48 ------------------------------------------------------------------------ -- Modification History -- | CR # N/A -- | Details - Initial Release ------------------------------------------------------------------------ -- -- For technical support, http://support.xilinx.com -> enter text 'bsdl' -- in the text search box at the left of the page. If none of -- these records resolve your problem you should open a web support case -- or contact our technical support at: -- -- North America 1-800-255-7778 hotline@xilinx.com -- United Kingdom +44 870 7350 610 eurosupport@xilinx.com -- France (33) 1 3463 0100 eurosupport@xilinx.com -- Germany (49) 89 991 54930 eurosupport@xilinx.com -- Japan (81) 3-3297-9163 jhotline@xilinx.com -- -- This BSDL file reflects the pre-configuration JTAG behavior. To reflect -- the post-configuration JTAG behavior (if any), edit this file as described -- below. Many of these changes are demonstrated by commented-out template -- lines preceeding the lines they would replace: -- -- 1. Enable USER instructions as appropriate (see below). -- 2. Set disable result of all pads as configured. -- 3. Set safe state of boundary cells as necessary. -- 4. Rename entity if necessary to avoid name collisions. -- 5. Modify USERCODE value in USERCODE_REGISTER declaration. -- -- To prevent losing the current configuration, the boundary scan -- test vectors should keep the PROGRAM_B pin high. -- -- PROGRAM_B can only be captured, not updated. The value -- at the pin is always used by the device. -- -- All IOBs prior to configuration, and unused and output-only IOBs following -- configuration, will sense their pad values during boundary-scan with an CMOS -- input buffer. In order to properly capture a logic high value at one -- of these IOBs into its input boundary scan cell, please refer to the -- datasheet and user guide for proper input levels. -- -- For post-configuration boundary scan only: If an IOB is configured to use -- an input standard that uses VREF pins, then the boundary scan test vectors -- must keep the used VREF pins 3-stated. ---------------------------------- -- BSDL File for P1149.6 Standard. ---------------------------------- -- ---------------------------------------------------------------------- -- This BSDL file has been checked and verified by JTAG Technologies B.V. -- on 2011-12-08, for syntactical and semantic compliance with -- IEEE standards 1149.1 and 1149.6 -- using bsdl32.dll 1.6.1.5 - 20110523 Win32 -- copyright (c) 2009 JTAG Technologies B.V., All rights reserved -- ---------------------------------------------------------------------- entity XC7K325T_FFG900 is -- Generic Parameter generic (PHYSICAL_PIN_MAP : string := "FFG900" ); -- Logical Port Description port ( CCLK_B10: inout bit; -- CCLK_0 CFGBVS_L10: in bit; -- CFGBVS_0 DONE_M10: inout bit; -- DONE_0 GND: linkage bit_vector (1 to 173); GNDADC_0: linkage bit; INIT_B_A10: inout bit; -- INIT_B_0 M0_AB5: in bit; -- M0_0 M1_AB2: in bit; -- M1_0 M2_AB1: in bit; -- M2_0 MGTAVCC: linkage bit_vector (1 to 7); MGTAVTT: linkage bit_vector (1 to 18); MGTAVTTRCAL_115: linkage bit; MGTREFCLK0N_115: linkage bit; MGTREFCLK0N_116: linkage bit; MGTREFCLK0N_117: linkage bit; MGTREFCLK0N_118: linkage bit; MGTREFCLK0P_115: linkage bit; MGTREFCLK0P_116: linkage bit; MGTREFCLK0P_117: linkage bit; MGTREFCLK0P_118: linkage bit; MGTREFCLK1N_115: linkage bit; MGTREFCLK1N_116: linkage bit; MGTREFCLK1N_117: linkage bit; MGTREFCLK1N_118: linkage bit; MGTREFCLK1P_115: linkage bit; MGTREFCLK1P_116: linkage bit; MGTREFCLK1P_117: linkage bit; MGTREFCLK1P_118: linkage bit; MGTRREF_115: linkage bit; MGTVCCAUX: linkage bit_vector (1 to 2); MGTXRXN0_115: in bit; MGTXRXN0_116: in bit; MGTXRXN0_117: in bit; MGTXRXN0_118: in bit; MGTXRXN1_115: in bit; MGTXRXN1_116: in bit; MGTXRXN1_117: in bit; MGTXRXN1_118: in bit; MGTXRXN2_115: in bit; MGTXRXN2_116: in bit; MGTXRXN2_117: in bit; MGTXRXN2_118: in bit; MGTXRXN3_115: in bit; MGTXRXN3_116: in bit; MGTXRXN3_117: in bit; MGTXRXN3_118: in bit; MGTXRXP0_115: in bit; MGTXRXP0_116: in bit; MGTXRXP0_117: in bit; MGTXRXP0_118: in bit; MGTXRXP1_115: in bit; MGTXRXP1_116: in bit; MGTXRXP1_117: in bit; MGTXRXP1_118: in bit; MGTXRXP2_115: in bit; MGTXRXP2_116: in bit; MGTXRXP2_117: in bit; MGTXRXP2_118: in bit; MGTXRXP3_115: in bit; MGTXRXP3_116: in bit; MGTXRXP3_117: in bit; MGTXRXP3_118: in bit; MGTXTXN0_115: buffer bit; MGTXTXN0_116: buffer bit; MGTXTXN0_117: buffer bit; MGTXTXN0_118: buffer bit; MGTXTXN1_115: buffer bit; MGTXTXN1_116: buffer bit; MGTXTXN1_117: buffer bit; MGTXTXN1_118: buffer bit; MGTXTXN2_115: buffer bit; MGTXTXN2_116: buffer bit; MGTXTXN2_117: buffer bit; MGTXTXN2_118: buffer bit; MGTXTXN3_115: buffer bit; MGTXTXN3_116: buffer bit; MGTXTXN3_117: buffer bit; MGTXTXN3_118: buffer bit; MGTXTXP0_115: buffer bit; MGTXTXP0_116: buffer bit; MGTXTXP0_117: buffer bit; MGTXTXP0_118: buffer bit; MGTXTXP1_115: buffer bit; MGTXTXP1_116: buffer bit; MGTXTXP1_117: buffer bit; MGTXTXP1_118: buffer bit; MGTXTXP2_115: buffer bit; MGTXTXP2_116: buffer bit; MGTXTXP2_117: buffer bit; MGTXTXP2_118: buffer bit; MGTXTXP3_115: buffer bit; MGTXTXP3_116: buffer bit; MGTXTXP3_117: buffer bit; MGTXTXP3_118: buffer bit; PROGRAM_B: in bit; -- PROGRAM_B_0 TCK: in bit; -- TCK_0 TDI: in bit; -- TDI_0 TDN_U14: linkage bit; -- DXN_0 TDO: out bit; -- TDO_0 TDP_U15: linkage bit; -- DXP_0 TMS: in bit; -- TMS_0 VCCADC_0: linkage bit; VCCAUX: linkage bit_vector (1 to 8); VCCBATT_0: linkage bit; VCCBRAM: linkage bit_vector (1 to 4); VCCINT: linkage bit_vector (1 to 20); VCCO_0: linkage bit_vector (1 to 2); VCCO_12: linkage bit_vector (1 to 6); VCCO_13: linkage bit_vector (1 to 6); VCCO_14: linkage bit_vector (1 to 6); VCCO_15: linkage bit_vector (1 to 6); VCCO_16: linkage bit_vector (1 to 7); VCCO_17: linkage bit_vector (1 to 7); VCCO_18: linkage bit_vector (1 to 6); VCCO_32: linkage bit_vector (1 to 6); VCCO_33: linkage bit_vector (1 to 6); VCCO_34: linkage bit_vector (1 to 7); VN_T14: linkage bit; -- VN_0 VP_R15: linkage bit; -- VP_0 VREFN_R14: linkage bit; -- VREFN_0 VREFP_T15: linkage bit; -- VREFP_0 IO_A11: inout bit; -- PAD34 IO_A12: inout bit; -- PAD35 IO_A13: inout bit; -- PAD45 IO_A15: inout bit; -- PAD49 IO_A16: inout bit; -- PAD90 IO_A17: inout bit; -- PAD91 IO_A18: inout bit; -- PAD95 IO_A20: inout bit; -- PAD92 IO_A21: inout bit; -- PAD93 IO_A22: inout bit; -- PAD97 IO_A23: inout bit; -- PAD103 IO_A25: inout bit; -- PAD120 IO_A26: inout bit; -- PAD121 IO_A27: inout bit; -- PAD115 IO_A28: inout bit; -- PAD119 IO_A30: inout bit; -- PAD135 IO_B12: inout bit; -- PAD31 IO_B13: inout bit; -- PAD44 IO_B14: inout bit; -- PAD48 IO_B15: inout bit; -- PAD47 IO_B17: inout bit; -- PAD85 IO_B18: inout bit; -- PAD94 IO_B19: inout bit; -- PAD99 IO_B20: inout bit; -- PAD89 IO_B22: inout bit; -- PAD96 IO_B23: inout bit; -- PAD102 IO_B24: inout bit; -- PAD117 IO_B25: inout bit; -- PAD125 IO_B27: inout bit; -- PAD114 IO_B28: inout bit; -- PAD118 IO_B29: inout bit; -- PAD131 IO_B30: inout bit; -- PAD134 IO_C11: inout bit; -- PAD37 IO_C12: inout bit; -- PAD30 IO_C14: inout bit; -- PAD43 IO_C15: inout bit; -- PAD46 IO_C16: inout bit; -- PAD81 IO_C17: inout bit; -- PAD84 IO_C19: inout bit; -- PAD98 IO_C20: inout bit; -- PAD88 IO_C21: inout bit; -- PAD67 IO_C22: inout bit; -- PAD71 IO_C24: inout bit; -- PAD116 IO_C25: inout bit; -- PAD124 IO_C26: inout bit; -- PAD123 IO_C27: inout bit; -- PAD127 IO_C29: inout bit; -- PAD130 IO_C30: inout bit; -- PAD133 IO_D11: inout bit; -- PAD36 IO_D12: inout bit; -- PAD26 IO_D13: inout bit; -- PAD27 IO_D14: inout bit; -- PAD42 IO_D16: inout bit; -- PAD80 IO_D17: inout bit; -- PAD76 IO_D18: inout bit; -- PAD77 IO_D19: inout bit; -- PAD79 IO_D21: inout bit; -- PAD66 IO_D22: inout bit; -- PAD70 IO_D23: inout bit; -- PAD105 IO_D24: inout bit; -- PAD109 IO_D26: inout bit; -- PAD122 IO_D27: inout bit; -- PAD126 IO_D28: inout bit; -- PAD129 IO_D29: inout bit; -- PAD132 IO_E11: inout bit; -- PAD33 IO_E13: inout bit; -- PAD29 IO_E14: inout bit; -- PAD40 IO_E15: inout bit; -- PAD41 IO_E16: inout bit; -- PAD39 IO_E18: inout bit; -- PAD100 IO_E19: inout bit; -- PAD78 IO_E20: inout bit; -- PAD75 IO_E21: inout bit; -- PAD73 IO_E23: inout bit; -- PAD104 IO_E24: inout bit; -- PAD108 IO_E25: inout bit; -- PAD107 IO_E26: inout bit; -- PAD111 IO_E28: inout bit; -- PAD128 IO_E29: inout bit; -- PAD136 IO_E30: inout bit; -- PAD137 IO_F11: inout bit; -- PAD32 IO_F12: inout bit; -- PAD28 IO_F13: inout bit; -- PAD25 IO_F15: inout bit; -- PAD38 IO_F16: inout bit; -- PAD50 IO_F17: inout bit; -- PAD87 IO_F18: inout bit; -- PAD83 IO_F20: inout bit; -- PAD74 IO_F21: inout bit; -- PAD72 IO_F22: inout bit; -- PAD69 IO_F23: inout bit; -- PAD101 IO_F25: inout bit; -- PAD106 IO_F26: inout bit; -- PAD110 IO_F27: inout bit; -- PAD143 IO_F28: inout bit; -- PAD141 IO_F30: inout bit; -- PAD145 IO_G12: inout bit; -- PAD1 IO_G13: inout bit; -- PAD24 IO_G14: inout bit; -- PAD23 IO_G15: inout bit; -- PAD15 IO_G17: inout bit; -- PAD86 IO_G18: inout bit; -- PAD82 IO_G19: inout bit; -- PAD51 IO_G20: inout bit; -- PAD55 IO_G22: inout bit; -- PAD68 IO_G23: inout bit; -- PAD112 IO_G24: inout bit; -- PAD113 IO_G25: inout bit; -- PAD150 IO_G27: inout bit; -- PAD142 IO_G28: inout bit; -- PAD140 IO_G29: inout bit; -- PAD144 IO_G30: inout bit; -- PAD149 IO_H11: inout bit; -- PAD20 IO_H12: inout bit; -- PAD21 IO_H14: inout bit; -- PAD22 IO_H15: inout bit; -- PAD14 IO_H16: inout bit; -- PAD19 IO_H17: inout bit; -- PAD57 IO_H19: inout bit; -- PAD59 IO_H20: inout bit; -- PAD54 IO_H21: inout bit; -- PAD64 IO_H22: inout bit; -- PAD65 IO_H24: inout bit; -- PAD138 IO_H25: inout bit; -- PAD139 IO_H26: inout bit; -- PAD146 IO_H27: inout bit; -- PAD147 IO_H29: inout bit; -- PAD165 IO_H30: inout bit; -- PAD148 IO_J11: inout bit; -- PAD16 IO_J12: inout bit; -- PAD17 IO_J13: inout bit; -- PAD9 IO_J14: inout bit; -- PAD11 IO_J16: inout bit; -- PAD18 IO_J17: inout bit; -- PAD56 IO_J18: inout bit; -- PAD53 IO_J19: inout bit; -- PAD58 IO_J21: inout bit; -- PAD160 IO_J22: inout bit; -- PAD161 IO_J23: inout bit; -- PAD152 IO_J24: inout bit; -- PAD153 IO_J26: inout bit; -- PAD171 IO_J27: inout bit; -- PAD166 IO_J28: inout bit; -- PAD167 IO_J29: inout bit; -- PAD164 IO_K11: inout bit; -- PAD13 IO_K13: inout bit; -- PAD8 IO_K14: inout bit; -- PAD10 IO_K15: inout bit; -- PAD5 IO_K16: inout bit; -- PAD3 IO_K18: inout bit; -- PAD52 IO_K19: inout bit; -- PAD62 IO_K20: inout bit; -- PAD63 IO_K21: inout bit; -- PAD159 IO_K23: inout bit; -- PAD156 IO_K24: inout bit; -- PAD157 IO_K25: inout bit; -- PAD175 IO_K26: inout bit; -- PAD170 IO_K28: inout bit; -- PAD176 IO_K29: inout bit; -- PAD177 IO_K30: inout bit; -- PAD169 IO_L11: inout bit; -- PAD12 IO_L12: inout bit; -- PAD6 IO_L13: inout bit; -- PAD7 IO_L15: inout bit; -- PAD4 IO_L16: inout bit; -- PAD2 IO_L17: inout bit; -- PAD60 IO_L18: inout bit; -- PAD61 IO_L20: inout bit; -- PAD163 IO_L21: inout bit; -- PAD158 IO_L22: inout bit; -- PAD154 IO_L23: inout bit; -- PAD155 IO_L25: inout bit; -- PAD174 IO_L26: inout bit; -- PAD172 IO_L27: inout bit; -- PAD173 IO_L28: inout bit; -- PAD179 IO_L30: inout bit; -- PAD168 IO_M19: inout bit; -- PAD151 IO_M20: inout bit; -- PAD162 IO_M22: inout bit; -- PAD198 IO_M23: inout bit; -- PAD199 IO_M24: inout bit; -- PAD196 IO_M25: inout bit; -- PAD197 IO_M27: inout bit; -- PAD183 IO_M28: inout bit; -- PAD178 IO_M29: inout bit; -- PAD180 IO_M30: inout bit; -- PAD181 IO_N19: inout bit; -- PAD188 IO_N20: inout bit; -- PAD189 IO_N21: inout bit; -- PAD190 IO_N22: inout bit; -- PAD191 IO_N24: inout bit; -- PAD193 IO_N25: inout bit; -- PAD186 IO_N26: inout bit; -- PAD187 IO_N27: inout bit; -- PAD182 IO_N29: inout bit; -- PAD184 IO_N30: inout bit; -- PAD185 IO_P19: inout bit; -- PAD200 IO_P21: inout bit; -- PAD194 IO_P22: inout bit; -- PAD195 IO_P23: inout bit; -- PAD192 IO_P24: inout bit; -- PAD202 IO_P26: inout bit; -- PAD220 IO_P27: inout bit; -- PAD216 IO_P28: inout bit; -- PAD217 IO_P29: inout bit; -- PAD214 IO_R19: inout bit; -- PAD201 IO_R20: inout bit; -- PAD204 IO_R21: inout bit; -- PAD205 IO_R23: inout bit; -- PAD206 IO_R24: inout bit; -- PAD207 IO_R25: inout bit; -- PAD203 IO_R26: inout bit; -- PAD221 IO_R28: inout bit; -- PAD222 IO_R29: inout bit; -- PAD215 IO_R30: inout bit; -- PAD218 IO_T20: inout bit; -- PAD208 IO_T21: inout bit; -- PAD209 IO_T22: inout bit; -- PAD210 IO_T23: inout bit; -- PAD211 IO_T25: inout bit; -- PAD228 IO_T26: inout bit; -- PAD224 IO_T27: inout bit; -- PAD225 IO_T28: inout bit; -- PAD223 IO_T30: inout bit; -- PAD219 IO_U19: inout bit; -- PAD212 IO_U20: inout bit; -- PAD213 IO_U22: inout bit; -- PAD242 IO_U23: inout bit; -- PAD243 IO_U24: inout bit; -- PAD246 IO_U25: inout bit; -- PAD229 IO_U27: inout bit; -- PAD226 IO_U28: inout bit; -- PAD227 IO_U29: inout bit; -- PAD230 IO_U30: inout bit; -- PAD231 IO_V19: inout bit; -- PAD238 IO_V20: inout bit; -- PAD239 IO_V21: inout bit; -- PAD244 IO_V22: inout bit; -- PAD245 IO_V24: inout bit; -- PAD247 IO_V25: inout bit; -- PAD236 IO_V26: inout bit; -- PAD232 IO_V27: inout bit; -- PAD233 IO_V29: inout bit; -- PAD234 IO_V30: inout bit; -- PAD235 IO_W19: inout bit; -- PAD250 IO_W21: inout bit; -- PAD248 IO_W22: inout bit; -- PAD249 IO_W23: inout bit; -- PAD240 IO_W24: inout bit; -- PAD241 IO_W26: inout bit; -- PAD237 IO_W27: inout bit; -- PAD254 IO_W28: inout bit; -- PAD255 IO_W29: inout bit; -- PAD258 IO_Y10: inout bit; -- PAD409 IO_Y11: inout bit; -- PAD408 IO_Y13: inout bit; -- PAD401 IO_Y14: inout bit; -- PAD451 IO_Y15: inout bit; -- PAD499 IO_Y16: inout bit; -- PAD498 IO_Y18: inout bit; -- PAD481 IO_Y19: inout bit; -- PAD480 IO_Y20: inout bit; -- PAD301 IO_Y21: inout bit; -- PAD304 IO_Y23: inout bit; -- PAD302 IO_Y24: inout bit; -- PAD303 IO_Y25: inout bit; -- PAD251 IO_Y26: inout bit; -- PAD252 IO_Y28: inout bit; -- PAD256 IO_Y29: inout bit; -- PAD259 IO_Y30: inout bit; -- PAD266 IO_AA8: inout bit; -- PAD404 IO_AA10: inout bit; -- PAD411 IO_AA11: inout bit; -- PAD410 IO_AA12: inout bit; -- PAD402 IO_AA13: inout bit; -- PAD412 IO_AA15: inout bit; -- PAD490 IO_AA16: inout bit; -- PAD497 IO_AA17: inout bit; -- PAD496 IO_AA18: inout bit; -- PAD482 IO_AA20: inout bit; -- PAD312 IO_AA21: inout bit; -- PAD305 IO_AA22: inout bit; -- PAD308 IO_AA23: inout bit; -- PAD309 IO_AA25: inout bit; -- PAD262 IO_AA26: inout bit; -- PAD253 IO_AA27: inout bit; -- PAD260 IO_AA28: inout bit; -- PAD257 IO_AA30: inout bit; -- PAD267 IO_AB7: inout bit; -- PAD400 IO_AB8: inout bit; -- PAD405 IO_AB9: inout bit; -- PAD406 IO_AB10: inout bit; -- PAD414 IO_AB12: inout bit; -- PAD403 IO_AB13: inout bit; -- PAD413 IO_AB14: inout bit; -- PAD500 IO_AB15: inout bit; -- PAD491 IO_AB17: inout bit; -- PAD486 IO_AB18: inout bit; -- PAD483 IO_AB19: inout bit; -- PAD484 IO_AB20: inout bit; -- PAD313 IO_AB22: inout bit; -- PAD306 IO_AB23: inout bit; -- PAD307 IO_AB24: inout bit; -- PAD314 IO_AB25: inout bit; -- PAD263 IO_AB27: inout bit; -- PAD274 IO_AB28: inout bit; -- PAD261 IO_AB29: inout bit; -- PAD270 IO_AB30: inout bit; -- PAD271 IO_AC1: inout bit; -- PAD355 IO_AC2: inout bit; -- PAD354 IO_AC4: inout bit; -- PAD359 IO_AC5: inout bit; -- PAD358 IO_AC6: inout bit; -- PAD351 IO_AC7: inout bit; -- PAD362 IO_AC9: inout bit; -- PAD407 IO_AC10: inout bit; -- PAD415 IO_AC11: inout bit; -- PAD419 IO_AC12: inout bit; -- PAD418 IO_AC14: inout bit; -- PAD494 IO_AC15: inout bit; -- PAD493 IO_AC16: inout bit; -- PAD492 IO_AC17: inout bit; -- PAD487 IO_AC19: inout bit; -- PAD485 IO_AC20: inout bit; -- PAD310 IO_AC21: inout bit; -- PAD311 IO_AC22: inout bit; -- PAD316 IO_AC24: inout bit; -- PAD318 IO_AC25: inout bit; -- PAD315 IO_AC26: inout bit; -- PAD288 IO_AC27: inout bit; -- PAD275 IO_AC29: inout bit; -- PAD264 IO_AC30: inout bit; -- PAD265 IO_AD1: inout bit; -- PAD357 IO_AD2: inout bit; -- PAD356 IO_AD3: inout bit; -- PAD353 IO_AD4: inout bit; -- PAD352 IO_AD6: inout bit; -- PAD360 IO_AD7: inout bit; -- PAD363 IO_AD8: inout bit; -- PAD416 IO_AD9: inout bit; -- PAD420 IO_AD11: inout bit; -- PAD425 IO_AD12: inout bit; -- PAD424 IO_AD13: inout bit; -- PAD450 IO_AD14: inout bit; -- PAD495 IO_AD16: inout bit; -- PAD479 IO_AD17: inout bit; -- PAD478 IO_AD18: inout bit; -- PAD476 IO_AD19: inout bit; -- PAD470 IO_AD21: inout bit; -- PAD320 IO_AD22: inout bit; -- PAD317 IO_AD23: inout bit; -- PAD324 IO_AD24: inout bit; -- PAD319 IO_AD26: inout bit; -- PAD289 IO_AD27: inout bit; -- PAD272 IO_AD28: inout bit; -- PAD273 IO_AD29: inout bit; -- PAD268 IO_AE1: inout bit; -- PAD366 IO_AE3: inout bit; -- PAD371 IO_AE4: inout bit; -- PAD370 IO_AE5: inout bit; -- PAD372 IO_AE6: inout bit; -- PAD361 IO_AE8: inout bit; -- PAD417 IO_AE9: inout bit; -- PAD421 IO_AE10: inout bit; -- PAD428 IO_AE11: inout bit; -- PAD422 IO_AE13: inout bit; -- PAD438 IO_AE14: inout bit; -- PAD489 IO_AE15: inout bit; -- PAD488 IO_AE16: inout bit; -- PAD462 IO_AE18: inout bit; -- PAD477 IO_AE19: inout bit; -- PAD471 IO_AE20: inout bit; -- PAD350 IO_AE21: inout bit; -- PAD321 IO_AE23: inout bit; -- PAD322 IO_AE24: inout bit; -- PAD325 IO_AE25: inout bit; -- PAD332 IO_AE26: inout bit; -- PAD300 IO_AE28: inout bit; -- PAD278 IO_AE29: inout bit; -- PAD269 IO_AE30: inout bit; -- PAD282 IO_AF1: inout bit; -- PAD367 IO_AF2: inout bit; -- PAD365 IO_AF3: inout bit; -- PAD364 IO_AF5: inout bit; -- PAD373 IO_AF6: inout bit; -- PAD374 IO_AF7: inout bit; -- PAD390 IO_AF8: inout bit; -- PAD388 IO_AF10: inout bit; -- PAD429 IO_AF11: inout bit; -- PAD423 IO_AF12: inout bit; -- PAD446 IO_AF13: inout bit; -- PAD439 IO_AF15: inout bit; -- PAD458 IO_AF16: inout bit; -- PAD463 IO_AF17: inout bit; -- PAD474 IO_AF18: inout bit; -- PAD472 IO_AF20: inout bit; -- PAD338 IO_AF21: inout bit; -- PAD339 IO_AF22: inout bit; -- PAD326 IO_AF23: inout bit; -- PAD323 IO_AF25: inout bit; -- PAD333 IO_AF26: inout bit; -- PAD296 IO_AF27: inout bit; -- PAD297 IO_AF28: inout bit; -- PAD279 IO_AF30: inout bit; -- PAD283 IO_AG2: inout bit; -- PAD380 IO_AG3: inout bit; -- PAD369 IO_AG4: inout bit; -- PAD368 IO_AG5: inout bit; -- PAD375 IO_AG7: inout bit; -- PAD391 IO_AG8: inout bit; -- PAD389 IO_AG9: inout bit; -- PAD432 IO_AG10: inout bit; -- PAD426 IO_AG12: inout bit; -- PAD447 IO_AG13: inout bit; -- PAD448 IO_AG14: inout bit; -- PAD459 IO_AG15: inout bit; -- PAD454 IO_AG17: inout bit; -- PAD475 IO_AG18: inout bit; -- PAD473 IO_AG19: inout bit; -- PAD466 IO_AG20: inout bit; -- PAD344 IO_AG22: inout bit; -- PAD340 IO_AG23: inout bit; -- PAD327 IO_AG24: inout bit; -- PAD328 IO_AG25: inout bit; -- PAD336 IO_AG27: inout bit; -- PAD292 IO_AG28: inout bit; -- PAD293 IO_AG29: inout bit; -- PAD276 IO_AG30: inout bit; -- PAD286 IO_AH1: inout bit; -- PAD381 IO_AH2: inout bit; -- PAD382 IO_AH4: inout bit; -- PAD376 IO_AH5: inout bit; -- PAD379 IO_AH6: inout bit; -- PAD378 IO_AH7: inout bit; -- PAD392 IO_AH9: inout bit; -- PAD433 IO_AH10: inout bit; -- PAD427 IO_AH11: inout bit; -- PAD436 IO_AH12: inout bit; -- PAD449 IO_AH14: inout bit; -- PAD442 IO_AH15: inout bit; -- PAD455 IO_AH16: inout bit; -- PAD456 IO_AH17: inout bit; -- PAD460 IO_AH19: inout bit; -- PAD467 IO_AH20: inout bit; -- PAD345 IO_AH21: inout bit; -- PAD346 IO_AH22: inout bit; -- PAD341 IO_AH24: inout bit; -- PAD329 IO_AH25: inout bit; -- PAD337 IO_AH26: inout bit; -- PAD294 IO_AH27: inout bit; -- PAD295 IO_AH29: inout bit; -- PAD277 IO_AH30: inout bit; -- PAD287 IO_AJ1: inout bit; -- PAD384 IO_AJ2: inout bit; -- PAD383 IO_AJ3: inout bit; -- PAD386 IO_AJ4: inout bit; -- PAD377 IO_AJ6: inout bit; -- PAD394 IO_AJ7: inout bit; -- PAD393 IO_AJ8: inout bit; -- PAD396 IO_AJ9: inout bit; -- PAD430 IO_AJ11: inout bit; -- PAD437 IO_AJ12: inout bit; -- PAD445 IO_AJ13: inout bit; -- PAD444 IO_AJ14: inout bit; -- PAD443 IO_AJ16: inout bit; -- PAD457 IO_AJ17: inout bit; -- PAD461 IO_AJ18: inout bit; -- PAD468 IO_AJ19: inout bit; -- PAD464 IO_AJ21: inout bit; -- PAD347 IO_AJ22: inout bit; -- PAD342 IO_AJ23: inout bit; -- PAD343 IO_AJ24: inout bit; -- PAD330 IO_AJ26: inout bit; -- PAD298 IO_AJ27: inout bit; -- PAD290 IO_AJ28: inout bit; -- PAD284 IO_AJ29: inout bit; -- PAD285 IO_AK1: inout bit; -- PAD385 IO_AK3: inout bit; -- PAD387 IO_AK4: inout bit; -- PAD399 IO_AK5: inout bit; -- PAD398 IO_AK6: inout bit; -- PAD395 IO_AK8: inout bit; -- PAD397 IO_AK9: inout bit; -- PAD431 IO_AK10: inout bit; -- PAD435 IO_AK11: inout bit; -- PAD434 IO_AK13: inout bit; -- PAD441 IO_AK14: inout bit; -- PAD440 IO_AK15: inout bit; -- PAD453 IO_AK16: inout bit; -- PAD452 IO_AK18: inout bit; -- PAD469 IO_AK19: inout bit; -- PAD465 IO_AK20: inout bit; -- PAD348 IO_AK21: inout bit; -- PAD349 IO_AK23: inout bit; -- PAD334 IO_AK24: inout bit; -- PAD335 IO_AK25: inout bit; -- PAD331 IO_AK26: inout bit; -- PAD299 IO_AK28: inout bit; -- PAD291 IO_AK29: inout bit; -- PAD280 IO_AK30: inout bit -- PAD281 ); --end port list -- Use Statements use STD_1149_1_2001.all; use STD_1149_6_2003.all; -- Component Conformance Statement(s) attribute COMPONENT_CONFORMANCE of XC7K325T_FFG900 : entity is "STD_1149_1_2001"; -- Device Package Pin Mappings attribute PIN_MAP of XC7K325T_FFG900 : entity is PHYSICAL_PIN_MAP; constant FFG900: PIN_MAP_STRING:= "CCLK_B10:B10," & "CFGBVS_L10:L10," & "DONE_M10:M10," & "GND:(A1,A2,A5,A6,A9,A14,A24,B4,B8,B9," & "B11,B21,C1,C2,C6,C9,C18,C28,D4,D8," & "D9,D15,D25,E1,E2,E6,E9,E12,E22,F4," & "F8,F9,F19,F29,G1,G2,G6,G9,G16,G26," & "H4,H8,H9,H13,H23,J1,J2,J6,J9,J10," & "J20,J30,K4,K8,K9,K17,K27,L1,L2,L6," & "L9,L14,L24,M4,M8,M9,M12,M14,M16,M18," & "M21,N1,N2,N6,N9,N11,N13,N15,N17,N28," & "P4,P8,P9,P10,P12,P16,P18,P25,R1,R2," & "R6,R9,R11,R13,R17,R22,T4,T8,T10,T12," & "T16,T18,T19,T29,U1,U2,U6,U9,U11,U13," & "U17,U26,V4,V8,V9,V10,V12,V14,V16,V18," & "V23,W1,W2,W6,W9,W11,W13,W15,W17,W20," & "W30,Y3,Y4,Y7,Y8,Y9,Y17,Y27,AA1,AA2," & "AA5,AA6,AA7,AA14,AA24,AB3,AB4,AB11,AB21,AC8," & "AC18,AC28,AD5,AD15,AD25,AE2,AE12,AE22,AF9,AF19," & "AF29,AG6,AG16,AG26,AH3,AH13,AH23,AJ10,AJ20,AJ30," & "AK7,AK17,AK27)," & "GNDADC_0:P14," & "INIT_B_A10:A10," & "M0_AB5:AB5," & "M1_AB2:AB2," & "M2_AB1:AB1," & "MGTAVCC:(B7,D7,F7,H7,K7,M7,P7)," & "MGTAVTT:(B3,C5,D3,E5,F3,G5,H3,J5,K3,L5," & "M3,N5,P3,R5,T3,U5,V3,W5)," & "MGTAVTTRCAL_115:W7," & "MGTREFCLK0N_115:R7," & "MGTREFCLK0N_116:L7," & "MGTREFCLK0N_117:G7," & "MGTREFCLK0N_118:C7," & "MGTREFCLK0P_115:R8," & "MGTREFCLK0P_116:L8," & "MGTREFCLK0P_117:G8," & "MGTREFCLK0P_118:C8," & "MGTREFCLK1N_115:U7," & "MGTREFCLK1N_116:N7," & "MGTREFCLK1N_117:J7," & "MGTREFCLK1N_118:E7," & "MGTREFCLK1P_115:U8," & "MGTREFCLK1P_116:N8," & "MGTREFCLK1P_117:J8," & "MGTREFCLK1P_118:E8," & "MGTRREF_115:W8," & "MGTVCCAUX:(T7,V7)," & "MGTXRXN0_115:AA3," & "MGTXRXN0_116:T5," & "MGTXRXN0_117:K5," & "MGTXRXN0_118:E3," & "MGTXRXN1_115:Y5," & "MGTXRXN1_116:R3," & "MGTXRXN1_117:H5," & "MGTXRXN1_118:D5," & "MGTXRXN2_115:W3," & "MGTXRXN2_116:P5," & "MGTXRXN2_117:G3," & "MGTXRXN2_118:B5," & "MGTXRXN3_115:V5," & "MGTXRXN3_116:M5," & "MGTXRXN3_117:F5," & "MGTXRXN3_118:A7," & "MGTXRXP0_115:AA4," & "MGTXRXP0_116:T6," & "MGTXRXP0_117:K6," & "MGTXRXP0_118:E4," & "MGTXRXP1_115:Y6," & "MGTXRXP1_116:R4," & "MGTXRXP1_117:H6," & "MGTXRXP1_118:D6," & "MGTXRXP2_115:W4," & "MGTXRXP2_116:P6," & "MGTXRXP2_117:G4," & "MGTXRXP2_118:B6," & "MGTXRXP3_115:V6," & "MGTXRXP3_116:M6," & "MGTXRXP3_117:F6," & "MGTXRXP3_118:A8," & "MGTXTXN0_115:Y1," & "MGTXTXN0_116:P1," & "MGTXTXN0_117:K1," & "MGTXTXN0_118:D1," & "MGTXTXN1_115:V1," & "MGTXTXN1_116:N3," & "MGTXTXN1_117:J3," & "MGTXTXN1_118:C3," & "MGTXTXN2_115:U3," & "MGTXTXN2_116:M1," & "MGTXTXN2_117:H1," & "MGTXTXN2_118:B1," & "MGTXTXN3_115:T1," & "MGTXTXN3_116:L3," & "MGTXTXN3_117:F1," & "MGTXTXN3_118:A3," & "MGTXTXP0_115:Y2," & "MGTXTXP0_116:P2," & "MGTXTXP0_117:K2," & "MGTXTXP0_118:D2," & "MGTXTXP1_115:V2," & "MGTXTXP1_116:N4," & "MGTXTXP1_117:J4," & "MGTXTXP1_118:C4," & "MGTXTXP2_115:U4," & "MGTXTXP2_116:M2," & "MGTXTXP2_117:H2," & "MGTXTXP2_118:B2," & "MGTXTXP3_115:T2," & "MGTXTXP3_116:L4," & "MGTXTXP3_117:F2," & "MGTXTXP3_118:A4," & "PROGRAM_B:K10," & "TCK:E10," & "TDI:H10," & "TDN_U14:U14," & "TDO:G10," & "TDP_U15:U15," & "TMS:F10," & "VCCADC_0:P15," & "VCCAUX:(P13,T13,V11,V13,V15,W10,W12,W14)," & "VCCBATT_0:C10," & "VCCBRAM:(N16,R16,U16,W16)," & "VCCINT:(M11,M13,M15,M17,N10,N12,N14,N18,P11,P17," & "R10,R12,R18,T11,T17,U10,U12,U18,V17,W18)," & "VCCO_0:(T9,AB6)," & "VCCO_12:(Y22,AC23,AD20,AF24,AG21,AK22)," & "VCCO_13:(AA29,AB26,AD30,AE27,AH28,AJ25)," & "VCCO_14:(P30,R27,T24,U21,V28,W25)," & "VCCO_15:(J25,K22,L29,M26,N23,P20)," & "VCCO_16:(A29,B26,C23,D30,E27,F24,H28)," & "VCCO_17:(A19,B16,D20,E17,G21,H18,L19)," & "VCCO_18:(C13,D10,F14,G11,J15,K12)," & "VCCO_32:(AA19,AB16,AE17,AF14,AH18,AJ15)," & "VCCO_33:(Y12,AA9,AC13,AD10,AG11,AK12)," & "VCCO_34:(AC3,AE7,AF4,AG1,AH8,AJ5,AK2)," & "VN_T14:T14," & "VP_R15:R15," & "VREFN_R14:R14," & "VREFP_T15:T15," & "IO_A11:A11," & "IO_A12:A12," & "IO_A13:A13," & "IO_A15:A15," & "IO_A16:A16," & "IO_A17:A17," & "IO_A18:A18," & "IO_A20:A20," & "IO_A21:A21," & "IO_A22:A22," & "IO_A23:A23," & "IO_A25:A25," & "IO_A26:A26," & "IO_A27:A27," & "IO_A28:A28," & "IO_A30:A30," & "IO_B12:B12," & "IO_B13:B13," & "IO_B14:B14," & "IO_B15:B15," & "IO_B17:B17," & "IO_B18:B18," & "IO_B19:B19," & "IO_B20:B20," & "IO_B22:B22," & "IO_B23:B23," & "IO_B24:B24," & "IO_B25:B25," & "IO_B27:B27," & "IO_B28:B28," & "IO_B29:B29," & "IO_B30:B30," & "IO_C11:C11," & "IO_C12:C12," & "IO_C14:C14," & "IO_C15:C15," & "IO_C16:C16," & "IO_C17:C17," & "IO_C19:C19," & "IO_C20:C20," & "IO_C21:C21," & "IO_C22:C22," & "IO_C24:C24," & "IO_C25:C25," & "IO_C26:C26," & "IO_C27:C27," & "IO_C29:C29," & "IO_C30:C30," & "IO_D11:D11," & "IO_D12:D12," & "IO_D13:D13," & "IO_D14:D14," & "IO_D16:D16," & "IO_D17:D17," & "IO_D18:D18," & "IO_D19:D19," & "IO_D21:D21," & "IO_D22:D22," & "IO_D23:D23," & "IO_D24:D24," & "IO_D26:D26," & "IO_D27:D27," & "IO_D28:D28," & "IO_D29:D29," & "IO_E11:E11," & "IO_E13:E13," & "IO_E14:E14," & "IO_E15:E15," & "IO_E16:E16," & "IO_E18:E18," & "IO_E19:E19," & "IO_E20:E20," & "IO_E21:E21," & "IO_E23:E23," & "IO_E24:E24," & "IO_E25:E25," & "IO_E26:E26," & "IO_E28:E28," & "IO_E29:E29," & "IO_E30:E30," & "IO_F11:F11," & "IO_F12:F12," & "IO_F13:F13," & "IO_F15:F15," & "IO_F16:F16," & "IO_F17:F17," & "IO_F18:F18," & "IO_F20:F20," & "IO_F21:F21," & "IO_F22:F22," & "IO_F23:F23," & "IO_F25:F25," & "IO_F26:F26," & "IO_F27:F27," & "IO_F28:F28," & "IO_F30:F30," & "IO_G12:G12," & "IO_G13:G13," & "IO_G14:G14," & "IO_G15:G15," & "IO_G17:G17," & "IO_G18:G18," & "IO_G19:G19," & "IO_G20:G20," & "IO_G22:G22," & "IO_G23:G23," & "IO_G24:G24," & "IO_G25:G25," & "IO_G27:G27," & "IO_G28:G28," & "IO_G29:G29," & "IO_G30:G30," & "IO_H11:H11," & "IO_H12:H12," & "IO_H14:H14," & "IO_H15:H15," & "IO_H16:H16," & "IO_H17:H17," & "IO_H19:H19," & "IO_H20:H20," & "IO_H21:H21," & "IO_H22:H22," & "IO_H24:H24," & "IO_H25:H25," & "IO_H26:H26," & "IO_H27:H27," & "IO_H29:H29," & "IO_H30:H30," & "IO_J11:J11," & "IO_J12:J12," & "IO_J13:J13," & "IO_J14:J14," & "IO_J16:J16," & "IO_J17:J17," & "IO_J18:J18," & "IO_J19:J19," & "IO_J21:J21," & "IO_J22:J22," & "IO_J23:J23," & "IO_J24:J24," & "IO_J26:J26," & "IO_J27:J27," & "IO_J28:J28," & "IO_J29:J29," & "IO_K11:K11," & "IO_K13:K13," & "IO_K14:K14," & "IO_K15:K15," & "IO_K16:K16," & "IO_K18:K18," & "IO_K19:K19," & "IO_K20:K20," & "IO_K21:K21," & "IO_K23:K23," & "IO_K24:K24," & "IO_K25:K25," & "IO_K26:K26," & "IO_K28:K28," & "IO_K29:K29," & "IO_K30:K30," & "IO_L11:L11," & "IO_L12:L12," & "IO_L13:L13," & "IO_L15:L15," & "IO_L16:L16," & "IO_L17:L17," & "IO_L18:L18," & "IO_L20:L20," & "IO_L21:L21," & "IO_L22:L22," & "IO_L23:L23," & "IO_L25:L25," & "IO_L26:L26," & "IO_L27:L27," & "IO_L28:L28," & "IO_L30:L30," & "IO_M19:M19," & "IO_M20:M20," & "IO_M22:M22," & "IO_M23:M23," & "IO_M24:M24," & "IO_M25:M25," & "IO_M27:M27," & "IO_M28:M28," & "IO_M29:M29," & "IO_M30:M30," & "IO_N19:N19," & "IO_N20:N20," & "IO_N21:N21," & "IO_N22:N22," & "IO_N24:N24," & "IO_N25:N25," & "IO_N26:N26," & "IO_N27:N27," & "IO_N29:N29," & "IO_N30:N30," & "IO_P19:P19," & "IO_P21:P21," & "IO_P22:P22," & "IO_P23:P23," & "IO_P24:P24," & "IO_P26:P26," & "IO_P27:P27," & "IO_P28:P28," & "IO_P29:P29," & "IO_R19:R19," & "IO_R20:R20," & "IO_R21:R21," & "IO_R23:R23," & "IO_R24:R24," & "IO_R25:R25," & "IO_R26:R26," & "IO_R28:R28," & "IO_R29:R29," & "IO_R30:R30," & "IO_T20:T20," & "IO_T21:T21," & "IO_T22:T22," & "IO_T23:T23," & "IO_T25:T25," & "IO_T26:T26," & "IO_T27:T27," & "IO_T28:T28," & "IO_T30:T30," & "IO_U19:U19," & "IO_U20:U20," & "IO_U22:U22," & "IO_U23:U23," & "IO_U24:U24," & "IO_U25:U25," & "IO_U27:U27," & "IO_U28:U28," & "IO_U29:U29," & "IO_U30:U30," & "IO_V19:V19," & "IO_V20:V20," & "IO_V21:V21," & "IO_V22:V22," & "IO_V24:V24," & "IO_V25:V25," & "IO_V26:V26," & "IO_V27:V27," & "IO_V29:V29," & "IO_V30:V30," & "IO_W19:W19," & "IO_W21:W21," & "IO_W22:W22," & "IO_W23:W23," & "IO_W24:W24," & "IO_W26:W26," & "IO_W27:W27," & "IO_W28:W28," & "IO_W29:W29," & "IO_Y10:Y10," & "IO_Y11:Y11," & "IO_Y13:Y13," & "IO_Y14:Y14," & "IO_Y15:Y15," & "IO_Y16:Y16," & "IO_Y18:Y18," & "IO_Y19:Y19," & "IO_Y20:Y20," & "IO_Y21:Y21," & "IO_Y23:Y23," & "IO_Y24:Y24," & "IO_Y25:Y25," & "IO_Y26:Y26," & "IO_Y28:Y28," & "IO_Y29:Y29," & "IO_Y30:Y30," & "IO_AA8:AA8," & "IO_AA10:AA10," & "IO_AA11:AA11," & "IO_AA12:AA12," & "IO_AA13:AA13," & "IO_AA15:AA15," & "IO_AA16:AA16," & "IO_AA17:AA17," & "IO_AA18:AA18," & "IO_AA20:AA20," & "IO_AA21:AA21," & "IO_AA22:AA22," & "IO_AA23:AA23," & "IO_AA25:AA25," & "IO_AA26:AA26," & "IO_AA27:AA27," & "IO_AA28:AA28," & "IO_AA30:AA30," & "IO_AB7:AB7," & "IO_AB8:AB8," & "IO_AB9:AB9," & "IO_AB10:AB10," & "IO_AB12:AB12," & "IO_AB13:AB13," & "IO_AB14:AB14," & "IO_AB15:AB15," & "IO_AB17:AB17," & "IO_AB18:AB18," & "IO_AB19:AB19," & "IO_AB20:AB20," & "IO_AB22:AB22," & "IO_AB23:AB23," & "IO_AB24:AB24," & "IO_AB25:AB25," & "IO_AB27:AB27," & "IO_AB28:AB28," & "IO_AB29:AB29," & "IO_AB30:AB30," & "IO_AC1:AC1," & "IO_AC2:AC2," & "IO_AC4:AC4," & "IO_AC5:AC5," & "IO_AC6:AC6," & "IO_AC7:AC7," & "IO_AC9:AC9," & "IO_AC10:AC10," & "IO_AC11:AC11," & "IO_AC12:AC12," & "IO_AC14:AC14," & "IO_AC15:AC15," & "IO_AC16:AC16," & "IO_AC17:AC17," & "IO_AC19:AC19," & "IO_AC20:AC20," & "IO_AC21:AC21," & "IO_AC22:AC22," & "IO_AC24:AC24," & "IO_AC25:AC25," & "IO_AC26:AC26," & "IO_AC27:AC27," & "IO_AC29:AC29," & "IO_AC30:AC30," & "IO_AD1:AD1," & "IO_AD2:AD2," & "IO_AD3:AD3," & "IO_AD4:AD4," & "IO_AD6:AD6," & "IO_AD7:AD7," & "IO_AD8:AD8," & "IO_AD9:AD9," & "IO_AD11:AD11," & "IO_AD12:AD12," & "IO_AD13:AD13," & "IO_AD14:AD14," & "IO_AD16:AD16," & "IO_AD17:AD17," & "IO_AD18:AD18," & "IO_AD19:AD19," & "IO_AD21:AD21," & "IO_AD22:AD22," & "IO_AD23:AD23," & "IO_AD24:AD24," & "IO_AD26:AD26," & "IO_AD27:AD27," & "IO_AD28:AD28," & "IO_AD29:AD29," & "IO_AE1:AE1," & "IO_AE3:AE3," & "IO_AE4:AE4," & "IO_AE5:AE5," & "IO_AE6:AE6," & "IO_AE8:AE8," & "IO_AE9:AE9," & "IO_AE10:AE10," & "IO_AE11:AE11," & "IO_AE13:AE13," & "IO_AE14:AE14," & "IO_AE15:AE15," & "IO_AE16:AE16," & "IO_AE18:AE18," & "IO_AE19:AE19," & "IO_AE20:AE20," & "IO_AE21:AE21," & "IO_AE23:AE23," & "IO_AE24:AE24," & "IO_AE25:AE25," & "IO_AE26:AE26," & "IO_AE28:AE28," & "IO_AE29:AE29," & "IO_AE30:AE30," & "IO_AF1:AF1," & "IO_AF2:AF2," & "IO_AF3:AF3," & "IO_AF5:AF5," & "IO_AF6:AF6," & "IO_AF7:AF7," & "IO_AF8:AF8," & "IO_AF10:AF10," & "IO_AF11:AF11," & "IO_AF12:AF12," & "IO_AF13:AF13," & "IO_AF15:AF15," & "IO_AF16:AF16," & "IO_AF17:AF17," & "IO_AF18:AF18," & "IO_AF20:AF20," & "IO_AF21:AF21," & "IO_AF22:AF22," & "IO_AF23:AF23," & "IO_AF25:AF25," & "IO_AF26:AF26," & "IO_AF27:AF27," & "IO_AF28:AF28," & "IO_AF30:AF30," & "IO_AG2:AG2," & "IO_AG3:AG3," & "IO_AG4:AG4," & "IO_AG5:AG5," & "IO_AG7:AG7," & "IO_AG8:AG8," & "IO_AG9:AG9," & "IO_AG10:AG10," & "IO_AG12:AG12," & "IO_AG13:AG13," & "IO_AG14:AG14," & "IO_AG15:AG15," & "IO_AG17:AG17," & "IO_AG18:AG18," & "IO_AG19:AG19," & "IO_AG20:AG20," & "IO_AG22:AG22," & "IO_AG23:AG23," & "IO_AG24:AG24," & "IO_AG25:AG25," & "IO_AG27:AG27," & "IO_AG28:AG28," & "IO_AG29:AG29," & "IO_AG30:AG30," & "IO_AH1:AH1," & "IO_AH2:AH2," & "IO_AH4:AH4," & "IO_AH5:AH5," & "IO_AH6:AH6," & "IO_AH7:AH7," & "IO_AH9:AH9," & "IO_AH10:AH10," & "IO_AH11:AH11," & "IO_AH12:AH12," & "IO_AH14:AH14," & "IO_AH15:AH15," & "IO_AH16:AH16," & "IO_AH17:AH17," & "IO_AH19:AH19," & "IO_AH20:AH20," & "IO_AH21:AH21," & "IO_AH22:AH22," & "IO_AH24:AH24," & "IO_AH25:AH25," & "IO_AH26:AH26," & "IO_AH27:AH27," & "IO_AH29:AH29," & "IO_AH30:AH30," & "IO_AJ1:AJ1," & "IO_AJ2:AJ2," & "IO_AJ3:AJ3," & "IO_AJ4:AJ4," & "IO_AJ6:AJ6," & "IO_AJ7:AJ7," & "IO_AJ8:AJ8," & "IO_AJ9:AJ9," & "IO_AJ11:AJ11," & "IO_AJ12:AJ12," & "IO_AJ13:AJ13," & "IO_AJ14:AJ14," & "IO_AJ16:AJ16," & "IO_AJ17:AJ17," & "IO_AJ18:AJ18," & "IO_AJ19:AJ19," & "IO_AJ21:AJ21," & "IO_AJ22:AJ22," & "IO_AJ23:AJ23," & "IO_AJ24:AJ24," & "IO_AJ26:AJ26," & "IO_AJ27:AJ27," & "IO_AJ28:AJ28," & "IO_AJ29:AJ29," & "IO_AK1:AK1," & "IO_AK3:AK3," & "IO_AK4:AK4," & "IO_AK5:AK5," & "IO_AK6:AK6," & "IO_AK8:AK8," & "IO_AK9:AK9," & "IO_AK10:AK10," & "IO_AK11:AK11," & "IO_AK13:AK13," & "IO_AK14:AK14," & "IO_AK15:AK15," & "IO_AK16:AK16," & "IO_AK18:AK18," & "IO_AK19:AK19," & "IO_AK20:AK20," & "IO_AK21:AK21," & "IO_AK23:AK23," & "IO_AK24:AK24," & "IO_AK25:AK25," & "IO_AK26:AK26," & "IO_AK28:AK28," & "IO_AK29:AK29," & "IO_AK30:AK30"; -- Grouped Port Identification attribute PORT_GROUPING of XC7K325T_FFG900 : entity is "DIFFERENTIAL_VOLTAGE (" & "(MGTXRXP0_115, MGTXRXN0_115), " & "(MGTXRXP0_116, MGTXRXN0_116), " & "(MGTXRXP0_117, MGTXRXN0_117), " & "(MGTXRXP0_118, MGTXRXN0_118), " & "(MGTXRXP1_115, MGTXRXN1_115), " & "(MGTXRXP1_116, MGTXRXN1_116), " & "(MGTXRXP1_117, MGTXRXN1_117), " & "(MGTXRXP1_118, MGTXRXN1_118), " & "(MGTXRXP2_115, MGTXRXN2_115), " & "(MGTXRXP2_116, MGTXRXN2_116), " & "(MGTXRXP2_117, MGTXRXN2_117), " & "(MGTXRXP2_118, MGTXRXN2_118), " & "(MGTXRXP3_115, MGTXRXN3_115), " & "(MGTXRXP3_116, MGTXRXN3_116), " & "(MGTXRXP3_117, MGTXRXN3_117), " & "(MGTXRXP3_118, MGTXRXN3_118), " & "(MGTXTXP0_115, MGTXTXN0_115), " & "(MGTXTXP0_116, MGTXTXN0_116), " & "(MGTXTXP0_117, MGTXTXN0_117), " & "(MGTXTXP0_118, MGTXTXN0_118), " & "(MGTXTXP1_115, MGTXTXN1_115), " & "(MGTXTXP1_116, MGTXTXN1_116), " & "(MGTXTXP1_117, MGTXTXN1_117), " & "(MGTXTXP1_118, MGTXTXN1_118), " & "(MGTXTXP2_115, MGTXTXN2_115), " & "(MGTXTXP2_116, MGTXTXN2_116), " & "(MGTXTXP2_117, MGTXTXN2_117), " & "(MGTXTXP2_118, MGTXTXN2_118), " & "(MGTXTXP3_115, MGTXTXN3_115), " & "(MGTXTXP3_116, MGTXTXN3_116), " & "(MGTXTXP3_117, MGTXTXN3_117), " & "(MGTXTXP3_118, MGTXTXN3_118))"; -- Scan Port Identification attribute TAP_SCAN_IN of TDI : signal is true; attribute TAP_SCAN_MODE of TMS : signal is true; attribute TAP_SCAN_OUT of TDO : signal is true; attribute TAP_SCAN_CLOCK of TCK : signal is (66.0e6, BOTH); -- Compliance-Enable Description attribute COMPLIANCE_PATTERNS of XC7K325T_FFG900 : entity is "(PROGRAM_B) (1)"; -- Instruction Register Description attribute INSTRUCTION_LENGTH of XC7K325T_FFG900 : entity is 6; attribute INSTRUCTION_OPCODE of XC7K325T_FFG900 : entity is "IDCODE (001001)," & -- DEVICE_ID "BYPASS (111111)," & -- BYPASS "EXTEST (100110)," & -- BOUNDARY "SAMPLE (000001)," & -- BOUNDARY "PRELOAD (000001)," & -- Same as SAMPLE "USERCODE (001000)," & -- DEVICE_ID "HIGHZ (001010)," & -- BYPASS "EXTEST_PULSE (111100)," & -- BOUNDARY "EXTEST_TRAIN (111101)," & -- BOUNDARY "ISC_ENABLE (010000)," & -- ISC_CONFIG "ISC_PROGRAM (010001)," & -- ISC_PDATA "ISC_NOOP (010100)," & -- ISC_DEFAULT "XSC_READ_RSVD (010101)," & -- PRIVATE "ISC_DISABLE (010110)," & -- ISC_CONFIG "XSC_PROGRAM_KEY (010010)," & -- XSC_KEY_DATA "XSC_DNA (010111)," & -- DNA "CFG_OUT (000100)," & -- Not available during configuration with another mode. "CFG_IN (000101)," & -- Not available during configuration with another mode. "JPROGRAM (001011)," & -- Not available during configuration with another mode. "JSTART (001100)," & -- Not available during configuration with another mode. "JSHUTDOWN (001101)," & -- Not available during configuration with another mode. "FUSE_CTS (110000)," & -- PRIVATE "FUSE_KEY (110001)," & -- PRIVATE "FUSE_DNA (110010)," & -- PRIVATE "FUSE_USER (110011)," & -- PRIVATE "FUSE_CNTL (110100)," & -- PRIVATE "USER1 (000010)," & -- Not available until after configuration "USER2 (000011)," & -- Not available until after configuration "USER3 (100010)," & -- Not available until after configuration "USER4 (100011)," & -- Not available until after configuration "XADC_DRP (110111)," & -- PRIVATE "INTEST_RSVD (000111)"; -- PRIVATE attribute INSTRUCTION_CAPTURE of XC7K325T_FFG900 : entity is -- Bit 5 is 1 when DONE is released (part of startup sequence) -- Bit 4 is 1 if house-cleaning is complete -- Bit 3 is ISC_Enabled -- Bit 2 is ISC_Done "XXXX01"; attribute INSTRUCTION_PRIVATE of XC7K325T_FFG900 : entity is -- If the device is configured, and a USER instruction is implemented -- and not private to the FPGA designer, then it should be removed -- from INSTRUCTION_PRIVATE, and the target register should be defined -- in REGISTER_ACCESS. "ISC_ENABLE," & "ISC_PROGRAM," & "ISC_NOOP," & "XSC_READ_RSVD," & "ISC_DISABLE," & "XSC_PROGRAM_KEY," & "XSC_DNA," & "CFG_OUT," & "CFG_IN," & "JPROGRAM," & "JSTART," & "JSHUTDOWN," & "FUSE_CTS," & "FUSE_KEY," & "FUSE_DNA," & "FUSE_USER," & "FUSE_CNTL," & "USER1," & "USER2," & "USER3," & "USER4," & "XADC_DRP," & "INTEST_RSVD"; -- Optional Register Description attribute IDCODE_REGISTER of XC7K325T_FFG900 : entity is "XXXX" & -- version "0011011" & -- family "001010001" & -- array size "00001001001" & -- manufacturer "1"; -- required by 1149.1 attribute USERCODE_REGISTER of XC7K325T_FFG900 : entity is "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; -- Register Access Description attribute REGISTER_ACCESS of XC7K325T_FFG900 : entity is -- "[] (USER1)," & -- "[] (USER2)," & -- "[] (USER3)," & -- "[] (USER4)," & "DATAREG[57] (XSC_DNA)," & "BYPASS (HIGHZ,BYPASS)," & "DEVICE_ID (USERCODE,IDCODE)," & "BOUNDARY (SAMPLE,PRELOAD,EXTEST,EXTEST_PULSE,EXTEST_TRAIN)"; -- Boundary-Scan Register Description attribute BOUNDARY_LENGTH of XC7K325T_FFG900 : entity is 1631; attribute BOUNDARY_REGISTER of XC7K325T_FFG900 : entity is -- cellnum (type, port, function, safe[, ccell, disval, disrslt]) " 0 (BC_2, *, controlr, 1)," & " 1 (BC_2, CCLK_B10, output3, X, 0, 1, Z)," & -- CCLK_0 " 2 (BC_2, CCLK_B10, input, X)," & -- CCLK_0 " 3 (BC_2, M0_AB5, input, X)," & " 4 (BC_2, M1_AB2, input, X)," & " 5 (BC_2, M2_AB1, input, X)," & " 6 (BC_2, CFGBVS_L10, input, X)," & " 7 (BC_2, *, internal, 1)," & -- PROGRAM_B " 8 (BC_2, *, controlr, 1)," & " 9 (BC_2, INIT_B_A10, output3, X, 8, 1, Z)," & -- INIT_B_0 " 10 (BC_2, INIT_B_A10, input, X)," & -- INIT_B_0 " 11 (BC_2, *, controlr, 1)," & " 12 (BC_2, DONE_M10, output3, X, 11, 1, Z)," & -- DONE_0 " 13 (BC_2, DONE_M10, input, X)," & -- DONE_0 " 14 (BC_2, *, internal, X)," & " 15 (BC_2, *, internal, X)," & " 16 (BC_2, *, internal, X)," & " 17 (BC_2, *, internal, X)," & " 18 (BC_2, *, internal, X)," & " 19 (BC_2, *, internal, X)," & " 20 (BC_2, *, internal, X)," & " 21 (BC_2, *, internal, X)," & " 22 (BC_2, *, internal, X)," & " 23 (BC_2, *, internal, X)," & " 24 (BC_2, *, internal, X)," & " 25 (BC_2, *, internal, X)," & " 26 (BC_2, *, internal, X)," & " 27 (BC_2, *, internal, X)," & " 28 (BC_2, *, internal, X)," & " 29 (BC_2, *, internal, X)," & " 30 (BC_2, *, internal, X)," & " 31 (BC_2, *, internal, X)," & " 32 (BC_2, *, internal, X)," & " 33 (BC_2, *, internal, X)," & " 34 (BC_2, *, internal, X)," & " 35 (BC_2, *, internal, X)," & " 36 (BC_2, *, internal, X)," & " 37 (BC_2, *, internal, X)," & " 38 (BC_2, *, internal, X)," & " 39 (BC_2, *, internal, X)," & " 40 (BC_2, *, internal, X)," & " 41 (BC_2, *, internal, X)," & " 42 (BC_2, *, internal, X)," & " 43 (BC_2, *, internal, X)," & " 44 (BC_2, *, controlr, 1)," & " 45 (BC_2, IO_AB14, output3, X, 44, 1, Z)," & -- PAD500 " 46 (BC_2, IO_AB14, input, X)," & -- PAD500 " 47 (BC_2, *, controlr, 1)," & " 48 (BC_2, IO_Y15, output3, X, 47, 1, Z)," & -- PAD499 " 49 (BC_2, IO_Y15, input, X)," & -- PAD499 " 50 (BC_2, *, controlr, 1)," & " 51 (BC_2, IO_Y16, output3, X, 50, 1, Z)," & -- PAD498 " 52 (BC_2, IO_Y16, input, X)," & -- PAD498 " 53 (BC_2, *, controlr, 1)," & " 54 (BC_2, IO_AA16, output3, X, 53, 1, Z)," & -- PAD497 " 55 (BC_2, IO_AA16, input, X)," & -- PAD497 " 56 (BC_2, *, controlr, 1)," & " 57 (BC_2, IO_AA17, output3, X, 56, 1, Z)," & -- PAD496 " 58 (BC_2, IO_AA17, input, X)," & -- PAD496 " 59 (BC_2, *, controlr, 1)," & " 60 (BC_2, IO_AD14, output3, X, 59, 1, Z)," & -- PAD495 " 61 (BC_2, IO_AD14, input, X)," & -- PAD495 " 62 (BC_2, *, controlr, 1)," & " 63 (BC_2, IO_AC14, output3, X, 62, 1, Z)," & -- PAD494 " 64 (BC_2, IO_AC14, input, X)," & -- PAD494 " 65 (BC_2, *, controlr, 1)," & " 66 (BC_2, IO_AC15, output3, X, 65, 1, Z)," & -- PAD493 " 67 (BC_2, IO_AC15, input, X)," & -- PAD493 " 68 (BC_2, *, controlr, 1)," & " 69 (BC_2, IO_AC16, output3, X, 68, 1, Z)," & -- PAD492 " 70 (BC_2, IO_AC16, input, X)," & -- PAD492 " 71 (BC_2, *, controlr, 1)," & " 72 (BC_2, IO_AB15, output3, X, 71, 1, Z)," & -- PAD491 " 73 (BC_2, IO_AB15, input, X)," & -- PAD491 " 74 (BC_2, *, controlr, 1)," & " 75 (BC_2, IO_AA15, output3, X, 74, 1, Z)," & -- PAD490 " 76 (BC_2, IO_AA15, input, X)," & -- PAD490 " 77 (BC_2, *, controlr, 1)," & " 78 (BC_2, IO_AE14, output3, X, 77, 1, Z)," & -- PAD489 " 79 (BC_2, IO_AE14, input, X)," & -- PAD489 " 80 (BC_2, *, controlr, 1)," & " 81 (BC_2, IO_AE15, output3, X, 80, 1, Z)," & -- PAD488 " 82 (BC_2, IO_AE15, input, X)," & -- PAD488 " 83 (BC_2, *, controlr, 1)," & " 84 (BC_2, IO_AC17, output3, X, 83, 1, Z)," & -- PAD487 " 85 (BC_2, IO_AC17, input, X)," & -- PAD487 " 86 (BC_2, *, controlr, 1)," & " 87 (BC_2, IO_AB17, output3, X, 86, 1, Z)," & -- PAD486 " 88 (BC_2, IO_AB17, input, X)," & -- PAD486 " 89 (BC_2, *, controlr, 1)," & " 90 (BC_2, IO_AC19, output3, X, 89, 1, Z)," & -- PAD485 " 91 (BC_2, IO_AC19, input, X)," & -- PAD485 " 92 (BC_2, *, controlr, 1)," & " 93 (BC_2, IO_AB19, output3, X, 92, 1, Z)," & -- PAD484 " 94 (BC_2, IO_AB19, input, X)," & -- PAD484 " 95 (BC_2, *, controlr, 1)," & " 96 (BC_2, IO_AB18, output3, X, 95, 1, Z)," & -- PAD483 " 97 (BC_2, IO_AB18, input, X)," & -- PAD483 " 98 (BC_2, *, controlr, 1)," & " 99 (BC_2, IO_AA18, output3, X, 98, 1, Z)," & -- PAD482 " 100 (BC_2, IO_AA18, input, X)," & -- PAD482 " 101 (BC_2, *, controlr, 1)," & " 102 (BC_2, IO_Y18, output3, X, 101, 1, Z)," & -- PAD481 " 103 (BC_2, IO_Y18, input, X)," & -- PAD481 " 104 (BC_2, *, controlr, 1)," & " 105 (BC_2, IO_Y19, output3, X, 104, 1, Z)," & -- PAD480 " 106 (BC_2, IO_Y19, input, X)," & -- PAD480 " 107 (BC_2, *, controlr, 1)," & " 108 (BC_2, IO_AD16, output3, X, 107, 1, Z)," & -- PAD479 " 109 (BC_2, IO_AD16, input, X)," & -- PAD479 " 110 (BC_2, *, controlr, 1)," & " 111 (BC_2, IO_AD17, output3, X, 110, 1, Z)," & -- PAD478 " 112 (BC_2, IO_AD17, input, X)," & -- PAD478 " 113 (BC_2, *, controlr, 1)," & " 114 (BC_2, IO_AE18, output3, X, 113, 1, Z)," & -- PAD477 " 115 (BC_2, IO_AE18, input, X)," & -- PAD477 " 116 (BC_2, *, controlr, 1)," & " 117 (BC_2, IO_AD18, output3, X, 116, 1, Z)," & -- PAD476 " 118 (BC_2, IO_AD18, input, X)," & -- PAD476 " 119 (BC_2, *, controlr, 1)," & " 120 (BC_2, IO_AG17, output3, X, 119, 1, Z)," & -- PAD475 " 121 (BC_2, IO_AG17, input, X)," & -- PAD475 " 122 (BC_2, *, controlr, 1)," & " 123 (BC_2, IO_AF17, output3, X, 122, 1, Z)," & -- PAD474 " 124 (BC_2, IO_AF17, input, X)," & -- PAD474 " 125 (BC_2, *, controlr, 1)," & " 126 (BC_2, IO_AG18, output3, X, 125, 1, Z)," & -- PAD473 " 127 (BC_2, IO_AG18, input, X)," & -- PAD473 " 128 (BC_2, *, controlr, 1)," & " 129 (BC_2, IO_AF18, output3, X, 128, 1, Z)," & -- PAD472 " 130 (BC_2, IO_AF18, input, X)," & -- PAD472 " 131 (BC_2, *, controlr, 1)," & " 132 (BC_2, IO_AE19, output3, X, 131, 1, Z)," & -- PAD471 " 133 (BC_2, IO_AE19, input, X)," & -- PAD471 " 134 (BC_2, *, controlr, 1)," & " 135 (BC_2, IO_AD19, output3, X, 134, 1, Z)," & -- PAD470 " 136 (BC_2, IO_AD19, input, X)," & -- PAD470 " 137 (BC_2, *, controlr, 1)," & " 138 (BC_2, IO_AK18, output3, X, 137, 1, Z)," & -- PAD469 " 139 (BC_2, IO_AK18, input, X)," & -- PAD469 " 140 (BC_2, *, controlr, 1)," & " 141 (BC_2, IO_AJ18, output3, X, 140, 1, Z)," & -- PAD468 " 142 (BC_2, IO_AJ18, input, X)," & -- PAD468 " 143 (BC_2, *, controlr, 1)," & " 144 (BC_2, IO_AH19, output3, X, 143, 1, Z)," & -- PAD467 " 145 (BC_2, IO_AH19, input, X)," & -- PAD467 " 146 (BC_2, *, controlr, 1)," & " 147 (BC_2, IO_AG19, output3, X, 146, 1, Z)," & -- PAD466 " 148 (BC_2, IO_AG19, input, X)," & -- PAD466 " 149 (BC_2, *, controlr, 1)," & " 150 (BC_2, IO_AK19, output3, X, 149, 1, Z)," & -- PAD465 " 151 (BC_2, IO_AK19, input, X)," & -- PAD465 " 152 (BC_2, *, controlr, 1)," & " 153 (BC_2, IO_AJ19, output3, X, 152, 1, Z)," & -- PAD464 " 154 (BC_2, IO_AJ19, input, X)," & -- PAD464 " 155 (BC_2, *, controlr, 1)," & " 156 (BC_2, IO_AF16, output3, X, 155, 1, Z)," & -- PAD463 " 157 (BC_2, IO_AF16, input, X)," & -- PAD463 " 158 (BC_2, *, controlr, 1)," & " 159 (BC_2, IO_AE16, output3, X, 158, 1, Z)," & -- PAD462 " 160 (BC_2, IO_AE16, input, X)," & -- PAD462 " 161 (BC_2, *, controlr, 1)," & " 162 (BC_2, IO_AJ17, output3, X, 161, 1, Z)," & -- PAD461 " 163 (BC_2, IO_AJ17, input, X)," & -- PAD461 " 164 (BC_2, *, controlr, 1)," & " 165 (BC_2, IO_AH17, output3, X, 164, 1, Z)," & -- PAD460 " 166 (BC_2, IO_AH17, input, X)," & -- PAD460 " 167 (BC_2, *, controlr, 1)," & " 168 (BC_2, IO_AG14, output3, X, 167, 1, Z)," & -- PAD459 " 169 (BC_2, IO_AG14, input, X)," & -- PAD459 " 170 (BC_2, *, controlr, 1)," & " 171 (BC_2, IO_AF15, output3, X, 170, 1, Z)," & -- PAD458 " 172 (BC_2, IO_AF15, input, X)," & -- PAD458 " 173 (BC_2, *, controlr, 1)," & " 174 (BC_2, IO_AJ16, output3, X, 173, 1, Z)," & -- PAD457 " 175 (BC_2, IO_AJ16, input, X)," & -- PAD457 " 176 (BC_2, *, controlr, 1)," & " 177 (BC_2, IO_AH16, output3, X, 176, 1, Z)," & -- PAD456 " 178 (BC_2, IO_AH16, input, X)," & -- PAD456 " 179 (BC_2, *, controlr, 1)," & " 180 (BC_2, IO_AH15, output3, X, 179, 1, Z)," & -- PAD455 " 181 (BC_2, IO_AH15, input, X)," & -- PAD455 " 182 (BC_2, *, controlr, 1)," & " 183 (BC_2, IO_AG15, output3, X, 182, 1, Z)," & -- PAD454 " 184 (BC_2, IO_AG15, input, X)," & -- PAD454 " 185 (BC_2, *, controlr, 1)," & " 186 (BC_2, IO_AK15, output3, X, 185, 1, Z)," & -- PAD453 " 187 (BC_2, IO_AK15, input, X)," & -- PAD453 " 188 (BC_2, *, controlr, 1)," & " 189 (BC_2, IO_AK16, output3, X, 188, 1, Z)," & -- PAD452 " 190 (BC_2, IO_AK16, input, X)," & -- PAD452 " 191 (BC_2, *, controlr, 1)," & " 192 (BC_2, IO_Y14, output3, X, 191, 1, Z)," & -- PAD451 " 193 (BC_2, IO_Y14, input, X)," & -- PAD451 " 194 (BC_2, *, controlr, 1)," & " 195 (BC_2, IO_AD13, output3, X, 194, 1, Z)," & -- PAD450 " 196 (BC_2, IO_AD13, input, X)," & -- PAD450 " 197 (BC_2, *, controlr, 1)," & " 198 (BC_2, IO_AH12, output3, X, 197, 1, Z)," & -- PAD449 " 199 (BC_2, IO_AH12, input, X)," & -- PAD449 " 200 (BC_2, *, controlr, 1)," & " 201 (BC_2, IO_AG13, output3, X, 200, 1, Z)," & -- PAD448 " 202 (BC_2, IO_AG13, input, X)," & -- PAD448 " 203 (BC_2, *, controlr, 1)," & " 204 (BC_2, IO_AG12, output3, X, 203, 1, Z)," & -- PAD447 " 205 (BC_2, IO_AG12, input, X)," & -- PAD447 " 206 (BC_2, *, controlr, 1)," & " 207 (BC_2, IO_AF12, output3, X, 206, 1, Z)," & -- PAD446 " 208 (BC_2, IO_AF12, input, X)," & -- PAD446 " 209 (BC_2, *, controlr, 1)," & " 210 (BC_2, IO_AJ12, output3, X, 209, 1, Z)," & -- PAD445 " 211 (BC_2, IO_AJ12, input, X)," & -- PAD445 " 212 (BC_2, *, controlr, 1)," & " 213 (BC_2, IO_AJ13, output3, X, 212, 1, Z)," & -- PAD444 " 214 (BC_2, IO_AJ13, input, X)," & -- PAD444 " 215 (BC_2, *, controlr, 1)," & " 216 (BC_2, IO_AJ14, output3, X, 215, 1, Z)," & -- PAD443 " 217 (BC_2, IO_AJ14, input, X)," & -- PAD443 " 218 (BC_2, *, controlr, 1)," & " 219 (BC_2, IO_AH14, output3, X, 218, 1, Z)," & -- PAD442 " 220 (BC_2, IO_AH14, input, X)," & -- PAD442 " 221 (BC_2, *, controlr, 1)," & " 222 (BC_2, IO_AK13, output3, X, 221, 1, Z)," & -- PAD441 " 223 (BC_2, IO_AK13, input, X)," & -- PAD441 " 224 (BC_2, *, controlr, 1)," & " 225 (BC_2, IO_AK14, output3, X, 224, 1, Z)," & -- PAD440 " 226 (BC_2, IO_AK14, input, X)," & -- PAD440 " 227 (BC_2, *, controlr, 1)," & " 228 (BC_2, IO_AF13, output3, X, 227, 1, Z)," & -- PAD439 " 229 (BC_2, IO_AF13, input, X)," & -- PAD439 " 230 (BC_2, *, controlr, 1)," & " 231 (BC_2, IO_AE13, output3, X, 230, 1, Z)," & -- PAD438 " 232 (BC_2, IO_AE13, input, X)," & -- PAD438 " 233 (BC_2, *, controlr, 1)," & " 234 (BC_2, IO_AJ11, output3, X, 233, 1, Z)," & -- PAD437 " 235 (BC_2, IO_AJ11, input, X)," & -- PAD437 " 236 (BC_2, *, controlr, 1)," & " 237 (BC_2, IO_AH11, output3, X, 236, 1, Z)," & -- PAD436 " 238 (BC_2, IO_AH11, input, X)," & -- PAD436 " 239 (BC_2, *, controlr, 1)," & " 240 (BC_2, IO_AK10, output3, X, 239, 1, Z)," & -- PAD435 " 241 (BC_2, IO_AK10, input, X)," & -- PAD435 " 242 (BC_2, *, controlr, 1)," & " 243 (BC_2, IO_AK11, output3, X, 242, 1, Z)," & -- PAD434 " 244 (BC_2, IO_AK11, input, X)," & -- PAD434 " 245 (BC_2, *, controlr, 1)," & " 246 (BC_2, IO_AH9, output3, X, 245, 1, Z)," & -- PAD433 " 247 (BC_2, IO_AH9, input, X)," & -- PAD433 " 248 (BC_2, *, controlr, 1)," & " 249 (BC_2, IO_AG9, output3, X, 248, 1, Z)," & -- PAD432 " 250 (BC_2, IO_AG9, input, X)," & -- PAD432 " 251 (BC_2, *, controlr, 1)," & " 252 (BC_2, IO_AK9, output3, X, 251, 1, Z)," & -- PAD431 " 253 (BC_2, IO_AK9, input, X)," & -- PAD431 " 254 (BC_2, *, controlr, 1)," & " 255 (BC_2, IO_AJ9, output3, X, 254, 1, Z)," & -- PAD430 " 256 (BC_2, IO_AJ9, input, X)," & -- PAD430 " 257 (BC_2, *, controlr, 1)," & " 258 (BC_2, IO_AF10, output3, X, 257, 1, Z)," & -- PAD429 " 259 (BC_2, IO_AF10, input, X)," & -- PAD429 " 260 (BC_2, *, controlr, 1)," & " 261 (BC_2, IO_AE10, output3, X, 260, 1, Z)," & -- PAD428 " 262 (BC_2, IO_AE10, input, X)," & -- PAD428 " 263 (BC_2, *, controlr, 1)," & " 264 (BC_2, IO_AH10, output3, X, 263, 1, Z)," & -- PAD427 " 265 (BC_2, IO_AH10, input, X)," & -- PAD427 " 266 (BC_2, *, controlr, 1)," & " 267 (BC_2, IO_AG10, output3, X, 266, 1, Z)," & -- PAD426 " 268 (BC_2, IO_AG10, input, X)," & -- PAD426 " 269 (BC_2, *, controlr, 1)," & " 270 (BC_2, IO_AD11, output3, X, 269, 1, Z)," & -- PAD425 " 271 (BC_2, IO_AD11, input, X)," & -- PAD425 " 272 (BC_2, *, controlr, 1)," & " 273 (BC_2, IO_AD12, output3, X, 272, 1, Z)," & -- PAD424 " 274 (BC_2, IO_AD12, input, X)," & -- PAD424 " 275 (BC_2, *, controlr, 1)," & " 276 (BC_2, IO_AF11, output3, X, 275, 1, Z)," & -- PAD423 " 277 (BC_2, IO_AF11, input, X)," & -- PAD423 " 278 (BC_2, *, controlr, 1)," & " 279 (BC_2, IO_AE11, output3, X, 278, 1, Z)," & -- PAD422 " 280 (BC_2, IO_AE11, input, X)," & -- PAD422 " 281 (BC_2, *, controlr, 1)," & " 282 (BC_2, IO_AE9, output3, X, 281, 1, Z)," & -- PAD421 " 283 (BC_2, IO_AE9, input, X)," & -- PAD421 " 284 (BC_2, *, controlr, 1)," & " 285 (BC_2, IO_AD9, output3, X, 284, 1, Z)," & -- PAD420 " 286 (BC_2, IO_AD9, input, X)," & -- PAD420 " 287 (BC_2, *, controlr, 1)," & " 288 (BC_2, IO_AC11, output3, X, 287, 1, Z)," & -- PAD419 " 289 (BC_2, IO_AC11, input, X)," & -- PAD419 " 290 (BC_2, *, controlr, 1)," & " 291 (BC_2, IO_AC12, output3, X, 290, 1, Z)," & -- PAD418 " 292 (BC_2, IO_AC12, input, X)," & -- PAD418 " 293 (BC_2, *, controlr, 1)," & " 294 (BC_2, IO_AE8, output3, X, 293, 1, Z)," & -- PAD417 " 295 (BC_2, IO_AE8, input, X)," & -- PAD417 " 296 (BC_2, *, controlr, 1)," & " 297 (BC_2, IO_AD8, output3, X, 296, 1, Z)," & -- PAD416 " 298 (BC_2, IO_AD8, input, X)," & -- PAD416 " 299 (BC_2, *, controlr, 1)," & " 300 (BC_2, IO_AC10, output3, X, 299, 1, Z)," & -- PAD415 " 301 (BC_2, IO_AC10, input, X)," & -- PAD415 " 302 (BC_2, *, controlr, 1)," & " 303 (BC_2, IO_AB10, output3, X, 302, 1, Z)," & -- PAD414 " 304 (BC_2, IO_AB10, input, X)," & -- PAD414 " 305 (BC_2, *, controlr, 1)," & " 306 (BC_2, IO_AB13, output3, X, 305, 1, Z)," & -- PAD413 " 307 (BC_2, IO_AB13, input, X)," & -- PAD413 " 308 (BC_2, *, controlr, 1)," & " 309 (BC_2, IO_AA13, output3, X, 308, 1, Z)," & -- PAD412 " 310 (BC_2, IO_AA13, input, X)," & -- PAD412 " 311 (BC_2, *, controlr, 1)," & " 312 (BC_2, IO_AA10, output3, X, 311, 1, Z)," & -- PAD411 " 313 (BC_2, IO_AA10, input, X)," & -- PAD411 " 314 (BC_2, *, controlr, 1)," & " 315 (BC_2, IO_AA11, output3, X, 314, 1, Z)," & -- PAD410 " 316 (BC_2, IO_AA11, input, X)," & -- PAD410 " 317 (BC_2, *, controlr, 1)," & " 318 (BC_2, IO_Y10, output3, X, 317, 1, Z)," & -- PAD409 " 319 (BC_2, IO_Y10, input, X)," & -- PAD409 " 320 (BC_2, *, controlr, 1)," & " 321 (BC_2, IO_Y11, output3, X, 320, 1, Z)," & -- PAD408 " 322 (BC_2, IO_Y11, input, X)," & -- PAD408 " 323 (BC_2, *, controlr, 1)," & " 324 (BC_2, IO_AC9, output3, X, 323, 1, Z)," & -- PAD407 " 325 (BC_2, IO_AC9, input, X)," & -- PAD407 " 326 (BC_2, *, controlr, 1)," & " 327 (BC_2, IO_AB9, output3, X, 326, 1, Z)," & -- PAD406 " 328 (BC_2, IO_AB9, input, X)," & -- PAD406 " 329 (BC_2, *, controlr, 1)," & " 330 (BC_2, IO_AB8, output3, X, 329, 1, Z)," & -- PAD405 " 331 (BC_2, IO_AB8, input, X)," & -- PAD405 " 332 (BC_2, *, controlr, 1)," & " 333 (BC_2, IO_AA8, output3, X, 332, 1, Z)," & -- PAD404 " 334 (BC_2, IO_AA8, input, X)," & -- PAD404 " 335 (BC_2, *, controlr, 1)," & " 336 (BC_2, IO_AB12, output3, X, 335, 1, Z)," & -- PAD403 " 337 (BC_2, IO_AB12, input, X)," & -- PAD403 " 338 (BC_2, *, controlr, 1)," & " 339 (BC_2, IO_AA12, output3, X, 338, 1, Z)," & -- PAD402 " 340 (BC_2, IO_AA12, input, X)," & -- PAD402 " 341 (BC_2, *, controlr, 1)," & " 342 (BC_2, IO_Y13, output3, X, 341, 1, Z)," & -- PAD401 " 343 (BC_2, IO_Y13, input, X)," & -- PAD401 " 344 (BC_2, *, controlr, 1)," & " 345 (BC_2, IO_AB7, output3, X, 344, 1, Z)," & -- PAD400 " 346 (BC_2, IO_AB7, input, X)," & -- PAD400 " 347 (BC_2, *, controlr, 1)," & " 348 (BC_2, IO_AK4, output3, X, 347, 1, Z)," & -- PAD399 " 349 (BC_2, IO_AK4, input, X)," & -- PAD399 " 350 (BC_2, *, controlr, 1)," & " 351 (BC_2, IO_AK5, output3, X, 350, 1, Z)," & -- PAD398 " 352 (BC_2, IO_AK5, input, X)," & -- PAD398 " 353 (BC_2, *, controlr, 1)," & " 354 (BC_2, IO_AK8, output3, X, 353, 1, Z)," & -- PAD397 " 355 (BC_2, IO_AK8, input, X)," & -- PAD397 " 356 (BC_2, *, controlr, 1)," & " 357 (BC_2, IO_AJ8, output3, X, 356, 1, Z)," & -- PAD396 " 358 (BC_2, IO_AJ8, input, X)," & -- PAD396 " 359 (BC_2, *, controlr, 1)," & " 360 (BC_2, IO_AK6, output3, X, 359, 1, Z)," & -- PAD395 " 361 (BC_2, IO_AK6, input, X)," & -- PAD395 " 362 (BC_2, *, controlr, 1)," & " 363 (BC_2, IO_AJ6, output3, X, 362, 1, Z)," & -- PAD394 " 364 (BC_2, IO_AJ6, input, X)," & -- PAD394 " 365 (BC_2, *, controlr, 1)," & " 366 (BC_2, IO_AJ7, output3, X, 365, 1, Z)," & -- PAD393 " 367 (BC_2, IO_AJ7, input, X)," & -- PAD393 " 368 (BC_2, *, controlr, 1)," & " 369 (BC_2, IO_AH7, output3, X, 368, 1, Z)," & -- PAD392 " 370 (BC_2, IO_AH7, input, X)," & -- PAD392 " 371 (BC_2, *, controlr, 1)," & " 372 (BC_2, IO_AG7, output3, X, 371, 1, Z)," & -- PAD391 " 373 (BC_2, IO_AG7, input, X)," & -- PAD391 " 374 (BC_2, *, controlr, 1)," & " 375 (BC_2, IO_AF7, output3, X, 374, 1, Z)," & -- PAD390 " 376 (BC_2, IO_AF7, input, X)," & -- PAD390 " 377 (BC_2, *, controlr, 1)," & " 378 (BC_2, IO_AG8, output3, X, 377, 1, Z)," & -- PAD389 " 379 (BC_2, IO_AG8, input, X)," & -- PAD389 " 380 (BC_2, *, controlr, 1)," & " 381 (BC_2, IO_AF8, output3, X, 380, 1, Z)," & -- PAD388 " 382 (BC_2, IO_AF8, input, X)," & -- PAD388 " 383 (BC_2, *, controlr, 1)," & " 384 (BC_2, IO_AK3, output3, X, 383, 1, Z)," & -- PAD387 " 385 (BC_2, IO_AK3, input, X)," & -- PAD387 " 386 (BC_2, *, controlr, 1)," & " 387 (BC_2, IO_AJ3, output3, X, 386, 1, Z)," & -- PAD386 " 388 (BC_2, IO_AJ3, input, X)," & -- PAD386 " 389 (BC_2, *, controlr, 1)," & " 390 (BC_2, IO_AK1, output3, X, 389, 1, Z)," & -- PAD385 " 391 (BC_2, IO_AK1, input, X)," & -- PAD385 " 392 (BC_2, *, controlr, 1)," & " 393 (BC_2, IO_AJ1, output3, X, 392, 1, Z)," & -- PAD384 " 394 (BC_2, IO_AJ1, input, X)," & -- PAD384 " 395 (BC_2, *, controlr, 1)," & " 396 (BC_2, IO_AJ2, output3, X, 395, 1, Z)," & -- PAD383 " 397 (BC_2, IO_AJ2, input, X)," & -- PAD383 " 398 (BC_2, *, controlr, 1)," & " 399 (BC_2, IO_AH2, output3, X, 398, 1, Z)," & -- PAD382 " 400 (BC_2, IO_AH2, input, X)," & -- PAD382 " 401 (BC_2, *, controlr, 1)," & " 402 (BC_2, IO_AH1, output3, X, 401, 1, Z)," & -- PAD381 " 403 (BC_2, IO_AH1, input, X)," & -- PAD381 " 404 (BC_2, *, controlr, 1)," & " 405 (BC_2, IO_AG2, output3, X, 404, 1, Z)," & -- PAD380 " 406 (BC_2, IO_AG2, input, X)," & -- PAD380 " 407 (BC_2, *, controlr, 1)," & " 408 (BC_2, IO_AH5, output3, X, 407, 1, Z)," & -- PAD379 " 409 (BC_2, IO_AH5, input, X)," & -- PAD379 " 410 (BC_2, *, controlr, 1)," & " 411 (BC_2, IO_AH6, output3, X, 410, 1, Z)," & -- PAD378 " 412 (BC_2, IO_AH6, input, X)," & -- PAD378 " 413 (BC_2, *, controlr, 1)," & " 414 (BC_2, IO_AJ4, output3, X, 413, 1, Z)," & -- PAD377 " 415 (BC_2, IO_AJ4, input, X)," & -- PAD377 " 416 (BC_2, *, controlr, 1)," & " 417 (BC_2, IO_AH4, output3, X, 416, 1, Z)," & -- PAD376 " 418 (BC_2, IO_AH4, input, X)," & -- PAD376 " 419 (BC_2, *, controlr, 1)," & " 420 (BC_2, IO_AG5, output3, X, 419, 1, Z)," & -- PAD375 " 421 (BC_2, IO_AG5, input, X)," & -- PAD375 " 422 (BC_2, *, controlr, 1)," & " 423 (BC_2, IO_AF6, output3, X, 422, 1, Z)," & -- PAD374 " 424 (BC_2, IO_AF6, input, X)," & -- PAD374 " 425 (BC_2, *, controlr, 1)," & " 426 (BC_2, IO_AF5, output3, X, 425, 1, Z)," & -- PAD373 " 427 (BC_2, IO_AF5, input, X)," & -- PAD373 " 428 (BC_2, *, controlr, 1)," & " 429 (BC_2, IO_AE5, output3, X, 428, 1, Z)," & -- PAD372 " 430 (BC_2, IO_AE5, input, X)," & -- PAD372 " 431 (BC_2, *, controlr, 1)," & " 432 (BC_2, IO_AE3, output3, X, 431, 1, Z)," & -- PAD371 " 433 (BC_2, IO_AE3, input, X)," & -- PAD371 " 434 (BC_2, *, controlr, 1)," & " 435 (BC_2, IO_AE4, output3, X, 434, 1, Z)," & -- PAD370 " 436 (BC_2, IO_AE4, input, X)," & -- PAD370 " 437 (BC_2, *, controlr, 1)," & " 438 (BC_2, IO_AG3, output3, X, 437, 1, Z)," & -- PAD369 " 439 (BC_2, IO_AG3, input, X)," & -- PAD369 " 440 (BC_2, *, controlr, 1)," & " 441 (BC_2, IO_AG4, output3, X, 440, 1, Z)," & -- PAD368 " 442 (BC_2, IO_AG4, input, X)," & -- PAD368 " 443 (BC_2, *, controlr, 1)," & " 444 (BC_2, IO_AF1, output3, X, 443, 1, Z)," & -- PAD367 " 445 (BC_2, IO_AF1, input, X)," & -- PAD367 " 446 (BC_2, *, controlr, 1)," & " 447 (BC_2, IO_AE1, output3, X, 446, 1, Z)," & -- PAD366 " 448 (BC_2, IO_AE1, input, X)," & -- PAD366 " 449 (BC_2, *, controlr, 1)," & " 450 (BC_2, IO_AF2, output3, X, 449, 1, Z)," & -- PAD365 " 451 (BC_2, IO_AF2, input, X)," & -- PAD365 " 452 (BC_2, *, controlr, 1)," & " 453 (BC_2, IO_AF3, output3, X, 452, 1, Z)," & -- PAD364 " 454 (BC_2, IO_AF3, input, X)," & -- PAD364 " 455 (BC_2, *, controlr, 1)," & " 456 (BC_2, IO_AD7, output3, X, 455, 1, Z)," & -- PAD363 " 457 (BC_2, IO_AD7, input, X)," & -- PAD363 " 458 (BC_2, *, controlr, 1)," & " 459 (BC_2, IO_AC7, output3, X, 458, 1, Z)," & -- PAD362 " 460 (BC_2, IO_AC7, input, X)," & -- PAD362 " 461 (BC_2, *, controlr, 1)," & " 462 (BC_2, IO_AE6, output3, X, 461, 1, Z)," & -- PAD361 " 463 (BC_2, IO_AE6, input, X)," & -- PAD361 " 464 (BC_2, *, controlr, 1)," & " 465 (BC_2, IO_AD6, output3, X, 464, 1, Z)," & -- PAD360 " 466 (BC_2, IO_AD6, input, X)," & -- PAD360 " 467 (BC_2, *, controlr, 1)," & " 468 (BC_2, IO_AC4, output3, X, 467, 1, Z)," & -- PAD359 " 469 (BC_2, IO_AC4, input, X)," & -- PAD359 " 470 (BC_2, *, controlr, 1)," & " 471 (BC_2, IO_AC5, output3, X, 470, 1, Z)," & -- PAD358 " 472 (BC_2, IO_AC5, input, X)," & -- PAD358 " 473 (BC_2, *, controlr, 1)," & " 474 (BC_2, IO_AD1, output3, X, 473, 1, Z)," & -- PAD357 " 475 (BC_2, IO_AD1, input, X)," & -- PAD357 " 476 (BC_2, *, controlr, 1)," & " 477 (BC_2, IO_AD2, output3, X, 476, 1, Z)," & -- PAD356 " 478 (BC_2, IO_AD2, input, X)," & -- PAD356 " 479 (BC_2, *, controlr, 1)," & " 480 (BC_2, IO_AC1, output3, X, 479, 1, Z)," & -- PAD355 " 481 (BC_2, IO_AC1, input, X)," & -- PAD355 " 482 (BC_2, *, controlr, 1)," & " 483 (BC_2, IO_AC2, output3, X, 482, 1, Z)," & -- PAD354 " 484 (BC_2, IO_AC2, input, X)," & -- PAD354 " 485 (BC_2, *, controlr, 1)," & " 486 (BC_2, IO_AD3, output3, X, 485, 1, Z)," & -- PAD353 " 487 (BC_2, IO_AD3, input, X)," & -- PAD353 " 488 (BC_2, *, controlr, 1)," & " 489 (BC_2, IO_AD4, output3, X, 488, 1, Z)," & -- PAD352 " 490 (BC_2, IO_AD4, input, X)," & -- PAD352 " 491 (BC_2, *, controlr, 1)," & " 492 (BC_2, IO_AC6, output3, X, 491, 1, Z)," & -- PAD351 " 493 (BC_2, IO_AC6, input, X)," & -- PAD351 " 494 (BC_2, *, internal, X)," & " 495 (BC_2, *, internal, X)," & " 496 (BC_2, *, internal, X)," & " 497 (BC_4, MGTXRXN0_115, OBSERVE_ONLY, X)," & " 498 (BC_4, MGTXRXP0_115, OBSERVE_ONLY, X)," & " 499 (AC_2, MGTXTXP0_115, OUTPUT2, X)," & " 500 (BC_4, MGTXRXN1_115, OBSERVE_ONLY, X)," & " 501 (BC_4, MGTXRXP1_115, OBSERVE_ONLY, X)," & " 502 (AC_2, MGTXTXP1_115, OUTPUT2, X)," & " 503 (BC_4, MGTXRXN2_115, OBSERVE_ONLY, X)," & " 504 (BC_4, MGTXRXP2_115, OBSERVE_ONLY, X)," & " 505 (AC_2, MGTXTXP2_115, OUTPUT2, X)," & " 506 (BC_4, MGTXRXN3_115, OBSERVE_ONLY, X)," & " 507 (BC_4, MGTXRXP3_115, OBSERVE_ONLY, X)," & " 508 (AC_2, MGTXTXP3_115, OUTPUT2, X)," & " 509 (BC_4, MGTXRXN0_116, OBSERVE_ONLY, X)," & " 510 (BC_4, MGTXRXP0_116, OBSERVE_ONLY, X)," & " 511 (AC_2, MGTXTXP0_116, OUTPUT2, X)," & " 512 (BC_4, MGTXRXN1_116, OBSERVE_ONLY, X)," & " 513 (BC_4, MGTXRXP1_116, OBSERVE_ONLY, X)," & " 514 (AC_2, MGTXTXP1_116, OUTPUT2, X)," & " 515 (BC_4, MGTXRXN2_116, OBSERVE_ONLY, X)," & " 516 (BC_4, MGTXRXP2_116, OBSERVE_ONLY, X)," & " 517 (AC_2, MGTXTXP2_116, OUTPUT2, X)," & " 518 (BC_4, MGTXRXN3_116, OBSERVE_ONLY, X)," & " 519 (BC_4, MGTXRXP3_116, OBSERVE_ONLY, X)," & " 520 (AC_2, MGTXTXP3_116, OUTPUT2, X)," & " 521 (BC_4, MGTXRXN0_117, OBSERVE_ONLY, X)," & " 522 (BC_4, MGTXRXP0_117, OBSERVE_ONLY, X)," & " 523 (AC_2, MGTXTXP0_117, OUTPUT2, X)," & " 524 (BC_4, MGTXRXN1_117, OBSERVE_ONLY, X)," & " 525 (BC_4, MGTXRXP1_117, OBSERVE_ONLY, X)," & " 526 (AC_2, MGTXTXP1_117, OUTPUT2, X)," & " 527 (BC_4, MGTXRXN2_117, OBSERVE_ONLY, X)," & " 528 (BC_4, MGTXRXP2_117, OBSERVE_ONLY, X)," & " 529 (AC_2, MGTXTXP2_117, OUTPUT2, X)," & " 530 (BC_4, MGTXRXN3_117, OBSERVE_ONLY, X)," & " 531 (BC_4, MGTXRXP3_117, OBSERVE_ONLY, X)," & " 532 (AC_2, MGTXTXP3_117, OUTPUT2, X)," & " 533 (BC_4, MGTXRXN0_118, OBSERVE_ONLY, X)," & " 534 (BC_4, MGTXRXP0_118, OBSERVE_ONLY, X)," & " 535 (AC_2, MGTXTXP0_118, OUTPUT2, X)," & " 536 (BC_4, MGTXRXN1_118, OBSERVE_ONLY, X)," & " 537 (BC_4, MGTXRXP1_118, OBSERVE_ONLY, X)," & " 538 (AC_2, MGTXTXP1_118, OUTPUT2, X)," & " 539 (BC_4, MGTXRXN2_118, OBSERVE_ONLY, X)," & " 540 (BC_4, MGTXRXP2_118, OBSERVE_ONLY, X)," & " 541 (AC_2, MGTXTXP2_118, OUTPUT2, X)," & " 542 (BC_4, MGTXRXN3_118, OBSERVE_ONLY, X)," & " 543 (BC_4, MGTXRXP3_118, OBSERVE_ONLY, X)," & " 544 (AC_2, MGTXTXP3_118, OUTPUT2, X)," & " 545 (BC_2, *, internal, X)," & " 546 (BC_2, *, internal, X)," & " 547 (BC_2, *, internal, X)," & " 548 (BC_2, *, internal, X)," & " 549 (BC_2, *, internal, X)," & " 550 (BC_2, *, internal, X)," & " 551 (BC_2, *, internal, X)," & " 552 (BC_2, *, internal, X)," & " 553 (BC_2, *, internal, X)," & " 554 (BC_2, *, internal, X)," & " 555 (BC_2, *, internal, X)," & " 556 (BC_2, *, internal, X)," & " 557 (BC_2, *, internal, X)," & " 558 (BC_2, *, internal, X)," & " 559 (BC_2, *, internal, X)," & " 560 (BC_2, *, internal, X)," & " 561 (BC_2, *, internal, X)," & " 562 (BC_2, *, internal, X)," & " 563 (BC_2, *, internal, X)," & " 564 (BC_2, *, internal, X)," & " 565 (BC_2, *, internal, X)," & " 566 (BC_2, *, internal, X)," & " 567 (BC_2, *, internal, X)," & " 568 (BC_2, *, internal, X)," & " 569 (BC_2, *, internal, X)," & " 570 (BC_2, *, internal, X)," & " 571 (BC_2, *, controlr, 1)," & " 572 (BC_2, IO_AE20, output3, X, 571, 1, Z)," & -- PAD350 " 573 (BC_2, IO_AE20, input, X)," & -- PAD350 " 574 (BC_2, *, controlr, 1)," & " 575 (BC_2, IO_AK21, output3, X, 574, 1, Z)," & -- PAD349 " 576 (BC_2, IO_AK21, input, X)," & -- PAD349 " 577 (BC_2, *, controlr, 1)," & " 578 (BC_2, IO_AK20, output3, X, 577, 1, Z)," & -- PAD348 " 579 (BC_2, IO_AK20, input, X)," & -- PAD348 " 580 (BC_2, *, controlr, 1)," & " 581 (BC_2, IO_AJ21, output3, X, 580, 1, Z)," & -- PAD347 " 582 (BC_2, IO_AJ21, input, X)," & -- PAD347 " 583 (BC_2, *, controlr, 1)," & " 584 (BC_2, IO_AH21, output3, X, 583, 1, Z)," & -- PAD346 " 585 (BC_2, IO_AH21, input, X)," & -- PAD346 " 586 (BC_2, *, controlr, 1)," & " 587 (BC_2, IO_AH20, output3, X, 586, 1, Z)," & -- PAD345 " 588 (BC_2, IO_AH20, input, X)," & -- PAD345 " 589 (BC_2, *, controlr, 1)," & " 590 (BC_2, IO_AG20, output3, X, 589, 1, Z)," & -- PAD344 " 591 (BC_2, IO_AG20, input, X)," & -- PAD344 " 592 (BC_2, *, controlr, 1)," & " 593 (BC_2, IO_AJ23, output3, X, 592, 1, Z)," & -- PAD343 " 594 (BC_2, IO_AJ23, input, X)," & -- PAD343 " 595 (BC_2, *, controlr, 1)," & " 596 (BC_2, IO_AJ22, output3, X, 595, 1, Z)," & -- PAD342 " 597 (BC_2, IO_AJ22, input, X)," & -- PAD342 " 598 (BC_2, *, controlr, 1)," & " 599 (BC_2, IO_AH22, output3, X, 598, 1, Z)," & -- PAD341 " 600 (BC_2, IO_AH22, input, X)," & -- PAD341 " 601 (BC_2, *, controlr, 1)," & " 602 (BC_2, IO_AG22, output3, X, 601, 1, Z)," & -- PAD340 " 603 (BC_2, IO_AG22, input, X)," & -- PAD340 " 604 (BC_2, *, controlr, 1)," & " 605 (BC_2, IO_AF21, output3, X, 604, 1, Z)," & -- PAD339 " 606 (BC_2, IO_AF21, input, X)," & -- PAD339 " 607 (BC_2, *, controlr, 1)," & " 608 (BC_2, IO_AF20, output3, X, 607, 1, Z)," & -- PAD338 " 609 (BC_2, IO_AF20, input, X)," & -- PAD338 " 610 (BC_2, *, controlr, 1)," & " 611 (BC_2, IO_AH25, output3, X, 610, 1, Z)," & -- PAD337 " 612 (BC_2, IO_AH25, input, X)," & -- PAD337 " 613 (BC_2, *, controlr, 1)," & " 614 (BC_2, IO_AG25, output3, X, 613, 1, Z)," & -- PAD336 " 615 (BC_2, IO_AG25, input, X)," & -- PAD336 " 616 (BC_2, *, controlr, 1)," & " 617 (BC_2, IO_AK24, output3, X, 616, 1, Z)," & -- PAD335 " 618 (BC_2, IO_AK24, input, X)," & -- PAD335 " 619 (BC_2, *, controlr, 1)," & " 620 (BC_2, IO_AK23, output3, X, 619, 1, Z)," & -- PAD334 " 621 (BC_2, IO_AK23, input, X)," & -- PAD334 " 622 (BC_2, *, controlr, 1)," & " 623 (BC_2, IO_AF25, output3, X, 622, 1, Z)," & -- PAD333 " 624 (BC_2, IO_AF25, input, X)," & -- PAD333 " 625 (BC_2, *, controlr, 1)," & " 626 (BC_2, IO_AE25, output3, X, 625, 1, Z)," & -- PAD332 " 627 (BC_2, IO_AE25, input, X)," & -- PAD332 " 628 (BC_2, *, controlr, 1)," & " 629 (BC_2, IO_AK25, output3, X, 628, 1, Z)," & -- PAD331 " 630 (BC_2, IO_AK25, input, X)," & -- PAD331 " 631 (BC_2, *, controlr, 1)," & " 632 (BC_2, IO_AJ24, output3, X, 631, 1, Z)," & -- PAD330 " 633 (BC_2, IO_AJ24, input, X)," & -- PAD330 " 634 (BC_2, *, controlr, 1)," & " 635 (BC_2, IO_AH24, output3, X, 634, 1, Z)," & -- PAD329 " 636 (BC_2, IO_AH24, input, X)," & -- PAD329 " 637 (BC_2, *, controlr, 1)," & " 638 (BC_2, IO_AG24, output3, X, 637, 1, Z)," & -- PAD328 " 639 (BC_2, IO_AG24, input, X)," & -- PAD328 " 640 (BC_2, *, controlr, 1)," & " 641 (BC_2, IO_AG23, output3, X, 640, 1, Z)," & -- PAD327 " 642 (BC_2, IO_AG23, input, X)," & -- PAD327 " 643 (BC_2, *, controlr, 1)," & " 644 (BC_2, IO_AF22, output3, X, 643, 1, Z)," & -- PAD326 " 645 (BC_2, IO_AF22, input, X)," & -- PAD326 " 646 (BC_2, *, controlr, 1)," & " 647 (BC_2, IO_AE24, output3, X, 646, 1, Z)," & -- PAD325 " 648 (BC_2, IO_AE24, input, X)," & -- PAD325 " 649 (BC_2, *, controlr, 1)," & " 650 (BC_2, IO_AD23, output3, X, 649, 1, Z)," & -- PAD324 " 651 (BC_2, IO_AD23, input, X)," & -- PAD324 " 652 (BC_2, *, controlr, 1)," & " 653 (BC_2, IO_AF23, output3, X, 652, 1, Z)," & -- PAD323 " 654 (BC_2, IO_AF23, input, X)," & -- PAD323 " 655 (BC_2, *, controlr, 1)," & " 656 (BC_2, IO_AE23, output3, X, 655, 1, Z)," & -- PAD322 " 657 (BC_2, IO_AE23, input, X)," & -- PAD322 " 658 (BC_2, *, controlr, 1)," & " 659 (BC_2, IO_AE21, output3, X, 658, 1, Z)," & -- PAD321 " 660 (BC_2, IO_AE21, input, X)," & -- PAD321 " 661 (BC_2, *, controlr, 1)," & " 662 (BC_2, IO_AD21, output3, X, 661, 1, Z)," & -- PAD320 " 663 (BC_2, IO_AD21, input, X)," & -- PAD320 " 664 (BC_2, *, controlr, 1)," & " 665 (BC_2, IO_AD24, output3, X, 664, 1, Z)," & -- PAD319 " 666 (BC_2, IO_AD24, input, X)," & -- PAD319 " 667 (BC_2, *, controlr, 1)," & " 668 (BC_2, IO_AC24, output3, X, 667, 1, Z)," & -- PAD318 " 669 (BC_2, IO_AC24, input, X)," & -- PAD318 " 670 (BC_2, *, controlr, 1)," & " 671 (BC_2, IO_AD22, output3, X, 670, 1, Z)," & -- PAD317 " 672 (BC_2, IO_AD22, input, X)," & -- PAD317 " 673 (BC_2, *, controlr, 1)," & " 674 (BC_2, IO_AC22, output3, X, 673, 1, Z)," & -- PAD316 " 675 (BC_2, IO_AC22, input, X)," & -- PAD316 " 676 (BC_2, *, controlr, 1)," & " 677 (BC_2, IO_AC25, output3, X, 676, 1, Z)," & -- PAD315 " 678 (BC_2, IO_AC25, input, X)," & -- PAD315 " 679 (BC_2, *, controlr, 1)," & " 680 (BC_2, IO_AB24, output3, X, 679, 1, Z)," & -- PAD314 " 681 (BC_2, IO_AB24, input, X)," & -- PAD314 " 682 (BC_2, *, controlr, 1)," & " 683 (BC_2, IO_AB20, output3, X, 682, 1, Z)," & -- PAD313 " 684 (BC_2, IO_AB20, input, X)," & -- PAD313 " 685 (BC_2, *, controlr, 1)," & " 686 (BC_2, IO_AA20, output3, X, 685, 1, Z)," & -- PAD312 " 687 (BC_2, IO_AA20, input, X)," & -- PAD312 " 688 (BC_2, *, controlr, 1)," & " 689 (BC_2, IO_AC21, output3, X, 688, 1, Z)," & -- PAD311 " 690 (BC_2, IO_AC21, input, X)," & -- PAD311 " 691 (BC_2, *, controlr, 1)," & " 692 (BC_2, IO_AC20, output3, X, 691, 1, Z)," & -- PAD310 " 693 (BC_2, IO_AC20, input, X)," & -- PAD310 " 694 (BC_2, *, controlr, 1)," & " 695 (BC_2, IO_AA23, output3, X, 694, 1, Z)," & -- PAD309 " 696 (BC_2, IO_AA23, input, X)," & -- PAD309 " 697 (BC_2, *, controlr, 1)," & " 698 (BC_2, IO_AA22, output3, X, 697, 1, Z)," & -- PAD308 " 699 (BC_2, IO_AA22, input, X)," & -- PAD308 " 700 (BC_2, *, controlr, 1)," & " 701 (BC_2, IO_AB23, output3, X, 700, 1, Z)," & -- PAD307 " 702 (BC_2, IO_AB23, input, X)," & -- PAD307 " 703 (BC_2, *, controlr, 1)," & " 704 (BC_2, IO_AB22, output3, X, 703, 1, Z)," & -- PAD306 " 705 (BC_2, IO_AB22, input, X)," & -- PAD306 " 706 (BC_2, *, controlr, 1)," & " 707 (BC_2, IO_AA21, output3, X, 706, 1, Z)," & -- PAD305 " 708 (BC_2, IO_AA21, input, X)," & -- PAD305 " 709 (BC_2, *, controlr, 1)," & " 710 (BC_2, IO_Y21, output3, X, 709, 1, Z)," & -- PAD304 " 711 (BC_2, IO_Y21, input, X)," & -- PAD304 " 712 (BC_2, *, controlr, 1)," & " 713 (BC_2, IO_Y24, output3, X, 712, 1, Z)," & -- PAD303 " 714 (BC_2, IO_Y24, input, X)," & -- PAD303 " 715 (BC_2, *, controlr, 1)," & " 716 (BC_2, IO_Y23, output3, X, 715, 1, Z)," & -- PAD302 " 717 (BC_2, IO_Y23, input, X)," & -- PAD302 " 718 (BC_2, *, controlr, 1)," & " 719 (BC_2, IO_Y20, output3, X, 718, 1, Z)," & -- PAD301 " 720 (BC_2, IO_Y20, input, X)," & -- PAD301 " 721 (BC_2, *, controlr, 1)," & " 722 (BC_2, IO_AE26, output3, X, 721, 1, Z)," & -- PAD300 " 723 (BC_2, IO_AE26, input, X)," & -- PAD300 " 724 (BC_2, *, controlr, 1)," & " 725 (BC_2, IO_AK26, output3, X, 724, 1, Z)," & -- PAD299 " 726 (BC_2, IO_AK26, input, X)," & -- PAD299 " 727 (BC_2, *, controlr, 1)," & " 728 (BC_2, IO_AJ26, output3, X, 727, 1, Z)," & -- PAD298 " 729 (BC_2, IO_AJ26, input, X)," & -- PAD298 " 730 (BC_2, *, controlr, 1)," & " 731 (BC_2, IO_AF27, output3, X, 730, 1, Z)," & -- PAD297 " 732 (BC_2, IO_AF27, input, X)," & -- PAD297 " 733 (BC_2, *, controlr, 1)," & " 734 (BC_2, IO_AF26, output3, X, 733, 1, Z)," & -- PAD296 " 735 (BC_2, IO_AF26, input, X)," & -- PAD296 " 736 (BC_2, *, controlr, 1)," & " 737 (BC_2, IO_AH27, output3, X, 736, 1, Z)," & -- PAD295 " 738 (BC_2, IO_AH27, input, X)," & -- PAD295 " 739 (BC_2, *, controlr, 1)," & " 740 (BC_2, IO_AH26, output3, X, 739, 1, Z)," & -- PAD294 " 741 (BC_2, IO_AH26, input, X)," & -- PAD294 " 742 (BC_2, *, controlr, 1)," & " 743 (BC_2, IO_AG28, output3, X, 742, 1, Z)," & -- PAD293 " 744 (BC_2, IO_AG28, input, X)," & -- PAD293 " 745 (BC_2, *, controlr, 1)," & " 746 (BC_2, IO_AG27, output3, X, 745, 1, Z)," & -- PAD292 " 747 (BC_2, IO_AG27, input, X)," & -- PAD292 " 748 (BC_2, *, controlr, 1)," & " 749 (BC_2, IO_AK28, output3, X, 748, 1, Z)," & -- PAD291 " 750 (BC_2, IO_AK28, input, X)," & -- PAD291 " 751 (BC_2, *, controlr, 1)," & " 752 (BC_2, IO_AJ27, output3, X, 751, 1, Z)," & -- PAD290 " 753 (BC_2, IO_AJ27, input, X)," & -- PAD290 " 754 (BC_2, *, controlr, 1)," & " 755 (BC_2, IO_AD26, output3, X, 754, 1, Z)," & -- PAD289 " 756 (BC_2, IO_AD26, input, X)," & -- PAD289 " 757 (BC_2, *, controlr, 1)," & " 758 (BC_2, IO_AC26, output3, X, 757, 1, Z)," & -- PAD288 " 759 (BC_2, IO_AC26, input, X)," & -- PAD288 " 760 (BC_2, *, controlr, 1)," & " 761 (BC_2, IO_AH30, output3, X, 760, 1, Z)," & -- PAD287 " 762 (BC_2, IO_AH30, input, X)," & -- PAD287 " 763 (BC_2, *, controlr, 1)," & " 764 (BC_2, IO_AG30, output3, X, 763, 1, Z)," & -- PAD286 " 765 (BC_2, IO_AG30, input, X)," & -- PAD286 " 766 (BC_2, *, controlr, 1)," & " 767 (BC_2, IO_AJ29, output3, X, 766, 1, Z)," & -- PAD285 " 768 (BC_2, IO_AJ29, input, X)," & -- PAD285 " 769 (BC_2, *, controlr, 1)," & " 770 (BC_2, IO_AJ28, output3, X, 769, 1, Z)," & -- PAD284 " 771 (BC_2, IO_AJ28, input, X)," & -- PAD284 " 772 (BC_2, *, controlr, 1)," & " 773 (BC_2, IO_AF30, output3, X, 772, 1, Z)," & -- PAD283 " 774 (BC_2, IO_AF30, input, X)," & -- PAD283 " 775 (BC_2, *, controlr, 1)," & " 776 (BC_2, IO_AE30, output3, X, 775, 1, Z)," & -- PAD282 " 777 (BC_2, IO_AE30, input, X)," & -- PAD282 " 778 (BC_2, *, controlr, 1)," & " 779 (BC_2, IO_AK30, output3, X, 778, 1, Z)," & -- PAD281 " 780 (BC_2, IO_AK30, input, X)," & -- PAD281 " 781 (BC_2, *, controlr, 1)," & " 782 (BC_2, IO_AK29, output3, X, 781, 1, Z)," & -- PAD280 " 783 (BC_2, IO_AK29, input, X)," & -- PAD280 " 784 (BC_2, *, controlr, 1)," & " 785 (BC_2, IO_AF28, output3, X, 784, 1, Z)," & -- PAD279 " 786 (BC_2, IO_AF28, input, X)," & -- PAD279 " 787 (BC_2, *, controlr, 1)," & " 788 (BC_2, IO_AE28, output3, X, 787, 1, Z)," & -- PAD278 " 789 (BC_2, IO_AE28, input, X)," & -- PAD278 " 790 (BC_2, *, controlr, 1)," & " 791 (BC_2, IO_AH29, output3, X, 790, 1, Z)," & -- PAD277 " 792 (BC_2, IO_AH29, input, X)," & -- PAD277 " 793 (BC_2, *, controlr, 1)," & " 794 (BC_2, IO_AG29, output3, X, 793, 1, Z)," & -- PAD276 " 795 (BC_2, IO_AG29, input, X)," & -- PAD276 " 796 (BC_2, *, controlr, 1)," & " 797 (BC_2, IO_AC27, output3, X, 796, 1, Z)," & -- PAD275 " 798 (BC_2, IO_AC27, input, X)," & -- PAD275 " 799 (BC_2, *, controlr, 1)," & " 800 (BC_2, IO_AB27, output3, X, 799, 1, Z)," & -- PAD274 " 801 (BC_2, IO_AB27, input, X)," & -- PAD274 " 802 (BC_2, *, controlr, 1)," & " 803 (BC_2, IO_AD28, output3, X, 802, 1, Z)," & -- PAD273 " 804 (BC_2, IO_AD28, input, X)," & -- PAD273 " 805 (BC_2, *, controlr, 1)," & " 806 (BC_2, IO_AD27, output3, X, 805, 1, Z)," & -- PAD272 " 807 (BC_2, IO_AD27, input, X)," & -- PAD272 " 808 (BC_2, *, controlr, 1)," & " 809 (BC_2, IO_AB30, output3, X, 808, 1, Z)," & -- PAD271 " 810 (BC_2, IO_AB30, input, X)," & -- PAD271 " 811 (BC_2, *, controlr, 1)," & " 812 (BC_2, IO_AB29, output3, X, 811, 1, Z)," & -- PAD270 " 813 (BC_2, IO_AB29, input, X)," & -- PAD270 " 814 (BC_2, *, controlr, 1)," & " 815 (BC_2, IO_AE29, output3, X, 814, 1, Z)," & -- PAD269 " 816 (BC_2, IO_AE29, input, X)," & -- PAD269 " 817 (BC_2, *, controlr, 1)," & " 818 (BC_2, IO_AD29, output3, X, 817, 1, Z)," & -- PAD268 " 819 (BC_2, IO_AD29, input, X)," & -- PAD268 " 820 (BC_2, *, controlr, 1)," & " 821 (BC_2, IO_AA30, output3, X, 820, 1, Z)," & -- PAD267 " 822 (BC_2, IO_AA30, input, X)," & -- PAD267 " 823 (BC_2, *, controlr, 1)," & " 824 (BC_2, IO_Y30, output3, X, 823, 1, Z)," & -- PAD266 " 825 (BC_2, IO_Y30, input, X)," & -- PAD266 " 826 (BC_2, *, controlr, 1)," & " 827 (BC_2, IO_AC30, output3, X, 826, 1, Z)," & -- PAD265 " 828 (BC_2, IO_AC30, input, X)," & -- PAD265 " 829 (BC_2, *, controlr, 1)," & " 830 (BC_2, IO_AC29, output3, X, 829, 1, Z)," & -- PAD264 " 831 (BC_2, IO_AC29, input, X)," & -- PAD264 " 832 (BC_2, *, controlr, 1)," & " 833 (BC_2, IO_AB25, output3, X, 832, 1, Z)," & -- PAD263 " 834 (BC_2, IO_AB25, input, X)," & -- PAD263 " 835 (BC_2, *, controlr, 1)," & " 836 (BC_2, IO_AA25, output3, X, 835, 1, Z)," & -- PAD262 " 837 (BC_2, IO_AA25, input, X)," & -- PAD262 " 838 (BC_2, *, controlr, 1)," & " 839 (BC_2, IO_AB28, output3, X, 838, 1, Z)," & -- PAD261 " 840 (BC_2, IO_AB28, input, X)," & -- PAD261 " 841 (BC_2, *, controlr, 1)," & " 842 (BC_2, IO_AA27, output3, X, 841, 1, Z)," & -- PAD260 " 843 (BC_2, IO_AA27, input, X)," & -- PAD260 " 844 (BC_2, *, controlr, 1)," & " 845 (BC_2, IO_Y29, output3, X, 844, 1, Z)," & -- PAD259 " 846 (BC_2, IO_Y29, input, X)," & -- PAD259 " 847 (BC_2, *, controlr, 1)," & " 848 (BC_2, IO_W29, output3, X, 847, 1, Z)," & -- PAD258 " 849 (BC_2, IO_W29, input, X)," & -- PAD258 " 850 (BC_2, *, controlr, 1)," & " 851 (BC_2, IO_AA28, output3, X, 850, 1, Z)," & -- PAD257 " 852 (BC_2, IO_AA28, input, X)," & -- PAD257 " 853 (BC_2, *, controlr, 1)," & " 854 (BC_2, IO_Y28, output3, X, 853, 1, Z)," & -- PAD256 " 855 (BC_2, IO_Y28, input, X)," & -- PAD256 " 856 (BC_2, *, controlr, 1)," & " 857 (BC_2, IO_W28, output3, X, 856, 1, Z)," & -- PAD255 " 858 (BC_2, IO_W28, input, X)," & -- PAD255 " 859 (BC_2, *, controlr, 1)," & " 860 (BC_2, IO_W27, output3, X, 859, 1, Z)," & -- PAD254 " 861 (BC_2, IO_W27, input, X)," & -- PAD254 " 862 (BC_2, *, controlr, 1)," & " 863 (BC_2, IO_AA26, output3, X, 862, 1, Z)," & -- PAD253 " 864 (BC_2, IO_AA26, input, X)," & -- PAD253 " 865 (BC_2, *, controlr, 1)," & " 866 (BC_2, IO_Y26, output3, X, 865, 1, Z)," & -- PAD252 " 867 (BC_2, IO_Y26, input, X)," & -- PAD252 " 868 (BC_2, *, controlr, 1)," & " 869 (BC_2, IO_Y25, output3, X, 868, 1, Z)," & -- PAD251 " 870 (BC_2, IO_Y25, input, X)," & -- PAD251 " 871 (BC_2, *, controlr, 1)," & " 872 (BC_2, IO_W19, output3, X, 871, 1, Z)," & -- PAD250 " 873 (BC_2, IO_W19, input, X)," & -- PAD250 " 874 (BC_2, *, controlr, 1)," & " 875 (BC_2, IO_W22, output3, X, 874, 1, Z)," & -- PAD249 " 876 (BC_2, IO_W22, input, X)," & -- PAD249 " 877 (BC_2, *, controlr, 1)," & " 878 (BC_2, IO_W21, output3, X, 877, 1, Z)," & -- PAD248 " 879 (BC_2, IO_W21, input, X)," & -- PAD248 " 880 (BC_2, *, controlr, 1)," & " 881 (BC_2, IO_V24, output3, X, 880, 1, Z)," & -- PAD247 " 882 (BC_2, IO_V24, input, X)," & -- PAD247 " 883 (BC_2, *, controlr, 1)," & " 884 (BC_2, IO_U24, output3, X, 883, 1, Z)," & -- PAD246 " 885 (BC_2, IO_U24, input, X)," & -- PAD246 " 886 (BC_2, *, controlr, 1)," & " 887 (BC_2, IO_V22, output3, X, 886, 1, Z)," & -- PAD245 " 888 (BC_2, IO_V22, input, X)," & -- PAD245 " 889 (BC_2, *, controlr, 1)," & " 890 (BC_2, IO_V21, output3, X, 889, 1, Z)," & -- PAD244 " 891 (BC_2, IO_V21, input, X)," & -- PAD244 " 892 (BC_2, *, controlr, 1)," & " 893 (BC_2, IO_U23, output3, X, 892, 1, Z)," & -- PAD243 " 894 (BC_2, IO_U23, input, X)," & -- PAD243 " 895 (BC_2, *, controlr, 1)," & " 896 (BC_2, IO_U22, output3, X, 895, 1, Z)," & -- PAD242 " 897 (BC_2, IO_U22, input, X)," & -- PAD242 " 898 (BC_2, *, controlr, 1)," & " 899 (BC_2, IO_W24, output3, X, 898, 1, Z)," & -- PAD241 " 900 (BC_2, IO_W24, input, X)," & -- PAD241 " 901 (BC_2, *, controlr, 1)," & " 902 (BC_2, IO_W23, output3, X, 901, 1, Z)," & -- PAD240 " 903 (BC_2, IO_W23, input, X)," & -- PAD240 " 904 (BC_2, *, controlr, 1)," & " 905 (BC_2, IO_V20, output3, X, 904, 1, Z)," & -- PAD239 " 906 (BC_2, IO_V20, input, X)," & -- PAD239 " 907 (BC_2, *, controlr, 1)," & " 908 (BC_2, IO_V19, output3, X, 907, 1, Z)," & -- PAD238 " 909 (BC_2, IO_V19, input, X)," & -- PAD238 " 910 (BC_2, *, controlr, 1)," & " 911 (BC_2, IO_W26, output3, X, 910, 1, Z)," & -- PAD237 " 912 (BC_2, IO_W26, input, X)," & -- PAD237 " 913 (BC_2, *, controlr, 1)," & " 914 (BC_2, IO_V25, output3, X, 913, 1, Z)," & -- PAD236 " 915 (BC_2, IO_V25, input, X)," & -- PAD236 " 916 (BC_2, *, controlr, 1)," & " 917 (BC_2, IO_V30, output3, X, 916, 1, Z)," & -- PAD235 " 918 (BC_2, IO_V30, input, X)," & -- PAD235 " 919 (BC_2, *, controlr, 1)," & " 920 (BC_2, IO_V29, output3, X, 919, 1, Z)," & -- PAD234 " 921 (BC_2, IO_V29, input, X)," & -- PAD234 " 922 (BC_2, *, controlr, 1)," & " 923 (BC_2, IO_V27, output3, X, 922, 1, Z)," & -- PAD233 " 924 (BC_2, IO_V27, input, X)," & -- PAD233 " 925 (BC_2, *, controlr, 1)," & " 926 (BC_2, IO_V26, output3, X, 925, 1, Z)," & -- PAD232 " 927 (BC_2, IO_V26, input, X)," & -- PAD232 " 928 (BC_2, *, controlr, 1)," & " 929 (BC_2, IO_U30, output3, X, 928, 1, Z)," & -- PAD231 " 930 (BC_2, IO_U30, input, X)," & -- PAD231 " 931 (BC_2, *, controlr, 1)," & " 932 (BC_2, IO_U29, output3, X, 931, 1, Z)," & -- PAD230 " 933 (BC_2, IO_U29, input, X)," & -- PAD230 " 934 (BC_2, *, controlr, 1)," & " 935 (BC_2, IO_U25, output3, X, 934, 1, Z)," & -- PAD229 " 936 (BC_2, IO_U25, input, X)," & -- PAD229 " 937 (BC_2, *, controlr, 1)," & " 938 (BC_2, IO_T25, output3, X, 937, 1, Z)," & -- PAD228 " 939 (BC_2, IO_T25, input, X)," & -- PAD228 " 940 (BC_2, *, controlr, 1)," & " 941 (BC_2, IO_U28, output3, X, 940, 1, Z)," & -- PAD227 " 942 (BC_2, IO_U28, input, X)," & -- PAD227 " 943 (BC_2, *, controlr, 1)," & " 944 (BC_2, IO_U27, output3, X, 943, 1, Z)," & -- PAD226 " 945 (BC_2, IO_U27, input, X)," & -- PAD226 " 946 (BC_2, *, controlr, 1)," & " 947 (BC_2, IO_T27, output3, X, 946, 1, Z)," & -- PAD225 " 948 (BC_2, IO_T27, input, X)," & -- PAD225 " 949 (BC_2, *, controlr, 1)," & " 950 (BC_2, IO_T26, output3, X, 949, 1, Z)," & -- PAD224 " 951 (BC_2, IO_T26, input, X)," & -- PAD224 " 952 (BC_2, *, controlr, 1)," & " 953 (BC_2, IO_T28, output3, X, 952, 1, Z)," & -- PAD223 " 954 (BC_2, IO_T28, input, X)," & -- PAD223 " 955 (BC_2, *, controlr, 1)," & " 956 (BC_2, IO_R28, output3, X, 955, 1, Z)," & -- PAD222 " 957 (BC_2, IO_R28, input, X)," & -- PAD222 " 958 (BC_2, *, controlr, 1)," & " 959 (BC_2, IO_R26, output3, X, 958, 1, Z)," & -- PAD221 " 960 (BC_2, IO_R26, input, X)," & -- PAD221 " 961 (BC_2, *, controlr, 1)," & " 962 (BC_2, IO_P26, output3, X, 961, 1, Z)," & -- PAD220 " 963 (BC_2, IO_P26, input, X)," & -- PAD220 " 964 (BC_2, *, controlr, 1)," & " 965 (BC_2, IO_T30, output3, X, 964, 1, Z)," & -- PAD219 " 966 (BC_2, IO_T30, input, X)," & -- PAD219 " 967 (BC_2, *, controlr, 1)," & " 968 (BC_2, IO_R30, output3, X, 967, 1, Z)," & -- PAD218 " 969 (BC_2, IO_R30, input, X)," & -- PAD218 " 970 (BC_2, *, controlr, 1)," & " 971 (BC_2, IO_P28, output3, X, 970, 1, Z)," & -- PAD217 " 972 (BC_2, IO_P28, input, X)," & -- PAD217 " 973 (BC_2, *, controlr, 1)," & " 974 (BC_2, IO_P27, output3, X, 973, 1, Z)," & -- PAD216 " 975 (BC_2, IO_P27, input, X)," & -- PAD216 " 976 (BC_2, *, controlr, 1)," & " 977 (BC_2, IO_R29, output3, X, 976, 1, Z)," & -- PAD215 " 978 (BC_2, IO_R29, input, X)," & -- PAD215 " 979 (BC_2, *, controlr, 1)," & " 980 (BC_2, IO_P29, output3, X, 979, 1, Z)," & -- PAD214 " 981 (BC_2, IO_P29, input, X)," & -- PAD214 " 982 (BC_2, *, controlr, 1)," & " 983 (BC_2, IO_U20, output3, X, 982, 1, Z)," & -- PAD213 " 984 (BC_2, IO_U20, input, X)," & -- PAD213 " 985 (BC_2, *, controlr, 1)," & " 986 (BC_2, IO_U19, output3, X, 985, 1, Z)," & -- PAD212 " 987 (BC_2, IO_U19, input, X)," & -- PAD212 " 988 (BC_2, *, controlr, 1)," & " 989 (BC_2, IO_T23, output3, X, 988, 1, Z)," & -- PAD211 " 990 (BC_2, IO_T23, input, X)," & -- PAD211 " 991 (BC_2, *, controlr, 1)," & " 992 (BC_2, IO_T22, output3, X, 991, 1, Z)," & -- PAD210 " 993 (BC_2, IO_T22, input, X)," & -- PAD210 " 994 (BC_2, *, controlr, 1)," & " 995 (BC_2, IO_T21, output3, X, 994, 1, Z)," & -- PAD209 " 996 (BC_2, IO_T21, input, X)," & -- PAD209 " 997 (BC_2, *, controlr, 1)," & " 998 (BC_2, IO_T20, output3, X, 997, 1, Z)," & -- PAD208 " 999 (BC_2, IO_T20, input, X)," & -- PAD208 "1000 (BC_2, *, controlr, 1)," & "1001 (BC_2, IO_R24, output3, X, 1000, 1, Z)," & -- PAD207 "1002 (BC_2, IO_R24, input, X)," & -- PAD207 "1003 (BC_2, *, controlr, 1)," & "1004 (BC_2, IO_R23, output3, X, 1003, 1, Z)," & -- PAD206 "1005 (BC_2, IO_R23, input, X)," & -- PAD206 "1006 (BC_2, *, controlr, 1)," & "1007 (BC_2, IO_R21, output3, X, 1006, 1, Z)," & -- PAD205 "1008 (BC_2, IO_R21, input, X)," & -- PAD205 "1009 (BC_2, *, controlr, 1)," & "1010 (BC_2, IO_R20, output3, X, 1009, 1, Z)," & -- PAD204 "1011 (BC_2, IO_R20, input, X)," & -- PAD204 "1012 (BC_2, *, controlr, 1)," & "1013 (BC_2, IO_R25, output3, X, 1012, 1, Z)," & -- PAD203 "1014 (BC_2, IO_R25, input, X)," & -- PAD203 "1015 (BC_2, *, controlr, 1)," & "1016 (BC_2, IO_P24, output3, X, 1015, 1, Z)," & -- PAD202 "1017 (BC_2, IO_P24, input, X)," & -- PAD202 "1018 (BC_2, *, controlr, 1)," & "1019 (BC_2, IO_R19, output3, X, 1018, 1, Z)," & -- PAD201 "1020 (BC_2, IO_R19, input, X)," & -- PAD201 "1021 (BC_2, *, controlr, 1)," & "1022 (BC_2, IO_P19, output3, X, 1021, 1, Z)," & -- PAD200 "1023 (BC_2, IO_P19, input, X)," & -- PAD200 "1024 (BC_2, *, controlr, 1)," & "1025 (BC_2, IO_M23, output3, X, 1024, 1, Z)," & -- PAD199 "1026 (BC_2, IO_M23, input, X)," & -- PAD199 "1027 (BC_2, *, controlr, 1)," & "1028 (BC_2, IO_M22, output3, X, 1027, 1, Z)," & -- PAD198 "1029 (BC_2, IO_M22, input, X)," & -- PAD198 "1030 (BC_2, *, controlr, 1)," & "1031 (BC_2, IO_M25, output3, X, 1030, 1, Z)," & -- PAD197 "1032 (BC_2, IO_M25, input, X)," & -- PAD197 "1033 (BC_2, *, controlr, 1)," & "1034 (BC_2, IO_M24, output3, X, 1033, 1, Z)," & -- PAD196 "1035 (BC_2, IO_M24, input, X)," & -- PAD196 "1036 (BC_2, *, controlr, 1)," & "1037 (BC_2, IO_P22, output3, X, 1036, 1, Z)," & -- PAD195 "1038 (BC_2, IO_P22, input, X)," & -- PAD195 "1039 (BC_2, *, controlr, 1)," & "1040 (BC_2, IO_P21, output3, X, 1039, 1, Z)," & -- PAD194 "1041 (BC_2, IO_P21, input, X)," & -- PAD194 "1042 (BC_2, *, controlr, 1)," & "1043 (BC_2, IO_N24, output3, X, 1042, 1, Z)," & -- PAD193 "1044 (BC_2, IO_N24, input, X)," & -- PAD193 "1045 (BC_2, *, controlr, 1)," & "1046 (BC_2, IO_P23, output3, X, 1045, 1, Z)," & -- PAD192 "1047 (BC_2, IO_P23, input, X)," & -- PAD192 "1048 (BC_2, *, controlr, 1)," & "1049 (BC_2, IO_N22, output3, X, 1048, 1, Z)," & -- PAD191 "1050 (BC_2, IO_N22, input, X)," & -- PAD191 "1051 (BC_2, *, controlr, 1)," & "1052 (BC_2, IO_N21, output3, X, 1051, 1, Z)," & -- PAD190 "1053 (BC_2, IO_N21, input, X)," & -- PAD190 "1054 (BC_2, *, controlr, 1)," & "1055 (BC_2, IO_N20, output3, X, 1054, 1, Z)," & -- PAD189 "1056 (BC_2, IO_N20, input, X)," & -- PAD189 "1057 (BC_2, *, controlr, 1)," & "1058 (BC_2, IO_N19, output3, X, 1057, 1, Z)," & -- PAD188 "1059 (BC_2, IO_N19, input, X)," & -- PAD188 "1060 (BC_2, *, controlr, 1)," & "1061 (BC_2, IO_N26, output3, X, 1060, 1, Z)," & -- PAD187 "1062 (BC_2, IO_N26, input, X)," & -- PAD187 "1063 (BC_2, *, controlr, 1)," & "1064 (BC_2, IO_N25, output3, X, 1063, 1, Z)," & -- PAD186 "1065 (BC_2, IO_N25, input, X)," & -- PAD186 "1066 (BC_2, *, controlr, 1)," & "1067 (BC_2, IO_N30, output3, X, 1066, 1, Z)," & -- PAD185 "1068 (BC_2, IO_N30, input, X)," & -- PAD185 "1069 (BC_2, *, controlr, 1)," & "1070 (BC_2, IO_N29, output3, X, 1069, 1, Z)," & -- PAD184 "1071 (BC_2, IO_N29, input, X)," & -- PAD184 "1072 (BC_2, *, controlr, 1)," & "1073 (BC_2, IO_M27, output3, X, 1072, 1, Z)," & -- PAD183 "1074 (BC_2, IO_M27, input, X)," & -- PAD183 "1075 (BC_2, *, controlr, 1)," & "1076 (BC_2, IO_N27, output3, X, 1075, 1, Z)," & -- PAD182 "1077 (BC_2, IO_N27, input, X)," & -- PAD182 "1078 (BC_2, *, controlr, 1)," & "1079 (BC_2, IO_M30, output3, X, 1078, 1, Z)," & -- PAD181 "1080 (BC_2, IO_M30, input, X)," & -- PAD181 "1081 (BC_2, *, controlr, 1)," & "1082 (BC_2, IO_M29, output3, X, 1081, 1, Z)," & -- PAD180 "1083 (BC_2, IO_M29, input, X)," & -- PAD180 "1084 (BC_2, *, controlr, 1)," & "1085 (BC_2, IO_L28, output3, X, 1084, 1, Z)," & -- PAD179 "1086 (BC_2, IO_L28, input, X)," & -- PAD179 "1087 (BC_2, *, controlr, 1)," & "1088 (BC_2, IO_M28, output3, X, 1087, 1, Z)," & -- PAD178 "1089 (BC_2, IO_M28, input, X)," & -- PAD178 "1090 (BC_2, *, controlr, 1)," & "1091 (BC_2, IO_K29, output3, X, 1090, 1, Z)," & -- PAD177 "1092 (BC_2, IO_K29, input, X)," & -- PAD177 "1093 (BC_2, *, controlr, 1)," & "1094 (BC_2, IO_K28, output3, X, 1093, 1, Z)," & -- PAD176 "1095 (BC_2, IO_K28, input, X)," & -- PAD176 "1096 (BC_2, *, controlr, 1)," & "1097 (BC_2, IO_K25, output3, X, 1096, 1, Z)," & -- PAD175 "1098 (BC_2, IO_K25, input, X)," & -- PAD175 "1099 (BC_2, *, controlr, 1)," & "1100 (BC_2, IO_L25, output3, X, 1099, 1, Z)," & -- PAD174 "1101 (BC_2, IO_L25, input, X)," & -- PAD174 "1102 (BC_2, *, controlr, 1)," & "1103 (BC_2, IO_L27, output3, X, 1102, 1, Z)," & -- PAD173 "1104 (BC_2, IO_L27, input, X)," & -- PAD173 "1105 (BC_2, *, controlr, 1)," & "1106 (BC_2, IO_L26, output3, X, 1105, 1, Z)," & -- PAD172 "1107 (BC_2, IO_L26, input, X)," & -- PAD172 "1108 (BC_2, *, controlr, 1)," & "1109 (BC_2, IO_J26, output3, X, 1108, 1, Z)," & -- PAD171 "1110 (BC_2, IO_J26, input, X)," & -- PAD171 "1111 (BC_2, *, controlr, 1)," & "1112 (BC_2, IO_K26, output3, X, 1111, 1, Z)," & -- PAD170 "1113 (BC_2, IO_K26, input, X)," & -- PAD170 "1114 (BC_2, *, controlr, 1)," & "1115 (BC_2, IO_K30, output3, X, 1114, 1, Z)," & -- PAD169 "1116 (BC_2, IO_K30, input, X)," & -- PAD169 "1117 (BC_2, *, controlr, 1)," & "1118 (BC_2, IO_L30, output3, X, 1117, 1, Z)," & -- PAD168 "1119 (BC_2, IO_L30, input, X)," & -- PAD168 "1120 (BC_2, *, controlr, 1)," & "1121 (BC_2, IO_J28, output3, X, 1120, 1, Z)," & -- PAD167 "1122 (BC_2, IO_J28, input, X)," & -- PAD167 "1123 (BC_2, *, controlr, 1)," & "1124 (BC_2, IO_J27, output3, X, 1123, 1, Z)," & -- PAD166 "1125 (BC_2, IO_J27, input, X)," & -- PAD166 "1126 (BC_2, *, controlr, 1)," & "1127 (BC_2, IO_H29, output3, X, 1126, 1, Z)," & -- PAD165 "1128 (BC_2, IO_H29, input, X)," & -- PAD165 "1129 (BC_2, *, controlr, 1)," & "1130 (BC_2, IO_J29, output3, X, 1129, 1, Z)," & -- PAD164 "1131 (BC_2, IO_J29, input, X)," & -- PAD164 "1132 (BC_2, *, controlr, 1)," & "1133 (BC_2, IO_L20, output3, X, 1132, 1, Z)," & -- PAD163 "1134 (BC_2, IO_L20, input, X)," & -- PAD163 "1135 (BC_2, *, controlr, 1)," & "1136 (BC_2, IO_M20, output3, X, 1135, 1, Z)," & -- PAD162 "1137 (BC_2, IO_M20, input, X)," & -- PAD162 "1138 (BC_2, *, controlr, 1)," & "1139 (BC_2, IO_J22, output3, X, 1138, 1, Z)," & -- PAD161 "1140 (BC_2, IO_J22, input, X)," & -- PAD161 "1141 (BC_2, *, controlr, 1)," & "1142 (BC_2, IO_J21, output3, X, 1141, 1, Z)," & -- PAD160 "1143 (BC_2, IO_J21, input, X)," & -- PAD160 "1144 (BC_2, *, controlr, 1)," & "1145 (BC_2, IO_K21, output3, X, 1144, 1, Z)," & -- PAD159 "1146 (BC_2, IO_K21, input, X)," & -- PAD159 "1147 (BC_2, *, controlr, 1)," & "1148 (BC_2, IO_L21, output3, X, 1147, 1, Z)," & -- PAD158 "1149 (BC_2, IO_L21, input, X)," & -- PAD158 "1150 (BC_2, *, controlr, 1)," & "1151 (BC_2, IO_K24, output3, X, 1150, 1, Z)," & -- PAD157 "1152 (BC_2, IO_K24, input, X)," & -- PAD157 "1153 (BC_2, *, controlr, 1)," & "1154 (BC_2, IO_K23, output3, X, 1153, 1, Z)," & -- PAD156 "1155 (BC_2, IO_K23, input, X)," & -- PAD156 "1156 (BC_2, *, controlr, 1)," & "1157 (BC_2, IO_L23, output3, X, 1156, 1, Z)," & -- PAD155 "1158 (BC_2, IO_L23, input, X)," & -- PAD155 "1159 (BC_2, *, controlr, 1)," & "1160 (BC_2, IO_L22, output3, X, 1159, 1, Z)," & -- PAD154 "1161 (BC_2, IO_L22, input, X)," & -- PAD154 "1162 (BC_2, *, controlr, 1)," & "1163 (BC_2, IO_J24, output3, X, 1162, 1, Z)," & -- PAD153 "1164 (BC_2, IO_J24, input, X)," & -- PAD153 "1165 (BC_2, *, controlr, 1)," & "1166 (BC_2, IO_J23, output3, X, 1165, 1, Z)," & -- PAD152 "1167 (BC_2, IO_J23, input, X)," & -- PAD152 "1168 (BC_2, *, controlr, 1)," & "1169 (BC_2, IO_M19, output3, X, 1168, 1, Z)," & -- PAD151 "1170 (BC_2, IO_M19, input, X)," & -- PAD151 "1171 (BC_2, *, controlr, 1)," & "1172 (BC_2, IO_G25, output3, X, 1171, 1, Z)," & -- PAD150 "1173 (BC_2, IO_G25, input, X)," & -- PAD150 "1174 (BC_2, *, controlr, 1)," & "1175 (BC_2, IO_G30, output3, X, 1174, 1, Z)," & -- PAD149 "1176 (BC_2, IO_G30, input, X)," & -- PAD149 "1177 (BC_2, *, controlr, 1)," & "1178 (BC_2, IO_H30, output3, X, 1177, 1, Z)," & -- PAD148 "1179 (BC_2, IO_H30, input, X)," & -- PAD148 "1180 (BC_2, *, controlr, 1)," & "1181 (BC_2, IO_H27, output3, X, 1180, 1, Z)," & -- PAD147 "1182 (BC_2, IO_H27, input, X)," & -- PAD147 "1183 (BC_2, *, controlr, 1)," & "1184 (BC_2, IO_H26, output3, X, 1183, 1, Z)," & -- PAD146 "1185 (BC_2, IO_H26, input, X)," & -- PAD146 "1186 (BC_2, *, controlr, 1)," & "1187 (BC_2, IO_F30, output3, X, 1186, 1, Z)," & -- PAD145 "1188 (BC_2, IO_F30, input, X)," & -- PAD145 "1189 (BC_2, *, controlr, 1)," & "1190 (BC_2, IO_G29, output3, X, 1189, 1, Z)," & -- PAD144 "1191 (BC_2, IO_G29, input, X)," & -- PAD144 "1192 (BC_2, *, controlr, 1)," & "1193 (BC_2, IO_F27, output3, X, 1192, 1, Z)," & -- PAD143 "1194 (BC_2, IO_F27, input, X)," & -- PAD143 "1195 (BC_2, *, controlr, 1)," & "1196 (BC_2, IO_G27, output3, X, 1195, 1, Z)," & -- PAD142 "1197 (BC_2, IO_G27, input, X)," & -- PAD142 "1198 (BC_2, *, controlr, 1)," & "1199 (BC_2, IO_F28, output3, X, 1198, 1, Z)," & -- PAD141 "1200 (BC_2, IO_F28, input, X)," & -- PAD141 "1201 (BC_2, *, controlr, 1)," & "1202 (BC_2, IO_G28, output3, X, 1201, 1, Z)," & -- PAD140 "1203 (BC_2, IO_G28, input, X)," & -- PAD140 "1204 (BC_2, *, controlr, 1)," & "1205 (BC_2, IO_H25, output3, X, 1204, 1, Z)," & -- PAD139 "1206 (BC_2, IO_H25, input, X)," & -- PAD139 "1207 (BC_2, *, controlr, 1)," & "1208 (BC_2, IO_H24, output3, X, 1207, 1, Z)," & -- PAD138 "1209 (BC_2, IO_H24, input, X)," & -- PAD138 "1210 (BC_2, *, controlr, 1)," & "1211 (BC_2, IO_E30, output3, X, 1210, 1, Z)," & -- PAD137 "1212 (BC_2, IO_E30, input, X)," & -- PAD137 "1213 (BC_2, *, controlr, 1)," & "1214 (BC_2, IO_E29, output3, X, 1213, 1, Z)," & -- PAD136 "1215 (BC_2, IO_E29, input, X)," & -- PAD136 "1216 (BC_2, *, controlr, 1)," & "1217 (BC_2, IO_A30, output3, X, 1216, 1, Z)," & -- PAD135 "1218 (BC_2, IO_A30, input, X)," & -- PAD135 "1219 (BC_2, *, controlr, 1)," & "1220 (BC_2, IO_B30, output3, X, 1219, 1, Z)," & -- PAD134 "1221 (BC_2, IO_B30, input, X)," & -- PAD134 "1222 (BC_2, *, controlr, 1)," & "1223 (BC_2, IO_C30, output3, X, 1222, 1, Z)," & -- PAD133 "1224 (BC_2, IO_C30, input, X)," & -- PAD133 "1225 (BC_2, *, controlr, 1)," & "1226 (BC_2, IO_D29, output3, X, 1225, 1, Z)," & -- PAD132 "1227 (BC_2, IO_D29, input, X)," & -- PAD132 "1228 (BC_2, *, controlr, 1)," & "1229 (BC_2, IO_B29, output3, X, 1228, 1, Z)," & -- PAD131 "1230 (BC_2, IO_B29, input, X)," & -- PAD131 "1231 (BC_2, *, controlr, 1)," & "1232 (BC_2, IO_C29, output3, X, 1231, 1, Z)," & -- PAD130 "1233 (BC_2, IO_C29, input, X)," & -- PAD130 "1234 (BC_2, *, controlr, 1)," & "1235 (BC_2, IO_D28, output3, X, 1234, 1, Z)," & -- PAD129 "1236 (BC_2, IO_D28, input, X)," & -- PAD129 "1237 (BC_2, *, controlr, 1)," & "1238 (BC_2, IO_E28, output3, X, 1237, 1, Z)," & -- PAD128 "1239 (BC_2, IO_E28, input, X)," & -- PAD128 "1240 (BC_2, *, controlr, 1)," & "1241 (BC_2, IO_C27, output3, X, 1240, 1, Z)," & -- PAD127 "1242 (BC_2, IO_C27, input, X)," & -- PAD127 "1243 (BC_2, *, controlr, 1)," & "1244 (BC_2, IO_D27, output3, X, 1243, 1, Z)," & -- PAD126 "1245 (BC_2, IO_D27, input, X)," & -- PAD126 "1246 (BC_2, *, controlr, 1)," & "1247 (BC_2, IO_B25, output3, X, 1246, 1, Z)," & -- PAD125 "1248 (BC_2, IO_B25, input, X)," & -- PAD125 "1249 (BC_2, *, controlr, 1)," & "1250 (BC_2, IO_C25, output3, X, 1249, 1, Z)," & -- PAD124 "1251 (BC_2, IO_C25, input, X)," & -- PAD124 "1252 (BC_2, *, controlr, 1)," & "1253 (BC_2, IO_C26, output3, X, 1252, 1, Z)," & -- PAD123 "1254 (BC_2, IO_C26, input, X)," & -- PAD123 "1255 (BC_2, *, controlr, 1)," & "1256 (BC_2, IO_D26, output3, X, 1255, 1, Z)," & -- PAD122 "1257 (BC_2, IO_D26, input, X)," & -- PAD122 "1258 (BC_2, *, controlr, 1)," & "1259 (BC_2, IO_A26, output3, X, 1258, 1, Z)," & -- PAD121 "1260 (BC_2, IO_A26, input, X)," & -- PAD121 "1261 (BC_2, *, controlr, 1)," & "1262 (BC_2, IO_A25, output3, X, 1261, 1, Z)," & -- PAD120 "1263 (BC_2, IO_A25, input, X)," & -- PAD120 "1264 (BC_2, *, controlr, 1)," & "1265 (BC_2, IO_A28, output3, X, 1264, 1, Z)," & -- PAD119 "1266 (BC_2, IO_A28, input, X)," & -- PAD119 "1267 (BC_2, *, controlr, 1)," & "1268 (BC_2, IO_B28, output3, X, 1267, 1, Z)," & -- PAD118 "1269 (BC_2, IO_B28, input, X)," & -- PAD118 "1270 (BC_2, *, controlr, 1)," & "1271 (BC_2, IO_B24, output3, X, 1270, 1, Z)," & -- PAD117 "1272 (BC_2, IO_B24, input, X)," & -- PAD117 "1273 (BC_2, *, controlr, 1)," & "1274 (BC_2, IO_C24, output3, X, 1273, 1, Z)," & -- PAD116 "1275 (BC_2, IO_C24, input, X)," & -- PAD116 "1276 (BC_2, *, controlr, 1)," & "1277 (BC_2, IO_A27, output3, X, 1276, 1, Z)," & -- PAD115 "1278 (BC_2, IO_A27, input, X)," & -- PAD115 "1279 (BC_2, *, controlr, 1)," & "1280 (BC_2, IO_B27, output3, X, 1279, 1, Z)," & -- PAD114 "1281 (BC_2, IO_B27, input, X)," & -- PAD114 "1282 (BC_2, *, controlr, 1)," & "1283 (BC_2, IO_G24, output3, X, 1282, 1, Z)," & -- PAD113 "1284 (BC_2, IO_G24, input, X)," & -- PAD113 "1285 (BC_2, *, controlr, 1)," & "1286 (BC_2, IO_G23, output3, X, 1285, 1, Z)," & -- PAD112 "1287 (BC_2, IO_G23, input, X)," & -- PAD112 "1288 (BC_2, *, controlr, 1)," & "1289 (BC_2, IO_E26, output3, X, 1288, 1, Z)," & -- PAD111 "1290 (BC_2, IO_E26, input, X)," & -- PAD111 "1291 (BC_2, *, controlr, 1)," & "1292 (BC_2, IO_F26, output3, X, 1291, 1, Z)," & -- PAD110 "1293 (BC_2, IO_F26, input, X)," & -- PAD110 "1294 (BC_2, *, controlr, 1)," & "1295 (BC_2, IO_D24, output3, X, 1294, 1, Z)," & -- PAD109 "1296 (BC_2, IO_D24, input, X)," & -- PAD109 "1297 (BC_2, *, controlr, 1)," & "1298 (BC_2, IO_E24, output3, X, 1297, 1, Z)," & -- PAD108 "1299 (BC_2, IO_E24, input, X)," & -- PAD108 "1300 (BC_2, *, controlr, 1)," & "1301 (BC_2, IO_E25, output3, X, 1300, 1, Z)," & -- PAD107 "1302 (BC_2, IO_E25, input, X)," & -- PAD107 "1303 (BC_2, *, controlr, 1)," & "1304 (BC_2, IO_F25, output3, X, 1303, 1, Z)," & -- PAD106 "1305 (BC_2, IO_F25, input, X)," & -- PAD106 "1306 (BC_2, *, controlr, 1)," & "1307 (BC_2, IO_D23, output3, X, 1306, 1, Z)," & -- PAD105 "1308 (BC_2, IO_D23, input, X)," & -- PAD105 "1309 (BC_2, *, controlr, 1)," & "1310 (BC_2, IO_E23, output3, X, 1309, 1, Z)," & -- PAD104 "1311 (BC_2, IO_E23, input, X)," & -- PAD104 "1312 (BC_2, *, controlr, 1)," & "1313 (BC_2, IO_A23, output3, X, 1312, 1, Z)," & -- PAD103 "1314 (BC_2, IO_A23, input, X)," & -- PAD103 "1315 (BC_2, *, controlr, 1)," & "1316 (BC_2, IO_B23, output3, X, 1315, 1, Z)," & -- PAD102 "1317 (BC_2, IO_B23, input, X)," & -- PAD102 "1318 (BC_2, *, controlr, 1)," & "1319 (BC_2, IO_F23, output3, X, 1318, 1, Z)," & -- PAD101 "1320 (BC_2, IO_F23, input, X)," & -- PAD101 "1321 (BC_2, *, controlr, 1)," & "1322 (BC_2, IO_E18, output3, X, 1321, 1, Z)," & -- PAD100 "1323 (BC_2, IO_E18, input, X)," & -- PAD100 "1324 (BC_2, *, controlr, 1)," & "1325 (BC_2, IO_B19, output3, X, 1324, 1, Z)," & -- PAD99 "1326 (BC_2, IO_B19, input, X)," & -- PAD99 "1327 (BC_2, *, controlr, 1)," & "1328 (BC_2, IO_C19, output3, X, 1327, 1, Z)," & -- PAD98 "1329 (BC_2, IO_C19, input, X)," & -- PAD98 "1330 (BC_2, *, controlr, 1)," & "1331 (BC_2, IO_A22, output3, X, 1330, 1, Z)," & -- PAD97 "1332 (BC_2, IO_A22, input, X)," & -- PAD97 "1333 (BC_2, *, controlr, 1)," & "1334 (BC_2, IO_B22, output3, X, 1333, 1, Z)," & -- PAD96 "1335 (BC_2, IO_B22, input, X)," & -- PAD96 "1336 (BC_2, *, controlr, 1)," & "1337 (BC_2, IO_A18, output3, X, 1336, 1, Z)," & -- PAD95 "1338 (BC_2, IO_A18, input, X)," & -- PAD95 "1339 (BC_2, *, controlr, 1)," & "1340 (BC_2, IO_B18, output3, X, 1339, 1, Z)," & -- PAD94 "1341 (BC_2, IO_B18, input, X)," & -- PAD94 "1342 (BC_2, *, controlr, 1)," & "1343 (BC_2, IO_A21, output3, X, 1342, 1, Z)," & -- PAD93 "1344 (BC_2, IO_A21, input, X)," & -- PAD93 "1345 (BC_2, *, controlr, 1)," & "1346 (BC_2, IO_A20, output3, X, 1345, 1, Z)," & -- PAD92 "1347 (BC_2, IO_A20, input, X)," & -- PAD92 "1348 (BC_2, *, controlr, 1)," & "1349 (BC_2, IO_A17, output3, X, 1348, 1, Z)," & -- PAD91 "1350 (BC_2, IO_A17, input, X)," & -- PAD91 "1351 (BC_2, *, controlr, 1)," & "1352 (BC_2, IO_A16, output3, X, 1351, 1, Z)," & -- PAD90 "1353 (BC_2, IO_A16, input, X)," & -- PAD90 "1354 (BC_2, *, controlr, 1)," & "1355 (BC_2, IO_B20, output3, X, 1354, 1, Z)," & -- PAD89 "1356 (BC_2, IO_B20, input, X)," & -- PAD89 "1357 (BC_2, *, controlr, 1)," & "1358 (BC_2, IO_C20, output3, X, 1357, 1, Z)," & -- PAD88 "1359 (BC_2, IO_C20, input, X)," & -- PAD88 "1360 (BC_2, *, controlr, 1)," & "1361 (BC_2, IO_F17, output3, X, 1360, 1, Z)," & -- PAD87 "1362 (BC_2, IO_F17, input, X)," & -- PAD87 "1363 (BC_2, *, controlr, 1)," & "1364 (BC_2, IO_G17, output3, X, 1363, 1, Z)," & -- PAD86 "1365 (BC_2, IO_G17, input, X)," & -- PAD86 "1366 (BC_2, *, controlr, 1)," & "1367 (BC_2, IO_B17, output3, X, 1366, 1, Z)," & -- PAD85 "1368 (BC_2, IO_B17, input, X)," & -- PAD85 "1369 (BC_2, *, controlr, 1)," & "1370 (BC_2, IO_C17, output3, X, 1369, 1, Z)," & -- PAD84 "1371 (BC_2, IO_C17, input, X)," & -- PAD84 "1372 (BC_2, *, controlr, 1)," & "1373 (BC_2, IO_F18, output3, X, 1372, 1, Z)," & -- PAD83 "1374 (BC_2, IO_F18, input, X)," & -- PAD83 "1375 (BC_2, *, controlr, 1)," & "1376 (BC_2, IO_G18, output3, X, 1375, 1, Z)," & -- PAD82 "1377 (BC_2, IO_G18, input, X)," & -- PAD82 "1378 (BC_2, *, controlr, 1)," & "1379 (BC_2, IO_C16, output3, X, 1378, 1, Z)," & -- PAD81 "1380 (BC_2, IO_C16, input, X)," & -- PAD81 "1381 (BC_2, *, controlr, 1)," & "1382 (BC_2, IO_D16, output3, X, 1381, 1, Z)," & -- PAD80 "1383 (BC_2, IO_D16, input, X)," & -- PAD80 "1384 (BC_2, *, controlr, 1)," & "1385 (BC_2, IO_D19, output3, X, 1384, 1, Z)," & -- PAD79 "1386 (BC_2, IO_D19, input, X)," & -- PAD79 "1387 (BC_2, *, controlr, 1)," & "1388 (BC_2, IO_E19, output3, X, 1387, 1, Z)," & -- PAD78 "1389 (BC_2, IO_E19, input, X)," & -- PAD78 "1390 (BC_2, *, controlr, 1)," & "1391 (BC_2, IO_D18, output3, X, 1390, 1, Z)," & -- PAD77 "1392 (BC_2, IO_D18, input, X)," & -- PAD77 "1393 (BC_2, *, controlr, 1)," & "1394 (BC_2, IO_D17, output3, X, 1393, 1, Z)," & -- PAD76 "1395 (BC_2, IO_D17, input, X)," & -- PAD76 "1396 (BC_2, *, controlr, 1)," & "1397 (BC_2, IO_E20, output3, X, 1396, 1, Z)," & -- PAD75 "1398 (BC_2, IO_E20, input, X)," & -- PAD75 "1399 (BC_2, *, controlr, 1)," & "1400 (BC_2, IO_F20, output3, X, 1399, 1, Z)," & -- PAD74 "1401 (BC_2, IO_F20, input, X)," & -- PAD74 "1402 (BC_2, *, controlr, 1)," & "1403 (BC_2, IO_E21, output3, X, 1402, 1, Z)," & -- PAD73 "1404 (BC_2, IO_E21, input, X)," & -- PAD73 "1405 (BC_2, *, controlr, 1)," & "1406 (BC_2, IO_F21, output3, X, 1405, 1, Z)," & -- PAD72 "1407 (BC_2, IO_F21, input, X)," & -- PAD72 "1408 (BC_2, *, controlr, 1)," & "1409 (BC_2, IO_C22, output3, X, 1408, 1, Z)," & -- PAD71 "1410 (BC_2, IO_C22, input, X)," & -- PAD71 "1411 (BC_2, *, controlr, 1)," & "1412 (BC_2, IO_D22, output3, X, 1411, 1, Z)," & -- PAD70 "1413 (BC_2, IO_D22, input, X)," & -- PAD70 "1414 (BC_2, *, controlr, 1)," & "1415 (BC_2, IO_F22, output3, X, 1414, 1, Z)," & -- PAD69 "1416 (BC_2, IO_F22, input, X)," & -- PAD69 "1417 (BC_2, *, controlr, 1)," & "1418 (BC_2, IO_G22, output3, X, 1417, 1, Z)," & -- PAD68 "1419 (BC_2, IO_G22, input, X)," & -- PAD68 "1420 (BC_2, *, controlr, 1)," & "1421 (BC_2, IO_C21, output3, X, 1420, 1, Z)," & -- PAD67 "1422 (BC_2, IO_C21, input, X)," & -- PAD67 "1423 (BC_2, *, controlr, 1)," & "1424 (BC_2, IO_D21, output3, X, 1423, 1, Z)," & -- PAD66 "1425 (BC_2, IO_D21, input, X)," & -- PAD66 "1426 (BC_2, *, controlr, 1)," & "1427 (BC_2, IO_H22, output3, X, 1426, 1, Z)," & -- PAD65 "1428 (BC_2, IO_H22, input, X)," & -- PAD65 "1429 (BC_2, *, controlr, 1)," & "1430 (BC_2, IO_H21, output3, X, 1429, 1, Z)," & -- PAD64 "1431 (BC_2, IO_H21, input, X)," & -- PAD64 "1432 (BC_2, *, controlr, 1)," & "1433 (BC_2, IO_K20, output3, X, 1432, 1, Z)," & -- PAD63 "1434 (BC_2, IO_K20, input, X)," & -- PAD63 "1435 (BC_2, *, controlr, 1)," & "1436 (BC_2, IO_K19, output3, X, 1435, 1, Z)," & -- PAD62 "1437 (BC_2, IO_K19, input, X)," & -- PAD62 "1438 (BC_2, *, controlr, 1)," & "1439 (BC_2, IO_L18, output3, X, 1438, 1, Z)," & -- PAD61 "1440 (BC_2, IO_L18, input, X)," & -- PAD61 "1441 (BC_2, *, controlr, 1)," & "1442 (BC_2, IO_L17, output3, X, 1441, 1, Z)," & -- PAD60 "1443 (BC_2, IO_L17, input, X)," & -- PAD60 "1444 (BC_2, *, controlr, 1)," & "1445 (BC_2, IO_H19, output3, X, 1444, 1, Z)," & -- PAD59 "1446 (BC_2, IO_H19, input, X)," & -- PAD59 "1447 (BC_2, *, controlr, 1)," & "1448 (BC_2, IO_J19, output3, X, 1447, 1, Z)," & -- PAD58 "1449 (BC_2, IO_J19, input, X)," & -- PAD58 "1450 (BC_2, *, controlr, 1)," & "1451 (BC_2, IO_H17, output3, X, 1450, 1, Z)," & -- PAD57 "1452 (BC_2, IO_H17, input, X)," & -- PAD57 "1453 (BC_2, *, controlr, 1)," & "1454 (BC_2, IO_J17, output3, X, 1453, 1, Z)," & -- PAD56 "1455 (BC_2, IO_J17, input, X)," & -- PAD56 "1456 (BC_2, *, controlr, 1)," & "1457 (BC_2, IO_G20, output3, X, 1456, 1, Z)," & -- PAD55 "1458 (BC_2, IO_G20, input, X)," & -- PAD55 "1459 (BC_2, *, controlr, 1)," & "1460 (BC_2, IO_H20, output3, X, 1459, 1, Z)," & -- PAD54 "1461 (BC_2, IO_H20, input, X)," & -- PAD54 "1462 (BC_2, *, controlr, 1)," & "1463 (BC_2, IO_J18, output3, X, 1462, 1, Z)," & -- PAD53 "1464 (BC_2, IO_J18, input, X)," & -- PAD53 "1465 (BC_2, *, controlr, 1)," & "1466 (BC_2, IO_K18, output3, X, 1465, 1, Z)," & -- PAD52 "1467 (BC_2, IO_K18, input, X)," & -- PAD52 "1468 (BC_2, *, controlr, 1)," & "1469 (BC_2, IO_G19, output3, X, 1468, 1, Z)," & -- PAD51 "1470 (BC_2, IO_G19, input, X)," & -- PAD51 "1471 (BC_2, *, controlr, 1)," & "1472 (BC_2, IO_F16, output3, X, 1471, 1, Z)," & -- PAD50 "1473 (BC_2, IO_F16, input, X)," & -- PAD50 "1474 (BC_2, *, controlr, 1)," & "1475 (BC_2, IO_A15, output3, X, 1474, 1, Z)," & -- PAD49 "1476 (BC_2, IO_A15, input, X)," & -- PAD49 "1477 (BC_2, *, controlr, 1)," & "1478 (BC_2, IO_B14, output3, X, 1477, 1, Z)," & -- PAD48 "1479 (BC_2, IO_B14, input, X)," & -- PAD48 "1480 (BC_2, *, controlr, 1)," & "1481 (BC_2, IO_B15, output3, X, 1480, 1, Z)," & -- PAD47 "1482 (BC_2, IO_B15, input, X)," & -- PAD47 "1483 (BC_2, *, controlr, 1)," & "1484 (BC_2, IO_C15, output3, X, 1483, 1, Z)," & -- PAD46 "1485 (BC_2, IO_C15, input, X)," & -- PAD46 "1486 (BC_2, *, controlr, 1)," & "1487 (BC_2, IO_A13, output3, X, 1486, 1, Z)," & -- PAD45 "1488 (BC_2, IO_A13, input, X)," & -- PAD45 "1489 (BC_2, *, controlr, 1)," & "1490 (BC_2, IO_B13, output3, X, 1489, 1, Z)," & -- PAD44 "1491 (BC_2, IO_B13, input, X)," & -- PAD44 "1492 (BC_2, *, controlr, 1)," & "1493 (BC_2, IO_C14, output3, X, 1492, 1, Z)," & -- PAD43 "1494 (BC_2, IO_C14, input, X)," & -- PAD43 "1495 (BC_2, *, controlr, 1)," & "1496 (BC_2, IO_D14, output3, X, 1495, 1, Z)," & -- PAD42 "1497 (BC_2, IO_D14, input, X)," & -- PAD42 "1498 (BC_2, *, controlr, 1)," & "1499 (BC_2, IO_E15, output3, X, 1498, 1, Z)," & -- PAD41 "1500 (BC_2, IO_E15, input, X)," & -- PAD41 "1501 (BC_2, *, controlr, 1)," & "1502 (BC_2, IO_E14, output3, X, 1501, 1, Z)," & -- PAD40 "1503 (BC_2, IO_E14, input, X)," & -- PAD40 "1504 (BC_2, *, controlr, 1)," & "1505 (BC_2, IO_E16, output3, X, 1504, 1, Z)," & -- PAD39 "1506 (BC_2, IO_E16, input, X)," & -- PAD39 "1507 (BC_2, *, controlr, 1)," & "1508 (BC_2, IO_F15, output3, X, 1507, 1, Z)," & -- PAD38 "1509 (BC_2, IO_F15, input, X)," & -- PAD38 "1510 (BC_2, *, controlr, 1)," & "1511 (BC_2, IO_C11, output3, X, 1510, 1, Z)," & -- PAD37 "1512 (BC_2, IO_C11, input, X)," & -- PAD37 "1513 (BC_2, *, controlr, 1)," & "1514 (BC_2, IO_D11, output3, X, 1513, 1, Z)," & -- PAD36 "1515 (BC_2, IO_D11, input, X)," & -- PAD36 "1516 (BC_2, *, controlr, 1)," & "1517 (BC_2, IO_A12, output3, X, 1516, 1, Z)," & -- PAD35 "1518 (BC_2, IO_A12, input, X)," & -- PAD35 "1519 (BC_2, *, controlr, 1)," & "1520 (BC_2, IO_A11, output3, X, 1519, 1, Z)," & -- PAD34 "1521 (BC_2, IO_A11, input, X)," & -- PAD34 "1522 (BC_2, *, controlr, 1)," & "1523 (BC_2, IO_E11, output3, X, 1522, 1, Z)," & -- PAD33 "1524 (BC_2, IO_E11, input, X)," & -- PAD33 "1525 (BC_2, *, controlr, 1)," & "1526 (BC_2, IO_F11, output3, X, 1525, 1, Z)," & -- PAD32 "1527 (BC_2, IO_F11, input, X)," & -- PAD32 "1528 (BC_2, *, controlr, 1)," & "1529 (BC_2, IO_B12, output3, X, 1528, 1, Z)," & -- PAD31 "1530 (BC_2, IO_B12, input, X)," & -- PAD31 "1531 (BC_2, *, controlr, 1)," & "1532 (BC_2, IO_C12, output3, X, 1531, 1, Z)," & -- PAD30 "1533 (BC_2, IO_C12, input, X)," & -- PAD30 "1534 (BC_2, *, controlr, 1)," & "1535 (BC_2, IO_E13, output3, X, 1534, 1, Z)," & -- PAD29 "1536 (BC_2, IO_E13, input, X)," & -- PAD29 "1537 (BC_2, *, controlr, 1)," & "1538 (BC_2, IO_F12, output3, X, 1537, 1, Z)," & -- PAD28 "1539 (BC_2, IO_F12, input, X)," & -- PAD28 "1540 (BC_2, *, controlr, 1)," & "1541 (BC_2, IO_D13, output3, X, 1540, 1, Z)," & -- PAD27 "1542 (BC_2, IO_D13, input, X)," & -- PAD27 "1543 (BC_2, *, controlr, 1)," & "1544 (BC_2, IO_D12, output3, X, 1543, 1, Z)," & -- PAD26 "1545 (BC_2, IO_D12, input, X)," & -- PAD26 "1546 (BC_2, *, controlr, 1)," & "1547 (BC_2, IO_F13, output3, X, 1546, 1, Z)," & -- PAD25 "1548 (BC_2, IO_F13, input, X)," & -- PAD25 "1549 (BC_2, *, controlr, 1)," & "1550 (BC_2, IO_G13, output3, X, 1549, 1, Z)," & -- PAD24 "1551 (BC_2, IO_G13, input, X)," & -- PAD24 "1552 (BC_2, *, controlr, 1)," & "1553 (BC_2, IO_G14, output3, X, 1552, 1, Z)," & -- PAD23 "1554 (BC_2, IO_G14, input, X)," & -- PAD23 "1555 (BC_2, *, controlr, 1)," & "1556 (BC_2, IO_H14, output3, X, 1555, 1, Z)," & -- PAD22 "1557 (BC_2, IO_H14, input, X)," & -- PAD22 "1558 (BC_2, *, controlr, 1)," & "1559 (BC_2, IO_H12, output3, X, 1558, 1, Z)," & -- PAD21 "1560 (BC_2, IO_H12, input, X)," & -- PAD21 "1561 (BC_2, *, controlr, 1)," & "1562 (BC_2, IO_H11, output3, X, 1561, 1, Z)," & -- PAD20 "1563 (BC_2, IO_H11, input, X)," & -- PAD20 "1564 (BC_2, *, controlr, 1)," & "1565 (BC_2, IO_H16, output3, X, 1564, 1, Z)," & -- PAD19 "1566 (BC_2, IO_H16, input, X)," & -- PAD19 "1567 (BC_2, *, controlr, 1)," & "1568 (BC_2, IO_J16, output3, X, 1567, 1, Z)," & -- PAD18 "1569 (BC_2, IO_J16, input, X)," & -- PAD18 "1570 (BC_2, *, controlr, 1)," & "1571 (BC_2, IO_J12, output3, X, 1570, 1, Z)," & -- PAD17 "1572 (BC_2, IO_J12, input, X)," & -- PAD17 "1573 (BC_2, *, controlr, 1)," & "1574 (BC_2, IO_J11, output3, X, 1573, 1, Z)," & -- PAD16 "1575 (BC_2, IO_J11, input, X)," & -- PAD16 "1576 (BC_2, *, controlr, 1)," & "1577 (BC_2, IO_G15, output3, X, 1576, 1, Z)," & -- PAD15 "1578 (BC_2, IO_G15, input, X)," & -- PAD15 "1579 (BC_2, *, controlr, 1)," & "1580 (BC_2, IO_H15, output3, X, 1579, 1, Z)," & -- PAD14 "1581 (BC_2, IO_H15, input, X)," & -- PAD14 "1582 (BC_2, *, controlr, 1)," & "1583 (BC_2, IO_K11, output3, X, 1582, 1, Z)," & -- PAD13 "1584 (BC_2, IO_K11, input, X)," & -- PAD13 "1585 (BC_2, *, controlr, 1)," & "1586 (BC_2, IO_L11, output3, X, 1585, 1, Z)," & -- PAD12 "1587 (BC_2, IO_L11, input, X)," & -- PAD12 "1588 (BC_2, *, controlr, 1)," & "1589 (BC_2, IO_J14, output3, X, 1588, 1, Z)," & -- PAD11 "1590 (BC_2, IO_J14, input, X)," & -- PAD11 "1591 (BC_2, *, controlr, 1)," & "1592 (BC_2, IO_K14, output3, X, 1591, 1, Z)," & -- PAD10 "1593 (BC_2, IO_K14, input, X)," & -- PAD10 "1594 (BC_2, *, controlr, 1)," & "1595 (BC_2, IO_J13, output3, X, 1594, 1, Z)," & -- PAD9 "1596 (BC_2, IO_J13, input, X)," & -- PAD9 "1597 (BC_2, *, controlr, 1)," & "1598 (BC_2, IO_K13, output3, X, 1597, 1, Z)," & -- PAD8 "1599 (BC_2, IO_K13, input, X)," & -- PAD8 "1600 (BC_2, *, controlr, 1)," & "1601 (BC_2, IO_L13, output3, X, 1600, 1, Z)," & -- PAD7 "1602 (BC_2, IO_L13, input, X)," & -- PAD7 "1603 (BC_2, *, controlr, 1)," & "1604 (BC_2, IO_L12, output3, X, 1603, 1, Z)," & -- PAD6 "1605 (BC_2, IO_L12, input, X)," & -- PAD6 "1606 (BC_2, *, controlr, 1)," & "1607 (BC_2, IO_K15, output3, X, 1606, 1, Z)," & -- PAD5 "1608 (BC_2, IO_K15, input, X)," & -- PAD5 "1609 (BC_2, *, controlr, 1)," & "1610 (BC_2, IO_L15, output3, X, 1609, 1, Z)," & -- PAD4 "1611 (BC_2, IO_L15, input, X)," & -- PAD4 "1612 (BC_2, *, controlr, 1)," & "1613 (BC_2, IO_K16, output3, X, 1612, 1, Z)," & -- PAD3 "1614 (BC_2, IO_K16, input, X)," & -- PAD3 "1615 (BC_2, *, controlr, 1)," & "1616 (BC_2, IO_L16, output3, X, 1615, 1, Z)," & -- PAD2 "1617 (BC_2, IO_L16, input, X)," & -- PAD2 "1618 (BC_2, *, controlr, 1)," & "1619 (BC_2, IO_G12, output3, X, 1618, 1, Z)," & -- PAD1 "1620 (BC_2, IO_G12, input, X)," & -- PAD1 "1621 (BC_2, *, internal, X)," & "1622 (BC_2, *, internal, X)," & "1623 (BC_2, *, internal, X)," & "1624 (BC_2, *, internal, X)," & "1625 (BC_2, *, internal, X)," & "1626 (BC_2, *, internal, X)," & "1627 (BC_2, *, internal, X)," & "1628 (BC_2, *, internal, X)," & "1629 (BC_2, *, internal, X)," & "1630 (BC_2, *, internal, X)"; -- Advanced I/O Description attribute AIO_COMPONENT_CONFORMANCE of XC7K325T_FFG900 : entity is "STD_1149_6_2003"; attribute AIO_EXTEST_Pulse_Execution of XC7K325T_FFG900 : entity is "Wait_Duration TCK 15"; attribute AIO_EXTEST_Train_Execution of XC7K325T_FFG900 : entity is "train 30, maximum_time 120.0e-6"; attribute AIO_Pin_Behavior of XC7K325T_FFG900 : entity is "MGTXRXP0_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXTXP0_115; " & "MGTXTXP0_116; " & "MGTXTXP0_117; " & "MGTXTXP0_118; " & "MGTXTXP1_115; " & "MGTXTXP1_116; " & "MGTXTXP1_117; " & "MGTXTXP1_118; " & "MGTXTXP2_115; " & "MGTXTXP2_116; " & "MGTXTXP2_117; " & "MGTXTXP2_118; " & "MGTXTXP3_115; " & "MGTXTXP3_116; " & "MGTXTXP3_117; " & "MGTXTXP3_118 "; -- Design Warning Section attribute DESIGN_WARNING of XC7K325T_FFG900 : entity is "This is a preliminary BSDL file which has not been verified." & "When no bitstream is loaded and GTPs are not instantiated," & "the boundary-scan cells associated with GTPs will not" & "capture correct state information. To model the boundary-" & "scan cell behavior correctly post-configuration, use" & "BSDLanno to modify the BSDL file." & "This BSDL file must be modified by the FPGA designer in order to" & "reflect post-configuration behavior (if any)." & "To avoid losing the current configuration, the boundary scan" & "test vectors should keep the PROGRAM_B pin" & "high. If the PROGRAM_B pin goes low by any means," & "the configuration will be cleared." & "PROGRAM_B can only be captured, not updated." & "The value at the pin is always used by the device." & "In EXTEST, output and tristate values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "Differential Serial IO pins do not support INTEST." & "In INTEST, the pin input values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "The output and tristate capture values are not valid until after" & "the device is configured." & "The tristate control value is not captured properly when" & "GTS is activated." & "The IEEE Std 1149.6 EXTEST_PULSE and EXTEST_TRAIN instructions" & "require a minimum TCK freq of 15 MHz and min temp of 0C." & "NOCONNECT pins should not be connected to any supply" & "or GND. They should be left floating."; end XC7K325T_FFG900; ================================================ FILE: jtag/bsd/xc7vx485t_ffg1761.bsd ================================================ -- (c) Copyright 2010 - 2011 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- releated to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitiations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. -- -- BSDL file for device XC7VX485T, package FFG1761 -- Generated by bsdlnet Version 1.7 -- Generated on Wed Dec 07, 2011 09:27:27 PST -- Generated using schematic at v32_top/xc7vx485t/schematic -- Schematic date = 2011-02-16 07:01:45 -- Schematic ICM_VARIANT = 28t_n1 -- Package File date = # Date : 2011-08-22 07:43:37 ------------------------------------------------------------------------ -- Modification History -- | CR # N/A -- | Details - Initial Release ------------------------------------------------------------------------ -- -- For technical support, http://support.xilinx.com -> enter text 'bsdl' -- in the text search box at the left of the page. If none of -- these records resolve your problem you should open a web support case -- or contact our technical support at: -- -- North America 1-800-255-7778 hotline@xilinx.com -- United Kingdom +44 870 7350 610 eurosupport@xilinx.com -- France (33) 1 3463 0100 eurosupport@xilinx.com -- Germany (49) 89 991 54930 eurosupport@xilinx.com -- Japan (81) 3-3297-9163 jhotline@xilinx.com -- -- This BSDL file reflects the pre-configuration JTAG behavior. To reflect -- the post-configuration JTAG behavior (if any), edit this file as described -- below. Many of these changes are demonstrated by commented-out template -- lines preceeding the lines they would replace: -- -- 1. Enable USER instructions as appropriate (see below). -- 2. Set disable result of all pads as configured. -- 3. Set safe state of boundary cells as necessary. -- 4. Rename entity if necessary to avoid name collisions. -- 5. Modify USERCODE value in USERCODE_REGISTER declaration. -- -- To prevent losing the current configuration, the boundary scan -- test vectors should keep the PROGRAM_B pin high. -- -- PROGRAM_B can only be captured, not updated. The value -- at the pin is always used by the device. -- -- All IOBs prior to configuration, and unused and output-only IOBs following -- configuration, will sense their pad values during boundary-scan with an CMOS -- input buffer. In order to properly capture a logic high value at one -- of these IOBs into its input boundary scan cell, please refer to the -- datasheet and user guide for proper input levels. -- -- For post-configuration boundary scan only: If an IOB is configured to use -- an input standard that uses VREF pins, then the boundary scan test vectors -- must keep the used VREF pins 3-stated. ---------------------------------- -- BSDL File for P1149.6 Standard. ---------------------------------- -- ---------------------------------------------------------------------- -- This BSDL file has been checked and verified by JTAG Technologies B.V. -- on 2011-12-08, for syntactical and semantic compliance with -- IEEE standards 1149.1 and 1149.6 -- using bsdl32.dll 1.6.1.5 - 20110523 Win32 -- copyright (c) 2009 JTAG Technologies B.V., All rights reserved -- ---------------------------------------------------------------------- entity XC7VX485T_FFG1761 is -- Generic Parameter generic (PHYSICAL_PIN_MAP : string := "FFG1761" ); -- Logical Port Description port ( CCLK_N10: inout bit; -- CCLK_0 CFGBVS_AH10: in bit; -- CFGBVS_0 DONE_AL11: inout bit; -- DONE_0 GND: linkage bit_vector (1 to 424); GNDADC_0: linkage bit; INIT_B_AG11: inout bit; -- INIT_B_0 M0_AL10: in bit; -- M0_0 M1_AK10: in bit; -- M1_0 M2_AJ10: in bit; -- M2_0 MGTAVCC_G10: linkage bit_vector (1 to 11); MGTAVCC_G11: linkage bit_vector (1 to 5); MGTAVTTRCAL_115: linkage bit; MGTAVTT_G10: linkage bit_vector (1 to 16); MGTAVTT_G11: linkage bit_vector (1 to 11); MGTREFCLK0N_113: linkage bit; MGTREFCLK0N_114: linkage bit; MGTREFCLK0N_115: linkage bit; MGTREFCLK0N_116: linkage bit; MGTREFCLK0N_117: linkage bit; MGTREFCLK0N_118: linkage bit; MGTREFCLK0N_119: linkage bit; MGTREFCLK0P_113: linkage bit; MGTREFCLK0P_114: linkage bit; MGTREFCLK0P_115: linkage bit; MGTREFCLK0P_116: linkage bit; MGTREFCLK0P_117: linkage bit; MGTREFCLK0P_118: linkage bit; MGTREFCLK0P_119: linkage bit; MGTREFCLK1N_113: linkage bit; MGTREFCLK1N_114: linkage bit; MGTREFCLK1N_115: linkage bit; MGTREFCLK1N_116: linkage bit; MGTREFCLK1N_117: linkage bit; MGTREFCLK1N_118: linkage bit; MGTREFCLK1N_119: linkage bit; MGTREFCLK1P_113: linkage bit; MGTREFCLK1P_114: linkage bit; MGTREFCLK1P_115: linkage bit; MGTREFCLK1P_116: linkage bit; MGTREFCLK1P_117: linkage bit; MGTREFCLK1P_118: linkage bit; MGTREFCLK1P_119: linkage bit; MGTRREF_115: linkage bit; MGTVCCAUX_G10: linkage bit_vector (1 to 2); MGTVCCAUX_G11: linkage bit; MGTXRXN0_113: in bit; MGTXRXN0_114: in bit; MGTXRXN0_115: in bit; MGTXRXN0_116: in bit; MGTXRXN0_117: in bit; MGTXRXN0_118: in bit; MGTXRXN0_119: in bit; MGTXRXN1_113: in bit; MGTXRXN1_114: in bit; MGTXRXN1_115: in bit; MGTXRXN1_116: in bit; MGTXRXN1_117: in bit; MGTXRXN1_118: in bit; MGTXRXN1_119: in bit; MGTXRXN2_113: in bit; MGTXRXN2_114: in bit; MGTXRXN2_115: in bit; MGTXRXN2_116: in bit; MGTXRXN2_117: in bit; MGTXRXN2_118: in bit; MGTXRXN2_119: in bit; MGTXRXN3_113: in bit; MGTXRXN3_114: in bit; MGTXRXN3_115: in bit; MGTXRXN3_116: in bit; MGTXRXN3_117: in bit; MGTXRXN3_118: in bit; MGTXRXN3_119: in bit; MGTXRXP0_113: in bit; MGTXRXP0_114: in bit; MGTXRXP0_115: in bit; MGTXRXP0_116: in bit; MGTXRXP0_117: in bit; MGTXRXP0_118: in bit; MGTXRXP0_119: in bit; MGTXRXP1_113: in bit; MGTXRXP1_114: in bit; MGTXRXP1_115: in bit; MGTXRXP1_116: in bit; MGTXRXP1_117: in bit; MGTXRXP1_118: in bit; MGTXRXP1_119: in bit; MGTXRXP2_113: in bit; MGTXRXP2_114: in bit; MGTXRXP2_115: in bit; MGTXRXP2_116: in bit; MGTXRXP2_117: in bit; MGTXRXP2_118: in bit; MGTXRXP2_119: in bit; MGTXRXP3_113: in bit; MGTXRXP3_114: in bit; MGTXRXP3_115: in bit; MGTXRXP3_116: in bit; MGTXRXP3_117: in bit; MGTXRXP3_118: in bit; MGTXRXP3_119: in bit; MGTXTXN0_113: buffer bit; MGTXTXN0_114: buffer bit; MGTXTXN0_115: buffer bit; MGTXTXN0_116: buffer bit; MGTXTXN0_117: buffer bit; MGTXTXN0_118: buffer bit; MGTXTXN0_119: buffer bit; MGTXTXN1_113: buffer bit; MGTXTXN1_114: buffer bit; MGTXTXN1_115: buffer bit; MGTXTXN1_116: buffer bit; MGTXTXN1_117: buffer bit; MGTXTXN1_118: buffer bit; MGTXTXN1_119: buffer bit; MGTXTXN2_113: buffer bit; MGTXTXN2_114: buffer bit; MGTXTXN2_115: buffer bit; MGTXTXN2_116: buffer bit; MGTXTXN2_117: buffer bit; MGTXTXN2_118: buffer bit; MGTXTXN2_119: buffer bit; MGTXTXN3_113: buffer bit; MGTXTXN3_114: buffer bit; MGTXTXN3_115: buffer bit; MGTXTXN3_116: buffer bit; MGTXTXN3_117: buffer bit; MGTXTXN3_118: buffer bit; MGTXTXN3_119: buffer bit; MGTXTXP0_113: buffer bit; MGTXTXP0_114: buffer bit; MGTXTXP0_115: buffer bit; MGTXTXP0_116: buffer bit; MGTXTXP0_117: buffer bit; MGTXTXP0_118: buffer bit; MGTXTXP0_119: buffer bit; MGTXTXP1_113: buffer bit; MGTXTXP1_114: buffer bit; MGTXTXP1_115: buffer bit; MGTXTXP1_116: buffer bit; MGTXTXP1_117: buffer bit; MGTXTXP1_118: buffer bit; MGTXTXP1_119: buffer bit; MGTXTXP2_113: buffer bit; MGTXTXP2_114: buffer bit; MGTXTXP2_115: buffer bit; MGTXTXP2_116: buffer bit; MGTXTXP2_117: buffer bit; MGTXTXP2_118: buffer bit; MGTXTXP2_119: buffer bit; MGTXTXP3_113: buffer bit; MGTXTXP3_114: buffer bit; MGTXTXP3_115: buffer bit; MGTXTXP3_116: buffer bit; MGTXTXP3_117: buffer bit; MGTXTXP3_118: buffer bit; MGTXTXP3_119: buffer bit; NOCONNECT: linkage bit_vector (1 to 194); PROGRAM_B: in bit; -- PROGRAM_B_0 TCK: in bit; -- TCK_0 TDI: in bit; -- TDI_0 TDN_AC20: linkage bit; -- DXN_0 TDO: out bit; -- TDO_0 TDP_AC21: linkage bit; -- DXP_0 TMS: in bit; -- TMS_0 VCCADC_0: linkage bit; VCCAUX: linkage bit_vector (1 to 29); VCCBATT_0: linkage bit; VCCBRAM: linkage bit_vector (1 to 8); VCCINT: linkage bit_vector (1 to 86); VCCO_0: linkage bit_vector (1 to 2); VCCO_12: linkage bit_vector (1 to 6); VCCO_13: linkage bit_vector (1 to 7); VCCO_14: linkage bit_vector (1 to 7); VCCO_15: linkage bit_vector (1 to 6); VCCO_16: linkage bit_vector (1 to 6); VCCO_17: linkage bit_vector (1 to 6); VCCO_18: linkage bit_vector (1 to 6); VCCO_19: linkage bit_vector (1 to 7); VCCO_31: linkage bit_vector (1 to 7); VCCO_32: linkage bit_vector (1 to 6); VCCO_33: linkage bit_vector (1 to 6); VCCO_34: linkage bit_vector (1 to 6); VCCO_35: linkage bit_vector (1 to 7); VCCO_36: linkage bit_vector (1 to 7); VCCO_37: linkage bit_vector (1 to 6); VCCO_38: linkage bit_vector (1 to 6); VCCO_39: linkage bit_vector (1 to 6); VN_AB20: linkage bit; -- VN_0 VP_AA21: linkage bit; -- VP_0 VREFN_AA20: linkage bit; -- VREFN_0 VREFP_AB21: linkage bit; -- VREFP_0 IO_A14: inout bit; -- PAD355 IO_A15: inout bit; -- PAD405 IO_A16: inout bit; -- PAD404 IO_A17: inout bit; -- PAD409 IO_A19: inout bit; -- PAD407 IO_A20: inout bit; -- PAD406 IO_A21: inout bit; -- PAD411 IO_A22: inout bit; -- PAD455 IO_A24: inout bit; -- PAD452 IO_A25: inout bit; -- PAD453 IO_A26: inout bit; -- PAD456 IO_A27: inout bit; -- PAD457 IO_A29: inout bit; -- PAD484 IO_A30: inout bit; -- PAD485 IO_A31: inout bit; -- PAD482 IO_A32: inout bit; -- PAD483 IO_A34: inout bit; -- PAD555 IO_A35: inout bit; -- PAD558 IO_A36: inout bit; -- PAD559 IO_A37: inout bit; -- PAD553 IO_A39: inout bit; -- PAD557 IO_A40: inout bit; -- PAD4 IO_A41: inout bit; -- PAD5 IO_B14: inout bit; -- PAD354 IO_B16: inout bit; -- PAD353 IO_B17: inout bit; -- PAD408 IO_B18: inout bit; -- PAD413 IO_B19: inout bit; -- PAD403 IO_B21: inout bit; -- PAD410 IO_B22: inout bit; -- PAD454 IO_B23: inout bit; -- PAD459 IO_B24: inout bit; -- PAD463 IO_B26: inout bit; -- PAD460 IO_B27: inout bit; -- PAD461 IO_B28: inout bit; -- PAD480 IO_B29: inout bit; -- PAD481 IO_B31: inout bit; -- PAD487 IO_B32: inout bit; -- PAD566 IO_B33: inout bit; -- PAD567 IO_B34: inout bit; -- PAD554 IO_B36: inout bit; -- PAD552 IO_B37: inout bit; -- PAD562 IO_B38: inout bit; -- PAD563 IO_B39: inout bit; -- PAD556 IO_B41: inout bit; -- PAD8 IO_B42: inout bit; -- PAD9 IO_C13: inout bit; -- PAD359 IO_C14: inout bit; -- PAD357 IO_C15: inout bit; -- PAD356 IO_C16: inout bit; -- PAD352 IO_C18: inout bit; -- PAD412 IO_C19: inout bit; -- PAD402 IO_C20: inout bit; -- PAD415 IO_C21: inout bit; -- PAD419 IO_C23: inout bit; -- PAD458 IO_C24: inout bit; -- PAD462 IO_C25: inout bit; -- PAD474 IO_C26: inout bit; -- PAD475 IO_C28: inout bit; -- PAD478 IO_C29: inout bit; -- PAD479 IO_C30: inout bit; -- PAD491 IO_C31: inout bit; -- PAD486 IO_C33: inout bit; -- PAD570 IO_C34: inout bit; -- PAD571 IO_C35: inout bit; -- PAD574 IO_C36: inout bit; -- PAD575 IO_C38: inout bit; -- PAD560 IO_C39: inout bit; -- PAD561 IO_C40: inout bit; -- PAD12 IO_C41: inout bit; -- PAD13 IO_D12: inout bit; -- PAD363 IO_D13: inout bit; -- PAD358 IO_D15: inout bit; -- PAD361 IO_D16: inout bit; -- PAD360 IO_D17: inout bit; -- PAD421 IO_D18: inout bit; -- PAD420 IO_D20: inout bit; -- PAD414 IO_D21: inout bit; -- PAD418 IO_D22: inout bit; -- PAD470 IO_D23: inout bit; -- PAD471 IO_D25: inout bit; -- PAD472 IO_D26: inout bit; -- PAD473 IO_D27: inout bit; -- PAD476 IO_D28: inout bit; -- PAD477 IO_D30: inout bit; -- PAD490 IO_D31: inout bit; -- PAD489 IO_D32: inout bit; -- PAD565 IO_D33: inout bit; -- PAD569 IO_D35: inout bit; -- PAD572 IO_D36: inout bit; -- PAD573 IO_D37: inout bit; -- PAD578 IO_D38: inout bit; -- PAD579 IO_D40: inout bit; -- PAD3 IO_D41: inout bit; -- PAD6 IO_D42: inout bit; -- PAD7 IO_E12: inout bit; -- PAD362 IO_E13: inout bit; -- PAD367 IO_E14: inout bit; -- PAD366 IO_E15: inout bit; -- PAD365 IO_E17: inout bit; -- PAD417 IO_E18: inout bit; -- PAD425 IO_E19: inout bit; -- PAD424 IO_E20: inout bit; -- PAD431 IO_E22: inout bit; -- PAD467 IO_E23: inout bit; -- PAD464 IO_E24: inout bit; -- PAD465 IO_E25: inout bit; -- PAD469 IO_E27: inout bit; -- PAD492 IO_E28: inout bit; -- PAD493 IO_E29: inout bit; -- PAD495 IO_E30: inout bit; -- PAD488 IO_E32: inout bit; -- PAD564 IO_E33: inout bit; -- PAD568 IO_E34: inout bit; -- PAD576 IO_E35: inout bit; -- PAD577 IO_E37: inout bit; -- PAD588 IO_E38: inout bit; -- PAD589 IO_E39: inout bit; -- PAD593 IO_E40: inout bit; -- PAD2 IO_E42: inout bit; -- PAD11 IO_F12: inout bit; -- PAD371 IO_F14: inout bit; -- PAD373 IO_F15: inout bit; -- PAD372 IO_F16: inout bit; -- PAD364 IO_F17: inout bit; -- PAD416 IO_F19: inout bit; -- PAD423 IO_F20: inout bit; -- PAD430 IO_F21: inout bit; -- PAD451 IO_F22: inout bit; -- PAD466 IO_F24: inout bit; -- PAD500 IO_F25: inout bit; -- PAD468 IO_F26: inout bit; -- PAD496 IO_F27: inout bit; -- PAD497 IO_F29: inout bit; -- PAD494 IO_F30: inout bit; -- PAD498 IO_F31: inout bit; -- PAD499 IO_F32: inout bit; -- PAD581 IO_F34: inout bit; -- PAD584 IO_F35: inout bit; -- PAD585 IO_F36: inout bit; -- PAD582 IO_F37: inout bit; -- PAD583 IO_F39: inout bit; -- PAD592 IO_F40: inout bit; -- PAD20 IO_F41: inout bit; -- PAD21 IO_F42: inout bit; -- PAD10 IO_G12: inout bit; -- PAD370 IO_G13: inout bit; -- PAD375 IO_G14: inout bit; -- PAD374 IO_G16: inout bit; -- PAD369 IO_G17: inout bit; -- PAD437 IO_G18: inout bit; -- PAD427 IO_G19: inout bit; -- PAD422 IO_G21: inout bit; -- PAD508 IO_G22: inout bit; -- PAD509 IO_G23: inout bit; -- PAD513 IO_G24: inout bit; -- PAD503 IO_G26: inout bit; -- PAD510 IO_G27: inout bit; -- PAD511 IO_G28: inout bit; -- PAD514 IO_G29: inout bit; -- PAD515 IO_G31: inout bit; -- PAD551 IO_G32: inout bit; -- PAD580 IO_G33: inout bit; -- PAD587 IO_G34: inout bit; -- PAD600 IO_G36: inout bit; -- PAD590 IO_G37: inout bit; -- PAD591 IO_G38: inout bit; -- PAD597 IO_G39: inout bit; -- PAD17 IO_G41: inout bit; -- PAD18 IO_G42: inout bit; -- PAD19 IO_H13: inout bit; -- PAD379 IO_H14: inout bit; -- PAD377 IO_H15: inout bit; -- PAD376 IO_H16: inout bit; -- PAD368 IO_H18: inout bit; -- PAD436 IO_H19: inout bit; -- PAD426 IO_H20: inout bit; -- PAD435 IO_H21: inout bit; -- PAD505 IO_H23: inout bit; -- PAD512 IO_H24: inout bit; -- PAD502 IO_H25: inout bit; -- PAD506 IO_H26: inout bit; -- PAD507 IO_H28: inout bit; -- PAD518 IO_H29: inout bit; -- PAD519 IO_H30: inout bit; -- PAD617 IO_H31: inout bit; -- PAD621 IO_H33: inout bit; -- PAD586 IO_H34: inout bit; -- PAD612 IO_H35: inout bit; -- PAD613 IO_H36: inout bit; -- PAD599 IO_H38: inout bit; -- PAD596 IO_H39: inout bit; -- PAD16 IO_H40: inout bit; -- PAD14 IO_H41: inout bit; -- PAD15 IO_J11: inout bit; -- PAD400 IO_J12: inout bit; -- PAD381 IO_J13: inout bit; -- PAD378 IO_J15: inout bit; -- PAD383 IO_J16: inout bit; -- PAD351 IO_J17: inout bit; -- PAD433 IO_J18: inout bit; -- PAD429 IO_J20: inout bit; -- PAD434 IO_J21: inout bit; -- PAD504 IO_J22: inout bit; -- PAD535 IO_J23: inout bit; -- PAD529 IO_J25: inout bit; -- PAD524 IO_J26: inout bit; -- PAD525 IO_J27: inout bit; -- PAD521 IO_J28: inout bit; -- PAD517 IO_J30: inout bit; -- PAD616 IO_J31: inout bit; -- PAD620 IO_J32: inout bit; -- PAD604 IO_J33: inout bit; -- PAD605 IO_J35: inout bit; -- PAD603 IO_J36: inout bit; -- PAD598 IO_J37: inout bit; -- PAD594 IO_J38: inout bit; -- PAD595 IO_J40: inout bit; -- PAD22 IO_J41: inout bit; -- PAD23 IO_J42: inout bit; -- PAD31 IO_K12: inout bit; -- PAD380 IO_K13: inout bit; -- PAD385 IO_K14: inout bit; -- PAD384 IO_K15: inout bit; -- PAD382 IO_K17: inout bit; -- PAD432 IO_K18: inout bit; -- PAD401 IO_K19: inout bit; -- PAD428 IO_K20: inout bit; -- PAD450 IO_K22: inout bit; -- PAD534 IO_K23: inout bit; -- PAD528 IO_K24: inout bit; -- PAD522 IO_K25: inout bit; -- PAD523 IO_K27: inout bit; -- PAD520 IO_K28: inout bit; -- PAD516 IO_K29: inout bit; -- PAD614 IO_K30: inout bit; -- PAD615 IO_K32: inout bit; -- PAD625 IO_K33: inout bit; -- PAD606 IO_K34: inout bit; -- PAD607 IO_K35: inout bit; -- PAD602 IO_K37: inout bit; -- PAD34 IO_K38: inout bit; -- PAD35 IO_K39: inout bit; -- PAD24 IO_K40: inout bit; -- PAD25 IO_K42: inout bit; -- PAD30 IO_L11: inout bit; -- PAD389 IO_L12: inout bit; -- PAD388 IO_L14: inout bit; -- PAD391 IO_L15: inout bit; -- PAD387 IO_L16: inout bit; -- PAD386 IO_L17: inout bit; -- PAD441 IO_L19: inout bit; -- PAD449 IO_L20: inout bit; -- PAD448 IO_L21: inout bit; -- PAD537 IO_L22: inout bit; -- PAD531 IO_L24: inout bit; -- PAD527 IO_L25: inout bit; -- PAD532 IO_L26: inout bit; -- PAD533 IO_L27: inout bit; -- PAD549 IO_L29: inout bit; -- PAD618 IO_L30: inout bit; -- PAD619 IO_L31: inout bit; -- PAD624 IO_L32: inout bit; -- PAD623 IO_L34: inout bit; -- PAD608 IO_L35: inout bit; -- PAD609 IO_L36: inout bit; -- PAD1 IO_L37: inout bit; -- PAD37 IO_L39: inout bit; -- PAD26 IO_L40: inout bit; -- PAD27 IO_L41: inout bit; -- PAD29 IO_L42: inout bit; -- PAD33 IO_M11: inout bit; -- PAD399 IO_M12: inout bit; -- PAD398 IO_M13: inout bit; -- PAD395 IO_M14: inout bit; -- PAD390 IO_M16: inout bit; -- PAD393 IO_M17: inout bit; -- PAD440 IO_M18: inout bit; -- PAD445 IO_M19: inout bit; -- PAD444 IO_M21: inout bit; -- PAD536 IO_M22: inout bit; -- PAD530 IO_M23: inout bit; -- PAD501 IO_M24: inout bit; -- PAD526 IO_M26: inout bit; -- PAD550 IO_M27: inout bit; -- PAD548 IO_M28: inout bit; -- PAD630 IO_M29: inout bit; -- PAD631 IO_M31: inout bit; -- PAD627 IO_M32: inout bit; -- PAD622 IO_M33: inout bit; -- PAD610 IO_M34: inout bit; -- PAD611 IO_M36: inout bit; -- PAD36 IO_M37: inout bit; -- PAD40 IO_M38: inout bit; -- PAD41 IO_M39: inout bit; -- PAD45 IO_M41: inout bit; -- PAD28 IO_M42: inout bit; -- PAD32 IO_N13: inout bit; -- PAD394 IO_N14: inout bit; -- PAD397 IO_N15: inout bit; -- PAD396 IO_N16: inout bit; -- PAD392 IO_N18: inout bit; -- PAD443 IO_N19: inout bit; -- PAD442 IO_N20: inout bit; -- PAD447 IO_N21: inout bit; -- PAD539 IO_N23: inout bit; -- PAD546 IO_N24: inout bit; -- PAD547 IO_N25: inout bit; -- PAD544 IO_N26: inout bit; -- PAD545 IO_N28: inout bit; -- PAD634 IO_N29: inout bit; -- PAD635 IO_N30: inout bit; -- PAD626 IO_N31: inout bit; -- PAD629 IO_N33: inout bit; -- PAD54 IO_N34: inout bit; -- PAD55 IO_N35: inout bit; -- PAD51 IO_N36: inout bit; -- PAD50 IO_N38: inout bit; -- PAD44 IO_N39: inout bit; -- PAD48 IO_N40: inout bit; -- PAD49 IO_N41: inout bit; -- PAD39 IO_P17: inout bit; -- PAD439 IO_P18: inout bit; -- PAD438 IO_P20: inout bit; -- PAD446 IO_P21: inout bit; -- PAD538 IO_P22: inout bit; -- PAD542 IO_P23: inout bit; -- PAD543 IO_P25: inout bit; -- PAD540 IO_P26: inout bit; -- PAD541 IO_P28: inout bit; -- PAD633 IO_P30: inout bit; -- PAD628 IO_P31: inout bit; -- PAD637 IO_P32: inout bit; -- PAD62 IO_P33: inout bit; -- PAD63 IO_P35: inout bit; -- PAD58 IO_P36: inout bit; -- PAD59 IO_P37: inout bit; -- PAD66 IO_P38: inout bit; -- PAD67 IO_P40: inout bit; -- PAD47 IO_P41: inout bit; -- PAD38 IO_P42: inout bit; -- PAD43 IO_R28: inout bit; -- PAD632 IO_R29: inout bit; -- PAD601 IO_R30: inout bit; -- PAD636 IO_R32: inout bit; -- PAD61 IO_R33: inout bit; -- PAD56 IO_R34: inout bit; -- PAD57 IO_R35: inout bit; -- PAD53 IO_R37: inout bit; -- PAD65 IO_R38: inout bit; -- PAD70 IO_R39: inout bit; -- PAD71 IO_R40: inout bit; -- PAD46 IO_R42: inout bit; -- PAD42 IO_T29: inout bit; -- PAD642 IO_T30: inout bit; -- PAD643 IO_T31: inout bit; -- PAD639 IO_T32: inout bit; -- PAD60 IO_T34: inout bit; -- PAD52 IO_T35: inout bit; -- PAD69 IO_T36: inout bit; -- PAD64 IO_T37: inout bit; -- PAD77 IO_T39: inout bit; -- PAD75 IO_T40: inout bit; -- PAD90 IO_T41: inout bit; -- PAD91 IO_T42: inout bit; -- PAD95 IO_U28: inout bit; -- PAD650 IO_U29: inout bit; -- PAD647 IO_U31: inout bit; -- PAD638 IO_U32: inout bit; -- PAD84 IO_U33: inout bit; -- PAD85 IO_U34: inout bit; -- PAD68 IO_U36: inout bit; -- PAD76 IO_U37: inout bit; -- PAD72 IO_U38: inout bit; -- PAD73 IO_U39: inout bit; -- PAD74 IO_U41: inout bit; -- PAD94 IO_U42: inout bit; -- PAD99 IO_V29: inout bit; -- PAD646 IO_V30: inout bit; -- PAD640 IO_V31: inout bit; -- PAD641 IO_V33: inout bit; -- PAD80 IO_V34: inout bit; -- PAD81 IO_V35: inout bit; -- PAD78 IO_V36: inout bit; -- PAD79 IO_V38: inout bit; -- PAD97 IO_V39: inout bit; -- PAD88 IO_V40: inout bit; -- PAD89 IO_V41: inout bit; -- PAD98 IO_W30: inout bit; -- PAD644 IO_W31: inout bit; -- PAD645 IO_W32: inout bit; -- PAD86 IO_W33: inout bit; -- PAD87 IO_W35: inout bit; -- PAD100 IO_W36: inout bit; -- PAD82 IO_W37: inout bit; -- PAD83 IO_W38: inout bit; -- PAD96 IO_W40: inout bit; -- PAD104 IO_W41: inout bit; -- PAD92 IO_W42: inout bit; -- PAD93 IO_Y29: inout bit; -- PAD648 IO_Y30: inout bit; -- PAD649 IO_Y32: inout bit; -- PAD188 IO_Y33: inout bit; -- PAD189 IO_Y34: inout bit; -- PAD151 IO_Y35: inout bit; -- PAD166 IO_Y37: inout bit; -- PAD164 IO_Y38: inout bit; -- PAD101 IO_Y39: inout bit; -- PAD106 IO_Y40: inout bit; -- PAD105 IO_Y42: inout bit; -- PAD108 IO_AA29: inout bit; -- PAD196 IO_AA30: inout bit; -- PAD197 IO_AA31: inout bit; -- PAD192 IO_AA32: inout bit; -- PAD193 IO_AA34: inout bit; -- PAD170 IO_AA35: inout bit; -- PAD171 IO_AA36: inout bit; -- PAD167 IO_AA37: inout bit; -- PAD165 IO_AA39: inout bit; -- PAD107 IO_AA40: inout bit; -- PAD112 IO_AA41: inout bit; -- PAD113 IO_AA42: inout bit; -- PAD109 IO_AB29: inout bit; -- PAD198 IO_AB31: inout bit; -- PAD172 IO_AB32: inout bit; -- PAD173 IO_AB33: inout bit; -- PAD174 IO_AB34: inout bit; -- PAD200 IO_AB36: inout bit; -- PAD168 IO_AB37: inout bit; -- PAD169 IO_AB38: inout bit; -- PAD110 IO_AB39: inout bit; -- PAD111 IO_AB41: inout bit; -- PAD102 IO_AB42: inout bit; -- PAD103 IO_AC29: inout bit; -- PAD199 IO_AC30: inout bit; -- PAD194 IO_AC31: inout bit; -- PAD190 IO_AC33: inout bit; -- PAD175 IO_AC34: inout bit; -- PAD178 IO_AC35: inout bit; -- PAD160 IO_AC36: inout bit; -- PAD161 IO_AC38: inout bit; -- PAD114 IO_AC39: inout bit; -- PAD115 IO_AC40: inout bit; -- PAD120 IO_AC41: inout bit; -- PAD121 IO_AD30: inout bit; -- PAD195 IO_AD31: inout bit; -- PAD191 IO_AD32: inout bit; -- PAD176 IO_AD33: inout bit; -- PAD177 IO_AD35: inout bit; -- PAD179 IO_AD36: inout bit; -- PAD158 IO_AD37: inout bit; -- PAD159 IO_AD38: inout bit; -- PAD118 IO_AD40: inout bit; -- PAD124 IO_AD41: inout bit; -- PAD125 IO_AD42: inout bit; -- PAD116 IO_AE29: inout bit; -- PAD186 IO_AE30: inout bit; -- PAD187 IO_AE32: inout bit; -- PAD180 IO_AE33: inout bit; -- PAD181 IO_AE34: inout bit; -- PAD184 IO_AE35: inout bit; -- PAD185 IO_AE37: inout bit; -- PAD154 IO_AE38: inout bit; -- PAD119 IO_AE39: inout bit; -- PAD122 IO_AE40: inout bit; -- PAD123 IO_AE42: inout bit; -- PAD117 IO_AF29: inout bit; -- PAD292 IO_AF30: inout bit; -- PAD296 IO_AF31: inout bit; -- PAD182 IO_AF32: inout bit; -- PAD183 IO_AF34: inout bit; -- PAD156 IO_AF35: inout bit; -- PAD152 IO_AF36: inout bit; -- PAD153 IO_AF37: inout bit; -- PAD155 IO_AF39: inout bit; -- PAD126 IO_AF40: inout bit; -- PAD127 IO_AF41: inout bit; -- PAD128 IO_AF42: inout bit; -- PAD132 IO_AG29: inout bit; -- PAD293 IO_AG31: inout bit; -- PAD297 IO_AG32: inout bit; -- PAD300 IO_AG33: inout bit; -- PAD264 IO_AG34: inout bit; -- PAD157 IO_AG36: inout bit; -- PAD162 IO_AG37: inout bit; -- PAD150 IO_AG38: inout bit; -- PAD134 IO_AG39: inout bit; -- PAD130 IO_AG41: inout bit; -- PAD129 IO_AG42: inout bit; -- PAD133 IO_AH28: inout bit; -- PAD298 IO_AH29: inout bit; -- PAD288 IO_AH30: inout bit; -- PAD289 IO_AH31: inout bit; -- PAD268 IO_AH33: inout bit; -- PAD265 IO_AH34: inout bit; -- PAD270 IO_AH35: inout bit; -- PAD251 IO_AH36: inout bit; -- PAD163 IO_AH38: inout bit; -- PAD135 IO_AH39: inout bit; -- PAD131 IO_AH40: inout bit; -- PAD140 IO_AH41: inout bit; -- PAD141 IO_AJ20: inout bit; -- PAD661 IO_AJ21: inout bit; -- PAD660 IO_AJ22: inout bit; -- PAD656 IO_AJ23: inout bit; -- PAD652 IO_AJ28: inout bit; -- PAD299 IO_AJ30: inout bit; -- PAD290 IO_AJ31: inout bit; -- PAD269 IO_AJ32: inout bit; -- PAD276 IO_AJ33: inout bit; -- PAD272 IO_AJ35: inout bit; -- PAD271 IO_AJ36: inout bit; -- PAD254 IO_AJ37: inout bit; -- PAD255 IO_AJ38: inout bit; -- PAD136 IO_AJ40: inout bit; -- PAD144 IO_AJ41: inout bit; -- PAD145 IO_AJ42: inout bit; -- PAD148 IO_AK20: inout bit; -- PAD654 IO_AK22: inout bit; -- PAD657 IO_AK23: inout bit; -- PAD653 IO_AK28: inout bit; -- PAD294 IO_AK29: inout bit; -- PAD295 IO_AK30: inout bit; -- PAD291 IO_AK32: inout bit; -- PAD277 IO_AK33: inout bit; -- PAD273 IO_AK34: inout bit; -- PAD274 IO_AK35: inout bit; -- PAD266 IO_AK37: inout bit; -- PAD258 IO_AK38: inout bit; -- PAD137 IO_AK39: inout bit; -- PAD146 IO_AK40: inout bit; -- PAD138 IO_AK42: inout bit; -- PAD149 IO_AL20: inout bit; -- PAD655 IO_AL21: inout bit; -- PAD658 IO_AL22: inout bit; -- PAD662 IO_AL24: inout bit; -- PAD651 IO_AL29: inout bit; -- PAD286 IO_AL30: inout bit; -- PAD287 IO_AL31: inout bit; -- PAD278 IO_AL32: inout bit; -- PAD279 IO_AL34: inout bit; -- PAD275 IO_AL35: inout bit; -- PAD267 IO_AL36: inout bit; -- PAD262 IO_AL37: inout bit; -- PAD259 IO_AL39: inout bit; -- PAD147 IO_AL40: inout bit; -- PAD139 IO_AL41: inout bit; -- PAD142 IO_AL42: inout bit; -- PAD143 IO_AM21: inout bit; -- PAD659 IO_AM22: inout bit; -- PAD663 IO_AM23: inout bit; -- PAD666 IO_AM24: inout bit; -- PAD664 IO_AM31: inout bit; -- PAD282 IO_AM32: inout bit; -- PAD283 IO_AM33: inout bit; -- PAD284 IO_AM34: inout bit; -- PAD280 IO_AM36: inout bit; -- PAD252 IO_AM37: inout bit; -- PAD263 IO_AM38: inout bit; -- PAD201 IO_AM39: inout bit; -- PAD212 IO_AM41: inout bit; -- PAD204 IO_AM42: inout bit; -- PAD205 IO_AN20: inout bit; -- PAD700 IO_AN21: inout bit; -- PAD670 IO_AN23: inout bit; -- PAD667 IO_AN24: inout bit; -- PAD665 IO_AN30: inout bit; -- PAD342 IO_AN31: inout bit; -- PAD346 IO_AN33: inout bit; -- PAD285 IO_AN34: inout bit; -- PAD281 IO_AN35: inout bit; -- PAD260 IO_AN36: inout bit; -- PAD253 IO_AN38: inout bit; -- PAD202 IO_AN39: inout bit; -- PAD213 IO_AN40: inout bit; -- PAD208 IO_AN41: inout bit; -- PAD209 IO_AP21: inout bit; -- PAD671 IO_AP22: inout bit; -- PAD669 IO_AP23: inout bit; -- PAD668 IO_AP30: inout bit; -- PAD343 IO_AP31: inout bit; -- PAD347 IO_AP32: inout bit; -- PAD344 IO_AP33: inout bit; -- PAD348 IO_AP35: inout bit; -- PAD261 IO_AP36: inout bit; -- PAD256 IO_AP37: inout bit; -- PAD257 IO_AP38: inout bit; -- PAD203 IO_AP40: inout bit; -- PAD214 IO_AP41: inout bit; -- PAD216 IO_AP42: inout bit; -- PAD217 IO_AR22: inout bit; -- PAD673 IO_AR23: inout bit; -- PAD672 IO_AR24: inout bit; -- PAD682 IO_AR30: inout bit; -- PAD338 IO_AR32: inout bit; -- PAD345 IO_AR33: inout bit; -- PAD349 IO_AR34: inout bit; -- PAD320 IO_AR35: inout bit; -- PAD301 IO_AR37: inout bit; -- PAD210 IO_AR38: inout bit; -- PAD206 IO_AR39: inout bit; -- PAD207 IO_AR40: inout bit; -- PAD215 IO_AR42: inout bit; -- PAD220 IO_AT21: inout bit; -- PAD680 IO_AT22: inout bit; -- PAD674 IO_AT24: inout bit; -- PAD683 IO_AT30: inout bit; -- PAD339 IO_AT31: inout bit; -- PAD350 IO_AT32: inout bit; -- PAD318 IO_AT34: inout bit; -- PAD314 IO_AT35: inout bit; -- PAD321 IO_AT36: inout bit; -- PAD316 IO_AT37: inout bit; -- PAD211 IO_AT39: inout bit; -- PAD218 IO_AT40: inout bit; -- PAD219 IO_AT41: inout bit; -- PAD240 IO_AT42: inout bit; -- PAD221 IO_AU21: inout bit; -- PAD681 IO_AU22: inout bit; -- PAD675 IO_AU23: inout bit; -- PAD676 IO_AU24: inout bit; -- PAD686 IO_AU31: inout bit; -- PAD340 IO_AU32: inout bit; -- PAD322 IO_AU33: inout bit; -- PAD319 IO_AU34: inout bit; -- PAD315 IO_AU36: inout bit; -- PAD317 IO_AU37: inout bit; -- PAD250 IO_AU38: inout bit; -- PAD224 IO_AU39: inout bit; -- PAD222 IO_AU41: inout bit; -- PAD244 IO_AU42: inout bit; -- PAD241 IO_AV21: inout bit; -- PAD684 IO_AV23: inout bit; -- PAD677 IO_AV24: inout bit; -- PAD687 IO_AV30: inout bit; -- PAD336 IO_AV31: inout bit; -- PAD341 IO_AV33: inout bit; -- PAD323 IO_AV34: inout bit; -- PAD326 IO_AV35: inout bit; -- PAD327 IO_AV36: inout bit; -- PAD304 IO_AV38: inout bit; -- PAD225 IO_AV39: inout bit; -- PAD223 IO_AV40: inout bit; -- PAD226 IO_AV41: inout bit; -- PAD245 IO_AW21: inout bit; -- PAD685 IO_AW22: inout bit; -- PAD679 IO_AW23: inout bit; -- PAD678 IO_AW30: inout bit; -- PAD332 IO_AW31: inout bit; -- PAD337 IO_AW32: inout bit; -- PAD324 IO_AW33: inout bit; -- PAD325 IO_AW35: inout bit; -- PAD312 IO_AW36: inout bit; -- PAD305 IO_AW37: inout bit; -- PAD230 IO_AW38: inout bit; -- PAD234 IO_AW40: inout bit; -- PAD227 IO_AW41: inout bit; -- PAD248 IO_AW42: inout bit; -- PAD249 IO_AY22: inout bit; -- PAD689 IO_AY23: inout bit; -- PAD688 IO_AY24: inout bit; -- PAD694 IO_AY25: inout bit; -- PAD690 IO_AY30: inout bit; -- PAD333 IO_AY32: inout bit; -- PAD328 IO_AY33: inout bit; -- PAD329 IO_AY34: inout bit; -- PAD302 IO_AY35: inout bit; -- PAD313 IO_AY37: inout bit; -- PAD231 IO_AY38: inout bit; -- PAD235 IO_AY39: inout bit; -- PAD228 IO_AY40: inout bit; -- PAD229 IO_AY42: inout bit; -- PAD242 IO_BA21: inout bit; -- PAD696 IO_BA22: inout bit; -- PAD692 IO_BA24: inout bit; -- PAD695 IO_BA25: inout bit; -- PAD691 IO_BA30: inout bit; -- PAD334 IO_BA31: inout bit; -- PAD330 IO_BA32: inout bit; -- PAD331 IO_BA34: inout bit; -- PAD306 IO_BA35: inout bit; -- PAD303 IO_BA36: inout bit; -- PAD308 IO_BA37: inout bit; -- PAD232 IO_BA39: inout bit; -- PAD238 IO_BA40: inout bit; -- PAD239 IO_BA41: inout bit; -- PAD246 IO_BA42: inout bit; -- PAD243 IO_BB21: inout bit; -- PAD697 IO_BB22: inout bit; -- PAD693 IO_BB23: inout bit; -- PAD699 IO_BB24: inout bit; -- PAD698 IO_BB31: inout bit; -- PAD335 IO_BB32: inout bit; -- PAD310 IO_BB33: inout bit; -- PAD311 IO_BB34: inout bit; -- PAD307 IO_BB36: inout bit; -- PAD309 IO_BB37: inout bit; -- PAD233 IO_BB38: inout bit; -- PAD236 IO_BB39: inout bit; -- PAD237 IO_BB41: inout bit -- PAD247 ); --end port list -- Use Statements use STD_1149_1_2001.all; use STD_1149_6_2003.all; -- Component Conformance Statement(s) attribute COMPONENT_CONFORMANCE of XC7VX485T_FFG1761 : entity is "STD_1149_1_2001"; -- Device Package Pin Mappings attribute PIN_MAP of XC7VX485T_FFG1761 : entity is PHYSICAL_PIN_MAP; constant FFG1761: PIN_MAP_STRING:= "CCLK_N10:N10," & "CFGBVS_AH10:AH10," & "DONE_AL11:AL11," & "GND:(A2,A3,A4,A7,A8,A11,A13,A18,A28,A38," & "B1,B2,B5,B9,B10,B12,B13,B15,B25,B35," & "C3,C7,C11,C12,C22,C32,C42,D1,D2,D5," & "D9,D10,D11,D19,D29,D39,E3,E7,E11,E16," & "E26,E36,F1,F2,F5,F9,F10,F11,F13,F23," & "F33,G3,G7,G11,G20,G30,G40,H1,H2,H5," & "H9,H10,H11,H17,H27,H37,J3,J7,J9,J10," & "J14,J24,J34,K1,K2,K5,K6,K9,K10,K11," & "K21,K31,K41,L3,L7,L9,L10,L18,L28,L38," & "M1,M2,M5,M6,M9,M15,M25,M35,N3,N7," & "N9,N12,N22,N32,N42,P1,P2,P5,P9,P12," & "P16,P19,P29,P39,R3,R7,R9,R11,R13,R15," & "R17,R19,R21,R23,R25,R27,R36,T1,T2,T5," & "T6,T9,T12,T14,T16,T18,T20,T22,T24,T26," & "T33,U3,U4,U7,U9,U10,U11,U13,U15,U17," & "U19,U21,U23,U25,U27,U30,U40,V1,V2,V5," & "V6,V9,V10,V12,V14,V16,V18,V20,V22,V24," & "V26,V28,V37,W3,W7,W11,W13,W15,W17,W19," & "W21,W23,W25,W27,W34,Y1,Y2,Y5,Y6,Y9," & "Y10,Y12,Y14,Y16,Y18,Y22,Y24,Y26,Y28,Y31," & "Y41,AA3,AA7,AA9,AA11,AA13,AA15,AA17,AA19,AA23," & "AA25,AA27,AA38,AB1,AB2,AB5,AB6,AB9,AB10,AB12," & "AB14,AB16,AB18,AB22,AB24,AB26,AB28,AB35,AC3,AC7," & "AC11,AC13,AC15,AC17,AC19,AC23,AC25,AC27,AC32,AC42," & "AD1,AD2,AD5,AD6,AD9,AD10,AD12,AD14,AD16,AD18," & "AD20,AD22,AD24,AD26,AD28,AD29,AD39,AE3,AE7,AE9," & "AE11,AE13,AE15,AE17,AE19,AE21,AE23,AE25,AE27,AE36," & "AF1,AF2,AF5,AF6,AF9,AF10,AF12,AF14,AF16,AF18," & "AF20,AF22,AF24,AF26,AF33,AG3,AG4,AG7,AG8,AG9," & "AG10,AG13,AG15,AG17,AG19,AG21,AG23,AG25,AG27,AG30," & "AG40,AH1,AH2,AH5,AH6,AH9,AH12,AH14,AH16,AH17," & "AH18,AH20,AH22,AH24,AH26,AH37,AJ3,AJ7,AJ9,AJ14," & "AJ24,AJ27,AJ34,AK1,AK2,AK5,AK6,AK9,AK11,AK21," & "AK31,AK41,AL3,AL7,AL9,AL18,AL28,AL38,AM1,AM2," & "AM5,AM9,AM10,AM15,AM25,AM35,AN3,AN7,AN9,AN10," & "AN12,AN22,AN32,AN42,AP1,AP2,AP5,AP9,AP10,AP19," & "AP29,AP39,AR3,AR7,AR9,AR10,AR16,AR26,AR36,AT1," & "AT2,AT5,AT6,AT9,AT10,AT11,AT13,AT23,AT33,AU3," & "AU7,AU11,AU20,AU30,AU40,AV1,AV2,AV5,AV9,AV10," & "AV11,AV17,AV27,AV37,AW3,AW7,AW11,AW14,AW24,AW34," & "AY1,AY2,AY5,AY9,AY10,AY11,AY21,AY31,AY41,BA3," & "BA7,BA11,BA18,BA28,BA38,BB2,BB5,BB6,BB9,BB10," & "BB11,BB15,BB25,BB35)," & "GNDADC_0:Y20," & "INIT_B_AG11:AG11," & "M0_AL10:AL10," & "M1_AK10:AK10," & "M2_AJ10:AJ10," & "MGTAVCC_G10:(W8,AA8,AC8,AE8,AJ8,AL8,AN8,AR8,AU8,AW8," & "BA8)," & "MGTAVCC_G11:(C8,E8,G8,J8,L8)," & "MGTAVTTRCAL_115:A12," & "MGTAVTT_G10:(R4,W4,AA4,AC4,AE4,AJ4,AL4,AM6,AN4,AP6," & "AR4,AU4,AV6,AW4,AY6,BA4)," & "MGTAVTT_G11:(B6,C4,D6,E4,F6,G4,H6,J4,L4,N4," & "P6)," & "MGTREFCLK0N_113:AH7," & "MGTREFCLK0N_114:AD7," & "MGTREFCLK0N_115:Y7," & "MGTREFCLK0N_116:T7," & "MGTREFCLK0N_117:K7," & "MGTREFCLK0N_118:E9," & "MGTREFCLK0N_119:A9," & "MGTREFCLK0P_113:AH8," & "MGTREFCLK0P_114:AD8," & "MGTREFCLK0P_115:Y8," & "MGTREFCLK0P_116:T8," & "MGTREFCLK0P_117:K8," & "MGTREFCLK0P_118:E10," & "MGTREFCLK0P_119:A10," & "MGTREFCLK1N_113:AK7," & "MGTREFCLK1N_114:AF7," & "MGTREFCLK1N_115:AB7," & "MGTREFCLK1N_116:V7," & "MGTREFCLK1N_117:M7," & "MGTREFCLK1N_118:G9," & "MGTREFCLK1N_119:C9," & "MGTREFCLK1P_113:AK8," & "MGTREFCLK1P_114:AF8," & "MGTREFCLK1P_115:AB8," & "MGTREFCLK1P_116:V8," & "MGTREFCLK1P_117:M8," & "MGTREFCLK1P_118:G10," & "MGTREFCLK1P_119:C10," & "MGTRREF_115:B11," & "MGTVCCAUX_G10:(R8,U8)," & "MGTVCCAUX_G11:N8," & "MGTXRXN0_113:AN5," & "MGTXRXN0_114:AG5," & "MGTXRXN0_115:AC5," & "MGTXRXN0_116:W5," & "MGTXRXN0_117:P7," & "MGTXRXN0_118:H7," & "MGTXRXN0_119:D7," & "MGTXRXN1_113:AM7," & "MGTXRXN1_114:AF3," & "MGTXRXN1_115:AB3," & "MGTXRXN1_116:V3," & "MGTXRXN1_117:N5," & "MGTXRXN1_118:G5," & "MGTXRXN1_119:C5," & "MGTXRXN2_113:AL5," & "MGTXRXN2_114:AE5," & "MGTXRXN2_115:AA5," & "MGTXRXN2_116:U5," & "MGTXRXN2_117:L5," & "MGTXRXN2_118:F7," & "MGTXRXN2_119:B7," & "MGTXRXN3_113:AJ5," & "MGTXRXN3_114:AD3," & "MGTXRXN3_115:Y3," & "MGTXRXN3_116:R5," & "MGTXRXN3_117:J5," & "MGTXRXN3_118:E5," & "MGTXRXN3_119:A5," & "MGTXRXP0_113:AN6," & "MGTXRXP0_114:AG6," & "MGTXRXP0_115:AC6," & "MGTXRXP0_116:W6," & "MGTXRXP0_117:P8," & "MGTXRXP0_118:H8," & "MGTXRXP0_119:D8," & "MGTXRXP1_113:AM8," & "MGTXRXP1_114:AF4," & "MGTXRXP1_115:AB4," & "MGTXRXP1_116:V4," & "MGTXRXP1_117:N6," & "MGTXRXP1_118:G6," & "MGTXRXP1_119:C6," & "MGTXRXP2_113:AL6," & "MGTXRXP2_114:AE6," & "MGTXRXP2_115:AA6," & "MGTXRXP2_116:U6," & "MGTXRXP2_117:L6," & "MGTXRXP2_118:F8," & "MGTXRXP2_119:B8," & "MGTXRXP3_113:AJ6," & "MGTXRXP3_114:AD4," & "MGTXRXP3_115:Y4," & "MGTXRXP3_116:R6," & "MGTXRXP3_117:J6," & "MGTXRXP3_118:E6," & "MGTXRXP3_119:A6," & "MGTXTXN0_113:AP3," & "MGTXTXN0_114:AK3," & "MGTXTXN0_115:AE1," & "MGTXTXN0_116:U1," & "MGTXTXN0_117:N1," & "MGTXTXN0_118:J1," & "MGTXTXN0_119:E1," & "MGTXTXN1_113:AN1," & "MGTXTXN1_114:AJ1," & "MGTXTXN1_115:AC1," & "MGTXTXN1_116:T3," & "MGTXTXN1_117:M3," & "MGTXTXN1_118:H3," & "MGTXTXN1_119:D3," & "MGTXTXN2_113:AM3," & "MGTXTXN2_114:AH3," & "MGTXTXN2_115:AA1," & "MGTXTXN2_116:R1," & "MGTXTXN2_117:L1," & "MGTXTXN2_118:G1," & "MGTXTXN2_119:C1," & "MGTXTXN3_113:AL1," & "MGTXTXN3_114:AG1," & "MGTXTXN3_115:W1," & "MGTXTXN3_116:P3," & "MGTXTXN3_117:K3," & "MGTXTXN3_118:F3," & "MGTXTXN3_119:B3," & "MGTXTXP0_113:AP4," & "MGTXTXP0_114:AK4," & "MGTXTXP0_115:AE2," & "MGTXTXP0_116:U2," & "MGTXTXP0_117:N2," & "MGTXTXP0_118:J2," & "MGTXTXP0_119:E2," & "MGTXTXP1_113:AN2," & "MGTXTXP1_114:AJ2," & "MGTXTXP1_115:AC2," & "MGTXTXP1_116:T4," & "MGTXTXP1_117:M4," & "MGTXTXP1_118:H4," & "MGTXTXP1_119:D4," & "MGTXTXP2_113:AM4," & "MGTXTXP2_114:AH4," & "MGTXTXP2_115:AA2," & "MGTXTXP2_116:R2," & "MGTXTXP2_117:L2," & "MGTXTXP2_118:G2," & "MGTXTXP2_119:C2," & "MGTXTXP3_113:AL2," & "MGTXTXP3_114:AG2," & "MGTXTXP3_115:W2," & "MGTXTXP3_116:P4," & "MGTXTXP3_117:K4," & "MGTXTXP3_118:F4," & "MGTXTXP3_119:B4," & "NOCONNECT:(W9,W10,AC9,AC10,AJ12,AJ13,AJ15,AJ16,AJ17,AJ18," & "AJ25,AJ26,AK12,AK13,AK14,AK15,AK17,AK18,AK19,AK24," & "AK25,AK27,AL12,AL14,AL15,AL16,AL17,AL19,AL25,AL26," & "AL27,AM11,AM12,AM13,AM14,AM16,AM17,AM18,AM19,AM26," & "AM27,AM28,AM29,AN11,AN13,AN14,AN15,AN16,AN18,AN19," & "AN25,AN26,AN28,AN29,AP7,AP8,AP11,AP12,AP13,AP15," & "AP16,AP17,AP18,AP20,AP25,AP26,AP27,AP28,AR1,AR2," & "AR5,AR6,AR12,AR13,AR14,AR15,AR17,AR18,AR19,AR20," & "AR25,AR27,AR28,AR29,AT3,AT4,AT7,AT8,AT12,AT14," & "AT15,AT16,AT17,AT19,AT20,AT25,AT26,AT27,AT29,AU1," & "AU2,AU5,AU6,AU9,AU10,AU12,AU13,AU14,AU16,AU17," & "AU18,AU19,AU26,AU27,AU28,AU29,AV3,AV4,AV7,AV8," & "AV13,AV14,AV15,AV16,AV18,AV19,AV20,AV25,AV26,AV28," & "AV29,AW1,AW2,AW5,AW6,AW9,AW10,AW12,AW13,AW15," & "AW16,AW17,AW18,AW20,AW25,AW26,AW27,AW28,AY3,AY4," & "AY7,AY8,AY12,AY13,AY14,AY15,AY17,AY18,AY19,AY20," & "AY27,AY28,AY29,BA1,BA2,BA5,BA6,BA9,BA10,BA12," & "BA14,BA15,BA16,BA17,BA19,BA20,BA26,BA27,BA29,BB3," & "BB4,BB7,BB8,BB12,BB13,BB14,BB16,BB17,BB18,BB19," & "BB26,BB27,BB28,BB29)," & "PROGRAM_B:AJ11," & "TCK:P10," & "TDI:T10," & "TDN_AC20:AC20," & "TDO:R10," & "TDP_AC21:AC21," & "TMS:P11," & "VCCADC_0:Y21," & "VCCAUX:(R18,R26,T17,T19,T25,U18,U26,V17,V25,W18," & "W26,Y17,Y25,AA18,AA26,AB17,AB25,AC18,AC26,AD17," & "AD25,AE18,AE26,AF17,AF19,AF25,AG18,AG26,AH25)," & "VCCBATT_0:N11," & "VCCBRAM:(R22,U22,W22,AA22,AC22,AE22,AG22,AH21)," & "VCCINT:(P13,P15,P27,R12,R14,R16,R20,R24,T13,T15," & "T21,T23,T27,U12,U14,U16,U20,U24,V11,V13," & "V15,V19,V21,V23,V27,W12,W14,W16,W20,W24," & "W28,Y11,Y13,Y15,Y19,Y23,Y27,AA10,AA12,AA14," & "AA16,AA24,AA28,AB11,AB13,AB15,AB19,AB23,AB27,AC12," & "AC14,AC16,AC24,AC28,AD11,AD13,AD15,AD19,AD21,AD23," & "AD27,AE10,AE12,AE14,AE16,AE20,AE24,AE28,AF11,AF13," & "AF15,AF21,AF23,AF27,AG12,AG14,AG16,AG20,AG24,AG28," & "AH11,AH13,AH15,AH19,AH23,AH27)," & "VCCO_0:(M10,T11)," & "VCCO_12:(AK26,AN27,AT28,AU25,AW29,AY26)," & "VCCO_13:(AP34,AR31,AU35,AV32,AY36,BA33,BB30)," & "VCCO_14:(AF28,AH32,AJ29,AK36,AL33,AM30,AN37)," & "VCCO_15:(AM40,AR41,AT38,AV42,AW39,BB40)," & "VCCO_16:(Y36,AA33,AB30,AD34,AE31,AG35)," & "VCCO_17:(AB40,AC37,AE41,AF38,AH42,AJ39)," & "VCCO_18:(P34,T38,U35,V32,V42,W39)," & "VCCO_19:(B40,E41,H42,J39,M40,N37,R41)," & "VCCO_31:(AK16,AL13,AP14,AR11,AU15,AV12,BA13)," & "VCCO_32:(AJ19,AN17,AT18,AW19,AY16,BB20)," & "VCCO_33:(AL23,AM20,AP24,AR21,AV22,BA23)," & "VCCO_34:(H32,L33,M30,R31,T28,W29)," & "VCCO_35:(A33,C37,D34,E31,F38,G35,K36)," & "VCCO_36:(G25,H22,J29,K26,L23,N27,P24)," & "VCCO_37:(A23,B30,C27,D24,E21,F28)," & "VCCO_38:(B20,C17,F18,J19,M20,N17)," & "VCCO_39:(D14,G15,H12,K16,L13,P14)," & "VN_AB20:AB20," & "VP_AA21:AA21," & "VREFN_AA20:AA20," & "VREFP_AB21:AB21," & "IO_A14:A14," & "IO_A15:A15," & "IO_A16:A16," & "IO_A17:A17," & "IO_A19:A19," & "IO_A20:A20," & "IO_A21:A21," & "IO_A22:A22," & "IO_A24:A24," & "IO_A25:A25," & "IO_A26:A26," & "IO_A27:A27," & "IO_A29:A29," & "IO_A30:A30," & "IO_A31:A31," & "IO_A32:A32," & "IO_A34:A34," & "IO_A35:A35," & "IO_A36:A36," & "IO_A37:A37," & "IO_A39:A39," & "IO_A40:A40," & "IO_A41:A41," & "IO_B14:B14," & "IO_B16:B16," & "IO_B17:B17," & "IO_B18:B18," & "IO_B19:B19," & "IO_B21:B21," & "IO_B22:B22," & "IO_B23:B23," & "IO_B24:B24," & "IO_B26:B26," & "IO_B27:B27," & "IO_B28:B28," & "IO_B29:B29," & "IO_B31:B31," & "IO_B32:B32," & "IO_B33:B33," & "IO_B34:B34," & "IO_B36:B36," & "IO_B37:B37," & "IO_B38:B38," & "IO_B39:B39," & "IO_B41:B41," & "IO_B42:B42," & "IO_C13:C13," & "IO_C14:C14," & "IO_C15:C15," & "IO_C16:C16," & "IO_C18:C18," & "IO_C19:C19," & "IO_C20:C20," & "IO_C21:C21," & "IO_C23:C23," & "IO_C24:C24," & "IO_C25:C25," & "IO_C26:C26," & "IO_C28:C28," & "IO_C29:C29," & "IO_C30:C30," & "IO_C31:C31," & "IO_C33:C33," & "IO_C34:C34," & "IO_C35:C35," & "IO_C36:C36," & "IO_C38:C38," & "IO_C39:C39," & "IO_C40:C40," & "IO_C41:C41," & "IO_D12:D12," & "IO_D13:D13," & "IO_D15:D15," & "IO_D16:D16," & "IO_D17:D17," & "IO_D18:D18," & "IO_D20:D20," & "IO_D21:D21," & "IO_D22:D22," & "IO_D23:D23," & "IO_D25:D25," & "IO_D26:D26," & "IO_D27:D27," & "IO_D28:D28," & "IO_D30:D30," & "IO_D31:D31," & "IO_D32:D32," & "IO_D33:D33," & "IO_D35:D35," & "IO_D36:D36," & "IO_D37:D37," & "IO_D38:D38," & "IO_D40:D40," & "IO_D41:D41," & "IO_D42:D42," & "IO_E12:E12," & "IO_E13:E13," & "IO_E14:E14," & "IO_E15:E15," & "IO_E17:E17," & "IO_E18:E18," & "IO_E19:E19," & "IO_E20:E20," & "IO_E22:E22," & "IO_E23:E23," & "IO_E24:E24," & "IO_E25:E25," & "IO_E27:E27," & "IO_E28:E28," & "IO_E29:E29," & "IO_E30:E30," & "IO_E32:E32," & "IO_E33:E33," & "IO_E34:E34," & "IO_E35:E35," & "IO_E37:E37," & "IO_E38:E38," & "IO_E39:E39," & "IO_E40:E40," & "IO_E42:E42," & "IO_F12:F12," & "IO_F14:F14," & "IO_F15:F15," & "IO_F16:F16," & "IO_F17:F17," & "IO_F19:F19," & "IO_F20:F20," & "IO_F21:F21," & "IO_F22:F22," & "IO_F24:F24," & "IO_F25:F25," & "IO_F26:F26," & "IO_F27:F27," & "IO_F29:F29," & "IO_F30:F30," & "IO_F31:F31," & "IO_F32:F32," & "IO_F34:F34," & "IO_F35:F35," & "IO_F36:F36," & "IO_F37:F37," & "IO_F39:F39," & "IO_F40:F40," & "IO_F41:F41," & "IO_F42:F42," & "IO_G12:G12," & "IO_G13:G13," & "IO_G14:G14," & "IO_G16:G16," & "IO_G17:G17," & "IO_G18:G18," & "IO_G19:G19," & "IO_G21:G21," & "IO_G22:G22," & "IO_G23:G23," & "IO_G24:G24," & "IO_G26:G26," & "IO_G27:G27," & "IO_G28:G28," & "IO_G29:G29," & "IO_G31:G31," & "IO_G32:G32," & "IO_G33:G33," & "IO_G34:G34," & "IO_G36:G36," & "IO_G37:G37," & "IO_G38:G38," & "IO_G39:G39," & "IO_G41:G41," & "IO_G42:G42," & "IO_H13:H13," & "IO_H14:H14," & "IO_H15:H15," & "IO_H16:H16," & "IO_H18:H18," & "IO_H19:H19," & "IO_H20:H20," & "IO_H21:H21," & "IO_H23:H23," & "IO_H24:H24," & "IO_H25:H25," & "IO_H26:H26," & "IO_H28:H28," & "IO_H29:H29," & "IO_H30:H30," & "IO_H31:H31," & "IO_H33:H33," & "IO_H34:H34," & "IO_H35:H35," & "IO_H36:H36," & "IO_H38:H38," & "IO_H39:H39," & "IO_H40:H40," & "IO_H41:H41," & "IO_J11:J11," & "IO_J12:J12," & "IO_J13:J13," & "IO_J15:J15," & "IO_J16:J16," & "IO_J17:J17," & "IO_J18:J18," & "IO_J20:J20," & "IO_J21:J21," & "IO_J22:J22," & "IO_J23:J23," & "IO_J25:J25," & "IO_J26:J26," & "IO_J27:J27," & "IO_J28:J28," & "IO_J30:J30," & "IO_J31:J31," & "IO_J32:J32," & "IO_J33:J33," & "IO_J35:J35," & "IO_J36:J36," & "IO_J37:J37," & "IO_J38:J38," & "IO_J40:J40," & "IO_J41:J41," & "IO_J42:J42," & "IO_K12:K12," & "IO_K13:K13," & "IO_K14:K14," & "IO_K15:K15," & "IO_K17:K17," & "IO_K18:K18," & "IO_K19:K19," & "IO_K20:K20," & "IO_K22:K22," & "IO_K23:K23," & "IO_K24:K24," & "IO_K25:K25," & "IO_K27:K27," & "IO_K28:K28," & "IO_K29:K29," & "IO_K30:K30," & "IO_K32:K32," & "IO_K33:K33," & "IO_K34:K34," & "IO_K35:K35," & "IO_K37:K37," & "IO_K38:K38," & "IO_K39:K39," & "IO_K40:K40," & "IO_K42:K42," & "IO_L11:L11," & "IO_L12:L12," & "IO_L14:L14," & "IO_L15:L15," & "IO_L16:L16," & "IO_L17:L17," & "IO_L19:L19," & "IO_L20:L20," & "IO_L21:L21," & "IO_L22:L22," & "IO_L24:L24," & "IO_L25:L25," & "IO_L26:L26," & "IO_L27:L27," & "IO_L29:L29," & "IO_L30:L30," & "IO_L31:L31," & "IO_L32:L32," & "IO_L34:L34," & "IO_L35:L35," & "IO_L36:L36," & "IO_L37:L37," & "IO_L39:L39," & "IO_L40:L40," & "IO_L41:L41," & "IO_L42:L42," & "IO_M11:M11," & "IO_M12:M12," & "IO_M13:M13," & "IO_M14:M14," & "IO_M16:M16," & "IO_M17:M17," & "IO_M18:M18," & "IO_M19:M19," & "IO_M21:M21," & "IO_M22:M22," & "IO_M23:M23," & "IO_M24:M24," & "IO_M26:M26," & "IO_M27:M27," & "IO_M28:M28," & "IO_M29:M29," & "IO_M31:M31," & "IO_M32:M32," & "IO_M33:M33," & "IO_M34:M34," & "IO_M36:M36," & "IO_M37:M37," & "IO_M38:M38," & "IO_M39:M39," & "IO_M41:M41," & "IO_M42:M42," & "IO_N13:N13," & "IO_N14:N14," & "IO_N15:N15," & "IO_N16:N16," & "IO_N18:N18," & "IO_N19:N19," & "IO_N20:N20," & "IO_N21:N21," & "IO_N23:N23," & "IO_N24:N24," & "IO_N25:N25," & "IO_N26:N26," & "IO_N28:N28," & "IO_N29:N29," & "IO_N30:N30," & "IO_N31:N31," & "IO_N33:N33," & "IO_N34:N34," & "IO_N35:N35," & "IO_N36:N36," & "IO_N38:N38," & "IO_N39:N39," & "IO_N40:N40," & "IO_N41:N41," & "IO_P17:P17," & "IO_P18:P18," & "IO_P20:P20," & "IO_P21:P21," & "IO_P22:P22," & "IO_P23:P23," & "IO_P25:P25," & "IO_P26:P26," & "IO_P28:P28," & "IO_P30:P30," & "IO_P31:P31," & "IO_P32:P32," & "IO_P33:P33," & "IO_P35:P35," & "IO_P36:P36," & "IO_P37:P37," & "IO_P38:P38," & "IO_P40:P40," & "IO_P41:P41," & "IO_P42:P42," & "IO_R28:R28," & "IO_R29:R29," & "IO_R30:R30," & "IO_R32:R32," & "IO_R33:R33," & "IO_R34:R34," & "IO_R35:R35," & "IO_R37:R37," & "IO_R38:R38," & "IO_R39:R39," & "IO_R40:R40," & "IO_R42:R42," & "IO_T29:T29," & "IO_T30:T30," & "IO_T31:T31," & "IO_T32:T32," & "IO_T34:T34," & "IO_T35:T35," & "IO_T36:T36," & "IO_T37:T37," & "IO_T39:T39," & "IO_T40:T40," & "IO_T41:T41," & "IO_T42:T42," & "IO_U28:U28," & "IO_U29:U29," & "IO_U31:U31," & "IO_U32:U32," & "IO_U33:U33," & "IO_U34:U34," & "IO_U36:U36," & "IO_U37:U37," & "IO_U38:U38," & "IO_U39:U39," & "IO_U41:U41," & "IO_U42:U42," & "IO_V29:V29," & "IO_V30:V30," & "IO_V31:V31," & "IO_V33:V33," & "IO_V34:V34," & "IO_V35:V35," & "IO_V36:V36," & "IO_V38:V38," & "IO_V39:V39," & "IO_V40:V40," & "IO_V41:V41," & "IO_W30:W30," & "IO_W31:W31," & "IO_W32:W32," & "IO_W33:W33," & "IO_W35:W35," & "IO_W36:W36," & "IO_W37:W37," & "IO_W38:W38," & "IO_W40:W40," & "IO_W41:W41," & "IO_W42:W42," & "IO_Y29:Y29," & "IO_Y30:Y30," & "IO_Y32:Y32," & "IO_Y33:Y33," & "IO_Y34:Y34," & "IO_Y35:Y35," & "IO_Y37:Y37," & "IO_Y38:Y38," & "IO_Y39:Y39," & "IO_Y40:Y40," & "IO_Y42:Y42," & "IO_AA29:AA29," & "IO_AA30:AA30," & "IO_AA31:AA31," & "IO_AA32:AA32," & "IO_AA34:AA34," & "IO_AA35:AA35," & "IO_AA36:AA36," & "IO_AA37:AA37," & "IO_AA39:AA39," & "IO_AA40:AA40," & "IO_AA41:AA41," & "IO_AA42:AA42," & "IO_AB29:AB29," & "IO_AB31:AB31," & "IO_AB32:AB32," & "IO_AB33:AB33," & "IO_AB34:AB34," & "IO_AB36:AB36," & "IO_AB37:AB37," & "IO_AB38:AB38," & "IO_AB39:AB39," & "IO_AB41:AB41," & "IO_AB42:AB42," & "IO_AC29:AC29," & "IO_AC30:AC30," & "IO_AC31:AC31," & "IO_AC33:AC33," & "IO_AC34:AC34," & "IO_AC35:AC35," & "IO_AC36:AC36," & "IO_AC38:AC38," & "IO_AC39:AC39," & "IO_AC40:AC40," & "IO_AC41:AC41," & "IO_AD30:AD30," & "IO_AD31:AD31," & "IO_AD32:AD32," & "IO_AD33:AD33," & "IO_AD35:AD35," & "IO_AD36:AD36," & "IO_AD37:AD37," & "IO_AD38:AD38," & "IO_AD40:AD40," & "IO_AD41:AD41," & "IO_AD42:AD42," & "IO_AE29:AE29," & "IO_AE30:AE30," & "IO_AE32:AE32," & "IO_AE33:AE33," & "IO_AE34:AE34," & "IO_AE35:AE35," & "IO_AE37:AE37," & "IO_AE38:AE38," & "IO_AE39:AE39," & "IO_AE40:AE40," & "IO_AE42:AE42," & "IO_AF29:AF29," & "IO_AF30:AF30," & "IO_AF31:AF31," & "IO_AF32:AF32," & "IO_AF34:AF34," & "IO_AF35:AF35," & "IO_AF36:AF36," & "IO_AF37:AF37," & "IO_AF39:AF39," & "IO_AF40:AF40," & "IO_AF41:AF41," & "IO_AF42:AF42," & "IO_AG29:AG29," & "IO_AG31:AG31," & "IO_AG32:AG32," & "IO_AG33:AG33," & "IO_AG34:AG34," & "IO_AG36:AG36," & "IO_AG37:AG37," & "IO_AG38:AG38," & "IO_AG39:AG39," & "IO_AG41:AG41," & "IO_AG42:AG42," & "IO_AH28:AH28," & "IO_AH29:AH29," & "IO_AH30:AH30," & "IO_AH31:AH31," & "IO_AH33:AH33," & "IO_AH34:AH34," & "IO_AH35:AH35," & "IO_AH36:AH36," & "IO_AH38:AH38," & "IO_AH39:AH39," & "IO_AH40:AH40," & "IO_AH41:AH41," & "IO_AJ20:AJ20," & "IO_AJ21:AJ21," & "IO_AJ22:AJ22," & "IO_AJ23:AJ23," & "IO_AJ28:AJ28," & "IO_AJ30:AJ30," & "IO_AJ31:AJ31," & "IO_AJ32:AJ32," & "IO_AJ33:AJ33," & "IO_AJ35:AJ35," & "IO_AJ36:AJ36," & "IO_AJ37:AJ37," & "IO_AJ38:AJ38," & "IO_AJ40:AJ40," & "IO_AJ41:AJ41," & "IO_AJ42:AJ42," & "IO_AK20:AK20," & "IO_AK22:AK22," & "IO_AK23:AK23," & "IO_AK28:AK28," & "IO_AK29:AK29," & "IO_AK30:AK30," & "IO_AK32:AK32," & "IO_AK33:AK33," & "IO_AK34:AK34," & "IO_AK35:AK35," & "IO_AK37:AK37," & "IO_AK38:AK38," & "IO_AK39:AK39," & "IO_AK40:AK40," & "IO_AK42:AK42," & "IO_AL20:AL20," & "IO_AL21:AL21," & "IO_AL22:AL22," & "IO_AL24:AL24," & "IO_AL29:AL29," & "IO_AL30:AL30," & "IO_AL31:AL31," & "IO_AL32:AL32," & "IO_AL34:AL34," & "IO_AL35:AL35," & "IO_AL36:AL36," & "IO_AL37:AL37," & "IO_AL39:AL39," & "IO_AL40:AL40," & "IO_AL41:AL41," & "IO_AL42:AL42," & "IO_AM21:AM21," & "IO_AM22:AM22," & "IO_AM23:AM23," & "IO_AM24:AM24," & "IO_AM31:AM31," & "IO_AM32:AM32," & "IO_AM33:AM33," & "IO_AM34:AM34," & "IO_AM36:AM36," & "IO_AM37:AM37," & "IO_AM38:AM38," & "IO_AM39:AM39," & "IO_AM41:AM41," & "IO_AM42:AM42," & "IO_AN20:AN20," & "IO_AN21:AN21," & "IO_AN23:AN23," & "IO_AN24:AN24," & "IO_AN30:AN30," & "IO_AN31:AN31," & "IO_AN33:AN33," & "IO_AN34:AN34," & "IO_AN35:AN35," & "IO_AN36:AN36," & "IO_AN38:AN38," & "IO_AN39:AN39," & "IO_AN40:AN40," & "IO_AN41:AN41," & "IO_AP21:AP21," & "IO_AP22:AP22," & "IO_AP23:AP23," & "IO_AP30:AP30," & "IO_AP31:AP31," & "IO_AP32:AP32," & "IO_AP33:AP33," & "IO_AP35:AP35," & "IO_AP36:AP36," & "IO_AP37:AP37," & "IO_AP38:AP38," & "IO_AP40:AP40," & "IO_AP41:AP41," & "IO_AP42:AP42," & "IO_AR22:AR22," & "IO_AR23:AR23," & "IO_AR24:AR24," & "IO_AR30:AR30," & "IO_AR32:AR32," & "IO_AR33:AR33," & "IO_AR34:AR34," & "IO_AR35:AR35," & "IO_AR37:AR37," & "IO_AR38:AR38," & "IO_AR39:AR39," & "IO_AR40:AR40," & "IO_AR42:AR42," & "IO_AT21:AT21," & "IO_AT22:AT22," & "IO_AT24:AT24," & "IO_AT30:AT30," & "IO_AT31:AT31," & "IO_AT32:AT32," & "IO_AT34:AT34," & "IO_AT35:AT35," & "IO_AT36:AT36," & "IO_AT37:AT37," & "IO_AT39:AT39," & "IO_AT40:AT40," & "IO_AT41:AT41," & "IO_AT42:AT42," & "IO_AU21:AU21," & "IO_AU22:AU22," & "IO_AU23:AU23," & "IO_AU24:AU24," & "IO_AU31:AU31," & "IO_AU32:AU32," & "IO_AU33:AU33," & "IO_AU34:AU34," & "IO_AU36:AU36," & "IO_AU37:AU37," & "IO_AU38:AU38," & "IO_AU39:AU39," & "IO_AU41:AU41," & "IO_AU42:AU42," & "IO_AV21:AV21," & "IO_AV23:AV23," & "IO_AV24:AV24," & "IO_AV30:AV30," & "IO_AV31:AV31," & "IO_AV33:AV33," & "IO_AV34:AV34," & "IO_AV35:AV35," & "IO_AV36:AV36," & "IO_AV38:AV38," & "IO_AV39:AV39," & "IO_AV40:AV40," & "IO_AV41:AV41," & "IO_AW21:AW21," & "IO_AW22:AW22," & "IO_AW23:AW23," & "IO_AW30:AW30," & "IO_AW31:AW31," & "IO_AW32:AW32," & "IO_AW33:AW33," & "IO_AW35:AW35," & "IO_AW36:AW36," & "IO_AW37:AW37," & "IO_AW38:AW38," & "IO_AW40:AW40," & "IO_AW41:AW41," & "IO_AW42:AW42," & "IO_AY22:AY22," & "IO_AY23:AY23," & "IO_AY24:AY24," & "IO_AY25:AY25," & "IO_AY30:AY30," & "IO_AY32:AY32," & "IO_AY33:AY33," & "IO_AY34:AY34," & "IO_AY35:AY35," & "IO_AY37:AY37," & "IO_AY38:AY38," & "IO_AY39:AY39," & "IO_AY40:AY40," & "IO_AY42:AY42," & "IO_BA21:BA21," & "IO_BA22:BA22," & "IO_BA24:BA24," & "IO_BA25:BA25," & "IO_BA30:BA30," & "IO_BA31:BA31," & "IO_BA32:BA32," & "IO_BA34:BA34," & "IO_BA35:BA35," & "IO_BA36:BA36," & "IO_BA37:BA37," & "IO_BA39:BA39," & "IO_BA40:BA40," & "IO_BA41:BA41," & "IO_BA42:BA42," & "IO_BB21:BB21," & "IO_BB22:BB22," & "IO_BB23:BB23," & "IO_BB24:BB24," & "IO_BB31:BB31," & "IO_BB32:BB32," & "IO_BB33:BB33," & "IO_BB34:BB34," & "IO_BB36:BB36," & "IO_BB37:BB37," & "IO_BB38:BB38," & "IO_BB39:BB39," & "IO_BB41:BB41"; -- Grouped Port Identification attribute PORT_GROUPING of XC7VX485T_FFG1761 : entity is "DIFFERENTIAL_VOLTAGE (" & "(MGTXRXP0_113, MGTXRXN0_113), " & "(MGTXRXP0_114, MGTXRXN0_114), " & "(MGTXRXP0_115, MGTXRXN0_115), " & "(MGTXRXP0_116, MGTXRXN0_116), " & "(MGTXRXP0_117, MGTXRXN0_117), " & "(MGTXRXP0_118, MGTXRXN0_118), " & "(MGTXRXP0_119, MGTXRXN0_119), " & "(MGTXRXP1_113, MGTXRXN1_113), " & "(MGTXRXP1_114, MGTXRXN1_114), " & "(MGTXRXP1_115, MGTXRXN1_115), " & "(MGTXRXP1_116, MGTXRXN1_116), " & "(MGTXRXP1_117, MGTXRXN1_117), " & "(MGTXRXP1_118, MGTXRXN1_118), " & "(MGTXRXP1_119, MGTXRXN1_119), " & "(MGTXRXP2_113, MGTXRXN2_113), " & "(MGTXRXP2_114, MGTXRXN2_114), " & "(MGTXRXP2_115, MGTXRXN2_115), " & "(MGTXRXP2_116, MGTXRXN2_116), " & "(MGTXRXP2_117, MGTXRXN2_117), " & "(MGTXRXP2_118, MGTXRXN2_118), " & "(MGTXRXP2_119, MGTXRXN2_119), " & "(MGTXRXP3_113, MGTXRXN3_113), " & "(MGTXRXP3_114, MGTXRXN3_114), " & "(MGTXRXP3_115, MGTXRXN3_115), " & "(MGTXRXP3_116, MGTXRXN3_116), " & "(MGTXRXP3_117, MGTXRXN3_117), " & "(MGTXRXP3_118, MGTXRXN3_118), " & "(MGTXRXP3_119, MGTXRXN3_119), " & "(MGTXTXP0_113, MGTXTXN0_113), " & "(MGTXTXP0_114, MGTXTXN0_114), " & "(MGTXTXP0_115, MGTXTXN0_115), " & "(MGTXTXP0_116, MGTXTXN0_116), " & "(MGTXTXP0_117, MGTXTXN0_117), " & "(MGTXTXP0_118, MGTXTXN0_118), " & "(MGTXTXP0_119, MGTXTXN0_119), " & "(MGTXTXP1_113, MGTXTXN1_113), " & "(MGTXTXP1_114, MGTXTXN1_114), " & "(MGTXTXP1_115, MGTXTXN1_115), " & "(MGTXTXP1_116, MGTXTXN1_116), " & "(MGTXTXP1_117, MGTXTXN1_117), " & "(MGTXTXP1_118, MGTXTXN1_118), " & "(MGTXTXP1_119, MGTXTXN1_119), " & "(MGTXTXP2_113, MGTXTXN2_113), " & "(MGTXTXP2_114, MGTXTXN2_114), " & "(MGTXTXP2_115, MGTXTXN2_115), " & "(MGTXTXP2_116, MGTXTXN2_116), " & "(MGTXTXP2_117, MGTXTXN2_117), " & "(MGTXTXP2_118, MGTXTXN2_118), " & "(MGTXTXP2_119, MGTXTXN2_119), " & "(MGTXTXP3_113, MGTXTXN3_113), " & "(MGTXTXP3_114, MGTXTXN3_114), " & "(MGTXTXP3_115, MGTXTXN3_115), " & "(MGTXTXP3_116, MGTXTXN3_116), " & "(MGTXTXP3_117, MGTXTXN3_117), " & "(MGTXTXP3_118, MGTXTXN3_118), " & "(MGTXTXP3_119, MGTXTXN3_119))"; -- Scan Port Identification attribute TAP_SCAN_IN of TDI : signal is true; attribute TAP_SCAN_MODE of TMS : signal is true; attribute TAP_SCAN_OUT of TDO : signal is true; attribute TAP_SCAN_CLOCK of TCK : signal is (66.0e6, BOTH); -- Compliance-Enable Description attribute COMPLIANCE_PATTERNS of XC7VX485T_FFG1761 : entity is "(PROGRAM_B) (1)"; -- Instruction Register Description attribute INSTRUCTION_LENGTH of XC7VX485T_FFG1761 : entity is 6; attribute INSTRUCTION_OPCODE of XC7VX485T_FFG1761 : entity is "IDCODE (001001)," & -- DEVICE_ID "BYPASS (111111)," & -- BYPASS "EXTEST (100110)," & -- BOUNDARY "SAMPLE (000001)," & -- BOUNDARY "PRELOAD (000001)," & -- Same as SAMPLE "USERCODE (001000)," & -- DEVICE_ID "HIGHZ (001010)," & -- BYPASS "EXTEST_PULSE (111100)," & -- BOUNDARY "EXTEST_TRAIN (111101)," & -- BOUNDARY "ISC_ENABLE (010000)," & -- ISC_CONFIG "ISC_PROGRAM (010001)," & -- ISC_PDATA "ISC_NOOP (010100)," & -- ISC_DEFAULT "XSC_READ_RSVD (010101)," & -- PRIVATE "ISC_DISABLE (010110)," & -- ISC_CONFIG "XSC_PROGRAM_KEY (010010)," & -- XSC_KEY_DATA "XSC_DNA (010111)," & -- DNA "CFG_OUT (000100)," & -- Not available during configuration with another mode. "CFG_IN (000101)," & -- Not available during configuration with another mode. "JPROGRAM (001011)," & -- Not available during configuration with another mode. "JSTART (001100)," & -- Not available during configuration with another mode. "JSHUTDOWN (001101)," & -- Not available during configuration with another mode. "FUSE_CTS (110000)," & -- PRIVATE "FUSE_KEY (110001)," & -- PRIVATE "FUSE_DNA (110010)," & -- PRIVATE "FUSE_USER (110011)," & -- PRIVATE "FUSE_CNTL (110100)," & -- PRIVATE "USER1 (000010)," & -- Not available until after configuration "USER2 (000011)," & -- Not available until after configuration "USER3 (100010)," & -- Not available until after configuration "USER4 (100011)," & -- Not available until after configuration "XADC_DRP (110111)," & -- PRIVATE "INTEST_RSVD (000111)"; -- PRIVATE attribute INSTRUCTION_CAPTURE of XC7VX485T_FFG1761 : entity is -- Bit 5 is 1 when DONE is released (part of startup sequence) -- Bit 4 is 1 if house-cleaning is complete -- Bit 3 is ISC_Enabled -- Bit 2 is ISC_Done "XXXX01"; attribute INSTRUCTION_PRIVATE of XC7VX485T_FFG1761 : entity is -- If the device is configured, and a USER instruction is implemented -- and not private to the FPGA designer, then it should be removed -- from INSTRUCTION_PRIVATE, and the target register should be defined -- in REGISTER_ACCESS. "ISC_ENABLE," & "ISC_PROGRAM," & "ISC_NOOP," & "XSC_READ_RSVD," & "ISC_DISABLE," & "XSC_PROGRAM_KEY," & "XSC_DNA," & "CFG_OUT," & "CFG_IN," & "JPROGRAM," & "JSTART," & "JSHUTDOWN," & "FUSE_CTS," & "FUSE_KEY," & "FUSE_DNA," & "FUSE_USER," & "FUSE_CNTL," & "USER1," & "USER2," & "USER3," & "USER4," & "XADC_DRP," & "INTEST_RSVD"; -- Optional Register Description attribute IDCODE_REGISTER of XC7VX485T_FFG1761 : entity is "XXXX" & -- version "0011011" & -- family "010000111" & -- array size "00001001001" & -- manufacturer "1"; -- required by 1149.1 attribute USERCODE_REGISTER of XC7VX485T_FFG1761 : entity is "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; -- Register Access Description attribute REGISTER_ACCESS of XC7VX485T_FFG1761 : entity is -- "[] (USER1)," & -- "[] (USER2)," & -- "[] (USER3)," & -- "[] (USER4)," & "DATAREG[57] (XSC_DNA)," & "BYPASS (HIGHZ,BYPASS)," & "DEVICE_ID (USERCODE,IDCODE)," & "BOUNDARY (SAMPLE,PRELOAD,EXTEST,EXTEST_PULSE,EXTEST_TRAIN)"; -- Boundary-Scan Register Description attribute BOUNDARY_LENGTH of XC7VX485T_FFG1761 : entity is 2401; attribute BOUNDARY_REGISTER of XC7VX485T_FFG1761 : entity is -- cellnum (type, port, function, safe[, ccell, disval, disrslt]) " 0 (BC_2, *, controlr, 1)," & " 1 (BC_2, CCLK_N10, output3, X, 0, 1, Z)," & -- CCLK_0 " 2 (BC_2, CCLK_N10, input, X)," & -- CCLK_0 " 3 (BC_2, M0_AL10, input, X)," & " 4 (BC_2, M1_AK10, input, X)," & " 5 (BC_2, M2_AJ10, input, X)," & " 6 (BC_2, CFGBVS_AH10, input, X)," & " 7 (BC_2, *, internal, 1)," & -- PROGRAM_B " 8 (BC_2, *, controlr, 1)," & " 9 (BC_2, INIT_B_AG11, output3, X, 8, 1, Z)," & -- INIT_B_0 " 10 (BC_2, INIT_B_AG11, input, X)," & -- INIT_B_0 " 11 (BC_2, *, controlr, 1)," & " 12 (BC_2, DONE_AL11, output3, X, 11, 1, Z)," & -- DONE_0 " 13 (BC_2, DONE_AL11, input, X)," & -- DONE_0 " 14 (BC_2, *, internal, X)," & " 15 (BC_2, *, internal, X)," & " 16 (BC_2, *, internal, X)," & " 17 (BC_2, *, internal, X)," & " 18 (BC_2, *, internal, X)," & " 19 (BC_2, *, internal, X)," & " 20 (BC_2, *, internal, X)," & " 21 (BC_2, *, internal, X)," & " 22 (BC_2, *, internal, X)," & " 23 (BC_2, *, internal, X)," & " 24 (BC_2, *, internal, X)," & " 25 (BC_2, *, internal, X)," & " 26 (BC_2, *, internal, X)," & " 27 (BC_2, *, internal, X)," & " 28 (BC_2, *, internal, X)," & " 29 (BC_2, *, internal, X)," & " 30 (BC_2, *, internal, X)," & " 31 (BC_2, *, internal, X)," & " 32 (BC_2, *, internal, X)," & " 33 (BC_2, *, internal, X)," & " 34 (BC_2, *, internal, X)," & " 35 (BC_2, *, internal, X)," & " 36 (BC_2, *, internal, X)," & " 37 (BC_2, *, internal, X)," & " 38 (BC_2, *, internal, X)," & " 39 (BC_2, *, internal, X)," & " 40 (BC_2, *, internal, X)," & " 41 (BC_2, *, internal, X)," & " 42 (BC_2, *, internal, X)," & " 43 (BC_2, *, controlr, 1)," & " 44 (BC_2, IO_AN20, output3, X, 43, 1, Z)," & -- PAD700 " 45 (BC_2, IO_AN20, input, X)," & -- PAD700 " 46 (BC_2, *, controlr, 1)," & " 47 (BC_2, IO_BB23, output3, X, 46, 1, Z)," & -- PAD699 " 48 (BC_2, IO_BB23, input, X)," & -- PAD699 " 49 (BC_2, *, controlr, 1)," & " 50 (BC_2, IO_BB24, output3, X, 49, 1, Z)," & -- PAD698 " 51 (BC_2, IO_BB24, input, X)," & -- PAD698 " 52 (BC_2, *, controlr, 1)," & " 53 (BC_2, IO_BB21, output3, X, 52, 1, Z)," & -- PAD697 " 54 (BC_2, IO_BB21, input, X)," & -- PAD697 " 55 (BC_2, *, controlr, 1)," & " 56 (BC_2, IO_BA21, output3, X, 55, 1, Z)," & -- PAD696 " 57 (BC_2, IO_BA21, input, X)," & -- PAD696 " 58 (BC_2, *, controlr, 1)," & " 59 (BC_2, IO_BA24, output3, X, 58, 1, Z)," & -- PAD695 " 60 (BC_2, IO_BA24, input, X)," & -- PAD695 " 61 (BC_2, *, controlr, 1)," & " 62 (BC_2, IO_AY24, output3, X, 61, 1, Z)," & -- PAD694 " 63 (BC_2, IO_AY24, input, X)," & -- PAD694 " 64 (BC_2, *, controlr, 1)," & " 65 (BC_2, IO_BB22, output3, X, 64, 1, Z)," & -- PAD693 " 66 (BC_2, IO_BB22, input, X)," & -- PAD693 " 67 (BC_2, *, controlr, 1)," & " 68 (BC_2, IO_BA22, output3, X, 67, 1, Z)," & -- PAD692 " 69 (BC_2, IO_BA22, input, X)," & -- PAD692 " 70 (BC_2, *, controlr, 1)," & " 71 (BC_2, IO_BA25, output3, X, 70, 1, Z)," & -- PAD691 " 72 (BC_2, IO_BA25, input, X)," & -- PAD691 " 73 (BC_2, *, controlr, 1)," & " 74 (BC_2, IO_AY25, output3, X, 73, 1, Z)," & -- PAD690 " 75 (BC_2, IO_AY25, input, X)," & -- PAD690 " 76 (BC_2, *, controlr, 1)," & " 77 (BC_2, IO_AY22, output3, X, 76, 1, Z)," & -- PAD689 " 78 (BC_2, IO_AY22, input, X)," & -- PAD689 " 79 (BC_2, *, controlr, 1)," & " 80 (BC_2, IO_AY23, output3, X, 79, 1, Z)," & -- PAD688 " 81 (BC_2, IO_AY23, input, X)," & -- PAD688 " 82 (BC_2, *, controlr, 1)," & " 83 (BC_2, IO_AV24, output3, X, 82, 1, Z)," & -- PAD687 " 84 (BC_2, IO_AV24, input, X)," & -- PAD687 " 85 (BC_2, *, controlr, 1)," & " 86 (BC_2, IO_AU24, output3, X, 85, 1, Z)," & -- PAD686 " 87 (BC_2, IO_AU24, input, X)," & -- PAD686 " 88 (BC_2, *, controlr, 1)," & " 89 (BC_2, IO_AW21, output3, X, 88, 1, Z)," & -- PAD685 " 90 (BC_2, IO_AW21, input, X)," & -- PAD685 " 91 (BC_2, *, controlr, 1)," & " 92 (BC_2, IO_AV21, output3, X, 91, 1, Z)," & -- PAD684 " 93 (BC_2, IO_AV21, input, X)," & -- PAD684 " 94 (BC_2, *, controlr, 1)," & " 95 (BC_2, IO_AT24, output3, X, 94, 1, Z)," & -- PAD683 " 96 (BC_2, IO_AT24, input, X)," & -- PAD683 " 97 (BC_2, *, controlr, 1)," & " 98 (BC_2, IO_AR24, output3, X, 97, 1, Z)," & -- PAD682 " 99 (BC_2, IO_AR24, input, X)," & -- PAD682 " 100 (BC_2, *, controlr, 1)," & " 101 (BC_2, IO_AU21, output3, X, 100, 1, Z)," & -- PAD681 " 102 (BC_2, IO_AU21, input, X)," & -- PAD681 " 103 (BC_2, *, controlr, 1)," & " 104 (BC_2, IO_AT21, output3, X, 103, 1, Z)," & -- PAD680 " 105 (BC_2, IO_AT21, input, X)," & -- PAD680 " 106 (BC_2, *, controlr, 1)," & " 107 (BC_2, IO_AW22, output3, X, 106, 1, Z)," & -- PAD679 " 108 (BC_2, IO_AW22, input, X)," & -- PAD679 " 109 (BC_2, *, controlr, 1)," & " 110 (BC_2, IO_AW23, output3, X, 109, 1, Z)," & -- PAD678 " 111 (BC_2, IO_AW23, input, X)," & -- PAD678 " 112 (BC_2, *, controlr, 1)," & " 113 (BC_2, IO_AV23, output3, X, 112, 1, Z)," & -- PAD677 " 114 (BC_2, IO_AV23, input, X)," & -- PAD677 " 115 (BC_2, *, controlr, 1)," & " 116 (BC_2, IO_AU23, output3, X, 115, 1, Z)," & -- PAD676 " 117 (BC_2, IO_AU23, input, X)," & -- PAD676 " 118 (BC_2, *, controlr, 1)," & " 119 (BC_2, IO_AU22, output3, X, 118, 1, Z)," & -- PAD675 " 120 (BC_2, IO_AU22, input, X)," & -- PAD675 " 121 (BC_2, *, controlr, 1)," & " 122 (BC_2, IO_AT22, output3, X, 121, 1, Z)," & -- PAD674 " 123 (BC_2, IO_AT22, input, X)," & -- PAD674 " 124 (BC_2, *, controlr, 1)," & " 125 (BC_2, IO_AR22, output3, X, 124, 1, Z)," & -- PAD673 " 126 (BC_2, IO_AR22, input, X)," & -- PAD673 " 127 (BC_2, *, controlr, 1)," & " 128 (BC_2, IO_AR23, output3, X, 127, 1, Z)," & -- PAD672 " 129 (BC_2, IO_AR23, input, X)," & -- PAD672 " 130 (BC_2, *, controlr, 1)," & " 131 (BC_2, IO_AP21, output3, X, 130, 1, Z)," & -- PAD671 " 132 (BC_2, IO_AP21, input, X)," & -- PAD671 " 133 (BC_2, *, controlr, 1)," & " 134 (BC_2, IO_AN21, output3, X, 133, 1, Z)," & -- PAD670 " 135 (BC_2, IO_AN21, input, X)," & -- PAD670 " 136 (BC_2, *, controlr, 1)," & " 137 (BC_2, IO_AP22, output3, X, 136, 1, Z)," & -- PAD669 " 138 (BC_2, IO_AP22, input, X)," & -- PAD669 " 139 (BC_2, *, controlr, 1)," & " 140 (BC_2, IO_AP23, output3, X, 139, 1, Z)," & -- PAD668 " 141 (BC_2, IO_AP23, input, X)," & -- PAD668 " 142 (BC_2, *, controlr, 1)," & " 143 (BC_2, IO_AN23, output3, X, 142, 1, Z)," & -- PAD667 " 144 (BC_2, IO_AN23, input, X)," & -- PAD667 " 145 (BC_2, *, controlr, 1)," & " 146 (BC_2, IO_AM23, output3, X, 145, 1, Z)," & -- PAD666 " 147 (BC_2, IO_AM23, input, X)," & -- PAD666 " 148 (BC_2, *, controlr, 1)," & " 149 (BC_2, IO_AN24, output3, X, 148, 1, Z)," & -- PAD665 " 150 (BC_2, IO_AN24, input, X)," & -- PAD665 " 151 (BC_2, *, controlr, 1)," & " 152 (BC_2, IO_AM24, output3, X, 151, 1, Z)," & -- PAD664 " 153 (BC_2, IO_AM24, input, X)," & -- PAD664 " 154 (BC_2, *, controlr, 1)," & " 155 (BC_2, IO_AM22, output3, X, 154, 1, Z)," & -- PAD663 " 156 (BC_2, IO_AM22, input, X)," & -- PAD663 " 157 (BC_2, *, controlr, 1)," & " 158 (BC_2, IO_AL22, output3, X, 157, 1, Z)," & -- PAD662 " 159 (BC_2, IO_AL22, input, X)," & -- PAD662 " 160 (BC_2, *, controlr, 1)," & " 161 (BC_2, IO_AJ20, output3, X, 160, 1, Z)," & -- PAD661 " 162 (BC_2, IO_AJ20, input, X)," & -- PAD661 " 163 (BC_2, *, controlr, 1)," & " 164 (BC_2, IO_AJ21, output3, X, 163, 1, Z)," & -- PAD660 " 165 (BC_2, IO_AJ21, input, X)," & -- PAD660 " 166 (BC_2, *, controlr, 1)," & " 167 (BC_2, IO_AM21, output3, X, 166, 1, Z)," & -- PAD659 " 168 (BC_2, IO_AM21, input, X)," & -- PAD659 " 169 (BC_2, *, controlr, 1)," & " 170 (BC_2, IO_AL21, output3, X, 169, 1, Z)," & -- PAD658 " 171 (BC_2, IO_AL21, input, X)," & -- PAD658 " 172 (BC_2, *, controlr, 1)," & " 173 (BC_2, IO_AK22, output3, X, 172, 1, Z)," & -- PAD657 " 174 (BC_2, IO_AK22, input, X)," & -- PAD657 " 175 (BC_2, *, controlr, 1)," & " 176 (BC_2, IO_AJ22, output3, X, 175, 1, Z)," & -- PAD656 " 177 (BC_2, IO_AJ22, input, X)," & -- PAD656 " 178 (BC_2, *, controlr, 1)," & " 179 (BC_2, IO_AL20, output3, X, 178, 1, Z)," & -- PAD655 " 180 (BC_2, IO_AL20, input, X)," & -- PAD655 " 181 (BC_2, *, controlr, 1)," & " 182 (BC_2, IO_AK20, output3, X, 181, 1, Z)," & -- PAD654 " 183 (BC_2, IO_AK20, input, X)," & -- PAD654 " 184 (BC_2, *, controlr, 1)," & " 185 (BC_2, IO_AK23, output3, X, 184, 1, Z)," & -- PAD653 " 186 (BC_2, IO_AK23, input, X)," & -- PAD653 " 187 (BC_2, *, controlr, 1)," & " 188 (BC_2, IO_AJ23, output3, X, 187, 1, Z)," & -- PAD652 " 189 (BC_2, IO_AJ23, input, X)," & -- PAD652 " 190 (BC_2, *, controlr, 1)," & " 191 (BC_2, IO_AL24, output3, X, 190, 1, Z)," & -- PAD651 " 192 (BC_2, IO_AL24, input, X)," & -- PAD651 " 193 (BC_2, *, controlr, 1)," & " 194 (BC_2, IO_U28, output3, X, 193, 1, Z)," & -- PAD650 " 195 (BC_2, IO_U28, input, X)," & -- PAD650 " 196 (BC_2, *, controlr, 1)," & " 197 (BC_2, IO_Y30, output3, X, 196, 1, Z)," & -- PAD649 " 198 (BC_2, IO_Y30, input, X)," & -- PAD649 " 199 (BC_2, *, controlr, 1)," & " 200 (BC_2, IO_Y29, output3, X, 199, 1, Z)," & -- PAD648 " 201 (BC_2, IO_Y29, input, X)," & -- PAD648 " 202 (BC_2, *, controlr, 1)," & " 203 (BC_2, IO_U29, output3, X, 202, 1, Z)," & -- PAD647 " 204 (BC_2, IO_U29, input, X)," & -- PAD647 " 205 (BC_2, *, controlr, 1)," & " 206 (BC_2, IO_V29, output3, X, 205, 1, Z)," & -- PAD646 " 207 (BC_2, IO_V29, input, X)," & -- PAD646 " 208 (BC_2, *, controlr, 1)," & " 209 (BC_2, IO_W31, output3, X, 208, 1, Z)," & -- PAD645 " 210 (BC_2, IO_W31, input, X)," & -- PAD645 " 211 (BC_2, *, controlr, 1)," & " 212 (BC_2, IO_W30, output3, X, 211, 1, Z)," & -- PAD644 " 213 (BC_2, IO_W30, input, X)," & -- PAD644 " 214 (BC_2, *, controlr, 1)," & " 215 (BC_2, IO_T30, output3, X, 214, 1, Z)," & -- PAD643 " 216 (BC_2, IO_T30, input, X)," & -- PAD643 " 217 (BC_2, *, controlr, 1)," & " 218 (BC_2, IO_T29, output3, X, 217, 1, Z)," & -- PAD642 " 219 (BC_2, IO_T29, input, X)," & -- PAD642 " 220 (BC_2, *, controlr, 1)," & " 221 (BC_2, IO_V31, output3, X, 220, 1, Z)," & -- PAD641 " 222 (BC_2, IO_V31, input, X)," & -- PAD641 " 223 (BC_2, *, controlr, 1)," & " 224 (BC_2, IO_V30, output3, X, 223, 1, Z)," & -- PAD640 " 225 (BC_2, IO_V30, input, X)," & -- PAD640 " 226 (BC_2, *, controlr, 1)," & " 227 (BC_2, IO_T31, output3, X, 226, 1, Z)," & -- PAD639 " 228 (BC_2, IO_T31, input, X)," & -- PAD639 " 229 (BC_2, *, controlr, 1)," & " 230 (BC_2, IO_U31, output3, X, 229, 1, Z)," & -- PAD638 " 231 (BC_2, IO_U31, input, X)," & -- PAD638 " 232 (BC_2, *, controlr, 1)," & " 233 (BC_2, IO_P31, output3, X, 232, 1, Z)," & -- PAD637 " 234 (BC_2, IO_P31, input, X)," & -- PAD637 " 235 (BC_2, *, controlr, 1)," & " 236 (BC_2, IO_R30, output3, X, 235, 1, Z)," & -- PAD636 " 237 (BC_2, IO_R30, input, X)," & -- PAD636 " 238 (BC_2, *, controlr, 1)," & " 239 (BC_2, IO_N29, output3, X, 238, 1, Z)," & -- PAD635 " 240 (BC_2, IO_N29, input, X)," & -- PAD635 " 241 (BC_2, *, controlr, 1)," & " 242 (BC_2, IO_N28, output3, X, 241, 1, Z)," & -- PAD634 " 243 (BC_2, IO_N28, input, X)," & -- PAD634 " 244 (BC_2, *, controlr, 1)," & " 245 (BC_2, IO_P28, output3, X, 244, 1, Z)," & -- PAD633 " 246 (BC_2, IO_P28, input, X)," & -- PAD633 " 247 (BC_2, *, controlr, 1)," & " 248 (BC_2, IO_R28, output3, X, 247, 1, Z)," & -- PAD632 " 249 (BC_2, IO_R28, input, X)," & -- PAD632 " 250 (BC_2, *, controlr, 1)," & " 251 (BC_2, IO_M29, output3, X, 250, 1, Z)," & -- PAD631 " 252 (BC_2, IO_M29, input, X)," & -- PAD631 " 253 (BC_2, *, controlr, 1)," & " 254 (BC_2, IO_M28, output3, X, 253, 1, Z)," & -- PAD630 " 255 (BC_2, IO_M28, input, X)," & -- PAD630 " 256 (BC_2, *, controlr, 1)," & " 257 (BC_2, IO_N31, output3, X, 256, 1, Z)," & -- PAD629 " 258 (BC_2, IO_N31, input, X)," & -- PAD629 " 259 (BC_2, *, controlr, 1)," & " 260 (BC_2, IO_P30, output3, X, 259, 1, Z)," & -- PAD628 " 261 (BC_2, IO_P30, input, X)," & -- PAD628 " 262 (BC_2, *, controlr, 1)," & " 263 (BC_2, IO_M31, output3, X, 262, 1, Z)," & -- PAD627 " 264 (BC_2, IO_M31, input, X)," & -- PAD627 " 265 (BC_2, *, controlr, 1)," & " 266 (BC_2, IO_N30, output3, X, 265, 1, Z)," & -- PAD626 " 267 (BC_2, IO_N30, input, X)," & -- PAD626 " 268 (BC_2, *, controlr, 1)," & " 269 (BC_2, IO_K32, output3, X, 268, 1, Z)," & -- PAD625 " 270 (BC_2, IO_K32, input, X)," & -- PAD625 " 271 (BC_2, *, controlr, 1)," & " 272 (BC_2, IO_L31, output3, X, 271, 1, Z)," & -- PAD624 " 273 (BC_2, IO_L31, input, X)," & -- PAD624 " 274 (BC_2, *, controlr, 1)," & " 275 (BC_2, IO_L32, output3, X, 274, 1, Z)," & -- PAD623 " 276 (BC_2, IO_L32, input, X)," & -- PAD623 " 277 (BC_2, *, controlr, 1)," & " 278 (BC_2, IO_M32, output3, X, 277, 1, Z)," & -- PAD622 " 279 (BC_2, IO_M32, input, X)," & -- PAD622 " 280 (BC_2, *, controlr, 1)," & " 281 (BC_2, IO_H31, output3, X, 280, 1, Z)," & -- PAD621 " 282 (BC_2, IO_H31, input, X)," & -- PAD621 " 283 (BC_2, *, controlr, 1)," & " 284 (BC_2, IO_J31, output3, X, 283, 1, Z)," & -- PAD620 " 285 (BC_2, IO_J31, input, X)," & -- PAD620 " 286 (BC_2, *, controlr, 1)," & " 287 (BC_2, IO_L30, output3, X, 286, 1, Z)," & -- PAD619 " 288 (BC_2, IO_L30, input, X)," & -- PAD619 " 289 (BC_2, *, controlr, 1)," & " 290 (BC_2, IO_L29, output3, X, 289, 1, Z)," & -- PAD618 " 291 (BC_2, IO_L29, input, X)," & -- PAD618 " 292 (BC_2, *, controlr, 1)," & " 293 (BC_2, IO_H30, output3, X, 292, 1, Z)," & -- PAD617 " 294 (BC_2, IO_H30, input, X)," & -- PAD617 " 295 (BC_2, *, controlr, 1)," & " 296 (BC_2, IO_J30, output3, X, 295, 1, Z)," & -- PAD616 " 297 (BC_2, IO_J30, input, X)," & -- PAD616 " 298 (BC_2, *, controlr, 1)," & " 299 (BC_2, IO_K30, output3, X, 298, 1, Z)," & -- PAD615 " 300 (BC_2, IO_K30, input, X)," & -- PAD615 " 301 (BC_2, *, controlr, 1)," & " 302 (BC_2, IO_K29, output3, X, 301, 1, Z)," & -- PAD614 " 303 (BC_2, IO_K29, input, X)," & -- PAD614 " 304 (BC_2, *, controlr, 1)," & " 305 (BC_2, IO_H35, output3, X, 304, 1, Z)," & -- PAD613 " 306 (BC_2, IO_H35, input, X)," & -- PAD613 " 307 (BC_2, *, controlr, 1)," & " 308 (BC_2, IO_H34, output3, X, 307, 1, Z)," & -- PAD612 " 309 (BC_2, IO_H34, input, X)," & -- PAD612 " 310 (BC_2, *, controlr, 1)," & " 311 (BC_2, IO_M34, output3, X, 310, 1, Z)," & -- PAD611 " 312 (BC_2, IO_M34, input, X)," & -- PAD611 " 313 (BC_2, *, controlr, 1)," & " 314 (BC_2, IO_M33, output3, X, 313, 1, Z)," & -- PAD610 " 315 (BC_2, IO_M33, input, X)," & -- PAD610 " 316 (BC_2, *, controlr, 1)," & " 317 (BC_2, IO_L35, output3, X, 316, 1, Z)," & -- PAD609 " 318 (BC_2, IO_L35, input, X)," & -- PAD609 " 319 (BC_2, *, controlr, 1)," & " 320 (BC_2, IO_L34, output3, X, 319, 1, Z)," & -- PAD608 " 321 (BC_2, IO_L34, input, X)," & -- PAD608 " 322 (BC_2, *, controlr, 1)," & " 323 (BC_2, IO_K34, output3, X, 322, 1, Z)," & -- PAD607 " 324 (BC_2, IO_K34, input, X)," & -- PAD607 " 325 (BC_2, *, controlr, 1)," & " 326 (BC_2, IO_K33, output3, X, 325, 1, Z)," & -- PAD606 " 327 (BC_2, IO_K33, input, X)," & -- PAD606 " 328 (BC_2, *, controlr, 1)," & " 329 (BC_2, IO_J33, output3, X, 328, 1, Z)," & -- PAD605 " 330 (BC_2, IO_J33, input, X)," & -- PAD605 " 331 (BC_2, *, controlr, 1)," & " 332 (BC_2, IO_J32, output3, X, 331, 1, Z)," & -- PAD604 " 333 (BC_2, IO_J32, input, X)," & -- PAD604 " 334 (BC_2, *, controlr, 1)," & " 335 (BC_2, IO_J35, output3, X, 334, 1, Z)," & -- PAD603 " 336 (BC_2, IO_J35, input, X)," & -- PAD603 " 337 (BC_2, *, controlr, 1)," & " 338 (BC_2, IO_K35, output3, X, 337, 1, Z)," & -- PAD602 " 339 (BC_2, IO_K35, input, X)," & -- PAD602 " 340 (BC_2, *, controlr, 1)," & " 341 (BC_2, IO_R29, output3, X, 340, 1, Z)," & -- PAD601 " 342 (BC_2, IO_R29, input, X)," & -- PAD601 " 343 (BC_2, *, controlr, 1)," & " 344 (BC_2, IO_G34, output3, X, 343, 1, Z)," & -- PAD600 " 345 (BC_2, IO_G34, input, X)," & -- PAD600 " 346 (BC_2, *, controlr, 1)," & " 347 (BC_2, IO_H36, output3, X, 346, 1, Z)," & -- PAD599 " 348 (BC_2, IO_H36, input, X)," & -- PAD599 " 349 (BC_2, *, controlr, 1)," & " 350 (BC_2, IO_J36, output3, X, 349, 1, Z)," & -- PAD598 " 351 (BC_2, IO_J36, input, X)," & -- PAD598 " 352 (BC_2, *, controlr, 1)," & " 353 (BC_2, IO_G38, output3, X, 352, 1, Z)," & -- PAD597 " 354 (BC_2, IO_G38, input, X)," & -- PAD597 " 355 (BC_2, *, controlr, 1)," & " 356 (BC_2, IO_H38, output3, X, 355, 1, Z)," & -- PAD596 " 357 (BC_2, IO_H38, input, X)," & -- PAD596 " 358 (BC_2, *, controlr, 1)," & " 359 (BC_2, IO_J38, output3, X, 358, 1, Z)," & -- PAD595 " 360 (BC_2, IO_J38, input, X)," & -- PAD595 " 361 (BC_2, *, controlr, 1)," & " 362 (BC_2, IO_J37, output3, X, 361, 1, Z)," & -- PAD594 " 363 (BC_2, IO_J37, input, X)," & -- PAD594 " 364 (BC_2, *, controlr, 1)," & " 365 (BC_2, IO_E39, output3, X, 364, 1, Z)," & -- PAD593 " 366 (BC_2, IO_E39, input, X)," & -- PAD593 " 367 (BC_2, *, controlr, 1)," & " 368 (BC_2, IO_F39, output3, X, 367, 1, Z)," & -- PAD592 " 369 (BC_2, IO_F39, input, X)," & -- PAD592 " 370 (BC_2, *, controlr, 1)," & " 371 (BC_2, IO_G37, output3, X, 370, 1, Z)," & -- PAD591 " 372 (BC_2, IO_G37, input, X)," & -- PAD591 " 373 (BC_2, *, controlr, 1)," & " 374 (BC_2, IO_G36, output3, X, 373, 1, Z)," & -- PAD590 " 375 (BC_2, IO_G36, input, X)," & -- PAD590 " 376 (BC_2, *, controlr, 1)," & " 377 (BC_2, IO_E38, output3, X, 376, 1, Z)," & -- PAD589 " 378 (BC_2, IO_E38, input, X)," & -- PAD589 " 379 (BC_2, *, controlr, 1)," & " 380 (BC_2, IO_E37, output3, X, 379, 1, Z)," & -- PAD588 " 381 (BC_2, IO_E37, input, X)," & -- PAD588 " 382 (BC_2, *, controlr, 1)," & " 383 (BC_2, IO_G33, output3, X, 382, 1, Z)," & -- PAD587 " 384 (BC_2, IO_G33, input, X)," & -- PAD587 " 385 (BC_2, *, controlr, 1)," & " 386 (BC_2, IO_H33, output3, X, 385, 1, Z)," & -- PAD586 " 387 (BC_2, IO_H33, input, X)," & -- PAD586 " 388 (BC_2, *, controlr, 1)," & " 389 (BC_2, IO_F35, output3, X, 388, 1, Z)," & -- PAD585 " 390 (BC_2, IO_F35, input, X)," & -- PAD585 " 391 (BC_2, *, controlr, 1)," & " 392 (BC_2, IO_F34, output3, X, 391, 1, Z)," & -- PAD584 " 393 (BC_2, IO_F34, input, X)," & -- PAD584 " 394 (BC_2, *, controlr, 1)," & " 395 (BC_2, IO_F37, output3, X, 394, 1, Z)," & -- PAD583 " 396 (BC_2, IO_F37, input, X)," & -- PAD583 " 397 (BC_2, *, controlr, 1)," & " 398 (BC_2, IO_F36, output3, X, 397, 1, Z)," & -- PAD582 " 399 (BC_2, IO_F36, input, X)," & -- PAD582 " 400 (BC_2, *, controlr, 1)," & " 401 (BC_2, IO_F32, output3, X, 400, 1, Z)," & -- PAD581 " 402 (BC_2, IO_F32, input, X)," & -- PAD581 " 403 (BC_2, *, controlr, 1)," & " 404 (BC_2, IO_G32, output3, X, 403, 1, Z)," & -- PAD580 " 405 (BC_2, IO_G32, input, X)," & -- PAD580 " 406 (BC_2, *, controlr, 1)," & " 407 (BC_2, IO_D38, output3, X, 406, 1, Z)," & -- PAD579 " 408 (BC_2, IO_D38, input, X)," & -- PAD579 " 409 (BC_2, *, controlr, 1)," & " 410 (BC_2, IO_D37, output3, X, 409, 1, Z)," & -- PAD578 " 411 (BC_2, IO_D37, input, X)," & -- PAD578 " 412 (BC_2, *, controlr, 1)," & " 413 (BC_2, IO_E35, output3, X, 412, 1, Z)," & -- PAD577 " 414 (BC_2, IO_E35, input, X)," & -- PAD577 " 415 (BC_2, *, controlr, 1)," & " 416 (BC_2, IO_E34, output3, X, 415, 1, Z)," & -- PAD576 " 417 (BC_2, IO_E34, input, X)," & -- PAD576 " 418 (BC_2, *, controlr, 1)," & " 419 (BC_2, IO_C36, output3, X, 418, 1, Z)," & -- PAD575 " 420 (BC_2, IO_C36, input, X)," & -- PAD575 " 421 (BC_2, *, controlr, 1)," & " 422 (BC_2, IO_C35, output3, X, 421, 1, Z)," & -- PAD574 " 423 (BC_2, IO_C35, input, X)," & -- PAD574 " 424 (BC_2, *, controlr, 1)," & " 425 (BC_2, IO_D36, output3, X, 424, 1, Z)," & -- PAD573 " 426 (BC_2, IO_D36, input, X)," & -- PAD573 " 427 (BC_2, *, controlr, 1)," & " 428 (BC_2, IO_D35, output3, X, 427, 1, Z)," & -- PAD572 " 429 (BC_2, IO_D35, input, X)," & -- PAD572 " 430 (BC_2, *, controlr, 1)," & " 431 (BC_2, IO_C34, output3, X, 430, 1, Z)," & -- PAD571 " 432 (BC_2, IO_C34, input, X)," & -- PAD571 " 433 (BC_2, *, controlr, 1)," & " 434 (BC_2, IO_C33, output3, X, 433, 1, Z)," & -- PAD570 " 435 (BC_2, IO_C33, input, X)," & -- PAD570 " 436 (BC_2, *, controlr, 1)," & " 437 (BC_2, IO_D33, output3, X, 436, 1, Z)," & -- PAD569 " 438 (BC_2, IO_D33, input, X)," & -- PAD569 " 439 (BC_2, *, controlr, 1)," & " 440 (BC_2, IO_E33, output3, X, 439, 1, Z)," & -- PAD568 " 441 (BC_2, IO_E33, input, X)," & -- PAD568 " 442 (BC_2, *, controlr, 1)," & " 443 (BC_2, IO_B33, output3, X, 442, 1, Z)," & -- PAD567 " 444 (BC_2, IO_B33, input, X)," & -- PAD567 " 445 (BC_2, *, controlr, 1)," & " 446 (BC_2, IO_B32, output3, X, 445, 1, Z)," & -- PAD566 " 447 (BC_2, IO_B32, input, X)," & -- PAD566 " 448 (BC_2, *, controlr, 1)," & " 449 (BC_2, IO_D32, output3, X, 448, 1, Z)," & -- PAD565 " 450 (BC_2, IO_D32, input, X)," & -- PAD565 " 451 (BC_2, *, controlr, 1)," & " 452 (BC_2, IO_E32, output3, X, 451, 1, Z)," & -- PAD564 " 453 (BC_2, IO_E32, input, X)," & -- PAD564 " 454 (BC_2, *, controlr, 1)," & " 455 (BC_2, IO_B38, output3, X, 454, 1, Z)," & -- PAD563 " 456 (BC_2, IO_B38, input, X)," & -- PAD563 " 457 (BC_2, *, controlr, 1)," & " 458 (BC_2, IO_B37, output3, X, 457, 1, Z)," & -- PAD562 " 459 (BC_2, IO_B37, input, X)," & -- PAD562 " 460 (BC_2, *, controlr, 1)," & " 461 (BC_2, IO_C39, output3, X, 460, 1, Z)," & -- PAD561 " 462 (BC_2, IO_C39, input, X)," & -- PAD561 " 463 (BC_2, *, controlr, 1)," & " 464 (BC_2, IO_C38, output3, X, 463, 1, Z)," & -- PAD560 " 465 (BC_2, IO_C38, input, X)," & -- PAD560 " 466 (BC_2, *, controlr, 1)," & " 467 (BC_2, IO_A36, output3, X, 466, 1, Z)," & -- PAD559 " 468 (BC_2, IO_A36, input, X)," & -- PAD559 " 469 (BC_2, *, controlr, 1)," & " 470 (BC_2, IO_A35, output3, X, 469, 1, Z)," & -- PAD558 " 471 (BC_2, IO_A35, input, X)," & -- PAD558 " 472 (BC_2, *, controlr, 1)," & " 473 (BC_2, IO_A39, output3, X, 472, 1, Z)," & -- PAD557 " 474 (BC_2, IO_A39, input, X)," & -- PAD557 " 475 (BC_2, *, controlr, 1)," & " 476 (BC_2, IO_B39, output3, X, 475, 1, Z)," & -- PAD556 " 477 (BC_2, IO_B39, input, X)," & -- PAD556 " 478 (BC_2, *, controlr, 1)," & " 479 (BC_2, IO_A34, output3, X, 478, 1, Z)," & -- PAD555 " 480 (BC_2, IO_A34, input, X)," & -- PAD555 " 481 (BC_2, *, controlr, 1)," & " 482 (BC_2, IO_B34, output3, X, 481, 1, Z)," & -- PAD554 " 483 (BC_2, IO_B34, input, X)," & -- PAD554 " 484 (BC_2, *, controlr, 1)," & " 485 (BC_2, IO_A37, output3, X, 484, 1, Z)," & -- PAD553 " 486 (BC_2, IO_A37, input, X)," & -- PAD553 " 487 (BC_2, *, controlr, 1)," & " 488 (BC_2, IO_B36, output3, X, 487, 1, Z)," & -- PAD552 " 489 (BC_2, IO_B36, input, X)," & -- PAD552 " 490 (BC_2, *, controlr, 1)," & " 491 (BC_2, IO_G31, output3, X, 490, 1, Z)," & -- PAD551 " 492 (BC_2, IO_G31, input, X)," & -- PAD551 " 493 (BC_2, *, controlr, 1)," & " 494 (BC_2, IO_M26, output3, X, 493, 1, Z)," & -- PAD550 " 495 (BC_2, IO_M26, input, X)," & -- PAD550 " 496 (BC_2, *, controlr, 1)," & " 497 (BC_2, IO_L27, output3, X, 496, 1, Z)," & -- PAD549 " 498 (BC_2, IO_L27, input, X)," & -- PAD549 " 499 (BC_2, *, controlr, 1)," & " 500 (BC_2, IO_M27, output3, X, 499, 1, Z)," & -- PAD548 " 501 (BC_2, IO_M27, input, X)," & -- PAD548 " 502 (BC_2, *, controlr, 1)," & " 503 (BC_2, IO_N24, output3, X, 502, 1, Z)," & -- PAD547 " 504 (BC_2, IO_N24, input, X)," & -- PAD547 " 505 (BC_2, *, controlr, 1)," & " 506 (BC_2, IO_N23, output3, X, 505, 1, Z)," & -- PAD546 " 507 (BC_2, IO_N23, input, X)," & -- PAD546 " 508 (BC_2, *, controlr, 1)," & " 509 (BC_2, IO_N26, output3, X, 508, 1, Z)," & -- PAD545 " 510 (BC_2, IO_N26, input, X)," & -- PAD545 " 511 (BC_2, *, controlr, 1)," & " 512 (BC_2, IO_N25, output3, X, 511, 1, Z)," & -- PAD544 " 513 (BC_2, IO_N25, input, X)," & -- PAD544 " 514 (BC_2, *, controlr, 1)," & " 515 (BC_2, IO_P23, output3, X, 514, 1, Z)," & -- PAD543 " 516 (BC_2, IO_P23, input, X)," & -- PAD543 " 517 (BC_2, *, controlr, 1)," & " 518 (BC_2, IO_P22, output3, X, 517, 1, Z)," & -- PAD542 " 519 (BC_2, IO_P22, input, X)," & -- PAD542 " 520 (BC_2, *, controlr, 1)," & " 521 (BC_2, IO_P26, output3, X, 520, 1, Z)," & -- PAD541 " 522 (BC_2, IO_P26, input, X)," & -- PAD541 " 523 (BC_2, *, controlr, 1)," & " 524 (BC_2, IO_P25, output3, X, 523, 1, Z)," & -- PAD540 " 525 (BC_2, IO_P25, input, X)," & -- PAD540 " 526 (BC_2, *, controlr, 1)," & " 527 (BC_2, IO_N21, output3, X, 526, 1, Z)," & -- PAD539 " 528 (BC_2, IO_N21, input, X)," & -- PAD539 " 529 (BC_2, *, controlr, 1)," & " 530 (BC_2, IO_P21, output3, X, 529, 1, Z)," & -- PAD538 " 531 (BC_2, IO_P21, input, X)," & -- PAD538 " 532 (BC_2, *, controlr, 1)," & " 533 (BC_2, IO_L21, output3, X, 532, 1, Z)," & -- PAD537 " 534 (BC_2, IO_L21, input, X)," & -- PAD537 " 535 (BC_2, *, controlr, 1)," & " 536 (BC_2, IO_M21, output3, X, 535, 1, Z)," & -- PAD536 " 537 (BC_2, IO_M21, input, X)," & -- PAD536 " 538 (BC_2, *, controlr, 1)," & " 539 (BC_2, IO_J22, output3, X, 538, 1, Z)," & -- PAD535 " 540 (BC_2, IO_J22, input, X)," & -- PAD535 " 541 (BC_2, *, controlr, 1)," & " 542 (BC_2, IO_K22, output3, X, 541, 1, Z)," & -- PAD534 " 543 (BC_2, IO_K22, input, X)," & -- PAD534 " 544 (BC_2, *, controlr, 1)," & " 545 (BC_2, IO_L26, output3, X, 544, 1, Z)," & -- PAD533 " 546 (BC_2, IO_L26, input, X)," & -- PAD533 " 547 (BC_2, *, controlr, 1)," & " 548 (BC_2, IO_L25, output3, X, 547, 1, Z)," & -- PAD532 " 549 (BC_2, IO_L25, input, X)," & -- PAD532 " 550 (BC_2, *, controlr, 1)," & " 551 (BC_2, IO_L22, output3, X, 550, 1, Z)," & -- PAD531 " 552 (BC_2, IO_L22, input, X)," & -- PAD531 " 553 (BC_2, *, controlr, 1)," & " 554 (BC_2, IO_M22, output3, X, 553, 1, Z)," & -- PAD530 " 555 (BC_2, IO_M22, input, X)," & -- PAD530 " 556 (BC_2, *, controlr, 1)," & " 557 (BC_2, IO_J23, output3, X, 556, 1, Z)," & -- PAD529 " 558 (BC_2, IO_J23, input, X)," & -- PAD529 " 559 (BC_2, *, controlr, 1)," & " 560 (BC_2, IO_K23, output3, X, 559, 1, Z)," & -- PAD528 " 561 (BC_2, IO_K23, input, X)," & -- PAD528 " 562 (BC_2, *, controlr, 1)," & " 563 (BC_2, IO_L24, output3, X, 562, 1, Z)," & -- PAD527 " 564 (BC_2, IO_L24, input, X)," & -- PAD527 " 565 (BC_2, *, controlr, 1)," & " 566 (BC_2, IO_M24, output3, X, 565, 1, Z)," & -- PAD526 " 567 (BC_2, IO_M24, input, X)," & -- PAD526 " 568 (BC_2, *, controlr, 1)," & " 569 (BC_2, IO_J26, output3, X, 568, 1, Z)," & -- PAD525 " 570 (BC_2, IO_J26, input, X)," & -- PAD525 " 571 (BC_2, *, controlr, 1)," & " 572 (BC_2, IO_J25, output3, X, 571, 1, Z)," & -- PAD524 " 573 (BC_2, IO_J25, input, X)," & -- PAD524 " 574 (BC_2, *, controlr, 1)," & " 575 (BC_2, IO_K25, output3, X, 574, 1, Z)," & -- PAD523 " 576 (BC_2, IO_K25, input, X)," & -- PAD523 " 577 (BC_2, *, controlr, 1)," & " 578 (BC_2, IO_K24, output3, X, 577, 1, Z)," & -- PAD522 " 579 (BC_2, IO_K24, input, X)," & -- PAD522 " 580 (BC_2, *, controlr, 1)," & " 581 (BC_2, IO_J27, output3, X, 580, 1, Z)," & -- PAD521 " 582 (BC_2, IO_J27, input, X)," & -- PAD521 " 583 (BC_2, *, controlr, 1)," & " 584 (BC_2, IO_K27, output3, X, 583, 1, Z)," & -- PAD520 " 585 (BC_2, IO_K27, input, X)," & -- PAD520 " 586 (BC_2, *, controlr, 1)," & " 587 (BC_2, IO_H29, output3, X, 586, 1, Z)," & -- PAD519 " 588 (BC_2, IO_H29, input, X)," & -- PAD519 " 589 (BC_2, *, controlr, 1)," & " 590 (BC_2, IO_H28, output3, X, 589, 1, Z)," & -- PAD518 " 591 (BC_2, IO_H28, input, X)," & -- PAD518 " 592 (BC_2, *, controlr, 1)," & " 593 (BC_2, IO_J28, output3, X, 592, 1, Z)," & -- PAD517 " 594 (BC_2, IO_J28, input, X)," & -- PAD517 " 595 (BC_2, *, controlr, 1)," & " 596 (BC_2, IO_K28, output3, X, 595, 1, Z)," & -- PAD516 " 597 (BC_2, IO_K28, input, X)," & -- PAD516 " 598 (BC_2, *, controlr, 1)," & " 599 (BC_2, IO_G29, output3, X, 598, 1, Z)," & -- PAD515 " 600 (BC_2, IO_G29, input, X)," & -- PAD515 " 601 (BC_2, *, controlr, 1)," & " 602 (BC_2, IO_G28, output3, X, 601, 1, Z)," & -- PAD514 " 603 (BC_2, IO_G28, input, X)," & -- PAD514 " 604 (BC_2, *, controlr, 1)," & " 605 (BC_2, IO_G23, output3, X, 604, 1, Z)," & -- PAD513 " 606 (BC_2, IO_G23, input, X)," & -- PAD513 " 607 (BC_2, *, controlr, 1)," & " 608 (BC_2, IO_H23, output3, X, 607, 1, Z)," & -- PAD512 " 609 (BC_2, IO_H23, input, X)," & -- PAD512 " 610 (BC_2, *, controlr, 1)," & " 611 (BC_2, IO_G27, output3, X, 610, 1, Z)," & -- PAD511 " 612 (BC_2, IO_G27, input, X)," & -- PAD511 " 613 (BC_2, *, controlr, 1)," & " 614 (BC_2, IO_G26, output3, X, 613, 1, Z)," & -- PAD510 " 615 (BC_2, IO_G26, input, X)," & -- PAD510 " 616 (BC_2, *, controlr, 1)," & " 617 (BC_2, IO_G22, output3, X, 616, 1, Z)," & -- PAD509 " 618 (BC_2, IO_G22, input, X)," & -- PAD509 " 619 (BC_2, *, controlr, 1)," & " 620 (BC_2, IO_G21, output3, X, 619, 1, Z)," & -- PAD508 " 621 (BC_2, IO_G21, input, X)," & -- PAD508 " 622 (BC_2, *, controlr, 1)," & " 623 (BC_2, IO_H26, output3, X, 622, 1, Z)," & -- PAD507 " 624 (BC_2, IO_H26, input, X)," & -- PAD507 " 625 (BC_2, *, controlr, 1)," & " 626 (BC_2, IO_H25, output3, X, 625, 1, Z)," & -- PAD506 " 627 (BC_2, IO_H25, input, X)," & -- PAD506 " 628 (BC_2, *, controlr, 1)," & " 629 (BC_2, IO_H21, output3, X, 628, 1, Z)," & -- PAD505 " 630 (BC_2, IO_H21, input, X)," & -- PAD505 " 631 (BC_2, *, controlr, 1)," & " 632 (BC_2, IO_J21, output3, X, 631, 1, Z)," & -- PAD504 " 633 (BC_2, IO_J21, input, X)," & -- PAD504 " 634 (BC_2, *, controlr, 1)," & " 635 (BC_2, IO_G24, output3, X, 634, 1, Z)," & -- PAD503 " 636 (BC_2, IO_G24, input, X)," & -- PAD503 " 637 (BC_2, *, controlr, 1)," & " 638 (BC_2, IO_H24, output3, X, 637, 1, Z)," & -- PAD502 " 639 (BC_2, IO_H24, input, X)," & -- PAD502 " 640 (BC_2, *, controlr, 1)," & " 641 (BC_2, IO_M23, output3, X, 640, 1, Z)," & -- PAD501 " 642 (BC_2, IO_M23, input, X)," & -- PAD501 " 643 (BC_2, *, controlr, 1)," & " 644 (BC_2, IO_F24, output3, X, 643, 1, Z)," & -- PAD500 " 645 (BC_2, IO_F24, input, X)," & -- PAD500 " 646 (BC_2, *, controlr, 1)," & " 647 (BC_2, IO_F31, output3, X, 646, 1, Z)," & -- PAD499 " 648 (BC_2, IO_F31, input, X)," & -- PAD499 " 649 (BC_2, *, controlr, 1)," & " 650 (BC_2, IO_F30, output3, X, 649, 1, Z)," & -- PAD498 " 651 (BC_2, IO_F30, input, X)," & -- PAD498 " 652 (BC_2, *, controlr, 1)," & " 653 (BC_2, IO_F27, output3, X, 652, 1, Z)," & -- PAD497 " 654 (BC_2, IO_F27, input, X)," & -- PAD497 " 655 (BC_2, *, controlr, 1)," & " 656 (BC_2, IO_F26, output3, X, 655, 1, Z)," & -- PAD496 " 657 (BC_2, IO_F26, input, X)," & -- PAD496 " 658 (BC_2, *, controlr, 1)," & " 659 (BC_2, IO_E29, output3, X, 658, 1, Z)," & -- PAD495 " 660 (BC_2, IO_E29, input, X)," & -- PAD495 " 661 (BC_2, *, controlr, 1)," & " 662 (BC_2, IO_F29, output3, X, 661, 1, Z)," & -- PAD494 " 663 (BC_2, IO_F29, input, X)," & -- PAD494 " 664 (BC_2, *, controlr, 1)," & " 665 (BC_2, IO_E28, output3, X, 664, 1, Z)," & -- PAD493 " 666 (BC_2, IO_E28, input, X)," & -- PAD493 " 667 (BC_2, *, controlr, 1)," & " 668 (BC_2, IO_E27, output3, X, 667, 1, Z)," & -- PAD492 " 669 (BC_2, IO_E27, input, X)," & -- PAD492 " 670 (BC_2, *, controlr, 1)," & " 671 (BC_2, IO_C30, output3, X, 670, 1, Z)," & -- PAD491 " 672 (BC_2, IO_C30, input, X)," & -- PAD491 " 673 (BC_2, *, controlr, 1)," & " 674 (BC_2, IO_D30, output3, X, 673, 1, Z)," & -- PAD490 " 675 (BC_2, IO_D30, input, X)," & -- PAD490 " 676 (BC_2, *, controlr, 1)," & " 677 (BC_2, IO_D31, output3, X, 676, 1, Z)," & -- PAD489 " 678 (BC_2, IO_D31, input, X)," & -- PAD489 " 679 (BC_2, *, controlr, 1)," & " 680 (BC_2, IO_E30, output3, X, 679, 1, Z)," & -- PAD488 " 681 (BC_2, IO_E30, input, X)," & -- PAD488 " 682 (BC_2, *, controlr, 1)," & " 683 (BC_2, IO_B31, output3, X, 682, 1, Z)," & -- PAD487 " 684 (BC_2, IO_B31, input, X)," & -- PAD487 " 685 (BC_2, *, controlr, 1)," & " 686 (BC_2, IO_C31, output3, X, 685, 1, Z)," & -- PAD486 " 687 (BC_2, IO_C31, input, X)," & -- PAD486 " 688 (BC_2, *, controlr, 1)," & " 689 (BC_2, IO_A30, output3, X, 688, 1, Z)," & -- PAD485 " 690 (BC_2, IO_A30, input, X)," & -- PAD485 " 691 (BC_2, *, controlr, 1)," & " 692 (BC_2, IO_A29, output3, X, 691, 1, Z)," & -- PAD484 " 693 (BC_2, IO_A29, input, X)," & -- PAD484 " 694 (BC_2, *, controlr, 1)," & " 695 (BC_2, IO_A32, output3, X, 694, 1, Z)," & -- PAD483 " 696 (BC_2, IO_A32, input, X)," & -- PAD483 " 697 (BC_2, *, controlr, 1)," & " 698 (BC_2, IO_A31, output3, X, 697, 1, Z)," & -- PAD482 " 699 (BC_2, IO_A31, input, X)," & -- PAD482 " 700 (BC_2, *, controlr, 1)," & " 701 (BC_2, IO_B29, output3, X, 700, 1, Z)," & -- PAD481 " 702 (BC_2, IO_B29, input, X)," & -- PAD481 " 703 (BC_2, *, controlr, 1)," & " 704 (BC_2, IO_B28, output3, X, 703, 1, Z)," & -- PAD480 " 705 (BC_2, IO_B28, input, X)," & -- PAD480 " 706 (BC_2, *, controlr, 1)," & " 707 (BC_2, IO_C29, output3, X, 706, 1, Z)," & -- PAD479 " 708 (BC_2, IO_C29, input, X)," & -- PAD479 " 709 (BC_2, *, controlr, 1)," & " 710 (BC_2, IO_C28, output3, X, 709, 1, Z)," & -- PAD478 " 711 (BC_2, IO_C28, input, X)," & -- PAD478 " 712 (BC_2, *, controlr, 1)," & " 713 (BC_2, IO_D28, output3, X, 712, 1, Z)," & -- PAD477 " 714 (BC_2, IO_D28, input, X)," & -- PAD477 " 715 (BC_2, *, controlr, 1)," & " 716 (BC_2, IO_D27, output3, X, 715, 1, Z)," & -- PAD476 " 717 (BC_2, IO_D27, input, X)," & -- PAD476 " 718 (BC_2, *, controlr, 1)," & " 719 (BC_2, IO_C26, output3, X, 718, 1, Z)," & -- PAD475 " 720 (BC_2, IO_C26, input, X)," & -- PAD475 " 721 (BC_2, *, controlr, 1)," & " 722 (BC_2, IO_C25, output3, X, 721, 1, Z)," & -- PAD474 " 723 (BC_2, IO_C25, input, X)," & -- PAD474 " 724 (BC_2, *, controlr, 1)," & " 725 (BC_2, IO_D26, output3, X, 724, 1, Z)," & -- PAD473 " 726 (BC_2, IO_D26, input, X)," & -- PAD473 " 727 (BC_2, *, controlr, 1)," & " 728 (BC_2, IO_D25, output3, X, 727, 1, Z)," & -- PAD472 " 729 (BC_2, IO_D25, input, X)," & -- PAD472 " 730 (BC_2, *, controlr, 1)," & " 731 (BC_2, IO_D23, output3, X, 730, 1, Z)," & -- PAD471 " 732 (BC_2, IO_D23, input, X)," & -- PAD471 " 733 (BC_2, *, controlr, 1)," & " 734 (BC_2, IO_D22, output3, X, 733, 1, Z)," & -- PAD470 " 735 (BC_2, IO_D22, input, X)," & -- PAD470 " 736 (BC_2, *, controlr, 1)," & " 737 (BC_2, IO_E25, output3, X, 736, 1, Z)," & -- PAD469 " 738 (BC_2, IO_E25, input, X)," & -- PAD469 " 739 (BC_2, *, controlr, 1)," & " 740 (BC_2, IO_F25, output3, X, 739, 1, Z)," & -- PAD468 " 741 (BC_2, IO_F25, input, X)," & -- PAD468 " 742 (BC_2, *, controlr, 1)," & " 743 (BC_2, IO_E22, output3, X, 742, 1, Z)," & -- PAD467 " 744 (BC_2, IO_E22, input, X)," & -- PAD467 " 745 (BC_2, *, controlr, 1)," & " 746 (BC_2, IO_F22, output3, X, 745, 1, Z)," & -- PAD466 " 747 (BC_2, IO_F22, input, X)," & -- PAD466 " 748 (BC_2, *, controlr, 1)," & " 749 (BC_2, IO_E24, output3, X, 748, 1, Z)," & -- PAD465 " 750 (BC_2, IO_E24, input, X)," & -- PAD465 " 751 (BC_2, *, controlr, 1)," & " 752 (BC_2, IO_E23, output3, X, 751, 1, Z)," & -- PAD464 " 753 (BC_2, IO_E23, input, X)," & -- PAD464 " 754 (BC_2, *, controlr, 1)," & " 755 (BC_2, IO_B24, output3, X, 754, 1, Z)," & -- PAD463 " 756 (BC_2, IO_B24, input, X)," & -- PAD463 " 757 (BC_2, *, controlr, 1)," & " 758 (BC_2, IO_C24, output3, X, 757, 1, Z)," & -- PAD462 " 759 (BC_2, IO_C24, input, X)," & -- PAD462 " 760 (BC_2, *, controlr, 1)," & " 761 (BC_2, IO_B27, output3, X, 760, 1, Z)," & -- PAD461 " 762 (BC_2, IO_B27, input, X)," & -- PAD461 " 763 (BC_2, *, controlr, 1)," & " 764 (BC_2, IO_B26, output3, X, 763, 1, Z)," & -- PAD460 " 765 (BC_2, IO_B26, input, X)," & -- PAD460 " 766 (BC_2, *, controlr, 1)," & " 767 (BC_2, IO_B23, output3, X, 766, 1, Z)," & -- PAD459 " 768 (BC_2, IO_B23, input, X)," & -- PAD459 " 769 (BC_2, *, controlr, 1)," & " 770 (BC_2, IO_C23, output3, X, 769, 1, Z)," & -- PAD458 " 771 (BC_2, IO_C23, input, X)," & -- PAD458 " 772 (BC_2, *, controlr, 1)," & " 773 (BC_2, IO_A27, output3, X, 772, 1, Z)," & -- PAD457 " 774 (BC_2, IO_A27, input, X)," & -- PAD457 " 775 (BC_2, *, controlr, 1)," & " 776 (BC_2, IO_A26, output3, X, 775, 1, Z)," & -- PAD456 " 777 (BC_2, IO_A26, input, X)," & -- PAD456 " 778 (BC_2, *, controlr, 1)," & " 779 (BC_2, IO_A22, output3, X, 778, 1, Z)," & -- PAD455 " 780 (BC_2, IO_A22, input, X)," & -- PAD455 " 781 (BC_2, *, controlr, 1)," & " 782 (BC_2, IO_B22, output3, X, 781, 1, Z)," & -- PAD454 " 783 (BC_2, IO_B22, input, X)," & -- PAD454 " 784 (BC_2, *, controlr, 1)," & " 785 (BC_2, IO_A25, output3, X, 784, 1, Z)," & -- PAD453 " 786 (BC_2, IO_A25, input, X)," & -- PAD453 " 787 (BC_2, *, controlr, 1)," & " 788 (BC_2, IO_A24, output3, X, 787, 1, Z)," & -- PAD452 " 789 (BC_2, IO_A24, input, X)," & -- PAD452 " 790 (BC_2, *, controlr, 1)," & " 791 (BC_2, IO_F21, output3, X, 790, 1, Z)," & -- PAD451 " 792 (BC_2, IO_F21, input, X)," & -- PAD451 " 793 (BC_2, *, controlr, 1)," & " 794 (BC_2, IO_K20, output3, X, 793, 1, Z)," & -- PAD450 " 795 (BC_2, IO_K20, input, X)," & -- PAD450 " 796 (BC_2, *, controlr, 1)," & " 797 (BC_2, IO_L19, output3, X, 796, 1, Z)," & -- PAD449 " 798 (BC_2, IO_L19, input, X)," & -- PAD449 " 799 (BC_2, *, controlr, 1)," & " 800 (BC_2, IO_L20, output3, X, 799, 1, Z)," & -- PAD448 " 801 (BC_2, IO_L20, input, X)," & -- PAD448 " 802 (BC_2, *, controlr, 1)," & " 803 (BC_2, IO_N20, output3, X, 802, 1, Z)," & -- PAD447 " 804 (BC_2, IO_N20, input, X)," & -- PAD447 " 805 (BC_2, *, controlr, 1)," & " 806 (BC_2, IO_P20, output3, X, 805, 1, Z)," & -- PAD446 " 807 (BC_2, IO_P20, input, X)," & -- PAD446 " 808 (BC_2, *, controlr, 1)," & " 809 (BC_2, IO_M18, output3, X, 808, 1, Z)," & -- PAD445 " 810 (BC_2, IO_M18, input, X)," & -- PAD445 " 811 (BC_2, *, controlr, 1)," & " 812 (BC_2, IO_M19, output3, X, 811, 1, Z)," & -- PAD444 " 813 (BC_2, IO_M19, input, X)," & -- PAD444 " 814 (BC_2, *, controlr, 1)," & " 815 (BC_2, IO_N18, output3, X, 814, 1, Z)," & -- PAD443 " 816 (BC_2, IO_N18, input, X)," & -- PAD443 " 817 (BC_2, *, controlr, 1)," & " 818 (BC_2, IO_N19, output3, X, 817, 1, Z)," & -- PAD442 " 819 (BC_2, IO_N19, input, X)," & -- PAD442 " 820 (BC_2, *, controlr, 1)," & " 821 (BC_2, IO_L17, output3, X, 820, 1, Z)," & -- PAD441 " 822 (BC_2, IO_L17, input, X)," & -- PAD441 " 823 (BC_2, *, controlr, 1)," & " 824 (BC_2, IO_M17, output3, X, 823, 1, Z)," & -- PAD440 " 825 (BC_2, IO_M17, input, X)," & -- PAD440 " 826 (BC_2, *, controlr, 1)," & " 827 (BC_2, IO_P17, output3, X, 826, 1, Z)," & -- PAD439 " 828 (BC_2, IO_P17, input, X)," & -- PAD439 " 829 (BC_2, *, controlr, 1)," & " 830 (BC_2, IO_P18, output3, X, 829, 1, Z)," & -- PAD438 " 831 (BC_2, IO_P18, input, X)," & -- PAD438 " 832 (BC_2, *, controlr, 1)," & " 833 (BC_2, IO_G17, output3, X, 832, 1, Z)," & -- PAD437 " 834 (BC_2, IO_G17, input, X)," & -- PAD437 " 835 (BC_2, *, controlr, 1)," & " 836 (BC_2, IO_H18, output3, X, 835, 1, Z)," & -- PAD436 " 837 (BC_2, IO_H18, input, X)," & -- PAD436 " 838 (BC_2, *, controlr, 1)," & " 839 (BC_2, IO_H20, output3, X, 838, 1, Z)," & -- PAD435 " 840 (BC_2, IO_H20, input, X)," & -- PAD435 " 841 (BC_2, *, controlr, 1)," & " 842 (BC_2, IO_J20, output3, X, 841, 1, Z)," & -- PAD434 " 843 (BC_2, IO_J20, input, X)," & -- PAD434 " 844 (BC_2, *, controlr, 1)," & " 845 (BC_2, IO_J17, output3, X, 844, 1, Z)," & -- PAD433 " 846 (BC_2, IO_J17, input, X)," & -- PAD433 " 847 (BC_2, *, controlr, 1)," & " 848 (BC_2, IO_K17, output3, X, 847, 1, Z)," & -- PAD432 " 849 (BC_2, IO_K17, input, X)," & -- PAD432 " 850 (BC_2, *, controlr, 1)," & " 851 (BC_2, IO_E20, output3, X, 850, 1, Z)," & -- PAD431 " 852 (BC_2, IO_E20, input, X)," & -- PAD431 " 853 (BC_2, *, controlr, 1)," & " 854 (BC_2, IO_F20, output3, X, 853, 1, Z)," & -- PAD430 " 855 (BC_2, IO_F20, input, X)," & -- PAD430 " 856 (BC_2, *, controlr, 1)," & " 857 (BC_2, IO_J18, output3, X, 856, 1, Z)," & -- PAD429 " 858 (BC_2, IO_J18, input, X)," & -- PAD429 " 859 (BC_2, *, controlr, 1)," & " 860 (BC_2, IO_K19, output3, X, 859, 1, Z)," & -- PAD428 " 861 (BC_2, IO_K19, input, X)," & -- PAD428 " 862 (BC_2, *, controlr, 1)," & " 863 (BC_2, IO_G18, output3, X, 862, 1, Z)," & -- PAD427 " 864 (BC_2, IO_G18, input, X)," & -- PAD427 " 865 (BC_2, *, controlr, 1)," & " 866 (BC_2, IO_H19, output3, X, 865, 1, Z)," & -- PAD426 " 867 (BC_2, IO_H19, input, X)," & -- PAD426 " 868 (BC_2, *, controlr, 1)," & " 869 (BC_2, IO_E18, output3, X, 868, 1, Z)," & -- PAD425 " 870 (BC_2, IO_E18, input, X)," & -- PAD425 " 871 (BC_2, *, controlr, 1)," & " 872 (BC_2, IO_E19, output3, X, 871, 1, Z)," & -- PAD424 " 873 (BC_2, IO_E19, input, X)," & -- PAD424 " 874 (BC_2, *, controlr, 1)," & " 875 (BC_2, IO_F19, output3, X, 874, 1, Z)," & -- PAD423 " 876 (BC_2, IO_F19, input, X)," & -- PAD423 " 877 (BC_2, *, controlr, 1)," & " 878 (BC_2, IO_G19, output3, X, 877, 1, Z)," & -- PAD422 " 879 (BC_2, IO_G19, input, X)," & -- PAD422 " 880 (BC_2, *, controlr, 1)," & " 881 (BC_2, IO_D17, output3, X, 880, 1, Z)," & -- PAD421 " 882 (BC_2, IO_D17, input, X)," & -- PAD421 " 883 (BC_2, *, controlr, 1)," & " 884 (BC_2, IO_D18, output3, X, 883, 1, Z)," & -- PAD420 " 885 (BC_2, IO_D18, input, X)," & -- PAD420 " 886 (BC_2, *, controlr, 1)," & " 887 (BC_2, IO_C21, output3, X, 886, 1, Z)," & -- PAD419 " 888 (BC_2, IO_C21, input, X)," & -- PAD419 " 889 (BC_2, *, controlr, 1)," & " 890 (BC_2, IO_D21, output3, X, 889, 1, Z)," & -- PAD418 " 891 (BC_2, IO_D21, input, X)," & -- PAD418 " 892 (BC_2, *, controlr, 1)," & " 893 (BC_2, IO_E17, output3, X, 892, 1, Z)," & -- PAD417 " 894 (BC_2, IO_E17, input, X)," & -- PAD417 " 895 (BC_2, *, controlr, 1)," & " 896 (BC_2, IO_F17, output3, X, 895, 1, Z)," & -- PAD416 " 897 (BC_2, IO_F17, input, X)," & -- PAD416 " 898 (BC_2, *, controlr, 1)," & " 899 (BC_2, IO_C20, output3, X, 898, 1, Z)," & -- PAD415 " 900 (BC_2, IO_C20, input, X)," & -- PAD415 " 901 (BC_2, *, controlr, 1)," & " 902 (BC_2, IO_D20, output3, X, 901, 1, Z)," & -- PAD414 " 903 (BC_2, IO_D20, input, X)," & -- PAD414 " 904 (BC_2, *, controlr, 1)," & " 905 (BC_2, IO_B18, output3, X, 904, 1, Z)," & -- PAD413 " 906 (BC_2, IO_B18, input, X)," & -- PAD413 " 907 (BC_2, *, controlr, 1)," & " 908 (BC_2, IO_C18, output3, X, 907, 1, Z)," & -- PAD412 " 909 (BC_2, IO_C18, input, X)," & -- PAD412 " 910 (BC_2, *, controlr, 1)," & " 911 (BC_2, IO_A21, output3, X, 910, 1, Z)," & -- PAD411 " 912 (BC_2, IO_A21, input, X)," & -- PAD411 " 913 (BC_2, *, controlr, 1)," & " 914 (BC_2, IO_B21, output3, X, 913, 1, Z)," & -- PAD410 " 915 (BC_2, IO_B21, input, X)," & -- PAD410 " 916 (BC_2, *, controlr, 1)," & " 917 (BC_2, IO_A17, output3, X, 916, 1, Z)," & -- PAD409 " 918 (BC_2, IO_A17, input, X)," & -- PAD409 " 919 (BC_2, *, controlr, 1)," & " 920 (BC_2, IO_B17, output3, X, 919, 1, Z)," & -- PAD408 " 921 (BC_2, IO_B17, input, X)," & -- PAD408 " 922 (BC_2, *, controlr, 1)," & " 923 (BC_2, IO_A19, output3, X, 922, 1, Z)," & -- PAD407 " 924 (BC_2, IO_A19, input, X)," & -- PAD407 " 925 (BC_2, *, controlr, 1)," & " 926 (BC_2, IO_A20, output3, X, 925, 1, Z)," & -- PAD406 " 927 (BC_2, IO_A20, input, X)," & -- PAD406 " 928 (BC_2, *, controlr, 1)," & " 929 (BC_2, IO_A15, output3, X, 928, 1, Z)," & -- PAD405 " 930 (BC_2, IO_A15, input, X)," & -- PAD405 " 931 (BC_2, *, controlr, 1)," & " 932 (BC_2, IO_A16, output3, X, 931, 1, Z)," & -- PAD404 " 933 (BC_2, IO_A16, input, X)," & -- PAD404 " 934 (BC_2, *, controlr, 1)," & " 935 (BC_2, IO_B19, output3, X, 934, 1, Z)," & -- PAD403 " 936 (BC_2, IO_B19, input, X)," & -- PAD403 " 937 (BC_2, *, controlr, 1)," & " 938 (BC_2, IO_C19, output3, X, 937, 1, Z)," & -- PAD402 " 939 (BC_2, IO_C19, input, X)," & -- PAD402 " 940 (BC_2, *, controlr, 1)," & " 941 (BC_2, IO_K18, output3, X, 940, 1, Z)," & -- PAD401 " 942 (BC_2, IO_K18, input, X)," & -- PAD401 " 943 (BC_2, *, controlr, 1)," & " 944 (BC_2, IO_J11, output3, X, 943, 1, Z)," & -- PAD400 " 945 (BC_2, IO_J11, input, X)," & -- PAD400 " 946 (BC_2, *, controlr, 1)," & " 947 (BC_2, IO_M11, output3, X, 946, 1, Z)," & -- PAD399 " 948 (BC_2, IO_M11, input, X)," & -- PAD399 " 949 (BC_2, *, controlr, 1)," & " 950 (BC_2, IO_M12, output3, X, 949, 1, Z)," & -- PAD398 " 951 (BC_2, IO_M12, input, X)," & -- PAD398 " 952 (BC_2, *, controlr, 1)," & " 953 (BC_2, IO_N14, output3, X, 952, 1, Z)," & -- PAD397 " 954 (BC_2, IO_N14, input, X)," & -- PAD397 " 955 (BC_2, *, controlr, 1)," & " 956 (BC_2, IO_N15, output3, X, 955, 1, Z)," & -- PAD396 " 957 (BC_2, IO_N15, input, X)," & -- PAD396 " 958 (BC_2, *, controlr, 1)," & " 959 (BC_2, IO_M13, output3, X, 958, 1, Z)," & -- PAD395 " 960 (BC_2, IO_M13, input, X)," & -- PAD395 " 961 (BC_2, *, controlr, 1)," & " 962 (BC_2, IO_N13, output3, X, 961, 1, Z)," & -- PAD394 " 963 (BC_2, IO_N13, input, X)," & -- PAD394 " 964 (BC_2, *, controlr, 1)," & " 965 (BC_2, IO_M16, output3, X, 964, 1, Z)," & -- PAD393 " 966 (BC_2, IO_M16, input, X)," & -- PAD393 " 967 (BC_2, *, controlr, 1)," & " 968 (BC_2, IO_N16, output3, X, 967, 1, Z)," & -- PAD392 " 969 (BC_2, IO_N16, input, X)," & -- PAD392 " 970 (BC_2, *, controlr, 1)," & " 971 (BC_2, IO_L14, output3, X, 970, 1, Z)," & -- PAD391 " 972 (BC_2, IO_L14, input, X)," & -- PAD391 " 973 (BC_2, *, controlr, 1)," & " 974 (BC_2, IO_M14, output3, X, 973, 1, Z)," & -- PAD390 " 975 (BC_2, IO_M14, input, X)," & -- PAD390 " 976 (BC_2, *, controlr, 1)," & " 977 (BC_2, IO_L11, output3, X, 976, 1, Z)," & -- PAD389 " 978 (BC_2, IO_L11, input, X)," & -- PAD389 " 979 (BC_2, *, controlr, 1)," & " 980 (BC_2, IO_L12, output3, X, 979, 1, Z)," & -- PAD388 " 981 (BC_2, IO_L12, input, X)," & -- PAD388 " 982 (BC_2, *, controlr, 1)," & " 983 (BC_2, IO_L15, output3, X, 982, 1, Z)," & -- PAD387 " 984 (BC_2, IO_L15, input, X)," & -- PAD387 " 985 (BC_2, *, controlr, 1)," & " 986 (BC_2, IO_L16, output3, X, 985, 1, Z)," & -- PAD386 " 987 (BC_2, IO_L16, input, X)," & -- PAD386 " 988 (BC_2, *, controlr, 1)," & " 989 (BC_2, IO_K13, output3, X, 988, 1, Z)," & -- PAD385 " 990 (BC_2, IO_K13, input, X)," & -- PAD385 " 991 (BC_2, *, controlr, 1)," & " 992 (BC_2, IO_K14, output3, X, 991, 1, Z)," & -- PAD384 " 993 (BC_2, IO_K14, input, X)," & -- PAD384 " 994 (BC_2, *, controlr, 1)," & " 995 (BC_2, IO_J15, output3, X, 994, 1, Z)," & -- PAD383 " 996 (BC_2, IO_J15, input, X)," & -- PAD383 " 997 (BC_2, *, controlr, 1)," & " 998 (BC_2, IO_K15, output3, X, 997, 1, Z)," & -- PAD382 " 999 (BC_2, IO_K15, input, X)," & -- PAD382 "1000 (BC_2, *, controlr, 1)," & "1001 (BC_2, IO_J12, output3, X, 1000, 1, Z)," & -- PAD381 "1002 (BC_2, IO_J12, input, X)," & -- PAD381 "1003 (BC_2, *, controlr, 1)," & "1004 (BC_2, IO_K12, output3, X, 1003, 1, Z)," & -- PAD380 "1005 (BC_2, IO_K12, input, X)," & -- PAD380 "1006 (BC_2, *, controlr, 1)," & "1007 (BC_2, IO_H13, output3, X, 1006, 1, Z)," & -- PAD379 "1008 (BC_2, IO_H13, input, X)," & -- PAD379 "1009 (BC_2, *, controlr, 1)," & "1010 (BC_2, IO_J13, output3, X, 1009, 1, Z)," & -- PAD378 "1011 (BC_2, IO_J13, input, X)," & -- PAD378 "1012 (BC_2, *, controlr, 1)," & "1013 (BC_2, IO_H14, output3, X, 1012, 1, Z)," & -- PAD377 "1014 (BC_2, IO_H14, input, X)," & -- PAD377 "1015 (BC_2, *, controlr, 1)," & "1016 (BC_2, IO_H15, output3, X, 1015, 1, Z)," & -- PAD376 "1017 (BC_2, IO_H15, input, X)," & -- PAD376 "1018 (BC_2, *, controlr, 1)," & "1019 (BC_2, IO_G13, output3, X, 1018, 1, Z)," & -- PAD375 "1020 (BC_2, IO_G13, input, X)," & -- PAD375 "1021 (BC_2, *, controlr, 1)," & "1022 (BC_2, IO_G14, output3, X, 1021, 1, Z)," & -- PAD374 "1023 (BC_2, IO_G14, input, X)," & -- PAD374 "1024 (BC_2, *, controlr, 1)," & "1025 (BC_2, IO_F14, output3, X, 1024, 1, Z)," & -- PAD373 "1026 (BC_2, IO_F14, input, X)," & -- PAD373 "1027 (BC_2, *, controlr, 1)," & "1028 (BC_2, IO_F15, output3, X, 1027, 1, Z)," & -- PAD372 "1029 (BC_2, IO_F15, input, X)," & -- PAD372 "1030 (BC_2, *, controlr, 1)," & "1031 (BC_2, IO_F12, output3, X, 1030, 1, Z)," & -- PAD371 "1032 (BC_2, IO_F12, input, X)," & -- PAD371 "1033 (BC_2, *, controlr, 1)," & "1034 (BC_2, IO_G12, output3, X, 1033, 1, Z)," & -- PAD370 "1035 (BC_2, IO_G12, input, X)," & -- PAD370 "1036 (BC_2, *, controlr, 1)," & "1037 (BC_2, IO_G16, output3, X, 1036, 1, Z)," & -- PAD369 "1038 (BC_2, IO_G16, input, X)," & -- PAD369 "1039 (BC_2, *, controlr, 1)," & "1040 (BC_2, IO_H16, output3, X, 1039, 1, Z)," & -- PAD368 "1041 (BC_2, IO_H16, input, X)," & -- PAD368 "1042 (BC_2, *, controlr, 1)," & "1043 (BC_2, IO_E13, output3, X, 1042, 1, Z)," & -- PAD367 "1044 (BC_2, IO_E13, input, X)," & -- PAD367 "1045 (BC_2, *, controlr, 1)," & "1046 (BC_2, IO_E14, output3, X, 1045, 1, Z)," & -- PAD366 "1047 (BC_2, IO_E14, input, X)," & -- PAD366 "1048 (BC_2, *, controlr, 1)," & "1049 (BC_2, IO_E15, output3, X, 1048, 1, Z)," & -- PAD365 "1050 (BC_2, IO_E15, input, X)," & -- PAD365 "1051 (BC_2, *, controlr, 1)," & "1052 (BC_2, IO_F16, output3, X, 1051, 1, Z)," & -- PAD364 "1053 (BC_2, IO_F16, input, X)," & -- PAD364 "1054 (BC_2, *, controlr, 1)," & "1055 (BC_2, IO_D12, output3, X, 1054, 1, Z)," & -- PAD363 "1056 (BC_2, IO_D12, input, X)," & -- PAD363 "1057 (BC_2, *, controlr, 1)," & "1058 (BC_2, IO_E12, output3, X, 1057, 1, Z)," & -- PAD362 "1059 (BC_2, IO_E12, input, X)," & -- PAD362 "1060 (BC_2, *, controlr, 1)," & "1061 (BC_2, IO_D15, output3, X, 1060, 1, Z)," & -- PAD361 "1062 (BC_2, IO_D15, input, X)," & -- PAD361 "1063 (BC_2, *, controlr, 1)," & "1064 (BC_2, IO_D16, output3, X, 1063, 1, Z)," & -- PAD360 "1065 (BC_2, IO_D16, input, X)," & -- PAD360 "1066 (BC_2, *, controlr, 1)," & "1067 (BC_2, IO_C13, output3, X, 1066, 1, Z)," & -- PAD359 "1068 (BC_2, IO_C13, input, X)," & -- PAD359 "1069 (BC_2, *, controlr, 1)," & "1070 (BC_2, IO_D13, output3, X, 1069, 1, Z)," & -- PAD358 "1071 (BC_2, IO_D13, input, X)," & -- PAD358 "1072 (BC_2, *, controlr, 1)," & "1073 (BC_2, IO_C14, output3, X, 1072, 1, Z)," & -- PAD357 "1074 (BC_2, IO_C14, input, X)," & -- PAD357 "1075 (BC_2, *, controlr, 1)," & "1076 (BC_2, IO_C15, output3, X, 1075, 1, Z)," & -- PAD356 "1077 (BC_2, IO_C15, input, X)," & -- PAD356 "1078 (BC_2, *, controlr, 1)," & "1079 (BC_2, IO_A14, output3, X, 1078, 1, Z)," & -- PAD355 "1080 (BC_2, IO_A14, input, X)," & -- PAD355 "1081 (BC_2, *, controlr, 1)," & "1082 (BC_2, IO_B14, output3, X, 1081, 1, Z)," & -- PAD354 "1083 (BC_2, IO_B14, input, X)," & -- PAD354 "1084 (BC_2, *, controlr, 1)," & "1085 (BC_2, IO_B16, output3, X, 1084, 1, Z)," & -- PAD353 "1086 (BC_2, IO_B16, input, X)," & -- PAD353 "1087 (BC_2, *, controlr, 1)," & "1088 (BC_2, IO_C16, output3, X, 1087, 1, Z)," & -- PAD352 "1089 (BC_2, IO_C16, input, X)," & -- PAD352 "1090 (BC_2, *, controlr, 1)," & "1091 (BC_2, IO_J16, output3, X, 1090, 1, Z)," & -- PAD351 "1092 (BC_2, IO_J16, input, X)," & -- PAD351 "1093 (BC_2, *, internal, X)," & "1094 (BC_2, *, internal, X)," & "1095 (BC_2, *, internal, X)," & "1096 (BC_2, *, internal, X)," & "1097 (BC_2, *, internal, X)," & "1098 (BC_2, *, internal, X)," & "1099 (BC_2, *, internal, X)," & "1100 (BC_2, *, internal, X)," & "1101 (BC_2, *, internal, X)," & "1102 (BC_2, *, internal, X)," & "1103 (BC_2, *, internal, X)," & "1104 (BC_2, *, internal, X)," & "1105 (BC_2, *, internal, X)," & "1106 (BC_2, *, internal, X)," & "1107 (BC_2, *, internal, X)," & "1108 (BC_2, *, internal, X)," & "1109 (BC_4, MGTXRXN0_113, OBSERVE_ONLY, X)," & "1110 (BC_4, MGTXRXP0_113, OBSERVE_ONLY, X)," & "1111 (AC_2, MGTXTXP0_113, OUTPUT2, X)," & "1112 (BC_4, MGTXRXN1_113, OBSERVE_ONLY, X)," & "1113 (BC_4, MGTXRXP1_113, OBSERVE_ONLY, X)," & "1114 (AC_2, MGTXTXP1_113, OUTPUT2, X)," & "1115 (BC_4, MGTXRXN2_113, OBSERVE_ONLY, X)," & "1116 (BC_4, MGTXRXP2_113, OBSERVE_ONLY, X)," & "1117 (AC_2, MGTXTXP2_113, OUTPUT2, X)," & "1118 (BC_4, MGTXRXN3_113, OBSERVE_ONLY, X)," & "1119 (BC_4, MGTXRXP3_113, OBSERVE_ONLY, X)," & "1120 (AC_2, MGTXTXP3_113, OUTPUT2, X)," & "1121 (BC_4, MGTXRXN0_114, OBSERVE_ONLY, X)," & "1122 (BC_4, MGTXRXP0_114, OBSERVE_ONLY, X)," & "1123 (AC_2, MGTXTXP0_114, OUTPUT2, X)," & "1124 (BC_4, MGTXRXN1_114, OBSERVE_ONLY, X)," & "1125 (BC_4, MGTXRXP1_114, OBSERVE_ONLY, X)," & "1126 (AC_2, MGTXTXP1_114, OUTPUT2, X)," & "1127 (BC_4, MGTXRXN2_114, OBSERVE_ONLY, X)," & "1128 (BC_4, MGTXRXP2_114, OBSERVE_ONLY, X)," & "1129 (AC_2, MGTXTXP2_114, OUTPUT2, X)," & "1130 (BC_4, MGTXRXN3_114, OBSERVE_ONLY, X)," & "1131 (BC_4, MGTXRXP3_114, OBSERVE_ONLY, X)," & "1132 (AC_2, MGTXTXP3_114, OUTPUT2, X)," & "1133 (BC_4, MGTXRXN0_115, OBSERVE_ONLY, X)," & "1134 (BC_4, MGTXRXP0_115, OBSERVE_ONLY, X)," & "1135 (AC_2, MGTXTXP0_115, OUTPUT2, X)," & "1136 (BC_4, MGTXRXN1_115, OBSERVE_ONLY, X)," & "1137 (BC_4, MGTXRXP1_115, OBSERVE_ONLY, X)," & "1138 (AC_2, MGTXTXP1_115, OUTPUT2, X)," & "1139 (BC_4, MGTXRXN2_115, OBSERVE_ONLY, X)," & "1140 (BC_4, MGTXRXP2_115, OBSERVE_ONLY, X)," & "1141 (AC_2, MGTXTXP2_115, OUTPUT2, X)," & "1142 (BC_4, MGTXRXN3_115, OBSERVE_ONLY, X)," & "1143 (BC_4, MGTXRXP3_115, OBSERVE_ONLY, X)," & "1144 (AC_2, MGTXTXP3_115, OUTPUT2, X)," & "1145 (BC_4, MGTXRXN0_116, OBSERVE_ONLY, X)," & "1146 (BC_4, MGTXRXP0_116, OBSERVE_ONLY, X)," & "1147 (AC_2, MGTXTXP0_116, OUTPUT2, X)," & "1148 (BC_4, MGTXRXN1_116, OBSERVE_ONLY, X)," & "1149 (BC_4, MGTXRXP1_116, OBSERVE_ONLY, X)," & "1150 (AC_2, MGTXTXP1_116, OUTPUT2, X)," & "1151 (BC_4, MGTXRXN2_116, OBSERVE_ONLY, X)," & "1152 (BC_4, MGTXRXP2_116, OBSERVE_ONLY, X)," & "1153 (AC_2, MGTXTXP2_116, OUTPUT2, X)," & "1154 (BC_4, MGTXRXN3_116, OBSERVE_ONLY, X)," & "1155 (BC_4, MGTXRXP3_116, OBSERVE_ONLY, X)," & "1156 (AC_2, MGTXTXP3_116, OUTPUT2, X)," & "1157 (BC_4, MGTXRXN0_117, OBSERVE_ONLY, X)," & "1158 (BC_4, MGTXRXP0_117, OBSERVE_ONLY, X)," & "1159 (AC_2, MGTXTXP0_117, OUTPUT2, X)," & "1160 (BC_4, MGTXRXN1_117, OBSERVE_ONLY, X)," & "1161 (BC_4, MGTXRXP1_117, OBSERVE_ONLY, X)," & "1162 (AC_2, MGTXTXP1_117, OUTPUT2, X)," & "1163 (BC_4, MGTXRXN2_117, OBSERVE_ONLY, X)," & "1164 (BC_4, MGTXRXP2_117, OBSERVE_ONLY, X)," & "1165 (AC_2, MGTXTXP2_117, OUTPUT2, X)," & "1166 (BC_4, MGTXRXN3_117, OBSERVE_ONLY, X)," & "1167 (BC_4, MGTXRXP3_117, OBSERVE_ONLY, X)," & "1168 (AC_2, MGTXTXP3_117, OUTPUT2, X)," & "1169 (BC_4, MGTXRXN0_118, OBSERVE_ONLY, X)," & "1170 (BC_4, MGTXRXP0_118, OBSERVE_ONLY, X)," & "1171 (AC_2, MGTXTXP0_118, OUTPUT2, X)," & "1172 (BC_4, MGTXRXN1_118, OBSERVE_ONLY, X)," & "1173 (BC_4, MGTXRXP1_118, OBSERVE_ONLY, X)," & "1174 (AC_2, MGTXTXP1_118, OUTPUT2, X)," & "1175 (BC_4, MGTXRXN2_118, OBSERVE_ONLY, X)," & "1176 (BC_4, MGTXRXP2_118, OBSERVE_ONLY, X)," & "1177 (AC_2, MGTXTXP2_118, OUTPUT2, X)," & "1178 (BC_4, MGTXRXN3_118, OBSERVE_ONLY, X)," & "1179 (BC_4, MGTXRXP3_118, OBSERVE_ONLY, X)," & "1180 (AC_2, MGTXTXP3_118, OUTPUT2, X)," & "1181 (BC_4, MGTXRXN0_119, OBSERVE_ONLY, X)," & "1182 (BC_4, MGTXRXP0_119, OBSERVE_ONLY, X)," & "1183 (AC_2, MGTXTXP0_119, OUTPUT2, X)," & "1184 (BC_4, MGTXRXN1_119, OBSERVE_ONLY, X)," & "1185 (BC_4, MGTXRXP1_119, OBSERVE_ONLY, X)," & "1186 (AC_2, MGTXTXP1_119, OUTPUT2, X)," & "1187 (BC_4, MGTXRXN2_119, OBSERVE_ONLY, X)," & "1188 (BC_4, MGTXRXP2_119, OBSERVE_ONLY, X)," & "1189 (AC_2, MGTXTXP2_119, OUTPUT2, X)," & "1190 (BC_4, MGTXRXN3_119, OBSERVE_ONLY, X)," & "1191 (BC_4, MGTXRXP3_119, OBSERVE_ONLY, X)," & "1192 (AC_2, MGTXTXP3_119, OUTPUT2, X)," & "1193 (BC_2, *, internal, X)," & "1194 (BC_2, *, internal, X)," & "1195 (BC_2, *, internal, X)," & "1196 (BC_2, *, internal, X)," & "1197 (BC_2, *, internal, X)," & "1198 (BC_2, *, internal, X)," & "1199 (BC_2, *, internal, X)," & "1200 (BC_2, *, internal, X)," & "1201 (BC_2, *, internal, X)," & "1202 (BC_2, *, internal, X)," & "1203 (BC_2, *, internal, X)," & "1204 (BC_2, *, internal, X)," & "1205 (BC_2, *, internal, X)," & "1206 (BC_2, *, internal, X)," & "1207 (BC_2, *, internal, X)," & "1208 (BC_2, *, internal, X)," & "1209 (BC_2, *, internal, X)," & "1210 (BC_2, *, internal, X)," & "1211 (BC_2, *, internal, X)," & "1212 (BC_2, *, internal, X)," & "1213 (BC_2, *, internal, X)," & "1214 (BC_2, *, internal, X)," & "1215 (BC_2, *, internal, X)," & "1216 (BC_2, *, internal, X)," & "1217 (BC_2, *, internal, X)," & "1218 (BC_2, *, internal, X)," & "1219 (BC_2, *, internal, X)," & "1220 (BC_2, *, internal, X)," & "1221 (BC_2, *, internal, X)," & "1222 (BC_2, *, internal, X)," & "1223 (BC_2, *, internal, X)," & "1224 (BC_2, *, internal, X)," & "1225 (BC_2, *, internal, X)," & "1226 (BC_2, *, internal, X)," & "1227 (BC_2, *, internal, X)," & "1228 (BC_2, *, internal, X)," & "1229 (BC_2, *, internal, X)," & "1230 (BC_2, *, controlr, 1)," & "1231 (BC_2, IO_AT31, output3, X, 1230, 1, Z)," & -- PAD350 "1232 (BC_2, IO_AT31, input, X)," & -- PAD350 "1233 (BC_2, *, controlr, 1)," & "1234 (BC_2, IO_AR33, output3, X, 1233, 1, Z)," & -- PAD349 "1235 (BC_2, IO_AR33, input, X)," & -- PAD349 "1236 (BC_2, *, controlr, 1)," & "1237 (BC_2, IO_AP33, output3, X, 1236, 1, Z)," & -- PAD348 "1238 (BC_2, IO_AP33, input, X)," & -- PAD348 "1239 (BC_2, *, controlr, 1)," & "1240 (BC_2, IO_AP31, output3, X, 1239, 1, Z)," & -- PAD347 "1241 (BC_2, IO_AP31, input, X)," & -- PAD347 "1242 (BC_2, *, controlr, 1)," & "1243 (BC_2, IO_AN31, output3, X, 1242, 1, Z)," & -- PAD346 "1244 (BC_2, IO_AN31, input, X)," & -- PAD346 "1245 (BC_2, *, controlr, 1)," & "1246 (BC_2, IO_AR32, output3, X, 1245, 1, Z)," & -- PAD345 "1247 (BC_2, IO_AR32, input, X)," & -- PAD345 "1248 (BC_2, *, controlr, 1)," & "1249 (BC_2, IO_AP32, output3, X, 1248, 1, Z)," & -- PAD344 "1250 (BC_2, IO_AP32, input, X)," & -- PAD344 "1251 (BC_2, *, controlr, 1)," & "1252 (BC_2, IO_AP30, output3, X, 1251, 1, Z)," & -- PAD343 "1253 (BC_2, IO_AP30, input, X)," & -- PAD343 "1254 (BC_2, *, controlr, 1)," & "1255 (BC_2, IO_AN30, output3, X, 1254, 1, Z)," & -- PAD342 "1256 (BC_2, IO_AN30, input, X)," & -- PAD342 "1257 (BC_2, *, controlr, 1)," & "1258 (BC_2, IO_AV31, output3, X, 1257, 1, Z)," & -- PAD341 "1259 (BC_2, IO_AV31, input, X)," & -- PAD341 "1260 (BC_2, *, controlr, 1)," & "1261 (BC_2, IO_AU31, output3, X, 1260, 1, Z)," & -- PAD340 "1262 (BC_2, IO_AU31, input, X)," & -- PAD340 "1263 (BC_2, *, controlr, 1)," & "1264 (BC_2, IO_AT30, output3, X, 1263, 1, Z)," & -- PAD339 "1265 (BC_2, IO_AT30, input, X)," & -- PAD339 "1266 (BC_2, *, controlr, 1)," & "1267 (BC_2, IO_AR30, output3, X, 1266, 1, Z)," & -- PAD338 "1268 (BC_2, IO_AR30, input, X)," & -- PAD338 "1269 (BC_2, *, controlr, 1)," & "1270 (BC_2, IO_AW31, output3, X, 1269, 1, Z)," & -- PAD337 "1271 (BC_2, IO_AW31, input, X)," & -- PAD337 "1272 (BC_2, *, controlr, 1)," & "1273 (BC_2, IO_AV30, output3, X, 1272, 1, Z)," & -- PAD336 "1274 (BC_2, IO_AV30, input, X)," & -- PAD336 "1275 (BC_2, *, controlr, 1)," & "1276 (BC_2, IO_BB31, output3, X, 1275, 1, Z)," & -- PAD335 "1277 (BC_2, IO_BB31, input, X)," & -- PAD335 "1278 (BC_2, *, controlr, 1)," & "1279 (BC_2, IO_BA30, output3, X, 1278, 1, Z)," & -- PAD334 "1280 (BC_2, IO_BA30, input, X)," & -- PAD334 "1281 (BC_2, *, controlr, 1)," & "1282 (BC_2, IO_AY30, output3, X, 1281, 1, Z)," & -- PAD333 "1283 (BC_2, IO_AY30, input, X)," & -- PAD333 "1284 (BC_2, *, controlr, 1)," & "1285 (BC_2, IO_AW30, output3, X, 1284, 1, Z)," & -- PAD332 "1286 (BC_2, IO_AW30, input, X)," & -- PAD332 "1287 (BC_2, *, controlr, 1)," & "1288 (BC_2, IO_BA32, output3, X, 1287, 1, Z)," & -- PAD331 "1289 (BC_2, IO_BA32, input, X)," & -- PAD331 "1290 (BC_2, *, controlr, 1)," & "1291 (BC_2, IO_BA31, output3, X, 1290, 1, Z)," & -- PAD330 "1292 (BC_2, IO_BA31, input, X)," & -- PAD330 "1293 (BC_2, *, controlr, 1)," & "1294 (BC_2, IO_AY33, output3, X, 1293, 1, Z)," & -- PAD329 "1295 (BC_2, IO_AY33, input, X)," & -- PAD329 "1296 (BC_2, *, controlr, 1)," & "1297 (BC_2, IO_AY32, output3, X, 1296, 1, Z)," & -- PAD328 "1298 (BC_2, IO_AY32, input, X)," & -- PAD328 "1299 (BC_2, *, controlr, 1)," & "1300 (BC_2, IO_AV35, output3, X, 1299, 1, Z)," & -- PAD327 "1301 (BC_2, IO_AV35, input, X)," & -- PAD327 "1302 (BC_2, *, controlr, 1)," & "1303 (BC_2, IO_AV34, output3, X, 1302, 1, Z)," & -- PAD326 "1304 (BC_2, IO_AV34, input, X)," & -- PAD326 "1305 (BC_2, *, controlr, 1)," & "1306 (BC_2, IO_AW33, output3, X, 1305, 1, Z)," & -- PAD325 "1307 (BC_2, IO_AW33, input, X)," & -- PAD325 "1308 (BC_2, *, controlr, 1)," & "1309 (BC_2, IO_AW32, output3, X, 1308, 1, Z)," & -- PAD324 "1310 (BC_2, IO_AW32, input, X)," & -- PAD324 "1311 (BC_2, *, controlr, 1)," & "1312 (BC_2, IO_AV33, output3, X, 1311, 1, Z)," & -- PAD323 "1313 (BC_2, IO_AV33, input, X)," & -- PAD323 "1314 (BC_2, *, controlr, 1)," & "1315 (BC_2, IO_AU32, output3, X, 1314, 1, Z)," & -- PAD322 "1316 (BC_2, IO_AU32, input, X)," & -- PAD322 "1317 (BC_2, *, controlr, 1)," & "1318 (BC_2, IO_AT35, output3, X, 1317, 1, Z)," & -- PAD321 "1319 (BC_2, IO_AT35, input, X)," & -- PAD321 "1320 (BC_2, *, controlr, 1)," & "1321 (BC_2, IO_AR34, output3, X, 1320, 1, Z)," & -- PAD320 "1322 (BC_2, IO_AR34, input, X)," & -- PAD320 "1323 (BC_2, *, controlr, 1)," & "1324 (BC_2, IO_AU33, output3, X, 1323, 1, Z)," & -- PAD319 "1325 (BC_2, IO_AU33, input, X)," & -- PAD319 "1326 (BC_2, *, controlr, 1)," & "1327 (BC_2, IO_AT32, output3, X, 1326, 1, Z)," & -- PAD318 "1328 (BC_2, IO_AT32, input, X)," & -- PAD318 "1329 (BC_2, *, controlr, 1)," & "1330 (BC_2, IO_AU36, output3, X, 1329, 1, Z)," & -- PAD317 "1331 (BC_2, IO_AU36, input, X)," & -- PAD317 "1332 (BC_2, *, controlr, 1)," & "1333 (BC_2, IO_AT36, output3, X, 1332, 1, Z)," & -- PAD316 "1334 (BC_2, IO_AT36, input, X)," & -- PAD316 "1335 (BC_2, *, controlr, 1)," & "1336 (BC_2, IO_AU34, output3, X, 1335, 1, Z)," & -- PAD315 "1337 (BC_2, IO_AU34, input, X)," & -- PAD315 "1338 (BC_2, *, controlr, 1)," & "1339 (BC_2, IO_AT34, output3, X, 1338, 1, Z)," & -- PAD314 "1340 (BC_2, IO_AT34, input, X)," & -- PAD314 "1341 (BC_2, *, controlr, 1)," & "1342 (BC_2, IO_AY35, output3, X, 1341, 1, Z)," & -- PAD313 "1343 (BC_2, IO_AY35, input, X)," & -- PAD313 "1344 (BC_2, *, controlr, 1)," & "1345 (BC_2, IO_AW35, output3, X, 1344, 1, Z)," & -- PAD312 "1346 (BC_2, IO_AW35, input, X)," & -- PAD312 "1347 (BC_2, *, controlr, 1)," & "1348 (BC_2, IO_BB33, output3, X, 1347, 1, Z)," & -- PAD311 "1349 (BC_2, IO_BB33, input, X)," & -- PAD311 "1350 (BC_2, *, controlr, 1)," & "1351 (BC_2, IO_BB32, output3, X, 1350, 1, Z)," & -- PAD310 "1352 (BC_2, IO_BB32, input, X)," & -- PAD310 "1353 (BC_2, *, controlr, 1)," & "1354 (BC_2, IO_BB36, output3, X, 1353, 1, Z)," & -- PAD309 "1355 (BC_2, IO_BB36, input, X)," & -- PAD309 "1356 (BC_2, *, controlr, 1)," & "1357 (BC_2, IO_BA36, output3, X, 1356, 1, Z)," & -- PAD308 "1358 (BC_2, IO_BA36, input, X)," & -- PAD308 "1359 (BC_2, *, controlr, 1)," & "1360 (BC_2, IO_BB34, output3, X, 1359, 1, Z)," & -- PAD307 "1361 (BC_2, IO_BB34, input, X)," & -- PAD307 "1362 (BC_2, *, controlr, 1)," & "1363 (BC_2, IO_BA34, output3, X, 1362, 1, Z)," & -- PAD306 "1364 (BC_2, IO_BA34, input, X)," & -- PAD306 "1365 (BC_2, *, controlr, 1)," & "1366 (BC_2, IO_AW36, output3, X, 1365, 1, Z)," & -- PAD305 "1367 (BC_2, IO_AW36, input, X)," & -- PAD305 "1368 (BC_2, *, controlr, 1)," & "1369 (BC_2, IO_AV36, output3, X, 1368, 1, Z)," & -- PAD304 "1370 (BC_2, IO_AV36, input, X)," & -- PAD304 "1371 (BC_2, *, controlr, 1)," & "1372 (BC_2, IO_BA35, output3, X, 1371, 1, Z)," & -- PAD303 "1373 (BC_2, IO_BA35, input, X)," & -- PAD303 "1374 (BC_2, *, controlr, 1)," & "1375 (BC_2, IO_AY34, output3, X, 1374, 1, Z)," & -- PAD302 "1376 (BC_2, IO_AY34, input, X)," & -- PAD302 "1377 (BC_2, *, controlr, 1)," & "1378 (BC_2, IO_AR35, output3, X, 1377, 1, Z)," & -- PAD301 "1379 (BC_2, IO_AR35, input, X)," & -- PAD301 "1380 (BC_2, *, controlr, 1)," & "1381 (BC_2, IO_AG32, output3, X, 1380, 1, Z)," & -- PAD300 "1382 (BC_2, IO_AG32, input, X)," & -- PAD300 "1383 (BC_2, *, controlr, 1)," & "1384 (BC_2, IO_AJ28, output3, X, 1383, 1, Z)," & -- PAD299 "1385 (BC_2, IO_AJ28, input, X)," & -- PAD299 "1386 (BC_2, *, controlr, 1)," & "1387 (BC_2, IO_AH28, output3, X, 1386, 1, Z)," & -- PAD298 "1388 (BC_2, IO_AH28, input, X)," & -- PAD298 "1389 (BC_2, *, controlr, 1)," & "1390 (BC_2, IO_AG31, output3, X, 1389, 1, Z)," & -- PAD297 "1391 (BC_2, IO_AG31, input, X)," & -- PAD297 "1392 (BC_2, *, controlr, 1)," & "1393 (BC_2, IO_AF30, output3, X, 1392, 1, Z)," & -- PAD296 "1394 (BC_2, IO_AF30, input, X)," & -- PAD296 "1395 (BC_2, *, controlr, 1)," & "1396 (BC_2, IO_AK29, output3, X, 1395, 1, Z)," & -- PAD295 "1397 (BC_2, IO_AK29, input, X)," & -- PAD295 "1398 (BC_2, *, controlr, 1)," & "1399 (BC_2, IO_AK28, output3, X, 1398, 1, Z)," & -- PAD294 "1400 (BC_2, IO_AK28, input, X)," & -- PAD294 "1401 (BC_2, *, controlr, 1)," & "1402 (BC_2, IO_AG29, output3, X, 1401, 1, Z)," & -- PAD293 "1403 (BC_2, IO_AG29, input, X)," & -- PAD293 "1404 (BC_2, *, controlr, 1)," & "1405 (BC_2, IO_AF29, output3, X, 1404, 1, Z)," & -- PAD292 "1406 (BC_2, IO_AF29, input, X)," & -- PAD292 "1407 (BC_2, *, controlr, 1)," & "1408 (BC_2, IO_AK30, output3, X, 1407, 1, Z)," & -- PAD291 "1409 (BC_2, IO_AK30, input, X)," & -- PAD291 "1410 (BC_2, *, controlr, 1)," & "1411 (BC_2, IO_AJ30, output3, X, 1410, 1, Z)," & -- PAD290 "1412 (BC_2, IO_AJ30, input, X)," & -- PAD290 "1413 (BC_2, *, controlr, 1)," & "1414 (BC_2, IO_AH30, output3, X, 1413, 1, Z)," & -- PAD289 "1415 (BC_2, IO_AH30, input, X)," & -- PAD289 "1416 (BC_2, *, controlr, 1)," & "1417 (BC_2, IO_AH29, output3, X, 1416, 1, Z)," & -- PAD288 "1418 (BC_2, IO_AH29, input, X)," & -- PAD288 "1419 (BC_2, *, controlr, 1)," & "1420 (BC_2, IO_AL30, output3, X, 1419, 1, Z)," & -- PAD287 "1421 (BC_2, IO_AL30, input, X)," & -- PAD287 "1422 (BC_2, *, controlr, 1)," & "1423 (BC_2, IO_AL29, output3, X, 1422, 1, Z)," & -- PAD286 "1424 (BC_2, IO_AL29, input, X)," & -- PAD286 "1425 (BC_2, *, controlr, 1)," & "1426 (BC_2, IO_AN33, output3, X, 1425, 1, Z)," & -- PAD285 "1427 (BC_2, IO_AN33, input, X)," & -- PAD285 "1428 (BC_2, *, controlr, 1)," & "1429 (BC_2, IO_AM33, output3, X, 1428, 1, Z)," & -- PAD284 "1430 (BC_2, IO_AM33, input, X)," & -- PAD284 "1431 (BC_2, *, controlr, 1)," & "1432 (BC_2, IO_AM32, output3, X, 1431, 1, Z)," & -- PAD283 "1433 (BC_2, IO_AM32, input, X)," & -- PAD283 "1434 (BC_2, *, controlr, 1)," & "1435 (BC_2, IO_AM31, output3, X, 1434, 1, Z)," & -- PAD282 "1436 (BC_2, IO_AM31, input, X)," & -- PAD282 "1437 (BC_2, *, controlr, 1)," & "1438 (BC_2, IO_AN34, output3, X, 1437, 1, Z)," & -- PAD281 "1439 (BC_2, IO_AN34, input, X)," & -- PAD281 "1440 (BC_2, *, controlr, 1)," & "1441 (BC_2, IO_AM34, output3, X, 1440, 1, Z)," & -- PAD280 "1442 (BC_2, IO_AM34, input, X)," & -- PAD280 "1443 (BC_2, *, controlr, 1)," & "1444 (BC_2, IO_AL32, output3, X, 1443, 1, Z)," & -- PAD279 "1445 (BC_2, IO_AL32, input, X)," & -- PAD279 "1446 (BC_2, *, controlr, 1)," & "1447 (BC_2, IO_AL31, output3, X, 1446, 1, Z)," & -- PAD278 "1448 (BC_2, IO_AL31, input, X)," & -- PAD278 "1449 (BC_2, *, controlr, 1)," & "1450 (BC_2, IO_AK32, output3, X, 1449, 1, Z)," & -- PAD277 "1451 (BC_2, IO_AK32, input, X)," & -- PAD277 "1452 (BC_2, *, controlr, 1)," & "1453 (BC_2, IO_AJ32, output3, X, 1452, 1, Z)," & -- PAD276 "1454 (BC_2, IO_AJ32, input, X)," & -- PAD276 "1455 (BC_2, *, controlr, 1)," & "1456 (BC_2, IO_AL34, output3, X, 1455, 1, Z)," & -- PAD275 "1457 (BC_2, IO_AL34, input, X)," & -- PAD275 "1458 (BC_2, *, controlr, 1)," & "1459 (BC_2, IO_AK34, output3, X, 1458, 1, Z)," & -- PAD274 "1460 (BC_2, IO_AK34, input, X)," & -- PAD274 "1461 (BC_2, *, controlr, 1)," & "1462 (BC_2, IO_AK33, output3, X, 1461, 1, Z)," & -- PAD273 "1463 (BC_2, IO_AK33, input, X)," & -- PAD273 "1464 (BC_2, *, controlr, 1)," & "1465 (BC_2, IO_AJ33, output3, X, 1464, 1, Z)," & -- PAD272 "1466 (BC_2, IO_AJ33, input, X)," & -- PAD272 "1467 (BC_2, *, controlr, 1)," & "1468 (BC_2, IO_AJ35, output3, X, 1467, 1, Z)," & -- PAD271 "1469 (BC_2, IO_AJ35, input, X)," & -- PAD271 "1470 (BC_2, *, controlr, 1)," & "1471 (BC_2, IO_AH34, output3, X, 1470, 1, Z)," & -- PAD270 "1472 (BC_2, IO_AH34, input, X)," & -- PAD270 "1473 (BC_2, *, controlr, 1)," & "1474 (BC_2, IO_AJ31, output3, X, 1473, 1, Z)," & -- PAD269 "1475 (BC_2, IO_AJ31, input, X)," & -- PAD269 "1476 (BC_2, *, controlr, 1)," & "1477 (BC_2, IO_AH31, output3, X, 1476, 1, Z)," & -- PAD268 "1478 (BC_2, IO_AH31, input, X)," & -- PAD268 "1479 (BC_2, *, controlr, 1)," & "1480 (BC_2, IO_AL35, output3, X, 1479, 1, Z)," & -- PAD267 "1481 (BC_2, IO_AL35, input, X)," & -- PAD267 "1482 (BC_2, *, controlr, 1)," & "1483 (BC_2, IO_AK35, output3, X, 1482, 1, Z)," & -- PAD266 "1484 (BC_2, IO_AK35, input, X)," & -- PAD266 "1485 (BC_2, *, controlr, 1)," & "1486 (BC_2, IO_AH33, output3, X, 1485, 1, Z)," & -- PAD265 "1487 (BC_2, IO_AH33, input, X)," & -- PAD265 "1488 (BC_2, *, controlr, 1)," & "1489 (BC_2, IO_AG33, output3, X, 1488, 1, Z)," & -- PAD264 "1490 (BC_2, IO_AG33, input, X)," & -- PAD264 "1491 (BC_2, *, controlr, 1)," & "1492 (BC_2, IO_AM37, output3, X, 1491, 1, Z)," & -- PAD263 "1493 (BC_2, IO_AM37, input, X)," & -- PAD263 "1494 (BC_2, *, controlr, 1)," & "1495 (BC_2, IO_AL36, output3, X, 1494, 1, Z)," & -- PAD262 "1496 (BC_2, IO_AL36, input, X)," & -- PAD262 "1497 (BC_2, *, controlr, 1)," & "1498 (BC_2, IO_AP35, output3, X, 1497, 1, Z)," & -- PAD261 "1499 (BC_2, IO_AP35, input, X)," & -- PAD261 "1500 (BC_2, *, controlr, 1)," & "1501 (BC_2, IO_AN35, output3, X, 1500, 1, Z)," & -- PAD260 "1502 (BC_2, IO_AN35, input, X)," & -- PAD260 "1503 (BC_2, *, controlr, 1)," & "1504 (BC_2, IO_AL37, output3, X, 1503, 1, Z)," & -- PAD259 "1505 (BC_2, IO_AL37, input, X)," & -- PAD259 "1506 (BC_2, *, controlr, 1)," & "1507 (BC_2, IO_AK37, output3, X, 1506, 1, Z)," & -- PAD258 "1508 (BC_2, IO_AK37, input, X)," & -- PAD258 "1509 (BC_2, *, controlr, 1)," & "1510 (BC_2, IO_AP37, output3, X, 1509, 1, Z)," & -- PAD257 "1511 (BC_2, IO_AP37, input, X)," & -- PAD257 "1512 (BC_2, *, controlr, 1)," & "1513 (BC_2, IO_AP36, output3, X, 1512, 1, Z)," & -- PAD256 "1514 (BC_2, IO_AP36, input, X)," & -- PAD256 "1515 (BC_2, *, controlr, 1)," & "1516 (BC_2, IO_AJ37, output3, X, 1515, 1, Z)," & -- PAD255 "1517 (BC_2, IO_AJ37, input, X)," & -- PAD255 "1518 (BC_2, *, controlr, 1)," & "1519 (BC_2, IO_AJ36, output3, X, 1518, 1, Z)," & -- PAD254 "1520 (BC_2, IO_AJ36, input, X)," & -- PAD254 "1521 (BC_2, *, controlr, 1)," & "1522 (BC_2, IO_AN36, output3, X, 1521, 1, Z)," & -- PAD253 "1523 (BC_2, IO_AN36, input, X)," & -- PAD253 "1524 (BC_2, *, controlr, 1)," & "1525 (BC_2, IO_AM36, output3, X, 1524, 1, Z)," & -- PAD252 "1526 (BC_2, IO_AM36, input, X)," & -- PAD252 "1527 (BC_2, *, controlr, 1)," & "1528 (BC_2, IO_AH35, output3, X, 1527, 1, Z)," & -- PAD251 "1529 (BC_2, IO_AH35, input, X)," & -- PAD251 "1530 (BC_2, *, controlr, 1)," & "1531 (BC_2, IO_AU37, output3, X, 1530, 1, Z)," & -- PAD250 "1532 (BC_2, IO_AU37, input, X)," & -- PAD250 "1533 (BC_2, *, controlr, 1)," & "1534 (BC_2, IO_AW42, output3, X, 1533, 1, Z)," & -- PAD249 "1535 (BC_2, IO_AW42, input, X)," & -- PAD249 "1536 (BC_2, *, controlr, 1)," & "1537 (BC_2, IO_AW41, output3, X, 1536, 1, Z)," & -- PAD248 "1538 (BC_2, IO_AW41, input, X)," & -- PAD248 "1539 (BC_2, *, controlr, 1)," & "1540 (BC_2, IO_BB41, output3, X, 1539, 1, Z)," & -- PAD247 "1541 (BC_2, IO_BB41, input, X)," & -- PAD247 "1542 (BC_2, *, controlr, 1)," & "1543 (BC_2, IO_BA41, output3, X, 1542, 1, Z)," & -- PAD246 "1544 (BC_2, IO_BA41, input, X)," & -- PAD246 "1545 (BC_2, *, controlr, 1)," & "1546 (BC_2, IO_AV41, output3, X, 1545, 1, Z)," & -- PAD245 "1547 (BC_2, IO_AV41, input, X)," & -- PAD245 "1548 (BC_2, *, controlr, 1)," & "1549 (BC_2, IO_AU41, output3, X, 1548, 1, Z)," & -- PAD244 "1550 (BC_2, IO_AU41, input, X)," & -- PAD244 "1551 (BC_2, *, controlr, 1)," & "1552 (BC_2, IO_BA42, output3, X, 1551, 1, Z)," & -- PAD243 "1553 (BC_2, IO_BA42, input, X)," & -- PAD243 "1554 (BC_2, *, controlr, 1)," & "1555 (BC_2, IO_AY42, output3, X, 1554, 1, Z)," & -- PAD242 "1556 (BC_2, IO_AY42, input, X)," & -- PAD242 "1557 (BC_2, *, controlr, 1)," & "1558 (BC_2, IO_AU42, output3, X, 1557, 1, Z)," & -- PAD241 "1559 (BC_2, IO_AU42, input, X)," & -- PAD241 "1560 (BC_2, *, controlr, 1)," & "1561 (BC_2, IO_AT41, output3, X, 1560, 1, Z)," & -- PAD240 "1562 (BC_2, IO_AT41, input, X)," & -- PAD240 "1563 (BC_2, *, controlr, 1)," & "1564 (BC_2, IO_BA40, output3, X, 1563, 1, Z)," & -- PAD239 "1565 (BC_2, IO_BA40, input, X)," & -- PAD239 "1566 (BC_2, *, controlr, 1)," & "1567 (BC_2, IO_BA39, output3, X, 1566, 1, Z)," & -- PAD238 "1568 (BC_2, IO_BA39, input, X)," & -- PAD238 "1569 (BC_2, *, controlr, 1)," & "1570 (BC_2, IO_BB39, output3, X, 1569, 1, Z)," & -- PAD237 "1571 (BC_2, IO_BB39, input, X)," & -- PAD237 "1572 (BC_2, *, controlr, 1)," & "1573 (BC_2, IO_BB38, output3, X, 1572, 1, Z)," & -- PAD236 "1574 (BC_2, IO_BB38, input, X)," & -- PAD236 "1575 (BC_2, *, controlr, 1)," & "1576 (BC_2, IO_AY38, output3, X, 1575, 1, Z)," & -- PAD235 "1577 (BC_2, IO_AY38, input, X)," & -- PAD235 "1578 (BC_2, *, controlr, 1)," & "1579 (BC_2, IO_AW38, output3, X, 1578, 1, Z)," & -- PAD234 "1580 (BC_2, IO_AW38, input, X)," & -- PAD234 "1581 (BC_2, *, controlr, 1)," & "1582 (BC_2, IO_BB37, output3, X, 1581, 1, Z)," & -- PAD233 "1583 (BC_2, IO_BB37, input, X)," & -- PAD233 "1584 (BC_2, *, controlr, 1)," & "1585 (BC_2, IO_BA37, output3, X, 1584, 1, Z)," & -- PAD232 "1586 (BC_2, IO_BA37, input, X)," & -- PAD232 "1587 (BC_2, *, controlr, 1)," & "1588 (BC_2, IO_AY37, output3, X, 1587, 1, Z)," & -- PAD231 "1589 (BC_2, IO_AY37, input, X)," & -- PAD231 "1590 (BC_2, *, controlr, 1)," & "1591 (BC_2, IO_AW37, output3, X, 1590, 1, Z)," & -- PAD230 "1592 (BC_2, IO_AW37, input, X)," & -- PAD230 "1593 (BC_2, *, controlr, 1)," & "1594 (BC_2, IO_AY40, output3, X, 1593, 1, Z)," & -- PAD229 "1595 (BC_2, IO_AY40, input, X)," & -- PAD229 "1596 (BC_2, *, controlr, 1)," & "1597 (BC_2, IO_AY39, output3, X, 1596, 1, Z)," & -- PAD228 "1598 (BC_2, IO_AY39, input, X)," & -- PAD228 "1599 (BC_2, *, controlr, 1)," & "1600 (BC_2, IO_AW40, output3, X, 1599, 1, Z)," & -- PAD227 "1601 (BC_2, IO_AW40, input, X)," & -- PAD227 "1602 (BC_2, *, controlr, 1)," & "1603 (BC_2, IO_AV40, output3, X, 1602, 1, Z)," & -- PAD226 "1604 (BC_2, IO_AV40, input, X)," & -- PAD226 "1605 (BC_2, *, controlr, 1)," & "1606 (BC_2, IO_AV38, output3, X, 1605, 1, Z)," & -- PAD225 "1607 (BC_2, IO_AV38, input, X)," & -- PAD225 "1608 (BC_2, *, controlr, 1)," & "1609 (BC_2, IO_AU38, output3, X, 1608, 1, Z)," & -- PAD224 "1610 (BC_2, IO_AU38, input, X)," & -- PAD224 "1611 (BC_2, *, controlr, 1)," & "1612 (BC_2, IO_AV39, output3, X, 1611, 1, Z)," & -- PAD223 "1613 (BC_2, IO_AV39, input, X)," & -- PAD223 "1614 (BC_2, *, controlr, 1)," & "1615 (BC_2, IO_AU39, output3, X, 1614, 1, Z)," & -- PAD222 "1616 (BC_2, IO_AU39, input, X)," & -- PAD222 "1617 (BC_2, *, controlr, 1)," & "1618 (BC_2, IO_AT42, output3, X, 1617, 1, Z)," & -- PAD221 "1619 (BC_2, IO_AT42, input, X)," & -- PAD221 "1620 (BC_2, *, controlr, 1)," & "1621 (BC_2, IO_AR42, output3, X, 1620, 1, Z)," & -- PAD220 "1622 (BC_2, IO_AR42, input, X)," & -- PAD220 "1623 (BC_2, *, controlr, 1)," & "1624 (BC_2, IO_AT40, output3, X, 1623, 1, Z)," & -- PAD219 "1625 (BC_2, IO_AT40, input, X)," & -- PAD219 "1626 (BC_2, *, controlr, 1)," & "1627 (BC_2, IO_AT39, output3, X, 1626, 1, Z)," & -- PAD218 "1628 (BC_2, IO_AT39, input, X)," & -- PAD218 "1629 (BC_2, *, controlr, 1)," & "1630 (BC_2, IO_AP42, output3, X, 1629, 1, Z)," & -- PAD217 "1631 (BC_2, IO_AP42, input, X)," & -- PAD217 "1632 (BC_2, *, controlr, 1)," & "1633 (BC_2, IO_AP41, output3, X, 1632, 1, Z)," & -- PAD216 "1634 (BC_2, IO_AP41, input, X)," & -- PAD216 "1635 (BC_2, *, controlr, 1)," & "1636 (BC_2, IO_AR40, output3, X, 1635, 1, Z)," & -- PAD215 "1637 (BC_2, IO_AR40, input, X)," & -- PAD215 "1638 (BC_2, *, controlr, 1)," & "1639 (BC_2, IO_AP40, output3, X, 1638, 1, Z)," & -- PAD214 "1640 (BC_2, IO_AP40, input, X)," & -- PAD214 "1641 (BC_2, *, controlr, 1)," & "1642 (BC_2, IO_AN39, output3, X, 1641, 1, Z)," & -- PAD213 "1643 (BC_2, IO_AN39, input, X)," & -- PAD213 "1644 (BC_2, *, controlr, 1)," & "1645 (BC_2, IO_AM39, output3, X, 1644, 1, Z)," & -- PAD212 "1646 (BC_2, IO_AM39, input, X)," & -- PAD212 "1647 (BC_2, *, controlr, 1)," & "1648 (BC_2, IO_AT37, output3, X, 1647, 1, Z)," & -- PAD211 "1649 (BC_2, IO_AT37, input, X)," & -- PAD211 "1650 (BC_2, *, controlr, 1)," & "1651 (BC_2, IO_AR37, output3, X, 1650, 1, Z)," & -- PAD210 "1652 (BC_2, IO_AR37, input, X)," & -- PAD210 "1653 (BC_2, *, controlr, 1)," & "1654 (BC_2, IO_AN41, output3, X, 1653, 1, Z)," & -- PAD209 "1655 (BC_2, IO_AN41, input, X)," & -- PAD209 "1656 (BC_2, *, controlr, 1)," & "1657 (BC_2, IO_AN40, output3, X, 1656, 1, Z)," & -- PAD208 "1658 (BC_2, IO_AN40, input, X)," & -- PAD208 "1659 (BC_2, *, controlr, 1)," & "1660 (BC_2, IO_AR39, output3, X, 1659, 1, Z)," & -- PAD207 "1661 (BC_2, IO_AR39, input, X)," & -- PAD207 "1662 (BC_2, *, controlr, 1)," & "1663 (BC_2, IO_AR38, output3, X, 1662, 1, Z)," & -- PAD206 "1664 (BC_2, IO_AR38, input, X)," & -- PAD206 "1665 (BC_2, *, controlr, 1)," & "1666 (BC_2, IO_AM42, output3, X, 1665, 1, Z)," & -- PAD205 "1667 (BC_2, IO_AM42, input, X)," & -- PAD205 "1668 (BC_2, *, controlr, 1)," & "1669 (BC_2, IO_AM41, output3, X, 1668, 1, Z)," & -- PAD204 "1670 (BC_2, IO_AM41, input, X)," & -- PAD204 "1671 (BC_2, *, controlr, 1)," & "1672 (BC_2, IO_AP38, output3, X, 1671, 1, Z)," & -- PAD203 "1673 (BC_2, IO_AP38, input, X)," & -- PAD203 "1674 (BC_2, *, controlr, 1)," & "1675 (BC_2, IO_AN38, output3, X, 1674, 1, Z)," & -- PAD202 "1676 (BC_2, IO_AN38, input, X)," & -- PAD202 "1677 (BC_2, *, controlr, 1)," & "1678 (BC_2, IO_AM38, output3, X, 1677, 1, Z)," & -- PAD201 "1679 (BC_2, IO_AM38, input, X)," & -- PAD201 "1680 (BC_2, *, controlr, 1)," & "1681 (BC_2, IO_AB34, output3, X, 1680, 1, Z)," & -- PAD200 "1682 (BC_2, IO_AB34, input, X)," & -- PAD200 "1683 (BC_2, *, controlr, 1)," & "1684 (BC_2, IO_AC29, output3, X, 1683, 1, Z)," & -- PAD199 "1685 (BC_2, IO_AC29, input, X)," & -- PAD199 "1686 (BC_2, *, controlr, 1)," & "1687 (BC_2, IO_AB29, output3, X, 1686, 1, Z)," & -- PAD198 "1688 (BC_2, IO_AB29, input, X)," & -- PAD198 "1689 (BC_2, *, controlr, 1)," & "1690 (BC_2, IO_AA30, output3, X, 1689, 1, Z)," & -- PAD197 "1691 (BC_2, IO_AA30, input, X)," & -- PAD197 "1692 (BC_2, *, controlr, 1)," & "1693 (BC_2, IO_AA29, output3, X, 1692, 1, Z)," & -- PAD196 "1694 (BC_2, IO_AA29, input, X)," & -- PAD196 "1695 (BC_2, *, controlr, 1)," & "1696 (BC_2, IO_AD30, output3, X, 1695, 1, Z)," & -- PAD195 "1697 (BC_2, IO_AD30, input, X)," & -- PAD195 "1698 (BC_2, *, controlr, 1)," & "1699 (BC_2, IO_AC30, output3, X, 1698, 1, Z)," & -- PAD194 "1700 (BC_2, IO_AC30, input, X)," & -- PAD194 "1701 (BC_2, *, controlr, 1)," & "1702 (BC_2, IO_AA32, output3, X, 1701, 1, Z)," & -- PAD193 "1703 (BC_2, IO_AA32, input, X)," & -- PAD193 "1704 (BC_2, *, controlr, 1)," & "1705 (BC_2, IO_AA31, output3, X, 1704, 1, Z)," & -- PAD192 "1706 (BC_2, IO_AA31, input, X)," & -- PAD192 "1707 (BC_2, *, controlr, 1)," & "1708 (BC_2, IO_AD31, output3, X, 1707, 1, Z)," & -- PAD191 "1709 (BC_2, IO_AD31, input, X)," & -- PAD191 "1710 (BC_2, *, controlr, 1)," & "1711 (BC_2, IO_AC31, output3, X, 1710, 1, Z)," & -- PAD190 "1712 (BC_2, IO_AC31, input, X)," & -- PAD190 "1713 (BC_2, *, controlr, 1)," & "1714 (BC_2, IO_Y33, output3, X, 1713, 1, Z)," & -- PAD189 "1715 (BC_2, IO_Y33, input, X)," & -- PAD189 "1716 (BC_2, *, controlr, 1)," & "1717 (BC_2, IO_Y32, output3, X, 1716, 1, Z)," & -- PAD188 "1718 (BC_2, IO_Y32, input, X)," & -- PAD188 "1719 (BC_2, *, controlr, 1)," & "1720 (BC_2, IO_AE30, output3, X, 1719, 1, Z)," & -- PAD187 "1721 (BC_2, IO_AE30, input, X)," & -- PAD187 "1722 (BC_2, *, controlr, 1)," & "1723 (BC_2, IO_AE29, output3, X, 1722, 1, Z)," & -- PAD186 "1724 (BC_2, IO_AE29, input, X)," & -- PAD186 "1725 (BC_2, *, controlr, 1)," & "1726 (BC_2, IO_AE35, output3, X, 1725, 1, Z)," & -- PAD185 "1727 (BC_2, IO_AE35, input, X)," & -- PAD185 "1728 (BC_2, *, controlr, 1)," & "1729 (BC_2, IO_AE34, output3, X, 1728, 1, Z)," & -- PAD184 "1730 (BC_2, IO_AE34, input, X)," & -- PAD184 "1731 (BC_2, *, controlr, 1)," & "1732 (BC_2, IO_AF32, output3, X, 1731, 1, Z)," & -- PAD183 "1733 (BC_2, IO_AF32, input, X)," & -- PAD183 "1734 (BC_2, *, controlr, 1)," & "1735 (BC_2, IO_AF31, output3, X, 1734, 1, Z)," & -- PAD182 "1736 (BC_2, IO_AF31, input, X)," & -- PAD182 "1737 (BC_2, *, controlr, 1)," & "1738 (BC_2, IO_AE33, output3, X, 1737, 1, Z)," & -- PAD181 "1739 (BC_2, IO_AE33, input, X)," & -- PAD181 "1740 (BC_2, *, controlr, 1)," & "1741 (BC_2, IO_AE32, output3, X, 1740, 1, Z)," & -- PAD180 "1742 (BC_2, IO_AE32, input, X)," & -- PAD180 "1743 (BC_2, *, controlr, 1)," & "1744 (BC_2, IO_AD35, output3, X, 1743, 1, Z)," & -- PAD179 "1745 (BC_2, IO_AD35, input, X)," & -- PAD179 "1746 (BC_2, *, controlr, 1)," & "1747 (BC_2, IO_AC34, output3, X, 1746, 1, Z)," & -- PAD178 "1748 (BC_2, IO_AC34, input, X)," & -- PAD178 "1749 (BC_2, *, controlr, 1)," & "1750 (BC_2, IO_AD33, output3, X, 1749, 1, Z)," & -- PAD177 "1751 (BC_2, IO_AD33, input, X)," & -- PAD177 "1752 (BC_2, *, controlr, 1)," & "1753 (BC_2, IO_AD32, output3, X, 1752, 1, Z)," & -- PAD176 "1754 (BC_2, IO_AD32, input, X)," & -- PAD176 "1755 (BC_2, *, controlr, 1)," & "1756 (BC_2, IO_AC33, output3, X, 1755, 1, Z)," & -- PAD175 "1757 (BC_2, IO_AC33, input, X)," & -- PAD175 "1758 (BC_2, *, controlr, 1)," & "1759 (BC_2, IO_AB33, output3, X, 1758, 1, Z)," & -- PAD174 "1760 (BC_2, IO_AB33, input, X)," & -- PAD174 "1761 (BC_2, *, controlr, 1)," & "1762 (BC_2, IO_AB32, output3, X, 1761, 1, Z)," & -- PAD173 "1763 (BC_2, IO_AB32, input, X)," & -- PAD173 "1764 (BC_2, *, controlr, 1)," & "1765 (BC_2, IO_AB31, output3, X, 1764, 1, Z)," & -- PAD172 "1766 (BC_2, IO_AB31, input, X)," & -- PAD172 "1767 (BC_2, *, controlr, 1)," & "1768 (BC_2, IO_AA35, output3, X, 1767, 1, Z)," & -- PAD171 "1769 (BC_2, IO_AA35, input, X)," & -- PAD171 "1770 (BC_2, *, controlr, 1)," & "1771 (BC_2, IO_AA34, output3, X, 1770, 1, Z)," & -- PAD170 "1772 (BC_2, IO_AA34, input, X)," & -- PAD170 "1773 (BC_2, *, controlr, 1)," & "1774 (BC_2, IO_AB37, output3, X, 1773, 1, Z)," & -- PAD169 "1775 (BC_2, IO_AB37, input, X)," & -- PAD169 "1776 (BC_2, *, controlr, 1)," & "1777 (BC_2, IO_AB36, output3, X, 1776, 1, Z)," & -- PAD168 "1778 (BC_2, IO_AB36, input, X)," & -- PAD168 "1779 (BC_2, *, controlr, 1)," & "1780 (BC_2, IO_AA36, output3, X, 1779, 1, Z)," & -- PAD167 "1781 (BC_2, IO_AA36, input, X)," & -- PAD167 "1782 (BC_2, *, controlr, 1)," & "1783 (BC_2, IO_Y35, output3, X, 1782, 1, Z)," & -- PAD166 "1784 (BC_2, IO_Y35, input, X)," & -- PAD166 "1785 (BC_2, *, controlr, 1)," & "1786 (BC_2, IO_AA37, output3, X, 1785, 1, Z)," & -- PAD165 "1787 (BC_2, IO_AA37, input, X)," & -- PAD165 "1788 (BC_2, *, controlr, 1)," & "1789 (BC_2, IO_Y37, output3, X, 1788, 1, Z)," & -- PAD164 "1790 (BC_2, IO_Y37, input, X)," & -- PAD164 "1791 (BC_2, *, controlr, 1)," & "1792 (BC_2, IO_AH36, output3, X, 1791, 1, Z)," & -- PAD163 "1793 (BC_2, IO_AH36, input, X)," & -- PAD163 "1794 (BC_2, *, controlr, 1)," & "1795 (BC_2, IO_AG36, output3, X, 1794, 1, Z)," & -- PAD162 "1796 (BC_2, IO_AG36, input, X)," & -- PAD162 "1797 (BC_2, *, controlr, 1)," & "1798 (BC_2, IO_AC36, output3, X, 1797, 1, Z)," & -- PAD161 "1799 (BC_2, IO_AC36, input, X)," & -- PAD161 "1800 (BC_2, *, controlr, 1)," & "1801 (BC_2, IO_AC35, output3, X, 1800, 1, Z)," & -- PAD160 "1802 (BC_2, IO_AC35, input, X)," & -- PAD160 "1803 (BC_2, *, controlr, 1)," & "1804 (BC_2, IO_AD37, output3, X, 1803, 1, Z)," & -- PAD159 "1805 (BC_2, IO_AD37, input, X)," & -- PAD159 "1806 (BC_2, *, controlr, 1)," & "1807 (BC_2, IO_AD36, output3, X, 1806, 1, Z)," & -- PAD158 "1808 (BC_2, IO_AD36, input, X)," & -- PAD158 "1809 (BC_2, *, controlr, 1)," & "1810 (BC_2, IO_AG34, output3, X, 1809, 1, Z)," & -- PAD157 "1811 (BC_2, IO_AG34, input, X)," & -- PAD157 "1812 (BC_2, *, controlr, 1)," & "1813 (BC_2, IO_AF34, output3, X, 1812, 1, Z)," & -- PAD156 "1814 (BC_2, IO_AF34, input, X)," & -- PAD156 "1815 (BC_2, *, controlr, 1)," & "1816 (BC_2, IO_AF37, output3, X, 1815, 1, Z)," & -- PAD155 "1817 (BC_2, IO_AF37, input, X)," & -- PAD155 "1818 (BC_2, *, controlr, 1)," & "1819 (BC_2, IO_AE37, output3, X, 1818, 1, Z)," & -- PAD154 "1820 (BC_2, IO_AE37, input, X)," & -- PAD154 "1821 (BC_2, *, controlr, 1)," & "1822 (BC_2, IO_AF36, output3, X, 1821, 1, Z)," & -- PAD153 "1823 (BC_2, IO_AF36, input, X)," & -- PAD153 "1824 (BC_2, *, controlr, 1)," & "1825 (BC_2, IO_AF35, output3, X, 1824, 1, Z)," & -- PAD152 "1826 (BC_2, IO_AF35, input, X)," & -- PAD152 "1827 (BC_2, *, controlr, 1)," & "1828 (BC_2, IO_Y34, output3, X, 1827, 1, Z)," & -- PAD151 "1829 (BC_2, IO_Y34, input, X)," & -- PAD151 "1830 (BC_2, *, controlr, 1)," & "1831 (BC_2, IO_AG37, output3, X, 1830, 1, Z)," & -- PAD150 "1832 (BC_2, IO_AG37, input, X)," & -- PAD150 "1833 (BC_2, *, controlr, 1)," & "1834 (BC_2, IO_AK42, output3, X, 1833, 1, Z)," & -- PAD149 "1835 (BC_2, IO_AK42, input, X)," & -- PAD149 "1836 (BC_2, *, controlr, 1)," & "1837 (BC_2, IO_AJ42, output3, X, 1836, 1, Z)," & -- PAD148 "1838 (BC_2, IO_AJ42, input, X)," & -- PAD148 "1839 (BC_2, *, controlr, 1)," & "1840 (BC_2, IO_AL39, output3, X, 1839, 1, Z)," & -- PAD147 "1841 (BC_2, IO_AL39, input, X)," & -- PAD147 "1842 (BC_2, *, controlr, 1)," & "1843 (BC_2, IO_AK39, output3, X, 1842, 1, Z)," & -- PAD146 "1844 (BC_2, IO_AK39, input, X)," & -- PAD146 "1845 (BC_2, *, controlr, 1)," & "1846 (BC_2, IO_AJ41, output3, X, 1845, 1, Z)," & -- PAD145 "1847 (BC_2, IO_AJ41, input, X)," & -- PAD145 "1848 (BC_2, *, controlr, 1)," & "1849 (BC_2, IO_AJ40, output3, X, 1848, 1, Z)," & -- PAD144 "1850 (BC_2, IO_AJ40, input, X)," & -- PAD144 "1851 (BC_2, *, controlr, 1)," & "1852 (BC_2, IO_AL42, output3, X, 1851, 1, Z)," & -- PAD143 "1853 (BC_2, IO_AL42, input, X)," & -- PAD143 "1854 (BC_2, *, controlr, 1)," & "1855 (BC_2, IO_AL41, output3, X, 1854, 1, Z)," & -- PAD142 "1856 (BC_2, IO_AL41, input, X)," & -- PAD142 "1857 (BC_2, *, controlr, 1)," & "1858 (BC_2, IO_AH41, output3, X, 1857, 1, Z)," & -- PAD141 "1859 (BC_2, IO_AH41, input, X)," & -- PAD141 "1860 (BC_2, *, controlr, 1)," & "1861 (BC_2, IO_AH40, output3, X, 1860, 1, Z)," & -- PAD140 "1862 (BC_2, IO_AH40, input, X)," & -- PAD140 "1863 (BC_2, *, controlr, 1)," & "1864 (BC_2, IO_AL40, output3, X, 1863, 1, Z)," & -- PAD139 "1865 (BC_2, IO_AL40, input, X)," & -- PAD139 "1866 (BC_2, *, controlr, 1)," & "1867 (BC_2, IO_AK40, output3, X, 1866, 1, Z)," & -- PAD138 "1868 (BC_2, IO_AK40, input, X)," & -- PAD138 "1869 (BC_2, *, controlr, 1)," & "1870 (BC_2, IO_AK38, output3, X, 1869, 1, Z)," & -- PAD137 "1871 (BC_2, IO_AK38, input, X)," & -- PAD137 "1872 (BC_2, *, controlr, 1)," & "1873 (BC_2, IO_AJ38, output3, X, 1872, 1, Z)," & -- PAD136 "1874 (BC_2, IO_AJ38, input, X)," & -- PAD136 "1875 (BC_2, *, controlr, 1)," & "1876 (BC_2, IO_AH38, output3, X, 1875, 1, Z)," & -- PAD135 "1877 (BC_2, IO_AH38, input, X)," & -- PAD135 "1878 (BC_2, *, controlr, 1)," & "1879 (BC_2, IO_AG38, output3, X, 1878, 1, Z)," & -- PAD134 "1880 (BC_2, IO_AG38, input, X)," & -- PAD134 "1881 (BC_2, *, controlr, 1)," & "1882 (BC_2, IO_AG42, output3, X, 1881, 1, Z)," & -- PAD133 "1883 (BC_2, IO_AG42, input, X)," & -- PAD133 "1884 (BC_2, *, controlr, 1)," & "1885 (BC_2, IO_AF42, output3, X, 1884, 1, Z)," & -- PAD132 "1886 (BC_2, IO_AF42, input, X)," & -- PAD132 "1887 (BC_2, *, controlr, 1)," & "1888 (BC_2, IO_AH39, output3, X, 1887, 1, Z)," & -- PAD131 "1889 (BC_2, IO_AH39, input, X)," & -- PAD131 "1890 (BC_2, *, controlr, 1)," & "1891 (BC_2, IO_AG39, output3, X, 1890, 1, Z)," & -- PAD130 "1892 (BC_2, IO_AG39, input, X)," & -- PAD130 "1893 (BC_2, *, controlr, 1)," & "1894 (BC_2, IO_AG41, output3, X, 1893, 1, Z)," & -- PAD129 "1895 (BC_2, IO_AG41, input, X)," & -- PAD129 "1896 (BC_2, *, controlr, 1)," & "1897 (BC_2, IO_AF41, output3, X, 1896, 1, Z)," & -- PAD128 "1898 (BC_2, IO_AF41, input, X)," & -- PAD128 "1899 (BC_2, *, controlr, 1)," & "1900 (BC_2, IO_AF40, output3, X, 1899, 1, Z)," & -- PAD127 "1901 (BC_2, IO_AF40, input, X)," & -- PAD127 "1902 (BC_2, *, controlr, 1)," & "1903 (BC_2, IO_AF39, output3, X, 1902, 1, Z)," & -- PAD126 "1904 (BC_2, IO_AF39, input, X)," & -- PAD126 "1905 (BC_2, *, controlr, 1)," & "1906 (BC_2, IO_AD41, output3, X, 1905, 1, Z)," & -- PAD125 "1907 (BC_2, IO_AD41, input, X)," & -- PAD125 "1908 (BC_2, *, controlr, 1)," & "1909 (BC_2, IO_AD40, output3, X, 1908, 1, Z)," & -- PAD124 "1910 (BC_2, IO_AD40, input, X)," & -- PAD124 "1911 (BC_2, *, controlr, 1)," & "1912 (BC_2, IO_AE40, output3, X, 1911, 1, Z)," & -- PAD123 "1913 (BC_2, IO_AE40, input, X)," & -- PAD123 "1914 (BC_2, *, controlr, 1)," & "1915 (BC_2, IO_AE39, output3, X, 1914, 1, Z)," & -- PAD122 "1916 (BC_2, IO_AE39, input, X)," & -- PAD122 "1917 (BC_2, *, controlr, 1)," & "1918 (BC_2, IO_AC41, output3, X, 1917, 1, Z)," & -- PAD121 "1919 (BC_2, IO_AC41, input, X)," & -- PAD121 "1920 (BC_2, *, controlr, 1)," & "1921 (BC_2, IO_AC40, output3, X, 1920, 1, Z)," & -- PAD120 "1922 (BC_2, IO_AC40, input, X)," & -- PAD120 "1923 (BC_2, *, controlr, 1)," & "1924 (BC_2, IO_AE38, output3, X, 1923, 1, Z)," & -- PAD119 "1925 (BC_2, IO_AE38, input, X)," & -- PAD119 "1926 (BC_2, *, controlr, 1)," & "1927 (BC_2, IO_AD38, output3, X, 1926, 1, Z)," & -- PAD118 "1928 (BC_2, IO_AD38, input, X)," & -- PAD118 "1929 (BC_2, *, controlr, 1)," & "1930 (BC_2, IO_AE42, output3, X, 1929, 1, Z)," & -- PAD117 "1931 (BC_2, IO_AE42, input, X)," & -- PAD117 "1932 (BC_2, *, controlr, 1)," & "1933 (BC_2, IO_AD42, output3, X, 1932, 1, Z)," & -- PAD116 "1934 (BC_2, IO_AD42, input, X)," & -- PAD116 "1935 (BC_2, *, controlr, 1)," & "1936 (BC_2, IO_AC39, output3, X, 1935, 1, Z)," & -- PAD115 "1937 (BC_2, IO_AC39, input, X)," & -- PAD115 "1938 (BC_2, *, controlr, 1)," & "1939 (BC_2, IO_AC38, output3, X, 1938, 1, Z)," & -- PAD114 "1940 (BC_2, IO_AC38, input, X)," & -- PAD114 "1941 (BC_2, *, controlr, 1)," & "1942 (BC_2, IO_AA41, output3, X, 1941, 1, Z)," & -- PAD113 "1943 (BC_2, IO_AA41, input, X)," & -- PAD113 "1944 (BC_2, *, controlr, 1)," & "1945 (BC_2, IO_AA40, output3, X, 1944, 1, Z)," & -- PAD112 "1946 (BC_2, IO_AA40, input, X)," & -- PAD112 "1947 (BC_2, *, controlr, 1)," & "1948 (BC_2, IO_AB39, output3, X, 1947, 1, Z)," & -- PAD111 "1949 (BC_2, IO_AB39, input, X)," & -- PAD111 "1950 (BC_2, *, controlr, 1)," & "1951 (BC_2, IO_AB38, output3, X, 1950, 1, Z)," & -- PAD110 "1952 (BC_2, IO_AB38, input, X)," & -- PAD110 "1953 (BC_2, *, controlr, 1)," & "1954 (BC_2, IO_AA42, output3, X, 1953, 1, Z)," & -- PAD109 "1955 (BC_2, IO_AA42, input, X)," & -- PAD109 "1956 (BC_2, *, controlr, 1)," & "1957 (BC_2, IO_Y42, output3, X, 1956, 1, Z)," & -- PAD108 "1958 (BC_2, IO_Y42, input, X)," & -- PAD108 "1959 (BC_2, *, controlr, 1)," & "1960 (BC_2, IO_AA39, output3, X, 1959, 1, Z)," & -- PAD107 "1961 (BC_2, IO_AA39, input, X)," & -- PAD107 "1962 (BC_2, *, controlr, 1)," & "1963 (BC_2, IO_Y39, output3, X, 1962, 1, Z)," & -- PAD106 "1964 (BC_2, IO_Y39, input, X)," & -- PAD106 "1965 (BC_2, *, controlr, 1)," & "1966 (BC_2, IO_Y40, output3, X, 1965, 1, Z)," & -- PAD105 "1967 (BC_2, IO_Y40, input, X)," & -- PAD105 "1968 (BC_2, *, controlr, 1)," & "1969 (BC_2, IO_W40, output3, X, 1968, 1, Z)," & -- PAD104 "1970 (BC_2, IO_W40, input, X)," & -- PAD104 "1971 (BC_2, *, controlr, 1)," & "1972 (BC_2, IO_AB42, output3, X, 1971, 1, Z)," & -- PAD103 "1973 (BC_2, IO_AB42, input, X)," & -- PAD103 "1974 (BC_2, *, controlr, 1)," & "1975 (BC_2, IO_AB41, output3, X, 1974, 1, Z)," & -- PAD102 "1976 (BC_2, IO_AB41, input, X)," & -- PAD102 "1977 (BC_2, *, controlr, 1)," & "1978 (BC_2, IO_Y38, output3, X, 1977, 1, Z)," & -- PAD101 "1979 (BC_2, IO_Y38, input, X)," & -- PAD101 "1980 (BC_2, *, controlr, 1)," & "1981 (BC_2, IO_W35, output3, X, 1980, 1, Z)," & -- PAD100 "1982 (BC_2, IO_W35, input, X)," & -- PAD100 "1983 (BC_2, *, controlr, 1)," & "1984 (BC_2, IO_U42, output3, X, 1983, 1, Z)," & -- PAD99 "1985 (BC_2, IO_U42, input, X)," & -- PAD99 "1986 (BC_2, *, controlr, 1)," & "1987 (BC_2, IO_V41, output3, X, 1986, 1, Z)," & -- PAD98 "1988 (BC_2, IO_V41, input, X)," & -- PAD98 "1989 (BC_2, *, controlr, 1)," & "1990 (BC_2, IO_V38, output3, X, 1989, 1, Z)," & -- PAD97 "1991 (BC_2, IO_V38, input, X)," & -- PAD97 "1992 (BC_2, *, controlr, 1)," & "1993 (BC_2, IO_W38, output3, X, 1992, 1, Z)," & -- PAD96 "1994 (BC_2, IO_W38, input, X)," & -- PAD96 "1995 (BC_2, *, controlr, 1)," & "1996 (BC_2, IO_T42, output3, X, 1995, 1, Z)," & -- PAD95 "1997 (BC_2, IO_T42, input, X)," & -- PAD95 "1998 (BC_2, *, controlr, 1)," & "1999 (BC_2, IO_U41, output3, X, 1998, 1, Z)," & -- PAD94 "2000 (BC_2, IO_U41, input, X)," & -- PAD94 "2001 (BC_2, *, controlr, 1)," & "2002 (BC_2, IO_W42, output3, X, 2001, 1, Z)," & -- PAD93 "2003 (BC_2, IO_W42, input, X)," & -- PAD93 "2004 (BC_2, *, controlr, 1)," & "2005 (BC_2, IO_W41, output3, X, 2004, 1, Z)," & -- PAD92 "2006 (BC_2, IO_W41, input, X)," & -- PAD92 "2007 (BC_2, *, controlr, 1)," & "2008 (BC_2, IO_T41, output3, X, 2007, 1, Z)," & -- PAD91 "2009 (BC_2, IO_T41, input, X)," & -- PAD91 "2010 (BC_2, *, controlr, 1)," & "2011 (BC_2, IO_T40, output3, X, 2010, 1, Z)," & -- PAD90 "2012 (BC_2, IO_T40, input, X)," & -- PAD90 "2013 (BC_2, *, controlr, 1)," & "2014 (BC_2, IO_V40, output3, X, 2013, 1, Z)," & -- PAD89 "2015 (BC_2, IO_V40, input, X)," & -- PAD89 "2016 (BC_2, *, controlr, 1)," & "2017 (BC_2, IO_V39, output3, X, 2016, 1, Z)," & -- PAD88 "2018 (BC_2, IO_V39, input, X)," & -- PAD88 "2019 (BC_2, *, controlr, 1)," & "2020 (BC_2, IO_W33, output3, X, 2019, 1, Z)," & -- PAD87 "2021 (BC_2, IO_W33, input, X)," & -- PAD87 "2022 (BC_2, *, controlr, 1)," & "2023 (BC_2, IO_W32, output3, X, 2022, 1, Z)," & -- PAD86 "2024 (BC_2, IO_W32, input, X)," & -- PAD86 "2025 (BC_2, *, controlr, 1)," & "2026 (BC_2, IO_U33, output3, X, 2025, 1, Z)," & -- PAD85 "2027 (BC_2, IO_U33, input, X)," & -- PAD85 "2028 (BC_2, *, controlr, 1)," & "2029 (BC_2, IO_U32, output3, X, 2028, 1, Z)," & -- PAD84 "2030 (BC_2, IO_U32, input, X)," & -- PAD84 "2031 (BC_2, *, controlr, 1)," & "2032 (BC_2, IO_W37, output3, X, 2031, 1, Z)," & -- PAD83 "2033 (BC_2, IO_W37, input, X)," & -- PAD83 "2034 (BC_2, *, controlr, 1)," & "2035 (BC_2, IO_W36, output3, X, 2034, 1, Z)," & -- PAD82 "2036 (BC_2, IO_W36, input, X)," & -- PAD82 "2037 (BC_2, *, controlr, 1)," & "2038 (BC_2, IO_V34, output3, X, 2037, 1, Z)," & -- PAD81 "2039 (BC_2, IO_V34, input, X)," & -- PAD81 "2040 (BC_2, *, controlr, 1)," & "2041 (BC_2, IO_V33, output3, X, 2040, 1, Z)," & -- PAD80 "2042 (BC_2, IO_V33, input, X)," & -- PAD80 "2043 (BC_2, *, controlr, 1)," & "2044 (BC_2, IO_V36, output3, X, 2043, 1, Z)," & -- PAD79 "2045 (BC_2, IO_V36, input, X)," & -- PAD79 "2046 (BC_2, *, controlr, 1)," & "2047 (BC_2, IO_V35, output3, X, 2046, 1, Z)," & -- PAD78 "2048 (BC_2, IO_V35, input, X)," & -- PAD78 "2049 (BC_2, *, controlr, 1)," & "2050 (BC_2, IO_T37, output3, X, 2049, 1, Z)," & -- PAD77 "2051 (BC_2, IO_T37, input, X)," & -- PAD77 "2052 (BC_2, *, controlr, 1)," & "2053 (BC_2, IO_U36, output3, X, 2052, 1, Z)," & -- PAD76 "2054 (BC_2, IO_U36, input, X)," & -- PAD76 "2055 (BC_2, *, controlr, 1)," & "2056 (BC_2, IO_T39, output3, X, 2055, 1, Z)," & -- PAD75 "2057 (BC_2, IO_T39, input, X)," & -- PAD75 "2058 (BC_2, *, controlr, 1)," & "2059 (BC_2, IO_U39, output3, X, 2058, 1, Z)," & -- PAD74 "2060 (BC_2, IO_U39, input, X)," & -- PAD74 "2061 (BC_2, *, controlr, 1)," & "2062 (BC_2, IO_U38, output3, X, 2061, 1, Z)," & -- PAD73 "2063 (BC_2, IO_U38, input, X)," & -- PAD73 "2064 (BC_2, *, controlr, 1)," & "2065 (BC_2, IO_U37, output3, X, 2064, 1, Z)," & -- PAD72 "2066 (BC_2, IO_U37, input, X)," & -- PAD72 "2067 (BC_2, *, controlr, 1)," & "2068 (BC_2, IO_R39, output3, X, 2067, 1, Z)," & -- PAD71 "2069 (BC_2, IO_R39, input, X)," & -- PAD71 "2070 (BC_2, *, controlr, 1)," & "2071 (BC_2, IO_R38, output3, X, 2070, 1, Z)," & -- PAD70 "2072 (BC_2, IO_R38, input, X)," & -- PAD70 "2073 (BC_2, *, controlr, 1)," & "2074 (BC_2, IO_T35, output3, X, 2073, 1, Z)," & -- PAD69 "2075 (BC_2, IO_T35, input, X)," & -- PAD69 "2076 (BC_2, *, controlr, 1)," & "2077 (BC_2, IO_U34, output3, X, 2076, 1, Z)," & -- PAD68 "2078 (BC_2, IO_U34, input, X)," & -- PAD68 "2079 (BC_2, *, controlr, 1)," & "2080 (BC_2, IO_P38, output3, X, 2079, 1, Z)," & -- PAD67 "2081 (BC_2, IO_P38, input, X)," & -- PAD67 "2082 (BC_2, *, controlr, 1)," & "2083 (BC_2, IO_P37, output3, X, 2082, 1, Z)," & -- PAD66 "2084 (BC_2, IO_P37, input, X)," & -- PAD66 "2085 (BC_2, *, controlr, 1)," & "2086 (BC_2, IO_R37, output3, X, 2085, 1, Z)," & -- PAD65 "2087 (BC_2, IO_R37, input, X)," & -- PAD65 "2088 (BC_2, *, controlr, 1)," & "2089 (BC_2, IO_T36, output3, X, 2088, 1, Z)," & -- PAD64 "2090 (BC_2, IO_T36, input, X)," & -- PAD64 "2091 (BC_2, *, controlr, 1)," & "2092 (BC_2, IO_P33, output3, X, 2091, 1, Z)," & -- PAD63 "2093 (BC_2, IO_P33, input, X)," & -- PAD63 "2094 (BC_2, *, controlr, 1)," & "2095 (BC_2, IO_P32, output3, X, 2094, 1, Z)," & -- PAD62 "2096 (BC_2, IO_P32, input, X)," & -- PAD62 "2097 (BC_2, *, controlr, 1)," & "2098 (BC_2, IO_R32, output3, X, 2097, 1, Z)," & -- PAD61 "2099 (BC_2, IO_R32, input, X)," & -- PAD61 "2100 (BC_2, *, controlr, 1)," & "2101 (BC_2, IO_T32, output3, X, 2100, 1, Z)," & -- PAD60 "2102 (BC_2, IO_T32, input, X)," & -- PAD60 "2103 (BC_2, *, controlr, 1)," & "2104 (BC_2, IO_P36, output3, X, 2103, 1, Z)," & -- PAD59 "2105 (BC_2, IO_P36, input, X)," & -- PAD59 "2106 (BC_2, *, controlr, 1)," & "2107 (BC_2, IO_P35, output3, X, 2106, 1, Z)," & -- PAD58 "2108 (BC_2, IO_P35, input, X)," & -- PAD58 "2109 (BC_2, *, controlr, 1)," & "2110 (BC_2, IO_R34, output3, X, 2109, 1, Z)," & -- PAD57 "2111 (BC_2, IO_R34, input, X)," & -- PAD57 "2112 (BC_2, *, controlr, 1)," & "2113 (BC_2, IO_R33, output3, X, 2112, 1, Z)," & -- PAD56 "2114 (BC_2, IO_R33, input, X)," & -- PAD56 "2115 (BC_2, *, controlr, 1)," & "2116 (BC_2, IO_N34, output3, X, 2115, 1, Z)," & -- PAD55 "2117 (BC_2, IO_N34, input, X)," & -- PAD55 "2118 (BC_2, *, controlr, 1)," & "2119 (BC_2, IO_N33, output3, X, 2118, 1, Z)," & -- PAD54 "2120 (BC_2, IO_N33, input, X)," & -- PAD54 "2121 (BC_2, *, controlr, 1)," & "2122 (BC_2, IO_R35, output3, X, 2121, 1, Z)," & -- PAD53 "2123 (BC_2, IO_R35, input, X)," & -- PAD53 "2124 (BC_2, *, controlr, 1)," & "2125 (BC_2, IO_T34, output3, X, 2124, 1, Z)," & -- PAD52 "2126 (BC_2, IO_T34, input, X)," & -- PAD52 "2127 (BC_2, *, controlr, 1)," & "2128 (BC_2, IO_N35, output3, X, 2127, 1, Z)," & -- PAD51 "2129 (BC_2, IO_N35, input, X)," & -- PAD51 "2130 (BC_2, *, controlr, 1)," & "2131 (BC_2, IO_N36, output3, X, 2130, 1, Z)," & -- PAD50 "2132 (BC_2, IO_N36, input, X)," & -- PAD50 "2133 (BC_2, *, controlr, 1)," & "2134 (BC_2, IO_N40, output3, X, 2133, 1, Z)," & -- PAD49 "2135 (BC_2, IO_N40, input, X)," & -- PAD49 "2136 (BC_2, *, controlr, 1)," & "2137 (BC_2, IO_N39, output3, X, 2136, 1, Z)," & -- PAD48 "2138 (BC_2, IO_N39, input, X)," & -- PAD48 "2139 (BC_2, *, controlr, 1)," & "2140 (BC_2, IO_P40, output3, X, 2139, 1, Z)," & -- PAD47 "2141 (BC_2, IO_P40, input, X)," & -- PAD47 "2142 (BC_2, *, controlr, 1)," & "2143 (BC_2, IO_R40, output3, X, 2142, 1, Z)," & -- PAD46 "2144 (BC_2, IO_R40, input, X)," & -- PAD46 "2145 (BC_2, *, controlr, 1)," & "2146 (BC_2, IO_M39, output3, X, 2145, 1, Z)," & -- PAD45 "2147 (BC_2, IO_M39, input, X)," & -- PAD45 "2148 (BC_2, *, controlr, 1)," & "2149 (BC_2, IO_N38, output3, X, 2148, 1, Z)," & -- PAD44 "2150 (BC_2, IO_N38, input, X)," & -- PAD44 "2151 (BC_2, *, controlr, 1)," & "2152 (BC_2, IO_P42, output3, X, 2151, 1, Z)," & -- PAD43 "2153 (BC_2, IO_P42, input, X)," & -- PAD43 "2154 (BC_2, *, controlr, 1)," & "2155 (BC_2, IO_R42, output3, X, 2154, 1, Z)," & -- PAD42 "2156 (BC_2, IO_R42, input, X)," & -- PAD42 "2157 (BC_2, *, controlr, 1)," & "2158 (BC_2, IO_M38, output3, X, 2157, 1, Z)," & -- PAD41 "2159 (BC_2, IO_M38, input, X)," & -- PAD41 "2160 (BC_2, *, controlr, 1)," & "2161 (BC_2, IO_M37, output3, X, 2160, 1, Z)," & -- PAD40 "2162 (BC_2, IO_M37, input, X)," & -- PAD40 "2163 (BC_2, *, controlr, 1)," & "2164 (BC_2, IO_N41, output3, X, 2163, 1, Z)," & -- PAD39 "2165 (BC_2, IO_N41, input, X)," & -- PAD39 "2166 (BC_2, *, controlr, 1)," & "2167 (BC_2, IO_P41, output3, X, 2166, 1, Z)," & -- PAD38 "2168 (BC_2, IO_P41, input, X)," & -- PAD38 "2169 (BC_2, *, controlr, 1)," & "2170 (BC_2, IO_L37, output3, X, 2169, 1, Z)," & -- PAD37 "2171 (BC_2, IO_L37, input, X)," & -- PAD37 "2172 (BC_2, *, controlr, 1)," & "2173 (BC_2, IO_M36, output3, X, 2172, 1, Z)," & -- PAD36 "2174 (BC_2, IO_M36, input, X)," & -- PAD36 "2175 (BC_2, *, controlr, 1)," & "2176 (BC_2, IO_K38, output3, X, 2175, 1, Z)," & -- PAD35 "2177 (BC_2, IO_K38, input, X)," & -- PAD35 "2178 (BC_2, *, controlr, 1)," & "2179 (BC_2, IO_K37, output3, X, 2178, 1, Z)," & -- PAD34 "2180 (BC_2, IO_K37, input, X)," & -- PAD34 "2181 (BC_2, *, controlr, 1)," & "2182 (BC_2, IO_L42, output3, X, 2181, 1, Z)," & -- PAD33 "2183 (BC_2, IO_L42, input, X)," & -- PAD33 "2184 (BC_2, *, controlr, 1)," & "2185 (BC_2, IO_M42, output3, X, 2184, 1, Z)," & -- PAD32 "2186 (BC_2, IO_M42, input, X)," & -- PAD32 "2187 (BC_2, *, controlr, 1)," & "2188 (BC_2, IO_J42, output3, X, 2187, 1, Z)," & -- PAD31 "2189 (BC_2, IO_J42, input, X)," & -- PAD31 "2190 (BC_2, *, controlr, 1)," & "2191 (BC_2, IO_K42, output3, X, 2190, 1, Z)," & -- PAD30 "2192 (BC_2, IO_K42, input, X)," & -- PAD30 "2193 (BC_2, *, controlr, 1)," & "2194 (BC_2, IO_L41, output3, X, 2193, 1, Z)," & -- PAD29 "2195 (BC_2, IO_L41, input, X)," & -- PAD29 "2196 (BC_2, *, controlr, 1)," & "2197 (BC_2, IO_M41, output3, X, 2196, 1, Z)," & -- PAD28 "2198 (BC_2, IO_M41, input, X)," & -- PAD28 "2199 (BC_2, *, controlr, 1)," & "2200 (BC_2, IO_L40, output3, X, 2199, 1, Z)," & -- PAD27 "2201 (BC_2, IO_L40, input, X)," & -- PAD27 "2202 (BC_2, *, controlr, 1)," & "2203 (BC_2, IO_L39, output3, X, 2202, 1, Z)," & -- PAD26 "2204 (BC_2, IO_L39, input, X)," & -- PAD26 "2205 (BC_2, *, controlr, 1)," & "2206 (BC_2, IO_K40, output3, X, 2205, 1, Z)," & -- PAD25 "2207 (BC_2, IO_K40, input, X)," & -- PAD25 "2208 (BC_2, *, controlr, 1)," & "2209 (BC_2, IO_K39, output3, X, 2208, 1, Z)," & -- PAD24 "2210 (BC_2, IO_K39, input, X)," & -- PAD24 "2211 (BC_2, *, controlr, 1)," & "2212 (BC_2, IO_J41, output3, X, 2211, 1, Z)," & -- PAD23 "2213 (BC_2, IO_J41, input, X)," & -- PAD23 "2214 (BC_2, *, controlr, 1)," & "2215 (BC_2, IO_J40, output3, X, 2214, 1, Z)," & -- PAD22 "2216 (BC_2, IO_J40, input, X)," & -- PAD22 "2217 (BC_2, *, controlr, 1)," & "2218 (BC_2, IO_F41, output3, X, 2217, 1, Z)," & -- PAD21 "2219 (BC_2, IO_F41, input, X)," & -- PAD21 "2220 (BC_2, *, controlr, 1)," & "2221 (BC_2, IO_F40, output3, X, 2220, 1, Z)," & -- PAD20 "2222 (BC_2, IO_F40, input, X)," & -- PAD20 "2223 (BC_2, *, controlr, 1)," & "2224 (BC_2, IO_G42, output3, X, 2223, 1, Z)," & -- PAD19 "2225 (BC_2, IO_G42, input, X)," & -- PAD19 "2226 (BC_2, *, controlr, 1)," & "2227 (BC_2, IO_G41, output3, X, 2226, 1, Z)," & -- PAD18 "2228 (BC_2, IO_G41, input, X)," & -- PAD18 "2229 (BC_2, *, controlr, 1)," & "2230 (BC_2, IO_G39, output3, X, 2229, 1, Z)," & -- PAD17 "2231 (BC_2, IO_G39, input, X)," & -- PAD17 "2232 (BC_2, *, controlr, 1)," & "2233 (BC_2, IO_H39, output3, X, 2232, 1, Z)," & -- PAD16 "2234 (BC_2, IO_H39, input, X)," & -- PAD16 "2235 (BC_2, *, controlr, 1)," & "2236 (BC_2, IO_H41, output3, X, 2235, 1, Z)," & -- PAD15 "2237 (BC_2, IO_H41, input, X)," & -- PAD15 "2238 (BC_2, *, controlr, 1)," & "2239 (BC_2, IO_H40, output3, X, 2238, 1, Z)," & -- PAD14 "2240 (BC_2, IO_H40, input, X)," & -- PAD14 "2241 (BC_2, *, controlr, 1)," & "2242 (BC_2, IO_C41, output3, X, 2241, 1, Z)," & -- PAD13 "2243 (BC_2, IO_C41, input, X)," & -- PAD13 "2244 (BC_2, *, controlr, 1)," & "2245 (BC_2, IO_C40, output3, X, 2244, 1, Z)," & -- PAD12 "2246 (BC_2, IO_C40, input, X)," & -- PAD12 "2247 (BC_2, *, controlr, 1)," & "2248 (BC_2, IO_E42, output3, X, 2247, 1, Z)," & -- PAD11 "2249 (BC_2, IO_E42, input, X)," & -- PAD11 "2250 (BC_2, *, controlr, 1)," & "2251 (BC_2, IO_F42, output3, X, 2250, 1, Z)," & -- PAD10 "2252 (BC_2, IO_F42, input, X)," & -- PAD10 "2253 (BC_2, *, controlr, 1)," & "2254 (BC_2, IO_B42, output3, X, 2253, 1, Z)," & -- PAD9 "2255 (BC_2, IO_B42, input, X)," & -- PAD9 "2256 (BC_2, *, controlr, 1)," & "2257 (BC_2, IO_B41, output3, X, 2256, 1, Z)," & -- PAD8 "2258 (BC_2, IO_B41, input, X)," & -- PAD8 "2259 (BC_2, *, controlr, 1)," & "2260 (BC_2, IO_D42, output3, X, 2259, 1, Z)," & -- PAD7 "2261 (BC_2, IO_D42, input, X)," & -- PAD7 "2262 (BC_2, *, controlr, 1)," & "2263 (BC_2, IO_D41, output3, X, 2262, 1, Z)," & -- PAD6 "2264 (BC_2, IO_D41, input, X)," & -- PAD6 "2265 (BC_2, *, controlr, 1)," & "2266 (BC_2, IO_A41, output3, X, 2265, 1, Z)," & -- PAD5 "2267 (BC_2, IO_A41, input, X)," & -- PAD5 "2268 (BC_2, *, controlr, 1)," & "2269 (BC_2, IO_A40, output3, X, 2268, 1, Z)," & -- PAD4 "2270 (BC_2, IO_A40, input, X)," & -- PAD4 "2271 (BC_2, *, controlr, 1)," & "2272 (BC_2, IO_D40, output3, X, 2271, 1, Z)," & -- PAD3 "2273 (BC_2, IO_D40, input, X)," & -- PAD3 "2274 (BC_2, *, controlr, 1)," & "2275 (BC_2, IO_E40, output3, X, 2274, 1, Z)," & -- PAD2 "2276 (BC_2, IO_E40, input, X)," & -- PAD2 "2277 (BC_2, *, controlr, 1)," & "2278 (BC_2, IO_L36, output3, X, 2277, 1, Z)," & -- PAD1 "2279 (BC_2, IO_L36, input, X)," & -- PAD1 "2280 (BC_2, *, internal, X)," & "2281 (BC_2, *, internal, X)," & "2282 (BC_2, *, internal, X)," & "2283 (BC_2, *, internal, X)," & "2284 (BC_2, *, internal, X)," & "2285 (BC_2, *, internal, X)," & "2286 (BC_2, *, internal, X)," & "2287 (BC_2, *, internal, X)," & "2288 (BC_2, *, internal, X)," & "2289 (BC_2, *, internal, X)," & "2290 (BC_2, *, internal, X)," & "2291 (BC_2, *, internal, X)," & "2292 (BC_2, *, internal, X)," & "2293 (BC_2, *, internal, X)," & "2294 (BC_2, *, internal, X)," & "2295 (BC_2, *, internal, X)," & "2296 (BC_4, *, internal, X)," & "2297 (BC_4, *, internal, X)," & "2298 (BC_4, *, internal, X)," & "2299 (BC_4, *, internal, X)," & "2300 (BC_4, *, internal, X)," & "2301 (BC_4, *, internal, X)," & "2302 (BC_4, *, internal, X)," & "2303 (BC_4, *, internal, X)," & "2304 (BC_4, *, internal, X)," & "2305 (BC_4, *, internal, X)," & "2306 (BC_4, *, internal, X)," & "2307 (BC_4, *, internal, X)," & "2308 (BC_4, *, internal, X)," & "2309 (BC_4, *, internal, X)," & "2310 (BC_4, *, internal, X)," & "2311 (BC_4, *, internal, X)," & "2312 (BC_4, *, internal, X)," & "2313 (BC_4, *, internal, X)," & "2314 (BC_4, *, internal, X)," & "2315 (BC_4, *, internal, X)," & "2316 (BC_4, *, internal, X)," & "2317 (BC_4, *, internal, X)," & "2318 (BC_4, *, internal, X)," & "2319 (BC_4, *, internal, X)," & "2320 (BC_4, *, internal, X)," & "2321 (BC_4, *, internal, X)," & "2322 (BC_4, *, internal, X)," & "2323 (BC_4, *, internal, X)," & "2324 (BC_4, *, internal, X)," & "2325 (BC_4, *, internal, X)," & "2326 (BC_4, *, internal, X)," & "2327 (BC_4, *, internal, X)," & "2328 (BC_4, *, internal, X)," & "2329 (BC_4, *, internal, X)," & "2330 (BC_4, *, internal, X)," & "2331 (BC_4, *, internal, X)," & "2332 (BC_4, *, internal, X)," & "2333 (BC_4, *, internal, X)," & "2334 (BC_4, *, internal, X)," & "2335 (BC_4, *, internal, X)," & "2336 (BC_4, *, internal, X)," & "2337 (BC_4, *, internal, X)," & "2338 (BC_4, *, internal, X)," & "2339 (BC_4, *, internal, X)," & "2340 (BC_4, *, internal, X)," & "2341 (BC_4, *, internal, X)," & "2342 (BC_4, *, internal, X)," & "2343 (BC_4, *, internal, X)," & "2344 (BC_4, *, internal, X)," & "2345 (BC_4, *, internal, X)," & "2346 (BC_4, *, internal, X)," & "2347 (BC_4, *, internal, X)," & "2348 (BC_4, *, internal, X)," & "2349 (BC_4, *, internal, X)," & "2350 (BC_4, *, internal, X)," & "2351 (BC_4, *, internal, X)," & "2352 (BC_4, *, internal, X)," & "2353 (BC_4, *, internal, X)," & "2354 (BC_4, *, internal, X)," & "2355 (BC_4, *, internal, X)," & "2356 (BC_4, *, internal, X)," & "2357 (BC_4, *, internal, X)," & "2358 (BC_4, *, internal, X)," & "2359 (BC_4, *, internal, X)," & "2360 (BC_4, *, internal, X)," & "2361 (BC_4, *, internal, X)," & "2362 (BC_4, *, internal, X)," & "2363 (BC_4, *, internal, X)," & "2364 (BC_4, *, internal, X)," & "2365 (BC_4, *, internal, X)," & "2366 (BC_4, *, internal, X)," & "2367 (BC_4, *, internal, X)," & "2368 (BC_4, *, internal, X)," & "2369 (BC_4, *, internal, X)," & "2370 (BC_4, *, internal, X)," & "2371 (BC_4, *, internal, X)," & "2372 (BC_4, *, internal, X)," & "2373 (BC_4, *, internal, X)," & "2374 (BC_4, *, internal, X)," & "2375 (BC_4, *, internal, X)," & "2376 (BC_4, *, internal, X)," & "2377 (BC_4, *, internal, X)," & "2378 (BC_4, *, internal, X)," & "2379 (BC_4, *, internal, X)," & "2380 (BC_2, *, internal, X)," & "2381 (BC_2, *, internal, X)," & "2382 (BC_2, *, internal, X)," & "2383 (BC_2, *, internal, X)," & "2384 (BC_2, *, internal, X)," & "2385 (BC_2, *, internal, X)," & "2386 (BC_2, *, internal, X)," & "2387 (BC_2, *, internal, X)," & "2388 (BC_2, *, internal, X)," & "2389 (BC_2, *, internal, X)," & "2390 (BC_2, *, internal, X)," & "2391 (BC_2, *, internal, X)," & "2392 (BC_2, *, internal, X)," & "2393 (BC_2, *, internal, X)," & "2394 (BC_2, *, internal, X)," & "2395 (BC_2, *, internal, X)," & "2396 (BC_2, *, internal, X)," & "2397 (BC_2, *, internal, X)," & "2398 (BC_2, *, internal, X)," & "2399 (BC_2, *, internal, X)," & "2400 (BC_2, *, internal, X)"; -- Advanced I/O Description attribute AIO_COMPONENT_CONFORMANCE of XC7VX485T_FFG1761 : entity is "STD_1149_6_2003"; attribute AIO_EXTEST_Pulse_Execution of XC7VX485T_FFG1761 : entity is "Wait_Duration TCK 15"; attribute AIO_EXTEST_Train_Execution of XC7VX485T_FFG1761 : entity is "train 30, maximum_time 120.0e-6"; attribute AIO_Pin_Behavior of XC7VX485T_FFG1761 : entity is "MGTXRXP0_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP0_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP1_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP2_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXRXP3_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTXTXP0_113; " & "MGTXTXP0_114; " & "MGTXTXP0_115; " & "MGTXTXP0_116; " & "MGTXTXP0_117; " & "MGTXTXP0_118; " & "MGTXTXP0_119; " & "MGTXTXP1_113; " & "MGTXTXP1_114; " & "MGTXTXP1_115; " & "MGTXTXP1_116; " & "MGTXTXP1_117; " & "MGTXTXP1_118; " & "MGTXTXP1_119; " & "MGTXTXP2_113; " & "MGTXTXP2_114; " & "MGTXTXP2_115; " & "MGTXTXP2_116; " & "MGTXTXP2_117; " & "MGTXTXP2_118; " & "MGTXTXP2_119; " & "MGTXTXP3_113; " & "MGTXTXP3_114; " & "MGTXTXP3_115; " & "MGTXTXP3_116; " & "MGTXTXP3_117; " & "MGTXTXP3_118; " & "MGTXTXP3_119 "; -- Design Warning Section attribute DESIGN_WARNING of XC7VX485T_FFG1761 : entity is "This is a preliminary BSDL file which has not been verified." & "When no bitstream is loaded and GTPs are not instantiated," & "the boundary-scan cells associated with GTPs will not" & "capture correct state information. To model the boundary-" & "scan cell behavior correctly post-configuration, use" & "BSDLanno to modify the BSDL file." & "This BSDL file must be modified by the FPGA designer in order to" & "reflect post-configuration behavior (if any)." & "To avoid losing the current configuration, the boundary scan" & "test vectors should keep the PROGRAM_B pin" & "high. If the PROGRAM_B pin goes low by any means," & "the configuration will be cleared." & "PROGRAM_B can only be captured, not updated." & "The value at the pin is always used by the device." & "In EXTEST, output and tristate values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "Differential Serial IO pins do not support INTEST." & "In INTEST, the pin input values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "The output and tristate capture values are not valid until after" & "the device is configured." & "The tristate control value is not captured properly when" & "GTS is activated." & "The IEEE Std 1149.6 EXTEST_PULSE and EXTEST_TRAIN instructions" & "require a minimum TCK freq of 15 MHz and min temp of 0C." & "NOCONNECT pins should not be connected to any supply" & "or GND. They should be left floating."; end XC7VX485T_FFG1761; ================================================ FILE: jtag/bsd/xc7vx690t_ffg1761.bsd ================================================ -- (c) Copyright 2010 - 2011 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- releated to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitiations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. -- -- BSDL file for device XC7VX690T, package FFG1761 -- Generated by bsdlnet Version 1.7 -- Generated on Wed Dec 07, 2011 09:45:28 PST -- Generated using schematic at v32_top/xc7vx690t/schematic -- Schematic date = 2011-10-18 10:03:12 -- Schematic ICM_VARIANT = 28t_n1 -- Package File date = # Date : 2011-09-22 15:41:14 ------------------------------------------------------------------------ -- Modification History -- | CR # N/A -- | Details - Initial Release ------------------------------------------------------------------------ -- -- For technical support, http://support.xilinx.com -> enter text 'bsdl' -- in the text search box at the left of the page. If none of -- these records resolve your problem you should open a web support case -- or contact our technical support at: -- -- North America 1-800-255-7778 hotline@xilinx.com -- United Kingdom +44 870 7350 610 eurosupport@xilinx.com -- France (33) 1 3463 0100 eurosupport@xilinx.com -- Germany (49) 89 991 54930 eurosupport@xilinx.com -- Japan (81) 3-3297-9163 jhotline@xilinx.com -- -- This BSDL file reflects the pre-configuration JTAG behavior. To reflect -- the post-configuration JTAG behavior (if any), edit this file as described -- below. Many of these changes are demonstrated by commented-out template -- lines preceeding the lines they would replace: -- -- 1. Enable USER instructions as appropriate (see below). -- 2. Set disable result of all pads as configured. -- 3. Set safe state of boundary cells as necessary. -- 4. Rename entity if necessary to avoid name collisions. -- 5. Modify USERCODE value in USERCODE_REGISTER declaration. -- -- To prevent losing the current configuration, the boundary scan -- test vectors should keep the PROGRAM_B pin high. -- -- PROGRAM_B can only be captured, not updated. The value -- at the pin is always used by the device. -- -- All IOBs prior to configuration, and unused and output-only IOBs following -- configuration, will sense their pad values during boundary-scan with an CMOS -- input buffer. In order to properly capture a logic high value at one -- of these IOBs into its input boundary scan cell, please refer to the -- datasheet and user guide for proper input levels. -- -- For post-configuration boundary scan only: If an IOB is configured to use -- an input standard that uses VREF pins, then the boundary scan test vectors -- must keep the used VREF pins 3-stated. ---------------------------------- -- BSDL File for P1149.6 Standard. ---------------------------------- -- ---------------------------------------------------------------------- -- This BSDL file has been checked and verified by JTAG Technologies B.V. -- on 2011-12-08, for syntactical and semantic compliance with -- IEEE standards 1149.1 and 1149.6 -- using bsdl32.dll 1.6.1.5 - 20110523 Win32 -- copyright (c) 2009 JTAG Technologies B.V., All rights reserved -- ---------------------------------------------------------------------- ------------------------------------------------------------------------ -- | Generated on 01/31/14 -- | CR # 707581 -- | Details - Removed "Prelim" statement. ------------------------------------------------------------------------ entity XC7VX690T_FFG1761 is -- Generic Parameter generic (PHYSICAL_PIN_MAP : string := "FFG1761" ); -- Logical Port Description port ( CCLK_N10: inout bit; -- CCLK_0 CFGBVS_AH10: in bit; -- CFGBVS_0 DONE_AL11: inout bit; -- DONE_0 GND: linkage bit_vector (1 to 424); GNDADC_0: linkage bit; INIT_B_AG11: inout bit; -- INIT_B_0 M0_AL10: in bit; -- M0_0 M1_AK10: in bit; -- M1_0 M2_AJ10: in bit; -- M2_0 MGTAVCC_G10: linkage bit_vector (1 to 11); MGTAVCC_G11: linkage bit_vector (1 to 5); MGTAVTTRCAL_115: linkage bit; MGTAVTT_G10: linkage bit_vector (1 to 16); MGTAVTT_G11: linkage bit_vector (1 to 11); MGTHRXN0_111: in bit; MGTHRXN0_112: in bit; MGTHRXN0_113: in bit; MGTHRXN0_114: in bit; MGTHRXN0_115: in bit; MGTHRXN0_116: in bit; MGTHRXN0_117: in bit; MGTHRXN0_118: in bit; MGTHRXN0_119: in bit; MGTHRXN1_111: in bit; MGTHRXN1_112: in bit; MGTHRXN1_113: in bit; MGTHRXN1_114: in bit; MGTHRXN1_115: in bit; MGTHRXN1_116: in bit; MGTHRXN1_117: in bit; MGTHRXN1_118: in bit; MGTHRXN1_119: in bit; MGTHRXN2_111: in bit; MGTHRXN2_112: in bit; MGTHRXN2_113: in bit; MGTHRXN2_114: in bit; MGTHRXN2_115: in bit; MGTHRXN2_116: in bit; MGTHRXN2_117: in bit; MGTHRXN2_118: in bit; MGTHRXN2_119: in bit; MGTHRXN3_111: in bit; MGTHRXN3_112: in bit; MGTHRXN3_113: in bit; MGTHRXN3_114: in bit; MGTHRXN3_115: in bit; MGTHRXN3_116: in bit; MGTHRXN3_117: in bit; MGTHRXN3_118: in bit; MGTHRXN3_119: in bit; MGTHRXP0_111: in bit; MGTHRXP0_112: in bit; MGTHRXP0_113: in bit; MGTHRXP0_114: in bit; MGTHRXP0_115: in bit; MGTHRXP0_116: in bit; MGTHRXP0_117: in bit; MGTHRXP0_118: in bit; MGTHRXP0_119: in bit; MGTHRXP1_111: in bit; MGTHRXP1_112: in bit; MGTHRXP1_113: in bit; MGTHRXP1_114: in bit; MGTHRXP1_115: in bit; MGTHRXP1_116: in bit; MGTHRXP1_117: in bit; MGTHRXP1_118: in bit; MGTHRXP1_119: in bit; MGTHRXP2_111: in bit; MGTHRXP2_112: in bit; MGTHRXP2_113: in bit; MGTHRXP2_114: in bit; MGTHRXP2_115: in bit; MGTHRXP2_116: in bit; MGTHRXP2_117: in bit; MGTHRXP2_118: in bit; MGTHRXP2_119: in bit; MGTHRXP3_111: in bit; MGTHRXP3_112: in bit; MGTHRXP3_113: in bit; MGTHRXP3_114: in bit; MGTHRXP3_115: in bit; MGTHRXP3_116: in bit; MGTHRXP3_117: in bit; MGTHRXP3_118: in bit; MGTHRXP3_119: in bit; MGTHTXN0_111: buffer bit; MGTHTXN0_112: buffer bit; MGTHTXN0_113: buffer bit; MGTHTXN0_114: buffer bit; MGTHTXN0_115: buffer bit; MGTHTXN0_116: buffer bit; MGTHTXN0_117: buffer bit; MGTHTXN0_118: buffer bit; MGTHTXN0_119: buffer bit; MGTHTXN1_111: buffer bit; MGTHTXN1_112: buffer bit; MGTHTXN1_113: buffer bit; MGTHTXN1_114: buffer bit; MGTHTXN1_115: buffer bit; MGTHTXN1_116: buffer bit; MGTHTXN1_117: buffer bit; MGTHTXN1_118: buffer bit; MGTHTXN1_119: buffer bit; MGTHTXN2_111: buffer bit; MGTHTXN2_112: buffer bit; MGTHTXN2_113: buffer bit; MGTHTXN2_114: buffer bit; MGTHTXN2_115: buffer bit; MGTHTXN2_116: buffer bit; MGTHTXN2_117: buffer bit; MGTHTXN2_118: buffer bit; MGTHTXN2_119: buffer bit; MGTHTXN3_111: buffer bit; MGTHTXN3_112: buffer bit; MGTHTXN3_113: buffer bit; MGTHTXN3_114: buffer bit; MGTHTXN3_115: buffer bit; MGTHTXN3_116: buffer bit; MGTHTXN3_117: buffer bit; MGTHTXN3_118: buffer bit; MGTHTXN3_119: buffer bit; MGTHTXP0_111: buffer bit; MGTHTXP0_112: buffer bit; MGTHTXP0_113: buffer bit; MGTHTXP0_114: buffer bit; MGTHTXP0_115: buffer bit; MGTHTXP0_116: buffer bit; MGTHTXP0_117: buffer bit; MGTHTXP0_118: buffer bit; MGTHTXP0_119: buffer bit; MGTHTXP1_111: buffer bit; MGTHTXP1_112: buffer bit; MGTHTXP1_113: buffer bit; MGTHTXP1_114: buffer bit; MGTHTXP1_115: buffer bit; MGTHTXP1_116: buffer bit; MGTHTXP1_117: buffer bit; MGTHTXP1_118: buffer bit; MGTHTXP1_119: buffer bit; MGTHTXP2_111: buffer bit; MGTHTXP2_112: buffer bit; MGTHTXP2_113: buffer bit; MGTHTXP2_114: buffer bit; MGTHTXP2_115: buffer bit; MGTHTXP2_116: buffer bit; MGTHTXP2_117: buffer bit; MGTHTXP2_118: buffer bit; MGTHTXP2_119: buffer bit; MGTHTXP3_111: buffer bit; MGTHTXP3_112: buffer bit; MGTHTXP3_113: buffer bit; MGTHTXP3_114: buffer bit; MGTHTXP3_115: buffer bit; MGTHTXP3_116: buffer bit; MGTHTXP3_117: buffer bit; MGTHTXP3_118: buffer bit; MGTHTXP3_119: buffer bit; MGTREFCLK0N_111: linkage bit; MGTREFCLK0N_112: linkage bit; MGTREFCLK0N_113: linkage bit; MGTREFCLK0N_114: linkage bit; MGTREFCLK0N_115: linkage bit; MGTREFCLK0N_116: linkage bit; MGTREFCLK0N_117: linkage bit; MGTREFCLK0N_118: linkage bit; MGTREFCLK0N_119: linkage bit; MGTREFCLK0P_111: linkage bit; MGTREFCLK0P_112: linkage bit; MGTREFCLK0P_113: linkage bit; MGTREFCLK0P_114: linkage bit; MGTREFCLK0P_115: linkage bit; MGTREFCLK0P_116: linkage bit; MGTREFCLK0P_117: linkage bit; MGTREFCLK0P_118: linkage bit; MGTREFCLK0P_119: linkage bit; MGTREFCLK1N_111: linkage bit; MGTREFCLK1N_112: linkage bit; MGTREFCLK1N_113: linkage bit; MGTREFCLK1N_114: linkage bit; MGTREFCLK1N_115: linkage bit; MGTREFCLK1N_116: linkage bit; MGTREFCLK1N_117: linkage bit; MGTREFCLK1N_118: linkage bit; MGTREFCLK1N_119: linkage bit; MGTREFCLK1P_111: linkage bit; MGTREFCLK1P_112: linkage bit; MGTREFCLK1P_113: linkage bit; MGTREFCLK1P_114: linkage bit; MGTREFCLK1P_115: linkage bit; MGTREFCLK1P_116: linkage bit; MGTREFCLK1P_117: linkage bit; MGTREFCLK1P_118: linkage bit; MGTREFCLK1P_119: linkage bit; MGTRREF_115: linkage bit; MGTVCCAUX_G10: linkage bit_vector (1 to 2); MGTVCCAUX_G11: linkage bit; NOCONNECT: linkage bit_vector (1 to 4); PROGRAM_B: in bit; -- PROGRAM_B_0 TCK: in bit; -- TCK_0 TDI: in bit; -- TDI_0 TDN_AC20: linkage bit; -- DXN_0 TDO: out bit; -- TDO_0 TDP_AC21: linkage bit; -- DXP_0 TMS: in bit; -- TMS_0 VCCADC_0: linkage bit; VCCAUX: linkage bit_vector (1 to 29); VCCBATT_0: linkage bit; VCCBRAM: linkage bit_vector (1 to 8); VCCINT: linkage bit_vector (1 to 86); VCCO_0: linkage bit_vector (1 to 2); VCCO_12: linkage bit_vector (1 to 6); VCCO_13: linkage bit_vector (1 to 7); VCCO_14: linkage bit_vector (1 to 7); VCCO_15: linkage bit_vector (1 to 6); VCCO_16: linkage bit_vector (1 to 6); VCCO_17: linkage bit_vector (1 to 6); VCCO_18: linkage bit_vector (1 to 6); VCCO_19: linkage bit_vector (1 to 7); VCCO_31: linkage bit_vector (1 to 7); VCCO_32: linkage bit_vector (1 to 6); VCCO_33: linkage bit_vector (1 to 6); VCCO_34: linkage bit_vector (1 to 6); VCCO_35: linkage bit_vector (1 to 7); VCCO_36: linkage bit_vector (1 to 7); VCCO_37: linkage bit_vector (1 to 6); VCCO_38: linkage bit_vector (1 to 6); VCCO_39: linkage bit_vector (1 to 6); VN_AB20: linkage bit; -- VN_0 VP_AA21: linkage bit; -- VP_0 VREFN_AA20: linkage bit; -- VREFN_0 VREFP_AB21: linkage bit; -- VREFP_0 IO_A14: inout bit; -- PAD505 IO_A15: inout bit; -- PAD555 IO_A16: inout bit; -- PAD554 IO_A17: inout bit; -- PAD559 IO_A19: inout bit; -- PAD557 IO_A20: inout bit; -- PAD556 IO_A21: inout bit; -- PAD561 IO_A22: inout bit; -- PAD605 IO_A24: inout bit; -- PAD602 IO_A25: inout bit; -- PAD603 IO_A26: inout bit; -- PAD606 IO_A27: inout bit; -- PAD607 IO_A29: inout bit; -- PAD634 IO_A30: inout bit; -- PAD635 IO_A31: inout bit; -- PAD632 IO_A32: inout bit; -- PAD633 IO_A34: inout bit; -- PAD705 IO_A35: inout bit; -- PAD708 IO_A36: inout bit; -- PAD709 IO_A37: inout bit; -- PAD703 IO_A39: inout bit; -- PAD707 IO_A40: inout bit; -- PAD4 IO_A41: inout bit; -- PAD5 IO_B14: inout bit; -- PAD504 IO_B16: inout bit; -- PAD503 IO_B17: inout bit; -- PAD558 IO_B18: inout bit; -- PAD563 IO_B19: inout bit; -- PAD553 IO_B21: inout bit; -- PAD560 IO_B22: inout bit; -- PAD604 IO_B23: inout bit; -- PAD609 IO_B24: inout bit; -- PAD613 IO_B26: inout bit; -- PAD610 IO_B27: inout bit; -- PAD611 IO_B28: inout bit; -- PAD630 IO_B29: inout bit; -- PAD631 IO_B31: inout bit; -- PAD637 IO_B32: inout bit; -- PAD716 IO_B33: inout bit; -- PAD717 IO_B34: inout bit; -- PAD704 IO_B36: inout bit; -- PAD702 IO_B37: inout bit; -- PAD712 IO_B38: inout bit; -- PAD713 IO_B39: inout bit; -- PAD706 IO_B41: inout bit; -- PAD8 IO_B42: inout bit; -- PAD9 IO_C13: inout bit; -- PAD509 IO_C14: inout bit; -- PAD507 IO_C15: inout bit; -- PAD506 IO_C16: inout bit; -- PAD502 IO_C18: inout bit; -- PAD562 IO_C19: inout bit; -- PAD552 IO_C20: inout bit; -- PAD565 IO_C21: inout bit; -- PAD569 IO_C23: inout bit; -- PAD608 IO_C24: inout bit; -- PAD612 IO_C25: inout bit; -- PAD624 IO_C26: inout bit; -- PAD625 IO_C28: inout bit; -- PAD628 IO_C29: inout bit; -- PAD629 IO_C30: inout bit; -- PAD641 IO_C31: inout bit; -- PAD636 IO_C33: inout bit; -- PAD720 IO_C34: inout bit; -- PAD721 IO_C35: inout bit; -- PAD724 IO_C36: inout bit; -- PAD725 IO_C38: inout bit; -- PAD710 IO_C39: inout bit; -- PAD711 IO_C40: inout bit; -- PAD12 IO_C41: inout bit; -- PAD13 IO_D12: inout bit; -- PAD513 IO_D13: inout bit; -- PAD508 IO_D15: inout bit; -- PAD511 IO_D16: inout bit; -- PAD510 IO_D17: inout bit; -- PAD571 IO_D18: inout bit; -- PAD570 IO_D20: inout bit; -- PAD564 IO_D21: inout bit; -- PAD568 IO_D22: inout bit; -- PAD620 IO_D23: inout bit; -- PAD621 IO_D25: inout bit; -- PAD622 IO_D26: inout bit; -- PAD623 IO_D27: inout bit; -- PAD626 IO_D28: inout bit; -- PAD627 IO_D30: inout bit; -- PAD640 IO_D31: inout bit; -- PAD639 IO_D32: inout bit; -- PAD715 IO_D33: inout bit; -- PAD719 IO_D35: inout bit; -- PAD722 IO_D36: inout bit; -- PAD723 IO_D37: inout bit; -- PAD728 IO_D38: inout bit; -- PAD729 IO_D40: inout bit; -- PAD3 IO_D41: inout bit; -- PAD6 IO_D42: inout bit; -- PAD7 IO_E12: inout bit; -- PAD512 IO_E13: inout bit; -- PAD517 IO_E14: inout bit; -- PAD516 IO_E15: inout bit; -- PAD515 IO_E17: inout bit; -- PAD567 IO_E18: inout bit; -- PAD575 IO_E19: inout bit; -- PAD574 IO_E20: inout bit; -- PAD581 IO_E22: inout bit; -- PAD617 IO_E23: inout bit; -- PAD614 IO_E24: inout bit; -- PAD615 IO_E25: inout bit; -- PAD619 IO_E27: inout bit; -- PAD642 IO_E28: inout bit; -- PAD643 IO_E29: inout bit; -- PAD645 IO_E30: inout bit; -- PAD638 IO_E32: inout bit; -- PAD714 IO_E33: inout bit; -- PAD718 IO_E34: inout bit; -- PAD726 IO_E35: inout bit; -- PAD727 IO_E37: inout bit; -- PAD738 IO_E38: inout bit; -- PAD739 IO_E39: inout bit; -- PAD743 IO_E40: inout bit; -- PAD2 IO_E42: inout bit; -- PAD11 IO_F12: inout bit; -- PAD521 IO_F14: inout bit; -- PAD523 IO_F15: inout bit; -- PAD522 IO_F16: inout bit; -- PAD514 IO_F17: inout bit; -- PAD566 IO_F19: inout bit; -- PAD573 IO_F20: inout bit; -- PAD580 IO_F21: inout bit; -- PAD601 IO_F22: inout bit; -- PAD616 IO_F24: inout bit; -- PAD650 IO_F25: inout bit; -- PAD618 IO_F26: inout bit; -- PAD646 IO_F27: inout bit; -- PAD647 IO_F29: inout bit; -- PAD644 IO_F30: inout bit; -- PAD648 IO_F31: inout bit; -- PAD649 IO_F32: inout bit; -- PAD731 IO_F34: inout bit; -- PAD734 IO_F35: inout bit; -- PAD735 IO_F36: inout bit; -- PAD732 IO_F37: inout bit; -- PAD733 IO_F39: inout bit; -- PAD742 IO_F40: inout bit; -- PAD20 IO_F41: inout bit; -- PAD21 IO_F42: inout bit; -- PAD10 IO_G12: inout bit; -- PAD520 IO_G13: inout bit; -- PAD525 IO_G14: inout bit; -- PAD524 IO_G16: inout bit; -- PAD519 IO_G17: inout bit; -- PAD587 IO_G18: inout bit; -- PAD577 IO_G19: inout bit; -- PAD572 IO_G21: inout bit; -- PAD658 IO_G22: inout bit; -- PAD659 IO_G23: inout bit; -- PAD663 IO_G24: inout bit; -- PAD653 IO_G26: inout bit; -- PAD660 IO_G27: inout bit; -- PAD661 IO_G28: inout bit; -- PAD664 IO_G29: inout bit; -- PAD665 IO_G31: inout bit; -- PAD701 IO_G32: inout bit; -- PAD730 IO_G33: inout bit; -- PAD737 IO_G34: inout bit; -- PAD750 IO_G36: inout bit; -- PAD740 IO_G37: inout bit; -- PAD741 IO_G38: inout bit; -- PAD747 IO_G39: inout bit; -- PAD17 IO_G41: inout bit; -- PAD18 IO_G42: inout bit; -- PAD19 IO_H13: inout bit; -- PAD529 IO_H14: inout bit; -- PAD527 IO_H15: inout bit; -- PAD526 IO_H16: inout bit; -- PAD518 IO_H18: inout bit; -- PAD586 IO_H19: inout bit; -- PAD576 IO_H20: inout bit; -- PAD585 IO_H21: inout bit; -- PAD655 IO_H23: inout bit; -- PAD662 IO_H24: inout bit; -- PAD652 IO_H25: inout bit; -- PAD656 IO_H26: inout bit; -- PAD657 IO_H28: inout bit; -- PAD668 IO_H29: inout bit; -- PAD669 IO_H30: inout bit; -- PAD767 IO_H31: inout bit; -- PAD771 IO_H33: inout bit; -- PAD736 IO_H34: inout bit; -- PAD762 IO_H35: inout bit; -- PAD763 IO_H36: inout bit; -- PAD749 IO_H38: inout bit; -- PAD746 IO_H39: inout bit; -- PAD16 IO_H40: inout bit; -- PAD14 IO_H41: inout bit; -- PAD15 IO_J11: inout bit; -- PAD550 IO_J12: inout bit; -- PAD531 IO_J13: inout bit; -- PAD528 IO_J15: inout bit; -- PAD533 IO_J16: inout bit; -- PAD501 IO_J17: inout bit; -- PAD583 IO_J18: inout bit; -- PAD579 IO_J20: inout bit; -- PAD584 IO_J21: inout bit; -- PAD654 IO_J22: inout bit; -- PAD685 IO_J23: inout bit; -- PAD679 IO_J25: inout bit; -- PAD674 IO_J26: inout bit; -- PAD675 IO_J27: inout bit; -- PAD671 IO_J28: inout bit; -- PAD667 IO_J30: inout bit; -- PAD766 IO_J31: inout bit; -- PAD770 IO_J32: inout bit; -- PAD754 IO_J33: inout bit; -- PAD755 IO_J35: inout bit; -- PAD753 IO_J36: inout bit; -- PAD748 IO_J37: inout bit; -- PAD744 IO_J38: inout bit; -- PAD745 IO_J40: inout bit; -- PAD22 IO_J41: inout bit; -- PAD23 IO_J42: inout bit; -- PAD31 IO_K12: inout bit; -- PAD530 IO_K13: inout bit; -- PAD535 IO_K14: inout bit; -- PAD534 IO_K15: inout bit; -- PAD532 IO_K17: inout bit; -- PAD582 IO_K18: inout bit; -- PAD551 IO_K19: inout bit; -- PAD578 IO_K20: inout bit; -- PAD600 IO_K22: inout bit; -- PAD684 IO_K23: inout bit; -- PAD678 IO_K24: inout bit; -- PAD672 IO_K25: inout bit; -- PAD673 IO_K27: inout bit; -- PAD670 IO_K28: inout bit; -- PAD666 IO_K29: inout bit; -- PAD764 IO_K30: inout bit; -- PAD765 IO_K32: inout bit; -- PAD775 IO_K33: inout bit; -- PAD756 IO_K34: inout bit; -- PAD757 IO_K35: inout bit; -- PAD752 IO_K37: inout bit; -- PAD34 IO_K38: inout bit; -- PAD35 IO_K39: inout bit; -- PAD24 IO_K40: inout bit; -- PAD25 IO_K42: inout bit; -- PAD30 IO_L11: inout bit; -- PAD539 IO_L12: inout bit; -- PAD538 IO_L14: inout bit; -- PAD541 IO_L15: inout bit; -- PAD537 IO_L16: inout bit; -- PAD536 IO_L17: inout bit; -- PAD591 IO_L19: inout bit; -- PAD599 IO_L20: inout bit; -- PAD598 IO_L21: inout bit; -- PAD687 IO_L22: inout bit; -- PAD681 IO_L24: inout bit; -- PAD677 IO_L25: inout bit; -- PAD682 IO_L26: inout bit; -- PAD683 IO_L27: inout bit; -- PAD699 IO_L29: inout bit; -- PAD768 IO_L30: inout bit; -- PAD769 IO_L31: inout bit; -- PAD774 IO_L32: inout bit; -- PAD773 IO_L34: inout bit; -- PAD758 IO_L35: inout bit; -- PAD759 IO_L36: inout bit; -- PAD1 IO_L37: inout bit; -- PAD37 IO_L39: inout bit; -- PAD26 IO_L40: inout bit; -- PAD27 IO_L41: inout bit; -- PAD29 IO_L42: inout bit; -- PAD33 IO_M11: inout bit; -- PAD549 IO_M12: inout bit; -- PAD548 IO_M13: inout bit; -- PAD545 IO_M14: inout bit; -- PAD540 IO_M16: inout bit; -- PAD543 IO_M17: inout bit; -- PAD590 IO_M18: inout bit; -- PAD595 IO_M19: inout bit; -- PAD594 IO_M21: inout bit; -- PAD686 IO_M22: inout bit; -- PAD680 IO_M23: inout bit; -- PAD651 IO_M24: inout bit; -- PAD676 IO_M26: inout bit; -- PAD700 IO_M27: inout bit; -- PAD698 IO_M28: inout bit; -- PAD780 IO_M29: inout bit; -- PAD781 IO_M31: inout bit; -- PAD777 IO_M32: inout bit; -- PAD772 IO_M33: inout bit; -- PAD760 IO_M34: inout bit; -- PAD761 IO_M36: inout bit; -- PAD36 IO_M37: inout bit; -- PAD40 IO_M38: inout bit; -- PAD41 IO_M39: inout bit; -- PAD45 IO_M41: inout bit; -- PAD28 IO_M42: inout bit; -- PAD32 IO_N13: inout bit; -- PAD544 IO_N14: inout bit; -- PAD547 IO_N15: inout bit; -- PAD546 IO_N16: inout bit; -- PAD542 IO_N18: inout bit; -- PAD593 IO_N19: inout bit; -- PAD592 IO_N20: inout bit; -- PAD597 IO_N21: inout bit; -- PAD689 IO_N23: inout bit; -- PAD696 IO_N24: inout bit; -- PAD697 IO_N25: inout bit; -- PAD694 IO_N26: inout bit; -- PAD695 IO_N28: inout bit; -- PAD784 IO_N29: inout bit; -- PAD785 IO_N30: inout bit; -- PAD776 IO_N31: inout bit; -- PAD779 IO_N33: inout bit; -- PAD54 IO_N34: inout bit; -- PAD55 IO_N35: inout bit; -- PAD51 IO_N36: inout bit; -- PAD50 IO_N38: inout bit; -- PAD44 IO_N39: inout bit; -- PAD48 IO_N40: inout bit; -- PAD49 IO_N41: inout bit; -- PAD39 IO_P17: inout bit; -- PAD589 IO_P18: inout bit; -- PAD588 IO_P20: inout bit; -- PAD596 IO_P21: inout bit; -- PAD688 IO_P22: inout bit; -- PAD692 IO_P23: inout bit; -- PAD693 IO_P25: inout bit; -- PAD690 IO_P26: inout bit; -- PAD691 IO_P28: inout bit; -- PAD783 IO_P30: inout bit; -- PAD778 IO_P31: inout bit; -- PAD787 IO_P32: inout bit; -- PAD62 IO_P33: inout bit; -- PAD63 IO_P35: inout bit; -- PAD58 IO_P36: inout bit; -- PAD59 IO_P37: inout bit; -- PAD66 IO_P38: inout bit; -- PAD67 IO_P40: inout bit; -- PAD47 IO_P41: inout bit; -- PAD38 IO_P42: inout bit; -- PAD43 IO_R28: inout bit; -- PAD782 IO_R29: inout bit; -- PAD751 IO_R30: inout bit; -- PAD786 IO_R32: inout bit; -- PAD61 IO_R33: inout bit; -- PAD56 IO_R34: inout bit; -- PAD57 IO_R35: inout bit; -- PAD53 IO_R37: inout bit; -- PAD65 IO_R38: inout bit; -- PAD70 IO_R39: inout bit; -- PAD71 IO_R40: inout bit; -- PAD46 IO_R42: inout bit; -- PAD42 IO_T29: inout bit; -- PAD792 IO_T30: inout bit; -- PAD793 IO_T31: inout bit; -- PAD789 IO_T32: inout bit; -- PAD60 IO_T34: inout bit; -- PAD52 IO_T35: inout bit; -- PAD69 IO_T36: inout bit; -- PAD64 IO_T37: inout bit; -- PAD77 IO_T39: inout bit; -- PAD75 IO_T40: inout bit; -- PAD90 IO_T41: inout bit; -- PAD91 IO_T42: inout bit; -- PAD95 IO_U28: inout bit; -- PAD800 IO_U29: inout bit; -- PAD797 IO_U31: inout bit; -- PAD788 IO_U32: inout bit; -- PAD84 IO_U33: inout bit; -- PAD85 IO_U34: inout bit; -- PAD68 IO_U36: inout bit; -- PAD76 IO_U37: inout bit; -- PAD72 IO_U38: inout bit; -- PAD73 IO_U39: inout bit; -- PAD74 IO_U41: inout bit; -- PAD94 IO_U42: inout bit; -- PAD99 IO_V29: inout bit; -- PAD796 IO_V30: inout bit; -- PAD790 IO_V31: inout bit; -- PAD791 IO_V33: inout bit; -- PAD80 IO_V34: inout bit; -- PAD81 IO_V35: inout bit; -- PAD78 IO_V36: inout bit; -- PAD79 IO_V38: inout bit; -- PAD97 IO_V39: inout bit; -- PAD88 IO_V40: inout bit; -- PAD89 IO_V41: inout bit; -- PAD98 IO_W30: inout bit; -- PAD794 IO_W31: inout bit; -- PAD795 IO_W32: inout bit; -- PAD86 IO_W33: inout bit; -- PAD87 IO_W35: inout bit; -- PAD100 IO_W36: inout bit; -- PAD82 IO_W37: inout bit; -- PAD83 IO_W38: inout bit; -- PAD96 IO_W40: inout bit; -- PAD104 IO_W41: inout bit; -- PAD92 IO_W42: inout bit; -- PAD93 IO_Y29: inout bit; -- PAD798 IO_Y30: inout bit; -- PAD799 IO_Y32: inout bit; -- PAD188 IO_Y33: inout bit; -- PAD189 IO_Y34: inout bit; -- PAD151 IO_Y35: inout bit; -- PAD166 IO_Y37: inout bit; -- PAD164 IO_Y38: inout bit; -- PAD101 IO_Y39: inout bit; -- PAD106 IO_Y40: inout bit; -- PAD105 IO_Y42: inout bit; -- PAD108 IO_AA29: inout bit; -- PAD196 IO_AA30: inout bit; -- PAD197 IO_AA31: inout bit; -- PAD192 IO_AA32: inout bit; -- PAD193 IO_AA34: inout bit; -- PAD170 IO_AA35: inout bit; -- PAD171 IO_AA36: inout bit; -- PAD167 IO_AA37: inout bit; -- PAD165 IO_AA39: inout bit; -- PAD107 IO_AA40: inout bit; -- PAD112 IO_AA41: inout bit; -- PAD113 IO_AA42: inout bit; -- PAD109 IO_AB29: inout bit; -- PAD198 IO_AB31: inout bit; -- PAD172 IO_AB32: inout bit; -- PAD173 IO_AB33: inout bit; -- PAD174 IO_AB34: inout bit; -- PAD200 IO_AB36: inout bit; -- PAD168 IO_AB37: inout bit; -- PAD169 IO_AB38: inout bit; -- PAD110 IO_AB39: inout bit; -- PAD111 IO_AB41: inout bit; -- PAD102 IO_AB42: inout bit; -- PAD103 IO_AC29: inout bit; -- PAD199 IO_AC30: inout bit; -- PAD194 IO_AC31: inout bit; -- PAD190 IO_AC33: inout bit; -- PAD175 IO_AC34: inout bit; -- PAD178 IO_AC35: inout bit; -- PAD160 IO_AC36: inout bit; -- PAD161 IO_AC38: inout bit; -- PAD114 IO_AC39: inout bit; -- PAD115 IO_AC40: inout bit; -- PAD120 IO_AC41: inout bit; -- PAD121 IO_AD30: inout bit; -- PAD195 IO_AD31: inout bit; -- PAD191 IO_AD32: inout bit; -- PAD176 IO_AD33: inout bit; -- PAD177 IO_AD35: inout bit; -- PAD179 IO_AD36: inout bit; -- PAD158 IO_AD37: inout bit; -- PAD159 IO_AD38: inout bit; -- PAD118 IO_AD40: inout bit; -- PAD124 IO_AD41: inout bit; -- PAD125 IO_AD42: inout bit; -- PAD116 IO_AE29: inout bit; -- PAD186 IO_AE30: inout bit; -- PAD187 IO_AE32: inout bit; -- PAD180 IO_AE33: inout bit; -- PAD181 IO_AE34: inout bit; -- PAD184 IO_AE35: inout bit; -- PAD185 IO_AE37: inout bit; -- PAD154 IO_AE38: inout bit; -- PAD119 IO_AE39: inout bit; -- PAD122 IO_AE40: inout bit; -- PAD123 IO_AE42: inout bit; -- PAD117 IO_AF29: inout bit; -- PAD292 IO_AF30: inout bit; -- PAD296 IO_AF31: inout bit; -- PAD182 IO_AF32: inout bit; -- PAD183 IO_AF34: inout bit; -- PAD156 IO_AF35: inout bit; -- PAD152 IO_AF36: inout bit; -- PAD153 IO_AF37: inout bit; -- PAD155 IO_AF39: inout bit; -- PAD126 IO_AF40: inout bit; -- PAD127 IO_AF41: inout bit; -- PAD128 IO_AF42: inout bit; -- PAD132 IO_AG29: inout bit; -- PAD293 IO_AG31: inout bit; -- PAD297 IO_AG32: inout bit; -- PAD300 IO_AG33: inout bit; -- PAD264 IO_AG34: inout bit; -- PAD157 IO_AG36: inout bit; -- PAD162 IO_AG37: inout bit; -- PAD150 IO_AG38: inout bit; -- PAD134 IO_AG39: inout bit; -- PAD130 IO_AG41: inout bit; -- PAD129 IO_AG42: inout bit; -- PAD133 IO_AH28: inout bit; -- PAD298 IO_AH29: inout bit; -- PAD288 IO_AH30: inout bit; -- PAD289 IO_AH31: inout bit; -- PAD268 IO_AH33: inout bit; -- PAD265 IO_AH34: inout bit; -- PAD270 IO_AH35: inout bit; -- PAD251 IO_AH36: inout bit; -- PAD163 IO_AH38: inout bit; -- PAD135 IO_AH39: inout bit; -- PAD131 IO_AH40: inout bit; -- PAD140 IO_AH41: inout bit; -- PAD141 IO_AJ12: inout bit; -- PAD909 IO_AJ13: inout bit; -- PAD908 IO_AJ15: inout bit; -- PAD903 IO_AJ16: inout bit; -- PAD902 IO_AJ17: inout bit; -- PAD863 IO_AJ18: inout bit; -- PAD862 IO_AJ20: inout bit; -- PAD811 IO_AJ21: inout bit; -- PAD810 IO_AJ22: inout bit; -- PAD806 IO_AJ23: inout bit; -- PAD802 IO_AJ25: inout bit; -- PAD398 IO_AJ26: inout bit; -- PAD399 IO_AJ28: inout bit; -- PAD299 IO_AJ30: inout bit; -- PAD290 IO_AJ31: inout bit; -- PAD269 IO_AJ32: inout bit; -- PAD276 IO_AJ33: inout bit; -- PAD272 IO_AJ35: inout bit; -- PAD271 IO_AJ36: inout bit; -- PAD254 IO_AJ37: inout bit; -- PAD255 IO_AJ38: inout bit; -- PAD136 IO_AJ40: inout bit; -- PAD144 IO_AJ41: inout bit; -- PAD145 IO_AJ42: inout bit; -- PAD148 IO_AK12: inout bit; -- PAD912 IO_AK13: inout bit; -- PAD905 IO_AK14: inout bit; -- PAD904 IO_AK15: inout bit; -- PAD906 IO_AK17: inout bit; -- PAD854 IO_AK18: inout bit; -- PAD859 IO_AK19: inout bit; -- PAD858 IO_AK20: inout bit; -- PAD804 IO_AK22: inout bit; -- PAD807 IO_AK23: inout bit; -- PAD803 IO_AK24: inout bit; -- PAD394 IO_AK25: inout bit; -- PAD395 IO_AK27: inout bit; -- PAD390 IO_AK28: inout bit; -- PAD294 IO_AK29: inout bit; -- PAD295 IO_AK30: inout bit; -- PAD291 IO_AK32: inout bit; -- PAD277 IO_AK33: inout bit; -- PAD273 IO_AK34: inout bit; -- PAD274 IO_AK35: inout bit; -- PAD266 IO_AK37: inout bit; -- PAD258 IO_AK38: inout bit; -- PAD137 IO_AK39: inout bit; -- PAD146 IO_AK40: inout bit; -- PAD138 IO_AK42: inout bit; -- PAD149 IO_AL12: inout bit; -- PAD913 IO_AL14: inout bit; -- PAD907 IO_AL15: inout bit; -- PAD911 IO_AL16: inout bit; -- PAD910 IO_AL17: inout bit; -- PAD855 IO_AL19: inout bit; -- PAD852 IO_AL20: inout bit; -- PAD805 IO_AL21: inout bit; -- PAD808 IO_AL22: inout bit; -- PAD812 IO_AL24: inout bit; -- PAD801 IO_AL25: inout bit; -- PAD396 IO_AL26: inout bit; -- PAD397 IO_AL27: inout bit; -- PAD391 IO_AL29: inout bit; -- PAD286 IO_AL30: inout bit; -- PAD287 IO_AL31: inout bit; -- PAD278 IO_AL32: inout bit; -- PAD279 IO_AL34: inout bit; -- PAD275 IO_AL35: inout bit; -- PAD267 IO_AL36: inout bit; -- PAD262 IO_AL37: inout bit; -- PAD259 IO_AL39: inout bit; -- PAD147 IO_AL40: inout bit; -- PAD139 IO_AL41: inout bit; -- PAD142 IO_AL42: inout bit; -- PAD143 IO_AM11: inout bit; -- PAD917 IO_AM12: inout bit; -- PAD916 IO_AM13: inout bit; -- PAD914 IO_AM14: inout bit; -- PAD901 IO_AM16: inout bit; -- PAD860 IO_AM17: inout bit; -- PAD857 IO_AM18: inout bit; -- PAD856 IO_AM19: inout bit; -- PAD853 IO_AM21: inout bit; -- PAD809 IO_AM22: inout bit; -- PAD813 IO_AM23: inout bit; -- PAD816 IO_AM24: inout bit; -- PAD814 IO_AM26: inout bit; -- PAD392 IO_AM27: inout bit; -- PAD393 IO_AM28: inout bit; -- PAD388 IO_AM29: inout bit; -- PAD389 IO_AM31: inout bit; -- PAD282 IO_AM32: inout bit; -- PAD283 IO_AM33: inout bit; -- PAD284 IO_AM34: inout bit; -- PAD280 IO_AM36: inout bit; -- PAD252 IO_AM37: inout bit; -- PAD263 IO_AM38: inout bit; -- PAD201 IO_AM39: inout bit; -- PAD212 IO_AM41: inout bit; -- PAD204 IO_AM42: inout bit; -- PAD205 IO_AN11: inout bit; -- PAD920 IO_AN13: inout bit; -- PAD915 IO_AN14: inout bit; -- PAD919 IO_AN15: inout bit; -- PAD918 IO_AN16: inout bit; -- PAD861 IO_AN18: inout bit; -- PAD869 IO_AN19: inout bit; -- PAD868 IO_AN20: inout bit; -- PAD850 IO_AN21: inout bit; -- PAD820 IO_AN23: inout bit; -- PAD817 IO_AN24: inout bit; -- PAD815 IO_AN25: inout bit; -- PAD386 IO_AN26: inout bit; -- PAD387 IO_AN28: inout bit; -- PAD380 IO_AN29: inout bit; -- PAD351 IO_AN30: inout bit; -- PAD342 IO_AN31: inout bit; -- PAD346 IO_AN33: inout bit; -- PAD285 IO_AN34: inout bit; -- PAD281 IO_AN35: inout bit; -- PAD260 IO_AN36: inout bit; -- PAD253 IO_AN38: inout bit; -- PAD202 IO_AN39: inout bit; -- PAD213 IO_AN40: inout bit; -- PAD208 IO_AN41: inout bit; -- PAD209 IO_AP11: inout bit; -- PAD921 IO_AP12: inout bit; -- PAD930 IO_AP13: inout bit; -- PAD924 IO_AP15: inout bit; -- PAD950 IO_AP16: inout bit; -- PAD900 IO_AP17: inout bit; -- PAD865 IO_AP18: inout bit; -- PAD864 IO_AP20: inout bit; -- PAD866 IO_AP21: inout bit; -- PAD821 IO_AP22: inout bit; -- PAD819 IO_AP23: inout bit; -- PAD818 IO_AP25: inout bit; -- PAD384 IO_AP26: inout bit; -- PAD400 IO_AP27: inout bit; -- PAD378 IO_AP28: inout bit; -- PAD381 IO_AP30: inout bit; -- PAD343 IO_AP31: inout bit; -- PAD347 IO_AP32: inout bit; -- PAD344 IO_AP33: inout bit; -- PAD348 IO_AP35: inout bit; -- PAD261 IO_AP36: inout bit; -- PAD256 IO_AP37: inout bit; -- PAD257 IO_AP38: inout bit; -- PAD203 IO_AP40: inout bit; -- PAD214 IO_AP41: inout bit; -- PAD216 IO_AP42: inout bit; -- PAD217 IO_AR12: inout bit; -- PAD931 IO_AR13: inout bit; -- PAD925 IO_AR14: inout bit; -- PAD922 IO_AR15: inout bit; -- PAD932 IO_AR17: inout bit; -- PAD871 IO_AR18: inout bit; -- PAD870 IO_AR19: inout bit; -- PAD867 IO_AR20: inout bit; -- PAD851 IO_AR22: inout bit; -- PAD823 IO_AR23: inout bit; -- PAD822 IO_AR24: inout bit; -- PAD832 IO_AR25: inout bit; -- PAD385 IO_AR27: inout bit; -- PAD376 IO_AR28: inout bit; -- PAD379 IO_AR29: inout bit; -- PAD366 IO_AR30: inout bit; -- PAD338 IO_AR32: inout bit; -- PAD345 IO_AR33: inout bit; -- PAD349 IO_AR34: inout bit; -- PAD320 IO_AR35: inout bit; -- PAD301 IO_AR37: inout bit; -- PAD210 IO_AR38: inout bit; -- PAD206 IO_AR39: inout bit; -- PAD207 IO_AR40: inout bit; -- PAD215 IO_AR42: inout bit; -- PAD220 IO_AT12: inout bit; -- PAD934 IO_AT14: inout bit; -- PAD923 IO_AT15: inout bit; -- PAD933 IO_AT16: inout bit; -- PAD886 IO_AT17: inout bit; -- PAD874 IO_AT19: inout bit; -- PAD883 IO_AT20: inout bit; -- PAD882 IO_AT21: inout bit; -- PAD830 IO_AT22: inout bit; -- PAD824 IO_AT24: inout bit; -- PAD833 IO_AT25: inout bit; -- PAD382 IO_AT26: inout bit; -- PAD383 IO_AT27: inout bit; -- PAD377 IO_AT29: inout bit; -- PAD367 IO_AT30: inout bit; -- PAD339 IO_AT31: inout bit; -- PAD350 IO_AT32: inout bit; -- PAD318 IO_AT34: inout bit; -- PAD314 IO_AT35: inout bit; -- PAD321 IO_AT36: inout bit; -- PAD316 IO_AT37: inout bit; -- PAD211 IO_AT39: inout bit; -- PAD218 IO_AT40: inout bit; -- PAD219 IO_AT41: inout bit; -- PAD240 IO_AT42: inout bit; -- PAD221 IO_AU12: inout bit; -- PAD935 IO_AU13: inout bit; -- PAD927 IO_AU14: inout bit; -- PAD926 IO_AU16: inout bit; -- PAD887 IO_AU17: inout bit; -- PAD875 IO_AU18: inout bit; -- PAD872 IO_AU19: inout bit; -- PAD880 IO_AU21: inout bit; -- PAD831 IO_AU22: inout bit; -- PAD825 IO_AU23: inout bit; -- PAD826 IO_AU24: inout bit; -- PAD836 IO_AU26: inout bit; -- PAD374 IO_AU27: inout bit; -- PAD375 IO_AU28: inout bit; -- PAD372 IO_AU29: inout bit; -- PAD354 IO_AU31: inout bit; -- PAD340 IO_AU32: inout bit; -- PAD322 IO_AU33: inout bit; -- PAD319 IO_AU34: inout bit; -- PAD315 IO_AU36: inout bit; -- PAD317 IO_AU37: inout bit; -- PAD250 IO_AU38: inout bit; -- PAD224 IO_AU39: inout bit; -- PAD222 IO_AU41: inout bit; -- PAD244 IO_AU42: inout bit; -- PAD241 IO_AV13: inout bit; -- PAD928 IO_AV14: inout bit; -- PAD937 IO_AV15: inout bit; -- PAD936 IO_AV16: inout bit; -- PAD884 IO_AV18: inout bit; -- PAD873 IO_AV19: inout bit; -- PAD881 IO_AV20: inout bit; -- PAD890 IO_AV21: inout bit; -- PAD834 IO_AV23: inout bit; -- PAD827 IO_AV24: inout bit; -- PAD837 IO_AV25: inout bit; -- PAD368 IO_AV26: inout bit; -- PAD369 IO_AV28: inout bit; -- PAD373 IO_AV29: inout bit; -- PAD355 IO_AV30: inout bit; -- PAD336 IO_AV31: inout bit; -- PAD341 IO_AV33: inout bit; -- PAD323 IO_AV34: inout bit; -- PAD326 IO_AV35: inout bit; -- PAD327 IO_AV36: inout bit; -- PAD304 IO_AV38: inout bit; -- PAD225 IO_AV39: inout bit; -- PAD223 IO_AV40: inout bit; -- PAD226 IO_AV41: inout bit; -- PAD245 IO_AW12: inout bit; -- PAD940 IO_AW13: inout bit; -- PAD929 IO_AW15: inout bit; -- PAD938 IO_AW16: inout bit; -- PAD885 IO_AW17: inout bit; -- PAD879 IO_AW18: inout bit; -- PAD878 IO_AW20: inout bit; -- PAD891 IO_AW21: inout bit; -- PAD835 IO_AW22: inout bit; -- PAD829 IO_AW23: inout bit; -- PAD828 IO_AW25: inout bit; -- PAD364 IO_AW26: inout bit; -- PAD365 IO_AW27: inout bit; -- PAD370 IO_AW28: inout bit; -- PAD371 IO_AW30: inout bit; -- PAD332 IO_AW31: inout bit; -- PAD337 IO_AW32: inout bit; -- PAD324 IO_AW33: inout bit; -- PAD325 IO_AW35: inout bit; -- PAD312 IO_AW36: inout bit; -- PAD305 IO_AW37: inout bit; -- PAD230 IO_AW38: inout bit; -- PAD234 IO_AW40: inout bit; -- PAD227 IO_AW41: inout bit; -- PAD248 IO_AW42: inout bit; -- PAD249 IO_AY12: inout bit; -- PAD941 IO_AY13: inout bit; -- PAD945 IO_AY14: inout bit; -- PAD944 IO_AY15: inout bit; -- PAD939 IO_AY17: inout bit; -- PAD877 IO_AY18: inout bit; -- PAD876 IO_AY19: inout bit; -- PAD898 IO_AY20: inout bit; -- PAD894 IO_AY22: inout bit; -- PAD839 IO_AY23: inout bit; -- PAD838 IO_AY24: inout bit; -- PAD844 IO_AY25: inout bit; -- PAD840 IO_AY27: inout bit; -- PAD352 IO_AY28: inout bit; -- PAD353 IO_AY29: inout bit; -- PAD362 IO_AY30: inout bit; -- PAD333 IO_AY32: inout bit; -- PAD328 IO_AY33: inout bit; -- PAD329 IO_AY34: inout bit; -- PAD302 IO_AY35: inout bit; -- PAD313 IO_AY37: inout bit; -- PAD231 IO_AY38: inout bit; -- PAD235 IO_AY39: inout bit; -- PAD228 IO_AY40: inout bit; -- PAD229 IO_AY42: inout bit; -- PAD242 IO_BA12: inout bit; -- PAD948 IO_BA14: inout bit; -- PAD943 IO_BA15: inout bit; -- PAD942 IO_BA16: inout bit; -- PAD896 IO_BA17: inout bit; -- PAD892 IO_BA19: inout bit; -- PAD899 IO_BA20: inout bit; -- PAD895 IO_BA21: inout bit; -- PAD846 IO_BA22: inout bit; -- PAD842 IO_BA24: inout bit; -- PAD845 IO_BA25: inout bit; -- PAD841 IO_BA26: inout bit; -- PAD356 IO_BA27: inout bit; -- PAD357 IO_BA29: inout bit; -- PAD363 IO_BA30: inout bit; -- PAD334 IO_BA31: inout bit; -- PAD330 IO_BA32: inout bit; -- PAD331 IO_BA34: inout bit; -- PAD306 IO_BA35: inout bit; -- PAD303 IO_BA36: inout bit; -- PAD308 IO_BA37: inout bit; -- PAD232 IO_BA39: inout bit; -- PAD238 IO_BA40: inout bit; -- PAD239 IO_BA41: inout bit; -- PAD246 IO_BA42: inout bit; -- PAD243 IO_BB12: inout bit; -- PAD949 IO_BB13: inout bit; -- PAD947 IO_BB14: inout bit; -- PAD946 IO_BB16: inout bit; -- PAD897 IO_BB17: inout bit; -- PAD893 IO_BB18: inout bit; -- PAD889 IO_BB19: inout bit; -- PAD888 IO_BB21: inout bit; -- PAD847 IO_BB22: inout bit; -- PAD843 IO_BB23: inout bit; -- PAD849 IO_BB24: inout bit; -- PAD848 IO_BB26: inout bit; -- PAD360 IO_BB27: inout bit; -- PAD361 IO_BB28: inout bit; -- PAD358 IO_BB29: inout bit; -- PAD359 IO_BB31: inout bit; -- PAD335 IO_BB32: inout bit; -- PAD310 IO_BB33: inout bit; -- PAD311 IO_BB34: inout bit; -- PAD307 IO_BB36: inout bit; -- PAD309 IO_BB37: inout bit; -- PAD233 IO_BB38: inout bit; -- PAD236 IO_BB39: inout bit; -- PAD237 IO_BB41: inout bit -- PAD247 ); --end port list -- Use Statements use STD_1149_1_2001.all; use STD_1149_6_2003.all; -- Component Conformance Statement(s) attribute COMPONENT_CONFORMANCE of XC7VX690T_FFG1761 : entity is "STD_1149_1_2001"; -- Device Package Pin Mappings attribute PIN_MAP of XC7VX690T_FFG1761 : entity is PHYSICAL_PIN_MAP; constant FFG1761: PIN_MAP_STRING:= "CCLK_N10:N10," & "CFGBVS_AH10:AH10," & "DONE_AL11:AL11," & "GND:(A2,A3,A4,A7,A8,A11,A13,A18,A28,A38," & "B1,B2,B5,B9,B10,B12,B13,B15,B25,B35," & "C3,C7,C11,C12,C22,C32,C42,D1,D2,D5," & "D9,D10,D11,D19,D29,D39,E3,E7,E11,E16," & "E26,E36,F1,F2,F5,F9,F10,F11,F13,F23," & "F33,G3,G7,G11,G20,G30,G40,H1,H2,H5," & "H9,H10,H11,H17,H27,H37,J3,J7,J9,J10," & "J14,J24,J34,K1,K2,K5,K6,K9,K10,K11," & "K21,K31,K41,L3,L7,L9,L10,L18,L28,L38," & "M1,M2,M5,M6,M9,M15,M25,M35,N3,N7," & "N9,N12,N22,N32,N42,P1,P2,P5,P9,P12," & "P16,P19,P29,P39,R3,R7,R9,R11,R13,R15," & "R17,R19,R21,R23,R25,R27,R36,T1,T2,T5," & "T6,T9,T12,T14,T16,T18,T20,T22,T24,T26," & "T33,U3,U4,U7,U9,U10,U11,U13,U15,U17," & "U19,U21,U23,U25,U27,U30,U40,V1,V2,V5," & "V6,V9,V10,V12,V14,V16,V18,V20,V22,V24," & "V26,V28,V37,W3,W7,W11,W13,W15,W17,W19," & "W21,W23,W25,W27,W34,Y1,Y2,Y5,Y6,Y9," & "Y10,Y12,Y14,Y16,Y18,Y22,Y24,Y26,Y28,Y31," & "Y41,AA3,AA7,AA9,AA11,AA13,AA15,AA17,AA19,AA23," & "AA25,AA27,AA38,AB1,AB2,AB5,AB6,AB9,AB10,AB12," & "AB14,AB16,AB18,AB22,AB24,AB26,AB28,AB35,AC3,AC7," & "AC11,AC13,AC15,AC17,AC19,AC23,AC25,AC27,AC32,AC42," & "AD1,AD2,AD5,AD6,AD9,AD10,AD12,AD14,AD16,AD18," & "AD20,AD22,AD24,AD26,AD28,AD29,AD39,AE3,AE7,AE9," & "AE11,AE13,AE15,AE17,AE19,AE21,AE23,AE25,AE27,AE36," & "AF1,AF2,AF5,AF6,AF9,AF10,AF12,AF14,AF16,AF18," & "AF20,AF22,AF24,AF26,AF33,AG3,AG4,AG7,AG8,AG9," & "AG10,AG13,AG15,AG17,AG19,AG21,AG23,AG25,AG27,AG30," & "AG40,AH1,AH2,AH5,AH6,AH9,AH12,AH14,AH16,AH17," & "AH18,AH20,AH22,AH24,AH26,AH37,AJ3,AJ7,AJ9,AJ14," & "AJ24,AJ27,AJ34,AK1,AK2,AK5,AK6,AK9,AK11,AK21," & "AK31,AK41,AL3,AL7,AL9,AL18,AL28,AL38,AM1,AM2," & "AM5,AM9,AM10,AM15,AM25,AM35,AN3,AN7,AN9,AN10," & "AN12,AN22,AN32,AN42,AP1,AP2,AP5,AP9,AP10,AP19," & "AP29,AP39,AR3,AR7,AR9,AR10,AR16,AR26,AR36,AT1," & "AT2,AT5,AT6,AT9,AT10,AT11,AT13,AT23,AT33,AU3," & "AU7,AU11,AU20,AU30,AU40,AV1,AV2,AV5,AV9,AV10," & "AV11,AV17,AV27,AV37,AW3,AW7,AW11,AW14,AW24,AW34," & "AY1,AY2,AY5,AY9,AY10,AY11,AY21,AY31,AY41,BA3," & "BA7,BA11,BA18,BA28,BA38,BB2,BB5,BB6,BB9,BB10," & "BB11,BB15,BB25,BB35)," & "GNDADC_0:Y20," & "INIT_B_AG11:AG11," & "M0_AL10:AL10," & "M1_AK10:AK10," & "M2_AJ10:AJ10," & "MGTAVCC_G10:(W8,AA8,AC8,AE8,AJ8,AL8,AN8,AR8,AU8,AW8," & "BA8)," & "MGTAVCC_G11:(C8,E8,G8,J8,L8)," & "MGTAVTTRCAL_115:A12," & "MGTAVTT_G10:(R4,W4,AA4,AC4,AE4,AJ4,AL4,AM6,AN4,AP6," & "AR4,AU4,AV6,AW4,AY6,BA4)," & "MGTAVTT_G11:(B6,C4,D6,E4,F6,G4,H6,J4,L4,N4," & "P6)," & "MGTHRXN0_111:BB7," & "MGTHRXN0_112:AV7," & "MGTHRXN0_113:AN5," & "MGTHRXN0_114:AG5," & "MGTHRXN0_115:AC5," & "MGTHRXN0_116:W5," & "MGTHRXN0_117:P7," & "MGTHRXN0_118:H7," & "MGTHRXN0_119:D7," & "MGTHRXN1_111:BA5," & "MGTHRXN1_112:AU5," & "MGTHRXN1_113:AM7," & "MGTHRXN1_114:AF3," & "MGTHRXN1_115:AB3," & "MGTHRXN1_116:V3," & "MGTHRXN1_117:N5," & "MGTHRXN1_118:G5," & "MGTHRXN1_119:C5," & "MGTHRXN2_111:AY7," & "MGTHRXN2_112:AR5," & "MGTHRXN2_113:AL5," & "MGTHRXN2_114:AE5," & "MGTHRXN2_115:AA5," & "MGTHRXN2_116:U5," & "MGTHRXN2_117:L5," & "MGTHRXN2_118:F7," & "MGTHRXN2_119:B7," & "MGTHRXN3_111:AW5," & "MGTHRXN3_112:AP7," & "MGTHRXN3_113:AJ5," & "MGTHRXN3_114:AD3," & "MGTHRXN3_115:Y3," & "MGTHRXN3_116:R5," & "MGTHRXN3_117:J5," & "MGTHRXN3_118:E5," & "MGTHRXN3_119:A5," & "MGTHRXP0_111:BB8," & "MGTHRXP0_112:AV8," & "MGTHRXP0_113:AN6," & "MGTHRXP0_114:AG6," & "MGTHRXP0_115:AC6," & "MGTHRXP0_116:W6," & "MGTHRXP0_117:P8," & "MGTHRXP0_118:H8," & "MGTHRXP0_119:D8," & "MGTHRXP1_111:BA6," & "MGTHRXP1_112:AU6," & "MGTHRXP1_113:AM8," & "MGTHRXP1_114:AF4," & "MGTHRXP1_115:AB4," & "MGTHRXP1_116:V4," & "MGTHRXP1_117:N6," & "MGTHRXP1_118:G6," & "MGTHRXP1_119:C6," & "MGTHRXP2_111:AY8," & "MGTHRXP2_112:AR6," & "MGTHRXP2_113:AL6," & "MGTHRXP2_114:AE6," & "MGTHRXP2_115:AA6," & "MGTHRXP2_116:U6," & "MGTHRXP2_117:L6," & "MGTHRXP2_118:F8," & "MGTHRXP2_119:B8," & "MGTHRXP3_111:AW6," & "MGTHRXP3_112:AP8," & "MGTHRXP3_113:AJ6," & "MGTHRXP3_114:AD4," & "MGTHRXP3_115:Y4," & "MGTHRXP3_116:R6," & "MGTHRXP3_117:J6," & "MGTHRXP3_118:E6," & "MGTHRXP3_119:A6," & "MGTHTXN0_111:BB3," & "MGTHTXN0_112:AV3," & "MGTHTXN0_113:AP3," & "MGTHTXN0_114:AK3," & "MGTHTXN0_115:AE1," & "MGTHTXN0_116:U1," & "MGTHTXN0_117:N1," & "MGTHTXN0_118:J1," & "MGTHTXN0_119:E1," & "MGTHTXN1_111:BA1," & "MGTHTXN1_112:AU1," & "MGTHTXN1_113:AN1," & "MGTHTXN1_114:AJ1," & "MGTHTXN1_115:AC1," & "MGTHTXN1_116:T3," & "MGTHTXN1_117:M3," & "MGTHTXN1_118:H3," & "MGTHTXN1_119:D3," & "MGTHTXN2_111:AY3," & "MGTHTXN2_112:AT3," & "MGTHTXN2_113:AM3," & "MGTHTXN2_114:AH3," & "MGTHTXN2_115:AA1," & "MGTHTXN2_116:R1," & "MGTHTXN2_117:L1," & "MGTHTXN2_118:G1," & "MGTHTXN2_119:C1," & "MGTHTXN3_111:AW1," & "MGTHTXN3_112:AR1," & "MGTHTXN3_113:AL1," & "MGTHTXN3_114:AG1," & "MGTHTXN3_115:W1," & "MGTHTXN3_116:P3," & "MGTHTXN3_117:K3," & "MGTHTXN3_118:F3," & "MGTHTXN3_119:B3," & "MGTHTXP0_111:BB4," & "MGTHTXP0_112:AV4," & "MGTHTXP0_113:AP4," & "MGTHTXP0_114:AK4," & "MGTHTXP0_115:AE2," & "MGTHTXP0_116:U2," & "MGTHTXP0_117:N2," & "MGTHTXP0_118:J2," & "MGTHTXP0_119:E2," & "MGTHTXP1_111:BA2," & "MGTHTXP1_112:AU2," & "MGTHTXP1_113:AN2," & "MGTHTXP1_114:AJ2," & "MGTHTXP1_115:AC2," & "MGTHTXP1_116:T4," & "MGTHTXP1_117:M4," & "MGTHTXP1_118:H4," & "MGTHTXP1_119:D4," & "MGTHTXP2_111:AY4," & "MGTHTXP2_112:AT4," & "MGTHTXP2_113:AM4," & "MGTHTXP2_114:AH4," & "MGTHTXP2_115:AA2," & "MGTHTXP2_116:R2," & "MGTHTXP2_117:L2," & "MGTHTXP2_118:G2," & "MGTHTXP2_119:C2," & "MGTHTXP3_111:AW2," & "MGTHTXP3_112:AR2," & "MGTHTXP3_113:AL2," & "MGTHTXP3_114:AG2," & "MGTHTXP3_115:W2," & "MGTHTXP3_116:P4," & "MGTHTXP3_117:K4," & "MGTHTXP3_118:F4," & "MGTHTXP3_119:B4," & "MGTREFCLK0N_111:AW9," & "MGTREFCLK0N_112:AT7," & "MGTREFCLK0N_113:AH7," & "MGTREFCLK0N_114:AD7," & "MGTREFCLK0N_115:Y7," & "MGTREFCLK0N_116:T7," & "MGTREFCLK0N_117:K7," & "MGTREFCLK0N_118:E9," & "MGTREFCLK0N_119:A9," & "MGTREFCLK0P_111:AW10," & "MGTREFCLK0P_112:AT8," & "MGTREFCLK0P_113:AH8," & "MGTREFCLK0P_114:AD8," & "MGTREFCLK0P_115:Y8," & "MGTREFCLK0P_116:T8," & "MGTREFCLK0P_117:K8," & "MGTREFCLK0P_118:E10," & "MGTREFCLK0P_119:A10," & "MGTREFCLK1N_111:BA9," & "MGTREFCLK1N_112:AU9," & "MGTREFCLK1N_113:AK7," & "MGTREFCLK1N_114:AF7," & "MGTREFCLK1N_115:AB7," & "MGTREFCLK1N_116:V7," & "MGTREFCLK1N_117:M7," & "MGTREFCLK1N_118:G9," & "MGTREFCLK1N_119:C9," & "MGTREFCLK1P_111:BA10," & "MGTREFCLK1P_112:AU10," & "MGTREFCLK1P_113:AK8," & "MGTREFCLK1P_114:AF8," & "MGTREFCLK1P_115:AB8," & "MGTREFCLK1P_116:V8," & "MGTREFCLK1P_117:M8," & "MGTREFCLK1P_118:G10," & "MGTREFCLK1P_119:C10," & "MGTRREF_115:B11," & "MGTVCCAUX_G10:(R8,U8)," & "MGTVCCAUX_G11:N8," & "NOCONNECT:(W9,W10,AC9,AC10)," & "PROGRAM_B:AJ11," & "TCK:P10," & "TDI:T10," & "TDN_AC20:AC20," & "TDO:R10," & "TDP_AC21:AC21," & "TMS:P11," & "VCCADC_0:Y21," & "VCCAUX:(R18,R26,T17,T19,T25,U18,U26,V17,V25,W18," & "W26,Y17,Y25,AA18,AA26,AB17,AB25,AC18,AC26,AD17," & "AD25,AE18,AE26,AF17,AF19,AF25,AG18,AG26,AH25)," & "VCCBATT_0:N11," & "VCCBRAM:(R22,U22,W22,AA22,AC22,AE22,AG22,AH21)," & "VCCINT:(P13,P15,P27,R12,R14,R16,R20,R24,T13,T15," & "T21,T23,T27,U12,U14,U16,U20,U24,V11,V13," & "V15,V19,V21,V23,V27,W12,W14,W16,W20,W24," & "W28,Y11,Y13,Y15,Y19,Y23,Y27,AA10,AA12,AA14," & "AA16,AA24,AA28,AB11,AB13,AB15,AB19,AB23,AB27,AC12," & "AC14,AC16,AC24,AC28,AD11,AD13,AD15,AD19,AD21,AD23," & "AD27,AE10,AE12,AE14,AE16,AE20,AE24,AE28,AF11,AF13," & "AF15,AF21,AF23,AF27,AG12,AG14,AG16,AG20,AG24,AG28," & "AH11,AH13,AH15,AH19,AH23,AH27)," & "VCCO_0:(M10,T11)," & "VCCO_12:(AK26,AN27,AT28,AU25,AW29,AY26)," & "VCCO_13:(AP34,AR31,AU35,AV32,AY36,BA33,BB30)," & "VCCO_14:(AF28,AH32,AJ29,AK36,AL33,AM30,AN37)," & "VCCO_15:(AM40,AR41,AT38,AV42,AW39,BB40)," & "VCCO_16:(Y36,AA33,AB30,AD34,AE31,AG35)," & "VCCO_17:(AB40,AC37,AE41,AF38,AH42,AJ39)," & "VCCO_18:(P34,T38,U35,V32,V42,W39)," & "VCCO_19:(B40,E41,H42,J39,M40,N37,R41)," & "VCCO_31:(AK16,AL13,AP14,AR11,AU15,AV12,BA13)," & "VCCO_32:(AJ19,AN17,AT18,AW19,AY16,BB20)," & "VCCO_33:(AL23,AM20,AP24,AR21,AV22,BA23)," & "VCCO_34:(H32,L33,M30,R31,T28,W29)," & "VCCO_35:(A33,C37,D34,E31,F38,G35,K36)," & "VCCO_36:(G25,H22,J29,K26,L23,N27,P24)," & "VCCO_37:(A23,B30,C27,D24,E21,F28)," & "VCCO_38:(B20,C17,F18,J19,M20,N17)," & "VCCO_39:(D14,G15,H12,K16,L13,P14)," & "VN_AB20:AB20," & "VP_AA21:AA21," & "VREFN_AA20:AA20," & "VREFP_AB21:AB21," & "IO_A14:A14," & "IO_A15:A15," & "IO_A16:A16," & "IO_A17:A17," & "IO_A19:A19," & "IO_A20:A20," & "IO_A21:A21," & "IO_A22:A22," & "IO_A24:A24," & "IO_A25:A25," & "IO_A26:A26," & "IO_A27:A27," & "IO_A29:A29," & "IO_A30:A30," & "IO_A31:A31," & "IO_A32:A32," & "IO_A34:A34," & "IO_A35:A35," & "IO_A36:A36," & "IO_A37:A37," & "IO_A39:A39," & "IO_A40:A40," & "IO_A41:A41," & "IO_B14:B14," & "IO_B16:B16," & "IO_B17:B17," & "IO_B18:B18," & "IO_B19:B19," & "IO_B21:B21," & "IO_B22:B22," & "IO_B23:B23," & "IO_B24:B24," & "IO_B26:B26," & "IO_B27:B27," & "IO_B28:B28," & "IO_B29:B29," & "IO_B31:B31," & "IO_B32:B32," & "IO_B33:B33," & "IO_B34:B34," & "IO_B36:B36," & "IO_B37:B37," & "IO_B38:B38," & "IO_B39:B39," & "IO_B41:B41," & "IO_B42:B42," & "IO_C13:C13," & "IO_C14:C14," & "IO_C15:C15," & "IO_C16:C16," & "IO_C18:C18," & "IO_C19:C19," & "IO_C20:C20," & "IO_C21:C21," & "IO_C23:C23," & "IO_C24:C24," & "IO_C25:C25," & "IO_C26:C26," & "IO_C28:C28," & "IO_C29:C29," & "IO_C30:C30," & "IO_C31:C31," & "IO_C33:C33," & "IO_C34:C34," & "IO_C35:C35," & "IO_C36:C36," & "IO_C38:C38," & "IO_C39:C39," & "IO_C40:C40," & "IO_C41:C41," & "IO_D12:D12," & "IO_D13:D13," & "IO_D15:D15," & "IO_D16:D16," & "IO_D17:D17," & "IO_D18:D18," & "IO_D20:D20," & "IO_D21:D21," & "IO_D22:D22," & "IO_D23:D23," & "IO_D25:D25," & "IO_D26:D26," & "IO_D27:D27," & "IO_D28:D28," & "IO_D30:D30," & "IO_D31:D31," & "IO_D32:D32," & "IO_D33:D33," & "IO_D35:D35," & "IO_D36:D36," & "IO_D37:D37," & "IO_D38:D38," & "IO_D40:D40," & "IO_D41:D41," & "IO_D42:D42," & "IO_E12:E12," & "IO_E13:E13," & "IO_E14:E14," & "IO_E15:E15," & "IO_E17:E17," & "IO_E18:E18," & "IO_E19:E19," & "IO_E20:E20," & "IO_E22:E22," & "IO_E23:E23," & "IO_E24:E24," & "IO_E25:E25," & "IO_E27:E27," & "IO_E28:E28," & "IO_E29:E29," & "IO_E30:E30," & "IO_E32:E32," & "IO_E33:E33," & "IO_E34:E34," & "IO_E35:E35," & "IO_E37:E37," & "IO_E38:E38," & "IO_E39:E39," & "IO_E40:E40," & "IO_E42:E42," & "IO_F12:F12," & "IO_F14:F14," & "IO_F15:F15," & "IO_F16:F16," & "IO_F17:F17," & "IO_F19:F19," & "IO_F20:F20," & "IO_F21:F21," & "IO_F22:F22," & "IO_F24:F24," & "IO_F25:F25," & "IO_F26:F26," & "IO_F27:F27," & "IO_F29:F29," & "IO_F30:F30," & "IO_F31:F31," & "IO_F32:F32," & "IO_F34:F34," & "IO_F35:F35," & "IO_F36:F36," & "IO_F37:F37," & "IO_F39:F39," & "IO_F40:F40," & "IO_F41:F41," & "IO_F42:F42," & "IO_G12:G12," & "IO_G13:G13," & "IO_G14:G14," & "IO_G16:G16," & "IO_G17:G17," & "IO_G18:G18," & "IO_G19:G19," & "IO_G21:G21," & "IO_G22:G22," & "IO_G23:G23," & "IO_G24:G24," & "IO_G26:G26," & "IO_G27:G27," & "IO_G28:G28," & "IO_G29:G29," & "IO_G31:G31," & "IO_G32:G32," & "IO_G33:G33," & "IO_G34:G34," & "IO_G36:G36," & "IO_G37:G37," & "IO_G38:G38," & "IO_G39:G39," & "IO_G41:G41," & "IO_G42:G42," & "IO_H13:H13," & "IO_H14:H14," & "IO_H15:H15," & "IO_H16:H16," & "IO_H18:H18," & "IO_H19:H19," & "IO_H20:H20," & "IO_H21:H21," & "IO_H23:H23," & "IO_H24:H24," & "IO_H25:H25," & "IO_H26:H26," & "IO_H28:H28," & "IO_H29:H29," & "IO_H30:H30," & "IO_H31:H31," & "IO_H33:H33," & "IO_H34:H34," & "IO_H35:H35," & "IO_H36:H36," & "IO_H38:H38," & "IO_H39:H39," & "IO_H40:H40," & "IO_H41:H41," & "IO_J11:J11," & "IO_J12:J12," & "IO_J13:J13," & "IO_J15:J15," & "IO_J16:J16," & "IO_J17:J17," & "IO_J18:J18," & "IO_J20:J20," & "IO_J21:J21," & "IO_J22:J22," & "IO_J23:J23," & "IO_J25:J25," & "IO_J26:J26," & "IO_J27:J27," & "IO_J28:J28," & "IO_J30:J30," & "IO_J31:J31," & "IO_J32:J32," & "IO_J33:J33," & "IO_J35:J35," & "IO_J36:J36," & "IO_J37:J37," & "IO_J38:J38," & "IO_J40:J40," & "IO_J41:J41," & "IO_J42:J42," & "IO_K12:K12," & "IO_K13:K13," & "IO_K14:K14," & "IO_K15:K15," & "IO_K17:K17," & "IO_K18:K18," & "IO_K19:K19," & "IO_K20:K20," & "IO_K22:K22," & "IO_K23:K23," & "IO_K24:K24," & "IO_K25:K25," & "IO_K27:K27," & "IO_K28:K28," & "IO_K29:K29," & "IO_K30:K30," & "IO_K32:K32," & "IO_K33:K33," & "IO_K34:K34," & "IO_K35:K35," & "IO_K37:K37," & "IO_K38:K38," & "IO_K39:K39," & "IO_K40:K40," & "IO_K42:K42," & "IO_L11:L11," & "IO_L12:L12," & "IO_L14:L14," & "IO_L15:L15," & "IO_L16:L16," & "IO_L17:L17," & "IO_L19:L19," & "IO_L20:L20," & "IO_L21:L21," & "IO_L22:L22," & "IO_L24:L24," & "IO_L25:L25," & "IO_L26:L26," & "IO_L27:L27," & "IO_L29:L29," & "IO_L30:L30," & "IO_L31:L31," & "IO_L32:L32," & "IO_L34:L34," & "IO_L35:L35," & "IO_L36:L36," & "IO_L37:L37," & "IO_L39:L39," & "IO_L40:L40," & "IO_L41:L41," & "IO_L42:L42," & "IO_M11:M11," & "IO_M12:M12," & "IO_M13:M13," & "IO_M14:M14," & "IO_M16:M16," & "IO_M17:M17," & "IO_M18:M18," & "IO_M19:M19," & "IO_M21:M21," & "IO_M22:M22," & "IO_M23:M23," & "IO_M24:M24," & "IO_M26:M26," & "IO_M27:M27," & "IO_M28:M28," & "IO_M29:M29," & "IO_M31:M31," & "IO_M32:M32," & "IO_M33:M33," & "IO_M34:M34," & "IO_M36:M36," & "IO_M37:M37," & "IO_M38:M38," & "IO_M39:M39," & "IO_M41:M41," & "IO_M42:M42," & "IO_N13:N13," & "IO_N14:N14," & "IO_N15:N15," & "IO_N16:N16," & "IO_N18:N18," & "IO_N19:N19," & "IO_N20:N20," & "IO_N21:N21," & "IO_N23:N23," & "IO_N24:N24," & "IO_N25:N25," & "IO_N26:N26," & "IO_N28:N28," & "IO_N29:N29," & "IO_N30:N30," & "IO_N31:N31," & "IO_N33:N33," & "IO_N34:N34," & "IO_N35:N35," & "IO_N36:N36," & "IO_N38:N38," & "IO_N39:N39," & "IO_N40:N40," & "IO_N41:N41," & "IO_P17:P17," & "IO_P18:P18," & "IO_P20:P20," & "IO_P21:P21," & "IO_P22:P22," & "IO_P23:P23," & "IO_P25:P25," & "IO_P26:P26," & "IO_P28:P28," & "IO_P30:P30," & "IO_P31:P31," & "IO_P32:P32," & "IO_P33:P33," & "IO_P35:P35," & "IO_P36:P36," & "IO_P37:P37," & "IO_P38:P38," & "IO_P40:P40," & "IO_P41:P41," & "IO_P42:P42," & "IO_R28:R28," & "IO_R29:R29," & "IO_R30:R30," & "IO_R32:R32," & "IO_R33:R33," & "IO_R34:R34," & "IO_R35:R35," & "IO_R37:R37," & "IO_R38:R38," & "IO_R39:R39," & "IO_R40:R40," & "IO_R42:R42," & "IO_T29:T29," & "IO_T30:T30," & "IO_T31:T31," & "IO_T32:T32," & "IO_T34:T34," & "IO_T35:T35," & "IO_T36:T36," & "IO_T37:T37," & "IO_T39:T39," & "IO_T40:T40," & "IO_T41:T41," & "IO_T42:T42," & "IO_U28:U28," & "IO_U29:U29," & "IO_U31:U31," & "IO_U32:U32," & "IO_U33:U33," & "IO_U34:U34," & "IO_U36:U36," & "IO_U37:U37," & "IO_U38:U38," & "IO_U39:U39," & "IO_U41:U41," & "IO_U42:U42," & "IO_V29:V29," & "IO_V30:V30," & "IO_V31:V31," & "IO_V33:V33," & "IO_V34:V34," & "IO_V35:V35," & "IO_V36:V36," & "IO_V38:V38," & "IO_V39:V39," & "IO_V40:V40," & "IO_V41:V41," & "IO_W30:W30," & "IO_W31:W31," & "IO_W32:W32," & "IO_W33:W33," & "IO_W35:W35," & "IO_W36:W36," & "IO_W37:W37," & "IO_W38:W38," & "IO_W40:W40," & "IO_W41:W41," & "IO_W42:W42," & "IO_Y29:Y29," & "IO_Y30:Y30," & "IO_Y32:Y32," & "IO_Y33:Y33," & "IO_Y34:Y34," & "IO_Y35:Y35," & "IO_Y37:Y37," & "IO_Y38:Y38," & "IO_Y39:Y39," & "IO_Y40:Y40," & "IO_Y42:Y42," & "IO_AA29:AA29," & "IO_AA30:AA30," & "IO_AA31:AA31," & "IO_AA32:AA32," & "IO_AA34:AA34," & "IO_AA35:AA35," & "IO_AA36:AA36," & "IO_AA37:AA37," & "IO_AA39:AA39," & "IO_AA40:AA40," & "IO_AA41:AA41," & "IO_AA42:AA42," & "IO_AB29:AB29," & "IO_AB31:AB31," & "IO_AB32:AB32," & "IO_AB33:AB33," & "IO_AB34:AB34," & "IO_AB36:AB36," & "IO_AB37:AB37," & "IO_AB38:AB38," & "IO_AB39:AB39," & "IO_AB41:AB41," & "IO_AB42:AB42," & "IO_AC29:AC29," & "IO_AC30:AC30," & "IO_AC31:AC31," & "IO_AC33:AC33," & "IO_AC34:AC34," & "IO_AC35:AC35," & "IO_AC36:AC36," & "IO_AC38:AC38," & "IO_AC39:AC39," & "IO_AC40:AC40," & "IO_AC41:AC41," & "IO_AD30:AD30," & "IO_AD31:AD31," & "IO_AD32:AD32," & "IO_AD33:AD33," & "IO_AD35:AD35," & "IO_AD36:AD36," & "IO_AD37:AD37," & "IO_AD38:AD38," & "IO_AD40:AD40," & "IO_AD41:AD41," & "IO_AD42:AD42," & "IO_AE29:AE29," & "IO_AE30:AE30," & "IO_AE32:AE32," & "IO_AE33:AE33," & "IO_AE34:AE34," & "IO_AE35:AE35," & "IO_AE37:AE37," & "IO_AE38:AE38," & "IO_AE39:AE39," & "IO_AE40:AE40," & "IO_AE42:AE42," & "IO_AF29:AF29," & "IO_AF30:AF30," & "IO_AF31:AF31," & "IO_AF32:AF32," & "IO_AF34:AF34," & "IO_AF35:AF35," & "IO_AF36:AF36," & "IO_AF37:AF37," & "IO_AF39:AF39," & "IO_AF40:AF40," & "IO_AF41:AF41," & "IO_AF42:AF42," & "IO_AG29:AG29," & "IO_AG31:AG31," & "IO_AG32:AG32," & "IO_AG33:AG33," & "IO_AG34:AG34," & "IO_AG36:AG36," & "IO_AG37:AG37," & "IO_AG38:AG38," & "IO_AG39:AG39," & "IO_AG41:AG41," & "IO_AG42:AG42," & "IO_AH28:AH28," & "IO_AH29:AH29," & "IO_AH30:AH30," & "IO_AH31:AH31," & "IO_AH33:AH33," & "IO_AH34:AH34," & "IO_AH35:AH35," & "IO_AH36:AH36," & "IO_AH38:AH38," & "IO_AH39:AH39," & "IO_AH40:AH40," & "IO_AH41:AH41," & "IO_AJ12:AJ12," & "IO_AJ13:AJ13," & "IO_AJ15:AJ15," & "IO_AJ16:AJ16," & "IO_AJ17:AJ17," & "IO_AJ18:AJ18," & "IO_AJ20:AJ20," & "IO_AJ21:AJ21," & "IO_AJ22:AJ22," & "IO_AJ23:AJ23," & "IO_AJ25:AJ25," & "IO_AJ26:AJ26," & "IO_AJ28:AJ28," & "IO_AJ30:AJ30," & "IO_AJ31:AJ31," & "IO_AJ32:AJ32," & "IO_AJ33:AJ33," & "IO_AJ35:AJ35," & "IO_AJ36:AJ36," & "IO_AJ37:AJ37," & "IO_AJ38:AJ38," & "IO_AJ40:AJ40," & "IO_AJ41:AJ41," & "IO_AJ42:AJ42," & "IO_AK12:AK12," & "IO_AK13:AK13," & "IO_AK14:AK14," & "IO_AK15:AK15," & "IO_AK17:AK17," & "IO_AK18:AK18," & "IO_AK19:AK19," & "IO_AK20:AK20," & "IO_AK22:AK22," & "IO_AK23:AK23," & "IO_AK24:AK24," & "IO_AK25:AK25," & "IO_AK27:AK27," & "IO_AK28:AK28," & "IO_AK29:AK29," & "IO_AK30:AK30," & "IO_AK32:AK32," & "IO_AK33:AK33," & "IO_AK34:AK34," & "IO_AK35:AK35," & "IO_AK37:AK37," & "IO_AK38:AK38," & "IO_AK39:AK39," & "IO_AK40:AK40," & "IO_AK42:AK42," & "IO_AL12:AL12," & "IO_AL14:AL14," & "IO_AL15:AL15," & "IO_AL16:AL16," & "IO_AL17:AL17," & "IO_AL19:AL19," & "IO_AL20:AL20," & "IO_AL21:AL21," & "IO_AL22:AL22," & "IO_AL24:AL24," & "IO_AL25:AL25," & "IO_AL26:AL26," & "IO_AL27:AL27," & "IO_AL29:AL29," & "IO_AL30:AL30," & "IO_AL31:AL31," & "IO_AL32:AL32," & "IO_AL34:AL34," & "IO_AL35:AL35," & "IO_AL36:AL36," & "IO_AL37:AL37," & "IO_AL39:AL39," & "IO_AL40:AL40," & "IO_AL41:AL41," & "IO_AL42:AL42," & "IO_AM11:AM11," & "IO_AM12:AM12," & "IO_AM13:AM13," & "IO_AM14:AM14," & "IO_AM16:AM16," & "IO_AM17:AM17," & "IO_AM18:AM18," & "IO_AM19:AM19," & "IO_AM21:AM21," & "IO_AM22:AM22," & "IO_AM23:AM23," & "IO_AM24:AM24," & "IO_AM26:AM26," & "IO_AM27:AM27," & "IO_AM28:AM28," & "IO_AM29:AM29," & "IO_AM31:AM31," & "IO_AM32:AM32," & "IO_AM33:AM33," & "IO_AM34:AM34," & "IO_AM36:AM36," & "IO_AM37:AM37," & "IO_AM38:AM38," & "IO_AM39:AM39," & "IO_AM41:AM41," & "IO_AM42:AM42," & "IO_AN11:AN11," & "IO_AN13:AN13," & "IO_AN14:AN14," & "IO_AN15:AN15," & "IO_AN16:AN16," & "IO_AN18:AN18," & "IO_AN19:AN19," & "IO_AN20:AN20," & "IO_AN21:AN21," & "IO_AN23:AN23," & "IO_AN24:AN24," & "IO_AN25:AN25," & "IO_AN26:AN26," & "IO_AN28:AN28," & "IO_AN29:AN29," & "IO_AN30:AN30," & "IO_AN31:AN31," & "IO_AN33:AN33," & "IO_AN34:AN34," & "IO_AN35:AN35," & "IO_AN36:AN36," & "IO_AN38:AN38," & "IO_AN39:AN39," & "IO_AN40:AN40," & "IO_AN41:AN41," & "IO_AP11:AP11," & "IO_AP12:AP12," & "IO_AP13:AP13," & "IO_AP15:AP15," & "IO_AP16:AP16," & "IO_AP17:AP17," & "IO_AP18:AP18," & "IO_AP20:AP20," & "IO_AP21:AP21," & "IO_AP22:AP22," & "IO_AP23:AP23," & "IO_AP25:AP25," & "IO_AP26:AP26," & "IO_AP27:AP27," & "IO_AP28:AP28," & "IO_AP30:AP30," & "IO_AP31:AP31," & "IO_AP32:AP32," & "IO_AP33:AP33," & "IO_AP35:AP35," & "IO_AP36:AP36," & "IO_AP37:AP37," & "IO_AP38:AP38," & "IO_AP40:AP40," & "IO_AP41:AP41," & "IO_AP42:AP42," & "IO_AR12:AR12," & "IO_AR13:AR13," & "IO_AR14:AR14," & "IO_AR15:AR15," & "IO_AR17:AR17," & "IO_AR18:AR18," & "IO_AR19:AR19," & "IO_AR20:AR20," & "IO_AR22:AR22," & "IO_AR23:AR23," & "IO_AR24:AR24," & "IO_AR25:AR25," & "IO_AR27:AR27," & "IO_AR28:AR28," & "IO_AR29:AR29," & "IO_AR30:AR30," & "IO_AR32:AR32," & "IO_AR33:AR33," & "IO_AR34:AR34," & "IO_AR35:AR35," & "IO_AR37:AR37," & "IO_AR38:AR38," & "IO_AR39:AR39," & "IO_AR40:AR40," & "IO_AR42:AR42," & "IO_AT12:AT12," & "IO_AT14:AT14," & "IO_AT15:AT15," & "IO_AT16:AT16," & "IO_AT17:AT17," & "IO_AT19:AT19," & "IO_AT20:AT20," & "IO_AT21:AT21," & "IO_AT22:AT22," & "IO_AT24:AT24," & "IO_AT25:AT25," & "IO_AT26:AT26," & "IO_AT27:AT27," & "IO_AT29:AT29," & "IO_AT30:AT30," & "IO_AT31:AT31," & "IO_AT32:AT32," & "IO_AT34:AT34," & "IO_AT35:AT35," & "IO_AT36:AT36," & "IO_AT37:AT37," & "IO_AT39:AT39," & "IO_AT40:AT40," & "IO_AT41:AT41," & "IO_AT42:AT42," & "IO_AU12:AU12," & "IO_AU13:AU13," & "IO_AU14:AU14," & "IO_AU16:AU16," & "IO_AU17:AU17," & "IO_AU18:AU18," & "IO_AU19:AU19," & "IO_AU21:AU21," & "IO_AU22:AU22," & "IO_AU23:AU23," & "IO_AU24:AU24," & "IO_AU26:AU26," & "IO_AU27:AU27," & "IO_AU28:AU28," & "IO_AU29:AU29," & "IO_AU31:AU31," & "IO_AU32:AU32," & "IO_AU33:AU33," & "IO_AU34:AU34," & "IO_AU36:AU36," & "IO_AU37:AU37," & "IO_AU38:AU38," & "IO_AU39:AU39," & "IO_AU41:AU41," & "IO_AU42:AU42," & "IO_AV13:AV13," & "IO_AV14:AV14," & "IO_AV15:AV15," & "IO_AV16:AV16," & "IO_AV18:AV18," & "IO_AV19:AV19," & "IO_AV20:AV20," & "IO_AV21:AV21," & "IO_AV23:AV23," & "IO_AV24:AV24," & "IO_AV25:AV25," & "IO_AV26:AV26," & "IO_AV28:AV28," & "IO_AV29:AV29," & "IO_AV30:AV30," & "IO_AV31:AV31," & "IO_AV33:AV33," & "IO_AV34:AV34," & "IO_AV35:AV35," & "IO_AV36:AV36," & "IO_AV38:AV38," & "IO_AV39:AV39," & "IO_AV40:AV40," & "IO_AV41:AV41," & "IO_AW12:AW12," & "IO_AW13:AW13," & "IO_AW15:AW15," & "IO_AW16:AW16," & "IO_AW17:AW17," & "IO_AW18:AW18," & "IO_AW20:AW20," & "IO_AW21:AW21," & "IO_AW22:AW22," & "IO_AW23:AW23," & "IO_AW25:AW25," & "IO_AW26:AW26," & "IO_AW27:AW27," & "IO_AW28:AW28," & "IO_AW30:AW30," & "IO_AW31:AW31," & "IO_AW32:AW32," & "IO_AW33:AW33," & "IO_AW35:AW35," & "IO_AW36:AW36," & "IO_AW37:AW37," & "IO_AW38:AW38," & "IO_AW40:AW40," & "IO_AW41:AW41," & "IO_AW42:AW42," & "IO_AY12:AY12," & "IO_AY13:AY13," & "IO_AY14:AY14," & "IO_AY15:AY15," & "IO_AY17:AY17," & "IO_AY18:AY18," & "IO_AY19:AY19," & "IO_AY20:AY20," & "IO_AY22:AY22," & "IO_AY23:AY23," & "IO_AY24:AY24," & "IO_AY25:AY25," & "IO_AY27:AY27," & "IO_AY28:AY28," & "IO_AY29:AY29," & "IO_AY30:AY30," & "IO_AY32:AY32," & "IO_AY33:AY33," & "IO_AY34:AY34," & "IO_AY35:AY35," & "IO_AY37:AY37," & "IO_AY38:AY38," & "IO_AY39:AY39," & "IO_AY40:AY40," & "IO_AY42:AY42," & "IO_BA12:BA12," & "IO_BA14:BA14," & "IO_BA15:BA15," & "IO_BA16:BA16," & "IO_BA17:BA17," & "IO_BA19:BA19," & "IO_BA20:BA20," & "IO_BA21:BA21," & "IO_BA22:BA22," & "IO_BA24:BA24," & "IO_BA25:BA25," & "IO_BA26:BA26," & "IO_BA27:BA27," & "IO_BA29:BA29," & "IO_BA30:BA30," & "IO_BA31:BA31," & "IO_BA32:BA32," & "IO_BA34:BA34," & "IO_BA35:BA35," & "IO_BA36:BA36," & "IO_BA37:BA37," & "IO_BA39:BA39," & "IO_BA40:BA40," & "IO_BA41:BA41," & "IO_BA42:BA42," & "IO_BB12:BB12," & "IO_BB13:BB13," & "IO_BB14:BB14," & "IO_BB16:BB16," & "IO_BB17:BB17," & "IO_BB18:BB18," & "IO_BB19:BB19," & "IO_BB21:BB21," & "IO_BB22:BB22," & "IO_BB23:BB23," & "IO_BB24:BB24," & "IO_BB26:BB26," & "IO_BB27:BB27," & "IO_BB28:BB28," & "IO_BB29:BB29," & "IO_BB31:BB31," & "IO_BB32:BB32," & "IO_BB33:BB33," & "IO_BB34:BB34," & "IO_BB36:BB36," & "IO_BB37:BB37," & "IO_BB38:BB38," & "IO_BB39:BB39," & "IO_BB41:BB41"; -- Grouped Port Identification attribute PORT_GROUPING of XC7VX690T_FFG1761 : entity is "DIFFERENTIAL_VOLTAGE (" & "(MGTHRXP0_111, MGTHRXN0_111), " & "(MGTHRXP0_112, MGTHRXN0_112), " & "(MGTHRXP0_113, MGTHRXN0_113), " & "(MGTHRXP0_114, MGTHRXN0_114), " & "(MGTHRXP0_115, MGTHRXN0_115), " & "(MGTHRXP0_116, MGTHRXN0_116), " & "(MGTHRXP0_117, MGTHRXN0_117), " & "(MGTHRXP0_118, MGTHRXN0_118), " & "(MGTHRXP0_119, MGTHRXN0_119), " & "(MGTHRXP1_111, MGTHRXN1_111), " & "(MGTHRXP1_112, MGTHRXN1_112), " & "(MGTHRXP1_113, MGTHRXN1_113), " & "(MGTHRXP1_114, MGTHRXN1_114), " & "(MGTHRXP1_115, MGTHRXN1_115), " & "(MGTHRXP1_116, MGTHRXN1_116), " & "(MGTHRXP1_117, MGTHRXN1_117), " & "(MGTHRXP1_118, MGTHRXN1_118), " & "(MGTHRXP1_119, MGTHRXN1_119), " & "(MGTHRXP2_111, MGTHRXN2_111), " & "(MGTHRXP2_112, MGTHRXN2_112), " & "(MGTHRXP2_113, MGTHRXN2_113), " & "(MGTHRXP2_114, MGTHRXN2_114), " & "(MGTHRXP2_115, MGTHRXN2_115), " & "(MGTHRXP2_116, MGTHRXN2_116), " & "(MGTHRXP2_117, MGTHRXN2_117), " & "(MGTHRXP2_118, MGTHRXN2_118), " & "(MGTHRXP2_119, MGTHRXN2_119), " & "(MGTHRXP3_111, MGTHRXN3_111), " & "(MGTHRXP3_112, MGTHRXN3_112), " & "(MGTHRXP3_113, MGTHRXN3_113), " & "(MGTHRXP3_114, MGTHRXN3_114), " & "(MGTHRXP3_115, MGTHRXN3_115), " & "(MGTHRXP3_116, MGTHRXN3_116), " & "(MGTHRXP3_117, MGTHRXN3_117), " & "(MGTHRXP3_118, MGTHRXN3_118), " & "(MGTHRXP3_119, MGTHRXN3_119), " & "(MGTHTXP0_111, MGTHTXN0_111), " & "(MGTHTXP0_112, MGTHTXN0_112), " & "(MGTHTXP0_113, MGTHTXN0_113), " & "(MGTHTXP0_114, MGTHTXN0_114), " & "(MGTHTXP0_115, MGTHTXN0_115), " & "(MGTHTXP0_116, MGTHTXN0_116), " & "(MGTHTXP0_117, MGTHTXN0_117), " & "(MGTHTXP0_118, MGTHTXN0_118), " & "(MGTHTXP0_119, MGTHTXN0_119), " & "(MGTHTXP1_111, MGTHTXN1_111), " & "(MGTHTXP1_112, MGTHTXN1_112), " & "(MGTHTXP1_113, MGTHTXN1_113), " & "(MGTHTXP1_114, MGTHTXN1_114), " & "(MGTHTXP1_115, MGTHTXN1_115), " & "(MGTHTXP1_116, MGTHTXN1_116), " & "(MGTHTXP1_117, MGTHTXN1_117), " & "(MGTHTXP1_118, MGTHTXN1_118), " & "(MGTHTXP1_119, MGTHTXN1_119), " & "(MGTHTXP2_111, MGTHTXN2_111), " & "(MGTHTXP2_112, MGTHTXN2_112), " & "(MGTHTXP2_113, MGTHTXN2_113), " & "(MGTHTXP2_114, MGTHTXN2_114), " & "(MGTHTXP2_115, MGTHTXN2_115), " & "(MGTHTXP2_116, MGTHTXN2_116), " & "(MGTHTXP2_117, MGTHTXN2_117), " & "(MGTHTXP2_118, MGTHTXN2_118), " & "(MGTHTXP2_119, MGTHTXN2_119), " & "(MGTHTXP3_111, MGTHTXN3_111), " & "(MGTHTXP3_112, MGTHTXN3_112), " & "(MGTHTXP3_113, MGTHTXN3_113), " & "(MGTHTXP3_114, MGTHTXN3_114), " & "(MGTHTXP3_115, MGTHTXN3_115), " & "(MGTHTXP3_116, MGTHTXN3_116), " & "(MGTHTXP3_117, MGTHTXN3_117), " & "(MGTHTXP3_118, MGTHTXN3_118), " & "(MGTHTXP3_119, MGTHTXN3_119))"; -- Scan Port Identification attribute TAP_SCAN_IN of TDI : signal is true; attribute TAP_SCAN_MODE of TMS : signal is true; attribute TAP_SCAN_OUT of TDO : signal is true; attribute TAP_SCAN_CLOCK of TCK : signal is (66.0e6, BOTH); -- Compliance-Enable Description attribute COMPLIANCE_PATTERNS of XC7VX690T_FFG1761 : entity is "(PROGRAM_B) (1)"; -- Instruction Register Description attribute INSTRUCTION_LENGTH of XC7VX690T_FFG1761 : entity is 6; attribute INSTRUCTION_OPCODE of XC7VX690T_FFG1761 : entity is "IDCODE (001001)," & -- DEVICE_ID "BYPASS (111111)," & -- BYPASS "EXTEST (100110)," & -- BOUNDARY "SAMPLE (000001)," & -- BOUNDARY "PRELOAD (000001)," & -- Same as SAMPLE "USERCODE (001000)," & -- DEVICE_ID "HIGHZ (001010)," & -- BYPASS "EXTEST_PULSE (111100)," & -- BOUNDARY "EXTEST_TRAIN (111101)," & -- BOUNDARY "ISC_ENABLE (010000)," & -- ISC_CONFIG "ISC_PROGRAM (010001)," & -- ISC_PDATA "ISC_NOOP (010100)," & -- ISC_DEFAULT "XSC_READ_RSVD (010101)," & -- PRIVATE "ISC_DISABLE (010110)," & -- ISC_CONFIG "XSC_PROGRAM_KEY (010010)," & -- XSC_KEY_DATA "XSC_DNA (010111)," & -- DNA "CFG_OUT (000100)," & -- Not available during configuration with another mode. "CFG_IN (000101)," & -- Not available during configuration with another mode. "JPROGRAM (001011)," & -- Not available during configuration with another mode. "JSTART (001100)," & -- Not available during configuration with another mode. "JSHUTDOWN (001101)," & -- Not available during configuration with another mode. "FUSE_CTS (110000)," & -- PRIVATE "FUSE_KEY (110001)," & -- PRIVATE "FUSE_DNA (110010)," & -- PRIVATE "FUSE_USER (110011)," & -- PRIVATE "FUSE_CNTL (110100)," & -- PRIVATE "USER1 (000010)," & -- Not available until after configuration "USER2 (000011)," & -- Not available until after configuration "USER3 (100010)," & -- Not available until after configuration "USER4 (100011)," & -- Not available until after configuration "XADC_DRP (110111)," & -- PRIVATE "INTEST_RSVD (000111)"; -- PRIVATE attribute INSTRUCTION_CAPTURE of XC7VX690T_FFG1761 : entity is -- Bit 5 is 1 when DONE is released (part of startup sequence) -- Bit 4 is 1 if house-cleaning is complete -- Bit 3 is ISC_Enabled -- Bit 2 is ISC_Done "XXXX01"; attribute INSTRUCTION_PRIVATE of XC7VX690T_FFG1761 : entity is -- If the device is configured, and a USER instruction is implemented -- and not private to the FPGA designer, then it should be removed -- from INSTRUCTION_PRIVATE, and the target register should be defined -- in REGISTER_ACCESS. "ISC_ENABLE," & "ISC_PROGRAM," & "ISC_NOOP," & "XSC_READ_RSVD," & "ISC_DISABLE," & "XSC_PROGRAM_KEY," & "XSC_DNA," & "CFG_OUT," & "CFG_IN," & "JPROGRAM," & "JSTART," & "JSHUTDOWN," & "FUSE_CTS," & "FUSE_KEY," & "FUSE_DNA," & "FUSE_USER," & "FUSE_CNTL," & "USER1," & "USER2," & "USER3," & "USER4," & "XADC_DRP," & "INTEST_RSVD"; -- Optional Register Description attribute IDCODE_REGISTER of XC7VX690T_FFG1761 : entity is "XXXX" & -- version "0011011" & -- family "010010001" & -- array size "00001001001" & -- manufacturer "1"; -- required by 1149.1 attribute USERCODE_REGISTER of XC7VX690T_FFG1761 : entity is "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; -- Register Access Description attribute REGISTER_ACCESS of XC7VX690T_FFG1761 : entity is -- "[] (USER1)," & -- "[] (USER2)," & -- "[] (USER3)," & -- "[] (USER4)," & "DATAREG[57] (XSC_DNA)," & "BYPASS (HIGHZ,BYPASS)," & "DEVICE_ID (USERCODE,IDCODE)," & "BOUNDARY (SAMPLE,PRELOAD,EXTEST,EXTEST_PULSE,EXTEST_TRAIN)"; -- Boundary-Scan Register Description attribute BOUNDARY_LENGTH of XC7VX690T_FFG1761 : entity is 3389; attribute BOUNDARY_REGISTER of XC7VX690T_FFG1761 : entity is -- cellnum (type, port, function, safe[, ccell, disval, disrslt]) " 0 (BC_2, *, controlr, 1)," & " 1 (BC_2, CCLK_N10, output3, X, 0, 1, Z)," & -- CCLK_0 " 2 (BC_2, CCLK_N10, input, X)," & -- CCLK_0 " 3 (BC_2, M0_AL10, input, X)," & " 4 (BC_2, M1_AK10, input, X)," & " 5 (BC_2, M2_AJ10, input, X)," & " 6 (BC_2, CFGBVS_AH10, input, X)," & " 7 (BC_2, *, internal, 1)," & -- PROGRAM_B " 8 (BC_2, *, controlr, 1)," & " 9 (BC_2, INIT_B_AG11, output3, X, 8, 1, Z)," & -- INIT_B_0 " 10 (BC_2, INIT_B_AG11, input, X)," & -- INIT_B_0 " 11 (BC_2, *, controlr, 1)," & " 12 (BC_2, DONE_AL11, output3, X, 11, 1, Z)," & -- DONE_0 " 13 (BC_2, DONE_AL11, input, X)," & -- DONE_0 " 14 (BC_2, *, internal, X)," & " 15 (BC_2, *, internal, X)," & " 16 (BC_2, *, internal, X)," & " 17 (BC_2, *, internal, X)," & " 18 (BC_2, *, internal, X)," & " 19 (BC_2, *, internal, X)," & " 20 (BC_2, *, internal, X)," & " 21 (BC_2, *, internal, X)," & " 22 (BC_2, *, internal, X)," & " 23 (BC_2, *, internal, X)," & " 24 (BC_2, *, internal, X)," & " 25 (BC_2, *, internal, X)," & " 26 (BC_2, *, internal, X)," & " 27 (BC_2, *, internal, X)," & " 28 (BC_2, *, internal, X)," & " 29 (BC_2, *, internal, X)," & " 30 (BC_2, *, internal, X)," & " 31 (BC_2, *, internal, X)," & " 32 (BC_2, *, internal, X)," & " 33 (BC_2, *, internal, X)," & " 34 (BC_2, *, internal, X)," & " 35 (BC_2, *, internal, X)," & " 36 (BC_2, *, internal, X)," & " 37 (BC_2, *, internal, X)," & " 38 (BC_2, *, internal, X)," & " 39 (BC_2, *, internal, X)," & " 40 (BC_2, *, internal, X)," & " 41 (BC_2, *, internal, X)," & " 42 (BC_2, *, internal, X)," & " 43 (BC_2, *, internal, X)," & " 44 (BC_2, *, internal, X)," & " 45 (BC_2, *, internal, 1)," & -- PAD1000.T " 46 (BC_2, *, internal, X)," & -- PAD1000.O " 47 (BC_2, *, internal, X)," & -- PAD1000.I " 48 (BC_2, *, internal, 1)," & -- PAD999.T " 49 (BC_2, *, internal, X)," & -- PAD999.O " 50 (BC_2, *, internal, X)," & -- PAD999.I " 51 (BC_2, *, internal, 1)," & -- PAD998.T " 52 (BC_2, *, internal, X)," & -- PAD998.O " 53 (BC_2, *, internal, X)," & -- PAD998.I " 54 (BC_2, *, internal, 1)," & -- PAD997.T " 55 (BC_2, *, internal, X)," & -- PAD997.O " 56 (BC_2, *, internal, X)," & -- PAD997.I " 57 (BC_2, *, internal, 1)," & -- PAD996.T " 58 (BC_2, *, internal, X)," & -- PAD996.O " 59 (BC_2, *, internal, X)," & -- PAD996.I " 60 (BC_2, *, internal, 1)," & -- PAD995.T " 61 (BC_2, *, internal, X)," & -- PAD995.O " 62 (BC_2, *, internal, X)," & -- PAD995.I " 63 (BC_2, *, internal, 1)," & -- PAD994.T " 64 (BC_2, *, internal, X)," & -- PAD994.O " 65 (BC_2, *, internal, X)," & -- PAD994.I " 66 (BC_2, *, internal, 1)," & -- PAD993.T " 67 (BC_2, *, internal, X)," & -- PAD993.O " 68 (BC_2, *, internal, X)," & -- PAD993.I " 69 (BC_2, *, internal, 1)," & -- PAD992.T " 70 (BC_2, *, internal, X)," & -- PAD992.O " 71 (BC_2, *, internal, X)," & -- PAD992.I " 72 (BC_2, *, internal, 1)," & -- PAD991.T " 73 (BC_2, *, internal, X)," & -- PAD991.O " 74 (BC_2, *, internal, X)," & -- PAD991.I " 75 (BC_2, *, internal, 1)," & -- PAD990.T " 76 (BC_2, *, internal, X)," & -- PAD990.O " 77 (BC_2, *, internal, X)," & -- PAD990.I " 78 (BC_2, *, internal, 1)," & -- PAD989.T " 79 (BC_2, *, internal, X)," & -- PAD989.O " 80 (BC_2, *, internal, X)," & -- PAD989.I " 81 (BC_2, *, internal, 1)," & -- PAD988.T " 82 (BC_2, *, internal, X)," & -- PAD988.O " 83 (BC_2, *, internal, X)," & -- PAD988.I " 84 (BC_2, *, internal, 1)," & -- PAD987.T " 85 (BC_2, *, internal, X)," & -- PAD987.O " 86 (BC_2, *, internal, X)," & -- PAD987.I " 87 (BC_2, *, internal, 1)," & -- PAD986.T " 88 (BC_2, *, internal, X)," & -- PAD986.O " 89 (BC_2, *, internal, X)," & -- PAD986.I " 90 (BC_2, *, internal, 1)," & -- PAD985.T " 91 (BC_2, *, internal, X)," & -- PAD985.O " 92 (BC_2, *, internal, X)," & -- PAD985.I " 93 (BC_2, *, internal, 1)," & -- PAD984.T " 94 (BC_2, *, internal, X)," & -- PAD984.O " 95 (BC_2, *, internal, X)," & -- PAD984.I " 96 (BC_2, *, internal, 1)," & -- PAD983.T " 97 (BC_2, *, internal, X)," & -- PAD983.O " 98 (BC_2, *, internal, X)," & -- PAD983.I " 99 (BC_2, *, internal, 1)," & -- PAD982.T " 100 (BC_2, *, internal, X)," & -- PAD982.O " 101 (BC_2, *, internal, X)," & -- PAD982.I " 102 (BC_2, *, internal, 1)," & -- PAD981.T " 103 (BC_2, *, internal, X)," & -- PAD981.O " 104 (BC_2, *, internal, X)," & -- PAD981.I " 105 (BC_2, *, internal, 1)," & -- PAD980.T " 106 (BC_2, *, internal, X)," & -- PAD980.O " 107 (BC_2, *, internal, X)," & -- PAD980.I " 108 (BC_2, *, internal, 1)," & -- PAD979.T " 109 (BC_2, *, internal, X)," & -- PAD979.O " 110 (BC_2, *, internal, X)," & -- PAD979.I " 111 (BC_2, *, internal, 1)," & -- PAD978.T " 112 (BC_2, *, internal, X)," & -- PAD978.O " 113 (BC_2, *, internal, X)," & -- PAD978.I " 114 (BC_2, *, internal, 1)," & -- PAD977.T " 115 (BC_2, *, internal, X)," & -- PAD977.O " 116 (BC_2, *, internal, X)," & -- PAD977.I " 117 (BC_2, *, internal, 1)," & -- PAD976.T " 118 (BC_2, *, internal, X)," & -- PAD976.O " 119 (BC_2, *, internal, X)," & -- PAD976.I " 120 (BC_2, *, internal, 1)," & -- PAD975.T " 121 (BC_2, *, internal, X)," & -- PAD975.O " 122 (BC_2, *, internal, X)," & -- PAD975.I " 123 (BC_2, *, internal, 1)," & -- PAD974.T " 124 (BC_2, *, internal, X)," & -- PAD974.O " 125 (BC_2, *, internal, X)," & -- PAD974.I " 126 (BC_2, *, internal, 1)," & -- PAD973.T " 127 (BC_2, *, internal, X)," & -- PAD973.O " 128 (BC_2, *, internal, X)," & -- PAD973.I " 129 (BC_2, *, internal, 1)," & -- PAD972.T " 130 (BC_2, *, internal, X)," & -- PAD972.O " 131 (BC_2, *, internal, X)," & -- PAD972.I " 132 (BC_2, *, internal, 1)," & -- PAD971.T " 133 (BC_2, *, internal, X)," & -- PAD971.O " 134 (BC_2, *, internal, X)," & -- PAD971.I " 135 (BC_2, *, internal, 1)," & -- PAD970.T " 136 (BC_2, *, internal, X)," & -- PAD970.O " 137 (BC_2, *, internal, X)," & -- PAD970.I " 138 (BC_2, *, internal, 1)," & -- PAD969.T " 139 (BC_2, *, internal, X)," & -- PAD969.O " 140 (BC_2, *, internal, X)," & -- PAD969.I " 141 (BC_2, *, internal, 1)," & -- PAD968.T " 142 (BC_2, *, internal, X)," & -- PAD968.O " 143 (BC_2, *, internal, X)," & -- PAD968.I " 144 (BC_2, *, internal, 1)," & -- PAD967.T " 145 (BC_2, *, internal, X)," & -- PAD967.O " 146 (BC_2, *, internal, X)," & -- PAD967.I " 147 (BC_2, *, internal, 1)," & -- PAD966.T " 148 (BC_2, *, internal, X)," & -- PAD966.O " 149 (BC_2, *, internal, X)," & -- PAD966.I " 150 (BC_2, *, internal, 1)," & -- PAD965.T " 151 (BC_2, *, internal, X)," & -- PAD965.O " 152 (BC_2, *, internal, X)," & -- PAD965.I " 153 (BC_2, *, internal, 1)," & -- PAD964.T " 154 (BC_2, *, internal, X)," & -- PAD964.O " 155 (BC_2, *, internal, X)," & -- PAD964.I " 156 (BC_2, *, internal, 1)," & -- PAD963.T " 157 (BC_2, *, internal, X)," & -- PAD963.O " 158 (BC_2, *, internal, X)," & -- PAD963.I " 159 (BC_2, *, internal, 1)," & -- PAD962.T " 160 (BC_2, *, internal, X)," & -- PAD962.O " 161 (BC_2, *, internal, X)," & -- PAD962.I " 162 (BC_2, *, internal, 1)," & -- PAD961.T " 163 (BC_2, *, internal, X)," & -- PAD961.O " 164 (BC_2, *, internal, X)," & -- PAD961.I " 165 (BC_2, *, internal, 1)," & -- PAD960.T " 166 (BC_2, *, internal, X)," & -- PAD960.O " 167 (BC_2, *, internal, X)," & -- PAD960.I " 168 (BC_2, *, internal, 1)," & -- PAD959.T " 169 (BC_2, *, internal, X)," & -- PAD959.O " 170 (BC_2, *, internal, X)," & -- PAD959.I " 171 (BC_2, *, internal, 1)," & -- PAD958.T " 172 (BC_2, *, internal, X)," & -- PAD958.O " 173 (BC_2, *, internal, X)," & -- PAD958.I " 174 (BC_2, *, internal, 1)," & -- PAD957.T " 175 (BC_2, *, internal, X)," & -- PAD957.O " 176 (BC_2, *, internal, X)," & -- PAD957.I " 177 (BC_2, *, internal, 1)," & -- PAD956.T " 178 (BC_2, *, internal, X)," & -- PAD956.O " 179 (BC_2, *, internal, X)," & -- PAD956.I " 180 (BC_2, *, internal, 1)," & -- PAD955.T " 181 (BC_2, *, internal, X)," & -- PAD955.O " 182 (BC_2, *, internal, X)," & -- PAD955.I " 183 (BC_2, *, internal, 1)," & -- PAD954.T " 184 (BC_2, *, internal, X)," & -- PAD954.O " 185 (BC_2, *, internal, X)," & -- PAD954.I " 186 (BC_2, *, internal, 1)," & -- PAD953.T " 187 (BC_2, *, internal, X)," & -- PAD953.O " 188 (BC_2, *, internal, X)," & -- PAD953.I " 189 (BC_2, *, internal, 1)," & -- PAD952.T " 190 (BC_2, *, internal, X)," & -- PAD952.O " 191 (BC_2, *, internal, X)," & -- PAD952.I " 192 (BC_2, *, internal, 1)," & -- PAD951.T " 193 (BC_2, *, internal, X)," & -- PAD951.O " 194 (BC_2, *, internal, X)," & -- PAD951.I " 195 (BC_2, *, controlr, 1)," & " 196 (BC_2, IO_AP15, output3, X, 195, 1, Z)," & -- PAD950 " 197 (BC_2, IO_AP15, input, X)," & -- PAD950 " 198 (BC_2, *, controlr, 1)," & " 199 (BC_2, IO_BB12, output3, X, 198, 1, Z)," & -- PAD949 " 200 (BC_2, IO_BB12, input, X)," & -- PAD949 " 201 (BC_2, *, controlr, 1)," & " 202 (BC_2, IO_BA12, output3, X, 201, 1, Z)," & -- PAD948 " 203 (BC_2, IO_BA12, input, X)," & -- PAD948 " 204 (BC_2, *, controlr, 1)," & " 205 (BC_2, IO_BB13, output3, X, 204, 1, Z)," & -- PAD947 " 206 (BC_2, IO_BB13, input, X)," & -- PAD947 " 207 (BC_2, *, controlr, 1)," & " 208 (BC_2, IO_BB14, output3, X, 207, 1, Z)," & -- PAD946 " 209 (BC_2, IO_BB14, input, X)," & -- PAD946 " 210 (BC_2, *, controlr, 1)," & " 211 (BC_2, IO_AY13, output3, X, 210, 1, Z)," & -- PAD945 " 212 (BC_2, IO_AY13, input, X)," & -- PAD945 " 213 (BC_2, *, controlr, 1)," & " 214 (BC_2, IO_AY14, output3, X, 213, 1, Z)," & -- PAD944 " 215 (BC_2, IO_AY14, input, X)," & -- PAD944 " 216 (BC_2, *, controlr, 1)," & " 217 (BC_2, IO_BA14, output3, X, 216, 1, Z)," & -- PAD943 " 218 (BC_2, IO_BA14, input, X)," & -- PAD943 " 219 (BC_2, *, controlr, 1)," & " 220 (BC_2, IO_BA15, output3, X, 219, 1, Z)," & -- PAD942 " 221 (BC_2, IO_BA15, input, X)," & -- PAD942 " 222 (BC_2, *, controlr, 1)," & " 223 (BC_2, IO_AY12, output3, X, 222, 1, Z)," & -- PAD941 " 224 (BC_2, IO_AY12, input, X)," & -- PAD941 " 225 (BC_2, *, controlr, 1)," & " 226 (BC_2, IO_AW12, output3, X, 225, 1, Z)," & -- PAD940 " 227 (BC_2, IO_AW12, input, X)," & -- PAD940 " 228 (BC_2, *, controlr, 1)," & " 229 (BC_2, IO_AY15, output3, X, 228, 1, Z)," & -- PAD939 " 230 (BC_2, IO_AY15, input, X)," & -- PAD939 " 231 (BC_2, *, controlr, 1)," & " 232 (BC_2, IO_AW15, output3, X, 231, 1, Z)," & -- PAD938 " 233 (BC_2, IO_AW15, input, X)," & -- PAD938 " 234 (BC_2, *, controlr, 1)," & " 235 (BC_2, IO_AV14, output3, X, 234, 1, Z)," & -- PAD937 " 236 (BC_2, IO_AV14, input, X)," & -- PAD937 " 237 (BC_2, *, controlr, 1)," & " 238 (BC_2, IO_AV15, output3, X, 237, 1, Z)," & -- PAD936 " 239 (BC_2, IO_AV15, input, X)," & -- PAD936 " 240 (BC_2, *, controlr, 1)," & " 241 (BC_2, IO_AU12, output3, X, 240, 1, Z)," & -- PAD935 " 242 (BC_2, IO_AU12, input, X)," & -- PAD935 " 243 (BC_2, *, controlr, 1)," & " 244 (BC_2, IO_AT12, output3, X, 243, 1, Z)," & -- PAD934 " 245 (BC_2, IO_AT12, input, X)," & -- PAD934 " 246 (BC_2, *, controlr, 1)," & " 247 (BC_2, IO_AT15, output3, X, 246, 1, Z)," & -- PAD933 " 248 (BC_2, IO_AT15, input, X)," & -- PAD933 " 249 (BC_2, *, controlr, 1)," & " 250 (BC_2, IO_AR15, output3, X, 249, 1, Z)," & -- PAD932 " 251 (BC_2, IO_AR15, input, X)," & -- PAD932 " 252 (BC_2, *, controlr, 1)," & " 253 (BC_2, IO_AR12, output3, X, 252, 1, Z)," & -- PAD931 " 254 (BC_2, IO_AR12, input, X)," & -- PAD931 " 255 (BC_2, *, controlr, 1)," & " 256 (BC_2, IO_AP12, output3, X, 255, 1, Z)," & -- PAD930 " 257 (BC_2, IO_AP12, input, X)," & -- PAD930 " 258 (BC_2, *, controlr, 1)," & " 259 (BC_2, IO_AW13, output3, X, 258, 1, Z)," & -- PAD929 " 260 (BC_2, IO_AW13, input, X)," & -- PAD929 " 261 (BC_2, *, controlr, 1)," & " 262 (BC_2, IO_AV13, output3, X, 261, 1, Z)," & -- PAD928 " 263 (BC_2, IO_AV13, input, X)," & -- PAD928 " 264 (BC_2, *, controlr, 1)," & " 265 (BC_2, IO_AU13, output3, X, 264, 1, Z)," & -- PAD927 " 266 (BC_2, IO_AU13, input, X)," & -- PAD927 " 267 (BC_2, *, controlr, 1)," & " 268 (BC_2, IO_AU14, output3, X, 267, 1, Z)," & -- PAD926 " 269 (BC_2, IO_AU14, input, X)," & -- PAD926 " 270 (BC_2, *, controlr, 1)," & " 271 (BC_2, IO_AR13, output3, X, 270, 1, Z)," & -- PAD925 " 272 (BC_2, IO_AR13, input, X)," & -- PAD925 " 273 (BC_2, *, controlr, 1)," & " 274 (BC_2, IO_AP13, output3, X, 273, 1, Z)," & -- PAD924 " 275 (BC_2, IO_AP13, input, X)," & -- PAD924 " 276 (BC_2, *, controlr, 1)," & " 277 (BC_2, IO_AT14, output3, X, 276, 1, Z)," & -- PAD923 " 278 (BC_2, IO_AT14, input, X)," & -- PAD923 " 279 (BC_2, *, controlr, 1)," & " 280 (BC_2, IO_AR14, output3, X, 279, 1, Z)," & -- PAD922 " 281 (BC_2, IO_AR14, input, X)," & -- PAD922 " 282 (BC_2, *, controlr, 1)," & " 283 (BC_2, IO_AP11, output3, X, 282, 1, Z)," & -- PAD921 " 284 (BC_2, IO_AP11, input, X)," & -- PAD921 " 285 (BC_2, *, controlr, 1)," & " 286 (BC_2, IO_AN11, output3, X, 285, 1, Z)," & -- PAD920 " 287 (BC_2, IO_AN11, input, X)," & -- PAD920 " 288 (BC_2, *, controlr, 1)," & " 289 (BC_2, IO_AN14, output3, X, 288, 1, Z)," & -- PAD919 " 290 (BC_2, IO_AN14, input, X)," & -- PAD919 " 291 (BC_2, *, controlr, 1)," & " 292 (BC_2, IO_AN15, output3, X, 291, 1, Z)," & -- PAD918 " 293 (BC_2, IO_AN15, input, X)," & -- PAD918 " 294 (BC_2, *, controlr, 1)," & " 295 (BC_2, IO_AM11, output3, X, 294, 1, Z)," & -- PAD917 " 296 (BC_2, IO_AM11, input, X)," & -- PAD917 " 297 (BC_2, *, controlr, 1)," & " 298 (BC_2, IO_AM12, output3, X, 297, 1, Z)," & -- PAD916 " 299 (BC_2, IO_AM12, input, X)," & -- PAD916 " 300 (BC_2, *, controlr, 1)," & " 301 (BC_2, IO_AN13, output3, X, 300, 1, Z)," & -- PAD915 " 302 (BC_2, IO_AN13, input, X)," & -- PAD915 " 303 (BC_2, *, controlr, 1)," & " 304 (BC_2, IO_AM13, output3, X, 303, 1, Z)," & -- PAD914 " 305 (BC_2, IO_AM13, input, X)," & -- PAD914 " 306 (BC_2, *, controlr, 1)," & " 307 (BC_2, IO_AL12, output3, X, 306, 1, Z)," & -- PAD913 " 308 (BC_2, IO_AL12, input, X)," & -- PAD913 " 309 (BC_2, *, controlr, 1)," & " 310 (BC_2, IO_AK12, output3, X, 309, 1, Z)," & -- PAD912 " 311 (BC_2, IO_AK12, input, X)," & -- PAD912 " 312 (BC_2, *, controlr, 1)," & " 313 (BC_2, IO_AL15, output3, X, 312, 1, Z)," & -- PAD911 " 314 (BC_2, IO_AL15, input, X)," & -- PAD911 " 315 (BC_2, *, controlr, 1)," & " 316 (BC_2, IO_AL16, output3, X, 315, 1, Z)," & -- PAD910 " 317 (BC_2, IO_AL16, input, X)," & -- PAD910 " 318 (BC_2, *, controlr, 1)," & " 319 (BC_2, IO_AJ12, output3, X, 318, 1, Z)," & -- PAD909 " 320 (BC_2, IO_AJ12, input, X)," & -- PAD909 " 321 (BC_2, *, controlr, 1)," & " 322 (BC_2, IO_AJ13, output3, X, 321, 1, Z)," & -- PAD908 " 323 (BC_2, IO_AJ13, input, X)," & -- PAD908 " 324 (BC_2, *, controlr, 1)," & " 325 (BC_2, IO_AL14, output3, X, 324, 1, Z)," & -- PAD907 " 326 (BC_2, IO_AL14, input, X)," & -- PAD907 " 327 (BC_2, *, controlr, 1)," & " 328 (BC_2, IO_AK15, output3, X, 327, 1, Z)," & -- PAD906 " 329 (BC_2, IO_AK15, input, X)," & -- PAD906 " 330 (BC_2, *, controlr, 1)," & " 331 (BC_2, IO_AK13, output3, X, 330, 1, Z)," & -- PAD905 " 332 (BC_2, IO_AK13, input, X)," & -- PAD905 " 333 (BC_2, *, controlr, 1)," & " 334 (BC_2, IO_AK14, output3, X, 333, 1, Z)," & -- PAD904 " 335 (BC_2, IO_AK14, input, X)," & -- PAD904 " 336 (BC_2, *, controlr, 1)," & " 337 (BC_2, IO_AJ15, output3, X, 336, 1, Z)," & -- PAD903 " 338 (BC_2, IO_AJ15, input, X)," & -- PAD903 " 339 (BC_2, *, controlr, 1)," & " 340 (BC_2, IO_AJ16, output3, X, 339, 1, Z)," & -- PAD902 " 341 (BC_2, IO_AJ16, input, X)," & -- PAD902 " 342 (BC_2, *, controlr, 1)," & " 343 (BC_2, IO_AM14, output3, X, 342, 1, Z)," & -- PAD901 " 344 (BC_2, IO_AM14, input, X)," & -- PAD901 " 345 (BC_2, *, controlr, 1)," & " 346 (BC_2, IO_AP16, output3, X, 345, 1, Z)," & -- PAD900 " 347 (BC_2, IO_AP16, input, X)," & -- PAD900 " 348 (BC_2, *, controlr, 1)," & " 349 (BC_2, IO_BA19, output3, X, 348, 1, Z)," & -- PAD899 " 350 (BC_2, IO_BA19, input, X)," & -- PAD899 " 351 (BC_2, *, controlr, 1)," & " 352 (BC_2, IO_AY19, output3, X, 351, 1, Z)," & -- PAD898 " 353 (BC_2, IO_AY19, input, X)," & -- PAD898 " 354 (BC_2, *, controlr, 1)," & " 355 (BC_2, IO_BB16, output3, X, 354, 1, Z)," & -- PAD897 " 356 (BC_2, IO_BB16, input, X)," & -- PAD897 " 357 (BC_2, *, controlr, 1)," & " 358 (BC_2, IO_BA16, output3, X, 357, 1, Z)," & -- PAD896 " 359 (BC_2, IO_BA16, input, X)," & -- PAD896 " 360 (BC_2, *, controlr, 1)," & " 361 (BC_2, IO_BA20, output3, X, 360, 1, Z)," & -- PAD895 " 362 (BC_2, IO_BA20, input, X)," & -- PAD895 " 363 (BC_2, *, controlr, 1)," & " 364 (BC_2, IO_AY20, output3, X, 363, 1, Z)," & -- PAD894 " 365 (BC_2, IO_AY20, input, X)," & -- PAD894 " 366 (BC_2, *, controlr, 1)," & " 367 (BC_2, IO_BB17, output3, X, 366, 1, Z)," & -- PAD893 " 368 (BC_2, IO_BB17, input, X)," & -- PAD893 " 369 (BC_2, *, controlr, 1)," & " 370 (BC_2, IO_BA17, output3, X, 369, 1, Z)," & -- PAD892 " 371 (BC_2, IO_BA17, input, X)," & -- PAD892 " 372 (BC_2, *, controlr, 1)," & " 373 (BC_2, IO_AW20, output3, X, 372, 1, Z)," & -- PAD891 " 374 (BC_2, IO_AW20, input, X)," & -- PAD891 " 375 (BC_2, *, controlr, 1)," & " 376 (BC_2, IO_AV20, output3, X, 375, 1, Z)," & -- PAD890 " 377 (BC_2, IO_AV20, input, X)," & -- PAD890 " 378 (BC_2, *, controlr, 1)," & " 379 (BC_2, IO_BB18, output3, X, 378, 1, Z)," & -- PAD889 " 380 (BC_2, IO_BB18, input, X)," & -- PAD889 " 381 (BC_2, *, controlr, 1)," & " 382 (BC_2, IO_BB19, output3, X, 381, 1, Z)," & -- PAD888 " 383 (BC_2, IO_BB19, input, X)," & -- PAD888 " 384 (BC_2, *, controlr, 1)," & " 385 (BC_2, IO_AU16, output3, X, 384, 1, Z)," & -- PAD887 " 386 (BC_2, IO_AU16, input, X)," & -- PAD887 " 387 (BC_2, *, controlr, 1)," & " 388 (BC_2, IO_AT16, output3, X, 387, 1, Z)," & -- PAD886 " 389 (BC_2, IO_AT16, input, X)," & -- PAD886 " 390 (BC_2, *, controlr, 1)," & " 391 (BC_2, IO_AW16, output3, X, 390, 1, Z)," & -- PAD885 " 392 (BC_2, IO_AW16, input, X)," & -- PAD885 " 393 (BC_2, *, controlr, 1)," & " 394 (BC_2, IO_AV16, output3, X, 393, 1, Z)," & -- PAD884 " 395 (BC_2, IO_AV16, input, X)," & -- PAD884 " 396 (BC_2, *, controlr, 1)," & " 397 (BC_2, IO_AT19, output3, X, 396, 1, Z)," & -- PAD883 " 398 (BC_2, IO_AT19, input, X)," & -- PAD883 " 399 (BC_2, *, controlr, 1)," & " 400 (BC_2, IO_AT20, output3, X, 399, 1, Z)," & -- PAD882 " 401 (BC_2, IO_AT20, input, X)," & -- PAD882 " 402 (BC_2, *, controlr, 1)," & " 403 (BC_2, IO_AV19, output3, X, 402, 1, Z)," & -- PAD881 " 404 (BC_2, IO_AV19, input, X)," & -- PAD881 " 405 (BC_2, *, controlr, 1)," & " 406 (BC_2, IO_AU19, output3, X, 405, 1, Z)," & -- PAD880 " 407 (BC_2, IO_AU19, input, X)," & -- PAD880 " 408 (BC_2, *, controlr, 1)," & " 409 (BC_2, IO_AW17, output3, X, 408, 1, Z)," & -- PAD879 " 410 (BC_2, IO_AW17, input, X)," & -- PAD879 " 411 (BC_2, *, controlr, 1)," & " 412 (BC_2, IO_AW18, output3, X, 411, 1, Z)," & -- PAD878 " 413 (BC_2, IO_AW18, input, X)," & -- PAD878 " 414 (BC_2, *, controlr, 1)," & " 415 (BC_2, IO_AY17, output3, X, 414, 1, Z)," & -- PAD877 " 416 (BC_2, IO_AY17, input, X)," & -- PAD877 " 417 (BC_2, *, controlr, 1)," & " 418 (BC_2, IO_AY18, output3, X, 417, 1, Z)," & -- PAD876 " 419 (BC_2, IO_AY18, input, X)," & -- PAD876 " 420 (BC_2, *, controlr, 1)," & " 421 (BC_2, IO_AU17, output3, X, 420, 1, Z)," & -- PAD875 " 422 (BC_2, IO_AU17, input, X)," & -- PAD875 " 423 (BC_2, *, controlr, 1)," & " 424 (BC_2, IO_AT17, output3, X, 423, 1, Z)," & -- PAD874 " 425 (BC_2, IO_AT17, input, X)," & -- PAD874 " 426 (BC_2, *, controlr, 1)," & " 427 (BC_2, IO_AV18, output3, X, 426, 1, Z)," & -- PAD873 " 428 (BC_2, IO_AV18, input, X)," & -- PAD873 " 429 (BC_2, *, controlr, 1)," & " 430 (BC_2, IO_AU18, output3, X, 429, 1, Z)," & -- PAD872 " 431 (BC_2, IO_AU18, input, X)," & -- PAD872 " 432 (BC_2, *, controlr, 1)," & " 433 (BC_2, IO_AR17, output3, X, 432, 1, Z)," & -- PAD871 " 434 (BC_2, IO_AR17, input, X)," & -- PAD871 " 435 (BC_2, *, controlr, 1)," & " 436 (BC_2, IO_AR18, output3, X, 435, 1, Z)," & -- PAD870 " 437 (BC_2, IO_AR18, input, X)," & -- PAD870 " 438 (BC_2, *, controlr, 1)," & " 439 (BC_2, IO_AN18, output3, X, 438, 1, Z)," & -- PAD869 " 440 (BC_2, IO_AN18, input, X)," & -- PAD869 " 441 (BC_2, *, controlr, 1)," & " 442 (BC_2, IO_AN19, output3, X, 441, 1, Z)," & -- PAD868 " 443 (BC_2, IO_AN19, input, X)," & -- PAD868 " 444 (BC_2, *, controlr, 1)," & " 445 (BC_2, IO_AR19, output3, X, 444, 1, Z)," & -- PAD867 " 446 (BC_2, IO_AR19, input, X)," & -- PAD867 " 447 (BC_2, *, controlr, 1)," & " 448 (BC_2, IO_AP20, output3, X, 447, 1, Z)," & -- PAD866 " 449 (BC_2, IO_AP20, input, X)," & -- PAD866 " 450 (BC_2, *, controlr, 1)," & " 451 (BC_2, IO_AP17, output3, X, 450, 1, Z)," & -- PAD865 " 452 (BC_2, IO_AP17, input, X)," & -- PAD865 " 453 (BC_2, *, controlr, 1)," & " 454 (BC_2, IO_AP18, output3, X, 453, 1, Z)," & -- PAD864 " 455 (BC_2, IO_AP18, input, X)," & -- PAD864 " 456 (BC_2, *, controlr, 1)," & " 457 (BC_2, IO_AJ17, output3, X, 456, 1, Z)," & -- PAD863 " 458 (BC_2, IO_AJ17, input, X)," & -- PAD863 " 459 (BC_2, *, controlr, 1)," & " 460 (BC_2, IO_AJ18, output3, X, 459, 1, Z)," & -- PAD862 " 461 (BC_2, IO_AJ18, input, X)," & -- PAD862 " 462 (BC_2, *, controlr, 1)," & " 463 (BC_2, IO_AN16, output3, X, 462, 1, Z)," & -- PAD861 " 464 (BC_2, IO_AN16, input, X)," & -- PAD861 " 465 (BC_2, *, controlr, 1)," & " 466 (BC_2, IO_AM16, output3, X, 465, 1, Z)," & -- PAD860 " 467 (BC_2, IO_AM16, input, X)," & -- PAD860 " 468 (BC_2, *, controlr, 1)," & " 469 (BC_2, IO_AK18, output3, X, 468, 1, Z)," & -- PAD859 " 470 (BC_2, IO_AK18, input, X)," & -- PAD859 " 471 (BC_2, *, controlr, 1)," & " 472 (BC_2, IO_AK19, output3, X, 471, 1, Z)," & -- PAD858 " 473 (BC_2, IO_AK19, input, X)," & -- PAD858 " 474 (BC_2, *, controlr, 1)," & " 475 (BC_2, IO_AM17, output3, X, 474, 1, Z)," & -- PAD857 " 476 (BC_2, IO_AM17, input, X)," & -- PAD857 " 477 (BC_2, *, controlr, 1)," & " 478 (BC_2, IO_AM18, output3, X, 477, 1, Z)," & -- PAD856 " 479 (BC_2, IO_AM18, input, X)," & -- PAD856 " 480 (BC_2, *, controlr, 1)," & " 481 (BC_2, IO_AL17, output3, X, 480, 1, Z)," & -- PAD855 " 482 (BC_2, IO_AL17, input, X)," & -- PAD855 " 483 (BC_2, *, controlr, 1)," & " 484 (BC_2, IO_AK17, output3, X, 483, 1, Z)," & -- PAD854 " 485 (BC_2, IO_AK17, input, X)," & -- PAD854 " 486 (BC_2, *, controlr, 1)," & " 487 (BC_2, IO_AM19, output3, X, 486, 1, Z)," & -- PAD853 " 488 (BC_2, IO_AM19, input, X)," & -- PAD853 " 489 (BC_2, *, controlr, 1)," & " 490 (BC_2, IO_AL19, output3, X, 489, 1, Z)," & -- PAD852 " 491 (BC_2, IO_AL19, input, X)," & -- PAD852 " 492 (BC_2, *, controlr, 1)," & " 493 (BC_2, IO_AR20, output3, X, 492, 1, Z)," & -- PAD851 " 494 (BC_2, IO_AR20, input, X)," & -- PAD851 " 495 (BC_2, *, controlr, 1)," & " 496 (BC_2, IO_AN20, output3, X, 495, 1, Z)," & -- PAD850 " 497 (BC_2, IO_AN20, input, X)," & -- PAD850 " 498 (BC_2, *, controlr, 1)," & " 499 (BC_2, IO_BB23, output3, X, 498, 1, Z)," & -- PAD849 " 500 (BC_2, IO_BB23, input, X)," & -- PAD849 " 501 (BC_2, *, controlr, 1)," & " 502 (BC_2, IO_BB24, output3, X, 501, 1, Z)," & -- PAD848 " 503 (BC_2, IO_BB24, input, X)," & -- PAD848 " 504 (BC_2, *, controlr, 1)," & " 505 (BC_2, IO_BB21, output3, X, 504, 1, Z)," & -- PAD847 " 506 (BC_2, IO_BB21, input, X)," & -- PAD847 " 507 (BC_2, *, controlr, 1)," & " 508 (BC_2, IO_BA21, output3, X, 507, 1, Z)," & -- PAD846 " 509 (BC_2, IO_BA21, input, X)," & -- PAD846 " 510 (BC_2, *, controlr, 1)," & " 511 (BC_2, IO_BA24, output3, X, 510, 1, Z)," & -- PAD845 " 512 (BC_2, IO_BA24, input, X)," & -- PAD845 " 513 (BC_2, *, controlr, 1)," & " 514 (BC_2, IO_AY24, output3, X, 513, 1, Z)," & -- PAD844 " 515 (BC_2, IO_AY24, input, X)," & -- PAD844 " 516 (BC_2, *, controlr, 1)," & " 517 (BC_2, IO_BB22, output3, X, 516, 1, Z)," & -- PAD843 " 518 (BC_2, IO_BB22, input, X)," & -- PAD843 " 519 (BC_2, *, controlr, 1)," & " 520 (BC_2, IO_BA22, output3, X, 519, 1, Z)," & -- PAD842 " 521 (BC_2, IO_BA22, input, X)," & -- PAD842 " 522 (BC_2, *, controlr, 1)," & " 523 (BC_2, IO_BA25, output3, X, 522, 1, Z)," & -- PAD841 " 524 (BC_2, IO_BA25, input, X)," & -- PAD841 " 525 (BC_2, *, controlr, 1)," & " 526 (BC_2, IO_AY25, output3, X, 525, 1, Z)," & -- PAD840 " 527 (BC_2, IO_AY25, input, X)," & -- PAD840 " 528 (BC_2, *, controlr, 1)," & " 529 (BC_2, IO_AY22, output3, X, 528, 1, Z)," & -- PAD839 " 530 (BC_2, IO_AY22, input, X)," & -- PAD839 " 531 (BC_2, *, controlr, 1)," & " 532 (BC_2, IO_AY23, output3, X, 531, 1, Z)," & -- PAD838 " 533 (BC_2, IO_AY23, input, X)," & -- PAD838 " 534 (BC_2, *, controlr, 1)," & " 535 (BC_2, IO_AV24, output3, X, 534, 1, Z)," & -- PAD837 " 536 (BC_2, IO_AV24, input, X)," & -- PAD837 " 537 (BC_2, *, controlr, 1)," & " 538 (BC_2, IO_AU24, output3, X, 537, 1, Z)," & -- PAD836 " 539 (BC_2, IO_AU24, input, X)," & -- PAD836 " 540 (BC_2, *, controlr, 1)," & " 541 (BC_2, IO_AW21, output3, X, 540, 1, Z)," & -- PAD835 " 542 (BC_2, IO_AW21, input, X)," & -- PAD835 " 543 (BC_2, *, controlr, 1)," & " 544 (BC_2, IO_AV21, output3, X, 543, 1, Z)," & -- PAD834 " 545 (BC_2, IO_AV21, input, X)," & -- PAD834 " 546 (BC_2, *, controlr, 1)," & " 547 (BC_2, IO_AT24, output3, X, 546, 1, Z)," & -- PAD833 " 548 (BC_2, IO_AT24, input, X)," & -- PAD833 " 549 (BC_2, *, controlr, 1)," & " 550 (BC_2, IO_AR24, output3, X, 549, 1, Z)," & -- PAD832 " 551 (BC_2, IO_AR24, input, X)," & -- PAD832 " 552 (BC_2, *, controlr, 1)," & " 553 (BC_2, IO_AU21, output3, X, 552, 1, Z)," & -- PAD831 " 554 (BC_2, IO_AU21, input, X)," & -- PAD831 " 555 (BC_2, *, controlr, 1)," & " 556 (BC_2, IO_AT21, output3, X, 555, 1, Z)," & -- PAD830 " 557 (BC_2, IO_AT21, input, X)," & -- PAD830 " 558 (BC_2, *, controlr, 1)," & " 559 (BC_2, IO_AW22, output3, X, 558, 1, Z)," & -- PAD829 " 560 (BC_2, IO_AW22, input, X)," & -- PAD829 " 561 (BC_2, *, controlr, 1)," & " 562 (BC_2, IO_AW23, output3, X, 561, 1, Z)," & -- PAD828 " 563 (BC_2, IO_AW23, input, X)," & -- PAD828 " 564 (BC_2, *, controlr, 1)," & " 565 (BC_2, IO_AV23, output3, X, 564, 1, Z)," & -- PAD827 " 566 (BC_2, IO_AV23, input, X)," & -- PAD827 " 567 (BC_2, *, controlr, 1)," & " 568 (BC_2, IO_AU23, output3, X, 567, 1, Z)," & -- PAD826 " 569 (BC_2, IO_AU23, input, X)," & -- PAD826 " 570 (BC_2, *, controlr, 1)," & " 571 (BC_2, IO_AU22, output3, X, 570, 1, Z)," & -- PAD825 " 572 (BC_2, IO_AU22, input, X)," & -- PAD825 " 573 (BC_2, *, controlr, 1)," & " 574 (BC_2, IO_AT22, output3, X, 573, 1, Z)," & -- PAD824 " 575 (BC_2, IO_AT22, input, X)," & -- PAD824 " 576 (BC_2, *, controlr, 1)," & " 577 (BC_2, IO_AR22, output3, X, 576, 1, Z)," & -- PAD823 " 578 (BC_2, IO_AR22, input, X)," & -- PAD823 " 579 (BC_2, *, controlr, 1)," & " 580 (BC_2, IO_AR23, output3, X, 579, 1, Z)," & -- PAD822 " 581 (BC_2, IO_AR23, input, X)," & -- PAD822 " 582 (BC_2, *, controlr, 1)," & " 583 (BC_2, IO_AP21, output3, X, 582, 1, Z)," & -- PAD821 " 584 (BC_2, IO_AP21, input, X)," & -- PAD821 " 585 (BC_2, *, controlr, 1)," & " 586 (BC_2, IO_AN21, output3, X, 585, 1, Z)," & -- PAD820 " 587 (BC_2, IO_AN21, input, X)," & -- PAD820 " 588 (BC_2, *, controlr, 1)," & " 589 (BC_2, IO_AP22, output3, X, 588, 1, Z)," & -- PAD819 " 590 (BC_2, IO_AP22, input, X)," & -- PAD819 " 591 (BC_2, *, controlr, 1)," & " 592 (BC_2, IO_AP23, output3, X, 591, 1, Z)," & -- PAD818 " 593 (BC_2, IO_AP23, input, X)," & -- PAD818 " 594 (BC_2, *, controlr, 1)," & " 595 (BC_2, IO_AN23, output3, X, 594, 1, Z)," & -- PAD817 " 596 (BC_2, IO_AN23, input, X)," & -- PAD817 " 597 (BC_2, *, controlr, 1)," & " 598 (BC_2, IO_AM23, output3, X, 597, 1, Z)," & -- PAD816 " 599 (BC_2, IO_AM23, input, X)," & -- PAD816 " 600 (BC_2, *, controlr, 1)," & " 601 (BC_2, IO_AN24, output3, X, 600, 1, Z)," & -- PAD815 " 602 (BC_2, IO_AN24, input, X)," & -- PAD815 " 603 (BC_2, *, controlr, 1)," & " 604 (BC_2, IO_AM24, output3, X, 603, 1, Z)," & -- PAD814 " 605 (BC_2, IO_AM24, input, X)," & -- PAD814 " 606 (BC_2, *, controlr, 1)," & " 607 (BC_2, IO_AM22, output3, X, 606, 1, Z)," & -- PAD813 " 608 (BC_2, IO_AM22, input, X)," & -- PAD813 " 609 (BC_2, *, controlr, 1)," & " 610 (BC_2, IO_AL22, output3, X, 609, 1, Z)," & -- PAD812 " 611 (BC_2, IO_AL22, input, X)," & -- PAD812 " 612 (BC_2, *, controlr, 1)," & " 613 (BC_2, IO_AJ20, output3, X, 612, 1, Z)," & -- PAD811 " 614 (BC_2, IO_AJ20, input, X)," & -- PAD811 " 615 (BC_2, *, controlr, 1)," & " 616 (BC_2, IO_AJ21, output3, X, 615, 1, Z)," & -- PAD810 " 617 (BC_2, IO_AJ21, input, X)," & -- PAD810 " 618 (BC_2, *, controlr, 1)," & " 619 (BC_2, IO_AM21, output3, X, 618, 1, Z)," & -- PAD809 " 620 (BC_2, IO_AM21, input, X)," & -- PAD809 " 621 (BC_2, *, controlr, 1)," & " 622 (BC_2, IO_AL21, output3, X, 621, 1, Z)," & -- PAD808 " 623 (BC_2, IO_AL21, input, X)," & -- PAD808 " 624 (BC_2, *, controlr, 1)," & " 625 (BC_2, IO_AK22, output3, X, 624, 1, Z)," & -- PAD807 " 626 (BC_2, IO_AK22, input, X)," & -- PAD807 " 627 (BC_2, *, controlr, 1)," & " 628 (BC_2, IO_AJ22, output3, X, 627, 1, Z)," & -- PAD806 " 629 (BC_2, IO_AJ22, input, X)," & -- PAD806 " 630 (BC_2, *, controlr, 1)," & " 631 (BC_2, IO_AL20, output3, X, 630, 1, Z)," & -- PAD805 " 632 (BC_2, IO_AL20, input, X)," & -- PAD805 " 633 (BC_2, *, controlr, 1)," & " 634 (BC_2, IO_AK20, output3, X, 633, 1, Z)," & -- PAD804 " 635 (BC_2, IO_AK20, input, X)," & -- PAD804 " 636 (BC_2, *, controlr, 1)," & " 637 (BC_2, IO_AK23, output3, X, 636, 1, Z)," & -- PAD803 " 638 (BC_2, IO_AK23, input, X)," & -- PAD803 " 639 (BC_2, *, controlr, 1)," & " 640 (BC_2, IO_AJ23, output3, X, 639, 1, Z)," & -- PAD802 " 641 (BC_2, IO_AJ23, input, X)," & -- PAD802 " 642 (BC_2, *, controlr, 1)," & " 643 (BC_2, IO_AL24, output3, X, 642, 1, Z)," & -- PAD801 " 644 (BC_2, IO_AL24, input, X)," & -- PAD801 " 645 (BC_2, *, controlr, 1)," & " 646 (BC_2, IO_U28, output3, X, 645, 1, Z)," & -- PAD800 " 647 (BC_2, IO_U28, input, X)," & -- PAD800 " 648 (BC_2, *, controlr, 1)," & " 649 (BC_2, IO_Y30, output3, X, 648, 1, Z)," & -- PAD799 " 650 (BC_2, IO_Y30, input, X)," & -- PAD799 " 651 (BC_2, *, controlr, 1)," & " 652 (BC_2, IO_Y29, output3, X, 651, 1, Z)," & -- PAD798 " 653 (BC_2, IO_Y29, input, X)," & -- PAD798 " 654 (BC_2, *, controlr, 1)," & " 655 (BC_2, IO_U29, output3, X, 654, 1, Z)," & -- PAD797 " 656 (BC_2, IO_U29, input, X)," & -- PAD797 " 657 (BC_2, *, controlr, 1)," & " 658 (BC_2, IO_V29, output3, X, 657, 1, Z)," & -- PAD796 " 659 (BC_2, IO_V29, input, X)," & -- PAD796 " 660 (BC_2, *, controlr, 1)," & " 661 (BC_2, IO_W31, output3, X, 660, 1, Z)," & -- PAD795 " 662 (BC_2, IO_W31, input, X)," & -- PAD795 " 663 (BC_2, *, controlr, 1)," & " 664 (BC_2, IO_W30, output3, X, 663, 1, Z)," & -- PAD794 " 665 (BC_2, IO_W30, input, X)," & -- PAD794 " 666 (BC_2, *, controlr, 1)," & " 667 (BC_2, IO_T30, output3, X, 666, 1, Z)," & -- PAD793 " 668 (BC_2, IO_T30, input, X)," & -- PAD793 " 669 (BC_2, *, controlr, 1)," & " 670 (BC_2, IO_T29, output3, X, 669, 1, Z)," & -- PAD792 " 671 (BC_2, IO_T29, input, X)," & -- PAD792 " 672 (BC_2, *, controlr, 1)," & " 673 (BC_2, IO_V31, output3, X, 672, 1, Z)," & -- PAD791 " 674 (BC_2, IO_V31, input, X)," & -- PAD791 " 675 (BC_2, *, controlr, 1)," & " 676 (BC_2, IO_V30, output3, X, 675, 1, Z)," & -- PAD790 " 677 (BC_2, IO_V30, input, X)," & -- PAD790 " 678 (BC_2, *, controlr, 1)," & " 679 (BC_2, IO_T31, output3, X, 678, 1, Z)," & -- PAD789 " 680 (BC_2, IO_T31, input, X)," & -- PAD789 " 681 (BC_2, *, controlr, 1)," & " 682 (BC_2, IO_U31, output3, X, 681, 1, Z)," & -- PAD788 " 683 (BC_2, IO_U31, input, X)," & -- PAD788 " 684 (BC_2, *, controlr, 1)," & " 685 (BC_2, IO_P31, output3, X, 684, 1, Z)," & -- PAD787 " 686 (BC_2, IO_P31, input, X)," & -- PAD787 " 687 (BC_2, *, controlr, 1)," & " 688 (BC_2, IO_R30, output3, X, 687, 1, Z)," & -- PAD786 " 689 (BC_2, IO_R30, input, X)," & -- PAD786 " 690 (BC_2, *, controlr, 1)," & " 691 (BC_2, IO_N29, output3, X, 690, 1, Z)," & -- PAD785 " 692 (BC_2, IO_N29, input, X)," & -- PAD785 " 693 (BC_2, *, controlr, 1)," & " 694 (BC_2, IO_N28, output3, X, 693, 1, Z)," & -- PAD784 " 695 (BC_2, IO_N28, input, X)," & -- PAD784 " 696 (BC_2, *, controlr, 1)," & " 697 (BC_2, IO_P28, output3, X, 696, 1, Z)," & -- PAD783 " 698 (BC_2, IO_P28, input, X)," & -- PAD783 " 699 (BC_2, *, controlr, 1)," & " 700 (BC_2, IO_R28, output3, X, 699, 1, Z)," & -- PAD782 " 701 (BC_2, IO_R28, input, X)," & -- PAD782 " 702 (BC_2, *, controlr, 1)," & " 703 (BC_2, IO_M29, output3, X, 702, 1, Z)," & -- PAD781 " 704 (BC_2, IO_M29, input, X)," & -- PAD781 " 705 (BC_2, *, controlr, 1)," & " 706 (BC_2, IO_M28, output3, X, 705, 1, Z)," & -- PAD780 " 707 (BC_2, IO_M28, input, X)," & -- PAD780 " 708 (BC_2, *, controlr, 1)," & " 709 (BC_2, IO_N31, output3, X, 708, 1, Z)," & -- PAD779 " 710 (BC_2, IO_N31, input, X)," & -- PAD779 " 711 (BC_2, *, controlr, 1)," & " 712 (BC_2, IO_P30, output3, X, 711, 1, Z)," & -- PAD778 " 713 (BC_2, IO_P30, input, X)," & -- PAD778 " 714 (BC_2, *, controlr, 1)," & " 715 (BC_2, IO_M31, output3, X, 714, 1, Z)," & -- PAD777 " 716 (BC_2, IO_M31, input, X)," & -- PAD777 " 717 (BC_2, *, controlr, 1)," & " 718 (BC_2, IO_N30, output3, X, 717, 1, Z)," & -- PAD776 " 719 (BC_2, IO_N30, input, X)," & -- PAD776 " 720 (BC_2, *, controlr, 1)," & " 721 (BC_2, IO_K32, output3, X, 720, 1, Z)," & -- PAD775 " 722 (BC_2, IO_K32, input, X)," & -- PAD775 " 723 (BC_2, *, controlr, 1)," & " 724 (BC_2, IO_L31, output3, X, 723, 1, Z)," & -- PAD774 " 725 (BC_2, IO_L31, input, X)," & -- PAD774 " 726 (BC_2, *, controlr, 1)," & " 727 (BC_2, IO_L32, output3, X, 726, 1, Z)," & -- PAD773 " 728 (BC_2, IO_L32, input, X)," & -- PAD773 " 729 (BC_2, *, controlr, 1)," & " 730 (BC_2, IO_M32, output3, X, 729, 1, Z)," & -- PAD772 " 731 (BC_2, IO_M32, input, X)," & -- PAD772 " 732 (BC_2, *, controlr, 1)," & " 733 (BC_2, IO_H31, output3, X, 732, 1, Z)," & -- PAD771 " 734 (BC_2, IO_H31, input, X)," & -- PAD771 " 735 (BC_2, *, controlr, 1)," & " 736 (BC_2, IO_J31, output3, X, 735, 1, Z)," & -- PAD770 " 737 (BC_2, IO_J31, input, X)," & -- PAD770 " 738 (BC_2, *, controlr, 1)," & " 739 (BC_2, IO_L30, output3, X, 738, 1, Z)," & -- PAD769 " 740 (BC_2, IO_L30, input, X)," & -- PAD769 " 741 (BC_2, *, controlr, 1)," & " 742 (BC_2, IO_L29, output3, X, 741, 1, Z)," & -- PAD768 " 743 (BC_2, IO_L29, input, X)," & -- PAD768 " 744 (BC_2, *, controlr, 1)," & " 745 (BC_2, IO_H30, output3, X, 744, 1, Z)," & -- PAD767 " 746 (BC_2, IO_H30, input, X)," & -- PAD767 " 747 (BC_2, *, controlr, 1)," & " 748 (BC_2, IO_J30, output3, X, 747, 1, Z)," & -- PAD766 " 749 (BC_2, IO_J30, input, X)," & -- PAD766 " 750 (BC_2, *, controlr, 1)," & " 751 (BC_2, IO_K30, output3, X, 750, 1, Z)," & -- PAD765 " 752 (BC_2, IO_K30, input, X)," & -- PAD765 " 753 (BC_2, *, controlr, 1)," & " 754 (BC_2, IO_K29, output3, X, 753, 1, Z)," & -- PAD764 " 755 (BC_2, IO_K29, input, X)," & -- PAD764 " 756 (BC_2, *, controlr, 1)," & " 757 (BC_2, IO_H35, output3, X, 756, 1, Z)," & -- PAD763 " 758 (BC_2, IO_H35, input, X)," & -- PAD763 " 759 (BC_2, *, controlr, 1)," & " 760 (BC_2, IO_H34, output3, X, 759, 1, Z)," & -- PAD762 " 761 (BC_2, IO_H34, input, X)," & -- PAD762 " 762 (BC_2, *, controlr, 1)," & " 763 (BC_2, IO_M34, output3, X, 762, 1, Z)," & -- PAD761 " 764 (BC_2, IO_M34, input, X)," & -- PAD761 " 765 (BC_2, *, controlr, 1)," & " 766 (BC_2, IO_M33, output3, X, 765, 1, Z)," & -- PAD760 " 767 (BC_2, IO_M33, input, X)," & -- PAD760 " 768 (BC_2, *, controlr, 1)," & " 769 (BC_2, IO_L35, output3, X, 768, 1, Z)," & -- PAD759 " 770 (BC_2, IO_L35, input, X)," & -- PAD759 " 771 (BC_2, *, controlr, 1)," & " 772 (BC_2, IO_L34, output3, X, 771, 1, Z)," & -- PAD758 " 773 (BC_2, IO_L34, input, X)," & -- PAD758 " 774 (BC_2, *, controlr, 1)," & " 775 (BC_2, IO_K34, output3, X, 774, 1, Z)," & -- PAD757 " 776 (BC_2, IO_K34, input, X)," & -- PAD757 " 777 (BC_2, *, controlr, 1)," & " 778 (BC_2, IO_K33, output3, X, 777, 1, Z)," & -- PAD756 " 779 (BC_2, IO_K33, input, X)," & -- PAD756 " 780 (BC_2, *, controlr, 1)," & " 781 (BC_2, IO_J33, output3, X, 780, 1, Z)," & -- PAD755 " 782 (BC_2, IO_J33, input, X)," & -- PAD755 " 783 (BC_2, *, controlr, 1)," & " 784 (BC_2, IO_J32, output3, X, 783, 1, Z)," & -- PAD754 " 785 (BC_2, IO_J32, input, X)," & -- PAD754 " 786 (BC_2, *, controlr, 1)," & " 787 (BC_2, IO_J35, output3, X, 786, 1, Z)," & -- PAD753 " 788 (BC_2, IO_J35, input, X)," & -- PAD753 " 789 (BC_2, *, controlr, 1)," & " 790 (BC_2, IO_K35, output3, X, 789, 1, Z)," & -- PAD752 " 791 (BC_2, IO_K35, input, X)," & -- PAD752 " 792 (BC_2, *, controlr, 1)," & " 793 (BC_2, IO_R29, output3, X, 792, 1, Z)," & -- PAD751 " 794 (BC_2, IO_R29, input, X)," & -- PAD751 " 795 (BC_2, *, controlr, 1)," & " 796 (BC_2, IO_G34, output3, X, 795, 1, Z)," & -- PAD750 " 797 (BC_2, IO_G34, input, X)," & -- PAD750 " 798 (BC_2, *, controlr, 1)," & " 799 (BC_2, IO_H36, output3, X, 798, 1, Z)," & -- PAD749 " 800 (BC_2, IO_H36, input, X)," & -- PAD749 " 801 (BC_2, *, controlr, 1)," & " 802 (BC_2, IO_J36, output3, X, 801, 1, Z)," & -- PAD748 " 803 (BC_2, IO_J36, input, X)," & -- PAD748 " 804 (BC_2, *, controlr, 1)," & " 805 (BC_2, IO_G38, output3, X, 804, 1, Z)," & -- PAD747 " 806 (BC_2, IO_G38, input, X)," & -- PAD747 " 807 (BC_2, *, controlr, 1)," & " 808 (BC_2, IO_H38, output3, X, 807, 1, Z)," & -- PAD746 " 809 (BC_2, IO_H38, input, X)," & -- PAD746 " 810 (BC_2, *, controlr, 1)," & " 811 (BC_2, IO_J38, output3, X, 810, 1, Z)," & -- PAD745 " 812 (BC_2, IO_J38, input, X)," & -- PAD745 " 813 (BC_2, *, controlr, 1)," & " 814 (BC_2, IO_J37, output3, X, 813, 1, Z)," & -- PAD744 " 815 (BC_2, IO_J37, input, X)," & -- PAD744 " 816 (BC_2, *, controlr, 1)," & " 817 (BC_2, IO_E39, output3, X, 816, 1, Z)," & -- PAD743 " 818 (BC_2, IO_E39, input, X)," & -- PAD743 " 819 (BC_2, *, controlr, 1)," & " 820 (BC_2, IO_F39, output3, X, 819, 1, Z)," & -- PAD742 " 821 (BC_2, IO_F39, input, X)," & -- PAD742 " 822 (BC_2, *, controlr, 1)," & " 823 (BC_2, IO_G37, output3, X, 822, 1, Z)," & -- PAD741 " 824 (BC_2, IO_G37, input, X)," & -- PAD741 " 825 (BC_2, *, controlr, 1)," & " 826 (BC_2, IO_G36, output3, X, 825, 1, Z)," & -- PAD740 " 827 (BC_2, IO_G36, input, X)," & -- PAD740 " 828 (BC_2, *, controlr, 1)," & " 829 (BC_2, IO_E38, output3, X, 828, 1, Z)," & -- PAD739 " 830 (BC_2, IO_E38, input, X)," & -- PAD739 " 831 (BC_2, *, controlr, 1)," & " 832 (BC_2, IO_E37, output3, X, 831, 1, Z)," & -- PAD738 " 833 (BC_2, IO_E37, input, X)," & -- PAD738 " 834 (BC_2, *, controlr, 1)," & " 835 (BC_2, IO_G33, output3, X, 834, 1, Z)," & -- PAD737 " 836 (BC_2, IO_G33, input, X)," & -- PAD737 " 837 (BC_2, *, controlr, 1)," & " 838 (BC_2, IO_H33, output3, X, 837, 1, Z)," & -- PAD736 " 839 (BC_2, IO_H33, input, X)," & -- PAD736 " 840 (BC_2, *, controlr, 1)," & " 841 (BC_2, IO_F35, output3, X, 840, 1, Z)," & -- PAD735 " 842 (BC_2, IO_F35, input, X)," & -- PAD735 " 843 (BC_2, *, controlr, 1)," & " 844 (BC_2, IO_F34, output3, X, 843, 1, Z)," & -- PAD734 " 845 (BC_2, IO_F34, input, X)," & -- PAD734 " 846 (BC_2, *, controlr, 1)," & " 847 (BC_2, IO_F37, output3, X, 846, 1, Z)," & -- PAD733 " 848 (BC_2, IO_F37, input, X)," & -- PAD733 " 849 (BC_2, *, controlr, 1)," & " 850 (BC_2, IO_F36, output3, X, 849, 1, Z)," & -- PAD732 " 851 (BC_2, IO_F36, input, X)," & -- PAD732 " 852 (BC_2, *, controlr, 1)," & " 853 (BC_2, IO_F32, output3, X, 852, 1, Z)," & -- PAD731 " 854 (BC_2, IO_F32, input, X)," & -- PAD731 " 855 (BC_2, *, controlr, 1)," & " 856 (BC_2, IO_G32, output3, X, 855, 1, Z)," & -- PAD730 " 857 (BC_2, IO_G32, input, X)," & -- PAD730 " 858 (BC_2, *, controlr, 1)," & " 859 (BC_2, IO_D38, output3, X, 858, 1, Z)," & -- PAD729 " 860 (BC_2, IO_D38, input, X)," & -- PAD729 " 861 (BC_2, *, controlr, 1)," & " 862 (BC_2, IO_D37, output3, X, 861, 1, Z)," & -- PAD728 " 863 (BC_2, IO_D37, input, X)," & -- PAD728 " 864 (BC_2, *, controlr, 1)," & " 865 (BC_2, IO_E35, output3, X, 864, 1, Z)," & -- PAD727 " 866 (BC_2, IO_E35, input, X)," & -- PAD727 " 867 (BC_2, *, controlr, 1)," & " 868 (BC_2, IO_E34, output3, X, 867, 1, Z)," & -- PAD726 " 869 (BC_2, IO_E34, input, X)," & -- PAD726 " 870 (BC_2, *, controlr, 1)," & " 871 (BC_2, IO_C36, output3, X, 870, 1, Z)," & -- PAD725 " 872 (BC_2, IO_C36, input, X)," & -- PAD725 " 873 (BC_2, *, controlr, 1)," & " 874 (BC_2, IO_C35, output3, X, 873, 1, Z)," & -- PAD724 " 875 (BC_2, IO_C35, input, X)," & -- PAD724 " 876 (BC_2, *, controlr, 1)," & " 877 (BC_2, IO_D36, output3, X, 876, 1, Z)," & -- PAD723 " 878 (BC_2, IO_D36, input, X)," & -- PAD723 " 879 (BC_2, *, controlr, 1)," & " 880 (BC_2, IO_D35, output3, X, 879, 1, Z)," & -- PAD722 " 881 (BC_2, IO_D35, input, X)," & -- PAD722 " 882 (BC_2, *, controlr, 1)," & " 883 (BC_2, IO_C34, output3, X, 882, 1, Z)," & -- PAD721 " 884 (BC_2, IO_C34, input, X)," & -- PAD721 " 885 (BC_2, *, controlr, 1)," & " 886 (BC_2, IO_C33, output3, X, 885, 1, Z)," & -- PAD720 " 887 (BC_2, IO_C33, input, X)," & -- PAD720 " 888 (BC_2, *, controlr, 1)," & " 889 (BC_2, IO_D33, output3, X, 888, 1, Z)," & -- PAD719 " 890 (BC_2, IO_D33, input, X)," & -- PAD719 " 891 (BC_2, *, controlr, 1)," & " 892 (BC_2, IO_E33, output3, X, 891, 1, Z)," & -- PAD718 " 893 (BC_2, IO_E33, input, X)," & -- PAD718 " 894 (BC_2, *, controlr, 1)," & " 895 (BC_2, IO_B33, output3, X, 894, 1, Z)," & -- PAD717 " 896 (BC_2, IO_B33, input, X)," & -- PAD717 " 897 (BC_2, *, controlr, 1)," & " 898 (BC_2, IO_B32, output3, X, 897, 1, Z)," & -- PAD716 " 899 (BC_2, IO_B32, input, X)," & -- PAD716 " 900 (BC_2, *, controlr, 1)," & " 901 (BC_2, IO_D32, output3, X, 900, 1, Z)," & -- PAD715 " 902 (BC_2, IO_D32, input, X)," & -- PAD715 " 903 (BC_2, *, controlr, 1)," & " 904 (BC_2, IO_E32, output3, X, 903, 1, Z)," & -- PAD714 " 905 (BC_2, IO_E32, input, X)," & -- PAD714 " 906 (BC_2, *, controlr, 1)," & " 907 (BC_2, IO_B38, output3, X, 906, 1, Z)," & -- PAD713 " 908 (BC_2, IO_B38, input, X)," & -- PAD713 " 909 (BC_2, *, controlr, 1)," & " 910 (BC_2, IO_B37, output3, X, 909, 1, Z)," & -- PAD712 " 911 (BC_2, IO_B37, input, X)," & -- PAD712 " 912 (BC_2, *, controlr, 1)," & " 913 (BC_2, IO_C39, output3, X, 912, 1, Z)," & -- PAD711 " 914 (BC_2, IO_C39, input, X)," & -- PAD711 " 915 (BC_2, *, controlr, 1)," & " 916 (BC_2, IO_C38, output3, X, 915, 1, Z)," & -- PAD710 " 917 (BC_2, IO_C38, input, X)," & -- PAD710 " 918 (BC_2, *, controlr, 1)," & " 919 (BC_2, IO_A36, output3, X, 918, 1, Z)," & -- PAD709 " 920 (BC_2, IO_A36, input, X)," & -- PAD709 " 921 (BC_2, *, controlr, 1)," & " 922 (BC_2, IO_A35, output3, X, 921, 1, Z)," & -- PAD708 " 923 (BC_2, IO_A35, input, X)," & -- PAD708 " 924 (BC_2, *, controlr, 1)," & " 925 (BC_2, IO_A39, output3, X, 924, 1, Z)," & -- PAD707 " 926 (BC_2, IO_A39, input, X)," & -- PAD707 " 927 (BC_2, *, controlr, 1)," & " 928 (BC_2, IO_B39, output3, X, 927, 1, Z)," & -- PAD706 " 929 (BC_2, IO_B39, input, X)," & -- PAD706 " 930 (BC_2, *, controlr, 1)," & " 931 (BC_2, IO_A34, output3, X, 930, 1, Z)," & -- PAD705 " 932 (BC_2, IO_A34, input, X)," & -- PAD705 " 933 (BC_2, *, controlr, 1)," & " 934 (BC_2, IO_B34, output3, X, 933, 1, Z)," & -- PAD704 " 935 (BC_2, IO_B34, input, X)," & -- PAD704 " 936 (BC_2, *, controlr, 1)," & " 937 (BC_2, IO_A37, output3, X, 936, 1, Z)," & -- PAD703 " 938 (BC_2, IO_A37, input, X)," & -- PAD703 " 939 (BC_2, *, controlr, 1)," & " 940 (BC_2, IO_B36, output3, X, 939, 1, Z)," & -- PAD702 " 941 (BC_2, IO_B36, input, X)," & -- PAD702 " 942 (BC_2, *, controlr, 1)," & " 943 (BC_2, IO_G31, output3, X, 942, 1, Z)," & -- PAD701 " 944 (BC_2, IO_G31, input, X)," & -- PAD701 " 945 (BC_2, *, controlr, 1)," & " 946 (BC_2, IO_M26, output3, X, 945, 1, Z)," & -- PAD700 " 947 (BC_2, IO_M26, input, X)," & -- PAD700 " 948 (BC_2, *, controlr, 1)," & " 949 (BC_2, IO_L27, output3, X, 948, 1, Z)," & -- PAD699 " 950 (BC_2, IO_L27, input, X)," & -- PAD699 " 951 (BC_2, *, controlr, 1)," & " 952 (BC_2, IO_M27, output3, X, 951, 1, Z)," & -- PAD698 " 953 (BC_2, IO_M27, input, X)," & -- PAD698 " 954 (BC_2, *, controlr, 1)," & " 955 (BC_2, IO_N24, output3, X, 954, 1, Z)," & -- PAD697 " 956 (BC_2, IO_N24, input, X)," & -- PAD697 " 957 (BC_2, *, controlr, 1)," & " 958 (BC_2, IO_N23, output3, X, 957, 1, Z)," & -- PAD696 " 959 (BC_2, IO_N23, input, X)," & -- PAD696 " 960 (BC_2, *, controlr, 1)," & " 961 (BC_2, IO_N26, output3, X, 960, 1, Z)," & -- PAD695 " 962 (BC_2, IO_N26, input, X)," & -- PAD695 " 963 (BC_2, *, controlr, 1)," & " 964 (BC_2, IO_N25, output3, X, 963, 1, Z)," & -- PAD694 " 965 (BC_2, IO_N25, input, X)," & -- PAD694 " 966 (BC_2, *, controlr, 1)," & " 967 (BC_2, IO_P23, output3, X, 966, 1, Z)," & -- PAD693 " 968 (BC_2, IO_P23, input, X)," & -- PAD693 " 969 (BC_2, *, controlr, 1)," & " 970 (BC_2, IO_P22, output3, X, 969, 1, Z)," & -- PAD692 " 971 (BC_2, IO_P22, input, X)," & -- PAD692 " 972 (BC_2, *, controlr, 1)," & " 973 (BC_2, IO_P26, output3, X, 972, 1, Z)," & -- PAD691 " 974 (BC_2, IO_P26, input, X)," & -- PAD691 " 975 (BC_2, *, controlr, 1)," & " 976 (BC_2, IO_P25, output3, X, 975, 1, Z)," & -- PAD690 " 977 (BC_2, IO_P25, input, X)," & -- PAD690 " 978 (BC_2, *, controlr, 1)," & " 979 (BC_2, IO_N21, output3, X, 978, 1, Z)," & -- PAD689 " 980 (BC_2, IO_N21, input, X)," & -- PAD689 " 981 (BC_2, *, controlr, 1)," & " 982 (BC_2, IO_P21, output3, X, 981, 1, Z)," & -- PAD688 " 983 (BC_2, IO_P21, input, X)," & -- PAD688 " 984 (BC_2, *, controlr, 1)," & " 985 (BC_2, IO_L21, output3, X, 984, 1, Z)," & -- PAD687 " 986 (BC_2, IO_L21, input, X)," & -- PAD687 " 987 (BC_2, *, controlr, 1)," & " 988 (BC_2, IO_M21, output3, X, 987, 1, Z)," & -- PAD686 " 989 (BC_2, IO_M21, input, X)," & -- PAD686 " 990 (BC_2, *, controlr, 1)," & " 991 (BC_2, IO_J22, output3, X, 990, 1, Z)," & -- PAD685 " 992 (BC_2, IO_J22, input, X)," & -- PAD685 " 993 (BC_2, *, controlr, 1)," & " 994 (BC_2, IO_K22, output3, X, 993, 1, Z)," & -- PAD684 " 995 (BC_2, IO_K22, input, X)," & -- PAD684 " 996 (BC_2, *, controlr, 1)," & " 997 (BC_2, IO_L26, output3, X, 996, 1, Z)," & -- PAD683 " 998 (BC_2, IO_L26, input, X)," & -- PAD683 " 999 (BC_2, *, controlr, 1)," & "1000 (BC_2, IO_L25, output3, X, 999, 1, Z)," & -- PAD682 "1001 (BC_2, IO_L25, input, X)," & -- PAD682 "1002 (BC_2, *, controlr, 1)," & "1003 (BC_2, IO_L22, output3, X, 1002, 1, Z)," & -- PAD681 "1004 (BC_2, IO_L22, input, X)," & -- PAD681 "1005 (BC_2, *, controlr, 1)," & "1006 (BC_2, IO_M22, output3, X, 1005, 1, Z)," & -- PAD680 "1007 (BC_2, IO_M22, input, X)," & -- PAD680 "1008 (BC_2, *, controlr, 1)," & "1009 (BC_2, IO_J23, output3, X, 1008, 1, Z)," & -- PAD679 "1010 (BC_2, IO_J23, input, X)," & -- PAD679 "1011 (BC_2, *, controlr, 1)," & "1012 (BC_2, IO_K23, output3, X, 1011, 1, Z)," & -- PAD678 "1013 (BC_2, IO_K23, input, X)," & -- PAD678 "1014 (BC_2, *, controlr, 1)," & "1015 (BC_2, IO_L24, output3, X, 1014, 1, Z)," & -- PAD677 "1016 (BC_2, IO_L24, input, X)," & -- PAD677 "1017 (BC_2, *, controlr, 1)," & "1018 (BC_2, IO_M24, output3, X, 1017, 1, Z)," & -- PAD676 "1019 (BC_2, IO_M24, input, X)," & -- PAD676 "1020 (BC_2, *, controlr, 1)," & "1021 (BC_2, IO_J26, output3, X, 1020, 1, Z)," & -- PAD675 "1022 (BC_2, IO_J26, input, X)," & -- PAD675 "1023 (BC_2, *, controlr, 1)," & "1024 (BC_2, IO_J25, output3, X, 1023, 1, Z)," & -- PAD674 "1025 (BC_2, IO_J25, input, X)," & -- PAD674 "1026 (BC_2, *, controlr, 1)," & "1027 (BC_2, IO_K25, output3, X, 1026, 1, Z)," & -- PAD673 "1028 (BC_2, IO_K25, input, X)," & -- PAD673 "1029 (BC_2, *, controlr, 1)," & "1030 (BC_2, IO_K24, output3, X, 1029, 1, Z)," & -- PAD672 "1031 (BC_2, IO_K24, input, X)," & -- PAD672 "1032 (BC_2, *, controlr, 1)," & "1033 (BC_2, IO_J27, output3, X, 1032, 1, Z)," & -- PAD671 "1034 (BC_2, IO_J27, input, X)," & -- PAD671 "1035 (BC_2, *, controlr, 1)," & "1036 (BC_2, IO_K27, output3, X, 1035, 1, Z)," & -- PAD670 "1037 (BC_2, IO_K27, input, X)," & -- PAD670 "1038 (BC_2, *, controlr, 1)," & "1039 (BC_2, IO_H29, output3, X, 1038, 1, Z)," & -- PAD669 "1040 (BC_2, IO_H29, input, X)," & -- PAD669 "1041 (BC_2, *, controlr, 1)," & "1042 (BC_2, IO_H28, output3, X, 1041, 1, Z)," & -- PAD668 "1043 (BC_2, IO_H28, input, X)," & -- PAD668 "1044 (BC_2, *, controlr, 1)," & "1045 (BC_2, IO_J28, output3, X, 1044, 1, Z)," & -- PAD667 "1046 (BC_2, IO_J28, input, X)," & -- PAD667 "1047 (BC_2, *, controlr, 1)," & "1048 (BC_2, IO_K28, output3, X, 1047, 1, Z)," & -- PAD666 "1049 (BC_2, IO_K28, input, X)," & -- PAD666 "1050 (BC_2, *, controlr, 1)," & "1051 (BC_2, IO_G29, output3, X, 1050, 1, Z)," & -- PAD665 "1052 (BC_2, IO_G29, input, X)," & -- PAD665 "1053 (BC_2, *, controlr, 1)," & "1054 (BC_2, IO_G28, output3, X, 1053, 1, Z)," & -- PAD664 "1055 (BC_2, IO_G28, input, X)," & -- PAD664 "1056 (BC_2, *, controlr, 1)," & "1057 (BC_2, IO_G23, output3, X, 1056, 1, Z)," & -- PAD663 "1058 (BC_2, IO_G23, input, X)," & -- PAD663 "1059 (BC_2, *, controlr, 1)," & "1060 (BC_2, IO_H23, output3, X, 1059, 1, Z)," & -- PAD662 "1061 (BC_2, IO_H23, input, X)," & -- PAD662 "1062 (BC_2, *, controlr, 1)," & "1063 (BC_2, IO_G27, output3, X, 1062, 1, Z)," & -- PAD661 "1064 (BC_2, IO_G27, input, X)," & -- PAD661 "1065 (BC_2, *, controlr, 1)," & "1066 (BC_2, IO_G26, output3, X, 1065, 1, Z)," & -- PAD660 "1067 (BC_2, IO_G26, input, X)," & -- PAD660 "1068 (BC_2, *, controlr, 1)," & "1069 (BC_2, IO_G22, output3, X, 1068, 1, Z)," & -- PAD659 "1070 (BC_2, IO_G22, input, X)," & -- PAD659 "1071 (BC_2, *, controlr, 1)," & "1072 (BC_2, IO_G21, output3, X, 1071, 1, Z)," & -- PAD658 "1073 (BC_2, IO_G21, input, X)," & -- PAD658 "1074 (BC_2, *, controlr, 1)," & "1075 (BC_2, IO_H26, output3, X, 1074, 1, Z)," & -- PAD657 "1076 (BC_2, IO_H26, input, X)," & -- PAD657 "1077 (BC_2, *, controlr, 1)," & "1078 (BC_2, IO_H25, output3, X, 1077, 1, Z)," & -- PAD656 "1079 (BC_2, IO_H25, input, X)," & -- PAD656 "1080 (BC_2, *, controlr, 1)," & "1081 (BC_2, IO_H21, output3, X, 1080, 1, Z)," & -- PAD655 "1082 (BC_2, IO_H21, input, X)," & -- PAD655 "1083 (BC_2, *, controlr, 1)," & "1084 (BC_2, IO_J21, output3, X, 1083, 1, Z)," & -- PAD654 "1085 (BC_2, IO_J21, input, X)," & -- PAD654 "1086 (BC_2, *, controlr, 1)," & "1087 (BC_2, IO_G24, output3, X, 1086, 1, Z)," & -- PAD653 "1088 (BC_2, IO_G24, input, X)," & -- PAD653 "1089 (BC_2, *, controlr, 1)," & "1090 (BC_2, IO_H24, output3, X, 1089, 1, Z)," & -- PAD652 "1091 (BC_2, IO_H24, input, X)," & -- PAD652 "1092 (BC_2, *, controlr, 1)," & "1093 (BC_2, IO_M23, output3, X, 1092, 1, Z)," & -- PAD651 "1094 (BC_2, IO_M23, input, X)," & -- PAD651 "1095 (BC_2, *, controlr, 1)," & "1096 (BC_2, IO_F24, output3, X, 1095, 1, Z)," & -- PAD650 "1097 (BC_2, IO_F24, input, X)," & -- PAD650 "1098 (BC_2, *, controlr, 1)," & "1099 (BC_2, IO_F31, output3, X, 1098, 1, Z)," & -- PAD649 "1100 (BC_2, IO_F31, input, X)," & -- PAD649 "1101 (BC_2, *, controlr, 1)," & "1102 (BC_2, IO_F30, output3, X, 1101, 1, Z)," & -- PAD648 "1103 (BC_2, IO_F30, input, X)," & -- PAD648 "1104 (BC_2, *, controlr, 1)," & "1105 (BC_2, IO_F27, output3, X, 1104, 1, Z)," & -- PAD647 "1106 (BC_2, IO_F27, input, X)," & -- PAD647 "1107 (BC_2, *, controlr, 1)," & "1108 (BC_2, IO_F26, output3, X, 1107, 1, Z)," & -- PAD646 "1109 (BC_2, IO_F26, input, X)," & -- PAD646 "1110 (BC_2, *, controlr, 1)," & "1111 (BC_2, IO_E29, output3, X, 1110, 1, Z)," & -- PAD645 "1112 (BC_2, IO_E29, input, X)," & -- PAD645 "1113 (BC_2, *, controlr, 1)," & "1114 (BC_2, IO_F29, output3, X, 1113, 1, Z)," & -- PAD644 "1115 (BC_2, IO_F29, input, X)," & -- PAD644 "1116 (BC_2, *, controlr, 1)," & "1117 (BC_2, IO_E28, output3, X, 1116, 1, Z)," & -- PAD643 "1118 (BC_2, IO_E28, input, X)," & -- PAD643 "1119 (BC_2, *, controlr, 1)," & "1120 (BC_2, IO_E27, output3, X, 1119, 1, Z)," & -- PAD642 "1121 (BC_2, IO_E27, input, X)," & -- PAD642 "1122 (BC_2, *, controlr, 1)," & "1123 (BC_2, IO_C30, output3, X, 1122, 1, Z)," & -- PAD641 "1124 (BC_2, IO_C30, input, X)," & -- PAD641 "1125 (BC_2, *, controlr, 1)," & "1126 (BC_2, IO_D30, output3, X, 1125, 1, Z)," & -- PAD640 "1127 (BC_2, IO_D30, input, X)," & -- PAD640 "1128 (BC_2, *, controlr, 1)," & "1129 (BC_2, IO_D31, output3, X, 1128, 1, Z)," & -- PAD639 "1130 (BC_2, IO_D31, input, X)," & -- PAD639 "1131 (BC_2, *, controlr, 1)," & "1132 (BC_2, IO_E30, output3, X, 1131, 1, Z)," & -- PAD638 "1133 (BC_2, IO_E30, input, X)," & -- PAD638 "1134 (BC_2, *, controlr, 1)," & "1135 (BC_2, IO_B31, output3, X, 1134, 1, Z)," & -- PAD637 "1136 (BC_2, IO_B31, input, X)," & -- PAD637 "1137 (BC_2, *, controlr, 1)," & "1138 (BC_2, IO_C31, output3, X, 1137, 1, Z)," & -- PAD636 "1139 (BC_2, IO_C31, input, X)," & -- PAD636 "1140 (BC_2, *, controlr, 1)," & "1141 (BC_2, IO_A30, output3, X, 1140, 1, Z)," & -- PAD635 "1142 (BC_2, IO_A30, input, X)," & -- PAD635 "1143 (BC_2, *, controlr, 1)," & "1144 (BC_2, IO_A29, output3, X, 1143, 1, Z)," & -- PAD634 "1145 (BC_2, IO_A29, input, X)," & -- PAD634 "1146 (BC_2, *, controlr, 1)," & "1147 (BC_2, IO_A32, output3, X, 1146, 1, Z)," & -- PAD633 "1148 (BC_2, IO_A32, input, X)," & -- PAD633 "1149 (BC_2, *, controlr, 1)," & "1150 (BC_2, IO_A31, output3, X, 1149, 1, Z)," & -- PAD632 "1151 (BC_2, IO_A31, input, X)," & -- PAD632 "1152 (BC_2, *, controlr, 1)," & "1153 (BC_2, IO_B29, output3, X, 1152, 1, Z)," & -- PAD631 "1154 (BC_2, IO_B29, input, X)," & -- PAD631 "1155 (BC_2, *, controlr, 1)," & "1156 (BC_2, IO_B28, output3, X, 1155, 1, Z)," & -- PAD630 "1157 (BC_2, IO_B28, input, X)," & -- PAD630 "1158 (BC_2, *, controlr, 1)," & "1159 (BC_2, IO_C29, output3, X, 1158, 1, Z)," & -- PAD629 "1160 (BC_2, IO_C29, input, X)," & -- PAD629 "1161 (BC_2, *, controlr, 1)," & "1162 (BC_2, IO_C28, output3, X, 1161, 1, Z)," & -- PAD628 "1163 (BC_2, IO_C28, input, X)," & -- PAD628 "1164 (BC_2, *, controlr, 1)," & "1165 (BC_2, IO_D28, output3, X, 1164, 1, Z)," & -- PAD627 "1166 (BC_2, IO_D28, input, X)," & -- PAD627 "1167 (BC_2, *, controlr, 1)," & "1168 (BC_2, IO_D27, output3, X, 1167, 1, Z)," & -- PAD626 "1169 (BC_2, IO_D27, input, X)," & -- PAD626 "1170 (BC_2, *, controlr, 1)," & "1171 (BC_2, IO_C26, output3, X, 1170, 1, Z)," & -- PAD625 "1172 (BC_2, IO_C26, input, X)," & -- PAD625 "1173 (BC_2, *, controlr, 1)," & "1174 (BC_2, IO_C25, output3, X, 1173, 1, Z)," & -- PAD624 "1175 (BC_2, IO_C25, input, X)," & -- PAD624 "1176 (BC_2, *, controlr, 1)," & "1177 (BC_2, IO_D26, output3, X, 1176, 1, Z)," & -- PAD623 "1178 (BC_2, IO_D26, input, X)," & -- PAD623 "1179 (BC_2, *, controlr, 1)," & "1180 (BC_2, IO_D25, output3, X, 1179, 1, Z)," & -- PAD622 "1181 (BC_2, IO_D25, input, X)," & -- PAD622 "1182 (BC_2, *, controlr, 1)," & "1183 (BC_2, IO_D23, output3, X, 1182, 1, Z)," & -- PAD621 "1184 (BC_2, IO_D23, input, X)," & -- PAD621 "1185 (BC_2, *, controlr, 1)," & "1186 (BC_2, IO_D22, output3, X, 1185, 1, Z)," & -- PAD620 "1187 (BC_2, IO_D22, input, X)," & -- PAD620 "1188 (BC_2, *, controlr, 1)," & "1189 (BC_2, IO_E25, output3, X, 1188, 1, Z)," & -- PAD619 "1190 (BC_2, IO_E25, input, X)," & -- PAD619 "1191 (BC_2, *, controlr, 1)," & "1192 (BC_2, IO_F25, output3, X, 1191, 1, Z)," & -- PAD618 "1193 (BC_2, IO_F25, input, X)," & -- PAD618 "1194 (BC_2, *, controlr, 1)," & "1195 (BC_2, IO_E22, output3, X, 1194, 1, Z)," & -- PAD617 "1196 (BC_2, IO_E22, input, X)," & -- PAD617 "1197 (BC_2, *, controlr, 1)," & "1198 (BC_2, IO_F22, output3, X, 1197, 1, Z)," & -- PAD616 "1199 (BC_2, IO_F22, input, X)," & -- PAD616 "1200 (BC_2, *, controlr, 1)," & "1201 (BC_2, IO_E24, output3, X, 1200, 1, Z)," & -- PAD615 "1202 (BC_2, IO_E24, input, X)," & -- PAD615 "1203 (BC_2, *, controlr, 1)," & "1204 (BC_2, IO_E23, output3, X, 1203, 1, Z)," & -- PAD614 "1205 (BC_2, IO_E23, input, X)," & -- PAD614 "1206 (BC_2, *, controlr, 1)," & "1207 (BC_2, IO_B24, output3, X, 1206, 1, Z)," & -- PAD613 "1208 (BC_2, IO_B24, input, X)," & -- PAD613 "1209 (BC_2, *, controlr, 1)," & "1210 (BC_2, IO_C24, output3, X, 1209, 1, Z)," & -- PAD612 "1211 (BC_2, IO_C24, input, X)," & -- PAD612 "1212 (BC_2, *, controlr, 1)," & "1213 (BC_2, IO_B27, output3, X, 1212, 1, Z)," & -- PAD611 "1214 (BC_2, IO_B27, input, X)," & -- PAD611 "1215 (BC_2, *, controlr, 1)," & "1216 (BC_2, IO_B26, output3, X, 1215, 1, Z)," & -- PAD610 "1217 (BC_2, IO_B26, input, X)," & -- PAD610 "1218 (BC_2, *, controlr, 1)," & "1219 (BC_2, IO_B23, output3, X, 1218, 1, Z)," & -- PAD609 "1220 (BC_2, IO_B23, input, X)," & -- PAD609 "1221 (BC_2, *, controlr, 1)," & "1222 (BC_2, IO_C23, output3, X, 1221, 1, Z)," & -- PAD608 "1223 (BC_2, IO_C23, input, X)," & -- PAD608 "1224 (BC_2, *, controlr, 1)," & "1225 (BC_2, IO_A27, output3, X, 1224, 1, Z)," & -- PAD607 "1226 (BC_2, IO_A27, input, X)," & -- PAD607 "1227 (BC_2, *, controlr, 1)," & "1228 (BC_2, IO_A26, output3, X, 1227, 1, Z)," & -- PAD606 "1229 (BC_2, IO_A26, input, X)," & -- PAD606 "1230 (BC_2, *, controlr, 1)," & "1231 (BC_2, IO_A22, output3, X, 1230, 1, Z)," & -- PAD605 "1232 (BC_2, IO_A22, input, X)," & -- PAD605 "1233 (BC_2, *, controlr, 1)," & "1234 (BC_2, IO_B22, output3, X, 1233, 1, Z)," & -- PAD604 "1235 (BC_2, IO_B22, input, X)," & -- PAD604 "1236 (BC_2, *, controlr, 1)," & "1237 (BC_2, IO_A25, output3, X, 1236, 1, Z)," & -- PAD603 "1238 (BC_2, IO_A25, input, X)," & -- PAD603 "1239 (BC_2, *, controlr, 1)," & "1240 (BC_2, IO_A24, output3, X, 1239, 1, Z)," & -- PAD602 "1241 (BC_2, IO_A24, input, X)," & -- PAD602 "1242 (BC_2, *, controlr, 1)," & "1243 (BC_2, IO_F21, output3, X, 1242, 1, Z)," & -- PAD601 "1244 (BC_2, IO_F21, input, X)," & -- PAD601 "1245 (BC_2, *, controlr, 1)," & "1246 (BC_2, IO_K20, output3, X, 1245, 1, Z)," & -- PAD600 "1247 (BC_2, IO_K20, input, X)," & -- PAD600 "1248 (BC_2, *, controlr, 1)," & "1249 (BC_2, IO_L19, output3, X, 1248, 1, Z)," & -- PAD599 "1250 (BC_2, IO_L19, input, X)," & -- PAD599 "1251 (BC_2, *, controlr, 1)," & "1252 (BC_2, IO_L20, output3, X, 1251, 1, Z)," & -- PAD598 "1253 (BC_2, IO_L20, input, X)," & -- PAD598 "1254 (BC_2, *, controlr, 1)," & "1255 (BC_2, IO_N20, output3, X, 1254, 1, Z)," & -- PAD597 "1256 (BC_2, IO_N20, input, X)," & -- PAD597 "1257 (BC_2, *, controlr, 1)," & "1258 (BC_2, IO_P20, output3, X, 1257, 1, Z)," & -- PAD596 "1259 (BC_2, IO_P20, input, X)," & -- PAD596 "1260 (BC_2, *, controlr, 1)," & "1261 (BC_2, IO_M18, output3, X, 1260, 1, Z)," & -- PAD595 "1262 (BC_2, IO_M18, input, X)," & -- PAD595 "1263 (BC_2, *, controlr, 1)," & "1264 (BC_2, IO_M19, output3, X, 1263, 1, Z)," & -- PAD594 "1265 (BC_2, IO_M19, input, X)," & -- PAD594 "1266 (BC_2, *, controlr, 1)," & "1267 (BC_2, IO_N18, output3, X, 1266, 1, Z)," & -- PAD593 "1268 (BC_2, IO_N18, input, X)," & -- PAD593 "1269 (BC_2, *, controlr, 1)," & "1270 (BC_2, IO_N19, output3, X, 1269, 1, Z)," & -- PAD592 "1271 (BC_2, IO_N19, input, X)," & -- PAD592 "1272 (BC_2, *, controlr, 1)," & "1273 (BC_2, IO_L17, output3, X, 1272, 1, Z)," & -- PAD591 "1274 (BC_2, IO_L17, input, X)," & -- PAD591 "1275 (BC_2, *, controlr, 1)," & "1276 (BC_2, IO_M17, output3, X, 1275, 1, Z)," & -- PAD590 "1277 (BC_2, IO_M17, input, X)," & -- PAD590 "1278 (BC_2, *, controlr, 1)," & "1279 (BC_2, IO_P17, output3, X, 1278, 1, Z)," & -- PAD589 "1280 (BC_2, IO_P17, input, X)," & -- PAD589 "1281 (BC_2, *, controlr, 1)," & "1282 (BC_2, IO_P18, output3, X, 1281, 1, Z)," & -- PAD588 "1283 (BC_2, IO_P18, input, X)," & -- PAD588 "1284 (BC_2, *, controlr, 1)," & "1285 (BC_2, IO_G17, output3, X, 1284, 1, Z)," & -- PAD587 "1286 (BC_2, IO_G17, input, X)," & -- PAD587 "1287 (BC_2, *, controlr, 1)," & "1288 (BC_2, IO_H18, output3, X, 1287, 1, Z)," & -- PAD586 "1289 (BC_2, IO_H18, input, X)," & -- PAD586 "1290 (BC_2, *, controlr, 1)," & "1291 (BC_2, IO_H20, output3, X, 1290, 1, Z)," & -- PAD585 "1292 (BC_2, IO_H20, input, X)," & -- PAD585 "1293 (BC_2, *, controlr, 1)," & "1294 (BC_2, IO_J20, output3, X, 1293, 1, Z)," & -- PAD584 "1295 (BC_2, IO_J20, input, X)," & -- PAD584 "1296 (BC_2, *, controlr, 1)," & "1297 (BC_2, IO_J17, output3, X, 1296, 1, Z)," & -- PAD583 "1298 (BC_2, IO_J17, input, X)," & -- PAD583 "1299 (BC_2, *, controlr, 1)," & "1300 (BC_2, IO_K17, output3, X, 1299, 1, Z)," & -- PAD582 "1301 (BC_2, IO_K17, input, X)," & -- PAD582 "1302 (BC_2, *, controlr, 1)," & "1303 (BC_2, IO_E20, output3, X, 1302, 1, Z)," & -- PAD581 "1304 (BC_2, IO_E20, input, X)," & -- PAD581 "1305 (BC_2, *, controlr, 1)," & "1306 (BC_2, IO_F20, output3, X, 1305, 1, Z)," & -- PAD580 "1307 (BC_2, IO_F20, input, X)," & -- PAD580 "1308 (BC_2, *, controlr, 1)," & "1309 (BC_2, IO_J18, output3, X, 1308, 1, Z)," & -- PAD579 "1310 (BC_2, IO_J18, input, X)," & -- PAD579 "1311 (BC_2, *, controlr, 1)," & "1312 (BC_2, IO_K19, output3, X, 1311, 1, Z)," & -- PAD578 "1313 (BC_2, IO_K19, input, X)," & -- PAD578 "1314 (BC_2, *, controlr, 1)," & "1315 (BC_2, IO_G18, output3, X, 1314, 1, Z)," & -- PAD577 "1316 (BC_2, IO_G18, input, X)," & -- PAD577 "1317 (BC_2, *, controlr, 1)," & "1318 (BC_2, IO_H19, output3, X, 1317, 1, Z)," & -- PAD576 "1319 (BC_2, IO_H19, input, X)," & -- PAD576 "1320 (BC_2, *, controlr, 1)," & "1321 (BC_2, IO_E18, output3, X, 1320, 1, Z)," & -- PAD575 "1322 (BC_2, IO_E18, input, X)," & -- PAD575 "1323 (BC_2, *, controlr, 1)," & "1324 (BC_2, IO_E19, output3, X, 1323, 1, Z)," & -- PAD574 "1325 (BC_2, IO_E19, input, X)," & -- PAD574 "1326 (BC_2, *, controlr, 1)," & "1327 (BC_2, IO_F19, output3, X, 1326, 1, Z)," & -- PAD573 "1328 (BC_2, IO_F19, input, X)," & -- PAD573 "1329 (BC_2, *, controlr, 1)," & "1330 (BC_2, IO_G19, output3, X, 1329, 1, Z)," & -- PAD572 "1331 (BC_2, IO_G19, input, X)," & -- PAD572 "1332 (BC_2, *, controlr, 1)," & "1333 (BC_2, IO_D17, output3, X, 1332, 1, Z)," & -- PAD571 "1334 (BC_2, IO_D17, input, X)," & -- PAD571 "1335 (BC_2, *, controlr, 1)," & "1336 (BC_2, IO_D18, output3, X, 1335, 1, Z)," & -- PAD570 "1337 (BC_2, IO_D18, input, X)," & -- PAD570 "1338 (BC_2, *, controlr, 1)," & "1339 (BC_2, IO_C21, output3, X, 1338, 1, Z)," & -- PAD569 "1340 (BC_2, IO_C21, input, X)," & -- PAD569 "1341 (BC_2, *, controlr, 1)," & "1342 (BC_2, IO_D21, output3, X, 1341, 1, Z)," & -- PAD568 "1343 (BC_2, IO_D21, input, X)," & -- PAD568 "1344 (BC_2, *, controlr, 1)," & "1345 (BC_2, IO_E17, output3, X, 1344, 1, Z)," & -- PAD567 "1346 (BC_2, IO_E17, input, X)," & -- PAD567 "1347 (BC_2, *, controlr, 1)," & "1348 (BC_2, IO_F17, output3, X, 1347, 1, Z)," & -- PAD566 "1349 (BC_2, IO_F17, input, X)," & -- PAD566 "1350 (BC_2, *, controlr, 1)," & "1351 (BC_2, IO_C20, output3, X, 1350, 1, Z)," & -- PAD565 "1352 (BC_2, IO_C20, input, X)," & -- PAD565 "1353 (BC_2, *, controlr, 1)," & "1354 (BC_2, IO_D20, output3, X, 1353, 1, Z)," & -- PAD564 "1355 (BC_2, IO_D20, input, X)," & -- PAD564 "1356 (BC_2, *, controlr, 1)," & "1357 (BC_2, IO_B18, output3, X, 1356, 1, Z)," & -- PAD563 "1358 (BC_2, IO_B18, input, X)," & -- PAD563 "1359 (BC_2, *, controlr, 1)," & "1360 (BC_2, IO_C18, output3, X, 1359, 1, Z)," & -- PAD562 "1361 (BC_2, IO_C18, input, X)," & -- PAD562 "1362 (BC_2, *, controlr, 1)," & "1363 (BC_2, IO_A21, output3, X, 1362, 1, Z)," & -- PAD561 "1364 (BC_2, IO_A21, input, X)," & -- PAD561 "1365 (BC_2, *, controlr, 1)," & "1366 (BC_2, IO_B21, output3, X, 1365, 1, Z)," & -- PAD560 "1367 (BC_2, IO_B21, input, X)," & -- PAD560 "1368 (BC_2, *, controlr, 1)," & "1369 (BC_2, IO_A17, output3, X, 1368, 1, Z)," & -- PAD559 "1370 (BC_2, IO_A17, input, X)," & -- PAD559 "1371 (BC_2, *, controlr, 1)," & "1372 (BC_2, IO_B17, output3, X, 1371, 1, Z)," & -- PAD558 "1373 (BC_2, IO_B17, input, X)," & -- PAD558 "1374 (BC_2, *, controlr, 1)," & "1375 (BC_2, IO_A19, output3, X, 1374, 1, Z)," & -- PAD557 "1376 (BC_2, IO_A19, input, X)," & -- PAD557 "1377 (BC_2, *, controlr, 1)," & "1378 (BC_2, IO_A20, output3, X, 1377, 1, Z)," & -- PAD556 "1379 (BC_2, IO_A20, input, X)," & -- PAD556 "1380 (BC_2, *, controlr, 1)," & "1381 (BC_2, IO_A15, output3, X, 1380, 1, Z)," & -- PAD555 "1382 (BC_2, IO_A15, input, X)," & -- PAD555 "1383 (BC_2, *, controlr, 1)," & "1384 (BC_2, IO_A16, output3, X, 1383, 1, Z)," & -- PAD554 "1385 (BC_2, IO_A16, input, X)," & -- PAD554 "1386 (BC_2, *, controlr, 1)," & "1387 (BC_2, IO_B19, output3, X, 1386, 1, Z)," & -- PAD553 "1388 (BC_2, IO_B19, input, X)," & -- PAD553 "1389 (BC_2, *, controlr, 1)," & "1390 (BC_2, IO_C19, output3, X, 1389, 1, Z)," & -- PAD552 "1391 (BC_2, IO_C19, input, X)," & -- PAD552 "1392 (BC_2, *, controlr, 1)," & "1393 (BC_2, IO_K18, output3, X, 1392, 1, Z)," & -- PAD551 "1394 (BC_2, IO_K18, input, X)," & -- PAD551 "1395 (BC_2, *, controlr, 1)," & "1396 (BC_2, IO_J11, output3, X, 1395, 1, Z)," & -- PAD550 "1397 (BC_2, IO_J11, input, X)," & -- PAD550 "1398 (BC_2, *, controlr, 1)," & "1399 (BC_2, IO_M11, output3, X, 1398, 1, Z)," & -- PAD549 "1400 (BC_2, IO_M11, input, X)," & -- PAD549 "1401 (BC_2, *, controlr, 1)," & "1402 (BC_2, IO_M12, output3, X, 1401, 1, Z)," & -- PAD548 "1403 (BC_2, IO_M12, input, X)," & -- PAD548 "1404 (BC_2, *, controlr, 1)," & "1405 (BC_2, IO_N14, output3, X, 1404, 1, Z)," & -- PAD547 "1406 (BC_2, IO_N14, input, X)," & -- PAD547 "1407 (BC_2, *, controlr, 1)," & "1408 (BC_2, IO_N15, output3, X, 1407, 1, Z)," & -- PAD546 "1409 (BC_2, IO_N15, input, X)," & -- PAD546 "1410 (BC_2, *, controlr, 1)," & "1411 (BC_2, IO_M13, output3, X, 1410, 1, Z)," & -- PAD545 "1412 (BC_2, IO_M13, input, X)," & -- PAD545 "1413 (BC_2, *, controlr, 1)," & "1414 (BC_2, IO_N13, output3, X, 1413, 1, Z)," & -- PAD544 "1415 (BC_2, IO_N13, input, X)," & -- PAD544 "1416 (BC_2, *, controlr, 1)," & "1417 (BC_2, IO_M16, output3, X, 1416, 1, Z)," & -- PAD543 "1418 (BC_2, IO_M16, input, X)," & -- PAD543 "1419 (BC_2, *, controlr, 1)," & "1420 (BC_2, IO_N16, output3, X, 1419, 1, Z)," & -- PAD542 "1421 (BC_2, IO_N16, input, X)," & -- PAD542 "1422 (BC_2, *, controlr, 1)," & "1423 (BC_2, IO_L14, output3, X, 1422, 1, Z)," & -- PAD541 "1424 (BC_2, IO_L14, input, X)," & -- PAD541 "1425 (BC_2, *, controlr, 1)," & "1426 (BC_2, IO_M14, output3, X, 1425, 1, Z)," & -- PAD540 "1427 (BC_2, IO_M14, input, X)," & -- PAD540 "1428 (BC_2, *, controlr, 1)," & "1429 (BC_2, IO_L11, output3, X, 1428, 1, Z)," & -- PAD539 "1430 (BC_2, IO_L11, input, X)," & -- PAD539 "1431 (BC_2, *, controlr, 1)," & "1432 (BC_2, IO_L12, output3, X, 1431, 1, Z)," & -- PAD538 "1433 (BC_2, IO_L12, input, X)," & -- PAD538 "1434 (BC_2, *, controlr, 1)," & "1435 (BC_2, IO_L15, output3, X, 1434, 1, Z)," & -- PAD537 "1436 (BC_2, IO_L15, input, X)," & -- PAD537 "1437 (BC_2, *, controlr, 1)," & "1438 (BC_2, IO_L16, output3, X, 1437, 1, Z)," & -- PAD536 "1439 (BC_2, IO_L16, input, X)," & -- PAD536 "1440 (BC_2, *, controlr, 1)," & "1441 (BC_2, IO_K13, output3, X, 1440, 1, Z)," & -- PAD535 "1442 (BC_2, IO_K13, input, X)," & -- PAD535 "1443 (BC_2, *, controlr, 1)," & "1444 (BC_2, IO_K14, output3, X, 1443, 1, Z)," & -- PAD534 "1445 (BC_2, IO_K14, input, X)," & -- PAD534 "1446 (BC_2, *, controlr, 1)," & "1447 (BC_2, IO_J15, output3, X, 1446, 1, Z)," & -- PAD533 "1448 (BC_2, IO_J15, input, X)," & -- PAD533 "1449 (BC_2, *, controlr, 1)," & "1450 (BC_2, IO_K15, output3, X, 1449, 1, Z)," & -- PAD532 "1451 (BC_2, IO_K15, input, X)," & -- PAD532 "1452 (BC_2, *, controlr, 1)," & "1453 (BC_2, IO_J12, output3, X, 1452, 1, Z)," & -- PAD531 "1454 (BC_2, IO_J12, input, X)," & -- PAD531 "1455 (BC_2, *, controlr, 1)," & "1456 (BC_2, IO_K12, output3, X, 1455, 1, Z)," & -- PAD530 "1457 (BC_2, IO_K12, input, X)," & -- PAD530 "1458 (BC_2, *, controlr, 1)," & "1459 (BC_2, IO_H13, output3, X, 1458, 1, Z)," & -- PAD529 "1460 (BC_2, IO_H13, input, X)," & -- PAD529 "1461 (BC_2, *, controlr, 1)," & "1462 (BC_2, IO_J13, output3, X, 1461, 1, Z)," & -- PAD528 "1463 (BC_2, IO_J13, input, X)," & -- PAD528 "1464 (BC_2, *, controlr, 1)," & "1465 (BC_2, IO_H14, output3, X, 1464, 1, Z)," & -- PAD527 "1466 (BC_2, IO_H14, input, X)," & -- PAD527 "1467 (BC_2, *, controlr, 1)," & "1468 (BC_2, IO_H15, output3, X, 1467, 1, Z)," & -- PAD526 "1469 (BC_2, IO_H15, input, X)," & -- PAD526 "1470 (BC_2, *, controlr, 1)," & "1471 (BC_2, IO_G13, output3, X, 1470, 1, Z)," & -- PAD525 "1472 (BC_2, IO_G13, input, X)," & -- PAD525 "1473 (BC_2, *, controlr, 1)," & "1474 (BC_2, IO_G14, output3, X, 1473, 1, Z)," & -- PAD524 "1475 (BC_2, IO_G14, input, X)," & -- PAD524 "1476 (BC_2, *, controlr, 1)," & "1477 (BC_2, IO_F14, output3, X, 1476, 1, Z)," & -- PAD523 "1478 (BC_2, IO_F14, input, X)," & -- PAD523 "1479 (BC_2, *, controlr, 1)," & "1480 (BC_2, IO_F15, output3, X, 1479, 1, Z)," & -- PAD522 "1481 (BC_2, IO_F15, input, X)," & -- PAD522 "1482 (BC_2, *, controlr, 1)," & "1483 (BC_2, IO_F12, output3, X, 1482, 1, Z)," & -- PAD521 "1484 (BC_2, IO_F12, input, X)," & -- PAD521 "1485 (BC_2, *, controlr, 1)," & "1486 (BC_2, IO_G12, output3, X, 1485, 1, Z)," & -- PAD520 "1487 (BC_2, IO_G12, input, X)," & -- PAD520 "1488 (BC_2, *, controlr, 1)," & "1489 (BC_2, IO_G16, output3, X, 1488, 1, Z)," & -- PAD519 "1490 (BC_2, IO_G16, input, X)," & -- PAD519 "1491 (BC_2, *, controlr, 1)," & "1492 (BC_2, IO_H16, output3, X, 1491, 1, Z)," & -- PAD518 "1493 (BC_2, IO_H16, input, X)," & -- PAD518 "1494 (BC_2, *, controlr, 1)," & "1495 (BC_2, IO_E13, output3, X, 1494, 1, Z)," & -- PAD517 "1496 (BC_2, IO_E13, input, X)," & -- PAD517 "1497 (BC_2, *, controlr, 1)," & "1498 (BC_2, IO_E14, output3, X, 1497, 1, Z)," & -- PAD516 "1499 (BC_2, IO_E14, input, X)," & -- PAD516 "1500 (BC_2, *, controlr, 1)," & "1501 (BC_2, IO_E15, output3, X, 1500, 1, Z)," & -- PAD515 "1502 (BC_2, IO_E15, input, X)," & -- PAD515 "1503 (BC_2, *, controlr, 1)," & "1504 (BC_2, IO_F16, output3, X, 1503, 1, Z)," & -- PAD514 "1505 (BC_2, IO_F16, input, X)," & -- PAD514 "1506 (BC_2, *, controlr, 1)," & "1507 (BC_2, IO_D12, output3, X, 1506, 1, Z)," & -- PAD513 "1508 (BC_2, IO_D12, input, X)," & -- PAD513 "1509 (BC_2, *, controlr, 1)," & "1510 (BC_2, IO_E12, output3, X, 1509, 1, Z)," & -- PAD512 "1511 (BC_2, IO_E12, input, X)," & -- PAD512 "1512 (BC_2, *, controlr, 1)," & "1513 (BC_2, IO_D15, output3, X, 1512, 1, Z)," & -- PAD511 "1514 (BC_2, IO_D15, input, X)," & -- PAD511 "1515 (BC_2, *, controlr, 1)," & "1516 (BC_2, IO_D16, output3, X, 1515, 1, Z)," & -- PAD510 "1517 (BC_2, IO_D16, input, X)," & -- PAD510 "1518 (BC_2, *, controlr, 1)," & "1519 (BC_2, IO_C13, output3, X, 1518, 1, Z)," & -- PAD509 "1520 (BC_2, IO_C13, input, X)," & -- PAD509 "1521 (BC_2, *, controlr, 1)," & "1522 (BC_2, IO_D13, output3, X, 1521, 1, Z)," & -- PAD508 "1523 (BC_2, IO_D13, input, X)," & -- PAD508 "1524 (BC_2, *, controlr, 1)," & "1525 (BC_2, IO_C14, output3, X, 1524, 1, Z)," & -- PAD507 "1526 (BC_2, IO_C14, input, X)," & -- PAD507 "1527 (BC_2, *, controlr, 1)," & "1528 (BC_2, IO_C15, output3, X, 1527, 1, Z)," & -- PAD506 "1529 (BC_2, IO_C15, input, X)," & -- PAD506 "1530 (BC_2, *, controlr, 1)," & "1531 (BC_2, IO_A14, output3, X, 1530, 1, Z)," & -- PAD505 "1532 (BC_2, IO_A14, input, X)," & -- PAD505 "1533 (BC_2, *, controlr, 1)," & "1534 (BC_2, IO_B14, output3, X, 1533, 1, Z)," & -- PAD504 "1535 (BC_2, IO_B14, input, X)," & -- PAD504 "1536 (BC_2, *, controlr, 1)," & "1537 (BC_2, IO_B16, output3, X, 1536, 1, Z)," & -- PAD503 "1538 (BC_2, IO_B16, input, X)," & -- PAD503 "1539 (BC_2, *, controlr, 1)," & "1540 (BC_2, IO_C16, output3, X, 1539, 1, Z)," & -- PAD502 "1541 (BC_2, IO_C16, input, X)," & -- PAD502 "1542 (BC_2, *, controlr, 1)," & "1543 (BC_2, IO_J16, output3, X, 1542, 1, Z)," & -- PAD501 "1544 (BC_2, IO_J16, input, X)," & -- PAD501 "1545 (BC_2, *, internal, X)," & "1546 (BC_2, *, internal, X)," & "1547 (BC_2, *, internal, X)," & "1548 (BC_2, *, internal, X)," & "1549 (BC_2, *, internal, X)," & "1550 (BC_2, *, internal, X)," & "1551 (BC_2, *, internal, X)," & "1552 (BC_2, *, internal, X)," & "1553 (BC_2, *, internal, X)," & "1554 (BC_2, *, internal, X)," & "1555 (BC_2, *, internal, X)," & "1556 (BC_2, *, internal, X)," & "1557 (BC_2, *, internal, X)," & "1558 (BC_2, *, internal, X)," & "1559 (BC_2, *, internal, X)," & "1560 (BC_2, *, internal, X)," & "1561 (BC_2, *, internal, X)," & "1562 (BC_2, *, internal, X)," & "1563 (BC_2, *, internal, X)," & "1564 (BC_2, *, internal, X)," & "1565 (BC_2, *, internal, X)," & "1566 (BC_4, *, internal, X)," & "1567 (BC_4, *, internal, X)," & "1568 (BC_4, *, internal, X)," & "1569 (BC_4, *, internal, X)," & "1570 (BC_4, *, internal, X)," & "1571 (BC_4, *, internal, X)," & "1572 (BC_4, *, internal, X)," & "1573 (BC_4, *, internal, X)," & "1574 (BC_4, *, internal, X)," & "1575 (BC_4, *, internal, X)," & "1576 (BC_4, *, internal, X)," & "1577 (BC_4, *, internal, X)," & "1578 (BC_4, MGTHRXN0_111, OBSERVE_ONLY, X)," & "1579 (BC_4, MGTHRXP0_111, OBSERVE_ONLY, X)," & "1580 (AC_2, MGTHTXP0_111, OUTPUT2, X)," & "1581 (BC_4, MGTHRXN1_111, OBSERVE_ONLY, X)," & "1582 (BC_4, MGTHRXP1_111, OBSERVE_ONLY, X)," & "1583 (AC_2, MGTHTXP1_111, OUTPUT2, X)," & "1584 (BC_4, MGTHRXN2_111, OBSERVE_ONLY, X)," & "1585 (BC_4, MGTHRXP2_111, OBSERVE_ONLY, X)," & "1586 (AC_2, MGTHTXP2_111, OUTPUT2, X)," & "1587 (BC_4, MGTHRXN3_111, OBSERVE_ONLY, X)," & "1588 (BC_4, MGTHRXP3_111, OBSERVE_ONLY, X)," & "1589 (AC_2, MGTHTXP3_111, OUTPUT2, X)," & "1590 (BC_4, MGTHRXN0_112, OBSERVE_ONLY, X)," & "1591 (BC_4, MGTHRXP0_112, OBSERVE_ONLY, X)," & "1592 (AC_2, MGTHTXP0_112, OUTPUT2, X)," & "1593 (BC_4, MGTHRXN1_112, OBSERVE_ONLY, X)," & "1594 (BC_4, MGTHRXP1_112, OBSERVE_ONLY, X)," & "1595 (AC_2, MGTHTXP1_112, OUTPUT2, X)," & "1596 (BC_4, MGTHRXN2_112, OBSERVE_ONLY, X)," & "1597 (BC_4, MGTHRXP2_112, OBSERVE_ONLY, X)," & "1598 (AC_2, MGTHTXP2_112, OUTPUT2, X)," & "1599 (BC_4, MGTHRXN3_112, OBSERVE_ONLY, X)," & "1600 (BC_4, MGTHRXP3_112, OBSERVE_ONLY, X)," & "1601 (AC_2, MGTHTXP3_112, OUTPUT2, X)," & "1602 (BC_4, MGTHRXN0_113, OBSERVE_ONLY, X)," & "1603 (BC_4, MGTHRXP0_113, OBSERVE_ONLY, X)," & "1604 (AC_2, MGTHTXP0_113, OUTPUT2, X)," & "1605 (BC_4, MGTHRXN1_113, OBSERVE_ONLY, X)," & "1606 (BC_4, MGTHRXP1_113, OBSERVE_ONLY, X)," & "1607 (AC_2, MGTHTXP1_113, OUTPUT2, X)," & "1608 (BC_4, MGTHRXN2_113, OBSERVE_ONLY, X)," & "1609 (BC_4, MGTHRXP2_113, OBSERVE_ONLY, X)," & "1610 (AC_2, MGTHTXP2_113, OUTPUT2, X)," & "1611 (BC_4, MGTHRXN3_113, OBSERVE_ONLY, X)," & "1612 (BC_4, MGTHRXP3_113, OBSERVE_ONLY, X)," & "1613 (AC_2, MGTHTXP3_113, OUTPUT2, X)," & "1614 (BC_4, MGTHRXN0_114, OBSERVE_ONLY, X)," & "1615 (BC_4, MGTHRXP0_114, OBSERVE_ONLY, X)," & "1616 (AC_2, MGTHTXP0_114, OUTPUT2, X)," & "1617 (BC_4, MGTHRXN1_114, OBSERVE_ONLY, X)," & "1618 (BC_4, MGTHRXP1_114, OBSERVE_ONLY, X)," & "1619 (AC_2, MGTHTXP1_114, OUTPUT2, X)," & "1620 (BC_4, MGTHRXN2_114, OBSERVE_ONLY, X)," & "1621 (BC_4, MGTHRXP2_114, OBSERVE_ONLY, X)," & "1622 (AC_2, MGTHTXP2_114, OUTPUT2, X)," & "1623 (BC_4, MGTHRXN3_114, OBSERVE_ONLY, X)," & "1624 (BC_4, MGTHRXP3_114, OBSERVE_ONLY, X)," & "1625 (AC_2, MGTHTXP3_114, OUTPUT2, X)," & "1626 (BC_4, MGTHRXN0_115, OBSERVE_ONLY, X)," & "1627 (BC_4, MGTHRXP0_115, OBSERVE_ONLY, X)," & "1628 (AC_2, MGTHTXP0_115, OUTPUT2, X)," & "1629 (BC_4, MGTHRXN1_115, OBSERVE_ONLY, X)," & "1630 (BC_4, MGTHRXP1_115, OBSERVE_ONLY, X)," & "1631 (AC_2, MGTHTXP1_115, OUTPUT2, X)," & "1632 (BC_4, MGTHRXN2_115, OBSERVE_ONLY, X)," & "1633 (BC_4, MGTHRXP2_115, OBSERVE_ONLY, X)," & "1634 (AC_2, MGTHTXP2_115, OUTPUT2, X)," & "1635 (BC_4, MGTHRXN3_115, OBSERVE_ONLY, X)," & "1636 (BC_4, MGTHRXP3_115, OBSERVE_ONLY, X)," & "1637 (AC_2, MGTHTXP3_115, OUTPUT2, X)," & "1638 (BC_4, MGTHRXN0_116, OBSERVE_ONLY, X)," & "1639 (BC_4, MGTHRXP0_116, OBSERVE_ONLY, X)," & "1640 (AC_2, MGTHTXP0_116, OUTPUT2, X)," & "1641 (BC_4, MGTHRXN1_116, OBSERVE_ONLY, X)," & "1642 (BC_4, MGTHRXP1_116, OBSERVE_ONLY, X)," & "1643 (AC_2, MGTHTXP1_116, OUTPUT2, X)," & "1644 (BC_4, MGTHRXN2_116, OBSERVE_ONLY, X)," & "1645 (BC_4, MGTHRXP2_116, OBSERVE_ONLY, X)," & "1646 (AC_2, MGTHTXP2_116, OUTPUT2, X)," & "1647 (BC_4, MGTHRXN3_116, OBSERVE_ONLY, X)," & "1648 (BC_4, MGTHRXP3_116, OBSERVE_ONLY, X)," & "1649 (AC_2, MGTHTXP3_116, OUTPUT2, X)," & "1650 (BC_4, MGTHRXN0_117, OBSERVE_ONLY, X)," & "1651 (BC_4, MGTHRXP0_117, OBSERVE_ONLY, X)," & "1652 (AC_2, MGTHTXP0_117, OUTPUT2, X)," & "1653 (BC_4, MGTHRXN1_117, OBSERVE_ONLY, X)," & "1654 (BC_4, MGTHRXP1_117, OBSERVE_ONLY, X)," & "1655 (AC_2, MGTHTXP1_117, OUTPUT2, X)," & "1656 (BC_4, MGTHRXN2_117, OBSERVE_ONLY, X)," & "1657 (BC_4, MGTHRXP2_117, OBSERVE_ONLY, X)," & "1658 (AC_2, MGTHTXP2_117, OUTPUT2, X)," & "1659 (BC_4, MGTHRXN3_117, OBSERVE_ONLY, X)," & "1660 (BC_4, MGTHRXP3_117, OBSERVE_ONLY, X)," & "1661 (AC_2, MGTHTXP3_117, OUTPUT2, X)," & "1662 (BC_4, MGTHRXN0_118, OBSERVE_ONLY, X)," & "1663 (BC_4, MGTHRXP0_118, OBSERVE_ONLY, X)," & "1664 (AC_2, MGTHTXP0_118, OUTPUT2, X)," & "1665 (BC_4, MGTHRXN1_118, OBSERVE_ONLY, X)," & "1666 (BC_4, MGTHRXP1_118, OBSERVE_ONLY, X)," & "1667 (AC_2, MGTHTXP1_118, OUTPUT2, X)," & "1668 (BC_4, MGTHRXN2_118, OBSERVE_ONLY, X)," & "1669 (BC_4, MGTHRXP2_118, OBSERVE_ONLY, X)," & "1670 (AC_2, MGTHTXP2_118, OUTPUT2, X)," & "1671 (BC_4, MGTHRXN3_118, OBSERVE_ONLY, X)," & "1672 (BC_4, MGTHRXP3_118, OBSERVE_ONLY, X)," & "1673 (AC_2, MGTHTXP3_118, OUTPUT2, X)," & "1674 (BC_4, MGTHRXN0_119, OBSERVE_ONLY, X)," & "1675 (BC_4, MGTHRXP0_119, OBSERVE_ONLY, X)," & "1676 (AC_2, MGTHTXP0_119, OUTPUT2, X)," & "1677 (BC_4, MGTHRXN1_119, OBSERVE_ONLY, X)," & "1678 (BC_4, MGTHRXP1_119, OBSERVE_ONLY, X)," & "1679 (AC_2, MGTHTXP1_119, OUTPUT2, X)," & "1680 (BC_4, MGTHRXN2_119, OBSERVE_ONLY, X)," & "1681 (BC_4, MGTHRXP2_119, OBSERVE_ONLY, X)," & "1682 (AC_2, MGTHTXP2_119, OUTPUT2, X)," & "1683 (BC_4, MGTHRXN3_119, OBSERVE_ONLY, X)," & "1684 (BC_4, MGTHRXP3_119, OBSERVE_ONLY, X)," & "1685 (AC_2, MGTHTXP3_119, OUTPUT2, X)," & "1686 (BC_2, *, internal, X)," & "1687 (BC_2, *, internal, X)," & "1688 (BC_2, *, internal, X)," & "1689 (BC_2, *, internal, X)," & "1690 (BC_2, *, internal, X)," & "1691 (BC_2, *, internal, X)," & "1692 (BC_2, *, internal, X)," & "1693 (BC_2, *, internal, X)," & "1694 (BC_2, *, internal, X)," & "1695 (BC_2, *, internal, X)," & "1696 (BC_2, *, internal, X)," & "1697 (BC_2, *, internal, X)," & "1698 (BC_2, *, internal, X)," & "1699 (BC_2, *, internal, X)," & "1700 (BC_2, *, internal, X)," & "1701 (BC_2, *, internal, X)," & "1702 (BC_2, *, internal, X)," & "1703 (BC_2, *, internal, X)," & "1704 (BC_2, *, internal, X)," & "1705 (BC_2, *, internal, X)," & "1706 (BC_2, *, internal, X)," & "1707 (BC_2, *, internal, X)," & "1708 (BC_2, *, internal, X)," & "1709 (BC_2, *, internal, X)," & "1710 (BC_2, *, internal, X)," & "1711 (BC_2, *, internal, X)," & "1712 (BC_2, *, internal, X)," & "1713 (BC_2, *, internal, X)," & "1714 (BC_2, *, internal, X)," & "1715 (BC_2, *, internal, X)," & "1716 (BC_2, *, internal, X)," & "1717 (BC_2, *, internal, X)," & "1718 (BC_2, *, internal, X)," & "1719 (BC_2, *, internal, X)," & "1720 (BC_2, *, internal, X)," & "1721 (BC_2, *, internal, X)," & "1722 (BC_2, *, internal, X)," & "1723 (BC_2, *, internal, X)," & "1724 (BC_2, *, internal, X)," & "1725 (BC_2, *, internal, X)," & "1726 (BC_2, *, internal, 1)," & -- PAD500.T "1727 (BC_2, *, internal, X)," & -- PAD500.O "1728 (BC_2, *, internal, X)," & -- PAD500.I "1729 (BC_2, *, internal, 1)," & -- PAD499.T "1730 (BC_2, *, internal, X)," & -- PAD499.O "1731 (BC_2, *, internal, X)," & -- PAD499.I "1732 (BC_2, *, internal, 1)," & -- PAD498.T "1733 (BC_2, *, internal, X)," & -- PAD498.O "1734 (BC_2, *, internal, X)," & -- PAD498.I "1735 (BC_2, *, internal, 1)," & -- PAD497.T "1736 (BC_2, *, internal, X)," & -- PAD497.O "1737 (BC_2, *, internal, X)," & -- PAD497.I "1738 (BC_2, *, internal, 1)," & -- PAD496.T "1739 (BC_2, *, internal, X)," & -- PAD496.O "1740 (BC_2, *, internal, X)," & -- PAD496.I "1741 (BC_2, *, internal, 1)," & -- PAD495.T "1742 (BC_2, *, internal, X)," & -- PAD495.O "1743 (BC_2, *, internal, X)," & -- PAD495.I "1744 (BC_2, *, internal, 1)," & -- PAD494.T "1745 (BC_2, *, internal, X)," & -- PAD494.O "1746 (BC_2, *, internal, X)," & -- PAD494.I "1747 (BC_2, *, internal, 1)," & -- PAD493.T "1748 (BC_2, *, internal, X)," & -- PAD493.O "1749 (BC_2, *, internal, X)," & -- PAD493.I "1750 (BC_2, *, internal, 1)," & -- PAD492.T "1751 (BC_2, *, internal, X)," & -- PAD492.O "1752 (BC_2, *, internal, X)," & -- PAD492.I "1753 (BC_2, *, internal, 1)," & -- PAD491.T "1754 (BC_2, *, internal, X)," & -- PAD491.O "1755 (BC_2, *, internal, X)," & -- PAD491.I "1756 (BC_2, *, internal, 1)," & -- PAD490.T "1757 (BC_2, *, internal, X)," & -- PAD490.O "1758 (BC_2, *, internal, X)," & -- PAD490.I "1759 (BC_2, *, internal, 1)," & -- PAD489.T "1760 (BC_2, *, internal, X)," & -- PAD489.O "1761 (BC_2, *, internal, X)," & -- PAD489.I "1762 (BC_2, *, internal, 1)," & -- PAD488.T "1763 (BC_2, *, internal, X)," & -- PAD488.O "1764 (BC_2, *, internal, X)," & -- PAD488.I "1765 (BC_2, *, internal, 1)," & -- PAD487.T "1766 (BC_2, *, internal, X)," & -- PAD487.O "1767 (BC_2, *, internal, X)," & -- PAD487.I "1768 (BC_2, *, internal, 1)," & -- PAD486.T "1769 (BC_2, *, internal, X)," & -- PAD486.O "1770 (BC_2, *, internal, X)," & -- PAD486.I "1771 (BC_2, *, internal, 1)," & -- PAD485.T "1772 (BC_2, *, internal, X)," & -- PAD485.O "1773 (BC_2, *, internal, X)," & -- PAD485.I "1774 (BC_2, *, internal, 1)," & -- PAD484.T "1775 (BC_2, *, internal, X)," & -- PAD484.O "1776 (BC_2, *, internal, X)," & -- PAD484.I "1777 (BC_2, *, internal, 1)," & -- PAD483.T "1778 (BC_2, *, internal, X)," & -- PAD483.O "1779 (BC_2, *, internal, X)," & -- PAD483.I "1780 (BC_2, *, internal, 1)," & -- PAD482.T "1781 (BC_2, *, internal, X)," & -- PAD482.O "1782 (BC_2, *, internal, X)," & -- PAD482.I "1783 (BC_2, *, internal, 1)," & -- PAD481.T "1784 (BC_2, *, internal, X)," & -- PAD481.O "1785 (BC_2, *, internal, X)," & -- PAD481.I "1786 (BC_2, *, internal, 1)," & -- PAD480.T "1787 (BC_2, *, internal, X)," & -- PAD480.O "1788 (BC_2, *, internal, X)," & -- PAD480.I "1789 (BC_2, *, internal, 1)," & -- PAD479.T "1790 (BC_2, *, internal, X)," & -- PAD479.O "1791 (BC_2, *, internal, X)," & -- PAD479.I "1792 (BC_2, *, internal, 1)," & -- PAD478.T "1793 (BC_2, *, internal, X)," & -- PAD478.O "1794 (BC_2, *, internal, X)," & -- PAD478.I "1795 (BC_2, *, internal, 1)," & -- PAD477.T "1796 (BC_2, *, internal, X)," & -- PAD477.O "1797 (BC_2, *, internal, X)," & -- PAD477.I "1798 (BC_2, *, internal, 1)," & -- PAD476.T "1799 (BC_2, *, internal, X)," & -- PAD476.O "1800 (BC_2, *, internal, X)," & -- PAD476.I "1801 (BC_2, *, internal, 1)," & -- PAD475.T "1802 (BC_2, *, internal, X)," & -- PAD475.O "1803 (BC_2, *, internal, X)," & -- PAD475.I "1804 (BC_2, *, internal, 1)," & -- PAD474.T "1805 (BC_2, *, internal, X)," & -- PAD474.O "1806 (BC_2, *, internal, X)," & -- PAD474.I "1807 (BC_2, *, internal, 1)," & -- PAD473.T "1808 (BC_2, *, internal, X)," & -- PAD473.O "1809 (BC_2, *, internal, X)," & -- PAD473.I "1810 (BC_2, *, internal, 1)," & -- PAD472.T "1811 (BC_2, *, internal, X)," & -- PAD472.O "1812 (BC_2, *, internal, X)," & -- PAD472.I "1813 (BC_2, *, internal, 1)," & -- PAD471.T "1814 (BC_2, *, internal, X)," & -- PAD471.O "1815 (BC_2, *, internal, X)," & -- PAD471.I "1816 (BC_2, *, internal, 1)," & -- PAD470.T "1817 (BC_2, *, internal, X)," & -- PAD470.O "1818 (BC_2, *, internal, X)," & -- PAD470.I "1819 (BC_2, *, internal, 1)," & -- PAD469.T "1820 (BC_2, *, internal, X)," & -- PAD469.O "1821 (BC_2, *, internal, X)," & -- PAD469.I "1822 (BC_2, *, internal, 1)," & -- PAD468.T "1823 (BC_2, *, internal, X)," & -- PAD468.O "1824 (BC_2, *, internal, X)," & -- PAD468.I "1825 (BC_2, *, internal, 1)," & -- PAD467.T "1826 (BC_2, *, internal, X)," & -- PAD467.O "1827 (BC_2, *, internal, X)," & -- PAD467.I "1828 (BC_2, *, internal, 1)," & -- PAD466.T "1829 (BC_2, *, internal, X)," & -- PAD466.O "1830 (BC_2, *, internal, X)," & -- PAD466.I "1831 (BC_2, *, internal, 1)," & -- PAD465.T "1832 (BC_2, *, internal, X)," & -- PAD465.O "1833 (BC_2, *, internal, X)," & -- PAD465.I "1834 (BC_2, *, internal, 1)," & -- PAD464.T "1835 (BC_2, *, internal, X)," & -- PAD464.O "1836 (BC_2, *, internal, X)," & -- PAD464.I "1837 (BC_2, *, internal, 1)," & -- PAD463.T "1838 (BC_2, *, internal, X)," & -- PAD463.O "1839 (BC_2, *, internal, X)," & -- PAD463.I "1840 (BC_2, *, internal, 1)," & -- PAD462.T "1841 (BC_2, *, internal, X)," & -- PAD462.O "1842 (BC_2, *, internal, X)," & -- PAD462.I "1843 (BC_2, *, internal, 1)," & -- PAD461.T "1844 (BC_2, *, internal, X)," & -- PAD461.O "1845 (BC_2, *, internal, X)," & -- PAD461.I "1846 (BC_2, *, internal, 1)," & -- PAD460.T "1847 (BC_2, *, internal, X)," & -- PAD460.O "1848 (BC_2, *, internal, X)," & -- PAD460.I "1849 (BC_2, *, internal, 1)," & -- PAD459.T "1850 (BC_2, *, internal, X)," & -- PAD459.O "1851 (BC_2, *, internal, X)," & -- PAD459.I "1852 (BC_2, *, internal, 1)," & -- PAD458.T "1853 (BC_2, *, internal, X)," & -- PAD458.O "1854 (BC_2, *, internal, X)," & -- PAD458.I "1855 (BC_2, *, internal, 1)," & -- PAD457.T "1856 (BC_2, *, internal, X)," & -- PAD457.O "1857 (BC_2, *, internal, X)," & -- PAD457.I "1858 (BC_2, *, internal, 1)," & -- PAD456.T "1859 (BC_2, *, internal, X)," & -- PAD456.O "1860 (BC_2, *, internal, X)," & -- PAD456.I "1861 (BC_2, *, internal, 1)," & -- PAD455.T "1862 (BC_2, *, internal, X)," & -- PAD455.O "1863 (BC_2, *, internal, X)," & -- PAD455.I "1864 (BC_2, *, internal, 1)," & -- PAD454.T "1865 (BC_2, *, internal, X)," & -- PAD454.O "1866 (BC_2, *, internal, X)," & -- PAD454.I "1867 (BC_2, *, internal, 1)," & -- PAD453.T "1868 (BC_2, *, internal, X)," & -- PAD453.O "1869 (BC_2, *, internal, X)," & -- PAD453.I "1870 (BC_2, *, internal, 1)," & -- PAD452.T "1871 (BC_2, *, internal, X)," & -- PAD452.O "1872 (BC_2, *, internal, X)," & -- PAD452.I "1873 (BC_2, *, internal, 1)," & -- PAD451.T "1874 (BC_2, *, internal, X)," & -- PAD451.O "1875 (BC_2, *, internal, X)," & -- PAD451.I "1876 (BC_2, *, internal, 1)," & -- PAD450.T "1877 (BC_2, *, internal, X)," & -- PAD450.O "1878 (BC_2, *, internal, X)," & -- PAD450.I "1879 (BC_2, *, internal, 1)," & -- PAD449.T "1880 (BC_2, *, internal, X)," & -- PAD449.O "1881 (BC_2, *, internal, X)," & -- PAD449.I "1882 (BC_2, *, internal, 1)," & -- PAD448.T "1883 (BC_2, *, internal, X)," & -- PAD448.O "1884 (BC_2, *, internal, X)," & -- PAD448.I "1885 (BC_2, *, internal, 1)," & -- PAD447.T "1886 (BC_2, *, internal, X)," & -- PAD447.O "1887 (BC_2, *, internal, X)," & -- PAD447.I "1888 (BC_2, *, internal, 1)," & -- PAD446.T "1889 (BC_2, *, internal, X)," & -- PAD446.O "1890 (BC_2, *, internal, X)," & -- PAD446.I "1891 (BC_2, *, internal, 1)," & -- PAD445.T "1892 (BC_2, *, internal, X)," & -- PAD445.O "1893 (BC_2, *, internal, X)," & -- PAD445.I "1894 (BC_2, *, internal, 1)," & -- PAD444.T "1895 (BC_2, *, internal, X)," & -- PAD444.O "1896 (BC_2, *, internal, X)," & -- PAD444.I "1897 (BC_2, *, internal, 1)," & -- PAD443.T "1898 (BC_2, *, internal, X)," & -- PAD443.O "1899 (BC_2, *, internal, X)," & -- PAD443.I "1900 (BC_2, *, internal, 1)," & -- PAD442.T "1901 (BC_2, *, internal, X)," & -- PAD442.O "1902 (BC_2, *, internal, X)," & -- PAD442.I "1903 (BC_2, *, internal, 1)," & -- PAD441.T "1904 (BC_2, *, internal, X)," & -- PAD441.O "1905 (BC_2, *, internal, X)," & -- PAD441.I "1906 (BC_2, *, internal, 1)," & -- PAD440.T "1907 (BC_2, *, internal, X)," & -- PAD440.O "1908 (BC_2, *, internal, X)," & -- PAD440.I "1909 (BC_2, *, internal, 1)," & -- PAD439.T "1910 (BC_2, *, internal, X)," & -- PAD439.O "1911 (BC_2, *, internal, X)," & -- PAD439.I "1912 (BC_2, *, internal, 1)," & -- PAD438.T "1913 (BC_2, *, internal, X)," & -- PAD438.O "1914 (BC_2, *, internal, X)," & -- PAD438.I "1915 (BC_2, *, internal, 1)," & -- PAD437.T "1916 (BC_2, *, internal, X)," & -- PAD437.O "1917 (BC_2, *, internal, X)," & -- PAD437.I "1918 (BC_2, *, internal, 1)," & -- PAD436.T "1919 (BC_2, *, internal, X)," & -- PAD436.O "1920 (BC_2, *, internal, X)," & -- PAD436.I "1921 (BC_2, *, internal, 1)," & -- PAD435.T "1922 (BC_2, *, internal, X)," & -- PAD435.O "1923 (BC_2, *, internal, X)," & -- PAD435.I "1924 (BC_2, *, internal, 1)," & -- PAD434.T "1925 (BC_2, *, internal, X)," & -- PAD434.O "1926 (BC_2, *, internal, X)," & -- PAD434.I "1927 (BC_2, *, internal, 1)," & -- PAD433.T "1928 (BC_2, *, internal, X)," & -- PAD433.O "1929 (BC_2, *, internal, X)," & -- PAD433.I "1930 (BC_2, *, internal, 1)," & -- PAD432.T "1931 (BC_2, *, internal, X)," & -- PAD432.O "1932 (BC_2, *, internal, X)," & -- PAD432.I "1933 (BC_2, *, internal, 1)," & -- PAD431.T "1934 (BC_2, *, internal, X)," & -- PAD431.O "1935 (BC_2, *, internal, X)," & -- PAD431.I "1936 (BC_2, *, internal, 1)," & -- PAD430.T "1937 (BC_2, *, internal, X)," & -- PAD430.O "1938 (BC_2, *, internal, X)," & -- PAD430.I "1939 (BC_2, *, internal, 1)," & -- PAD429.T "1940 (BC_2, *, internal, X)," & -- PAD429.O "1941 (BC_2, *, internal, X)," & -- PAD429.I "1942 (BC_2, *, internal, 1)," & -- PAD428.T "1943 (BC_2, *, internal, X)," & -- PAD428.O "1944 (BC_2, *, internal, X)," & -- PAD428.I "1945 (BC_2, *, internal, 1)," & -- PAD427.T "1946 (BC_2, *, internal, X)," & -- PAD427.O "1947 (BC_2, *, internal, X)," & -- PAD427.I "1948 (BC_2, *, internal, 1)," & -- PAD426.T "1949 (BC_2, *, internal, X)," & -- PAD426.O "1950 (BC_2, *, internal, X)," & -- PAD426.I "1951 (BC_2, *, internal, 1)," & -- PAD425.T "1952 (BC_2, *, internal, X)," & -- PAD425.O "1953 (BC_2, *, internal, X)," & -- PAD425.I "1954 (BC_2, *, internal, 1)," & -- PAD424.T "1955 (BC_2, *, internal, X)," & -- PAD424.O "1956 (BC_2, *, internal, X)," & -- PAD424.I "1957 (BC_2, *, internal, 1)," & -- PAD423.T "1958 (BC_2, *, internal, X)," & -- PAD423.O "1959 (BC_2, *, internal, X)," & -- PAD423.I "1960 (BC_2, *, internal, 1)," & -- PAD422.T "1961 (BC_2, *, internal, X)," & -- PAD422.O "1962 (BC_2, *, internal, X)," & -- PAD422.I "1963 (BC_2, *, internal, 1)," & -- PAD421.T "1964 (BC_2, *, internal, X)," & -- PAD421.O "1965 (BC_2, *, internal, X)," & -- PAD421.I "1966 (BC_2, *, internal, 1)," & -- PAD420.T "1967 (BC_2, *, internal, X)," & -- PAD420.O "1968 (BC_2, *, internal, X)," & -- PAD420.I "1969 (BC_2, *, internal, 1)," & -- PAD419.T "1970 (BC_2, *, internal, X)," & -- PAD419.O "1971 (BC_2, *, internal, X)," & -- PAD419.I "1972 (BC_2, *, internal, 1)," & -- PAD418.T "1973 (BC_2, *, internal, X)," & -- PAD418.O "1974 (BC_2, *, internal, X)," & -- PAD418.I "1975 (BC_2, *, internal, 1)," & -- PAD417.T "1976 (BC_2, *, internal, X)," & -- PAD417.O "1977 (BC_2, *, internal, X)," & -- PAD417.I "1978 (BC_2, *, internal, 1)," & -- PAD416.T "1979 (BC_2, *, internal, X)," & -- PAD416.O "1980 (BC_2, *, internal, X)," & -- PAD416.I "1981 (BC_2, *, internal, 1)," & -- PAD415.T "1982 (BC_2, *, internal, X)," & -- PAD415.O "1983 (BC_2, *, internal, X)," & -- PAD415.I "1984 (BC_2, *, internal, 1)," & -- PAD414.T "1985 (BC_2, *, internal, X)," & -- PAD414.O "1986 (BC_2, *, internal, X)," & -- PAD414.I "1987 (BC_2, *, internal, 1)," & -- PAD413.T "1988 (BC_2, *, internal, X)," & -- PAD413.O "1989 (BC_2, *, internal, X)," & -- PAD413.I "1990 (BC_2, *, internal, 1)," & -- PAD412.T "1991 (BC_2, *, internal, X)," & -- PAD412.O "1992 (BC_2, *, internal, X)," & -- PAD412.I "1993 (BC_2, *, internal, 1)," & -- PAD411.T "1994 (BC_2, *, internal, X)," & -- PAD411.O "1995 (BC_2, *, internal, X)," & -- PAD411.I "1996 (BC_2, *, internal, 1)," & -- PAD410.T "1997 (BC_2, *, internal, X)," & -- PAD410.O "1998 (BC_2, *, internal, X)," & -- PAD410.I "1999 (BC_2, *, internal, 1)," & -- PAD409.T "2000 (BC_2, *, internal, X)," & -- PAD409.O "2001 (BC_2, *, internal, X)," & -- PAD409.I "2002 (BC_2, *, internal, 1)," & -- PAD408.T "2003 (BC_2, *, internal, X)," & -- PAD408.O "2004 (BC_2, *, internal, X)," & -- PAD408.I "2005 (BC_2, *, internal, 1)," & -- PAD407.T "2006 (BC_2, *, internal, X)," & -- PAD407.O "2007 (BC_2, *, internal, X)," & -- PAD407.I "2008 (BC_2, *, internal, 1)," & -- PAD406.T "2009 (BC_2, *, internal, X)," & -- PAD406.O "2010 (BC_2, *, internal, X)," & -- PAD406.I "2011 (BC_2, *, internal, 1)," & -- PAD405.T "2012 (BC_2, *, internal, X)," & -- PAD405.O "2013 (BC_2, *, internal, X)," & -- PAD405.I "2014 (BC_2, *, internal, 1)," & -- PAD404.T "2015 (BC_2, *, internal, X)," & -- PAD404.O "2016 (BC_2, *, internal, X)," & -- PAD404.I "2017 (BC_2, *, internal, 1)," & -- PAD403.T "2018 (BC_2, *, internal, X)," & -- PAD403.O "2019 (BC_2, *, internal, X)," & -- PAD403.I "2020 (BC_2, *, internal, 1)," & -- PAD402.T "2021 (BC_2, *, internal, X)," & -- PAD402.O "2022 (BC_2, *, internal, X)," & -- PAD402.I "2023 (BC_2, *, internal, 1)," & -- PAD401.T "2024 (BC_2, *, internal, X)," & -- PAD401.O "2025 (BC_2, *, internal, X)," & -- PAD401.I "2026 (BC_2, *, controlr, 1)," & "2027 (BC_2, IO_AP26, output3, X, 2026, 1, Z)," & -- PAD400 "2028 (BC_2, IO_AP26, input, X)," & -- PAD400 "2029 (BC_2, *, controlr, 1)," & "2030 (BC_2, IO_AJ26, output3, X, 2029, 1, Z)," & -- PAD399 "2031 (BC_2, IO_AJ26, input, X)," & -- PAD399 "2032 (BC_2, *, controlr, 1)," & "2033 (BC_2, IO_AJ25, output3, X, 2032, 1, Z)," & -- PAD398 "2034 (BC_2, IO_AJ25, input, X)," & -- PAD398 "2035 (BC_2, *, controlr, 1)," & "2036 (BC_2, IO_AL26, output3, X, 2035, 1, Z)," & -- PAD397 "2037 (BC_2, IO_AL26, input, X)," & -- PAD397 "2038 (BC_2, *, controlr, 1)," & "2039 (BC_2, IO_AL25, output3, X, 2038, 1, Z)," & -- PAD396 "2040 (BC_2, IO_AL25, input, X)," & -- PAD396 "2041 (BC_2, *, controlr, 1)," & "2042 (BC_2, IO_AK25, output3, X, 2041, 1, Z)," & -- PAD395 "2043 (BC_2, IO_AK25, input, X)," & -- PAD395 "2044 (BC_2, *, controlr, 1)," & "2045 (BC_2, IO_AK24, output3, X, 2044, 1, Z)," & -- PAD394 "2046 (BC_2, IO_AK24, input, X)," & -- PAD394 "2047 (BC_2, *, controlr, 1)," & "2048 (BC_2, IO_AM27, output3, X, 2047, 1, Z)," & -- PAD393 "2049 (BC_2, IO_AM27, input, X)," & -- PAD393 "2050 (BC_2, *, controlr, 1)," & "2051 (BC_2, IO_AM26, output3, X, 2050, 1, Z)," & -- PAD392 "2052 (BC_2, IO_AM26, input, X)," & -- PAD392 "2053 (BC_2, *, controlr, 1)," & "2054 (BC_2, IO_AL27, output3, X, 2053, 1, Z)," & -- PAD391 "2055 (BC_2, IO_AL27, input, X)," & -- PAD391 "2056 (BC_2, *, controlr, 1)," & "2057 (BC_2, IO_AK27, output3, X, 2056, 1, Z)," & -- PAD390 "2058 (BC_2, IO_AK27, input, X)," & -- PAD390 "2059 (BC_2, *, controlr, 1)," & "2060 (BC_2, IO_AM29, output3, X, 2059, 1, Z)," & -- PAD389 "2061 (BC_2, IO_AM29, input, X)," & -- PAD389 "2062 (BC_2, *, controlr, 1)," & "2063 (BC_2, IO_AM28, output3, X, 2062, 1, Z)," & -- PAD388 "2064 (BC_2, IO_AM28, input, X)," & -- PAD388 "2065 (BC_2, *, controlr, 1)," & "2066 (BC_2, IO_AN26, output3, X, 2065, 1, Z)," & -- PAD387 "2067 (BC_2, IO_AN26, input, X)," & -- PAD387 "2068 (BC_2, *, controlr, 1)," & "2069 (BC_2, IO_AN25, output3, X, 2068, 1, Z)," & -- PAD386 "2070 (BC_2, IO_AN25, input, X)," & -- PAD386 "2071 (BC_2, *, controlr, 1)," & "2072 (BC_2, IO_AR25, output3, X, 2071, 1, Z)," & -- PAD385 "2073 (BC_2, IO_AR25, input, X)," & -- PAD385 "2074 (BC_2, *, controlr, 1)," & "2075 (BC_2, IO_AP25, output3, X, 2074, 1, Z)," & -- PAD384 "2076 (BC_2, IO_AP25, input, X)," & -- PAD384 "2077 (BC_2, *, controlr, 1)," & "2078 (BC_2, IO_AT26, output3, X, 2077, 1, Z)," & -- PAD383 "2079 (BC_2, IO_AT26, input, X)," & -- PAD383 "2080 (BC_2, *, controlr, 1)," & "2081 (BC_2, IO_AT25, output3, X, 2080, 1, Z)," & -- PAD382 "2082 (BC_2, IO_AT25, input, X)," & -- PAD382 "2083 (BC_2, *, controlr, 1)," & "2084 (BC_2, IO_AP28, output3, X, 2083, 1, Z)," & -- PAD381 "2085 (BC_2, IO_AP28, input, X)," & -- PAD381 "2086 (BC_2, *, controlr, 1)," & "2087 (BC_2, IO_AN28, output3, X, 2086, 1, Z)," & -- PAD380 "2088 (BC_2, IO_AN28, input, X)," & -- PAD380 "2089 (BC_2, *, controlr, 1)," & "2090 (BC_2, IO_AR28, output3, X, 2089, 1, Z)," & -- PAD379 "2091 (BC_2, IO_AR28, input, X)," & -- PAD379 "2092 (BC_2, *, controlr, 1)," & "2093 (BC_2, IO_AP27, output3, X, 2092, 1, Z)," & -- PAD378 "2094 (BC_2, IO_AP27, input, X)," & -- PAD378 "2095 (BC_2, *, controlr, 1)," & "2096 (BC_2, IO_AT27, output3, X, 2095, 1, Z)," & -- PAD377 "2097 (BC_2, IO_AT27, input, X)," & -- PAD377 "2098 (BC_2, *, controlr, 1)," & "2099 (BC_2, IO_AR27, output3, X, 2098, 1, Z)," & -- PAD376 "2100 (BC_2, IO_AR27, input, X)," & -- PAD376 "2101 (BC_2, *, controlr, 1)," & "2102 (BC_2, IO_AU27, output3, X, 2101, 1, Z)," & -- PAD375 "2103 (BC_2, IO_AU27, input, X)," & -- PAD375 "2104 (BC_2, *, controlr, 1)," & "2105 (BC_2, IO_AU26, output3, X, 2104, 1, Z)," & -- PAD374 "2106 (BC_2, IO_AU26, input, X)," & -- PAD374 "2107 (BC_2, *, controlr, 1)," & "2108 (BC_2, IO_AV28, output3, X, 2107, 1, Z)," & -- PAD373 "2109 (BC_2, IO_AV28, input, X)," & -- PAD373 "2110 (BC_2, *, controlr, 1)," & "2111 (BC_2, IO_AU28, output3, X, 2110, 1, Z)," & -- PAD372 "2112 (BC_2, IO_AU28, input, X)," & -- PAD372 "2113 (BC_2, *, controlr, 1)," & "2114 (BC_2, IO_AW28, output3, X, 2113, 1, Z)," & -- PAD371 "2115 (BC_2, IO_AW28, input, X)," & -- PAD371 "2116 (BC_2, *, controlr, 1)," & "2117 (BC_2, IO_AW27, output3, X, 2116, 1, Z)," & -- PAD370 "2118 (BC_2, IO_AW27, input, X)," & -- PAD370 "2119 (BC_2, *, controlr, 1)," & "2120 (BC_2, IO_AV26, output3, X, 2119, 1, Z)," & -- PAD369 "2121 (BC_2, IO_AV26, input, X)," & -- PAD369 "2122 (BC_2, *, controlr, 1)," & "2123 (BC_2, IO_AV25, output3, X, 2122, 1, Z)," & -- PAD368 "2124 (BC_2, IO_AV25, input, X)," & -- PAD368 "2125 (BC_2, *, controlr, 1)," & "2126 (BC_2, IO_AT29, output3, X, 2125, 1, Z)," & -- PAD367 "2127 (BC_2, IO_AT29, input, X)," & -- PAD367 "2128 (BC_2, *, controlr, 1)," & "2129 (BC_2, IO_AR29, output3, X, 2128, 1, Z)," & -- PAD366 "2130 (BC_2, IO_AR29, input, X)," & -- PAD366 "2131 (BC_2, *, controlr, 1)," & "2132 (BC_2, IO_AW26, output3, X, 2131, 1, Z)," & -- PAD365 "2133 (BC_2, IO_AW26, input, X)," & -- PAD365 "2134 (BC_2, *, controlr, 1)," & "2135 (BC_2, IO_AW25, output3, X, 2134, 1, Z)," & -- PAD364 "2136 (BC_2, IO_AW25, input, X)," & -- PAD364 "2137 (BC_2, *, controlr, 1)," & "2138 (BC_2, IO_BA29, output3, X, 2137, 1, Z)," & -- PAD363 "2139 (BC_2, IO_BA29, input, X)," & -- PAD363 "2140 (BC_2, *, controlr, 1)," & "2141 (BC_2, IO_AY29, output3, X, 2140, 1, Z)," & -- PAD362 "2142 (BC_2, IO_AY29, input, X)," & -- PAD362 "2143 (BC_2, *, controlr, 1)," & "2144 (BC_2, IO_BB27, output3, X, 2143, 1, Z)," & -- PAD361 "2145 (BC_2, IO_BB27, input, X)," & -- PAD361 "2146 (BC_2, *, controlr, 1)," & "2147 (BC_2, IO_BB26, output3, X, 2146, 1, Z)," & -- PAD360 "2148 (BC_2, IO_BB26, input, X)," & -- PAD360 "2149 (BC_2, *, controlr, 1)," & "2150 (BC_2, IO_BB29, output3, X, 2149, 1, Z)," & -- PAD359 "2151 (BC_2, IO_BB29, input, X)," & -- PAD359 "2152 (BC_2, *, controlr, 1)," & "2153 (BC_2, IO_BB28, output3, X, 2152, 1, Z)," & -- PAD358 "2154 (BC_2, IO_BB28, input, X)," & -- PAD358 "2155 (BC_2, *, controlr, 1)," & "2156 (BC_2, IO_BA27, output3, X, 2155, 1, Z)," & -- PAD357 "2157 (BC_2, IO_BA27, input, X)," & -- PAD357 "2158 (BC_2, *, controlr, 1)," & "2159 (BC_2, IO_BA26, output3, X, 2158, 1, Z)," & -- PAD356 "2160 (BC_2, IO_BA26, input, X)," & -- PAD356 "2161 (BC_2, *, controlr, 1)," & "2162 (BC_2, IO_AV29, output3, X, 2161, 1, Z)," & -- PAD355 "2163 (BC_2, IO_AV29, input, X)," & -- PAD355 "2164 (BC_2, *, controlr, 1)," & "2165 (BC_2, IO_AU29, output3, X, 2164, 1, Z)," & -- PAD354 "2166 (BC_2, IO_AU29, input, X)," & -- PAD354 "2167 (BC_2, *, controlr, 1)," & "2168 (BC_2, IO_AY28, output3, X, 2167, 1, Z)," & -- PAD353 "2169 (BC_2, IO_AY28, input, X)," & -- PAD353 "2170 (BC_2, *, controlr, 1)," & "2171 (BC_2, IO_AY27, output3, X, 2170, 1, Z)," & -- PAD352 "2172 (BC_2, IO_AY27, input, X)," & -- PAD352 "2173 (BC_2, *, controlr, 1)," & "2174 (BC_2, IO_AN29, output3, X, 2173, 1, Z)," & -- PAD351 "2175 (BC_2, IO_AN29, input, X)," & -- PAD351 "2176 (BC_2, *, controlr, 1)," & "2177 (BC_2, IO_AT31, output3, X, 2176, 1, Z)," & -- PAD350 "2178 (BC_2, IO_AT31, input, X)," & -- PAD350 "2179 (BC_2, *, controlr, 1)," & "2180 (BC_2, IO_AR33, output3, X, 2179, 1, Z)," & -- PAD349 "2181 (BC_2, IO_AR33, input, X)," & -- PAD349 "2182 (BC_2, *, controlr, 1)," & "2183 (BC_2, IO_AP33, output3, X, 2182, 1, Z)," & -- PAD348 "2184 (BC_2, IO_AP33, input, X)," & -- PAD348 "2185 (BC_2, *, controlr, 1)," & "2186 (BC_2, IO_AP31, output3, X, 2185, 1, Z)," & -- PAD347 "2187 (BC_2, IO_AP31, input, X)," & -- PAD347 "2188 (BC_2, *, controlr, 1)," & "2189 (BC_2, IO_AN31, output3, X, 2188, 1, Z)," & -- PAD346 "2190 (BC_2, IO_AN31, input, X)," & -- PAD346 "2191 (BC_2, *, controlr, 1)," & "2192 (BC_2, IO_AR32, output3, X, 2191, 1, Z)," & -- PAD345 "2193 (BC_2, IO_AR32, input, X)," & -- PAD345 "2194 (BC_2, *, controlr, 1)," & "2195 (BC_2, IO_AP32, output3, X, 2194, 1, Z)," & -- PAD344 "2196 (BC_2, IO_AP32, input, X)," & -- PAD344 "2197 (BC_2, *, controlr, 1)," & "2198 (BC_2, IO_AP30, output3, X, 2197, 1, Z)," & -- PAD343 "2199 (BC_2, IO_AP30, input, X)," & -- PAD343 "2200 (BC_2, *, controlr, 1)," & "2201 (BC_2, IO_AN30, output3, X, 2200, 1, Z)," & -- PAD342 "2202 (BC_2, IO_AN30, input, X)," & -- PAD342 "2203 (BC_2, *, controlr, 1)," & "2204 (BC_2, IO_AV31, output3, X, 2203, 1, Z)," & -- PAD341 "2205 (BC_2, IO_AV31, input, X)," & -- PAD341 "2206 (BC_2, *, controlr, 1)," & "2207 (BC_2, IO_AU31, output3, X, 2206, 1, Z)," & -- PAD340 "2208 (BC_2, IO_AU31, input, X)," & -- PAD340 "2209 (BC_2, *, controlr, 1)," & "2210 (BC_2, IO_AT30, output3, X, 2209, 1, Z)," & -- PAD339 "2211 (BC_2, IO_AT30, input, X)," & -- PAD339 "2212 (BC_2, *, controlr, 1)," & "2213 (BC_2, IO_AR30, output3, X, 2212, 1, Z)," & -- PAD338 "2214 (BC_2, IO_AR30, input, X)," & -- PAD338 "2215 (BC_2, *, controlr, 1)," & "2216 (BC_2, IO_AW31, output3, X, 2215, 1, Z)," & -- PAD337 "2217 (BC_2, IO_AW31, input, X)," & -- PAD337 "2218 (BC_2, *, controlr, 1)," & "2219 (BC_2, IO_AV30, output3, X, 2218, 1, Z)," & -- PAD336 "2220 (BC_2, IO_AV30, input, X)," & -- PAD336 "2221 (BC_2, *, controlr, 1)," & "2222 (BC_2, IO_BB31, output3, X, 2221, 1, Z)," & -- PAD335 "2223 (BC_2, IO_BB31, input, X)," & -- PAD335 "2224 (BC_2, *, controlr, 1)," & "2225 (BC_2, IO_BA30, output3, X, 2224, 1, Z)," & -- PAD334 "2226 (BC_2, IO_BA30, input, X)," & -- PAD334 "2227 (BC_2, *, controlr, 1)," & "2228 (BC_2, IO_AY30, output3, X, 2227, 1, Z)," & -- PAD333 "2229 (BC_2, IO_AY30, input, X)," & -- PAD333 "2230 (BC_2, *, controlr, 1)," & "2231 (BC_2, IO_AW30, output3, X, 2230, 1, Z)," & -- PAD332 "2232 (BC_2, IO_AW30, input, X)," & -- PAD332 "2233 (BC_2, *, controlr, 1)," & "2234 (BC_2, IO_BA32, output3, X, 2233, 1, Z)," & -- PAD331 "2235 (BC_2, IO_BA32, input, X)," & -- PAD331 "2236 (BC_2, *, controlr, 1)," & "2237 (BC_2, IO_BA31, output3, X, 2236, 1, Z)," & -- PAD330 "2238 (BC_2, IO_BA31, input, X)," & -- PAD330 "2239 (BC_2, *, controlr, 1)," & "2240 (BC_2, IO_AY33, output3, X, 2239, 1, Z)," & -- PAD329 "2241 (BC_2, IO_AY33, input, X)," & -- PAD329 "2242 (BC_2, *, controlr, 1)," & "2243 (BC_2, IO_AY32, output3, X, 2242, 1, Z)," & -- PAD328 "2244 (BC_2, IO_AY32, input, X)," & -- PAD328 "2245 (BC_2, *, controlr, 1)," & "2246 (BC_2, IO_AV35, output3, X, 2245, 1, Z)," & -- PAD327 "2247 (BC_2, IO_AV35, input, X)," & -- PAD327 "2248 (BC_2, *, controlr, 1)," & "2249 (BC_2, IO_AV34, output3, X, 2248, 1, Z)," & -- PAD326 "2250 (BC_2, IO_AV34, input, X)," & -- PAD326 "2251 (BC_2, *, controlr, 1)," & "2252 (BC_2, IO_AW33, output3, X, 2251, 1, Z)," & -- PAD325 "2253 (BC_2, IO_AW33, input, X)," & -- PAD325 "2254 (BC_2, *, controlr, 1)," & "2255 (BC_2, IO_AW32, output3, X, 2254, 1, Z)," & -- PAD324 "2256 (BC_2, IO_AW32, input, X)," & -- PAD324 "2257 (BC_2, *, controlr, 1)," & "2258 (BC_2, IO_AV33, output3, X, 2257, 1, Z)," & -- PAD323 "2259 (BC_2, IO_AV33, input, X)," & -- PAD323 "2260 (BC_2, *, controlr, 1)," & "2261 (BC_2, IO_AU32, output3, X, 2260, 1, Z)," & -- PAD322 "2262 (BC_2, IO_AU32, input, X)," & -- PAD322 "2263 (BC_2, *, controlr, 1)," & "2264 (BC_2, IO_AT35, output3, X, 2263, 1, Z)," & -- PAD321 "2265 (BC_2, IO_AT35, input, X)," & -- PAD321 "2266 (BC_2, *, controlr, 1)," & "2267 (BC_2, IO_AR34, output3, X, 2266, 1, Z)," & -- PAD320 "2268 (BC_2, IO_AR34, input, X)," & -- PAD320 "2269 (BC_2, *, controlr, 1)," & "2270 (BC_2, IO_AU33, output3, X, 2269, 1, Z)," & -- PAD319 "2271 (BC_2, IO_AU33, input, X)," & -- PAD319 "2272 (BC_2, *, controlr, 1)," & "2273 (BC_2, IO_AT32, output3, X, 2272, 1, Z)," & -- PAD318 "2274 (BC_2, IO_AT32, input, X)," & -- PAD318 "2275 (BC_2, *, controlr, 1)," & "2276 (BC_2, IO_AU36, output3, X, 2275, 1, Z)," & -- PAD317 "2277 (BC_2, IO_AU36, input, X)," & -- PAD317 "2278 (BC_2, *, controlr, 1)," & "2279 (BC_2, IO_AT36, output3, X, 2278, 1, Z)," & -- PAD316 "2280 (BC_2, IO_AT36, input, X)," & -- PAD316 "2281 (BC_2, *, controlr, 1)," & "2282 (BC_2, IO_AU34, output3, X, 2281, 1, Z)," & -- PAD315 "2283 (BC_2, IO_AU34, input, X)," & -- PAD315 "2284 (BC_2, *, controlr, 1)," & "2285 (BC_2, IO_AT34, output3, X, 2284, 1, Z)," & -- PAD314 "2286 (BC_2, IO_AT34, input, X)," & -- PAD314 "2287 (BC_2, *, controlr, 1)," & "2288 (BC_2, IO_AY35, output3, X, 2287, 1, Z)," & -- PAD313 "2289 (BC_2, IO_AY35, input, X)," & -- PAD313 "2290 (BC_2, *, controlr, 1)," & "2291 (BC_2, IO_AW35, output3, X, 2290, 1, Z)," & -- PAD312 "2292 (BC_2, IO_AW35, input, X)," & -- PAD312 "2293 (BC_2, *, controlr, 1)," & "2294 (BC_2, IO_BB33, output3, X, 2293, 1, Z)," & -- PAD311 "2295 (BC_2, IO_BB33, input, X)," & -- PAD311 "2296 (BC_2, *, controlr, 1)," & "2297 (BC_2, IO_BB32, output3, X, 2296, 1, Z)," & -- PAD310 "2298 (BC_2, IO_BB32, input, X)," & -- PAD310 "2299 (BC_2, *, controlr, 1)," & "2300 (BC_2, IO_BB36, output3, X, 2299, 1, Z)," & -- PAD309 "2301 (BC_2, IO_BB36, input, X)," & -- PAD309 "2302 (BC_2, *, controlr, 1)," & "2303 (BC_2, IO_BA36, output3, X, 2302, 1, Z)," & -- PAD308 "2304 (BC_2, IO_BA36, input, X)," & -- PAD308 "2305 (BC_2, *, controlr, 1)," & "2306 (BC_2, IO_BB34, output3, X, 2305, 1, Z)," & -- PAD307 "2307 (BC_2, IO_BB34, input, X)," & -- PAD307 "2308 (BC_2, *, controlr, 1)," & "2309 (BC_2, IO_BA34, output3, X, 2308, 1, Z)," & -- PAD306 "2310 (BC_2, IO_BA34, input, X)," & -- PAD306 "2311 (BC_2, *, controlr, 1)," & "2312 (BC_2, IO_AW36, output3, X, 2311, 1, Z)," & -- PAD305 "2313 (BC_2, IO_AW36, input, X)," & -- PAD305 "2314 (BC_2, *, controlr, 1)," & "2315 (BC_2, IO_AV36, output3, X, 2314, 1, Z)," & -- PAD304 "2316 (BC_2, IO_AV36, input, X)," & -- PAD304 "2317 (BC_2, *, controlr, 1)," & "2318 (BC_2, IO_BA35, output3, X, 2317, 1, Z)," & -- PAD303 "2319 (BC_2, IO_BA35, input, X)," & -- PAD303 "2320 (BC_2, *, controlr, 1)," & "2321 (BC_2, IO_AY34, output3, X, 2320, 1, Z)," & -- PAD302 "2322 (BC_2, IO_AY34, input, X)," & -- PAD302 "2323 (BC_2, *, controlr, 1)," & "2324 (BC_2, IO_AR35, output3, X, 2323, 1, Z)," & -- PAD301 "2325 (BC_2, IO_AR35, input, X)," & -- PAD301 "2326 (BC_2, *, controlr, 1)," & "2327 (BC_2, IO_AG32, output3, X, 2326, 1, Z)," & -- PAD300 "2328 (BC_2, IO_AG32, input, X)," & -- PAD300 "2329 (BC_2, *, controlr, 1)," & "2330 (BC_2, IO_AJ28, output3, X, 2329, 1, Z)," & -- PAD299 "2331 (BC_2, IO_AJ28, input, X)," & -- PAD299 "2332 (BC_2, *, controlr, 1)," & "2333 (BC_2, IO_AH28, output3, X, 2332, 1, Z)," & -- PAD298 "2334 (BC_2, IO_AH28, input, X)," & -- PAD298 "2335 (BC_2, *, controlr, 1)," & "2336 (BC_2, IO_AG31, output3, X, 2335, 1, Z)," & -- PAD297 "2337 (BC_2, IO_AG31, input, X)," & -- PAD297 "2338 (BC_2, *, controlr, 1)," & "2339 (BC_2, IO_AF30, output3, X, 2338, 1, Z)," & -- PAD296 "2340 (BC_2, IO_AF30, input, X)," & -- PAD296 "2341 (BC_2, *, controlr, 1)," & "2342 (BC_2, IO_AK29, output3, X, 2341, 1, Z)," & -- PAD295 "2343 (BC_2, IO_AK29, input, X)," & -- PAD295 "2344 (BC_2, *, controlr, 1)," & "2345 (BC_2, IO_AK28, output3, X, 2344, 1, Z)," & -- PAD294 "2346 (BC_2, IO_AK28, input, X)," & -- PAD294 "2347 (BC_2, *, controlr, 1)," & "2348 (BC_2, IO_AG29, output3, X, 2347, 1, Z)," & -- PAD293 "2349 (BC_2, IO_AG29, input, X)," & -- PAD293 "2350 (BC_2, *, controlr, 1)," & "2351 (BC_2, IO_AF29, output3, X, 2350, 1, Z)," & -- PAD292 "2352 (BC_2, IO_AF29, input, X)," & -- PAD292 "2353 (BC_2, *, controlr, 1)," & "2354 (BC_2, IO_AK30, output3, X, 2353, 1, Z)," & -- PAD291 "2355 (BC_2, IO_AK30, input, X)," & -- PAD291 "2356 (BC_2, *, controlr, 1)," & "2357 (BC_2, IO_AJ30, output3, X, 2356, 1, Z)," & -- PAD290 "2358 (BC_2, IO_AJ30, input, X)," & -- PAD290 "2359 (BC_2, *, controlr, 1)," & "2360 (BC_2, IO_AH30, output3, X, 2359, 1, Z)," & -- PAD289 "2361 (BC_2, IO_AH30, input, X)," & -- PAD289 "2362 (BC_2, *, controlr, 1)," & "2363 (BC_2, IO_AH29, output3, X, 2362, 1, Z)," & -- PAD288 "2364 (BC_2, IO_AH29, input, X)," & -- PAD288 "2365 (BC_2, *, controlr, 1)," & "2366 (BC_2, IO_AL30, output3, X, 2365, 1, Z)," & -- PAD287 "2367 (BC_2, IO_AL30, input, X)," & -- PAD287 "2368 (BC_2, *, controlr, 1)," & "2369 (BC_2, IO_AL29, output3, X, 2368, 1, Z)," & -- PAD286 "2370 (BC_2, IO_AL29, input, X)," & -- PAD286 "2371 (BC_2, *, controlr, 1)," & "2372 (BC_2, IO_AN33, output3, X, 2371, 1, Z)," & -- PAD285 "2373 (BC_2, IO_AN33, input, X)," & -- PAD285 "2374 (BC_2, *, controlr, 1)," & "2375 (BC_2, IO_AM33, output3, X, 2374, 1, Z)," & -- PAD284 "2376 (BC_2, IO_AM33, input, X)," & -- PAD284 "2377 (BC_2, *, controlr, 1)," & "2378 (BC_2, IO_AM32, output3, X, 2377, 1, Z)," & -- PAD283 "2379 (BC_2, IO_AM32, input, X)," & -- PAD283 "2380 (BC_2, *, controlr, 1)," & "2381 (BC_2, IO_AM31, output3, X, 2380, 1, Z)," & -- PAD282 "2382 (BC_2, IO_AM31, input, X)," & -- PAD282 "2383 (BC_2, *, controlr, 1)," & "2384 (BC_2, IO_AN34, output3, X, 2383, 1, Z)," & -- PAD281 "2385 (BC_2, IO_AN34, input, X)," & -- PAD281 "2386 (BC_2, *, controlr, 1)," & "2387 (BC_2, IO_AM34, output3, X, 2386, 1, Z)," & -- PAD280 "2388 (BC_2, IO_AM34, input, X)," & -- PAD280 "2389 (BC_2, *, controlr, 1)," & "2390 (BC_2, IO_AL32, output3, X, 2389, 1, Z)," & -- PAD279 "2391 (BC_2, IO_AL32, input, X)," & -- PAD279 "2392 (BC_2, *, controlr, 1)," & "2393 (BC_2, IO_AL31, output3, X, 2392, 1, Z)," & -- PAD278 "2394 (BC_2, IO_AL31, input, X)," & -- PAD278 "2395 (BC_2, *, controlr, 1)," & "2396 (BC_2, IO_AK32, output3, X, 2395, 1, Z)," & -- PAD277 "2397 (BC_2, IO_AK32, input, X)," & -- PAD277 "2398 (BC_2, *, controlr, 1)," & "2399 (BC_2, IO_AJ32, output3, X, 2398, 1, Z)," & -- PAD276 "2400 (BC_2, IO_AJ32, input, X)," & -- PAD276 "2401 (BC_2, *, controlr, 1)," & "2402 (BC_2, IO_AL34, output3, X, 2401, 1, Z)," & -- PAD275 "2403 (BC_2, IO_AL34, input, X)," & -- PAD275 "2404 (BC_2, *, controlr, 1)," & "2405 (BC_2, IO_AK34, output3, X, 2404, 1, Z)," & -- PAD274 "2406 (BC_2, IO_AK34, input, X)," & -- PAD274 "2407 (BC_2, *, controlr, 1)," & "2408 (BC_2, IO_AK33, output3, X, 2407, 1, Z)," & -- PAD273 "2409 (BC_2, IO_AK33, input, X)," & -- PAD273 "2410 (BC_2, *, controlr, 1)," & "2411 (BC_2, IO_AJ33, output3, X, 2410, 1, Z)," & -- PAD272 "2412 (BC_2, IO_AJ33, input, X)," & -- PAD272 "2413 (BC_2, *, controlr, 1)," & "2414 (BC_2, IO_AJ35, output3, X, 2413, 1, Z)," & -- PAD271 "2415 (BC_2, IO_AJ35, input, X)," & -- PAD271 "2416 (BC_2, *, controlr, 1)," & "2417 (BC_2, IO_AH34, output3, X, 2416, 1, Z)," & -- PAD270 "2418 (BC_2, IO_AH34, input, X)," & -- PAD270 "2419 (BC_2, *, controlr, 1)," & "2420 (BC_2, IO_AJ31, output3, X, 2419, 1, Z)," & -- PAD269 "2421 (BC_2, IO_AJ31, input, X)," & -- PAD269 "2422 (BC_2, *, controlr, 1)," & "2423 (BC_2, IO_AH31, output3, X, 2422, 1, Z)," & -- PAD268 "2424 (BC_2, IO_AH31, input, X)," & -- PAD268 "2425 (BC_2, *, controlr, 1)," & "2426 (BC_2, IO_AL35, output3, X, 2425, 1, Z)," & -- PAD267 "2427 (BC_2, IO_AL35, input, X)," & -- PAD267 "2428 (BC_2, *, controlr, 1)," & "2429 (BC_2, IO_AK35, output3, X, 2428, 1, Z)," & -- PAD266 "2430 (BC_2, IO_AK35, input, X)," & -- PAD266 "2431 (BC_2, *, controlr, 1)," & "2432 (BC_2, IO_AH33, output3, X, 2431, 1, Z)," & -- PAD265 "2433 (BC_2, IO_AH33, input, X)," & -- PAD265 "2434 (BC_2, *, controlr, 1)," & "2435 (BC_2, IO_AG33, output3, X, 2434, 1, Z)," & -- PAD264 "2436 (BC_2, IO_AG33, input, X)," & -- PAD264 "2437 (BC_2, *, controlr, 1)," & "2438 (BC_2, IO_AM37, output3, X, 2437, 1, Z)," & -- PAD263 "2439 (BC_2, IO_AM37, input, X)," & -- PAD263 "2440 (BC_2, *, controlr, 1)," & "2441 (BC_2, IO_AL36, output3, X, 2440, 1, Z)," & -- PAD262 "2442 (BC_2, IO_AL36, input, X)," & -- PAD262 "2443 (BC_2, *, controlr, 1)," & "2444 (BC_2, IO_AP35, output3, X, 2443, 1, Z)," & -- PAD261 "2445 (BC_2, IO_AP35, input, X)," & -- PAD261 "2446 (BC_2, *, controlr, 1)," & "2447 (BC_2, IO_AN35, output3, X, 2446, 1, Z)," & -- PAD260 "2448 (BC_2, IO_AN35, input, X)," & -- PAD260 "2449 (BC_2, *, controlr, 1)," & "2450 (BC_2, IO_AL37, output3, X, 2449, 1, Z)," & -- PAD259 "2451 (BC_2, IO_AL37, input, X)," & -- PAD259 "2452 (BC_2, *, controlr, 1)," & "2453 (BC_2, IO_AK37, output3, X, 2452, 1, Z)," & -- PAD258 "2454 (BC_2, IO_AK37, input, X)," & -- PAD258 "2455 (BC_2, *, controlr, 1)," & "2456 (BC_2, IO_AP37, output3, X, 2455, 1, Z)," & -- PAD257 "2457 (BC_2, IO_AP37, input, X)," & -- PAD257 "2458 (BC_2, *, controlr, 1)," & "2459 (BC_2, IO_AP36, output3, X, 2458, 1, Z)," & -- PAD256 "2460 (BC_2, IO_AP36, input, X)," & -- PAD256 "2461 (BC_2, *, controlr, 1)," & "2462 (BC_2, IO_AJ37, output3, X, 2461, 1, Z)," & -- PAD255 "2463 (BC_2, IO_AJ37, input, X)," & -- PAD255 "2464 (BC_2, *, controlr, 1)," & "2465 (BC_2, IO_AJ36, output3, X, 2464, 1, Z)," & -- PAD254 "2466 (BC_2, IO_AJ36, input, X)," & -- PAD254 "2467 (BC_2, *, controlr, 1)," & "2468 (BC_2, IO_AN36, output3, X, 2467, 1, Z)," & -- PAD253 "2469 (BC_2, IO_AN36, input, X)," & -- PAD253 "2470 (BC_2, *, controlr, 1)," & "2471 (BC_2, IO_AM36, output3, X, 2470, 1, Z)," & -- PAD252 "2472 (BC_2, IO_AM36, input, X)," & -- PAD252 "2473 (BC_2, *, controlr, 1)," & "2474 (BC_2, IO_AH35, output3, X, 2473, 1, Z)," & -- PAD251 "2475 (BC_2, IO_AH35, input, X)," & -- PAD251 "2476 (BC_2, *, controlr, 1)," & "2477 (BC_2, IO_AU37, output3, X, 2476, 1, Z)," & -- PAD250 "2478 (BC_2, IO_AU37, input, X)," & -- PAD250 "2479 (BC_2, *, controlr, 1)," & "2480 (BC_2, IO_AW42, output3, X, 2479, 1, Z)," & -- PAD249 "2481 (BC_2, IO_AW42, input, X)," & -- PAD249 "2482 (BC_2, *, controlr, 1)," & "2483 (BC_2, IO_AW41, output3, X, 2482, 1, Z)," & -- PAD248 "2484 (BC_2, IO_AW41, input, X)," & -- PAD248 "2485 (BC_2, *, controlr, 1)," & "2486 (BC_2, IO_BB41, output3, X, 2485, 1, Z)," & -- PAD247 "2487 (BC_2, IO_BB41, input, X)," & -- PAD247 "2488 (BC_2, *, controlr, 1)," & "2489 (BC_2, IO_BA41, output3, X, 2488, 1, Z)," & -- PAD246 "2490 (BC_2, IO_BA41, input, X)," & -- PAD246 "2491 (BC_2, *, controlr, 1)," & "2492 (BC_2, IO_AV41, output3, X, 2491, 1, Z)," & -- PAD245 "2493 (BC_2, IO_AV41, input, X)," & -- PAD245 "2494 (BC_2, *, controlr, 1)," & "2495 (BC_2, IO_AU41, output3, X, 2494, 1, Z)," & -- PAD244 "2496 (BC_2, IO_AU41, input, X)," & -- PAD244 "2497 (BC_2, *, controlr, 1)," & "2498 (BC_2, IO_BA42, output3, X, 2497, 1, Z)," & -- PAD243 "2499 (BC_2, IO_BA42, input, X)," & -- PAD243 "2500 (BC_2, *, controlr, 1)," & "2501 (BC_2, IO_AY42, output3, X, 2500, 1, Z)," & -- PAD242 "2502 (BC_2, IO_AY42, input, X)," & -- PAD242 "2503 (BC_2, *, controlr, 1)," & "2504 (BC_2, IO_AU42, output3, X, 2503, 1, Z)," & -- PAD241 "2505 (BC_2, IO_AU42, input, X)," & -- PAD241 "2506 (BC_2, *, controlr, 1)," & "2507 (BC_2, IO_AT41, output3, X, 2506, 1, Z)," & -- PAD240 "2508 (BC_2, IO_AT41, input, X)," & -- PAD240 "2509 (BC_2, *, controlr, 1)," & "2510 (BC_2, IO_BA40, output3, X, 2509, 1, Z)," & -- PAD239 "2511 (BC_2, IO_BA40, input, X)," & -- PAD239 "2512 (BC_2, *, controlr, 1)," & "2513 (BC_2, IO_BA39, output3, X, 2512, 1, Z)," & -- PAD238 "2514 (BC_2, IO_BA39, input, X)," & -- PAD238 "2515 (BC_2, *, controlr, 1)," & "2516 (BC_2, IO_BB39, output3, X, 2515, 1, Z)," & -- PAD237 "2517 (BC_2, IO_BB39, input, X)," & -- PAD237 "2518 (BC_2, *, controlr, 1)," & "2519 (BC_2, IO_BB38, output3, X, 2518, 1, Z)," & -- PAD236 "2520 (BC_2, IO_BB38, input, X)," & -- PAD236 "2521 (BC_2, *, controlr, 1)," & "2522 (BC_2, IO_AY38, output3, X, 2521, 1, Z)," & -- PAD235 "2523 (BC_2, IO_AY38, input, X)," & -- PAD235 "2524 (BC_2, *, controlr, 1)," & "2525 (BC_2, IO_AW38, output3, X, 2524, 1, Z)," & -- PAD234 "2526 (BC_2, IO_AW38, input, X)," & -- PAD234 "2527 (BC_2, *, controlr, 1)," & "2528 (BC_2, IO_BB37, output3, X, 2527, 1, Z)," & -- PAD233 "2529 (BC_2, IO_BB37, input, X)," & -- PAD233 "2530 (BC_2, *, controlr, 1)," & "2531 (BC_2, IO_BA37, output3, X, 2530, 1, Z)," & -- PAD232 "2532 (BC_2, IO_BA37, input, X)," & -- PAD232 "2533 (BC_2, *, controlr, 1)," & "2534 (BC_2, IO_AY37, output3, X, 2533, 1, Z)," & -- PAD231 "2535 (BC_2, IO_AY37, input, X)," & -- PAD231 "2536 (BC_2, *, controlr, 1)," & "2537 (BC_2, IO_AW37, output3, X, 2536, 1, Z)," & -- PAD230 "2538 (BC_2, IO_AW37, input, X)," & -- PAD230 "2539 (BC_2, *, controlr, 1)," & "2540 (BC_2, IO_AY40, output3, X, 2539, 1, Z)," & -- PAD229 "2541 (BC_2, IO_AY40, input, X)," & -- PAD229 "2542 (BC_2, *, controlr, 1)," & "2543 (BC_2, IO_AY39, output3, X, 2542, 1, Z)," & -- PAD228 "2544 (BC_2, IO_AY39, input, X)," & -- PAD228 "2545 (BC_2, *, controlr, 1)," & "2546 (BC_2, IO_AW40, output3, X, 2545, 1, Z)," & -- PAD227 "2547 (BC_2, IO_AW40, input, X)," & -- PAD227 "2548 (BC_2, *, controlr, 1)," & "2549 (BC_2, IO_AV40, output3, X, 2548, 1, Z)," & -- PAD226 "2550 (BC_2, IO_AV40, input, X)," & -- PAD226 "2551 (BC_2, *, controlr, 1)," & "2552 (BC_2, IO_AV38, output3, X, 2551, 1, Z)," & -- PAD225 "2553 (BC_2, IO_AV38, input, X)," & -- PAD225 "2554 (BC_2, *, controlr, 1)," & "2555 (BC_2, IO_AU38, output3, X, 2554, 1, Z)," & -- PAD224 "2556 (BC_2, IO_AU38, input, X)," & -- PAD224 "2557 (BC_2, *, controlr, 1)," & "2558 (BC_2, IO_AV39, output3, X, 2557, 1, Z)," & -- PAD223 "2559 (BC_2, IO_AV39, input, X)," & -- PAD223 "2560 (BC_2, *, controlr, 1)," & "2561 (BC_2, IO_AU39, output3, X, 2560, 1, Z)," & -- PAD222 "2562 (BC_2, IO_AU39, input, X)," & -- PAD222 "2563 (BC_2, *, controlr, 1)," & "2564 (BC_2, IO_AT42, output3, X, 2563, 1, Z)," & -- PAD221 "2565 (BC_2, IO_AT42, input, X)," & -- PAD221 "2566 (BC_2, *, controlr, 1)," & "2567 (BC_2, IO_AR42, output3, X, 2566, 1, Z)," & -- PAD220 "2568 (BC_2, IO_AR42, input, X)," & -- PAD220 "2569 (BC_2, *, controlr, 1)," & "2570 (BC_2, IO_AT40, output3, X, 2569, 1, Z)," & -- PAD219 "2571 (BC_2, IO_AT40, input, X)," & -- PAD219 "2572 (BC_2, *, controlr, 1)," & "2573 (BC_2, IO_AT39, output3, X, 2572, 1, Z)," & -- PAD218 "2574 (BC_2, IO_AT39, input, X)," & -- PAD218 "2575 (BC_2, *, controlr, 1)," & "2576 (BC_2, IO_AP42, output3, X, 2575, 1, Z)," & -- PAD217 "2577 (BC_2, IO_AP42, input, X)," & -- PAD217 "2578 (BC_2, *, controlr, 1)," & "2579 (BC_2, IO_AP41, output3, X, 2578, 1, Z)," & -- PAD216 "2580 (BC_2, IO_AP41, input, X)," & -- PAD216 "2581 (BC_2, *, controlr, 1)," & "2582 (BC_2, IO_AR40, output3, X, 2581, 1, Z)," & -- PAD215 "2583 (BC_2, IO_AR40, input, X)," & -- PAD215 "2584 (BC_2, *, controlr, 1)," & "2585 (BC_2, IO_AP40, output3, X, 2584, 1, Z)," & -- PAD214 "2586 (BC_2, IO_AP40, input, X)," & -- PAD214 "2587 (BC_2, *, controlr, 1)," & "2588 (BC_2, IO_AN39, output3, X, 2587, 1, Z)," & -- PAD213 "2589 (BC_2, IO_AN39, input, X)," & -- PAD213 "2590 (BC_2, *, controlr, 1)," & "2591 (BC_2, IO_AM39, output3, X, 2590, 1, Z)," & -- PAD212 "2592 (BC_2, IO_AM39, input, X)," & -- PAD212 "2593 (BC_2, *, controlr, 1)," & "2594 (BC_2, IO_AT37, output3, X, 2593, 1, Z)," & -- PAD211 "2595 (BC_2, IO_AT37, input, X)," & -- PAD211 "2596 (BC_2, *, controlr, 1)," & "2597 (BC_2, IO_AR37, output3, X, 2596, 1, Z)," & -- PAD210 "2598 (BC_2, IO_AR37, input, X)," & -- PAD210 "2599 (BC_2, *, controlr, 1)," & "2600 (BC_2, IO_AN41, output3, X, 2599, 1, Z)," & -- PAD209 "2601 (BC_2, IO_AN41, input, X)," & -- PAD209 "2602 (BC_2, *, controlr, 1)," & "2603 (BC_2, IO_AN40, output3, X, 2602, 1, Z)," & -- PAD208 "2604 (BC_2, IO_AN40, input, X)," & -- PAD208 "2605 (BC_2, *, controlr, 1)," & "2606 (BC_2, IO_AR39, output3, X, 2605, 1, Z)," & -- PAD207 "2607 (BC_2, IO_AR39, input, X)," & -- PAD207 "2608 (BC_2, *, controlr, 1)," & "2609 (BC_2, IO_AR38, output3, X, 2608, 1, Z)," & -- PAD206 "2610 (BC_2, IO_AR38, input, X)," & -- PAD206 "2611 (BC_2, *, controlr, 1)," & "2612 (BC_2, IO_AM42, output3, X, 2611, 1, Z)," & -- PAD205 "2613 (BC_2, IO_AM42, input, X)," & -- PAD205 "2614 (BC_2, *, controlr, 1)," & "2615 (BC_2, IO_AM41, output3, X, 2614, 1, Z)," & -- PAD204 "2616 (BC_2, IO_AM41, input, X)," & -- PAD204 "2617 (BC_2, *, controlr, 1)," & "2618 (BC_2, IO_AP38, output3, X, 2617, 1, Z)," & -- PAD203 "2619 (BC_2, IO_AP38, input, X)," & -- PAD203 "2620 (BC_2, *, controlr, 1)," & "2621 (BC_2, IO_AN38, output3, X, 2620, 1, Z)," & -- PAD202 "2622 (BC_2, IO_AN38, input, X)," & -- PAD202 "2623 (BC_2, *, controlr, 1)," & "2624 (BC_2, IO_AM38, output3, X, 2623, 1, Z)," & -- PAD201 "2625 (BC_2, IO_AM38, input, X)," & -- PAD201 "2626 (BC_2, *, controlr, 1)," & "2627 (BC_2, IO_AB34, output3, X, 2626, 1, Z)," & -- PAD200 "2628 (BC_2, IO_AB34, input, X)," & -- PAD200 "2629 (BC_2, *, controlr, 1)," & "2630 (BC_2, IO_AC29, output3, X, 2629, 1, Z)," & -- PAD199 "2631 (BC_2, IO_AC29, input, X)," & -- PAD199 "2632 (BC_2, *, controlr, 1)," & "2633 (BC_2, IO_AB29, output3, X, 2632, 1, Z)," & -- PAD198 "2634 (BC_2, IO_AB29, input, X)," & -- PAD198 "2635 (BC_2, *, controlr, 1)," & "2636 (BC_2, IO_AA30, output3, X, 2635, 1, Z)," & -- PAD197 "2637 (BC_2, IO_AA30, input, X)," & -- PAD197 "2638 (BC_2, *, controlr, 1)," & "2639 (BC_2, IO_AA29, output3, X, 2638, 1, Z)," & -- PAD196 "2640 (BC_2, IO_AA29, input, X)," & -- PAD196 "2641 (BC_2, *, controlr, 1)," & "2642 (BC_2, IO_AD30, output3, X, 2641, 1, Z)," & -- PAD195 "2643 (BC_2, IO_AD30, input, X)," & -- PAD195 "2644 (BC_2, *, controlr, 1)," & "2645 (BC_2, IO_AC30, output3, X, 2644, 1, Z)," & -- PAD194 "2646 (BC_2, IO_AC30, input, X)," & -- PAD194 "2647 (BC_2, *, controlr, 1)," & "2648 (BC_2, IO_AA32, output3, X, 2647, 1, Z)," & -- PAD193 "2649 (BC_2, IO_AA32, input, X)," & -- PAD193 "2650 (BC_2, *, controlr, 1)," & "2651 (BC_2, IO_AA31, output3, X, 2650, 1, Z)," & -- PAD192 "2652 (BC_2, IO_AA31, input, X)," & -- PAD192 "2653 (BC_2, *, controlr, 1)," & "2654 (BC_2, IO_AD31, output3, X, 2653, 1, Z)," & -- PAD191 "2655 (BC_2, IO_AD31, input, X)," & -- PAD191 "2656 (BC_2, *, controlr, 1)," & "2657 (BC_2, IO_AC31, output3, X, 2656, 1, Z)," & -- PAD190 "2658 (BC_2, IO_AC31, input, X)," & -- PAD190 "2659 (BC_2, *, controlr, 1)," & "2660 (BC_2, IO_Y33, output3, X, 2659, 1, Z)," & -- PAD189 "2661 (BC_2, IO_Y33, input, X)," & -- PAD189 "2662 (BC_2, *, controlr, 1)," & "2663 (BC_2, IO_Y32, output3, X, 2662, 1, Z)," & -- PAD188 "2664 (BC_2, IO_Y32, input, X)," & -- PAD188 "2665 (BC_2, *, controlr, 1)," & "2666 (BC_2, IO_AE30, output3, X, 2665, 1, Z)," & -- PAD187 "2667 (BC_2, IO_AE30, input, X)," & -- PAD187 "2668 (BC_2, *, controlr, 1)," & "2669 (BC_2, IO_AE29, output3, X, 2668, 1, Z)," & -- PAD186 "2670 (BC_2, IO_AE29, input, X)," & -- PAD186 "2671 (BC_2, *, controlr, 1)," & "2672 (BC_2, IO_AE35, output3, X, 2671, 1, Z)," & -- PAD185 "2673 (BC_2, IO_AE35, input, X)," & -- PAD185 "2674 (BC_2, *, controlr, 1)," & "2675 (BC_2, IO_AE34, output3, X, 2674, 1, Z)," & -- PAD184 "2676 (BC_2, IO_AE34, input, X)," & -- PAD184 "2677 (BC_2, *, controlr, 1)," & "2678 (BC_2, IO_AF32, output3, X, 2677, 1, Z)," & -- PAD183 "2679 (BC_2, IO_AF32, input, X)," & -- PAD183 "2680 (BC_2, *, controlr, 1)," & "2681 (BC_2, IO_AF31, output3, X, 2680, 1, Z)," & -- PAD182 "2682 (BC_2, IO_AF31, input, X)," & -- PAD182 "2683 (BC_2, *, controlr, 1)," & "2684 (BC_2, IO_AE33, output3, X, 2683, 1, Z)," & -- PAD181 "2685 (BC_2, IO_AE33, input, X)," & -- PAD181 "2686 (BC_2, *, controlr, 1)," & "2687 (BC_2, IO_AE32, output3, X, 2686, 1, Z)," & -- PAD180 "2688 (BC_2, IO_AE32, input, X)," & -- PAD180 "2689 (BC_2, *, controlr, 1)," & "2690 (BC_2, IO_AD35, output3, X, 2689, 1, Z)," & -- PAD179 "2691 (BC_2, IO_AD35, input, X)," & -- PAD179 "2692 (BC_2, *, controlr, 1)," & "2693 (BC_2, IO_AC34, output3, X, 2692, 1, Z)," & -- PAD178 "2694 (BC_2, IO_AC34, input, X)," & -- PAD178 "2695 (BC_2, *, controlr, 1)," & "2696 (BC_2, IO_AD33, output3, X, 2695, 1, Z)," & -- PAD177 "2697 (BC_2, IO_AD33, input, X)," & -- PAD177 "2698 (BC_2, *, controlr, 1)," & "2699 (BC_2, IO_AD32, output3, X, 2698, 1, Z)," & -- PAD176 "2700 (BC_2, IO_AD32, input, X)," & -- PAD176 "2701 (BC_2, *, controlr, 1)," & "2702 (BC_2, IO_AC33, output3, X, 2701, 1, Z)," & -- PAD175 "2703 (BC_2, IO_AC33, input, X)," & -- PAD175 "2704 (BC_2, *, controlr, 1)," & "2705 (BC_2, IO_AB33, output3, X, 2704, 1, Z)," & -- PAD174 "2706 (BC_2, IO_AB33, input, X)," & -- PAD174 "2707 (BC_2, *, controlr, 1)," & "2708 (BC_2, IO_AB32, output3, X, 2707, 1, Z)," & -- PAD173 "2709 (BC_2, IO_AB32, input, X)," & -- PAD173 "2710 (BC_2, *, controlr, 1)," & "2711 (BC_2, IO_AB31, output3, X, 2710, 1, Z)," & -- PAD172 "2712 (BC_2, IO_AB31, input, X)," & -- PAD172 "2713 (BC_2, *, controlr, 1)," & "2714 (BC_2, IO_AA35, output3, X, 2713, 1, Z)," & -- PAD171 "2715 (BC_2, IO_AA35, input, X)," & -- PAD171 "2716 (BC_2, *, controlr, 1)," & "2717 (BC_2, IO_AA34, output3, X, 2716, 1, Z)," & -- PAD170 "2718 (BC_2, IO_AA34, input, X)," & -- PAD170 "2719 (BC_2, *, controlr, 1)," & "2720 (BC_2, IO_AB37, output3, X, 2719, 1, Z)," & -- PAD169 "2721 (BC_2, IO_AB37, input, X)," & -- PAD169 "2722 (BC_2, *, controlr, 1)," & "2723 (BC_2, IO_AB36, output3, X, 2722, 1, Z)," & -- PAD168 "2724 (BC_2, IO_AB36, input, X)," & -- PAD168 "2725 (BC_2, *, controlr, 1)," & "2726 (BC_2, IO_AA36, output3, X, 2725, 1, Z)," & -- PAD167 "2727 (BC_2, IO_AA36, input, X)," & -- PAD167 "2728 (BC_2, *, controlr, 1)," & "2729 (BC_2, IO_Y35, output3, X, 2728, 1, Z)," & -- PAD166 "2730 (BC_2, IO_Y35, input, X)," & -- PAD166 "2731 (BC_2, *, controlr, 1)," & "2732 (BC_2, IO_AA37, output3, X, 2731, 1, Z)," & -- PAD165 "2733 (BC_2, IO_AA37, input, X)," & -- PAD165 "2734 (BC_2, *, controlr, 1)," & "2735 (BC_2, IO_Y37, output3, X, 2734, 1, Z)," & -- PAD164 "2736 (BC_2, IO_Y37, input, X)," & -- PAD164 "2737 (BC_2, *, controlr, 1)," & "2738 (BC_2, IO_AH36, output3, X, 2737, 1, Z)," & -- PAD163 "2739 (BC_2, IO_AH36, input, X)," & -- PAD163 "2740 (BC_2, *, controlr, 1)," & "2741 (BC_2, IO_AG36, output3, X, 2740, 1, Z)," & -- PAD162 "2742 (BC_2, IO_AG36, input, X)," & -- PAD162 "2743 (BC_2, *, controlr, 1)," & "2744 (BC_2, IO_AC36, output3, X, 2743, 1, Z)," & -- PAD161 "2745 (BC_2, IO_AC36, input, X)," & -- PAD161 "2746 (BC_2, *, controlr, 1)," & "2747 (BC_2, IO_AC35, output3, X, 2746, 1, Z)," & -- PAD160 "2748 (BC_2, IO_AC35, input, X)," & -- PAD160 "2749 (BC_2, *, controlr, 1)," & "2750 (BC_2, IO_AD37, output3, X, 2749, 1, Z)," & -- PAD159 "2751 (BC_2, IO_AD37, input, X)," & -- PAD159 "2752 (BC_2, *, controlr, 1)," & "2753 (BC_2, IO_AD36, output3, X, 2752, 1, Z)," & -- PAD158 "2754 (BC_2, IO_AD36, input, X)," & -- PAD158 "2755 (BC_2, *, controlr, 1)," & "2756 (BC_2, IO_AG34, output3, X, 2755, 1, Z)," & -- PAD157 "2757 (BC_2, IO_AG34, input, X)," & -- PAD157 "2758 (BC_2, *, controlr, 1)," & "2759 (BC_2, IO_AF34, output3, X, 2758, 1, Z)," & -- PAD156 "2760 (BC_2, IO_AF34, input, X)," & -- PAD156 "2761 (BC_2, *, controlr, 1)," & "2762 (BC_2, IO_AF37, output3, X, 2761, 1, Z)," & -- PAD155 "2763 (BC_2, IO_AF37, input, X)," & -- PAD155 "2764 (BC_2, *, controlr, 1)," & "2765 (BC_2, IO_AE37, output3, X, 2764, 1, Z)," & -- PAD154 "2766 (BC_2, IO_AE37, input, X)," & -- PAD154 "2767 (BC_2, *, controlr, 1)," & "2768 (BC_2, IO_AF36, output3, X, 2767, 1, Z)," & -- PAD153 "2769 (BC_2, IO_AF36, input, X)," & -- PAD153 "2770 (BC_2, *, controlr, 1)," & "2771 (BC_2, IO_AF35, output3, X, 2770, 1, Z)," & -- PAD152 "2772 (BC_2, IO_AF35, input, X)," & -- PAD152 "2773 (BC_2, *, controlr, 1)," & "2774 (BC_2, IO_Y34, output3, X, 2773, 1, Z)," & -- PAD151 "2775 (BC_2, IO_Y34, input, X)," & -- PAD151 "2776 (BC_2, *, controlr, 1)," & "2777 (BC_2, IO_AG37, output3, X, 2776, 1, Z)," & -- PAD150 "2778 (BC_2, IO_AG37, input, X)," & -- PAD150 "2779 (BC_2, *, controlr, 1)," & "2780 (BC_2, IO_AK42, output3, X, 2779, 1, Z)," & -- PAD149 "2781 (BC_2, IO_AK42, input, X)," & -- PAD149 "2782 (BC_2, *, controlr, 1)," & "2783 (BC_2, IO_AJ42, output3, X, 2782, 1, Z)," & -- PAD148 "2784 (BC_2, IO_AJ42, input, X)," & -- PAD148 "2785 (BC_2, *, controlr, 1)," & "2786 (BC_2, IO_AL39, output3, X, 2785, 1, Z)," & -- PAD147 "2787 (BC_2, IO_AL39, input, X)," & -- PAD147 "2788 (BC_2, *, controlr, 1)," & "2789 (BC_2, IO_AK39, output3, X, 2788, 1, Z)," & -- PAD146 "2790 (BC_2, IO_AK39, input, X)," & -- PAD146 "2791 (BC_2, *, controlr, 1)," & "2792 (BC_2, IO_AJ41, output3, X, 2791, 1, Z)," & -- PAD145 "2793 (BC_2, IO_AJ41, input, X)," & -- PAD145 "2794 (BC_2, *, controlr, 1)," & "2795 (BC_2, IO_AJ40, output3, X, 2794, 1, Z)," & -- PAD144 "2796 (BC_2, IO_AJ40, input, X)," & -- PAD144 "2797 (BC_2, *, controlr, 1)," & "2798 (BC_2, IO_AL42, output3, X, 2797, 1, Z)," & -- PAD143 "2799 (BC_2, IO_AL42, input, X)," & -- PAD143 "2800 (BC_2, *, controlr, 1)," & "2801 (BC_2, IO_AL41, output3, X, 2800, 1, Z)," & -- PAD142 "2802 (BC_2, IO_AL41, input, X)," & -- PAD142 "2803 (BC_2, *, controlr, 1)," & "2804 (BC_2, IO_AH41, output3, X, 2803, 1, Z)," & -- PAD141 "2805 (BC_2, IO_AH41, input, X)," & -- PAD141 "2806 (BC_2, *, controlr, 1)," & "2807 (BC_2, IO_AH40, output3, X, 2806, 1, Z)," & -- PAD140 "2808 (BC_2, IO_AH40, input, X)," & -- PAD140 "2809 (BC_2, *, controlr, 1)," & "2810 (BC_2, IO_AL40, output3, X, 2809, 1, Z)," & -- PAD139 "2811 (BC_2, IO_AL40, input, X)," & -- PAD139 "2812 (BC_2, *, controlr, 1)," & "2813 (BC_2, IO_AK40, output3, X, 2812, 1, Z)," & -- PAD138 "2814 (BC_2, IO_AK40, input, X)," & -- PAD138 "2815 (BC_2, *, controlr, 1)," & "2816 (BC_2, IO_AK38, output3, X, 2815, 1, Z)," & -- PAD137 "2817 (BC_2, IO_AK38, input, X)," & -- PAD137 "2818 (BC_2, *, controlr, 1)," & "2819 (BC_2, IO_AJ38, output3, X, 2818, 1, Z)," & -- PAD136 "2820 (BC_2, IO_AJ38, input, X)," & -- PAD136 "2821 (BC_2, *, controlr, 1)," & "2822 (BC_2, IO_AH38, output3, X, 2821, 1, Z)," & -- PAD135 "2823 (BC_2, IO_AH38, input, X)," & -- PAD135 "2824 (BC_2, *, controlr, 1)," & "2825 (BC_2, IO_AG38, output3, X, 2824, 1, Z)," & -- PAD134 "2826 (BC_2, IO_AG38, input, X)," & -- PAD134 "2827 (BC_2, *, controlr, 1)," & "2828 (BC_2, IO_AG42, output3, X, 2827, 1, Z)," & -- PAD133 "2829 (BC_2, IO_AG42, input, X)," & -- PAD133 "2830 (BC_2, *, controlr, 1)," & "2831 (BC_2, IO_AF42, output3, X, 2830, 1, Z)," & -- PAD132 "2832 (BC_2, IO_AF42, input, X)," & -- PAD132 "2833 (BC_2, *, controlr, 1)," & "2834 (BC_2, IO_AH39, output3, X, 2833, 1, Z)," & -- PAD131 "2835 (BC_2, IO_AH39, input, X)," & -- PAD131 "2836 (BC_2, *, controlr, 1)," & "2837 (BC_2, IO_AG39, output3, X, 2836, 1, Z)," & -- PAD130 "2838 (BC_2, IO_AG39, input, X)," & -- PAD130 "2839 (BC_2, *, controlr, 1)," & "2840 (BC_2, IO_AG41, output3, X, 2839, 1, Z)," & -- PAD129 "2841 (BC_2, IO_AG41, input, X)," & -- PAD129 "2842 (BC_2, *, controlr, 1)," & "2843 (BC_2, IO_AF41, output3, X, 2842, 1, Z)," & -- PAD128 "2844 (BC_2, IO_AF41, input, X)," & -- PAD128 "2845 (BC_2, *, controlr, 1)," & "2846 (BC_2, IO_AF40, output3, X, 2845, 1, Z)," & -- PAD127 "2847 (BC_2, IO_AF40, input, X)," & -- PAD127 "2848 (BC_2, *, controlr, 1)," & "2849 (BC_2, IO_AF39, output3, X, 2848, 1, Z)," & -- PAD126 "2850 (BC_2, IO_AF39, input, X)," & -- PAD126 "2851 (BC_2, *, controlr, 1)," & "2852 (BC_2, IO_AD41, output3, X, 2851, 1, Z)," & -- PAD125 "2853 (BC_2, IO_AD41, input, X)," & -- PAD125 "2854 (BC_2, *, controlr, 1)," & "2855 (BC_2, IO_AD40, output3, X, 2854, 1, Z)," & -- PAD124 "2856 (BC_2, IO_AD40, input, X)," & -- PAD124 "2857 (BC_2, *, controlr, 1)," & "2858 (BC_2, IO_AE40, output3, X, 2857, 1, Z)," & -- PAD123 "2859 (BC_2, IO_AE40, input, X)," & -- PAD123 "2860 (BC_2, *, controlr, 1)," & "2861 (BC_2, IO_AE39, output3, X, 2860, 1, Z)," & -- PAD122 "2862 (BC_2, IO_AE39, input, X)," & -- PAD122 "2863 (BC_2, *, controlr, 1)," & "2864 (BC_2, IO_AC41, output3, X, 2863, 1, Z)," & -- PAD121 "2865 (BC_2, IO_AC41, input, X)," & -- PAD121 "2866 (BC_2, *, controlr, 1)," & "2867 (BC_2, IO_AC40, output3, X, 2866, 1, Z)," & -- PAD120 "2868 (BC_2, IO_AC40, input, X)," & -- PAD120 "2869 (BC_2, *, controlr, 1)," & "2870 (BC_2, IO_AE38, output3, X, 2869, 1, Z)," & -- PAD119 "2871 (BC_2, IO_AE38, input, X)," & -- PAD119 "2872 (BC_2, *, controlr, 1)," & "2873 (BC_2, IO_AD38, output3, X, 2872, 1, Z)," & -- PAD118 "2874 (BC_2, IO_AD38, input, X)," & -- PAD118 "2875 (BC_2, *, controlr, 1)," & "2876 (BC_2, IO_AE42, output3, X, 2875, 1, Z)," & -- PAD117 "2877 (BC_2, IO_AE42, input, X)," & -- PAD117 "2878 (BC_2, *, controlr, 1)," & "2879 (BC_2, IO_AD42, output3, X, 2878, 1, Z)," & -- PAD116 "2880 (BC_2, IO_AD42, input, X)," & -- PAD116 "2881 (BC_2, *, controlr, 1)," & "2882 (BC_2, IO_AC39, output3, X, 2881, 1, Z)," & -- PAD115 "2883 (BC_2, IO_AC39, input, X)," & -- PAD115 "2884 (BC_2, *, controlr, 1)," & "2885 (BC_2, IO_AC38, output3, X, 2884, 1, Z)," & -- PAD114 "2886 (BC_2, IO_AC38, input, X)," & -- PAD114 "2887 (BC_2, *, controlr, 1)," & "2888 (BC_2, IO_AA41, output3, X, 2887, 1, Z)," & -- PAD113 "2889 (BC_2, IO_AA41, input, X)," & -- PAD113 "2890 (BC_2, *, controlr, 1)," & "2891 (BC_2, IO_AA40, output3, X, 2890, 1, Z)," & -- PAD112 "2892 (BC_2, IO_AA40, input, X)," & -- PAD112 "2893 (BC_2, *, controlr, 1)," & "2894 (BC_2, IO_AB39, output3, X, 2893, 1, Z)," & -- PAD111 "2895 (BC_2, IO_AB39, input, X)," & -- PAD111 "2896 (BC_2, *, controlr, 1)," & "2897 (BC_2, IO_AB38, output3, X, 2896, 1, Z)," & -- PAD110 "2898 (BC_2, IO_AB38, input, X)," & -- PAD110 "2899 (BC_2, *, controlr, 1)," & "2900 (BC_2, IO_AA42, output3, X, 2899, 1, Z)," & -- PAD109 "2901 (BC_2, IO_AA42, input, X)," & -- PAD109 "2902 (BC_2, *, controlr, 1)," & "2903 (BC_2, IO_Y42, output3, X, 2902, 1, Z)," & -- PAD108 "2904 (BC_2, IO_Y42, input, X)," & -- PAD108 "2905 (BC_2, *, controlr, 1)," & "2906 (BC_2, IO_AA39, output3, X, 2905, 1, Z)," & -- PAD107 "2907 (BC_2, IO_AA39, input, X)," & -- PAD107 "2908 (BC_2, *, controlr, 1)," & "2909 (BC_2, IO_Y39, output3, X, 2908, 1, Z)," & -- PAD106 "2910 (BC_2, IO_Y39, input, X)," & -- PAD106 "2911 (BC_2, *, controlr, 1)," & "2912 (BC_2, IO_Y40, output3, X, 2911, 1, Z)," & -- PAD105 "2913 (BC_2, IO_Y40, input, X)," & -- PAD105 "2914 (BC_2, *, controlr, 1)," & "2915 (BC_2, IO_W40, output3, X, 2914, 1, Z)," & -- PAD104 "2916 (BC_2, IO_W40, input, X)," & -- PAD104 "2917 (BC_2, *, controlr, 1)," & "2918 (BC_2, IO_AB42, output3, X, 2917, 1, Z)," & -- PAD103 "2919 (BC_2, IO_AB42, input, X)," & -- PAD103 "2920 (BC_2, *, controlr, 1)," & "2921 (BC_2, IO_AB41, output3, X, 2920, 1, Z)," & -- PAD102 "2922 (BC_2, IO_AB41, input, X)," & -- PAD102 "2923 (BC_2, *, controlr, 1)," & "2924 (BC_2, IO_Y38, output3, X, 2923, 1, Z)," & -- PAD101 "2925 (BC_2, IO_Y38, input, X)," & -- PAD101 "2926 (BC_2, *, controlr, 1)," & "2927 (BC_2, IO_W35, output3, X, 2926, 1, Z)," & -- PAD100 "2928 (BC_2, IO_W35, input, X)," & -- PAD100 "2929 (BC_2, *, controlr, 1)," & "2930 (BC_2, IO_U42, output3, X, 2929, 1, Z)," & -- PAD99 "2931 (BC_2, IO_U42, input, X)," & -- PAD99 "2932 (BC_2, *, controlr, 1)," & "2933 (BC_2, IO_V41, output3, X, 2932, 1, Z)," & -- PAD98 "2934 (BC_2, IO_V41, input, X)," & -- PAD98 "2935 (BC_2, *, controlr, 1)," & "2936 (BC_2, IO_V38, output3, X, 2935, 1, Z)," & -- PAD97 "2937 (BC_2, IO_V38, input, X)," & -- PAD97 "2938 (BC_2, *, controlr, 1)," & "2939 (BC_2, IO_W38, output3, X, 2938, 1, Z)," & -- PAD96 "2940 (BC_2, IO_W38, input, X)," & -- PAD96 "2941 (BC_2, *, controlr, 1)," & "2942 (BC_2, IO_T42, output3, X, 2941, 1, Z)," & -- PAD95 "2943 (BC_2, IO_T42, input, X)," & -- PAD95 "2944 (BC_2, *, controlr, 1)," & "2945 (BC_2, IO_U41, output3, X, 2944, 1, Z)," & -- PAD94 "2946 (BC_2, IO_U41, input, X)," & -- PAD94 "2947 (BC_2, *, controlr, 1)," & "2948 (BC_2, IO_W42, output3, X, 2947, 1, Z)," & -- PAD93 "2949 (BC_2, IO_W42, input, X)," & -- PAD93 "2950 (BC_2, *, controlr, 1)," & "2951 (BC_2, IO_W41, output3, X, 2950, 1, Z)," & -- PAD92 "2952 (BC_2, IO_W41, input, X)," & -- PAD92 "2953 (BC_2, *, controlr, 1)," & "2954 (BC_2, IO_T41, output3, X, 2953, 1, Z)," & -- PAD91 "2955 (BC_2, IO_T41, input, X)," & -- PAD91 "2956 (BC_2, *, controlr, 1)," & "2957 (BC_2, IO_T40, output3, X, 2956, 1, Z)," & -- PAD90 "2958 (BC_2, IO_T40, input, X)," & -- PAD90 "2959 (BC_2, *, controlr, 1)," & "2960 (BC_2, IO_V40, output3, X, 2959, 1, Z)," & -- PAD89 "2961 (BC_2, IO_V40, input, X)," & -- PAD89 "2962 (BC_2, *, controlr, 1)," & "2963 (BC_2, IO_V39, output3, X, 2962, 1, Z)," & -- PAD88 "2964 (BC_2, IO_V39, input, X)," & -- PAD88 "2965 (BC_2, *, controlr, 1)," & "2966 (BC_2, IO_W33, output3, X, 2965, 1, Z)," & -- PAD87 "2967 (BC_2, IO_W33, input, X)," & -- PAD87 "2968 (BC_2, *, controlr, 1)," & "2969 (BC_2, IO_W32, output3, X, 2968, 1, Z)," & -- PAD86 "2970 (BC_2, IO_W32, input, X)," & -- PAD86 "2971 (BC_2, *, controlr, 1)," & "2972 (BC_2, IO_U33, output3, X, 2971, 1, Z)," & -- PAD85 "2973 (BC_2, IO_U33, input, X)," & -- PAD85 "2974 (BC_2, *, controlr, 1)," & "2975 (BC_2, IO_U32, output3, X, 2974, 1, Z)," & -- PAD84 "2976 (BC_2, IO_U32, input, X)," & -- PAD84 "2977 (BC_2, *, controlr, 1)," & "2978 (BC_2, IO_W37, output3, X, 2977, 1, Z)," & -- PAD83 "2979 (BC_2, IO_W37, input, X)," & -- PAD83 "2980 (BC_2, *, controlr, 1)," & "2981 (BC_2, IO_W36, output3, X, 2980, 1, Z)," & -- PAD82 "2982 (BC_2, IO_W36, input, X)," & -- PAD82 "2983 (BC_2, *, controlr, 1)," & "2984 (BC_2, IO_V34, output3, X, 2983, 1, Z)," & -- PAD81 "2985 (BC_2, IO_V34, input, X)," & -- PAD81 "2986 (BC_2, *, controlr, 1)," & "2987 (BC_2, IO_V33, output3, X, 2986, 1, Z)," & -- PAD80 "2988 (BC_2, IO_V33, input, X)," & -- PAD80 "2989 (BC_2, *, controlr, 1)," & "2990 (BC_2, IO_V36, output3, X, 2989, 1, Z)," & -- PAD79 "2991 (BC_2, IO_V36, input, X)," & -- PAD79 "2992 (BC_2, *, controlr, 1)," & "2993 (BC_2, IO_V35, output3, X, 2992, 1, Z)," & -- PAD78 "2994 (BC_2, IO_V35, input, X)," & -- PAD78 "2995 (BC_2, *, controlr, 1)," & "2996 (BC_2, IO_T37, output3, X, 2995, 1, Z)," & -- PAD77 "2997 (BC_2, IO_T37, input, X)," & -- PAD77 "2998 (BC_2, *, controlr, 1)," & "2999 (BC_2, IO_U36, output3, X, 2998, 1, Z)," & -- PAD76 "3000 (BC_2, IO_U36, input, X)," & -- PAD76 "3001 (BC_2, *, controlr, 1)," & "3002 (BC_2, IO_T39, output3, X, 3001, 1, Z)," & -- PAD75 "3003 (BC_2, IO_T39, input, X)," & -- PAD75 "3004 (BC_2, *, controlr, 1)," & "3005 (BC_2, IO_U39, output3, X, 3004, 1, Z)," & -- PAD74 "3006 (BC_2, IO_U39, input, X)," & -- PAD74 "3007 (BC_2, *, controlr, 1)," & "3008 (BC_2, IO_U38, output3, X, 3007, 1, Z)," & -- PAD73 "3009 (BC_2, IO_U38, input, X)," & -- PAD73 "3010 (BC_2, *, controlr, 1)," & "3011 (BC_2, IO_U37, output3, X, 3010, 1, Z)," & -- PAD72 "3012 (BC_2, IO_U37, input, X)," & -- PAD72 "3013 (BC_2, *, controlr, 1)," & "3014 (BC_2, IO_R39, output3, X, 3013, 1, Z)," & -- PAD71 "3015 (BC_2, IO_R39, input, X)," & -- PAD71 "3016 (BC_2, *, controlr, 1)," & "3017 (BC_2, IO_R38, output3, X, 3016, 1, Z)," & -- PAD70 "3018 (BC_2, IO_R38, input, X)," & -- PAD70 "3019 (BC_2, *, controlr, 1)," & "3020 (BC_2, IO_T35, output3, X, 3019, 1, Z)," & -- PAD69 "3021 (BC_2, IO_T35, input, X)," & -- PAD69 "3022 (BC_2, *, controlr, 1)," & "3023 (BC_2, IO_U34, output3, X, 3022, 1, Z)," & -- PAD68 "3024 (BC_2, IO_U34, input, X)," & -- PAD68 "3025 (BC_2, *, controlr, 1)," & "3026 (BC_2, IO_P38, output3, X, 3025, 1, Z)," & -- PAD67 "3027 (BC_2, IO_P38, input, X)," & -- PAD67 "3028 (BC_2, *, controlr, 1)," & "3029 (BC_2, IO_P37, output3, X, 3028, 1, Z)," & -- PAD66 "3030 (BC_2, IO_P37, input, X)," & -- PAD66 "3031 (BC_2, *, controlr, 1)," & "3032 (BC_2, IO_R37, output3, X, 3031, 1, Z)," & -- PAD65 "3033 (BC_2, IO_R37, input, X)," & -- PAD65 "3034 (BC_2, *, controlr, 1)," & "3035 (BC_2, IO_T36, output3, X, 3034, 1, Z)," & -- PAD64 "3036 (BC_2, IO_T36, input, X)," & -- PAD64 "3037 (BC_2, *, controlr, 1)," & "3038 (BC_2, IO_P33, output3, X, 3037, 1, Z)," & -- PAD63 "3039 (BC_2, IO_P33, input, X)," & -- PAD63 "3040 (BC_2, *, controlr, 1)," & "3041 (BC_2, IO_P32, output3, X, 3040, 1, Z)," & -- PAD62 "3042 (BC_2, IO_P32, input, X)," & -- PAD62 "3043 (BC_2, *, controlr, 1)," & "3044 (BC_2, IO_R32, output3, X, 3043, 1, Z)," & -- PAD61 "3045 (BC_2, IO_R32, input, X)," & -- PAD61 "3046 (BC_2, *, controlr, 1)," & "3047 (BC_2, IO_T32, output3, X, 3046, 1, Z)," & -- PAD60 "3048 (BC_2, IO_T32, input, X)," & -- PAD60 "3049 (BC_2, *, controlr, 1)," & "3050 (BC_2, IO_P36, output3, X, 3049, 1, Z)," & -- PAD59 "3051 (BC_2, IO_P36, input, X)," & -- PAD59 "3052 (BC_2, *, controlr, 1)," & "3053 (BC_2, IO_P35, output3, X, 3052, 1, Z)," & -- PAD58 "3054 (BC_2, IO_P35, input, X)," & -- PAD58 "3055 (BC_2, *, controlr, 1)," & "3056 (BC_2, IO_R34, output3, X, 3055, 1, Z)," & -- PAD57 "3057 (BC_2, IO_R34, input, X)," & -- PAD57 "3058 (BC_2, *, controlr, 1)," & "3059 (BC_2, IO_R33, output3, X, 3058, 1, Z)," & -- PAD56 "3060 (BC_2, IO_R33, input, X)," & -- PAD56 "3061 (BC_2, *, controlr, 1)," & "3062 (BC_2, IO_N34, output3, X, 3061, 1, Z)," & -- PAD55 "3063 (BC_2, IO_N34, input, X)," & -- PAD55 "3064 (BC_2, *, controlr, 1)," & "3065 (BC_2, IO_N33, output3, X, 3064, 1, Z)," & -- PAD54 "3066 (BC_2, IO_N33, input, X)," & -- PAD54 "3067 (BC_2, *, controlr, 1)," & "3068 (BC_2, IO_R35, output3, X, 3067, 1, Z)," & -- PAD53 "3069 (BC_2, IO_R35, input, X)," & -- PAD53 "3070 (BC_2, *, controlr, 1)," & "3071 (BC_2, IO_T34, output3, X, 3070, 1, Z)," & -- PAD52 "3072 (BC_2, IO_T34, input, X)," & -- PAD52 "3073 (BC_2, *, controlr, 1)," & "3074 (BC_2, IO_N35, output3, X, 3073, 1, Z)," & -- PAD51 "3075 (BC_2, IO_N35, input, X)," & -- PAD51 "3076 (BC_2, *, controlr, 1)," & "3077 (BC_2, IO_N36, output3, X, 3076, 1, Z)," & -- PAD50 "3078 (BC_2, IO_N36, input, X)," & -- PAD50 "3079 (BC_2, *, controlr, 1)," & "3080 (BC_2, IO_N40, output3, X, 3079, 1, Z)," & -- PAD49 "3081 (BC_2, IO_N40, input, X)," & -- PAD49 "3082 (BC_2, *, controlr, 1)," & "3083 (BC_2, IO_N39, output3, X, 3082, 1, Z)," & -- PAD48 "3084 (BC_2, IO_N39, input, X)," & -- PAD48 "3085 (BC_2, *, controlr, 1)," & "3086 (BC_2, IO_P40, output3, X, 3085, 1, Z)," & -- PAD47 "3087 (BC_2, IO_P40, input, X)," & -- PAD47 "3088 (BC_2, *, controlr, 1)," & "3089 (BC_2, IO_R40, output3, X, 3088, 1, Z)," & -- PAD46 "3090 (BC_2, IO_R40, input, X)," & -- PAD46 "3091 (BC_2, *, controlr, 1)," & "3092 (BC_2, IO_M39, output3, X, 3091, 1, Z)," & -- PAD45 "3093 (BC_2, IO_M39, input, X)," & -- PAD45 "3094 (BC_2, *, controlr, 1)," & "3095 (BC_2, IO_N38, output3, X, 3094, 1, Z)," & -- PAD44 "3096 (BC_2, IO_N38, input, X)," & -- PAD44 "3097 (BC_2, *, controlr, 1)," & "3098 (BC_2, IO_P42, output3, X, 3097, 1, Z)," & -- PAD43 "3099 (BC_2, IO_P42, input, X)," & -- PAD43 "3100 (BC_2, *, controlr, 1)," & "3101 (BC_2, IO_R42, output3, X, 3100, 1, Z)," & -- PAD42 "3102 (BC_2, IO_R42, input, X)," & -- PAD42 "3103 (BC_2, *, controlr, 1)," & "3104 (BC_2, IO_M38, output3, X, 3103, 1, Z)," & -- PAD41 "3105 (BC_2, IO_M38, input, X)," & -- PAD41 "3106 (BC_2, *, controlr, 1)," & "3107 (BC_2, IO_M37, output3, X, 3106, 1, Z)," & -- PAD40 "3108 (BC_2, IO_M37, input, X)," & -- PAD40 "3109 (BC_2, *, controlr, 1)," & "3110 (BC_2, IO_N41, output3, X, 3109, 1, Z)," & -- PAD39 "3111 (BC_2, IO_N41, input, X)," & -- PAD39 "3112 (BC_2, *, controlr, 1)," & "3113 (BC_2, IO_P41, output3, X, 3112, 1, Z)," & -- PAD38 "3114 (BC_2, IO_P41, input, X)," & -- PAD38 "3115 (BC_2, *, controlr, 1)," & "3116 (BC_2, IO_L37, output3, X, 3115, 1, Z)," & -- PAD37 "3117 (BC_2, IO_L37, input, X)," & -- PAD37 "3118 (BC_2, *, controlr, 1)," & "3119 (BC_2, IO_M36, output3, X, 3118, 1, Z)," & -- PAD36 "3120 (BC_2, IO_M36, input, X)," & -- PAD36 "3121 (BC_2, *, controlr, 1)," & "3122 (BC_2, IO_K38, output3, X, 3121, 1, Z)," & -- PAD35 "3123 (BC_2, IO_K38, input, X)," & -- PAD35 "3124 (BC_2, *, controlr, 1)," & "3125 (BC_2, IO_K37, output3, X, 3124, 1, Z)," & -- PAD34 "3126 (BC_2, IO_K37, input, X)," & -- PAD34 "3127 (BC_2, *, controlr, 1)," & "3128 (BC_2, IO_L42, output3, X, 3127, 1, Z)," & -- PAD33 "3129 (BC_2, IO_L42, input, X)," & -- PAD33 "3130 (BC_2, *, controlr, 1)," & "3131 (BC_2, IO_M42, output3, X, 3130, 1, Z)," & -- PAD32 "3132 (BC_2, IO_M42, input, X)," & -- PAD32 "3133 (BC_2, *, controlr, 1)," & "3134 (BC_2, IO_J42, output3, X, 3133, 1, Z)," & -- PAD31 "3135 (BC_2, IO_J42, input, X)," & -- PAD31 "3136 (BC_2, *, controlr, 1)," & "3137 (BC_2, IO_K42, output3, X, 3136, 1, Z)," & -- PAD30 "3138 (BC_2, IO_K42, input, X)," & -- PAD30 "3139 (BC_2, *, controlr, 1)," & "3140 (BC_2, IO_L41, output3, X, 3139, 1, Z)," & -- PAD29 "3141 (BC_2, IO_L41, input, X)," & -- PAD29 "3142 (BC_2, *, controlr, 1)," & "3143 (BC_2, IO_M41, output3, X, 3142, 1, Z)," & -- PAD28 "3144 (BC_2, IO_M41, input, X)," & -- PAD28 "3145 (BC_2, *, controlr, 1)," & "3146 (BC_2, IO_L40, output3, X, 3145, 1, Z)," & -- PAD27 "3147 (BC_2, IO_L40, input, X)," & -- PAD27 "3148 (BC_2, *, controlr, 1)," & "3149 (BC_2, IO_L39, output3, X, 3148, 1, Z)," & -- PAD26 "3150 (BC_2, IO_L39, input, X)," & -- PAD26 "3151 (BC_2, *, controlr, 1)," & "3152 (BC_2, IO_K40, output3, X, 3151, 1, Z)," & -- PAD25 "3153 (BC_2, IO_K40, input, X)," & -- PAD25 "3154 (BC_2, *, controlr, 1)," & "3155 (BC_2, IO_K39, output3, X, 3154, 1, Z)," & -- PAD24 "3156 (BC_2, IO_K39, input, X)," & -- PAD24 "3157 (BC_2, *, controlr, 1)," & "3158 (BC_2, IO_J41, output3, X, 3157, 1, Z)," & -- PAD23 "3159 (BC_2, IO_J41, input, X)," & -- PAD23 "3160 (BC_2, *, controlr, 1)," & "3161 (BC_2, IO_J40, output3, X, 3160, 1, Z)," & -- PAD22 "3162 (BC_2, IO_J40, input, X)," & -- PAD22 "3163 (BC_2, *, controlr, 1)," & "3164 (BC_2, IO_F41, output3, X, 3163, 1, Z)," & -- PAD21 "3165 (BC_2, IO_F41, input, X)," & -- PAD21 "3166 (BC_2, *, controlr, 1)," & "3167 (BC_2, IO_F40, output3, X, 3166, 1, Z)," & -- PAD20 "3168 (BC_2, IO_F40, input, X)," & -- PAD20 "3169 (BC_2, *, controlr, 1)," & "3170 (BC_2, IO_G42, output3, X, 3169, 1, Z)," & -- PAD19 "3171 (BC_2, IO_G42, input, X)," & -- PAD19 "3172 (BC_2, *, controlr, 1)," & "3173 (BC_2, IO_G41, output3, X, 3172, 1, Z)," & -- PAD18 "3174 (BC_2, IO_G41, input, X)," & -- PAD18 "3175 (BC_2, *, controlr, 1)," & "3176 (BC_2, IO_G39, output3, X, 3175, 1, Z)," & -- PAD17 "3177 (BC_2, IO_G39, input, X)," & -- PAD17 "3178 (BC_2, *, controlr, 1)," & "3179 (BC_2, IO_H39, output3, X, 3178, 1, Z)," & -- PAD16 "3180 (BC_2, IO_H39, input, X)," & -- PAD16 "3181 (BC_2, *, controlr, 1)," & "3182 (BC_2, IO_H41, output3, X, 3181, 1, Z)," & -- PAD15 "3183 (BC_2, IO_H41, input, X)," & -- PAD15 "3184 (BC_2, *, controlr, 1)," & "3185 (BC_2, IO_H40, output3, X, 3184, 1, Z)," & -- PAD14 "3186 (BC_2, IO_H40, input, X)," & -- PAD14 "3187 (BC_2, *, controlr, 1)," & "3188 (BC_2, IO_C41, output3, X, 3187, 1, Z)," & -- PAD13 "3189 (BC_2, IO_C41, input, X)," & -- PAD13 "3190 (BC_2, *, controlr, 1)," & "3191 (BC_2, IO_C40, output3, X, 3190, 1, Z)," & -- PAD12 "3192 (BC_2, IO_C40, input, X)," & -- PAD12 "3193 (BC_2, *, controlr, 1)," & "3194 (BC_2, IO_E42, output3, X, 3193, 1, Z)," & -- PAD11 "3195 (BC_2, IO_E42, input, X)," & -- PAD11 "3196 (BC_2, *, controlr, 1)," & "3197 (BC_2, IO_F42, output3, X, 3196, 1, Z)," & -- PAD10 "3198 (BC_2, IO_F42, input, X)," & -- PAD10 "3199 (BC_2, *, controlr, 1)," & "3200 (BC_2, IO_B42, output3, X, 3199, 1, Z)," & -- PAD9 "3201 (BC_2, IO_B42, input, X)," & -- PAD9 "3202 (BC_2, *, controlr, 1)," & "3203 (BC_2, IO_B41, output3, X, 3202, 1, Z)," & -- PAD8 "3204 (BC_2, IO_B41, input, X)," & -- PAD8 "3205 (BC_2, *, controlr, 1)," & "3206 (BC_2, IO_D42, output3, X, 3205, 1, Z)," & -- PAD7 "3207 (BC_2, IO_D42, input, X)," & -- PAD7 "3208 (BC_2, *, controlr, 1)," & "3209 (BC_2, IO_D41, output3, X, 3208, 1, Z)," & -- PAD6 "3210 (BC_2, IO_D41, input, X)," & -- PAD6 "3211 (BC_2, *, controlr, 1)," & "3212 (BC_2, IO_A41, output3, X, 3211, 1, Z)," & -- PAD5 "3213 (BC_2, IO_A41, input, X)," & -- PAD5 "3214 (BC_2, *, controlr, 1)," & "3215 (BC_2, IO_A40, output3, X, 3214, 1, Z)," & -- PAD4 "3216 (BC_2, IO_A40, input, X)," & -- PAD4 "3217 (BC_2, *, controlr, 1)," & "3218 (BC_2, IO_D40, output3, X, 3217, 1, Z)," & -- PAD3 "3219 (BC_2, IO_D40, input, X)," & -- PAD3 "3220 (BC_2, *, controlr, 1)," & "3221 (BC_2, IO_E40, output3, X, 3220, 1, Z)," & -- PAD2 "3222 (BC_2, IO_E40, input, X)," & -- PAD2 "3223 (BC_2, *, controlr, 1)," & "3224 (BC_2, IO_L36, output3, X, 3223, 1, Z)," & -- PAD1 "3225 (BC_2, IO_L36, input, X)," & -- PAD1 "3226 (BC_2, *, internal, X)," & "3227 (BC_2, *, internal, X)," & "3228 (BC_2, *, internal, X)," & "3229 (BC_2, *, internal, X)," & "3230 (BC_2, *, internal, X)," & "3231 (BC_2, *, internal, X)," & "3232 (BC_2, *, internal, X)," & "3233 (BC_2, *, internal, X)," & "3234 (BC_2, *, internal, X)," & "3235 (BC_2, *, internal, X)," & "3236 (BC_2, *, internal, X)," & "3237 (BC_2, *, internal, X)," & "3238 (BC_2, *, internal, X)," & "3239 (BC_2, *, internal, X)," & "3240 (BC_2, *, internal, X)," & "3241 (BC_2, *, internal, X)," & "3242 (BC_2, *, internal, X)," & "3243 (BC_2, *, internal, X)," & "3244 (BC_2, *, internal, X)," & "3245 (BC_2, *, internal, X)," & "3246 (BC_2, *, internal, X)," & "3247 (BC_4, *, internal, X)," & "3248 (BC_4, *, internal, X)," & "3249 (BC_4, *, internal, X)," & "3250 (BC_4, *, internal, X)," & "3251 (BC_4, *, internal, X)," & "3252 (BC_4, *, internal, X)," & "3253 (BC_4, *, internal, X)," & "3254 (BC_4, *, internal, X)," & "3255 (BC_4, *, internal, X)," & "3256 (BC_4, *, internal, X)," & "3257 (BC_4, *, internal, X)," & "3258 (BC_4, *, internal, X)," & "3259 (BC_4, *, internal, X)," & "3260 (BC_4, *, internal, X)," & "3261 (BC_4, *, internal, X)," & "3262 (BC_4, *, internal, X)," & "3263 (BC_4, *, internal, X)," & "3264 (BC_4, *, internal, X)," & "3265 (BC_4, *, internal, X)," & "3266 (BC_4, *, internal, X)," & "3267 (BC_4, *, internal, X)," & "3268 (BC_4, *, internal, X)," & "3269 (BC_4, *, internal, X)," & "3270 (BC_4, *, internal, X)," & "3271 (BC_4, *, internal, X)," & "3272 (BC_4, *, internal, X)," & "3273 (BC_4, *, internal, X)," & "3274 (BC_4, *, internal, X)," & "3275 (BC_4, *, internal, X)," & "3276 (BC_4, *, internal, X)," & "3277 (BC_4, *, internal, X)," & "3278 (BC_4, *, internal, X)," & "3279 (BC_4, *, internal, X)," & "3280 (BC_4, *, internal, X)," & "3281 (BC_4, *, internal, X)," & "3282 (BC_4, *, internal, X)," & "3283 (BC_4, *, internal, X)," & "3284 (BC_4, *, internal, X)," & "3285 (BC_4, *, internal, X)," & "3286 (BC_4, *, internal, X)," & "3287 (BC_4, *, internal, X)," & "3288 (BC_4, *, internal, X)," & "3289 (BC_4, *, internal, X)," & "3290 (BC_4, *, internal, X)," & "3291 (BC_4, *, internal, X)," & "3292 (BC_4, *, internal, X)," & "3293 (BC_4, *, internal, X)," & "3294 (BC_4, *, internal, X)," & "3295 (BC_4, *, internal, X)," & "3296 (BC_4, *, internal, X)," & "3297 (BC_4, *, internal, X)," & "3298 (BC_4, *, internal, X)," & "3299 (BC_4, *, internal, X)," & "3300 (BC_4, *, internal, X)," & "3301 (BC_4, *, internal, X)," & "3302 (BC_4, *, internal, X)," & "3303 (BC_4, *, internal, X)," & "3304 (BC_4, *, internal, X)," & "3305 (BC_4, *, internal, X)," & "3306 (BC_4, *, internal, X)," & "3307 (BC_4, *, internal, X)," & "3308 (BC_4, *, internal, X)," & "3309 (BC_4, *, internal, X)," & "3310 (BC_4, *, internal, X)," & "3311 (BC_4, *, internal, X)," & "3312 (BC_4, *, internal, X)," & "3313 (BC_4, *, internal, X)," & "3314 (BC_4, *, internal, X)," & "3315 (BC_4, *, internal, X)," & "3316 (BC_4, *, internal, X)," & "3317 (BC_4, *, internal, X)," & "3318 (BC_4, *, internal, X)," & "3319 (BC_4, *, internal, X)," & "3320 (BC_4, *, internal, X)," & "3321 (BC_4, *, internal, X)," & "3322 (BC_4, *, internal, X)," & "3323 (BC_4, *, internal, X)," & "3324 (BC_4, *, internal, X)," & "3325 (BC_4, *, internal, X)," & "3326 (BC_4, *, internal, X)," & "3327 (BC_4, *, internal, X)," & "3328 (BC_4, *, internal, X)," & "3329 (BC_4, *, internal, X)," & "3330 (BC_4, *, internal, X)," & "3331 (BC_4, *, internal, X)," & "3332 (BC_4, *, internal, X)," & "3333 (BC_4, *, internal, X)," & "3334 (BC_4, *, internal, X)," & "3335 (BC_4, *, internal, X)," & "3336 (BC_4, *, internal, X)," & "3337 (BC_4, *, internal, X)," & "3338 (BC_4, *, internal, X)," & "3339 (BC_4, *, internal, X)," & "3340 (BC_4, *, internal, X)," & "3341 (BC_4, *, internal, X)," & "3342 (BC_4, *, internal, X)," & "3343 (BC_4, *, internal, X)," & "3344 (BC_4, *, internal, X)," & "3345 (BC_4, *, internal, X)," & "3346 (BC_4, *, internal, X)," & "3347 (BC_4, *, internal, X)," & "3348 (BC_4, *, internal, X)," & "3349 (BC_4, *, internal, X)," & "3350 (BC_4, *, internal, X)," & "3351 (BC_4, *, internal, X)," & "3352 (BC_4, *, internal, X)," & "3353 (BC_4, *, internal, X)," & "3354 (BC_4, *, internal, X)," & "3355 (BC_4, *, internal, X)," & "3356 (BC_4, *, internal, X)," & "3357 (BC_4, *, internal, X)," & "3358 (BC_4, *, internal, X)," & "3359 (BC_4, *, internal, X)," & "3360 (BC_4, *, internal, X)," & "3361 (BC_4, *, internal, X)," & "3362 (BC_4, *, internal, X)," & "3363 (BC_4, *, internal, X)," & "3364 (BC_4, *, internal, X)," & "3365 (BC_4, *, internal, X)," & "3366 (BC_4, *, internal, X)," & "3367 (BC_2, *, internal, X)," & "3368 (BC_2, *, internal, X)," & "3369 (BC_2, *, internal, X)," & "3370 (BC_2, *, internal, X)," & "3371 (BC_2, *, internal, X)," & "3372 (BC_2, *, internal, X)," & "3373 (BC_2, *, internal, X)," & "3374 (BC_2, *, internal, X)," & "3375 (BC_2, *, internal, X)," & "3376 (BC_2, *, internal, X)," & "3377 (BC_2, *, internal, X)," & "3378 (BC_2, *, internal, X)," & "3379 (BC_2, *, internal, X)," & "3380 (BC_2, *, internal, X)," & "3381 (BC_2, *, internal, X)," & "3382 (BC_2, *, internal, X)," & "3383 (BC_2, *, internal, X)," & "3384 (BC_2, *, internal, X)," & "3385 (BC_2, *, internal, X)," & "3386 (BC_2, *, internal, X)," & "3387 (BC_2, *, internal, X)," & "3388 (BC_2, *, internal, X)"; -- Advanced I/O Description attribute AIO_COMPONENT_CONFORMANCE of XC7VX690T_FFG1761 : entity is "STD_1149_6_2003"; attribute AIO_EXTEST_Pulse_Execution of XC7VX690T_FFG1761 : entity is "Wait_Duration TCK 15"; attribute AIO_EXTEST_Train_Execution of XC7VX690T_FFG1761 : entity is "train 30, maximum_time 120.0e-6"; attribute AIO_Pin_Behavior of XC7VX690T_FFG1761 : entity is "MGTHRXP0_111 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_112 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP0_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_111 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_112 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP1_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_111 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_112 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP2_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_111 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_112 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_113 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_114 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_115 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_116 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_117 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_118 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHRXP3_119 : LP_time=22.5e-9 HP_time=45.0e-9; " & "MGTHTXP0_111; " & "MGTHTXP0_112; " & "MGTHTXP0_113; " & "MGTHTXP0_114; " & "MGTHTXP0_115; " & "MGTHTXP0_116; " & "MGTHTXP0_117; " & "MGTHTXP0_118; " & "MGTHTXP0_119; " & "MGTHTXP1_111; " & "MGTHTXP1_112; " & "MGTHTXP1_113; " & "MGTHTXP1_114; " & "MGTHTXP1_115; " & "MGTHTXP1_116; " & "MGTHTXP1_117; " & "MGTHTXP1_118; " & "MGTHTXP1_119; " & "MGTHTXP2_111; " & "MGTHTXP2_112; " & "MGTHTXP2_113; " & "MGTHTXP2_114; " & "MGTHTXP2_115; " & "MGTHTXP2_116; " & "MGTHTXP2_117; " & "MGTHTXP2_118; " & "MGTHTXP2_119; " & "MGTHTXP3_111; " & "MGTHTXP3_112; " & "MGTHTXP3_113; " & "MGTHTXP3_114; " & "MGTHTXP3_115; " & "MGTHTXP3_116; " & "MGTHTXP3_117; " & "MGTHTXP3_118; " & "MGTHTXP3_119 "; -- Design Warning Section attribute DESIGN_WARNING of XC7VX690T_FFG1761 : entity is "When no bitstream is loaded and GTPs are not instantiated," & "the boundary-scan cells associated with GTPs will not" & "capture correct state information. To model the boundary-" & "scan cell behavior correctly post-configuration, use" & "BSDLanno to modify the BSDL file." & "This BSDL file must be modified by the FPGA designer in order to" & "reflect post-configuration behavior (if any)." & "To avoid losing the current configuration, the boundary scan" & "test vectors should keep the PROGRAM_B pin" & "high. If the PROGRAM_B pin goes low by any means," & "the configuration will be cleared." & "PROGRAM_B can only be captured, not updated." & "The value at the pin is always used by the device." & "In EXTEST, output and tristate values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "Differential Serial IO pins do not support INTEST." & "In INTEST, the pin input values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "The output and tristate capture values are not valid until after" & "the device is configured." & "The tristate control value is not captured properly when" & "GTS is activated." & "The IEEE Std 1149.6 EXTEST_PULSE and EXTEST_TRAIN instructions" & "require a minimum TCK freq of 15 MHz and min temp of 0C." & "NOCONNECT pins should not be connected to any supply" & "or GND. They should be left floating."; end XC7VX690T_FFG1761; ================================================ FILE: jtag/bsd/xc7z020_clg484.bsd ================================================ -- (c) Copyright 2010 - 2011 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- releated to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitiations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. -- -- BSDL file for device XC7Z020, package CLG484 -- Generated by bsdlnet Version 1.10 -- Generated on Fri Apr 06, 2012 09:30:32 IST -- Generated using schematic at v32_top/xc7z020/schematic -- Schematic date = 2011-08-03 17:24:25 -- Schematic ICM_VARIANT = 28t_n1 -- Package File date = # Date : 2011-09-22 10:22:08 ------------------------------------------------------------------------ -- Modification History -- | CR # N/A -- | Details - Initial Release ------------------------------------------------------------------------ -- -- For technical support, http://support.xilinx.com -> enter text 'bsdl' -- in the text search box at the left of the page. If none of -- these records resolve your problem you should open a web support case -- or contact our technical support at: -- -- North America 1-800-255-7778 hotline@xilinx.com -- United Kingdom +44 870 7350 610 eurosupport@xilinx.com -- France (33) 1 3463 0100 eurosupport@xilinx.com -- Germany (49) 89 991 54930 eurosupport@xilinx.com -- Japan (81) 3-3297-9163 jhotline@xilinx.com -- -- This BSDL file reflects the pre-configuration JTAG behavior. To reflect -- the post-configuration JTAG behavior (if any), edit this file as described -- below. Many of these changes are demonstrated by commented-out template -- lines preceeding the lines they would replace: -- -- 1. Enable USER instructions as appropriate (see below). -- 2. Set disable result of all pads as configured. -- 3. Set safe state of boundary cells as necessary. -- 4. Rename entity if necessary to avoid name collisions. -- 5. Modify USERCODE value in USERCODE_REGISTER declaration. -- -- To prevent losing the current configuration, the boundary scan -- test vectors should keep the PROGRAM_B pin high. -- -- PROGRAM_B can only be captured, not updated. The value -- at the pin is always used by the device. -- -- All IOBs prior to configuration, and unused and output-only IOBs following -- configuration, will sense their pad values during boundary-scan with an CMOS -- input buffer. In order to properly capture a logic high value at one -- of these IOBs into its input boundary scan cell, please refer to the -- datasheet and user guide for proper input levels. -- -- For post-configuration boundary scan only: If an IOB is configured to use -- an input standard that uses VREF pins, then the boundary scan test vectors -- must keep the used VREF pins 3-stated. ---------------------------------- -- BSDL File for P1149.6 Standard. ---------------------------------- -- ---------------------------------------------------------------------- -- This BSDL file has been checked and verified by JTAG Technologies B.V. -- on 2012-04-09, for syntactical and semantic compliance with -- IEEE standards 1149.1 and 1149.6 -- using bsdl32.dll 1.6.1.5 - 20110523 Win32 -- copyright (c) 2009 JTAG Technologies B.V., All rights reserved -- ---------------------------------------------------------------------- entity XC7Z020_CLG484 is -- Generic Parameter generic (PHYSICAL_PIN_MAP : string := "CLG484" ); -- Logical Port Description port ( RSVDGND_G10: inout bit; -- RSVDGND_0 CFGBVS_T13: in bit; -- CFGBVS_0 DONE_T12: inout bit; -- DONE_0 GND: linkage bit_vector (1 to 63); GNDADC_0: linkage bit; INIT_B_T14: inout bit; -- INIT_B_0 RSVD0VCC_T10: in bit; -- RSVD0VCC_0 RSVD1VCC_T8: in bit; -- RSVD1VCC_0 RSVD2VCC_T7: in bit; -- RSVD2VCC_0 PROGRAM_B: in bit; -- PROGRAM_B_0 PS_CLK: in bit; PS_DDR_A0: inout bit; PS_DDR_A1: inout bit; PS_DDR_A10: inout bit; PS_DDR_A11: inout bit; PS_DDR_A12: inout bit; PS_DDR_A13: inout bit; PS_DDR_A14: inout bit; PS_DDR_A2: inout bit; PS_DDR_A3: inout bit; PS_DDR_A4: inout bit; PS_DDR_A5: inout bit; PS_DDR_A6: inout bit; PS_DDR_A7: inout bit; PS_DDR_A8: inout bit; PS_DDR_A9: inout bit; PS_DDR_BA0: inout bit; PS_DDR_BA1: inout bit; PS_DDR_BA2: inout bit; PS_DDR_CAS_B: inout bit; PS_DDR_CKE: inout bit; PS_DDR_CKN: inout bit; PS_DDR_CKP: inout bit; PS_DDR_CS_B: inout bit; PS_DDR_DM0: inout bit; PS_DDR_DM1: inout bit; PS_DDR_DM2: inout bit; PS_DDR_DM3: inout bit; PS_DDR_DQ0: inout bit; PS_DDR_DQ1: inout bit; PS_DDR_DQ10: inout bit; PS_DDR_DQ11: inout bit; PS_DDR_DQ12: inout bit; PS_DDR_DQ13: inout bit; PS_DDR_DQ14: inout bit; PS_DDR_DQ15: inout bit; PS_DDR_DQ16: inout bit; PS_DDR_DQ17: inout bit; PS_DDR_DQ18: inout bit; PS_DDR_DQ19: inout bit; PS_DDR_DQ2: inout bit; PS_DDR_DQ20: inout bit; PS_DDR_DQ21: inout bit; PS_DDR_DQ22: inout bit; PS_DDR_DQ23: inout bit; PS_DDR_DQ24: inout bit; PS_DDR_DQ25: inout bit; PS_DDR_DQ26: inout bit; PS_DDR_DQ27: inout bit; PS_DDR_DQ28: inout bit; PS_DDR_DQ29: inout bit; PS_DDR_DQ3: inout bit; PS_DDR_DQ30: inout bit; PS_DDR_DQ31: inout bit; PS_DDR_DQ4: inout bit; PS_DDR_DQ5: inout bit; PS_DDR_DQ6: inout bit; PS_DDR_DQ7: inout bit; PS_DDR_DQ8: inout bit; PS_DDR_DQ9: inout bit; PS_DDR_DQS_N0: inout bit; PS_DDR_DQS_N1: inout bit; PS_DDR_DQS_N2: inout bit; PS_DDR_DQS_N3: inout bit; PS_DDR_DQS_P0: inout bit; PS_DDR_DQS_P1: inout bit; PS_DDR_DQS_P2: inout bit; PS_DDR_DQS_P3: inout bit; PS_DDR_DRST_B: inout bit; PS_DDR_ODT: inout bit; PS_DDR_RAS_B: inout bit; PS_DDR_VREF0_502: linkage bit; PS_DDR_VREF1_502: linkage bit; PS_DDR_VRN: inout bit; PS_DDR_VRP: inout bit; PS_DDR_WE_B: inout bit; PS_MIO0: inout bit; PS_MIO1: inout bit; PS_MIO10: inout bit; PS_MIO11: inout bit; PS_MIO12: inout bit; PS_MIO13: inout bit; PS_MIO14: inout bit; PS_MIO15: inout bit; PS_MIO16: inout bit; PS_MIO17: inout bit; PS_MIO18: inout bit; PS_MIO19: inout bit; PS_MIO2: inout bit; PS_MIO20: inout bit; PS_MIO21: inout bit; PS_MIO22: inout bit; PS_MIO23: inout bit; PS_MIO24: inout bit; PS_MIO25: inout bit; PS_MIO26: inout bit; PS_MIO27: inout bit; PS_MIO28: inout bit; PS_MIO29: inout bit; PS_MIO3: inout bit; PS_MIO30: inout bit; PS_MIO31: inout bit; PS_MIO32: inout bit; PS_MIO33: inout bit; PS_MIO34: inout bit; PS_MIO35: inout bit; PS_MIO36: inout bit; PS_MIO37: inout bit; PS_MIO38: inout bit; PS_MIO39: inout bit; PS_MIO4: inout bit; PS_MIO40: inout bit; PS_MIO41: inout bit; PS_MIO42: inout bit; PS_MIO43: inout bit; PS_MIO44: inout bit; PS_MIO45: inout bit; PS_MIO46: inout bit; PS_MIO47: inout bit; PS_MIO48: inout bit; PS_MIO49: inout bit; PS_MIO5: inout bit; PS_MIO50: inout bit; PS_MIO51: inout bit; PS_MIO52: inout bit; PS_MIO53: inout bit; PS_MIO6: inout bit; PS_MIO7: inout bit; PS_MIO8: inout bit; PS_MIO9: inout bit; PS_MIO_VREF: in bit; PS_POR_B: in bit; PS_SRST_B: in bit; TCK: in bit; -- TCK_0 TDI: in bit; -- TDI_0 TDN_N12: linkage bit; -- DXN_0 TDO: out bit; -- TDO_0 TDP_N11: linkage bit; -- DXP_0 TMS: in bit; -- TMS_0 VCCADC_0: linkage bit; VCCAUX: linkage bit_vector (1 to 4); VCCBATT_0: linkage bit; VCCBRAM: linkage bit_vector (1 to 2); VCCINT: linkage bit_vector (1 to 8); VCCO_0: linkage bit; VCCO_13: linkage bit_vector (1 to 7); VCCO_33: linkage bit_vector (1 to 6); VCCO_34: linkage bit_vector (1 to 6); VCCO_35: linkage bit_vector (1 to 7); VCCO_DDR_502: linkage bit_vector (1 to 9); VCCO_MIO0_500: linkage bit_vector (1 to 2); VCCO_MIO1_501: linkage bit_vector (1 to 4); VCCPAUX: linkage bit_vector (1 to 4); VCCPINT: linkage bit_vector (1 to 6); VCCPLL: linkage bit; VN_M12: linkage bit; -- VN_0 VP_L11: linkage bit; -- VP_0 VREFN_L12: linkage bit; -- VREFN_0 VREFP_M11: linkage bit; -- VREFP_0 IO_A16: inout bit; -- PAD68 IO_A17: inout bit; -- PAD69 IO_A18: inout bit; -- PAD70 IO_A19: inout bit; -- PAD71 IO_A21: inout bit; -- PAD80 IO_A22: inout bit; -- PAD81 IO_B15: inout bit; -- PAD65 IO_B16: inout bit; -- PAD66 IO_B17: inout bit; -- PAD67 IO_B19: inout bit; -- PAD76 IO_B20: inout bit; -- PAD77 IO_B21: inout bit; -- PAD86 IO_B22: inout bit; -- PAD87 IO_C15: inout bit; -- PAD64 IO_C17: inout bit; -- PAD72 IO_C18: inout bit; -- PAD73 IO_C19: inout bit; -- PAD75 IO_C20: inout bit; -- PAD79 IO_C22: inout bit; -- PAD83 IO_D15: inout bit; -- PAD57 IO_D16: inout bit; -- PAD54 IO_D17: inout bit; -- PAD55 IO_D18: inout bit; -- PAD74 IO_D20: inout bit; -- PAD78 IO_D21: inout bit; -- PAD85 IO_D22: inout bit; -- PAD82 IO_E15: inout bit; -- PAD56 IO_E16: inout bit; -- PAD53 IO_E18: inout bit; -- PAD61 IO_E19: inout bit; -- PAD92 IO_E20: inout bit; -- PAD93 IO_E21: inout bit; -- PAD84 IO_F16: inout bit; -- PAD52 IO_F17: inout bit; -- PAD63 IO_F18: inout bit; -- PAD60 IO_F19: inout bit; -- PAD91 IO_F21: inout bit; -- PAD96 IO_F22: inout bit; -- PAD97 IO_G15: inout bit; -- PAD58 IO_G16: inout bit; -- PAD59 IO_G17: inout bit; -- PAD62 IO_G19: inout bit; -- PAD90 IO_G20: inout bit; -- PAD94 IO_G21: inout bit; -- PAD95 IO_G22: inout bit; -- PAD99 IO_H15: inout bit; -- PAD101 IO_H17: inout bit; -- PAD51 IO_H18: inout bit; -- PAD100 IO_H19: inout bit; -- PAD88 IO_H20: inout bit; -- PAD89 IO_H22: inout bit; -- PAD98 IO_J15: inout bit; -- PAD102 IO_J16: inout bit; -- PAD104 IO_J17: inout bit; -- PAD105 IO_J18: inout bit; -- PAD114 IO_J20: inout bit; -- PAD118 IO_J21: inout bit; -- PAD116 IO_J22: inout bit; -- PAD117 IO_K15: inout bit; -- PAD103 IO_K16: inout bit; -- PAD106 IO_K18: inout bit; -- PAD115 IO_K19: inout bit; -- PAD122 IO_K20: inout bit; -- PAD123 IO_K21: inout bit; -- PAD119 IO_L16: inout bit; -- PAD107 IO_L17: inout bit; -- PAD108 IO_L18: inout bit; -- PAD124 IO_L19: inout bit; -- PAD125 IO_L21: inout bit; -- PAD120 IO_L22: inout bit; -- PAD121 IO_M15: inout bit; -- PAD112 IO_M16: inout bit; -- PAD113 IO_M17: inout bit; -- PAD109 IO_M19: inout bit; -- PAD126 IO_M20: inout bit; -- PAD127 IO_M21: inout bit; -- PAD130 IO_M22: inout bit; -- PAD131 IO_N15: inout bit; -- PAD138 IO_N17: inout bit; -- PAD110 IO_N18: inout bit; -- PAD111 IO_N19: inout bit; -- PAD128 IO_N20: inout bit; -- PAD129 IO_N22: inout bit; -- PAD132 IO_P15: inout bit; -- PAD139 IO_P16: inout bit; -- PAD148 IO_P17: inout bit; -- PAD140 IO_P18: inout bit; -- PAD141 IO_P20: inout bit; -- PAD136 IO_P21: inout bit; -- PAD137 IO_P22: inout bit; -- PAD133 IO_R6: inout bit; -- PAD38 IO_R7: inout bit; -- PAD1 IO_R15: inout bit; -- PAD150 IO_R16: inout bit; -- PAD149 IO_R18: inout bit; -- PAD146 IO_R19: inout bit; -- PAD144 IO_R20: inout bit; -- PAD134 IO_R21: inout bit; -- PAD135 IO_T4: inout bit; -- PAD40 IO_T6: inout bit; -- PAD39 IO_T16: inout bit; -- PAD142 IO_T17: inout bit; -- PAD143 IO_T18: inout bit; -- PAD147 IO_T19: inout bit; -- PAD145 IO_T21: inout bit; -- PAD152 IO_T22: inout bit; -- PAD154 IO_U4: inout bit; -- PAD41 IO_U5: inout bit; -- PAD45 IO_U6: inout bit; -- PAD44 IO_U7: inout bit; -- PAD50 IO_U9: inout bit; -- PAD13 IO_U10: inout bit; -- PAD12 IO_U11: inout bit; -- PAD11 IO_U12: inout bit; -- PAD10 IO_U14: inout bit; -- PAD200 IO_U15: inout bit; -- PAD180 IO_U16: inout bit; -- PAD181 IO_U17: inout bit; -- PAD182 IO_U19: inout bit; -- PAD151 IO_U20: inout bit; -- PAD160 IO_U21: inout bit; -- PAD153 IO_U22: inout bit; -- PAD155 IO_V4: inout bit; -- PAD43 IO_V5: inout bit; -- PAD42 IO_V7: inout bit; -- PAD46 IO_V8: inout bit; -- PAD4 IO_V9: inout bit; -- PAD3 IO_V10: inout bit; -- PAD2 IO_V12: inout bit; -- PAD8 IO_V13: inout bit; -- PAD190 IO_V14: inout bit; -- PAD188 IO_V15: inout bit; -- PAD189 IO_V17: inout bit; -- PAD183 IO_V18: inout bit; -- PAD162 IO_V19: inout bit; -- PAD163 IO_V20: inout bit; -- PAD161 IO_V22: inout bit; -- PAD156 IO_W5: inout bit; -- PAD49 IO_W6: inout bit; -- PAD48 IO_W7: inout bit; -- PAD47 IO_W8: inout bit; -- PAD5 IO_W10: inout bit; -- PAD7 IO_W11: inout bit; -- PAD6 IO_W12: inout bit; -- PAD9 IO_W13: inout bit; -- PAD191 IO_W15: inout bit; -- PAD192 IO_W16: inout bit; -- PAD178 IO_W17: inout bit; -- PAD176 IO_W18: inout bit; -- PAD177 IO_W20: inout bit; -- PAD158 IO_W21: inout bit; -- PAD159 IO_W22: inout bit; -- PAD157 IO_Y4: inout bit; -- PAD36 IO_Y5: inout bit; -- PAD27 IO_Y6: inout bit; -- PAD26 IO_Y8: inout bit; -- PAD25 IO_Y9: inout bit; -- PAD24 IO_Y10: inout bit; -- PAD21 IO_Y11: inout bit; -- PAD20 IO_Y13: inout bit; -- PAD196 IO_Y14: inout bit; -- PAD194 IO_Y15: inout bit; -- PAD193 IO_Y16: inout bit; -- PAD179 IO_Y18: inout bit; -- PAD174 IO_Y19: inout bit; -- PAD172 IO_Y20: inout bit; -- PAD168 IO_Y21: inout bit; -- PAD169 IO_AA4: inout bit; -- PAD37 IO_AA6: inout bit; -- PAD29 IO_AA7: inout bit; -- PAD28 IO_AA8: inout bit; -- PAD23 IO_AA9: inout bit; -- PAD22 IO_AA11: inout bit; -- PAD16 IO_AA12: inout bit; -- PAD14 IO_AA13: inout bit; -- PAD197 IO_AA14: inout bit; -- PAD195 IO_AA16: inout bit; -- PAD186 IO_AA17: inout bit; -- PAD184 IO_AA18: inout bit; -- PAD175 IO_AA19: inout bit; -- PAD173 IO_AA21: inout bit; -- PAD166 IO_AA22: inout bit; -- PAD164 IO_AB1: inout bit; -- PAD31 IO_AB2: inout bit; -- PAD30 IO_AB4: inout bit; -- PAD33 IO_AB5: inout bit; -- PAD32 IO_AB6: inout bit; -- PAD35 IO_AB7: inout bit; -- PAD34 IO_AB9: inout bit; -- PAD19 IO_AB10: inout bit; -- PAD18 IO_AB11: inout bit; -- PAD17 IO_AB12: inout bit; -- PAD15 IO_AB14: inout bit; -- PAD198 IO_AB15: inout bit; -- PAD199 IO_AB16: inout bit; -- PAD187 IO_AB17: inout bit; -- PAD185 IO_AB19: inout bit; -- PAD170 IO_AB20: inout bit; -- PAD171 IO_AB21: inout bit; -- PAD167 IO_AB22: inout bit -- PAD165 ); --end port list -- Use Statements use STD_1149_1_2001.all; use STD_1149_6_2003.all; -- Component Conformance Statement(s) attribute COMPONENT_CONFORMANCE of XC7Z020_CLG484 : entity is "STD_1149_1_2001"; -- Device Package Pin Mappings attribute PIN_MAP of XC7Z020_CLG484 : entity is PHYSICAL_PIN_MAP; constant CLG484: PIN_MAP_STRING:= "RSVDGND_G10:G10," & "CFGBVS_T13:T13," & "DONE_T12:T12," & "GND:(A5,A15,B8,B18,C1,C11,C21,D4,D14,E7," & "E17,F10,F20,G3,H6,H8,H12,H14,H16,J9," & "J11,J13,J19,K2,K8,K10,K14,K22,L5,L9," & "L13,L15,M8,M10,M14,M18,N1,N9,N13,N21," & "P4,P8,P10,P12,P14,R9,R11,R13,R17,T20," & "U3,U13,V6,V16,W9,W19,Y2,Y12,Y22,AA5," & "AA15,AB8,AB18)," & "GNDADC_0:K12," & "INIT_B_T14:T14," & "RSVD0VCC_T10:T10," & "RSVD1VCC_T8:T8," & "RSVD2VCC_T7:T7," & "PROGRAM_B:T11," & "PS_CLK:F7," & "PS_DDR_A0:M4," & "PS_DDR_A1:M5," & "PS_DDR_A10:J3," & "PS_DDR_A11:G5," & "PS_DDR_A12:H4," & "PS_DDR_A13:F4," & "PS_DDR_A14:G4," & "PS_DDR_A2:K4," & "PS_DDR_A3:L4," & "PS_DDR_A4:K6," & "PS_DDR_A5:K5," & "PS_DDR_A6:J7," & "PS_DDR_A7:J6," & "PS_DDR_A8:J5," & "PS_DDR_A9:H5," & "PS_DDR_BA0:L7," & "PS_DDR_BA1:L6," & "PS_DDR_BA2:M6," & "PS_DDR_CAS_B:P3," & "PS_DDR_CKE:V3," & "PS_DDR_CKN:N5," & "PS_DDR_CKP:N4," & "PS_DDR_CS_B:P6," & "PS_DDR_DM0:B1," & "PS_DDR_DM1:H3," & "PS_DDR_DM2:P1," & "PS_DDR_DM3:AA2," & "PS_DDR_DQ0:D1," & "PS_DDR_DQ1:C3," & "PS_DDR_DQ10:L1," & "PS_DDR_DQ11:L2," & "PS_DDR_DQ12:L3," & "PS_DDR_DQ13:K1," & "PS_DDR_DQ14:J1," & "PS_DDR_DQ15:K3," & "PS_DDR_DQ16:M1," & "PS_DDR_DQ17:T3," & "PS_DDR_DQ18:N3," & "PS_DDR_DQ19:T1," & "PS_DDR_DQ2:B2," & "PS_DDR_DQ20:R3," & "PS_DDR_DQ21:T2," & "PS_DDR_DQ22:M2," & "PS_DDR_DQ23:R1," & "PS_DDR_DQ24:AA3," & "PS_DDR_DQ25:U1," & "PS_DDR_DQ26:AA1," & "PS_DDR_DQ27:U2," & "PS_DDR_DQ28:W1," & "PS_DDR_DQ29:Y3," & "PS_DDR_DQ3:D3," & "PS_DDR_DQ30:W3," & "PS_DDR_DQ31:Y1," & "PS_DDR_DQ4:E3," & "PS_DDR_DQ5:E1," & "PS_DDR_DQ6:F2," & "PS_DDR_DQ7:F1," & "PS_DDR_DQ8:G2," & "PS_DDR_DQ9:G1," & "PS_DDR_DQS_N0:D2," & "PS_DDR_DQS_N1:J2," & "PS_DDR_DQS_N2:P2," & "PS_DDR_DQS_N3:W2," & "PS_DDR_DQS_P0:C2," & "PS_DDR_DQS_P1:H2," & "PS_DDR_DQS_P2:N2," & "PS_DDR_DQS_P3:V2," & "PS_DDR_DRST_B:F3," & "PS_DDR_ODT:P5," & "PS_DDR_RAS_B:R5," & "PS_DDR_VREF0_502:H7," & "PS_DDR_VREF1_502:P7," & "PS_DDR_VRN:M7," & "PS_DDR_VRP:N7," & "PS_DDR_WE_B:R4," & "PS_MIO0:G6," & "PS_MIO1:A1," & "PS_MIO10:G7," & "PS_MIO11:B4," & "PS_MIO12:C5," & "PS_MIO13:A6," & "PS_MIO14:B6," & "PS_MIO15:E6," & "PS_MIO16:D6," & "PS_MIO17:E9," & "PS_MIO18:A7," & "PS_MIO19:E10," & "PS_MIO2:A2," & "PS_MIO20:A8," & "PS_MIO21:F11," & "PS_MIO22:A14," & "PS_MIO23:E11," & "PS_MIO24:B7," & "PS_MIO25:F12," & "PS_MIO26:A13," & "PS_MIO27:D7," & "PS_MIO28:A12," & "PS_MIO29:E8," & "PS_MIO3:F6," & "PS_MIO30:A11," & "PS_MIO31:F9," & "PS_MIO32:C7," & "PS_MIO33:G13," & "PS_MIO34:B12," & "PS_MIO35:F14," & "PS_MIO36:A9," & "PS_MIO37:B14," & "PS_MIO38:F13," & "PS_MIO39:C13," & "PS_MIO4:E4," & "PS_MIO40:E14," & "PS_MIO41:C8," & "PS_MIO42:D8," & "PS_MIO43:B11," & "PS_MIO44:E13," & "PS_MIO45:B9," & "PS_MIO46:D12," & "PS_MIO47:B10," & "PS_MIO48:D11," & "PS_MIO49:C14," & "PS_MIO5:A3," & "PS_MIO50:D13," & "PS_MIO51:C10," & "PS_MIO52:D10," & "PS_MIO53:C12," & "PS_MIO6:A4," & "PS_MIO7:D5," & "PS_MIO8:E5," & "PS_MIO9:C4," & "PS_MIO_VREF:F8," & "PS_POR_B:B5," & "PS_SRST_B:C9," & "TCK:G11," & "TDI:H13," & "TDN_N12:N12," & "TDO:G14," & "TDP_N11:N11," & "TMS:G12," & "VCCADC_0:K11," & "VCCAUX:(L10,N10,P11,R10)," & "VCCBATT_0:G9," & "VCCBRAM:(H11,J10)," & "VCCINT:(J12,J14,K13,L14,M13,N14,P13,R14)," & "VCCO_0:R12," & "VCCO_13:(T5,U8,V11,W4,Y7,AA10,AB3)," & "VCCO_33:(U18,V21,W14,Y17,AA20,AB13)," & "VCCO_34:(K17,L20,N16,P19,R22,T15)," & "VCCO_35:(A20,C16,D19,E22,F15,G18,H21)," & "VCCO_DDR_502:(E2,F5,H1,J4,K7,M3,N6,R2,V1)," & "VCCO_MIO0_500:(B3,C6)," & "VCCO_MIO1_501:(A10,B13,D9,E12)," & "VCCPAUX:(K9,M9,P9,T9)," & "VCCPINT:(G8,H9,J8,L8,N8,R8)," & "VCCPLL:H10," & "VN_M12:M12," & "VP_L11:L11," & "VREFN_L12:L12," & "VREFP_M11:M11," & "IO_A16:A16," & "IO_A17:A17," & "IO_A18:A18," & "IO_A19:A19," & "IO_A21:A21," & "IO_A22:A22," & "IO_B15:B15," & "IO_B16:B16," & "IO_B17:B17," & "IO_B19:B19," & "IO_B20:B20," & "IO_B21:B21," & "IO_B22:B22," & "IO_C15:C15," & "IO_C17:C17," & "IO_C18:C18," & "IO_C19:C19," & "IO_C20:C20," & "IO_C22:C22," & "IO_D15:D15," & "IO_D16:D16," & "IO_D17:D17," & "IO_D18:D18," & "IO_D20:D20," & "IO_D21:D21," & "IO_D22:D22," & "IO_E15:E15," & "IO_E16:E16," & "IO_E18:E18," & "IO_E19:E19," & "IO_E20:E20," & "IO_E21:E21," & "IO_F16:F16," & "IO_F17:F17," & "IO_F18:F18," & "IO_F19:F19," & "IO_F21:F21," & "IO_F22:F22," & "IO_G15:G15," & "IO_G16:G16," & "IO_G17:G17," & "IO_G19:G19," & "IO_G20:G20," & "IO_G21:G21," & "IO_G22:G22," & "IO_H15:H15," & "IO_H17:H17," & "IO_H18:H18," & "IO_H19:H19," & "IO_H20:H20," & "IO_H22:H22," & "IO_J15:J15," & "IO_J16:J16," & "IO_J17:J17," & "IO_J18:J18," & "IO_J20:J20," & "IO_J21:J21," & "IO_J22:J22," & "IO_K15:K15," & "IO_K16:K16," & "IO_K18:K18," & "IO_K19:K19," & "IO_K20:K20," & "IO_K21:K21," & "IO_L16:L16," & "IO_L17:L17," & "IO_L18:L18," & "IO_L19:L19," & "IO_L21:L21," & "IO_L22:L22," & "IO_M15:M15," & "IO_M16:M16," & "IO_M17:M17," & "IO_M19:M19," & "IO_M20:M20," & "IO_M21:M21," & "IO_M22:M22," & "IO_N15:N15," & "IO_N17:N17," & "IO_N18:N18," & "IO_N19:N19," & "IO_N20:N20," & "IO_N22:N22," & "IO_P15:P15," & "IO_P16:P16," & "IO_P17:P17," & "IO_P18:P18," & "IO_P20:P20," & "IO_P21:P21," & "IO_P22:P22," & "IO_R6:R6," & "IO_R7:R7," & "IO_R15:R15," & "IO_R16:R16," & "IO_R18:R18," & "IO_R19:R19," & "IO_R20:R20," & "IO_R21:R21," & "IO_T4:T4," & "IO_T6:T6," & "IO_T16:T16," & "IO_T17:T17," & "IO_T18:T18," & "IO_T19:T19," & "IO_T21:T21," & "IO_T22:T22," & "IO_U4:U4," & "IO_U5:U5," & "IO_U6:U6," & "IO_U7:U7," & "IO_U9:U9," & "IO_U10:U10," & "IO_U11:U11," & "IO_U12:U12," & "IO_U14:U14," & "IO_U15:U15," & "IO_U16:U16," & "IO_U17:U17," & "IO_U19:U19," & "IO_U20:U20," & "IO_U21:U21," & "IO_U22:U22," & "IO_V4:V4," & "IO_V5:V5," & "IO_V7:V7," & "IO_V8:V8," & "IO_V9:V9," & "IO_V10:V10," & "IO_V12:V12," & "IO_V13:V13," & "IO_V14:V14," & "IO_V15:V15," & "IO_V17:V17," & "IO_V18:V18," & "IO_V19:V19," & "IO_V20:V20," & "IO_V22:V22," & "IO_W5:W5," & "IO_W6:W6," & "IO_W7:W7," & "IO_W8:W8," & "IO_W10:W10," & "IO_W11:W11," & "IO_W12:W12," & "IO_W13:W13," & "IO_W15:W15," & "IO_W16:W16," & "IO_W17:W17," & "IO_W18:W18," & "IO_W20:W20," & "IO_W21:W21," & "IO_W22:W22," & "IO_Y4:Y4," & "IO_Y5:Y5," & "IO_Y6:Y6," & "IO_Y8:Y8," & "IO_Y9:Y9," & "IO_Y10:Y10," & "IO_Y11:Y11," & "IO_Y13:Y13," & "IO_Y14:Y14," & "IO_Y15:Y15," & "IO_Y16:Y16," & "IO_Y18:Y18," & "IO_Y19:Y19," & "IO_Y20:Y20," & "IO_Y21:Y21," & "IO_AA4:AA4," & "IO_AA6:AA6," & "IO_AA7:AA7," & "IO_AA8:AA8," & "IO_AA9:AA9," & "IO_AA11:AA11," & "IO_AA12:AA12," & "IO_AA13:AA13," & "IO_AA14:AA14," & "IO_AA16:AA16," & "IO_AA17:AA17," & "IO_AA18:AA18," & "IO_AA19:AA19," & "IO_AA21:AA21," & "IO_AA22:AA22," & "IO_AB1:AB1," & "IO_AB2:AB2," & "IO_AB4:AB4," & "IO_AB5:AB5," & "IO_AB6:AB6," & "IO_AB7:AB7," & "IO_AB9:AB9," & "IO_AB10:AB10," & "IO_AB11:AB11," & "IO_AB12:AB12," & "IO_AB14:AB14," & "IO_AB15:AB15," & "IO_AB16:AB16," & "IO_AB17:AB17," & "IO_AB19:AB19," & "IO_AB20:AB20," & "IO_AB21:AB21," & "IO_AB22:AB22"; -- Grouped Port Identification -- Scan Port Identification attribute TAP_SCAN_IN of TDI : signal is true; attribute TAP_SCAN_MODE of TMS : signal is true; attribute TAP_SCAN_OUT of TDO : signal is true; attribute TAP_SCAN_CLOCK of TCK : signal is (66.0e6, BOTH); -- Compliance-Enable Description attribute COMPLIANCE_PATTERNS of XC7Z020_CLG484 : entity is "(PROGRAM_B) (1)"; -- Instruction Register Description attribute INSTRUCTION_LENGTH of XC7Z020_CLG484 : entity is 6; attribute INSTRUCTION_OPCODE of XC7Z020_CLG484 : entity is "IDCODE (001001)," & -- DEVICE_ID "BYPASS (111111)," & -- BYPASS "EXTEST (100110)," & -- BOUNDARY "SAMPLE (000001)," & -- BOUNDARY "PRELOAD (000001)," & -- Same as SAMPLE "USERCODE (001000)," & -- DEVICE_ID "HIGHZ (001010)," & -- BYPASS "EXTEST_PULSE (111100)," & -- BOUNDARY "EXTEST_TRAIN (111101)," & -- BOUNDARY "ISC_ENABLE (010000)," & -- ISC_CONFIG "ISC_PROGRAM (010001)," & -- ISC_PDATA "ISC_NOOP (010100)," & -- ISC_DEFAULT "XSC_READ_RSVD (010101)," & -- PRIVATE "ISC_DISABLE (010110)," & -- ISC_CONFIG "XSC_PROGRAM_KEY (010010)," & -- XSC_KEY_DATA "XSC_DNA (010111)," & -- DNA "CFG_OUT (000100)," & -- Not available during configuration with another mode. "CFG_IN (000101)," & -- Not available during configuration with another mode. "JPROGRAM (001011)," & -- Not available during configuration with another mode. "JSTART (001100)," & -- Not available during configuration with another mode. "JSHUTDOWN (001101)," & -- Not available during configuration with another mode. "FUSE_CTS (110000)," & -- PRIVATE "FUSE_KEY (110001)," & -- PRIVATE "FUSE_DNA (110010)," & -- PRIVATE "FUSE_USER (110011)," & -- PRIVATE "FUSE_CNTL (110100)," & -- PRIVATE "USER1 (000010)," & -- Not available until after configuration "USER2 (000011)," & -- Not available until after configuration "USER3 (100010)," & -- Not available until after configuration "USER4 (100011)," & -- Not available until after configuration "XADC_DRP (110111)," & -- PRIVATE "INTEST_RSVD (000111)"; -- PRIVATE attribute INSTRUCTION_CAPTURE of XC7Z020_CLG484 : entity is -- Bit 5 is 1 when DONE is released (part of startup sequence) -- Bit 4 is 1 if house-cleaning is complete -- Bit 3 is ISC_Enabled -- Bit 2 is ISC_Done "XXXX01"; attribute INSTRUCTION_PRIVATE of XC7Z020_CLG484 : entity is -- If the device is configured, and a USER instruction is implemented -- and not private to the FPGA designer, then it should be removed -- from INSTRUCTION_PRIVATE, and the target register should be defined -- in REGISTER_ACCESS. "ISC_ENABLE," & "ISC_PROGRAM," & "ISC_NOOP," & "XSC_READ_RSVD," & "ISC_DISABLE," & "XSC_PROGRAM_KEY," & "XSC_DNA," & "CFG_OUT," & "CFG_IN," & "JPROGRAM," & "JSTART," & "JSHUTDOWN," & "FUSE_CTS," & "FUSE_KEY," & "FUSE_DNA," & "FUSE_USER," & "FUSE_CNTL," & "USER1," & "USER2," & "USER3," & "USER4," & "XADC_DRP," & "INTEST_RSVD"; -- Optional Register Description attribute IDCODE_REGISTER of XC7Z020_CLG484 : entity is "XXXX" & -- version "0011011" & -- family "100100111" & -- array size "00001001001" & -- manufacturer "1"; -- required by 1149.1 attribute USERCODE_REGISTER of XC7Z020_CLG484 : entity is "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; -- Register Access Description attribute REGISTER_ACCESS of XC7Z020_CLG484 : entity is -- "[] (USER1)," & -- "[] (USER2)," & -- "[] (USER3)," & -- "[] (USER4)," & "DATAREG[57] (XSC_DNA)," & "BYPASS (HIGHZ,BYPASS)," & "DEVICE_ID (USERCODE,IDCODE)," & "BOUNDARY (SAMPLE,PRELOAD,EXTEST,EXTEST_PULSE,EXTEST_TRAIN)"; -- Boundary-Scan Register Description attribute BOUNDARY_LENGTH of XC7Z020_CLG484 : entity is 1077; attribute BOUNDARY_REGISTER of XC7Z020_CLG484 : entity is -- cellnum (type, port, function, safe[, ccell, disval, disrslt]) " 0 (BC_2, *, controlr, 1)," & " 1 (BC_2, RSVDGND_G10, output3, X, 0, 1, Z)," & -- RSVDGND_0 " 2 (BC_2, RSVDGND_G10, input, X)," & -- RSVDGND_0 " 3 (BC_2, RSVD0VCC_T10, input, X)," & " 4 (BC_2, RSVD1VCC_T8, input, X)," & " 5 (BC_2, RSVD2VCC_T7, input, X)," & " 6 (BC_2, CFGBVS_T13, input, X)," & " 7 (BC_2, *, internal, 1)," & -- PROGRAM_B " 8 (BC_2, *, controlr, 1)," & " 9 (BC_2, INIT_B_T14, output3, X, 8, 1, Z)," & -- INIT_B_0 " 10 (BC_2, INIT_B_T14, input, X)," & -- INIT_B_0 " 11 (BC_2, *, controlr, 1)," & " 12 (BC_2, DONE_T12, output3, X, 11, 1, Z)," & -- DONE_0 " 13 (BC_2, DONE_T12, input, X)," & -- DONE_0 " 14 (BC_2, *, internal, X)," & " 15 (BC_2, *, internal, X)," & " 16 (BC_2, *, internal, X)," & " 17 (BC_2, *, internal, X)," & " 18 (BC_2, *, internal, X)," & " 19 (BC_2, *, internal, X)," & " 20 (BC_2, *, internal, X)," & " 21 (BC_2, *, internal, X)," & " 22 (BC_2, *, internal, X)," & " 23 (BC_2, *, internal, X)," & " 24 (BC_2, *, internal, X)," & " 25 (BC_2, *, internal, X)," & " 26 (BC_2, *, controlr, 1)," & " 27 (BC_2, IO_U14, output3, X, 26, 1, Z)," & -- PAD200 " 28 (BC_2, IO_U14, input, X)," & -- PAD200 " 29 (BC_2, *, controlr, 1)," & " 30 (BC_2, IO_AB15, output3, X, 29, 1, Z)," & -- PAD199 " 31 (BC_2, IO_AB15, input, X)," & -- PAD199 " 32 (BC_2, *, controlr, 1)," & " 33 (BC_2, IO_AB14, output3, X, 32, 1, Z)," & -- PAD198 " 34 (BC_2, IO_AB14, input, X)," & -- PAD198 " 35 (BC_2, *, controlr, 1)," & " 36 (BC_2, IO_AA13, output3, X, 35, 1, Z)," & -- PAD197 " 37 (BC_2, IO_AA13, input, X)," & -- PAD197 " 38 (BC_2, *, controlr, 1)," & " 39 (BC_2, IO_Y13, output3, X, 38, 1, Z)," & -- PAD196 " 40 (BC_2, IO_Y13, input, X)," & -- PAD196 " 41 (BC_2, *, controlr, 1)," & " 42 (BC_2, IO_AA14, output3, X, 41, 1, Z)," & -- PAD195 " 43 (BC_2, IO_AA14, input, X)," & -- PAD195 " 44 (BC_2, *, controlr, 1)," & " 45 (BC_2, IO_Y14, output3, X, 44, 1, Z)," & -- PAD194 " 46 (BC_2, IO_Y14, input, X)," & -- PAD194 " 47 (BC_2, *, controlr, 1)," & " 48 (BC_2, IO_Y15, output3, X, 47, 1, Z)," & -- PAD193 " 49 (BC_2, IO_Y15, input, X)," & -- PAD193 " 50 (BC_2, *, controlr, 1)," & " 51 (BC_2, IO_W15, output3, X, 50, 1, Z)," & -- PAD192 " 52 (BC_2, IO_W15, input, X)," & -- PAD192 " 53 (BC_2, *, controlr, 1)," & " 54 (BC_2, IO_W13, output3, X, 53, 1, Z)," & -- PAD191 " 55 (BC_2, IO_W13, input, X)," & -- PAD191 " 56 (BC_2, *, controlr, 1)," & " 57 (BC_2, IO_V13, output3, X, 56, 1, Z)," & -- PAD190 " 58 (BC_2, IO_V13, input, X)," & -- PAD190 " 59 (BC_2, *, controlr, 1)," & " 60 (BC_2, IO_V15, output3, X, 59, 1, Z)," & -- PAD189 " 61 (BC_2, IO_V15, input, X)," & -- PAD189 " 62 (BC_2, *, controlr, 1)," & " 63 (BC_2, IO_V14, output3, X, 62, 1, Z)," & -- PAD188 " 64 (BC_2, IO_V14, input, X)," & -- PAD188 " 65 (BC_2, *, controlr, 1)," & " 66 (BC_2, IO_AB16, output3, X, 65, 1, Z)," & -- PAD187 " 67 (BC_2, IO_AB16, input, X)," & -- PAD187 " 68 (BC_2, *, controlr, 1)," & " 69 (BC_2, IO_AA16, output3, X, 68, 1, Z)," & -- PAD186 " 70 (BC_2, IO_AA16, input, X)," & -- PAD186 " 71 (BC_2, *, controlr, 1)," & " 72 (BC_2, IO_AB17, output3, X, 71, 1, Z)," & -- PAD185 " 73 (BC_2, IO_AB17, input, X)," & -- PAD185 " 74 (BC_2, *, controlr, 1)," & " 75 (BC_2, IO_AA17, output3, X, 74, 1, Z)," & -- PAD184 " 76 (BC_2, IO_AA17, input, X)," & -- PAD184 " 77 (BC_2, *, controlr, 1)," & " 78 (BC_2, IO_V17, output3, X, 77, 1, Z)," & -- PAD183 " 79 (BC_2, IO_V17, input, X)," & -- PAD183 " 80 (BC_2, *, controlr, 1)," & " 81 (BC_2, IO_U17, output3, X, 80, 1, Z)," & -- PAD182 " 82 (BC_2, IO_U17, input, X)," & -- PAD182 " 83 (BC_2, *, controlr, 1)," & " 84 (BC_2, IO_U16, output3, X, 83, 1, Z)," & -- PAD181 " 85 (BC_2, IO_U16, input, X)," & -- PAD181 " 86 (BC_2, *, controlr, 1)," & " 87 (BC_2, IO_U15, output3, X, 86, 1, Z)," & -- PAD180 " 88 (BC_2, IO_U15, input, X)," & -- PAD180 " 89 (BC_2, *, controlr, 1)," & " 90 (BC_2, IO_Y16, output3, X, 89, 1, Z)," & -- PAD179 " 91 (BC_2, IO_Y16, input, X)," & -- PAD179 " 92 (BC_2, *, controlr, 1)," & " 93 (BC_2, IO_W16, output3, X, 92, 1, Z)," & -- PAD178 " 94 (BC_2, IO_W16, input, X)," & -- PAD178 " 95 (BC_2, *, controlr, 1)," & " 96 (BC_2, IO_W18, output3, X, 95, 1, Z)," & -- PAD177 " 97 (BC_2, IO_W18, input, X)," & -- PAD177 " 98 (BC_2, *, controlr, 1)," & " 99 (BC_2, IO_W17, output3, X, 98, 1, Z)," & -- PAD176 " 100 (BC_2, IO_W17, input, X)," & -- PAD176 " 101 (BC_2, *, controlr, 1)," & " 102 (BC_2, IO_AA18, output3, X, 101, 1, Z)," & -- PAD175 " 103 (BC_2, IO_AA18, input, X)," & -- PAD175 " 104 (BC_2, *, controlr, 1)," & " 105 (BC_2, IO_Y18, output3, X, 104, 1, Z)," & -- PAD174 " 106 (BC_2, IO_Y18, input, X)," & -- PAD174 " 107 (BC_2, *, controlr, 1)," & " 108 (BC_2, IO_AA19, output3, X, 107, 1, Z)," & -- PAD173 " 109 (BC_2, IO_AA19, input, X)," & -- PAD173 " 110 (BC_2, *, controlr, 1)," & " 111 (BC_2, IO_Y19, output3, X, 110, 1, Z)," & -- PAD172 " 112 (BC_2, IO_Y19, input, X)," & -- PAD172 " 113 (BC_2, *, controlr, 1)," & " 114 (BC_2, IO_AB20, output3, X, 113, 1, Z)," & -- PAD171 " 115 (BC_2, IO_AB20, input, X)," & -- PAD171 " 116 (BC_2, *, controlr, 1)," & " 117 (BC_2, IO_AB19, output3, X, 116, 1, Z)," & -- PAD170 " 118 (BC_2, IO_AB19, input, X)," & -- PAD170 " 119 (BC_2, *, controlr, 1)," & " 120 (BC_2, IO_Y21, output3, X, 119, 1, Z)," & -- PAD169 " 121 (BC_2, IO_Y21, input, X)," & -- PAD169 " 122 (BC_2, *, controlr, 1)," & " 123 (BC_2, IO_Y20, output3, X, 122, 1, Z)," & -- PAD168 " 124 (BC_2, IO_Y20, input, X)," & -- PAD168 " 125 (BC_2, *, controlr, 1)," & " 126 (BC_2, IO_AB21, output3, X, 125, 1, Z)," & -- PAD167 " 127 (BC_2, IO_AB21, input, X)," & -- PAD167 " 128 (BC_2, *, controlr, 1)," & " 129 (BC_2, IO_AA21, output3, X, 128, 1, Z)," & -- PAD166 " 130 (BC_2, IO_AA21, input, X)," & -- PAD166 " 131 (BC_2, *, controlr, 1)," & " 132 (BC_2, IO_AB22, output3, X, 131, 1, Z)," & -- PAD165 " 133 (BC_2, IO_AB22, input, X)," & -- PAD165 " 134 (BC_2, *, controlr, 1)," & " 135 (BC_2, IO_AA22, output3, X, 134, 1, Z)," & -- PAD164 " 136 (BC_2, IO_AA22, input, X)," & -- PAD164 " 137 (BC_2, *, controlr, 1)," & " 138 (BC_2, IO_V19, output3, X, 137, 1, Z)," & -- PAD163 " 139 (BC_2, IO_V19, input, X)," & -- PAD163 " 140 (BC_2, *, controlr, 1)," & " 141 (BC_2, IO_V18, output3, X, 140, 1, Z)," & -- PAD162 " 142 (BC_2, IO_V18, input, X)," & -- PAD162 " 143 (BC_2, *, controlr, 1)," & " 144 (BC_2, IO_V20, output3, X, 143, 1, Z)," & -- PAD161 " 145 (BC_2, IO_V20, input, X)," & -- PAD161 " 146 (BC_2, *, controlr, 1)," & " 147 (BC_2, IO_U20, output3, X, 146, 1, Z)," & -- PAD160 " 148 (BC_2, IO_U20, input, X)," & -- PAD160 " 149 (BC_2, *, controlr, 1)," & " 150 (BC_2, IO_W21, output3, X, 149, 1, Z)," & -- PAD159 " 151 (BC_2, IO_W21, input, X)," & -- PAD159 " 152 (BC_2, *, controlr, 1)," & " 153 (BC_2, IO_W20, output3, X, 152, 1, Z)," & -- PAD158 " 154 (BC_2, IO_W20, input, X)," & -- PAD158 " 155 (BC_2, *, controlr, 1)," & " 156 (BC_2, IO_W22, output3, X, 155, 1, Z)," & -- PAD157 " 157 (BC_2, IO_W22, input, X)," & -- PAD157 " 158 (BC_2, *, controlr, 1)," & " 159 (BC_2, IO_V22, output3, X, 158, 1, Z)," & -- PAD156 " 160 (BC_2, IO_V22, input, X)," & -- PAD156 " 161 (BC_2, *, controlr, 1)," & " 162 (BC_2, IO_U22, output3, X, 161, 1, Z)," & -- PAD155 " 163 (BC_2, IO_U22, input, X)," & -- PAD155 " 164 (BC_2, *, controlr, 1)," & " 165 (BC_2, IO_T22, output3, X, 164, 1, Z)," & -- PAD154 " 166 (BC_2, IO_T22, input, X)," & -- PAD154 " 167 (BC_2, *, controlr, 1)," & " 168 (BC_2, IO_U21, output3, X, 167, 1, Z)," & -- PAD153 " 169 (BC_2, IO_U21, input, X)," & -- PAD153 " 170 (BC_2, *, controlr, 1)," & " 171 (BC_2, IO_T21, output3, X, 170, 1, Z)," & -- PAD152 " 172 (BC_2, IO_T21, input, X)," & -- PAD152 " 173 (BC_2, *, controlr, 1)," & " 174 (BC_2, IO_U19, output3, X, 173, 1, Z)," & -- PAD151 " 175 (BC_2, IO_U19, input, X)," & -- PAD151 " 176 (BC_2, *, controlr, 1)," & " 177 (BC_2, IO_R15, output3, X, 176, 1, Z)," & -- PAD150 " 178 (BC_2, IO_R15, input, X)," & -- PAD150 " 179 (BC_2, *, controlr, 1)," & " 180 (BC_2, IO_R16, output3, X, 179, 1, Z)," & -- PAD149 " 181 (BC_2, IO_R16, input, X)," & -- PAD149 " 182 (BC_2, *, controlr, 1)," & " 183 (BC_2, IO_P16, output3, X, 182, 1, Z)," & -- PAD148 " 184 (BC_2, IO_P16, input, X)," & -- PAD148 " 185 (BC_2, *, controlr, 1)," & " 186 (BC_2, IO_T18, output3, X, 185, 1, Z)," & -- PAD147 " 187 (BC_2, IO_T18, input, X)," & -- PAD147 " 188 (BC_2, *, controlr, 1)," & " 189 (BC_2, IO_R18, output3, X, 188, 1, Z)," & -- PAD146 " 190 (BC_2, IO_R18, input, X)," & -- PAD146 " 191 (BC_2, *, controlr, 1)," & " 192 (BC_2, IO_T19, output3, X, 191, 1, Z)," & -- PAD145 " 193 (BC_2, IO_T19, input, X)," & -- PAD145 " 194 (BC_2, *, controlr, 1)," & " 195 (BC_2, IO_R19, output3, X, 194, 1, Z)," & -- PAD144 " 196 (BC_2, IO_R19, input, X)," & -- PAD144 " 197 (BC_2, *, controlr, 1)," & " 198 (BC_2, IO_T17, output3, X, 197, 1, Z)," & -- PAD143 " 199 (BC_2, IO_T17, input, X)," & -- PAD143 " 200 (BC_2, *, controlr, 1)," & " 201 (BC_2, IO_T16, output3, X, 200, 1, Z)," & -- PAD142 " 202 (BC_2, IO_T16, input, X)," & -- PAD142 " 203 (BC_2, *, controlr, 1)," & " 204 (BC_2, IO_P18, output3, X, 203, 1, Z)," & -- PAD141 " 205 (BC_2, IO_P18, input, X)," & -- PAD141 " 206 (BC_2, *, controlr, 1)," & " 207 (BC_2, IO_P17, output3, X, 206, 1, Z)," & -- PAD140 " 208 (BC_2, IO_P17, input, X)," & -- PAD140 " 209 (BC_2, *, controlr, 1)," & " 210 (BC_2, IO_P15, output3, X, 209, 1, Z)," & -- PAD139 " 211 (BC_2, IO_P15, input, X)," & -- PAD139 " 212 (BC_2, *, controlr, 1)," & " 213 (BC_2, IO_N15, output3, X, 212, 1, Z)," & -- PAD138 " 214 (BC_2, IO_N15, input, X)," & -- PAD138 " 215 (BC_2, *, controlr, 1)," & " 216 (BC_2, IO_P21, output3, X, 215, 1, Z)," & -- PAD137 " 217 (BC_2, IO_P21, input, X)," & -- PAD137 " 218 (BC_2, *, controlr, 1)," & " 219 (BC_2, IO_P20, output3, X, 218, 1, Z)," & -- PAD136 " 220 (BC_2, IO_P20, input, X)," & -- PAD136 " 221 (BC_2, *, controlr, 1)," & " 222 (BC_2, IO_R21, output3, X, 221, 1, Z)," & -- PAD135 " 223 (BC_2, IO_R21, input, X)," & -- PAD135 " 224 (BC_2, *, controlr, 1)," & " 225 (BC_2, IO_R20, output3, X, 224, 1, Z)," & -- PAD134 " 226 (BC_2, IO_R20, input, X)," & -- PAD134 " 227 (BC_2, *, controlr, 1)," & " 228 (BC_2, IO_P22, output3, X, 227, 1, Z)," & -- PAD133 " 229 (BC_2, IO_P22, input, X)," & -- PAD133 " 230 (BC_2, *, controlr, 1)," & " 231 (BC_2, IO_N22, output3, X, 230, 1, Z)," & -- PAD132 " 232 (BC_2, IO_N22, input, X)," & -- PAD132 " 233 (BC_2, *, controlr, 1)," & " 234 (BC_2, IO_M22, output3, X, 233, 1, Z)," & -- PAD131 " 235 (BC_2, IO_M22, input, X)," & -- PAD131 " 236 (BC_2, *, controlr, 1)," & " 237 (BC_2, IO_M21, output3, X, 236, 1, Z)," & -- PAD130 " 238 (BC_2, IO_M21, input, X)," & -- PAD130 " 239 (BC_2, *, controlr, 1)," & " 240 (BC_2, IO_N20, output3, X, 239, 1, Z)," & -- PAD129 " 241 (BC_2, IO_N20, input, X)," & -- PAD129 " 242 (BC_2, *, controlr, 1)," & " 243 (BC_2, IO_N19, output3, X, 242, 1, Z)," & -- PAD128 " 244 (BC_2, IO_N19, input, X)," & -- PAD128 " 245 (BC_2, *, controlr, 1)," & " 246 (BC_2, IO_M20, output3, X, 245, 1, Z)," & -- PAD127 " 247 (BC_2, IO_M20, input, X)," & -- PAD127 " 248 (BC_2, *, controlr, 1)," & " 249 (BC_2, IO_M19, output3, X, 248, 1, Z)," & -- PAD126 " 250 (BC_2, IO_M19, input, X)," & -- PAD126 " 251 (BC_2, *, controlr, 1)," & " 252 (BC_2, IO_L19, output3, X, 251, 1, Z)," & -- PAD125 " 253 (BC_2, IO_L19, input, X)," & -- PAD125 " 254 (BC_2, *, controlr, 1)," & " 255 (BC_2, IO_L18, output3, X, 254, 1, Z)," & -- PAD124 " 256 (BC_2, IO_L18, input, X)," & -- PAD124 " 257 (BC_2, *, controlr, 1)," & " 258 (BC_2, IO_K20, output3, X, 257, 1, Z)," & -- PAD123 " 259 (BC_2, IO_K20, input, X)," & -- PAD123 " 260 (BC_2, *, controlr, 1)," & " 261 (BC_2, IO_K19, output3, X, 260, 1, Z)," & -- PAD122 " 262 (BC_2, IO_K19, input, X)," & -- PAD122 " 263 (BC_2, *, controlr, 1)," & " 264 (BC_2, IO_L22, output3, X, 263, 1, Z)," & -- PAD121 " 265 (BC_2, IO_L22, input, X)," & -- PAD121 " 266 (BC_2, *, controlr, 1)," & " 267 (BC_2, IO_L21, output3, X, 266, 1, Z)," & -- PAD120 " 268 (BC_2, IO_L21, input, X)," & -- PAD120 " 269 (BC_2, *, controlr, 1)," & " 270 (BC_2, IO_K21, output3, X, 269, 1, Z)," & -- PAD119 " 271 (BC_2, IO_K21, input, X)," & -- PAD119 " 272 (BC_2, *, controlr, 1)," & " 273 (BC_2, IO_J20, output3, X, 272, 1, Z)," & -- PAD118 " 274 (BC_2, IO_J20, input, X)," & -- PAD118 " 275 (BC_2, *, controlr, 1)," & " 276 (BC_2, IO_J22, output3, X, 275, 1, Z)," & -- PAD117 " 277 (BC_2, IO_J22, input, X)," & -- PAD117 " 278 (BC_2, *, controlr, 1)," & " 279 (BC_2, IO_J21, output3, X, 278, 1, Z)," & -- PAD116 " 280 (BC_2, IO_J21, input, X)," & -- PAD116 " 281 (BC_2, *, controlr, 1)," & " 282 (BC_2, IO_K18, output3, X, 281, 1, Z)," & -- PAD115 " 283 (BC_2, IO_K18, input, X)," & -- PAD115 " 284 (BC_2, *, controlr, 1)," & " 285 (BC_2, IO_J18, output3, X, 284, 1, Z)," & -- PAD114 " 286 (BC_2, IO_J18, input, X)," & -- PAD114 " 287 (BC_2, *, controlr, 1)," & " 288 (BC_2, IO_M16, output3, X, 287, 1, Z)," & -- PAD113 " 289 (BC_2, IO_M16, input, X)," & -- PAD113 " 290 (BC_2, *, controlr, 1)," & " 291 (BC_2, IO_M15, output3, X, 290, 1, Z)," & -- PAD112 " 292 (BC_2, IO_M15, input, X)," & -- PAD112 " 293 (BC_2, *, controlr, 1)," & " 294 (BC_2, IO_N18, output3, X, 293, 1, Z)," & -- PAD111 " 295 (BC_2, IO_N18, input, X)," & -- PAD111 " 296 (BC_2, *, controlr, 1)," & " 297 (BC_2, IO_N17, output3, X, 296, 1, Z)," & -- PAD110 " 298 (BC_2, IO_N17, input, X)," & -- PAD110 " 299 (BC_2, *, controlr, 1)," & " 300 (BC_2, IO_M17, output3, X, 299, 1, Z)," & -- PAD109 " 301 (BC_2, IO_M17, input, X)," & -- PAD109 " 302 (BC_2, *, controlr, 1)," & " 303 (BC_2, IO_L17, output3, X, 302, 1, Z)," & -- PAD108 " 304 (BC_2, IO_L17, input, X)," & -- PAD108 " 305 (BC_2, *, controlr, 1)," & " 306 (BC_2, IO_L16, output3, X, 305, 1, Z)," & -- PAD107 " 307 (BC_2, IO_L16, input, X)," & -- PAD107 " 308 (BC_2, *, controlr, 1)," & " 309 (BC_2, IO_K16, output3, X, 308, 1, Z)," & -- PAD106 " 310 (BC_2, IO_K16, input, X)," & -- PAD106 " 311 (BC_2, *, controlr, 1)," & " 312 (BC_2, IO_J17, output3, X, 311, 1, Z)," & -- PAD105 " 313 (BC_2, IO_J17, input, X)," & -- PAD105 " 314 (BC_2, *, controlr, 1)," & " 315 (BC_2, IO_J16, output3, X, 314, 1, Z)," & -- PAD104 " 316 (BC_2, IO_J16, input, X)," & -- PAD104 " 317 (BC_2, *, controlr, 1)," & " 318 (BC_2, IO_K15, output3, X, 317, 1, Z)," & -- PAD103 " 319 (BC_2, IO_K15, input, X)," & -- PAD103 " 320 (BC_2, *, controlr, 1)," & " 321 (BC_2, IO_J15, output3, X, 320, 1, Z)," & -- PAD102 " 322 (BC_2, IO_J15, input, X)," & -- PAD102 " 323 (BC_2, *, controlr, 1)," & " 324 (BC_2, IO_H15, output3, X, 323, 1, Z)," & -- PAD101 " 325 (BC_2, IO_H15, input, X)," & -- PAD101 " 326 (BC_2, *, controlr, 1)," & " 327 (BC_2, IO_H18, output3, X, 326, 1, Z)," & -- PAD100 " 328 (BC_2, IO_H18, input, X)," & -- PAD100 " 329 (BC_2, *, controlr, 1)," & " 330 (BC_2, IO_G22, output3, X, 329, 1, Z)," & -- PAD99 " 331 (BC_2, IO_G22, input, X)," & -- PAD99 " 332 (BC_2, *, controlr, 1)," & " 333 (BC_2, IO_H22, output3, X, 332, 1, Z)," & -- PAD98 " 334 (BC_2, IO_H22, input, X)," & -- PAD98 " 335 (BC_2, *, controlr, 1)," & " 336 (BC_2, IO_F22, output3, X, 335, 1, Z)," & -- PAD97 " 337 (BC_2, IO_F22, input, X)," & -- PAD97 " 338 (BC_2, *, controlr, 1)," & " 339 (BC_2, IO_F21, output3, X, 338, 1, Z)," & -- PAD96 " 340 (BC_2, IO_F21, input, X)," & -- PAD96 " 341 (BC_2, *, controlr, 1)," & " 342 (BC_2, IO_G21, output3, X, 341, 1, Z)," & -- PAD95 " 343 (BC_2, IO_G21, input, X)," & -- PAD95 " 344 (BC_2, *, controlr, 1)," & " 345 (BC_2, IO_G20, output3, X, 344, 1, Z)," & -- PAD94 " 346 (BC_2, IO_G20, input, X)," & -- PAD94 " 347 (BC_2, *, controlr, 1)," & " 348 (BC_2, IO_E20, output3, X, 347, 1, Z)," & -- PAD93 " 349 (BC_2, IO_E20, input, X)," & -- PAD93 " 350 (BC_2, *, controlr, 1)," & " 351 (BC_2, IO_E19, output3, X, 350, 1, Z)," & -- PAD92 " 352 (BC_2, IO_E19, input, X)," & -- PAD92 " 353 (BC_2, *, controlr, 1)," & " 354 (BC_2, IO_F19, output3, X, 353, 1, Z)," & -- PAD91 " 355 (BC_2, IO_F19, input, X)," & -- PAD91 " 356 (BC_2, *, controlr, 1)," & " 357 (BC_2, IO_G19, output3, X, 356, 1, Z)," & -- PAD90 " 358 (BC_2, IO_G19, input, X)," & -- PAD90 " 359 (BC_2, *, controlr, 1)," & " 360 (BC_2, IO_H20, output3, X, 359, 1, Z)," & -- PAD89 " 361 (BC_2, IO_H20, input, X)," & -- PAD89 " 362 (BC_2, *, controlr, 1)," & " 363 (BC_2, IO_H19, output3, X, 362, 1, Z)," & -- PAD88 " 364 (BC_2, IO_H19, input, X)," & -- PAD88 " 365 (BC_2, *, controlr, 1)," & " 366 (BC_2, IO_B22, output3, X, 365, 1, Z)," & -- PAD87 " 367 (BC_2, IO_B22, input, X)," & -- PAD87 " 368 (BC_2, *, controlr, 1)," & " 369 (BC_2, IO_B21, output3, X, 368, 1, Z)," & -- PAD86 " 370 (BC_2, IO_B21, input, X)," & -- PAD86 " 371 (BC_2, *, controlr, 1)," & " 372 (BC_2, IO_D21, output3, X, 371, 1, Z)," & -- PAD85 " 373 (BC_2, IO_D21, input, X)," & -- PAD85 " 374 (BC_2, *, controlr, 1)," & " 375 (BC_2, IO_E21, output3, X, 374, 1, Z)," & -- PAD84 " 376 (BC_2, IO_E21, input, X)," & -- PAD84 " 377 (BC_2, *, controlr, 1)," & " 378 (BC_2, IO_C22, output3, X, 377, 1, Z)," & -- PAD83 " 379 (BC_2, IO_C22, input, X)," & -- PAD83 " 380 (BC_2, *, controlr, 1)," & " 381 (BC_2, IO_D22, output3, X, 380, 1, Z)," & -- PAD82 " 382 (BC_2, IO_D22, input, X)," & -- PAD82 " 383 (BC_2, *, controlr, 1)," & " 384 (BC_2, IO_A22, output3, X, 383, 1, Z)," & -- PAD81 " 385 (BC_2, IO_A22, input, X)," & -- PAD81 " 386 (BC_2, *, controlr, 1)," & " 387 (BC_2, IO_A21, output3, X, 386, 1, Z)," & -- PAD80 " 388 (BC_2, IO_A21, input, X)," & -- PAD80 " 389 (BC_2, *, controlr, 1)," & " 390 (BC_2, IO_C20, output3, X, 389, 1, Z)," & -- PAD79 " 391 (BC_2, IO_C20, input, X)," & -- PAD79 " 392 (BC_2, *, controlr, 1)," & " 393 (BC_2, IO_D20, output3, X, 392, 1, Z)," & -- PAD78 " 394 (BC_2, IO_D20, input, X)," & -- PAD78 " 395 (BC_2, *, controlr, 1)," & " 396 (BC_2, IO_B20, output3, X, 395, 1, Z)," & -- PAD77 " 397 (BC_2, IO_B20, input, X)," & -- PAD77 " 398 (BC_2, *, controlr, 1)," & " 399 (BC_2, IO_B19, output3, X, 398, 1, Z)," & -- PAD76 " 400 (BC_2, IO_B19, input, X)," & -- PAD76 " 401 (BC_2, *, controlr, 1)," & " 402 (BC_2, IO_C19, output3, X, 401, 1, Z)," & -- PAD75 " 403 (BC_2, IO_C19, input, X)," & -- PAD75 " 404 (BC_2, *, controlr, 1)," & " 405 (BC_2, IO_D18, output3, X, 404, 1, Z)," & -- PAD74 " 406 (BC_2, IO_D18, input, X)," & -- PAD74 " 407 (BC_2, *, controlr, 1)," & " 408 (BC_2, IO_C18, output3, X, 407, 1, Z)," & -- PAD73 " 409 (BC_2, IO_C18, input, X)," & -- PAD73 " 410 (BC_2, *, controlr, 1)," & " 411 (BC_2, IO_C17, output3, X, 410, 1, Z)," & -- PAD72 " 412 (BC_2, IO_C17, input, X)," & -- PAD72 " 413 (BC_2, *, controlr, 1)," & " 414 (BC_2, IO_A19, output3, X, 413, 1, Z)," & -- PAD71 " 415 (BC_2, IO_A19, input, X)," & -- PAD71 " 416 (BC_2, *, controlr, 1)," & " 417 (BC_2, IO_A18, output3, X, 416, 1, Z)," & -- PAD70 " 418 (BC_2, IO_A18, input, X)," & -- PAD70 " 419 (BC_2, *, controlr, 1)," & " 420 (BC_2, IO_A17, output3, X, 419, 1, Z)," & -- PAD69 " 421 (BC_2, IO_A17, input, X)," & -- PAD69 " 422 (BC_2, *, controlr, 1)," & " 423 (BC_2, IO_A16, output3, X, 422, 1, Z)," & -- PAD68 " 424 (BC_2, IO_A16, input, X)," & -- PAD68 " 425 (BC_2, *, controlr, 1)," & " 426 (BC_2, IO_B17, output3, X, 425, 1, Z)," & -- PAD67 " 427 (BC_2, IO_B17, input, X)," & -- PAD67 " 428 (BC_2, *, controlr, 1)," & " 429 (BC_2, IO_B16, output3, X, 428, 1, Z)," & -- PAD66 " 430 (BC_2, IO_B16, input, X)," & -- PAD66 " 431 (BC_2, *, controlr, 1)," & " 432 (BC_2, IO_B15, output3, X, 431, 1, Z)," & -- PAD65 " 433 (BC_2, IO_B15, input, X)," & -- PAD65 " 434 (BC_2, *, controlr, 1)," & " 435 (BC_2, IO_C15, output3, X, 434, 1, Z)," & -- PAD64 " 436 (BC_2, IO_C15, input, X)," & -- PAD64 " 437 (BC_2, *, controlr, 1)," & " 438 (BC_2, IO_F17, output3, X, 437, 1, Z)," & -- PAD63 " 439 (BC_2, IO_F17, input, X)," & -- PAD63 " 440 (BC_2, *, controlr, 1)," & " 441 (BC_2, IO_G17, output3, X, 440, 1, Z)," & -- PAD62 " 442 (BC_2, IO_G17, input, X)," & -- PAD62 " 443 (BC_2, *, controlr, 1)," & " 444 (BC_2, IO_E18, output3, X, 443, 1, Z)," & -- PAD61 " 445 (BC_2, IO_E18, input, X)," & -- PAD61 " 446 (BC_2, *, controlr, 1)," & " 447 (BC_2, IO_F18, output3, X, 446, 1, Z)," & -- PAD60 " 448 (BC_2, IO_F18, input, X)," & -- PAD60 " 449 (BC_2, *, controlr, 1)," & " 450 (BC_2, IO_G16, output3, X, 449, 1, Z)," & -- PAD59 " 451 (BC_2, IO_G16, input, X)," & -- PAD59 " 452 (BC_2, *, controlr, 1)," & " 453 (BC_2, IO_G15, output3, X, 452, 1, Z)," & -- PAD58 " 454 (BC_2, IO_G15, input, X)," & -- PAD58 " 455 (BC_2, *, controlr, 1)," & " 456 (BC_2, IO_D15, output3, X, 455, 1, Z)," & -- PAD57 " 457 (BC_2, IO_D15, input, X)," & -- PAD57 " 458 (BC_2, *, controlr, 1)," & " 459 (BC_2, IO_E15, output3, X, 458, 1, Z)," & -- PAD56 " 460 (BC_2, IO_E15, input, X)," & -- PAD56 " 461 (BC_2, *, controlr, 1)," & " 462 (BC_2, IO_D17, output3, X, 461, 1, Z)," & -- PAD55 " 463 (BC_2, IO_D17, input, X)," & -- PAD55 " 464 (BC_2, *, controlr, 1)," & " 465 (BC_2, IO_D16, output3, X, 464, 1, Z)," & -- PAD54 " 466 (BC_2, IO_D16, input, X)," & -- PAD54 " 467 (BC_2, *, controlr, 1)," & " 468 (BC_2, IO_E16, output3, X, 467, 1, Z)," & -- PAD53 " 469 (BC_2, IO_E16, input, X)," & -- PAD53 " 470 (BC_2, *, controlr, 1)," & " 471 (BC_2, IO_F16, output3, X, 470, 1, Z)," & -- PAD52 " 472 (BC_2, IO_F16, input, X)," & -- PAD52 " 473 (BC_2, *, controlr, 1)," & " 474 (BC_2, IO_H17, output3, X, 473, 1, Z)," & -- PAD51 " 475 (BC_2, IO_H17, input, X)," & -- PAD51 " 476 (BC_2, *, internal, X)," & " 477 (BC_2, *, internal, X)," & " 478 (BC_2, *, internal, X)," & " 479 (BC_2, *, internal, X)," & " 480 (BC_2, *, internal, X)," & " 481 (BC_2, *, internal, X)," & " 482 (BC_2, *, internal, X)," & " 483 (BC_2, *, internal, X)," & " 484 (BC_2, *, internal, X)," & " 485 (BC_2, *, internal, X)," & " 486 (BC_2, *, internal, X)," & " 487 (BC_2, *, internal, X)," & " 488 (BC_2, *, internal, X)," & " 489 (BC_2, *, internal, X)," & " 490 (BC_2, *, internal, X)," & " 491 (BC_2, *, internal, X)," & " 492 (BC_2, *, internal, X)," & " 493 (BC_2, *, internal, X)," & " 494 (BC_2, *, internal, X)," & " 495 (BC_2, *, internal, X)," & " 496 (BC_2, *, internal, X)," & " 497 (BC_2, *, controlr, 1)," & " 498 (BC_2, IO_U7, output3, X, 497, 1, Z)," & -- PAD50 " 499 (BC_2, IO_U7, input, X)," & -- PAD50 " 500 (BC_2, *, controlr, 1)," & " 501 (BC_2, IO_W5, output3, X, 500, 1, Z)," & -- PAD49 " 502 (BC_2, IO_W5, input, X)," & -- PAD49 " 503 (BC_2, *, controlr, 1)," & " 504 (BC_2, IO_W6, output3, X, 503, 1, Z)," & -- PAD48 " 505 (BC_2, IO_W6, input, X)," & -- PAD48 " 506 (BC_2, *, controlr, 1)," & " 507 (BC_2, IO_W7, output3, X, 506, 1, Z)," & -- PAD47 " 508 (BC_2, IO_W7, input, X)," & -- PAD47 " 509 (BC_2, *, controlr, 1)," & " 510 (BC_2, IO_V7, output3, X, 509, 1, Z)," & -- PAD46 " 511 (BC_2, IO_V7, input, X)," & -- PAD46 " 512 (BC_2, *, controlr, 1)," & " 513 (BC_2, IO_U5, output3, X, 512, 1, Z)," & -- PAD45 " 514 (BC_2, IO_U5, input, X)," & -- PAD45 " 515 (BC_2, *, controlr, 1)," & " 516 (BC_2, IO_U6, output3, X, 515, 1, Z)," & -- PAD44 " 517 (BC_2, IO_U6, input, X)," & -- PAD44 " 518 (BC_2, *, controlr, 1)," & " 519 (BC_2, IO_V4, output3, X, 518, 1, Z)," & -- PAD43 " 520 (BC_2, IO_V4, input, X)," & -- PAD43 " 521 (BC_2, *, controlr, 1)," & " 522 (BC_2, IO_V5, output3, X, 521, 1, Z)," & -- PAD42 " 523 (BC_2, IO_V5, input, X)," & -- PAD42 " 524 (BC_2, *, controlr, 1)," & " 525 (BC_2, IO_U4, output3, X, 524, 1, Z)," & -- PAD41 " 526 (BC_2, IO_U4, input, X)," & -- PAD41 " 527 (BC_2, *, controlr, 1)," & " 528 (BC_2, IO_T4, output3, X, 527, 1, Z)," & -- PAD40 " 529 (BC_2, IO_T4, input, X)," & -- PAD40 " 530 (BC_2, *, controlr, 1)," & " 531 (BC_2, IO_T6, output3, X, 530, 1, Z)," & -- PAD39 " 532 (BC_2, IO_T6, input, X)," & -- PAD39 " 533 (BC_2, *, controlr, 1)," & " 534 (BC_2, IO_R6, output3, X, 533, 1, Z)," & -- PAD38 " 535 (BC_2, IO_R6, input, X)," & -- PAD38 " 536 (BC_2, *, controlr, 1)," & " 537 (BC_2, IO_AA4, output3, X, 536, 1, Z)," & -- PAD37 " 538 (BC_2, IO_AA4, input, X)," & -- PAD37 " 539 (BC_2, *, controlr, 1)," & " 540 (BC_2, IO_Y4, output3, X, 539, 1, Z)," & -- PAD36 " 541 (BC_2, IO_Y4, input, X)," & -- PAD36 " 542 (BC_2, *, controlr, 1)," & " 543 (BC_2, IO_AB6, output3, X, 542, 1, Z)," & -- PAD35 " 544 (BC_2, IO_AB6, input, X)," & -- PAD35 " 545 (BC_2, *, controlr, 1)," & " 546 (BC_2, IO_AB7, output3, X, 545, 1, Z)," & -- PAD34 " 547 (BC_2, IO_AB7, input, X)," & -- PAD34 " 548 (BC_2, *, controlr, 1)," & " 549 (BC_2, IO_AB4, output3, X, 548, 1, Z)," & -- PAD33 " 550 (BC_2, IO_AB4, input, X)," & -- PAD33 " 551 (BC_2, *, controlr, 1)," & " 552 (BC_2, IO_AB5, output3, X, 551, 1, Z)," & -- PAD32 " 553 (BC_2, IO_AB5, input, X)," & -- PAD32 " 554 (BC_2, *, controlr, 1)," & " 555 (BC_2, IO_AB1, output3, X, 554, 1, Z)," & -- PAD31 " 556 (BC_2, IO_AB1, input, X)," & -- PAD31 " 557 (BC_2, *, controlr, 1)," & " 558 (BC_2, IO_AB2, output3, X, 557, 1, Z)," & -- PAD30 " 559 (BC_2, IO_AB2, input, X)," & -- PAD30 " 560 (BC_2, *, controlr, 1)," & " 561 (BC_2, IO_AA6, output3, X, 560, 1, Z)," & -- PAD29 " 562 (BC_2, IO_AA6, input, X)," & -- PAD29 " 563 (BC_2, *, controlr, 1)," & " 564 (BC_2, IO_AA7, output3, X, 563, 1, Z)," & -- PAD28 " 565 (BC_2, IO_AA7, input, X)," & -- PAD28 " 566 (BC_2, *, controlr, 1)," & " 567 (BC_2, IO_Y5, output3, X, 566, 1, Z)," & -- PAD27 " 568 (BC_2, IO_Y5, input, X)," & -- PAD27 " 569 (BC_2, *, controlr, 1)," & " 570 (BC_2, IO_Y6, output3, X, 569, 1, Z)," & -- PAD26 " 571 (BC_2, IO_Y6, input, X)," & -- PAD26 " 572 (BC_2, *, controlr, 1)," & " 573 (BC_2, IO_Y8, output3, X, 572, 1, Z)," & -- PAD25 " 574 (BC_2, IO_Y8, input, X)," & -- PAD25 " 575 (BC_2, *, controlr, 1)," & " 576 (BC_2, IO_Y9, output3, X, 575, 1, Z)," & -- PAD24 " 577 (BC_2, IO_Y9, input, X)," & -- PAD24 " 578 (BC_2, *, controlr, 1)," & " 579 (BC_2, IO_AA8, output3, X, 578, 1, Z)," & -- PAD23 " 580 (BC_2, IO_AA8, input, X)," & -- PAD23 " 581 (BC_2, *, controlr, 1)," & " 582 (BC_2, IO_AA9, output3, X, 581, 1, Z)," & -- PAD22 " 583 (BC_2, IO_AA9, input, X)," & -- PAD22 " 584 (BC_2, *, controlr, 1)," & " 585 (BC_2, IO_Y10, output3, X, 584, 1, Z)," & -- PAD21 " 586 (BC_2, IO_Y10, input, X)," & -- PAD21 " 587 (BC_2, *, controlr, 1)," & " 588 (BC_2, IO_Y11, output3, X, 587, 1, Z)," & -- PAD20 " 589 (BC_2, IO_Y11, input, X)," & -- PAD20 " 590 (BC_2, *, controlr, 1)," & " 591 (BC_2, IO_AB9, output3, X, 590, 1, Z)," & -- PAD19 " 592 (BC_2, IO_AB9, input, X)," & -- PAD19 " 593 (BC_2, *, controlr, 1)," & " 594 (BC_2, IO_AB10, output3, X, 593, 1, Z)," & -- PAD18 " 595 (BC_2, IO_AB10, input, X)," & -- PAD18 " 596 (BC_2, *, controlr, 1)," & " 597 (BC_2, IO_AB11, output3, X, 596, 1, Z)," & -- PAD17 " 598 (BC_2, IO_AB11, input, X)," & -- PAD17 " 599 (BC_2, *, controlr, 1)," & " 600 (BC_2, IO_AA11, output3, X, 599, 1, Z)," & -- PAD16 " 601 (BC_2, IO_AA11, input, X)," & -- PAD16 " 602 (BC_2, *, controlr, 1)," & " 603 (BC_2, IO_AB12, output3, X, 602, 1, Z)," & -- PAD15 " 604 (BC_2, IO_AB12, input, X)," & -- PAD15 " 605 (BC_2, *, controlr, 1)," & " 606 (BC_2, IO_AA12, output3, X, 605, 1, Z)," & -- PAD14 " 607 (BC_2, IO_AA12, input, X)," & -- PAD14 " 608 (BC_2, *, controlr, 1)," & " 609 (BC_2, IO_U9, output3, X, 608, 1, Z)," & -- PAD13 " 610 (BC_2, IO_U9, input, X)," & -- PAD13 " 611 (BC_2, *, controlr, 1)," & " 612 (BC_2, IO_U10, output3, X, 611, 1, Z)," & -- PAD12 " 613 (BC_2, IO_U10, input, X)," & -- PAD12 " 614 (BC_2, *, controlr, 1)," & " 615 (BC_2, IO_U11, output3, X, 614, 1, Z)," & -- PAD11 " 616 (BC_2, IO_U11, input, X)," & -- PAD11 " 617 (BC_2, *, controlr, 1)," & " 618 (BC_2, IO_U12, output3, X, 617, 1, Z)," & -- PAD10 " 619 (BC_2, IO_U12, input, X)," & -- PAD10 " 620 (BC_2, *, controlr, 1)," & " 621 (BC_2, IO_W12, output3, X, 620, 1, Z)," & -- PAD9 " 622 (BC_2, IO_W12, input, X)," & -- PAD9 " 623 (BC_2, *, controlr, 1)," & " 624 (BC_2, IO_V12, output3, X, 623, 1, Z)," & -- PAD8 " 625 (BC_2, IO_V12, input, X)," & -- PAD8 " 626 (BC_2, *, controlr, 1)," & " 627 (BC_2, IO_W10, output3, X, 626, 1, Z)," & -- PAD7 " 628 (BC_2, IO_W10, input, X)," & -- PAD7 " 629 (BC_2, *, controlr, 1)," & " 630 (BC_2, IO_W11, output3, X, 629, 1, Z)," & -- PAD6 " 631 (BC_2, IO_W11, input, X)," & -- PAD6 " 632 (BC_2, *, controlr, 1)," & " 633 (BC_2, IO_W8, output3, X, 632, 1, Z)," & -- PAD5 " 634 (BC_2, IO_W8, input, X)," & -- PAD5 " 635 (BC_2, *, controlr, 1)," & " 636 (BC_2, IO_V8, output3, X, 635, 1, Z)," & -- PAD4 " 637 (BC_2, IO_V8, input, X)," & -- PAD4 " 638 (BC_2, *, controlr, 1)," & " 639 (BC_2, IO_V9, output3, X, 638, 1, Z)," & -- PAD3 " 640 (BC_2, IO_V9, input, X)," & -- PAD3 " 641 (BC_2, *, controlr, 1)," & " 642 (BC_2, IO_V10, output3, X, 641, 1, Z)," & -- PAD2 " 643 (BC_2, IO_V10, input, X)," & -- PAD2 " 644 (BC_2, *, controlr, 1)," & " 645 (BC_2, IO_R7, output3, X, 644, 1, Z)," & -- PAD1 " 646 (BC_2, IO_R7, input, X)," & -- PAD1 " 647 (BC_2, *, controlr, 1)," & " 648 (BC_2, PS_DDR_DQ31, output3, X, 647, 1, Z)," & " 649 (BC_2, PS_DDR_DQ31, input, X)," & " 650 (BC_2, *, controlr, 1)," & " 651 (BC_2, PS_DDR_DQ30, output3, X, 650, 1, Z)," & " 652 (BC_2, PS_DDR_DQ30, input, X)," & " 653 (BC_2, *, controlr, 1)," & " 654 (BC_2, PS_DDR_DQ29, output3, X, 653, 1, Z)," & " 655 (BC_2, PS_DDR_DQ29, input, X)," & " 656 (BC_2, *, controlr, 1)," & " 657 (BC_2, PS_DDR_DQ28, output3, X, 656, 1, Z)," & " 658 (BC_2, PS_DDR_DQ28, input, X)," & " 659 (BC_2, *, controlr, 1)," & " 660 (BC_2, PS_DDR_DQS_N3, output3, X, 659, 1, Z)," & " 661 (BC_2, PS_DDR_DQS_N3, input, X)," & " 662 (BC_2, *, controlr, 1)," & " 663 (BC_2, PS_DDR_DQS_P3, output3, X, 662, 1, Z)," & " 664 (BC_2, PS_DDR_DQS_P3, input, X)," & " 665 (BC_2, *, internal, 1)," & " 666 (BC_2, *, internal, X)," & " 667 (BC_2, *, internal, X)," & " 668 (BC_2, *, controlr, 1)," & " 669 (BC_2, PS_DDR_DM3, output3, X, 668, 1, Z)," & " 670 (BC_2, PS_DDR_DM3, input, X)," & " 671 (BC_2, *, controlr, 1)," & " 672 (BC_2, PS_DDR_DQ27, output3, X, 671, 1, Z)," & " 673 (BC_2, PS_DDR_DQ27, input, X)," & " 674 (BC_2, *, controlr, 1)," & " 675 (BC_2, PS_DDR_DQ26, output3, X, 674, 1, Z)," & " 676 (BC_2, PS_DDR_DQ26, input, X)," & " 677 (BC_2, *, controlr, 1)," & " 678 (BC_2, PS_DDR_DQ25, output3, X, 677, 1, Z)," & " 679 (BC_2, PS_DDR_DQ25, input, X)," & " 680 (BC_2, *, controlr, 1)," & " 681 (BC_2, PS_DDR_DQ24, output3, X, 680, 1, Z)," & " 682 (BC_2, PS_DDR_DQ24, input, X)," & " 683 (BC_2, *, internal, X)," & " 684 (BC_2, *, internal, X)," & " 685 (BC_2, *, internal, X)," & " 686 (BC_2, *, internal, 1)," & " 687 (BC_2, *, internal, X)," & " 688 (BC_2, *, internal, X)," & " 689 (BC_2, *, controlr, 1)," & " 690 (BC_2, PS_DDR_DQ23, output3, X, 689, 1, Z)," & " 691 (BC_2, PS_DDR_DQ23, input, X)," & " 692 (BC_2, *, controlr, 1)," & " 693 (BC_2, PS_DDR_DQ22, output3, X, 692, 1, Z)," & " 694 (BC_2, PS_DDR_DQ22, input, X)," & " 695 (BC_2, *, controlr, 1)," & " 696 (BC_2, PS_DDR_DQ21, output3, X, 695, 1, Z)," & " 697 (BC_2, PS_DDR_DQ21, input, X)," & " 698 (BC_2, *, controlr, 1)," & " 699 (BC_2, PS_DDR_DQ20, output3, X, 698, 1, Z)," & " 700 (BC_2, PS_DDR_DQ20, input, X)," & " 701 (BC_2, *, controlr, 1)," & " 702 (BC_2, PS_DDR_DQS_N2, output3, X, 701, 1, Z)," & " 703 (BC_2, PS_DDR_DQS_N2, input, X)," & " 704 (BC_2, *, controlr, 1)," & " 705 (BC_2, PS_DDR_DQS_P2, output3, X, 704, 1, Z)," & " 706 (BC_2, PS_DDR_DQS_P2, input, X)," & " 707 (BC_2, *, internal, 1)," & " 708 (BC_2, *, internal, X)," & " 709 (BC_2, *, internal, X)," & " 710 (BC_2, *, controlr, 1)," & " 711 (BC_2, PS_DDR_DM2, output3, X, 710, 1, Z)," & " 712 (BC_2, PS_DDR_DM2, input, X)," & " 713 (BC_2, *, controlr, 1)," & " 714 (BC_2, PS_DDR_DQ19, output3, X, 713, 1, Z)," & " 715 (BC_2, PS_DDR_DQ19, input, X)," & " 716 (BC_2, *, controlr, 1)," & " 717 (BC_2, PS_DDR_DQ18, output3, X, 716, 1, Z)," & " 718 (BC_2, PS_DDR_DQ18, input, X)," & " 719 (BC_2, *, controlr, 1)," & " 720 (BC_2, PS_DDR_DQ17, output3, X, 719, 1, Z)," & " 721 (BC_2, PS_DDR_DQ17, input, X)," & " 722 (BC_2, *, controlr, 1)," & " 723 (BC_2, PS_DDR_DQ16, output3, X, 722, 1, Z)," & " 724 (BC_2, PS_DDR_DQ16, input, X)," & " 725 (BC_2, *, controlr, 1)," & " 726 (BC_2, PS_DDR_RAS_B, output3, X, 725, 1, Z)," & " 727 (BC_2, PS_DDR_RAS_B, input, X)," & " 728 (BC_2, *, controlr, 1)," & " 729 (BC_2, PS_DDR_CAS_B, output3, X, 728, 1, Z)," & " 730 (BC_2, PS_DDR_CAS_B, input, X)," & " 731 (BC_2, *, controlr, 1)," & " 732 (BC_2, PS_DDR_WE_B, output3, X, 731, 1, Z)," & " 733 (BC_2, PS_DDR_WE_B, input, X)," & " 734 (BC_2, *, controlr, 1)," & " 735 (BC_2, PS_DDR_CKE, output3, X, 734, 1, Z)," & " 736 (BC_2, PS_DDR_CKE, input, X)," & " 737 (BC_2, *, controlr, 1)," & " 738 (BC_2, PS_DDR_CS_B, output3, X, 737, 1, Z)," & " 739 (BC_2, PS_DDR_CS_B, input, X)," & " 740 (BC_2, *, controlr, 1)," & " 741 (BC_2, PS_DDR_ODT, output3, X, 740, 1, Z)," & " 742 (BC_2, PS_DDR_ODT, input, X)," & " 743 (BC_2, *, controlr, 1)," & " 744 (BC_2, PS_DDR_BA0, output3, X, 743, 1, Z)," & " 745 (BC_2, PS_DDR_BA0, input, X)," & " 746 (BC_2, *, controlr, 1)," & " 747 (BC_2, PS_DDR_BA1, output3, X, 746, 1, Z)," & " 748 (BC_2, PS_DDR_BA1, input, X)," & " 749 (BC_2, *, controlr, 1)," & " 750 (BC_2, PS_DDR_BA2, output3, X, 749, 1, Z)," & " 751 (BC_2, PS_DDR_BA2, input, X)," & " 752 (BC_2, *, controlr, 1)," & " 753 (BC_2, PS_DDR_A0, output3, X, 752, 1, Z)," & " 754 (BC_2, PS_DDR_A0, input, X)," & " 755 (BC_2, *, controlr, 1)," & " 756 (BC_2, PS_DDR_A1, output3, X, 755, 1, Z)," & " 757 (BC_2, PS_DDR_A1, input, X)," & " 758 (BC_2, *, controlr, 1)," & " 759 (BC_2, PS_DDR_A2, output3, X, 758, 1, Z)," & " 760 (BC_2, PS_DDR_A2, input, X)," & " 761 (BC_2, *, controlr, 1)," & " 762 (BC_2, PS_DDR_CKN, output3, X, 761, 1, Z)," & " 763 (BC_2, PS_DDR_CKN, input, X)," & " 764 (BC_2, *, controlr, 1)," & " 765 (BC_2, PS_DDR_CKP, output3, X, 764, 1, Z)," & " 766 (BC_2, PS_DDR_CKP, input, X)," & " 767 (BC_2, *, controlr, 1)," & " 768 (BC_2, PS_DDR_VRN, output3, X, 767, 1, Z)," & " 769 (BC_2, PS_DDR_VRN, input, X)," & " 770 (BC_2, *, controlr, 1)," & " 771 (BC_2, PS_DDR_VRP, output3, X, 770, 1, Z)," & " 772 (BC_2, PS_DDR_VRP, input, X)," & " 773 (BC_2, *, controlr, 1)," & " 774 (BC_2, PS_DDR_A3, output3, X, 773, 1, Z)," & " 775 (BC_2, PS_DDR_A3, input, X)," & " 776 (BC_2, *, controlr, 1)," & " 777 (BC_2, PS_DDR_A4, output3, X, 776, 1, Z)," & " 778 (BC_2, PS_DDR_A4, input, X)," & " 779 (BC_2, *, controlr, 1)," & " 780 (BC_2, PS_DDR_A5, output3, X, 779, 1, Z)," & " 781 (BC_2, PS_DDR_A5, input, X)," & " 782 (BC_2, *, controlr, 1)," & " 783 (BC_2, PS_DDR_A6, output3, X, 782, 1, Z)," & " 784 (BC_2, PS_DDR_A6, input, X)," & " 785 (BC_2, *, controlr, 1)," & " 786 (BC_2, PS_DDR_A7, output3, X, 785, 1, Z)," & " 787 (BC_2, PS_DDR_A7, input, X)," & " 788 (BC_2, *, controlr, 1)," & " 789 (BC_2, PS_DDR_A8, output3, X, 788, 1, Z)," & " 790 (BC_2, PS_DDR_A8, input, X)," & " 791 (BC_2, *, controlr, 1)," & " 792 (BC_2, PS_DDR_A9, output3, X, 791, 1, Z)," & " 793 (BC_2, PS_DDR_A9, input, X)," & " 794 (BC_2, *, controlr, 1)," & " 795 (BC_2, PS_DDR_A10, output3, X, 794, 1, Z)," & " 796 (BC_2, PS_DDR_A10, input, X)," & " 797 (BC_2, *, controlr, 1)," & " 798 (BC_2, PS_DDR_A11, output3, X, 797, 1, Z)," & " 799 (BC_2, PS_DDR_A11, input, X)," & " 800 (BC_2, *, controlr, 1)," & " 801 (BC_2, PS_DDR_A12, output3, X, 800, 1, Z)," & " 802 (BC_2, PS_DDR_A12, input, X)," & " 803 (BC_2, *, controlr, 1)," & " 804 (BC_2, PS_DDR_A13, output3, X, 803, 1, Z)," & " 805 (BC_2, PS_DDR_A13, input, X)," & " 806 (BC_2, *, controlr, 1)," & " 807 (BC_2, PS_DDR_A14, output3, X, 806, 1, Z)," & " 808 (BC_2, PS_DDR_A14, input, X)," & " 809 (BC_2, *, controlr, 1)," & " 810 (BC_2, PS_DDR_DQ15, output3, X, 809, 1, Z)," & " 811 (BC_2, PS_DDR_DQ15, input, X)," & " 812 (BC_2, *, controlr, 1)," & " 813 (BC_2, PS_DDR_DQ14, output3, X, 812, 1, Z)," & " 814 (BC_2, PS_DDR_DQ14, input, X)," & " 815 (BC_2, *, controlr, 1)," & " 816 (BC_2, PS_DDR_DQ13, output3, X, 815, 1, Z)," & " 817 (BC_2, PS_DDR_DQ13, input, X)," & " 818 (BC_2, *, controlr, 1)," & " 819 (BC_2, PS_DDR_DQ12, output3, X, 818, 1, Z)," & " 820 (BC_2, PS_DDR_DQ12, input, X)," & " 821 (BC_2, *, controlr, 1)," & " 822 (BC_2, PS_DDR_DQS_N1, output3, X, 821, 1, Z)," & " 823 (BC_2, PS_DDR_DQS_N1, input, X)," & " 824 (BC_2, *, controlr, 1)," & " 825 (BC_2, PS_DDR_DQS_P1, output3, X, 824, 1, Z)," & " 826 (BC_2, PS_DDR_DQS_P1, input, X)," & " 827 (BC_2, *, internal, 1)," & " 828 (BC_2, *, internal, X)," & " 829 (BC_2, *, internal, X)," & " 830 (BC_2, *, controlr, 1)," & " 831 (BC_2, PS_DDR_DM1, output3, X, 830, 1, Z)," & " 832 (BC_2, PS_DDR_DM1, input, X)," & " 833 (BC_2, *, controlr, 1)," & " 834 (BC_2, PS_DDR_DQ11, output3, X, 833, 1, Z)," & " 835 (BC_2, PS_DDR_DQ11, input, X)," & " 836 (BC_2, *, controlr, 1)," & " 837 (BC_2, PS_DDR_DQ10, output3, X, 836, 1, Z)," & " 838 (BC_2, PS_DDR_DQ10, input, X)," & " 839 (BC_2, *, controlr, 1)," & " 840 (BC_2, PS_DDR_DQ9, output3, X, 839, 1, Z)," & " 841 (BC_2, PS_DDR_DQ9, input, X)," & " 842 (BC_2, *, controlr, 1)," & " 843 (BC_2, PS_DDR_DQ8, output3, X, 842, 1, Z)," & " 844 (BC_2, PS_DDR_DQ8, input, X)," & " 845 (BC_2, *, internal, X)," & " 846 (BC_2, *, internal, X)," & " 847 (BC_2, *, internal, X)," & " 848 (BC_2, *, internal, 1)," & " 849 (BC_2, *, internal, X)," & " 850 (BC_2, *, internal, X)," & " 851 (BC_2, *, controlr, 1)," & " 852 (BC_2, PS_DDR_DQ7, output3, X, 851, 1, Z)," & " 853 (BC_2, PS_DDR_DQ7, input, X)," & " 854 (BC_2, *, controlr, 1)," & " 855 (BC_2, PS_DDR_DQ6, output3, X, 854, 1, Z)," & " 856 (BC_2, PS_DDR_DQ6, input, X)," & " 857 (BC_2, *, controlr, 1)," & " 858 (BC_2, PS_DDR_DQ5, output3, X, 857, 1, Z)," & " 859 (BC_2, PS_DDR_DQ5, input, X)," & " 860 (BC_2, *, controlr, 1)," & " 861 (BC_2, PS_DDR_DQ4, output3, X, 860, 1, Z)," & " 862 (BC_2, PS_DDR_DQ4, input, X)," & " 863 (BC_2, *, controlr, 1)," & " 864 (BC_2, PS_DDR_DQS_N0, output3, X, 863, 1, Z)," & " 865 (BC_2, PS_DDR_DQS_N0, input, X)," & " 866 (BC_2, *, controlr, 1)," & " 867 (BC_2, PS_DDR_DQS_P0, output3, X, 866, 1, Z)," & " 868 (BC_2, PS_DDR_DQS_P0, input, X)," & " 869 (BC_2, *, internal, 1)," & " 870 (BC_2, *, internal, X)," & " 871 (BC_2, *, internal, X)," & " 872 (BC_2, *, controlr, 1)," & " 873 (BC_2, PS_DDR_DM0, output3, X, 872, 1, Z)," & " 874 (BC_2, PS_DDR_DM0, input, X)," & " 875 (BC_2, *, controlr, 1)," & " 876 (BC_2, PS_DDR_DQ3, output3, X, 875, 1, Z)," & " 877 (BC_2, PS_DDR_DQ3, input, X)," & " 878 (BC_2, *, controlr, 1)," & " 879 (BC_2, PS_DDR_DQ2, output3, X, 878, 1, Z)," & " 880 (BC_2, PS_DDR_DQ2, input, X)," & " 881 (BC_2, *, controlr, 1)," & " 882 (BC_2, PS_DDR_DQ1, output3, X, 881, 1, Z)," & " 883 (BC_2, PS_DDR_DQ1, input, X)," & " 884 (BC_2, *, controlr, 1)," & " 885 (BC_2, PS_DDR_DQ0, output3, X, 884, 1, Z)," & " 886 (BC_2, PS_DDR_DQ0, input, X)," & " 887 (BC_2, *, controlr, 1)," & " 888 (BC_2, PS_DDR_DRST_B, output3, X, 887, 1, Z)," & " 889 (BC_2, PS_DDR_DRST_B, input, X)," & " 890 (BC_2, *, controlr, 1)," & " 891 (BC_2, PS_MIO0, output3, X, 890, 1, Z)," & " 892 (BC_2, PS_MIO0, input, X)," & " 893 (BC_2, *, controlr, 1)," & " 894 (BC_2, PS_MIO1, output3, X, 893, 1, Z)," & " 895 (BC_2, PS_MIO1, input, X)," & " 896 (BC_2, *, controlr, 1)," & " 897 (BC_2, PS_MIO2, output3, X, 896, 1, Z)," & " 898 (BC_2, PS_MIO2, input, X)," & " 899 (BC_2, *, controlr, 1)," & " 900 (BC_2, PS_MIO3, output3, X, 899, 1, Z)," & " 901 (BC_2, PS_MIO3, input, X)," & " 902 (BC_2, *, controlr, 1)," & " 903 (BC_2, PS_MIO4, output3, X, 902, 1, Z)," & " 904 (BC_2, PS_MIO4, input, X)," & " 905 (BC_2, *, controlr, 1)," & " 906 (BC_2, PS_MIO5, output3, X, 905, 1, Z)," & " 907 (BC_2, PS_MIO5, input, X)," & " 908 (BC_2, *, controlr, 1)," & " 909 (BC_2, PS_MIO6, output3, X, 908, 1, Z)," & " 910 (BC_2, PS_MIO6, input, X)," & " 911 (BC_2, *, controlr, 1)," & " 912 (BC_2, PS_MIO7, output3, X, 911, 1, Z)," & " 913 (BC_2, PS_MIO7, input, X)," & " 914 (BC_2, *, controlr, 1)," & " 915 (BC_2, PS_MIO8, output3, X, 914, 1, Z)," & " 916 (BC_2, PS_MIO8, input, X)," & " 917 (BC_2, *, controlr, 1)," & " 918 (BC_2, PS_MIO9, output3, X, 917, 1, Z)," & " 919 (BC_2, PS_MIO9, input, X)," & " 920 (BC_2, *, controlr, 1)," & " 921 (BC_2, PS_MIO10, output3, X, 920, 1, Z)," & " 922 (BC_2, PS_MIO10, input, X)," & " 923 (BC_2, *, controlr, 1)," & " 924 (BC_2, PS_MIO11, output3, X, 923, 1, Z)," & " 925 (BC_2, PS_MIO11, input, X)," & " 926 (BC_2, *, controlr, 1)," & " 927 (BC_2, PS_MIO12, output3, X, 926, 1, Z)," & " 928 (BC_2, PS_MIO12, input, X)," & " 929 (BC_2, *, controlr, 1)," & " 930 (BC_2, PS_MIO13, output3, X, 929, 1, Z)," & " 931 (BC_2, PS_MIO13, input, X)," & " 932 (BC_2, *, controlr, 1)," & " 933 (BC_2, PS_MIO14, output3, X, 932, 1, Z)," & " 934 (BC_2, PS_MIO14, input, X)," & " 935 (BC_2, *, controlr, 1)," & " 936 (BC_2, PS_MIO15, output3, X, 935, 1, Z)," & " 937 (BC_2, PS_MIO15, input, X)," & " 938 (BC_2, *, internal, 1)," & " 939 (BC_2, *, internal, X)," & " 940 (BC_2, PS_POR_B, input, X)," & " 941 (BC_2, *, internal, 1)," & " 942 (BC_2, *, internal, X)," & " 943 (BC_2, PS_CLK, input, X)," & " 944 (BC_2, *, controlr, 1)," & " 945 (BC_2, PS_MIO16, output3, X, 944, 1, Z)," & " 946 (BC_2, PS_MIO16, input, X)," & " 947 (BC_2, *, controlr, 1)," & " 948 (BC_2, PS_MIO17, output3, X, 947, 1, Z)," & " 949 (BC_2, PS_MIO17, input, X)," & " 950 (BC_2, *, controlr, 1)," & " 951 (BC_2, PS_MIO18, output3, X, 950, 1, Z)," & " 952 (BC_2, PS_MIO18, input, X)," & " 953 (BC_2, *, controlr, 1)," & " 954 (BC_2, PS_MIO19, output3, X, 953, 1, Z)," & " 955 (BC_2, PS_MIO19, input, X)," & " 956 (BC_2, *, controlr, 1)," & " 957 (BC_2, PS_MIO20, output3, X, 956, 1, Z)," & " 958 (BC_2, PS_MIO20, input, X)," & " 959 (BC_2, *, controlr, 1)," & " 960 (BC_2, PS_MIO21, output3, X, 959, 1, Z)," & " 961 (BC_2, PS_MIO21, input, X)," & " 962 (BC_2, *, controlr, 1)," & " 963 (BC_2, PS_MIO22, output3, X, 962, 1, Z)," & " 964 (BC_2, PS_MIO22, input, X)," & " 965 (BC_2, *, controlr, 1)," & " 966 (BC_2, PS_MIO23, output3, X, 965, 1, Z)," & " 967 (BC_2, PS_MIO23, input, X)," & " 968 (BC_2, *, controlr, 1)," & " 969 (BC_2, PS_MIO24, output3, X, 968, 1, Z)," & " 970 (BC_2, PS_MIO24, input, X)," & " 971 (BC_2, *, controlr, 1)," & " 972 (BC_2, PS_MIO25, output3, X, 971, 1, Z)," & " 973 (BC_2, PS_MIO25, input, X)," & " 974 (BC_2, *, controlr, 1)," & " 975 (BC_2, PS_MIO26, output3, X, 974, 1, Z)," & " 976 (BC_2, PS_MIO26, input, X)," & " 977 (BC_2, *, controlr, 1)," & " 978 (BC_2, PS_MIO27, output3, X, 977, 1, Z)," & " 979 (BC_2, PS_MIO27, input, X)," & " 980 (BC_2, *, controlr, 1)," & " 981 (BC_2, PS_MIO28, output3, X, 980, 1, Z)," & " 982 (BC_2, PS_MIO28, input, X)," & " 983 (BC_2, *, controlr, 1)," & " 984 (BC_2, PS_MIO29, output3, X, 983, 1, Z)," & " 985 (BC_2, PS_MIO29, input, X)," & " 986 (BC_2, *, controlr, 1)," & " 987 (BC_2, PS_MIO30, output3, X, 986, 1, Z)," & " 988 (BC_2, PS_MIO30, input, X)," & " 989 (BC_2, *, controlr, 1)," & " 990 (BC_2, PS_MIO31, output3, X, 989, 1, Z)," & " 991 (BC_2, PS_MIO31, input, X)," & " 992 (BC_2, *, controlr, 1)," & " 993 (BC_2, PS_MIO32, output3, X, 992, 1, Z)," & " 994 (BC_2, PS_MIO32, input, X)," & " 995 (BC_2, *, controlr, 1)," & " 996 (BC_2, PS_MIO33, output3, X, 995, 1, Z)," & " 997 (BC_2, PS_MIO33, input, X)," & " 998 (BC_2, *, controlr, 1)," & " 999 (BC_2, PS_MIO34, output3, X, 998, 1, Z)," & "1000 (BC_2, PS_MIO34, input, X)," & "1001 (BC_2, *, controlr, 1)," & "1002 (BC_2, PS_MIO35, output3, X, 1001, 1, Z)," & "1003 (BC_2, PS_MIO35, input, X)," & "1004 (BC_2, *, controlr, 1)," & "1005 (BC_2, PS_MIO36, output3, X, 1004, 1, Z)," & "1006 (BC_2, PS_MIO36, input, X)," & "1007 (BC_2, *, internal, 1)," & "1008 (BC_2, *, internal, X)," & "1009 (BC_2, PS_MIO_VREF, input, X)," & "1010 (BC_2, *, controlr, 1)," & "1011 (BC_2, PS_MIO37, output3, X, 1010, 1, Z)," & "1012 (BC_2, PS_MIO37, input, X)," & "1013 (BC_2, *, controlr, 1)," & "1014 (BC_2, PS_MIO38, output3, X, 1013, 1, Z)," & "1015 (BC_2, PS_MIO38, input, X)," & "1016 (BC_2, *, controlr, 1)," & "1017 (BC_2, PS_MIO39, output3, X, 1016, 1, Z)," & "1018 (BC_2, PS_MIO39, input, X)," & "1019 (BC_2, *, controlr, 1)," & "1020 (BC_2, PS_MIO40, output3, X, 1019, 1, Z)," & "1021 (BC_2, PS_MIO40, input, X)," & "1022 (BC_2, *, controlr, 1)," & "1023 (BC_2, PS_MIO41, output3, X, 1022, 1, Z)," & "1024 (BC_2, PS_MIO41, input, X)," & "1025 (BC_2, *, controlr, 1)," & "1026 (BC_2, PS_MIO42, output3, X, 1025, 1, Z)," & "1027 (BC_2, PS_MIO42, input, X)," & "1028 (BC_2, *, controlr, 1)," & "1029 (BC_2, PS_MIO43, output3, X, 1028, 1, Z)," & "1030 (BC_2, PS_MIO43, input, X)," & "1031 (BC_2, *, controlr, 1)," & "1032 (BC_2, PS_MIO44, output3, X, 1031, 1, Z)," & "1033 (BC_2, PS_MIO44, input, X)," & "1034 (BC_2, *, controlr, 1)," & "1035 (BC_2, PS_MIO45, output3, X, 1034, 1, Z)," & "1036 (BC_2, PS_MIO45, input, X)," & "1037 (BC_2, *, controlr, 1)," & "1038 (BC_2, PS_MIO46, output3, X, 1037, 1, Z)," & "1039 (BC_2, PS_MIO46, input, X)," & "1040 (BC_2, *, controlr, 1)," & "1041 (BC_2, PS_MIO47, output3, X, 1040, 1, Z)," & "1042 (BC_2, PS_MIO47, input, X)," & "1043 (BC_2, *, controlr, 1)," & "1044 (BC_2, PS_MIO48, output3, X, 1043, 1, Z)," & "1045 (BC_2, PS_MIO48, input, X)," & "1046 (BC_2, *, controlr, 1)," & "1047 (BC_2, PS_MIO49, output3, X, 1046, 1, Z)," & "1048 (BC_2, PS_MIO49, input, X)," & "1049 (BC_2, *, controlr, 1)," & "1050 (BC_2, PS_MIO50, output3, X, 1049, 1, Z)," & "1051 (BC_2, PS_MIO50, input, X)," & "1052 (BC_2, *, controlr, 1)," & "1053 (BC_2, PS_MIO51, output3, X, 1052, 1, Z)," & "1054 (BC_2, PS_MIO51, input, X)," & "1055 (BC_2, *, controlr, 1)," & "1056 (BC_2, PS_MIO52, output3, X, 1055, 1, Z)," & "1057 (BC_2, PS_MIO52, input, X)," & "1058 (BC_2, *, controlr, 1)," & "1059 (BC_2, PS_MIO53, output3, X, 1058, 1, Z)," & "1060 (BC_2, PS_MIO53, input, X)," & "1061 (BC_2, *, internal, 1)," & "1062 (BC_2, *, internal, X)," & "1063 (BC_2, PS_SRST_B, input, X)," & "1064 (BC_2, *, internal, X)," & "1065 (BC_2, *, internal, X)," & "1066 (BC_2, *, internal, X)," & "1067 (BC_2, *, internal, X)," & "1068 (BC_2, *, internal, X)," & "1069 (BC_2, *, internal, X)," & "1070 (BC_2, *, internal, X)," & "1071 (BC_2, *, internal, X)," & "1072 (BC_2, *, internal, X)," & "1073 (BC_2, *, internal, X)," & "1074 (BC_2, *, internal, X)," & "1075 (BC_2, *, internal, X)," & "1076 (BC_2, *, internal, X)"; -- Advanced I/O Description attribute AIO_COMPONENT_CONFORMANCE of XC7Z020_CLG484 : entity is "STD_1149_6_2003"; attribute AIO_EXTEST_Pulse_Execution of XC7Z020_CLG484 : entity is "Wait_Duration TCK 15"; attribute AIO_EXTEST_Train_Execution of XC7Z020_CLG484 : entity is "train 30, maximum_time 120.0e-6"; -- Design Warning Section attribute DESIGN_WARNING of XC7Z020_CLG484 : entity is "This is a preliminary BSDL file which has not been verified." & "When no bitstream is loaded and GTPs are not instantiated," & "the boundary-scan cells associated with GTPs will not" & "capture correct state information. To model the boundary-" & "scan cell behavior correctly post-configuration, use" & "BSDLanno to modify the BSDL file." & "This BSDL file must be modified by the FPGA designer in order to" & "reflect post-configuration behavior (if any)." & "To avoid losing the current configuration, the boundary scan" & "test vectors should keep the PROGRAM_B pin" & "high. If the PROGRAM_B pin goes low by any means," & "the configuration will be cleared." & "PROGRAM_B can only be captured, not updated." & "The value at the pin is always used by the device." & "In EXTEST, output and tristate values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "Differential Serial IO pins do not support INTEST." & "In INTEST, the pin input values are not captured in the" & "Capture-DR state - those register cells are unchanged." & "The output and tristate capture values are not valid until after" & "the device is configured." & "The tristate control value is not captured properly when" & "GTS is activated." & "The IEEE Std 1149.6 EXTEST_PULSE and EXTEST_TRAIN instructions" & "require a minimum TCK freq of 15 MHz and min temp of 0C." & "NOCONNECT pins should not be connected to any supply" & "or GND. They should be left floating." & "PSS IOs do not support INTEST" & "PSS IOs do not support cfg_ts which is asserted for TSC instructions" & "BSCAN is not available if the PSS power supplies are not applied" & "PS_POR_B can only be captured, not updated." & "The value at the pin is always used by the device."; end XC7Z020_CLG484; ================================================ FILE: jtag/digilent-hs1.cfg ================================================ # # Digilent HS1 # # The Digilent HS1 is a high-speed FT2232H-based adapter, compliant with the # Xilinx JTAG 14-pin pinout. # It does not support ARM reset signals (SRST and TRST) but can still be used for # hardware debugging, with some limitations. # # http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,922&Prod=JTAG-HS1 # interface ft2232 ft2232_device_desc "Digilent Adept USB Device" ft2232_layout digilent-hs1 ft2232_vid_pid 0x0403 0x6010 adapter_khz 100 ================================================ FILE: jtag/digilent-hs2.cfg ================================================ # # high-speed FT232H-based adapter, compliant with the # Xilinx JTAG 14-pin pinout. # interface ft2232 ft2232_layout digilent-hs1 ft2232_vid_pid 0x0403 0x6014 adapter_khz 100 ================================================ FILE: jtag/dumptrace.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import sys print('dumptrace: opening', sys.argv[1]) lines = open(sys.argv[1]).readlines() print('len', len(lines)) addressarr = [] for thisline in lines: thisline = thisline.strip() if thisline.find(' ') >= 0 or thisline.startswith('http:'): continue #print('LL', thisline) addressarr.append(int(thisline, 16)) if addressarr.pop() != 0xaaaabbbb or addressarr.pop() != 0xdeadbeef: printf('dumptrace: incomplete read of trace data') sys.exit(1) while len(addressarr) > 0 and addressarr[0] == 0xdeadbeef: #remove leading entries in case the trace buffer was never really full addressarr.pop(0) for item in addressarr: transname = ['REQ ', 'REQR', ' IND ', ' INDR']; topbits = item >> 18 fpganumber = (item >> 16) & 0x7 transtype = (item >> 14) & 0x3 channel = (item >> 8) & 0x3f bottombits = item & 0xff if topbits != 0x1b90: print('dumptrace: address is not in m_axi_gp[0] range', format(topbits, '05x')) fpganame = 'Dir ' channelname = ' ' if fpganumber != 0: fpganame = 'fpga'+format(fpganumber, 'x') channelname = 'channel ' + format(channel, 'x') elif channel != 2: channelname = 'channel ' + format(channel, 'x') if bottombits & 0x3 != 0: print('dumptrace: LSB are not 32 word aligned') print(fpganame, transname[transtype], channelname, format(bottombits >> 2, '2x')) ================================================ FILE: jtag/kc705.cfg ================================================ source digilent-hs1.cfg jtag newtap kc705 tap -irlen 6 -ircapture 0x01 -expected-id 0x43651093 verify_jtag init scan_chain #drscan kc705 irscan kc705.tap 9 set idreg [drscan kc705.tap 64 0] #runtest 10 irscan kc705.tap 1 set usrreg [drscan kc705.tap 64 0] echo "idreg "$idreg echo "usrreg "$usrreg irscan kc705.tap 2 echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] echo "USER1 "[drscan kc705.tap 64 00] irscan kc705.tap 3 echo "USER2 "[drscan kc705.tap 64 0] #svf -tap kc705.tap foo.test shutdown ================================================ FILE: jtag/kc705program.cfg ================================================ source digilent-hs1.cfg jtag newtap kc705 tap -irlen 6 -ircapture 0x01 -expected-id 0x43651093 # configuration sequence from ug470_7Series_Config.pdf, # Chapter5: Configuration Details; Section: Configuration Sequence # pp 74-81 # init scan_chain # Clear Configuration Memory (Step 2, Initialization) # JPROGRAM irscan kc705.tap 0xb echo "JPROGRAM "[drscan kc705.tap 64 0] # Check Device ID (Step 5) irscan kc705.tap 9 echo "IDCODE "[drscan kc705.tap 32 0] verify_jtag disable # Load Configuration Data Frames (Step 6) irscan kc705.tap 5 drscan kc705.tap -infile mkPcieTop.bin verify_jtag enable #check IDCODE again.... irscan kc705.tap 9 echo "IDCODE "[drscan kc705.tap 32 0] # Cyclic Redundancy Check (Step 7) # Startup (Step 8) irscan kc705.tap 0xc echo "STARTUP "[drscan kc705.tap 32 0] #check IDCODE again.... irscan kc705.tap 9 echo "IDCODE "[drscan kc705.tap 32 0] shutdown # "BYPASS (111111)," & -- BYPASS # "EXTEST (100110)," & -- BOUNDARY # "SAMPLE (000001)," & -- BOUNDARY # "PRELOAD (000001)," & -- Same as SAMPLE # "USERCODE (001000)," & -- DEVICE_ID # "HIGHZ (001010)," & -- BYPASS # "EXTEST_PULSE (111100)," & -- BOUNDARY # "EXTEST_TRAIN (111101)," & -- BOUNDARY # "ISC_ENABLE (010000)," & -- ISC_CONFIG # "ISC_PROGRAM (010001)," & -- ISC_PDATA # "ISC_NOOP (010100)," & -- ISC_DEFAULT # "XSC_READ_RSVD (010101)," & -- PRIVATE # "ISC_DISABLE (010110)," & -- ISC_CONFIG # "XSC_PROGRAM_KEY (010010)," & -- XSC_KEY_DATA # "XSC_DNA (010111)," & -- DNA # "CFG_OUT (000100)," & -- Not available during configuration with another mode. # "CFG_IN (000101)," & -- Not available during configuration with another mode. # "JSTART (001100)," & -- Not available during configuration with another mode. # "JSHUTDOWN (001101)," & -- Not available during configuration with another mode. # "XADC_DRP (110111)," & -- PRIVATE # "INTEST_RSVD (000111)"; -- PRIVATE ================================================ FILE: jtag/pcietrace.cfg ================================================ # # Digilent HS1 # # The Digilent HS1 is a high-speed FT2232H-based adapter, compliant with the # Xilinx JTAG 14-pin pinout. # It does not support ARM reset signals (SRST and TRST) but can still be used for # hardware debugging, with some limitations. # # http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,922&Prod=JTAG-HS1 # interface ft2232 ft2232_device_desc "Digilent Adept USB Device" ft2232_layout digilent-hs1 ft2232_vid_pid 0x0403 0x6010 adapter_khz 100 source digilent-hs1.cfg jtag newtap kc705 tap -irlen 6 -ircapture 0x01 -expected-id 0x43651093 verify_jtag init scan_chain #drscan kc705 irscan kc705.tap 9 set idreg [drscan kc705.tap 64 0] #runtest 10 irscan kc705.tap 1 set usrreg [drscan kc705.tap 64 0] echo "idreg "$idreg echo "usrreg "$usrreg irscan kc705.tap 2 for {set i 0} {$i < 2048} {incr i} { echo "USER1 "[drscan kc705.tap 192 00] } irscan kc705.tap 3 echo "USER2 "[drscan kc705.tap 192 0] #svf -tap kc705.tap foo.test shutdown ================================================ FILE: jtag/readll.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import sys def getbit(lastx, lasty): toff = 36 * int((lastx - 14)/2) if lastx >= 54: toff = toff + 2 + 4 * 28 elif lastx >= 50: # column X1 toff = toff + 2 + 3 * 28 elif lastx >= 36: toff = toff + 2 * 28 elif lastx >= 32: toff = toff + 28 if lasty <= 49: # row Y0 toff = toff + 2 * 2 * 1283 elif lasty <= 99: # row Y1 toff = toff + 2 * 1283 return toff def printval(starty, lastx, lasty, lastval): if starty == -1: return '' return ' %3d-%3d/%d' % (starty, lasty, lastval - getbit(lastx, lasty)) print('readll: opening', sys.argv[1]) lines = open(sys.argv[1]).readlines() print('len', len(lines)) i = 0 toplist = {} topoffset = {} topref = {} for thisline in lines: if thisline[0] == ';': continue iteml = thisline.split() if iteml[0] != 'Bit' or not iteml[4].startswith('Block=SLICE_X'): print('Non-Bit line', thisline.strip()) continue for i in range(3): iteml[i+1] = int(iteml[i+1], 0) bitoff = iteml[1] frameoffset = iteml[3] temp = iteml[4][13:] ind = temp.find('Y') coordx = int(temp[:ind]) coordy = int(temp[ind+1:]) itemtype = iteml[5] if itemtype.startswith('Ram='): continue if not itemtype.endswith('MUX'): itemtype = itemtype[:6] + ' ' + itemtype[6:] if not topoffset.get(itemtype): topoffset[itemtype] = {} if not topoffset[itemtype].get(frameoffset): topoffset[itemtype][frameoffset] = 0 topoffset[itemtype][frameoffset] = topoffset[itemtype][frameoffset] + 1 ftemp = frameoffset % 32 fmult = int(frameoffset/32) if not topref.get(ftemp): topref[ftemp] = {} if not topref[ftemp].get(itemtype): topref[ftemp][itemtype] = {} if not topref[ftemp][itemtype].get(fmult): topref[ftemp][itemtype][fmult] = 0 topref[ftemp][itemtype][fmult] = topref[ftemp][itemtype][fmult] + 1 toplist['%4d_%4d_%5d' % (coordx, coordy, frameoffset)] = [ coordx, coordy, (bitoff - frameoffset)/ 3232.0 - 467] lastx = 0 outstring = '' starty = -1 lasty = -1 lastval = -1 for key, value in sorted(toplist.items()): if value[0] != lastx: outstring = outstring + printval(starty, lastx, lasty, lastval) lastx = value[0] print(outstring) outstring = '%3d:' % value[0] starty = -1 if lastval != value[2]: outstring = outstring + printval(starty, lastx, lasty, lastval) starty = value[1] lasty = value[1] lastval = value[2] outstring = outstring + printval(starty, lastx, lasty, lastval) print(outstring) #for key, value in sorted(topoffset.items()): # outstring = key + ': ' # for vkey, vvalue in sorted(value.items()): # if vvalue != 1: # outstring = outstring + ' ' + str(vkey) + '/' + str(vvalue) # print(outstring) print('ref') for key, value in sorted(topref.items()): #print(key, value) for vkey, vvalue in sorted(value.items()): outstringhead = str(key) + '=' + vkey[6:].strip() + ':' outstring = outstringhead prevrkey = -1 for rkey, rvalue in sorted(vvalue.items()): if prevrkey != -1 and rkey != prevrkey + 2: print(outstring) outstring = ' ' + outstringhead prevrkey = -1 outstring = outstring + ' ' + str(rkey) if rvalue != 1: outstring = outstring + '/' + str(rvalue) prevrkey = rkey print(outstring) ================================================ FILE: jtag/run_jtag.sh ================================================ # set -e set -x #openocd -f kc705.cfg openocd -f zedboard.cfg ================================================ FILE: jtag/run_trace.sh ================================================ #/bin/bash set -x set -e openocd -f zedtrace.cfg 2>trace.xx.tempfile sed -e"s/\(.\)\(...\)\(....\)/\1 \2 \3 /" trace.log #rm -f trace.xx.tempfile ================================================ FILE: jtag/zedboard.cfg ================================================ source digilent-hs2.cfg jtag newtap zed tap -irlen 6 -ircapture 0x01 -expected-id 0x03727093 jtag newtap cortex tap -irlen 4 -ircapture 0x01 -expected-id 0x4ba00477 # targets cortex_a verify_jtag init scan_chain # clear bscan.sel() by setting IR to a different register irscan zed.tap 9 # try reading out USER1 register 000010 irscan zed.tap 2 echo "USER1="[drscan zed.tap 32 0xdeadbeef] irscan zed.tap 2 echo "USER1="[drscan zed.tap 32 0x12345678] irscan zed.tap 2 echo "USER1="[drscan zed.tap 32 0xabcdef01] # clear bscan.sel() by setting IR to a different register irscan zed.tap 9 # try reading out USER1 register 000010 irscan zed.tap 2 echo "USER1="[drscan zed.tap 32 0xaaaabbbb] irscan zed.tap 2 echo "USER1="[drscan zed.tap 32 0xccccdddd] irscan zed.tap 2 echo "USER1="[drscan zed.tap 32 0xeeeeffff] # clear bscan.sel() by setting IR to a different register irscan zed.tap 9 #svf -tap zed.tap foo.test #runtest 10 shutdown ================================================ FILE: jtag/zedtrace.cfg ================================================ source digilent-hs2.cfg jtag newtap zed tap -irlen 6 -ircapture 0x01 -expected-id 0x03727093 jtag newtap cortex tap -irlen 4 -ircapture 0x01 -expected-id 0x4ba00477 # targets cortex_a verify_jtag init scan_chain # clear bscan.sel() by setting IR to a different register irscan zed.tap 9 #echo [drscan zed.tap 64 0xffffffffffffffff] #echo [drscan zed.tap 64 0xffffffffffffffff] #echo [drscan zed.tap 64 0x0000000000000000] #echo [drscan zed.tap 64 0x0000000000000000] #echo [drscan zed.tap 64 0x00000000000000f0] for {set j 0} {$j < 4} {incr j} { # try reading out USER2 register 000011 irscan zed.tap 3 for {set i 0} {$i < 256 + 2} {incr i} { echo [drscan zed.tap 64 0xdeadbeefbeefdead] } sleep 1000 } # clear bscan.sel() by setting IR to a different register irscan zed.tap 9 shutdown ================================================ FILE: lib/bsv/Arith.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; function Bool booland(Bool x1, Bool x2); return x1 && x2; endfunction function Bool boolor(Bool x1, Bool x2); return x1 || x2; endfunction function Bool eq(a x1, a x2) provisos (Eq#(a)); return x1 == x2; endfunction function a add(a x1, a x2) provisos (Arith#(a)); return x1 + x2; endfunction function a mul(a x1, a x2) provisos (Arith#(a)); return x1 * x2; endfunction function Bit#(b) rshift(Bit#(b) x1, Integer i); return x1 >> i; endfunction function Vector#(n, a) vadd(Vector#(n, a) x1, Vector#(n, a) x2) provisos (Arith#(a)); return map(uncurry(add), zip(x1, x2)); endfunction function Vector#(n, a) vmul(Vector#(n, a) x1, Vector#(n, a) x2) provisos (Arith#(a)); return map(uncurry(mul), zip(x1, x2)); endfunction function Vector#(n, Bit#(b)) vrshift(Vector#(n, Bit#(b)) x1, Integer i); return map(flip(rshift)(i), x1); endfunction function a bitwiseor(a x1, a x2) provisos (Bitwise#(a)); return x1 | x2; endfunction function a bitwiseand(a x1, a x2) provisos (Bitwise#(a)); return x1 & x2; endfunction ================================================ FILE: lib/bsv/BRAMFIFOFLevel.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; import BRAMFIFO::*; import FIFOF::*; interface Counter#(numeric type count_sz); method Action reset(); method Action increment(); method Action decrement(); method Bit#(count_sz) read(); endinterface module mkCounter#(Bit#(count_sz) init_val)(Counter#(count_sz)); PulseWire inc_wire <- mkPulseWire; PulseWire dec_wire <- mkPulseWire; PulseWire rst_wire <- mkPulseWire; Reg#(Bit#(count_sz)) cnt <- mkReg(init_val); (* fire_when_enabled *) rule react; if (rst_wire) cnt <= 0; else if (inc_wire && dec_wire) noAction; else if (inc_wire) cnt <= cnt+1; else if (dec_wire) cnt <= cnt-1; else noAction; endrule method Action increment = inc_wire.send; method Action decrement = dec_wire.send; method Action reset = rst_wire.send; method Bit#(count_sz) read = cnt._read; endmodule interface FIFOFLevel#(type element_type, numeric type fifo_depth); interface FIFOF#(element_type) fifo; method Bool highWater(Bit#(TAdd#(1,TLog#(fifo_depth))) mark); method Bool lowWater(Bit#(TAdd#(1,TLog#(fifo_depth))) mark); endinterface instance ToGet#(FIFOFLevel#(a,b), a); function Get#(a) toGet(FIFOFLevel#(a,b) f) = toGet(f.fifo); endinstance instance ToPut#(FIFOFLevel#(a,b), a); function Put#(a) toPut(FIFOFLevel#(a,b) f) = toPut(f.fifo); endinstance module mkBRAMFIFOFLevel(FIFOFLevel#(element_type, fifo_depth)) provisos(Log#(fifo_depth, log_fifo_depth), Add#(log_fifo_depth,1,mark_width), Bits#(element_type, __a), Add#(1, a__, __a)); Counter#(mark_width) cnt <- mkCounter(0); FIFOF#(element_type) fif <- mkSizedBRAMFIFOF(valueOf(fifo_depth)); method Bool highWater(Bit#(mark_width) mark); return (cnt.read >= mark); endmethod method Bool lowWater(Bit#(mark_width) mark); return (fromInteger(valueOf(fifo_depth))-cnt.read >= mark); endmethod interface FIFOF fifo; method Action enq (element_type x); cnt.increment; fif.enq(x); endmethod method Action deq; cnt.decrement; fif.deq; endmethod method Action clear; cnt.reset; fif.clear; endmethod method element_type first = fif.first; method Bool notFull = fif.notFull; method Bool notEmpty = fif.notEmpty; endinterface endmodule module mkFIFOFLevel(FIFOFLevel#(element_type, fifo_depth)) provisos(Log#(fifo_depth, log_fifo_depth), Add#(log_fifo_depth,1,mark_width), Bits#(element_type, __a), Add#(1, a__, __a)); Counter#(mark_width) cnt <- mkCounter(0); FIFOF#(element_type) fif <- mkSizedFIFOF(valueOf(fifo_depth)); method Bool highWater(Bit#(mark_width) mark); return (cnt.read >= mark); endmethod method Bool lowWater(Bit#(mark_width) mark); return (fromInteger(valueOf(fifo_depth))-cnt.read >= mark); endmethod interface FIFOF fifo; method Action enq (element_type x); cnt.increment; fif.enq(x); endmethod method Action deq; cnt.decrement; fif.deq; endmethod method Action clear; cnt.reset; fif.clear; endmethod method element_type first = fif.first; method Bool notFull = fif.notFull; method Bool notEmpty = fif.notEmpty; endinterface endmodule ================================================ FILE: lib/bsv/BlueScope.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import FIFO::*; import FIFOF::*; import BRAMFIFO::*; import GetPut::*; import Connectable::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import ClientServer::*; interface BlueScopeIndication; method Action triggerFired(); method Action done(); endinterface interface BlueScopeRequest; method Action start(Bit#(32) pointer, Bit#(32) len); method Action reset(); method Action setTriggerMask(Bit#(64) mask); method Action setTriggerValue(Bit#(64) value); endinterface interface BlueScope#(numeric type dataWidth); method Action dataIn(Bit#(dataWidth) d, Bit#(dataWidth) t); interface BlueScopeRequest requestIfc; interface MemWriteClient#(dataWidth) writeClient; endinterface typedef enum { Idle, Enabled, Triggered } State deriving (Bits,Eq); module mkBlueScope#(Integer samples, BlueScopeIndication indication)(BlueScope#(dataWidth)) provisos(Add#(a__,dataWidth,64), Mul#(TDiv#(dataWidth, 8), 8, dataWidth), Add#(1,b__,dataWidth)); let clk <- exposeCurrentClock; let rst <- exposeCurrentReset; let rv <- mkSyncBlueScope(samples, indication, clk, rst, clk,rst); return rv; endmodule module mkSyncBlueScope#(Integer samples, BlueScopeIndication indication, Clock sClk, Reset sRst, Clock dClk, Reset dRst)(BlueScope#(dataWidth)) provisos(Add#(a__,dataWidth,64), Add#(1,b__,dataWidth), Mul#(dataBytes, 8, dataWidth), Div#(dataWidth,8,dataBytes)); SyncFIFOIfc#(Bit#(dataWidth)) dfifo <- mkSyncBRAMFIFO(samples, sClk, sRst, dClk, dRst); Reg#(Bit#(dataWidth)) maskReg <- mkSyncReg(0, dClk, dRst, sClk); Reg#(Bit#(dataWidth)) valueReg <- mkSyncReg(0, dClk, dRst, sClk); Reg#(Bit#(1)) triggeredReg <- mkReg(0, clocked_by sClk, reset_by sRst); Reg#(State) stateReg <- mkReg(Idle, clocked_by sClk, reset_by sRst); Reg#(Bit#(32)) countReg <- mkReg(0, clocked_by sClk, reset_by sRst); Reg#(Bit#(MemOffsetSize)) writeOffsetReg <- mkReg(0, clocked_by dClk, reset_by dRst); SyncPulseIfc startPulse <- mkSyncPulse(dClk, dRst, sClk); SyncPulseIfc resetPulse <- mkSyncPulse(dClk, dRst, sClk); SyncPulseIfc triggeredPulse <- mkSyncPulse(sClk, sRst, dClk); SyncPulseIfc donePulse <- mkSyncPulse(sClk, sRst, dClk); MemWriteEngine#(dataWidth,dataWidth,2,1) mwriter <- mkMemWriteEngine; (* descending_urgency = "resetState, startState" *) rule resetState if (resetPulse.pulse); stateReg <= Idle; countReg <= 0; endrule rule startState if (startPulse.pulse && !resetPulse.pulse); stateReg <= Enabled; endrule mkConnection(toGet(dfifo), toPut(mwriter.writeServers[0].data)); rule writeDone; let tag <- mwriter.writeServers[0].done.get(); endrule rule triggerRule if (triggeredPulse.pulse); indication.triggerFired; endrule rule doneRule if (donePulse.pulse); indication.done; endrule method Action dataIn(Bit#(dataWidth) data, Bit#(dataWidth) trigger);// if (stateReg != Idle); let e = False; let s = stateReg; let c = countReg; let t = False; let d = False; // if 'Enabled', we can transition to 'Triggered' if (s == Enabled && ((trigger & maskReg) == (valueReg & maskReg) && dfifo.notFull())) begin s = Triggered; e = True; c = c + 1; t = True; end // if 'Triggered', we can transition to 'Enabled' else if (s == Triggered && c == fromInteger(samples)) begin s = Idle; e = False; c = 0; t = False; d = True; end // if 'Triggered', we can remain in 'Triggered' else if (s == Triggered && c < fromInteger(samples)) begin s = Triggered; e = True; c = c + 1; t = False; end // else we must be enabled waiting for a Trigger else begin s = s; e = e; c = c; t = t; end if (e) begin if (dfifo.notFull()) dfifo.enq(data); else $display("bluescope.stall c=%d", c); end if(t) triggeredPulse.send(); if(d) donePulse.send(); countReg <= c; stateReg <= s; endmethod interface BlueScopeRequest requestIfc; method Action start(Bit#(32) pointer, Bit#(32) len); mwriter.writeServers[0].request.put(MemengineCmd {sglId: pointer, base: 0, burstLen: 8*fromInteger(valueOf(TDiv#(dataWidth,8))), len: len, tag: 0}); startPulse.send(); endmethod method Action reset(); resetPulse.send(); endmethod method Action setTriggerMask(Bit#(64) mask); maskReg <= truncate(mask); endmethod method Action setTriggerValue(Bit#(64) value); valueReg <= truncate(value); endmethod endinterface interface writeClient = mwriter.dmaClient; endmodule ================================================ FILE: lib/bsv/BlueScopeEvent.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Idea: // BlueScopeEvent allows one to record values only when they change, // along with timestamps of the time of change. // The input is some collection of bits, in some clock domain // A trigger signal is generated when the input, anded with a trigger // mask, changes from clock to clock // Whenever the trigger happens, the new value and a timestamp are saved // into a SyncBRAMFiFo. The output of the FiFo is in the system clock // domain, as is a counter value that says how many events have happened. // One can request a DMA write from the FiFo to system memory, at a given // address, for a given count. // One can reset the fifo and counter. import Clocks::*; import FIFO::*; import FIFOF::*; import BRAMFIFO::*; import GetPut::*; import Connectable::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import ClientServer::*; // This version records timestamped events interface BlueScopeEventRequest; // emtpy fifo and reset event counter method Action doReset(); // changes in bits selected by the mask will trigger events method Action setTriggerMask(Bit#(32) mask); // generate a report pointer indication method Action getCounterValue(); // copy from fifo to memory method Action startDma(Bit#(32) pointer, Bit#(32) len); endinterface interface BlueScopeEventIndication; // report number of events since last reset, method Action counterValue(Bit#(32) v); // dma operation complete method Action dmaDone(); endinterface interface BlueScopeEvent#(numeric type dataWidth); method Action dataIn(Bit#(dataWidth) d); endinterface interface BlueScopeEventControl#(numeric type dataWidth); interface BlueScopeEvent#(dataWidth) bse; interface BlueScopeEventRequest requestIfc; interface MemWriteClient#(64) writeClient; endinterface module mkBlueScopeEvent#(Integer samples, BlueScopeEventIndication indication)(BlueScopeEventControl#(dataWidth)) provisos(Add#(0,dataWidth,32)); let clk <- exposeCurrentClock; let rst <- exposeCurrentReset; let rv <- mkSyncBlueScopeEvent(samples, indication, clk, rst, clk,rst); return rv; endmodule // sClk is the source? sample? side, input samples come here // dClk is the destination? dma? side, this will generally be the system clock module mkSyncBlueScopeEvent#(Integer samples, BlueScopeEventIndication indication, Clock sClk, Reset sRst, Clock dClk, Reset dRst)(BlueScopeEventControl#(dataWidth)) provisos(Add#(0, dataWidth, 32)); // the idea here is that we let events pour into the Bram continually, // then reset them before starting an acquisition interval // we reset both halves of the fifo, not clear that is needed MakeResetIfc sFifoReset <- mkReset(2, True, sClk); MakeResetIfc dFifoReset <- mkReset(2, True, dClk); SyncFIFOIfc#(Bit#(64)) dfifo <- mkSyncBRAMFIFO(samples, sClk, sFifoReset.new_rst, dClk, dFifoReset.new_rst); // mask reg is set from a request in the dClk domain but used in the // sClk domain to determine triggering Reg#(Bit#(dataWidth)) maskReg <- mkSyncReg(0, dClk, dRst, sClk); // freeClockReg counts cycles to timestamp events Reg#(Bit#(32)) freeClockReg <- mkReg(0, clocked_by sClk, reset_by sRst); // countReg counts accumulated samples Reg#(Bit#(32)) countReg <- mkReg(0, clocked_by sClk, reset_by sRst); // countSyncReg repeats that value into the dClk domain Reg#(Bit#(32)) countSyncReg <- mkSyncReg(0, sClk, sFifoReset.new_rst, dClk); // oldData is used in the sample domain, to save the previous value Reg#(Bit#(dataWidth)) olddata <- mkReg(0, clocked_by sClk, reset_by sRst); MemWriteEngine#(64,64,2,1) mwriter <- mkMemWriteEngine; // (* descending_urgency = "resetState, startState" *) mkConnection(toGet(dfifo), toPut(mwriter.writeServers[0].data)); rule writeDone; let tag <- mwriter.writeServers[0].done.get(); indication.dmaDone; endrule rule freeClock; freeClockReg <= freeClockReg + 1; endrule interface BlueScopeEvent bse; method Action dataIn(Bit#(dataWidth) data);// if (stateReg != Idle); let c = countReg; if ((maskReg & (data ^ olddata)) != 0) begin if (dfifo.notFull()) begin dfifo.enq({data, freeClockReg}); countReg <= c + 1; countSyncReg <= c + 1; end else $display("bluescope.stall c=%d", c); end olddata <= data; endmethod endinterface interface BlueScopeEventRequest requestIfc; method Action doReset(); sFifoReset.assertReset(); dFifoReset.assertReset(); endmethod method Action setTriggerMask(Bit#(32) mask); maskReg <= truncate(mask); endmethod method Action getCounterValue(); indication.counterValue(countSyncReg); endmethod method Action startDma(Bit#(32) pointer, Bit#(32) len); mwriter.writeServers[0].request.put(MemengineCmd {sglId: pointer, base: 0, burstLen: 8*fromInteger(valueOf(TDiv#(dataWidth,8))), len: len, tag: ?}); endmethod endinterface interface writeClient = mwriter.dmaClient; endmodule ================================================ FILE: lib/bsv/BlueScopeEventPIO.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // Idea: // BlueScopeEventPIO allows one to record values only when they change, // along with timestamps of the time of change. // The input is some collection of bits, in some clock domain // A trigger signal is generated when the input, anded with a trigger // mask, changes from clock to clock // Whenever the trigger happens, the new value and a timestamp are saved // into a SyncBRAMFiFo. The output of the FiFo is in the system clock // domain, as is a counter value that says how many events have happened. // When enabled, the events in the fifo are reported by indication // A very similar module is BlueScopeEventPIO.bsv, which reports by DMA. // It supports a much higher data rate, but is more trouble to set up and use import Clocks::*; import FIFO::*; import FIFOF::*; import BRAMFIFO::*; // This version records timestamped events interface BlueScopeEventPIORequest; // emtpy fifo and reset event counter method Action doReset(); // changes in bits selected by the mask will trigger events method Action setTriggerMask(Bit#(32) mask); // generate a report pointer indication method Action getCounterValue(); // copy from fifo to memory method Action enableIndications(Bit#(32) en); endinterface interface BlueScopeEventPIOIndication; // report number of events since last reset, method Action counterValue(Bit#(32) v); // report an event method Action reportEvent(Bit#(32) value, Bit#(32) timestamp); endinterface // This interface is used by the device under test to report events // Reported events are actually recorded only if they meet the trigger // conditions interface BlueScopeEventPIO#(numeric type dataWidth); method Action dataIn(Bit#(dataWidth) d); endinterface interface BlueScopeEventPIOControl#(numeric type dataWidth); interface BlueScopeEventPIO#(dataWidth) bse; interface BlueScopeEventPIORequest requestIfc; endinterface module mkBlueScopeEventPIO#(Integer samples, BlueScopeEventPIOIndication indication)(BlueScopeEventPIOControl#(dataWidth)) provisos(Add#(0,dataWidth,32)); let clk <- exposeCurrentClock; let rst <- exposeCurrentReset; let rv <- mkSyncBlueScopeEventPIO(samples, indication, clk, rst, clk,rst); return rv; endmodule // sClk is the source? sample? side, input samples come here // dClk is the destination? dma? side, this will generally be the system clock module mkSyncBlueScopeEventPIO#(Integer samples, BlueScopeEventPIOIndication indication, Clock sClk, Reset sRst, Clock dClk, Reset dRst)(BlueScopeEventPIOControl#(dataWidth)) provisos(Add#(0, dataWidth, 32)); // the idea here is that we let events pour into the Bram continually, // then reset them before starting an acquisition interval // we reset both halves of the fifo, not clear that is needed MakeResetIfc sFifoReset <- mkReset(2, True, sClk); MakeResetIfc dFifoReset <- mkReset(2, True, dClk); SyncFIFOIfc#(Bit#(64)) dfifo <- mkSyncBRAMFIFO(samples, sClk, sFifoReset.new_rst, dClk, dFifoReset.new_rst); // mask reg is set from a request in the dClk domain but used in the // sClk domain to determine triggering Reg#(Bit#(dataWidth)) maskReg <- mkSyncReg(0, dClk, dRst, sClk); // freeClockReg counts cycles to timestamp events Reg#(Bit#(32)) freeClockReg <- mkReg(0, clocked_by sClk, reset_by sRst); // countReg counts accumulated samples Reg#(Bit#(32)) countReg <- mkReg(0, clocked_by sClk, reset_by sRst); // countSyncReg repeats that value into the dClk domain Reg#(Bit#(32)) countSyncReg <- mkSyncReg(0, sClk, sFifoReset.new_rst, dClk); // oldData is used in the sample domain, to save the previous value Reg#(Bit#(dataWidth)) olddata <- mkReg(0, clocked_by sClk, reset_by sRst); Reg#(Bit#(1)) enableIndicationReg <- mkReg(0); rule doIndication (enableIndicationReg == 1); let v = dfifo.first(); indication.reportEvent(v[63:32], v[31:0]); dfifo.deq(); endrule rule freeClock; freeClockReg <= freeClockReg + 1; endrule interface BlueScopeEventPIO bse; method Action dataIn(Bit#(dataWidth) data);// if (stateReg != Idle); let c = countReg; if ((maskReg & (data ^ olddata)) != 0) begin if (dfifo.notFull()) begin dfifo.enq({data, freeClockReg}); countReg <= c + 1; countSyncReg <= c + 1; end else $display("bluescope.stall c=%d", c); end olddata <= data; endmethod endinterface interface BlueScopeEventPIORequest requestIfc; method Action doReset(); sFifoReset.assertReset(); dFifoReset.assertReset(); endmethod method Action setTriggerMask(Bit#(32) mask); maskReg <= truncate(mask); endmethod method Action getCounterValue(); indication.counterValue(countSyncReg); endmethod method Action enableIndications(Bit#(32) en); enableIndicationReg <= en[0]; endmethod endinterface endmodule ================================================ FILE: lib/bsv/Bscan.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFOF::*; import Clocks::*; import Vector::*; import BRAM::*; import BscanE2::*; import GetPut::*; import XilinxCells::*; import SyncBits::*; // From: http://siliconexposed.blogspot.com/2013/10/soc-framework-part-5.html // Example usage: http://www.pld.ttu.ee/~vadim/tty/IAY0570/video_pipeline/psram_app/program_rom.v // Example usage: http://ohm.bu.edu/~dean/G-2TrackerWORKING/uart_test.vhd interface BscanTop; interface Reset rst; interface Clock tck; method Bit#(1) reset(); method Bit#(1) capture(); method Bit#(1) shift(); method Bit#(1) tdi(); method Action tdo(Bit#(1) v); method Bit#(1) update(); method Bool first(); endinterface `ifdef SIMULATION module mkBscanTop#(Integer bus)(BscanTop); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); interface tck = defaultClock; interface rst = defaultReset; method reset(); return 0; endmethod method tdi; return 0; endmethod method Action tdo(Bit#(1) v); endmethod method capture; return 0; endmethod method shift; return 0; endmethod method update; return 0; endmethod method first(); return False; endmethod endmodule `else module mkBscanTop#(Integer bus)(BscanTop); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); BscanE2 bscan <- mkBscanE2(bus); Clock mytck <- mkClockBUFG(clocked_by bscan.tck); Reset myrst <- mkAsyncReset(2, defaultReset, mytck); SyncBitIfc#(Bool) selected <- mkSyncBits(False, mytck, myrst, defaultClock, defaultReset); Reg#(Bool) selectdelay <- mkReg(False); rule updater; selected.send(bscan.sel() == 1); endrule rule writed; selectdelay <= selected.read(); endrule interface tck = mytck; interface rst = myrst; method reset = bscan.reset; method tdi = bscan.tdi; method tdo = bscan.tdo; method capture; return bscan.sel & bscan.capture; endmethod method shift; return bscan.sel & bscan.shift; endmethod method update; return bscan.sel & bscan.update; endmethod method first(); return selected.read() && !selectdelay; endmethod endmodule `endif interface BscanLocal; interface Vector#(2, BscanTop) loc; endinterface module mkBscanLocal#(BscanTop bscan)(BscanLocal); Vector#(2, Wire#(Bit#(1))) tdo_wire <- replicateM(mkDWire(0)); //Wire#(Bit#(1)) tdo_wire2 <- mkDWire(0); rule tdo_rule; bscan.tdo(tdo_wire[0] | tdo_wire[1]); endrule Vector#(2, BscanTop) vloc; for (Integer i = 0; i < 2; i = i + 1) begin vloc[i] = (interface BscanTop; method rst = bscan.rst; method tck = bscan.tck; method reset = bscan.reset; method capture = bscan.capture; method shift = bscan.shift; method tdi = bscan.tdi; method update = bscan.update; method first = bscan.first; method Action tdo(Bit#(1) v); tdo_wire[i] <= v; endmethod endinterface); end interface loc = vloc; endmodule interface BscanBram#(type atype, type dtype); interface BRAMClient#(atype, dtype) bramClient; method Bit#(1) data_out(); endinterface module mkBscanBram#(Integer id, atype addr, BscanTop bscan)(BscanBram#(atype, dtype)) provisos (Bits#(atype, asz), Bits#(dtype,dsz), Add#(1, a__, dsz)); let asz = valueOf(asz); let dsz = valueOf(dsz); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reg#(Bit#(asz)) addrReg <- mkReg(0); Reg#(Bool) readData <- mkReg(False); Reg#(Bool) firstItem <- mkReg(False); Reg#(Bool) selected <- mkReg(False); SyncBitIfc#(Bool) selectedj <- mkSyncBits(False, defaultClock, defaultReset, bscan.tck, bscan.rst); Reg#(Bit#(dsz)) shiftReg <- mkReg(0, clocked_by bscan.tck, reset_by bscan.rst); SyncBitIfc#(Bit#(dsz)) tojtag <- mkSyncBits(0, defaultClock, defaultReset, bscan.tck, bscan.rst); SyncBitIfc#(Bit#(dsz)) fromjtag <- mkSyncBits(0, bscan.tck, bscan.rst, defaultClock, defaultReset); SyncPulseIfc startWrite <- mkSyncHandshake(bscan.tck, bscan.rst, defaultClock); rule captureRule if(bscan.capture() == 1); shiftReg <= tojtag.read(); endrule rule shiftRule if (bscan.shift() == 1); shiftReg <= { bscan.tdi(), shiftReg[dsz-1:1] }; endrule rule updateRule if(bscan.update() == 1); startWrite.send(); fromjtag.send(shiftReg); endrule rule firstRule if (bscan.first()); firstItem <= True; selected <= False; selectedj.send(False); tojtag.send(0); endrule rule addrRule if (startWrite.pulse()); let v = fromInteger(0); // first time USER1, reset address if (firstItem) begin selected <= fromjtag.read() == fromInteger(id); selectedj.send(fromjtag.read() == fromInteger(id)); end else v = addrReg + 1; addrReg <= v; firstItem <= False; endrule rule readdataRule; readData <= startWrite.pulse(); endrule interface BRAMClient bramClient; interface Get request; method ActionValue#(BRAMRequest#(atype,dtype)) get() if ((selected && startWrite.pulse()) || readData); return BRAMRequest {write:!readData, responseOnWrite:False, address:unpack(addrReg), datain:unpack(fromjtag.read())}; endmethod endinterface interface Put response; method Action put(dtype d); tojtag.send(pack(d)); endmethod endinterface endinterface method Bit#(1) data_out(); // the output lines are all OR'ed together when going back to the BSCAN core if (selectedj.read()) return shiftReg[0]; else return 0; endmethod endmodule ================================================ FILE: lib/bsv/ConfigCounter.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; interface ConfigCounter#(numeric type count_sz); method Action decrement(UInt#(count_sz) x); method ActionValue#(Bool) maybeDecrement(UInt#(count_sz) x); method Action increment(UInt#(count_sz) x); method UInt#(count_sz) read(); //method UInt#(count_sz) read_bypass(); method Bool positive(); endinterface module mkConfigCounter#(UInt#(count_sz) init_val)(ConfigCounter#(count_sz)); Wire#(UInt#(count_sz)) inc_wire <- mkDWire(0); Wire#(UInt#(count_sz)) dec_wire <- mkDWire(0); Reg#(UInt#(count_sz)) cnt <- mkReg(init_val); Reg#(Bool) positive_reg <- mkReg(False); (* fire_when_enabled *) rule react; let new_count = (cnt + inc_wire) - dec_wire; cnt <= new_count; positive_reg <= (new_count > 0); endrule method Action increment(UInt#(count_sz) x); inc_wire <= x; endmethod method Action decrement(UInt#(count_sz) x); dec_wire <= x; endmethod method ActionValue#(Bool) maybeDecrement(UInt#(count_sz) x); if (cnt >= x) begin dec_wire <= x; return True; end else return False; endmethod method UInt#(count_sz) read = cnt._read; method Bool positive = positive_reg._read; endmodule ================================================ FILE: lib/bsv/ConnectalSpi.bsv ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks :: *; import GetPut :: *; import FIFOF :: *; import Probe :: *; import Connectable :: *; import SpecialFIFOs:: *; import SyncBits :: *; import StmtFSM :: *; import Assert :: *; import XilinxCells :: *; import Vector :: *; import ConnectalClocks :: *; (* always_enabled *) interface SpiMasterPins#(numeric type num_cs); method Bit#(1) mosi(); method Bit#(num_cs) sel_n(); method Action miso(Bit#(1) v); interface Clock clock; interface Clock deleteme_unused_clock; interface Reset deleteme_unused_reset; endinterface: SpiMasterPins (* always_enabled *) interface SpiSlavePins#(numeric type num_cs); method Action mosi(Bit#(1) v); method Action sel_n(Bit#(num_cs) v); method Bit#(1) miso(); method Action clock(Bit#(1) v); interface Clock deleteme_unused_clock; interface Reset deleteme_unused_reset; endinterface interface SPIMaster#(type a, numeric type num_cs); interface Vector#(num_cs, Put#(a)) request; interface Vector#(num_cs, Get#(a)) response; interface SpiMasterPins#(num_cs) pins; endinterface interface SPISlave#(type a, numeric type num_cs); interface Vector#(num_cs, Get#(a)) request; interface Vector#(num_cs, Put#(a)) response; interface SpiSlavePins#(num_cs) pins; endinterface module mkSpiMasterShifter#(Bool invert_clk) (SPIMaster#(a,num_cs)) provisos(Bits#(a,awidth),Add#(1,awidth1,awidth),Log#(awidth,logawidth)); Clock defaultClock <- exposeCurrentClock; Reset defaultReset <- exposeCurrentReset; ClockDividerIfc clockInverter <- mkClockInverter; Clock spiClock = clockInverter.slowClock; Reset spiReset <- mkAsyncResetFromCR(2, clockInverter.slowClock); Reg#(Bit#(awidth)) shiftreg <- mkReg(unpack(0)); Reg#(Bit#(num_cs)) selreg <- mkReg(maxBound); Reg#(Bit#(TAdd#(logawidth,1))) countreg <- mkReg(0); Reg#(Bit#(TLog#(num_cs))) ifcnumreg <- mkReg(0); Vector#(num_cs, FIFOF#(a)) requestFifo <- replicateM(mkFIFOF); Vector#(num_cs, FIFOF#(a)) resultFifo <- replicateM(mkFIFOF); Clock outputClock = invert_clk ? clockInverter.slowClock : defaultClock; Reset outputReset = defaultReset; ReadOnly#(Bit#(awidth)) sync_shiftreg <- mkNullCrossingWire(outputClock, shiftreg); Wire#(Bit#(1)) misoWire <- mkDWire(0); let verbose = False; rule running if (countreg > 0); countreg <= countreg - 1; Bit#(awidth) newshiftreg = { shiftreg[valueOf(awidth)-2:0], misoWire }; if(verbose) $display("newshiftreg = %08h", newshiftreg); shiftreg <= newshiftreg; if (countreg == 1 && resultFifo[ifcnumreg].notFull) begin resultFifo[ifcnumreg].enq(unpack(newshiftreg)); selreg <= maxBound; end endrule for (Integer i = 0; i < valueOf(num_cs); i = i + 1) rule start_request if (countreg == 0); let v <- toGet(requestFifo[i]).get(); ifcnumreg <= fromInteger(i); selreg <= ~(1 << fromInteger(i)); shiftreg <= pack(v); countreg <= fromInteger(valueOf(awidth)); endrule interface Vector request = map(toPut, requestFifo); interface Vector response = map(toGet, resultFifo); interface SpiMasterPins pins; method Bit#(1) mosi(); return sync_shiftreg[valueOf(awidth)-1]; endmethod method Bit#(num_cs) sel_n(); return selreg; endmethod method Action miso(Bit#(1) v); misoWire <= v; endmethod interface Clock clock = outputClock; interface Clock deleteme_unused_clock = invert_clk ? defaultClock : clockInverter.slowClock; interface Reset deleteme_unused_reset = defaultReset; endinterface: pins endmodule: mkSpiMasterShifter module mkSpiSlaveShifter#(ReadOnly#(Bit#(1)) mosi, ReadOnly#(Bit#(num_cs)) seln)(SPISlave#(a, num_cs)) provisos(Bits#(a,awidth), Add#(__a,1,awidth), Add#(TLog#(awidth),1,cwidth)); let awidth = valueOf(awidth); Reg#(Bit#(awidth)) shift_reg <- mkReg(0); Reg#(Bit#(cwidth)) cnt_reg <- mkReg(0); Vector#(num_cs, FIFOF#(a)) req_fifo <- replicateM(mkFIFOF); Vector#(num_cs, FIFOF#(a)) resp_fifo <- replicateM(mkFIFOF); for (Integer i = 0; i < valueOf(num_cs); i = i + 1) (* fire_when_enabled *) rule mosi_rule if (seln._read[i] == 0); let s = shift_reg; if (cnt_reg == 0 && resp_fifo[i].notEmpty) begin s = pack(resp_fifo[i].first); resp_fifo[0].deq; end let new_s = {s[awidth-2:0],mosi._read}; if (cnt_reg+1 == fromInteger(awidth) && req_fifo[i].notFull) begin cnt_reg <= 0; req_fifo[i].enq(unpack(new_s)); end else begin cnt_reg <= cnt_reg+1; shift_reg <= new_s; end endrule interface request = map(toGet, req_fifo); interface response = map(toPut, resp_fifo); interface SpiSlavePins pins; method Bit#(1) miso(); return shift_reg[awidth-1]; endmethod endinterface endmodule : mkSpiSlaveShifter module mkSPISlave(SPISlave#(a, num_cs)) provisos(Bits#(a,awidth), Add#(__a,1,awidth)); B2C1 b2c <- mkB2C1(); Clock def_clk <- exposeCurrentClock; Clock spi_clk <- mkClockBUFG(clocked_by b2c.c); Reset spi_rst <- mkAsyncResetFromCR(2, spi_clk); Wire#(Bit#(1)) mosi_wire <- mkDWire(0); Wire#(Bit#(num_cs)) seln_wire <- mkDWire(1); Wire#(Bit#(1)) clk_wire <- mkDWire(0); ReadOnly#(Bit#(1)) mosi_sync <- mkNullCrossingWire(spi_clk, mosi_wire); ReadOnly#(Bit#(num_cs)) seln_sync <- mkNullCrossingWire(spi_clk, seln_wire); SPISlave#(a,num_cs) shifter <- mkSpiSlaveShifter(mosi_sync, seln_sync, clocked_by spi_clk, reset_by spi_rst); ReadOnly#(Bit#(1)) miso_sync <- mkNullCrossingWire(def_clk, shifter.pins.miso); Vector#(num_cs, SyncFIFOIfc#(a)) responseFifo <- replicateM(mkSyncFIFOFromCC(1, spi_clk)); Vector#(num_cs, SyncFIFOIfc#(a)) requestFifo <- replicateM(mkSyncFIFOToCC(1, spi_clk, spi_rst)); zipWithM(mkConnection, map(toPut, requestFifo), shifter.request); zipWithM(mkConnection, map(toGet, responseFifo), shifter.response); rule clk_rule; b2c.inputclock(clk_wire); endrule interface request = map(toGet, requestFifo); interface response = map(toPut, responseFifo); interface SpiSlavePins pins; method Action mosi(Bit#(1) v); mosi_wire._write(v); endmethod method Action sel_n(Bit#(num_cs) v); seln_wire._write(v); endmethod method Bit#(1) miso(); return miso_sync._read(); endmethod method Action clock(Bit#(1) v); clk_wire._write(v); endmethod interface Clock deleteme_unused_clock = spi_clk; interface Reset deleteme_unused_reset = spi_rst; endinterface: pins endmodule : mkSPISlave module mkSPIMaster#(Integer divisor, Bool invert_clk)(SPIMaster#(a,num_cs)) provisos(Bits#(a,awidth),Add#(1,awidth1,awidth),Log#(awidth,logawidth)); ClockDividerIfc clockDivider <- mkClockDivider(divisor); Reset slowReset <- mkAsyncResetFromCR(2, clockDivider.slowClock); SPIMaster#(a, num_cs) spi <- mkSpiMasterShifter(invert_clk, clocked_by clockDivider.slowClock, reset_by slowReset); Vector#(num_cs, SyncFIFOIfc#(a)) requestFifo <- replicateM(mkSyncFIFOFromCC(1, clockDivider.slowClock)); Vector#(num_cs, SyncFIFOIfc#(a)) responseFifo <- replicateM(mkSyncFIFOToCC(1, clockDivider.slowClock, slowReset)); zipWithM(mkConnection, map(toGet, requestFifo), spi.request); zipWithM(mkConnection, spi.response, map(toPut, responseFifo)); //interface spiClock = spi.spiClock; interface request = map(toPut, requestFifo); interface response = map(toGet, responseFifo); interface pins = spi.pins; endmodule: mkSPIMaster module mkSPI20(SPIMaster#(Bit#(20),1)); SPIMaster#(Bit#(20),1) spi <- mkSPIMaster(200, True); return spi; endmodule module mkSpiTestBench(Empty); Clock defaultClock <- exposeCurrentClock; Reset defaultReset <- exposeCurrentReset; Bit#(20) slaveV = 20'h96ed5; Bit#(20) masterV = 20'h8baeb; let verbose = False; SPIMaster#(Bit#(20),1) spi <- mkSPIMaster(4, False); Reg#(Bit#(20)) slaveCount <- mkReg(20, clocked_by spi.pins.clock, reset_by spi.pins.deleteme_unused_reset); Reg#(Bit#(20)) slaveValue <- mkReg(slaveV, clocked_by spi.pins.clock, reset_by spi.pins.deleteme_unused_reset); Reg#(Bit#(20)) responseValue <- mkReg(0, clocked_by spi.pins.clock, reset_by spi.pins.deleteme_unused_reset); SyncBitIfc#(Bit#(1)) sync_sel_n <- mkSyncBits(0, defaultClock, defaultReset, spi.pins.clock, spi.pins.deleteme_unused_reset); Probe#(Bit#(1)) probeSelN <- mkProbe(clocked_by spi.pins.clock, reset_by spi.pins.deleteme_unused_reset); Probe#(Bit#(1)) probeMiso <- mkProbe(clocked_by spi.pins.clock, reset_by spi.pins.deleteme_unused_reset); Probe#(Bit#(1)) probeMosi <- mkProbe(clocked_by spi.pins.clock, reset_by spi.pins.deleteme_unused_reset); rule probePins; probeSelN <= spi.pins.sel_n; probeMosi <= spi.pins.mosi; endrule rule slaveIn if (spi.pins.sel_n == 0); slaveCount <= slaveCount - 1; slaveValue <= (slaveValue << 1); endrule rule miso if (spi.pins.sel_n == 0); probeMiso <= slaveValue[19]; spi.pins.miso(slaveValue[19]); endrule rule spipins if (spi.pins.sel_n == 0); if(verbose) $display("miso=%d mosi=%d sel=%d", slaveValue[19], spi.pins.mosi, sync_sel_n.read()); responseValue <= { responseValue[18:0], spi.pins.mosi }; endrule rule displaySlaveValue if (slaveCount == 0); if(verbose) $display("slave received %h", responseValue); dynamicAssert(responseValue == masterV, "wrong value received by slave"); endrule rule finished; let result <- spi.response[0].get(); if(verbose) $display("master received %h", result); dynamicAssert(result == slaveV, "wrong value received by master"); $finish(0); endrule let once <- mkOnce(action if(verbose) $display("master sending %h; slave sending %h", masterV, slaveV); $dumpvars(); spi.request[0].put(masterV); endaction); rule foobar; once.start(); endrule endmodule ================================================ FILE: lib/bsv/Dma2BRAM.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BRAM::*; import FIFO::*; import Vector::*; import Gearbox::*; import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import ClientServer::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import ConnectalMemUtils::*; import Pipe::*; interface BRAMWriter#(numeric type bramIdxWidth, numeric type busWidth); method Action start(SGLId h, Bit#(MemOffsetSize) base, Bit#(bramIdxWidth) start_idx, Bit#(bramIdxWidth) finish_idx); method ActionValue#(Bool) finish(); endinterface interface BRAMReadClient#(numeric type bramIdxWidth, numeric type busWidth); method Action start(SGLId h, Bit#(MemOffsetSize) base, Bit#(bramIdxWidth) start_idx, Bit#(bramIdxWidth) finish_idx); method ActionValue#(Bool) finish(); interface MemReadClient#(busWidth) dmaClient; endinterface interface BRAMWriteClient#(numeric type bramIdxWidth, numeric type busWidth); method Action start(SGLId h, Bit#(MemOffsetSize) base, Bit#(bramIdxWidth) start_idx, Bit#(bramIdxWidth) finish_idx); method ActionValue#(Bool) finish(); interface MemWriteClient#(busWidth) dmaClient; endinterface interface BRAMPipeIn#(numeric type bramIdxWidth, numeric type busWidth); interface PipeIn#(MemDataF#(busWidth)) pipe; endinterface module mkBRAMReadClient#(BRAMServer#(Bit#(bramIdxWidth),d) br)(BRAMReadClient#(bramIdxWidth,busWidth)) provisos(Bits#(d,dsz), Div#(busWidth,dsz,nd), Mul#(nd,dsz,busWidth), Add#(1,a__,nd), Add#(1,bramIdxWidth,cntW), Mul#(TDiv#(busWidth, 8), 8, busWidth)); Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; FIFO#(void) f <- mkSizedFIFO(1); Reg#(Bit#(cntW)) i <- mkReg(maxBound); Reg#(Bit#(cntW)) j <- mkReg(maxBound); Reg#(Bit#(cntW)) n <- mkReg(0); Reg#(SGLId) ptr <- mkReg(0); Reg#(Bit#(MemOffsetSize)) off <- mkReg(0); Gearbox#(nd,1,d) gb <- mkNto1Gearbox(clk,rst,clk,rst); let bus_width_in_bytes = fromInteger(valueOf(busWidth)/8); MemReader#(busWidth) re <- mkMemReader; rule feed_gearbox; let v <- re.readServer.readData.get; //$display("mkBRAMReadClient::readData.get %x", v.data); gb.enq(unpack(v.data)); endrule rule loadReq(i <= n); re.readServer.readReq.put(MemRequest{sglId:ptr, offset:off, burstLen:bus_width_in_bytes, tag:0}); off <= off+bus_width_in_bytes; //$display("mkBRAMReadClient::readReq.put %x, %x", i, n); i <= i+fromInteger(valueOf(nd)); endrule rule load(j <= n); br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:truncate(j), datain:gb.first[0]}); gb.deq; j <= j+1; //$display("mkBRAMReadClient::bramserver put write %x, %x", j, n); if (j == n) f.enq(?); endrule rule discard(j > n); gb.deq; endrule method Action start(SGLId h, Bit#(MemOffsetSize) b, Bit#(bramIdxWidth) start_idx, Bit#(bramIdxWidth) finish_idx); $display("mkBRAMReadClient::start(%h, %h, %h %h)", h, b, start_idx, finish_idx); i <= extend(start_idx); j <= extend(start_idx); n <= extend(finish_idx); ptr <= h; off <= b; endmethod method ActionValue#(Bool) finish(); $display("mkBRAMReadClient::finish"); f.deq; return True; endmethod interface dmaClient = re.readClient; endmodule module mkBRAMWriter#(Integer id, BRAMServer#(Bit#(bramIdxWidth),d) br, MemReadEngineServer#(busWidth) readServer)(BRAMWriter#(bramIdxWidth,busWidth)) provisos(Bits#(d,dsz), Div#(busWidth,dsz,nd), Mul#(nd,dsz,busWidth), Add#(1,a__,nd), Add#(1,bramIdxWidth,cntW), Div#(busWidth,8,bwbytes), Mul#(bwbytes, 8, busWidth), Add#(b__, bramIdxWidth, 32), Add#(c__, TLog#(nd), 32)); let verbose = False; Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; Reg#(Bit#(cntW)) j <- mkReg(maxBound); Reg#(Bit#(cntW)) n <- mkReg(0); Gearbox#(nd,1,d) gb <- mkNto1Gearbox(clk,rst,clk,rst); Reg#(Bool) running <- mkReg(False); FIFO#(void) doneFifo <- mkFIFO; rule feed_gearbox if (running); let v <- toGet(readServer.data).get; if(verbose) $display("mkBRAMWriter::feed_gearbox (%d) %x", id, v.data); gb.enq(unpack(v.data)); if (v.last) doneFifo.enq(?); endrule rule load(j <= n); br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:truncate(j), datain:gb.first[0]}); gb.deq; j <= j+1; if(verbose) $display("mkBRAMWriter::load (%d) %x, %x", id, j, n); endrule rule discard(j > n); gb.deq; if(verbose) $display("mkBRAMWriter::discard (%d) %x", id, j); endrule method Action start(SGLId h, Bit#(MemOffsetSize) b, Bit#(bramIdxWidth) start_idx, Bit#(bramIdxWidth) finish_idx) if (!running); if(verbose) $display("mkBRAMWriter::start (%d) %d, %d, %d %d", id, h, b, start_idx, finish_idx); Bit#(BurstLenSize) burst_len_bytes = fromInteger(valueOf(bwbytes)); Bit#(32) req_len_ds = extend(finish_idx-start_idx)+fromInteger(valueOf(nd)); Bit#(TLog#(nd)) zeros = 0; Bit#(32) req_len_bytes = {zeros,req_len_ds[31:valueOf(TLog#(nd))]} * fromInteger(valueOf(bwbytes)); readServer.request.put(MemengineCmd{sglId:h, base:truncate(b), len:req_len_bytes, burstLen:burst_len_bytes, tag: 0}); if(verbose) $display("mkBRAMWriter::start id=%d offset=%d len=%d burstLen=%d", id, b, req_len_bytes, burst_len_bytes); j <= extend(start_idx); n <= extend(finish_idx); running <= True; endmethod method ActionValue#(Bool) finish() if (running); if(verbose) $display("mkBRAMWriter::finish (%d)", id); doneFifo.deq; running <= False; return True; endmethod endmodule module mkBRAMWriteClient#(BRAMServer#(Bit#(bramIdxWidth),d) br)(BRAMWriteClient#(bramIdxWidth,busWidth)) provisos(Bits#(d,dsz), Div#(busWidth,dsz,nd), Mul#(nd,dsz,busWidth), Add#(1,a__,nd), Add#(1, d__, busWidth), Add#(1, b__, TMul#(2, nd)), Add#(nd, c__, TMul#(2, nd)), Add#(1,bramIdxWidth,cntW), Mul#(TDiv#(busWidth, 8), 8, busWidth)); Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; FIFO#(void) f <- mkSizedFIFO(1); Reg#(Bit#(cntW)) i <- mkReg(maxBound); Reg#(Bit#(cntW)) j <- mkReg(maxBound); Reg#(Bit#(cntW)) n <- mkReg(0); Reg#(SGLId) ptr <- mkReg(0); Reg#(Bit#(MemOffsetSize)) off <- mkReg(0); Gearbox#(1,nd,Bit#(dsz)) gb <- mk1toNGearbox(clk,rst,clk,rst); MemWriteEngine#(busWidth,busWidth,1,1) we <- mkMemWriteEngine; Bit#(MemOffsetSize) bus_width_in_bytes = fromInteger(valueOf(busWidth)/8); rule drain_geatbox; Vector#(nd,Bit#(dsz)) v = gb.first; we.writeServers[0].data.enq(pack(v)); gb.deq; endrule rule bramReq(j <= n); //$display("mkBRAMWriteClient::bramReq %h", j); br.request.put(BRAMRequest{write:False, responseOnWrite:False, address:truncate(j), datain:?}); j <= j+1; endrule rule bramResp; d rv <- br.response.get; gb.enq(cons(pack(rv), nil)); endrule rule loadReq(i <= n); we.writeServers[0].request.put(MemengineCmd{sglId:ptr, base:truncate(off), len:truncate(bus_width_in_bytes), burstLen:truncate(bus_width_in_bytes), tag: 0}); off <= off+bus_width_in_bytes; i <= i+fromInteger(valueOf(nd)); //$display("mkBRAMWriteClient::loadReq %h", i); endrule rule loadResp; let __x <- we.writeServers[0].done.get; if (i > n) f.enq(?); endrule method Action start(SGLId h, Bit#(MemOffsetSize) b, Bit#(bramIdxWidth) start_idx, Bit#(bramIdxWidth) finish_idx); $display("mkBRAMWriteClient::start(%h, %h, %h %h)", h, b, start_idx, finish_idx); i <= extend(start_idx); j <= extend(start_idx); n <= extend(finish_idx); ptr <= h; off <= b; endmethod method ActionValue#(Bool) finish(); $display("mkBRAMWriteClient::finish"); f.deq; return True; endmethod interface dmaClient = we.dmaClient; endmodule module mkBRAMPipeIn#(Integer id, BRAMServer#(Bit#(bramIdxWidth),d) br)(BRAMPipeIn#(bramIdxWidth,busWidth)) provisos(Bits#(d,dsz), Div#(busWidth,dsz,nd), Mul#(nd,dsz,busWidth), Add#(1,a__,nd), Add#(1,bramIdxWidth,cntW), Div#(busWidth,8,bwbytes), Mul#(bwbytes, 8, busWidth), Add#(b__, bramIdxWidth, 32), Add#(c__, TLog#(nd), 32)); let verbose = False; Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; Reg#(Bit#(cntW)) j <- mkReg(0); Reg#(Bit#(cntW)) n <- mkReg(0); Gearbox#(nd,1,MemDataF#(dsz)) gb <- mkNto1Gearbox(clk,rst,clk,rst); Reg#(Bool) running <- mkReg(False); FIFO#(void) doneFifo <- mkFIFO; FIFOF#(MemDataF#(busWidth)) dataFifo <- mkFIFOF(); rule feed_gearbox; let md <- toGet(dataFifo).get; if(verbose) $display("mkBRAMWriter::feed_gearbox (%d) %x", id, md.data); Vector#(nd,Bit#(dsz)) ds = unpack(md.data); Vector#(nd,MemDataF#(dsz)) mds = unpack(0); for (Integer i = 0; i < valueOf(nd); i = i + 1) mds[i].data = ds[i]; if (md.last) mds[valueOf(nd)-1].last = True; gb.enq(mds); endrule rule load; let md = gb.first[0]; $display("load id=%d j=%d data=%h", id, j, md.data); br.request.put(BRAMRequest{write:True, responseOnWrite:False, address:truncate(j), datain:unpack(md.data)}); gb.deq; let nextj = j + 1; if (md.last) begin nextj = 0; $display("end of stream j=%d", j); end j <= nextj; if(verbose) $display("mkBRAMWriter::load (%d) %x, %x", id, j, n); endrule interface PipeIn pipe = toPipeIn(dataFifo); endmodule ================================================ FILE: lib/bsv/FrequencyCounter.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import FIFO::*; import StmtFSM::*; interface FrequencyCounter; method Action start(Bit#(32) periodA); method ActionValue#(Bit#(32)) elapsedCycles(); endinterface module mkFrequencyCounter#(Clock clock, Reset reset)(FrequencyCounter); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Reg#(Bit#(32)) counter <- mkReg(0, clocked_by clock, reset_by reset); SyncPulseIfc startElapsed <- mkSyncHandshake(defaultClock, defaultReset, clock); SyncPulseIfc getElapsed <- mkSyncHandshake(defaultClock, defaultReset, clock); SyncFIFOIfc#(Bit#(32)) elapsedFifo <- mkSyncFIFO(2, clock, reset, defaultClock); rule cyclecount; let c = counter + 1; if (startElapsed.pulse()) c = 0; counter <= c; endrule rule calcElapsed if (getElapsed.pulse()); elapsedFifo.enq(counter); endrule Reg#(Bit#(32)) counterALimit <- mkReg(0); Reg#(Bit#(32)) counterA <- mkReg(0); rule periodACount if (counterA < counterALimit); counterA <= counterA + 1; if (counterA == counterALimit - 1) getElapsed.send(); endrule method Action start(Bit#(32) periodA); counterA <= 0; counterALimit <= periodA; startElapsed.send(); endmethod method ActionValue#(Bit#(32)) elapsedCycles(); elapsedFifo.deq(); return elapsedFifo.first(); endmethod endmodule module mkTB(Empty); Clock c <- exposeCurrentClock(); Reset r <- exposeCurrentReset(); let fc <- mkFrequencyCounter(c,r); Stmt test = (seq delay(10); fc.start(10); action let v <- fc.elapsedCycles; $display(v); endaction endseq); mkAutoFSM(test); endmodule ================================================ FILE: lib/bsv/HDMI.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Vector::*; import Clocks::*; import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import GetPut::*; import SyncBits::*; import YUV::*; import Arith::*; `ifdef ZC706 typedef 24 HdmiBits; `else typedef 16 HdmiBits; `endif interface HDMI#(type pixelType); method Bit#(1) hdmi_vsync; method Bit#(1) hdmi_hsync; method Bit#(1) hdmi_de; method pixelType hdmi_data; interface Clock hdmi_clock_if; interface Reset deleteme_unused_reset; endinterface interface HdmiGeneratorRequest; method Action setTestPattern(Bit#(1) v); method Action setPatternColor(Bit#(32) v); method Action setDePixel(Bit#(12) frontPorch, Bit#(12) syncWidth, Bit#(12) visible, Bit#(12) last, Bit#(12) mid); method Action setDeLine(Bit#(11) frontPorch, Bit#(11) syncWidth, Bit#(11) visible, Bit#(11) last, Bit#(11) mid); method Action waitForVsync(Bit#(32) unused); endinterface interface HdmiGeneratorIndication; method Action vsync(Bit#(64) v, Bit#(32) vs); endinterface interface HdmiGenerator#(type pixelType); interface HdmiGeneratorRequest request; interface Get#(VideoData#(pixelType)) rgb888; interface Put#(Bit#(32)) pdata; endinterface module mkHdmiGenerator#(Clock axi_clock, Reset axi_reset, SyncPulseIfc startDMA, HdmiGeneratorIndication indication)(HdmiGenerator#(Rgb888)); let verbose = True; Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); // 1920 * 1080 // horiz: frontPorch:87, sync: 44, backPorch:148, pixel:1920 // vert: frontPorch:3, sync:5, backPorch:36, lines:1080 `define hFront 87 `define hSync 44 `define hBack 148 `define hPixel 1920 `define vFront 3 `define vSync 5 `define vBack 36 `define vLines 1080 //`define hFront 88 //`define hSync 44 //`define hBack 280 //`define hPixel 1920 //`define vFront 4 //`define vSync 5 //`define vBack 45 //`define vLines 1080 Reg#(Bit#(12)) dePixelStartSync <- mkSyncReg( `hFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(12)) dePixelEndSync <- mkSyncReg( `hSync + `hFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(12)) dePixelStartVisible <- mkSyncReg(`hBack + `hSync + `hFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(12)) dePixelEnd <- mkSyncReg( `hPixel + `hBack + `hSync + `hFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(12)) dePixelMid <- mkSyncReg((`hPixel/2) + `hBack + `hSync, axi_clock, axi_reset, defaultClock); Reg#(Bit#(11)) deLineStartSync <- mkSyncReg( `vFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(11)) deLineEndSync <- mkSyncReg( `vSync + `vFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(11)) deLineStartVisible <- mkSyncReg( `vBack + `vSync + `vFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(11)) deLineEnd <- mkSyncReg( `vLines + `vBack + `vSync + `vFront, axi_clock, axi_reset, defaultClock); Reg#(Bit#(11)) deLineMid <- mkSyncReg((`vLines/2) + `vBack + `vSync, axi_clock, axi_reset, defaultClock); Vector#(4, Reg#(Bit#(24))) patternRegs <- replicateM(mkSyncReg(24'h00FFFFFF, axi_clock, axi_reset, defaultClock)); Reg#(Bit#(1)) shadowTestPatternEnabled <- mkSyncReg(1, axi_clock, axi_reset, defaultClock); Reg#(Bool) waitingForVsync <- mkSyncReg(False, axi_clock, axi_reset, defaultClock); SyncPulseIfc sendVsyncIndication <- mkSyncHandshake(defaultClock, defaultReset, axi_clock); Reg#(Bit#(11)) lineCount <- mkReg(0); Reg#(Bit#(12)) pixelCount <- mkReg(0); Reg#(Bit#(1)) patternIndex0 <- mkReg(0); Reg#(Bit#(1)) patternIndex1 <- mkReg(0); Reg#(Bit#(1)) testPatternEnabled <- mkReg(1); Reg#(Bool) dataEnable <- mkReg(False); Reg#(Bool) lineVisible <- mkReg(False); Reg#(Bit#(1)) vsync <- mkReg(0); Reg#(Bit#(1)) hsync <- mkReg(0); Reg#(Bit#(32)) vsyncCounter <- mkReg(0); Reg#(VideoData#(Rgb888)) rgb888StageReg <- mkReg(unpack(0)); Reg#(Bool) evenOddPixelReg <- mkReg(False); Reg#(Bit#(32)) underflowCount <- mkReg(0); Reg#(Bit#(32)) underflowCountAxi <- mkSyncReg(0, defaultClock, defaultReset, axi_clock); Reg#(Bit#(32)) counter <- mkReg(0, clocked_by axi_clock, reset_by axi_reset); Reg#(Bit#(32)) elapsed <- mkReg(0, clocked_by axi_clock, reset_by axi_reset); Reg#(Bit#(32)) elapsedVsync <- mkReg(0, clocked_by axi_clock, reset_by axi_reset); SyncBitIfc#(Bit#(32)) vsyncCounters <- mkSyncBits(0, defaultClock, defaultReset, axi_clock, axi_reset); Wire#(Bool) gotDataWire <- mkDWire(False); rule vsyncaxi; vsyncCounters.send(vsyncCounter); endrule rule axicyclecount; counter <= counter + 1; endrule rule vsyncReceived if (sendVsyncIndication.pulse()); $display("HDMI: sending vsync"); elapsed <= counter; elapsedVsync <= vsyncCounters.read(); indication.vsync(extend(elapsed - counter), vsyncCounter - vsyncCounter); waitingForVsync <= False; endrule rule init_pattern; patternRegs[1] <= 24'h00FF0000; // blue patternRegs[2] <= 24'h0000FF00; // green patternRegs[3] <= 24'h000000FF; // red //patternRegs[1] <= 32'h80ff80ff; // yuv422 white //patternRegs[2] <= 32'h2c961596; // yuv422 green //patternRegs[3] <= 32'hff1d6b1d; // yuv422 red endrule rule inc_counters; if (pixelCount == dePixelEnd) begin if (testPatternEnabled == 0 && verbose) $display("HDMI: endofline %d", lineCount); pixelCount <= 0; dataEnable <= False; patternIndex0 <= 0; if (lineCount == deLineEnd) begin lineCount <= 0; patternIndex1 <= 0; lineVisible <= False; if (verbose) $display("HDMI: lineVisible off"); testPatternEnabled <= shadowTestPatternEnabled; $display("HDMI: lineend %d", waitingForVsync); if (waitingForVsync) sendVsyncIndication.send(); end else begin if (lineCount == deLineStartVisible) begin lineVisible <= True; if (verbose) $display("HDMI: lineVisible on"); end lineCount <= lineCount+1; if (lineCount >= deLineMid) patternIndex1 <= 1; end end else begin if (lineCount == deLineStartSync) begin vsync <= 1; if (pixelCount == 0 && testPatternEnabled == 0) begin vsyncCounter <= vsyncCounter+1; startDMA.send(); $display("HDMI:vsync %d", lineCount); end end else if (lineCount == deLineEndSync) vsync <= 0; if (pixelCount == dePixelStartSync) hsync <= 1; else if (pixelCount == dePixelEndSync) hsync <= 0; if (pixelCount == dePixelStartVisible) dataEnable <= lineVisible; pixelCount <= pixelCount + 1; if (pixelCount == dePixelMid) patternIndex0 <= 1; end endrule rule output_data_rule if (!dataEnable); rgb888StageReg <= VideoData {de: 0, pixel: unpack(0), vsync: vsync, hsync: hsync }; endrule rule testpattern_rule if (testPatternEnabled != 0 && dataEnable); rgb888StageReg <= VideoData {de: 1, vsync: 0, hsync: 0, pixel: unpack(patternRegs[{patternIndex1, patternIndex0}])}; endrule rule gdr if (testPatternEnabled == 0 && dataEnable && !gotDataWire); $display("HDMI::nodata [%d:%d]", lineCount, pixelCount); endrule interface Put pdata; method Action put(Bit#(32) v) if (testPatternEnabled == 0 && dataEnable); rgb888StageReg <= VideoData {de: 1, vsync: 0, hsync: 0, pixel: unpack(v[23:0])}; gotDataWire <= True; //if (verbose) //$display("HDMI::pdata [%d:%d] = %x", lineCount, pixelCount, v); endmethod endinterface interface HdmiGeneratorRequest request; method Action setPatternColor(Bit#(32) v); patternRegs[0] <= v[23:0]; endmethod method Action setTestPattern(Bit#(1) v); shadowTestPatternEnabled <= v; endmethod method Action setDePixel(Bit#(12) frontPorch, Bit#(12) syncWidth, Bit#(12) visible, Bit#(12) last, Bit#(12) mid); dePixelStartSync <= frontPorch; dePixelEndSync <= syncWidth; dePixelStartVisible <= visible; dePixelEnd <= last; dePixelMid <= mid; endmethod method Action setDeLine(Bit#(11) frontPorch, Bit#(11) syncWidth, Bit#(11) visible, Bit#(11) last, Bit#(11) mid); deLineStartSync <= frontPorch; deLineEndSync <= syncWidth; deLineStartVisible <= visible; deLineEnd <= last; deLineMid <= mid; endmethod method Action waitForVsync(Bit#(32) unused); waitingForVsync <= True; $display("HDMI: waitForVsync set"); endmethod endinterface interface Get rgb888; method ActionValue#(VideoData#(Rgb888)) get(); return rgb888StageReg; endmethod endinterface endmodule module mkHDMI#(Get#(VideoData#(pixelType)) videoInput)(HDMI#(Bit#(pixelsz))) provisos (Bits#(VideoData#(pixelType), a__), Bits#(pixelType,pixelsz)); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); Wire#(VideoData#(pixelType)) video <- mkDWire(unpack(0)); rule getvideo; let v <- videoInput.get(); video <= v; endrule method Bit#(1) hdmi_vsync; return video.vsync; endmethod method Bit#(1) hdmi_hsync; return video.hsync; endmethod method Bit#(1) hdmi_de; return video.de; endmethod method Bit#(pixelsz) hdmi_data; return pack(video.pixel); endmethod interface hdmi_clock_if = defaultClock; interface deleteme_unused_reset = defaultReset; endmodule interface Rgb888ToYyuv; interface Put#(VideoData#(Rgb888)) rgb888; interface Get#(VideoData#(Yyuv)) yyuv; endinterface (* synthesize *) module mkRgb888ToYyuv(Rgb888ToYyuv); Reg#(VideoData#(Rgb888)) stage0Reg <- mkReg(unpack(0)); Reg#(VideoData#(Yuv444Intermediates)) stage1Reg <- mkReg(unpack(0)); Reg#(VideoData#(Vector#(2,Vector#(3,Bit#(16))))) stage2Reg <- mkReg(unpack(0)); Reg#(VideoData#(Yuv444)) stage3Reg <- mkReg(unpack(0)); Reg#(VideoData#(Yyuv)) stage4Reg <- mkReg(unpack(0)); Reg#(Bool) evenOddPixelReg <- mkReg(False); rule stage1_rule; let previous = stage0Reg; let pixel = previous.pixel; stage1Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: (previous.de != 0) ? rgbToYuvIntermediates(pixel) : unpack(0) }; endrule rule stage2_rule; let previous = stage1Reg; Vector#(4, Vector#(3, Bit#(16))) vprev = previous.pixel; Vector#(2, Vector#(3, Bit#(16))) vnext; vnext[0] = vadd(vprev[0], vprev[1]); vnext[1] = vadd(vprev[2], vprev[3]); stage2Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: (previous.de != 0) ? vnext : unpack(0) }; endrule rule stage3_rule; let previous = stage2Reg; Vector#(2, Vector#(3, Bit#(16))) vprev = previous.pixel; Yuv444 pixel = yuv444FromVector(vrshift(vadd(vprev[0], vprev[1]), 8)); stage3Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: (previous.de != 0) ? pixel : unpack(0) }; endrule rule stage4_rule; let previous = stage3Reg; if (previous.de != 0) evenOddPixelReg <= !evenOddPixelReg; Yyuv data = Yyuv { uv: evenOddPixelReg ? previous.pixel.u : previous.pixel.v, yy: previous.pixel.y }; stage4Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: data }; endrule interface Put rgb888; method Action put(VideoData#(Rgb888) v); stage0Reg <= v; endmethod endinterface interface Get yyuv; method ActionValue#(VideoData#(Yyuv)) get(); return stage4Reg; endmethod endinterface endmodule ================================================ FILE: lib/bsv/HdmiDisplay.bsv ================================================ // Copyright (c) 2012 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import BRAMFIFO::*; import Vector::*; import Clocks::*; import GetPut::*; import ClientServer::*; import Connectable::*; import ConnectalMemTypes::*; import MemReadEngine::*; import HDMI::*; import XADC::*; import YUV::*; import BlueScope::*; interface HdmiDisplayRequest; method Action startFrameBuffer(Int#(32) base, UInt#(32) byteCount); method Action stopFrameBuffer(); method Action getTransferStats(); method Action setTraceTransfers(Bit#(1) trace); endinterface interface HdmiDisplayIndication; method Action transferStarted(Bit#(32) count); method Action transferFinished(Bit#(32) count, Bit#(32) byteLen); method Action transferStats(Bit#(32) count, Bit#(32) transferCycles, Bit#(64) sumOfCycles); endinterface interface HdmiDisplay; `ifdef HDMI_BLUESCOPE interface BlueScopeRequest bluescopeRequest; interface MemWriteClient#(64) bluescopeWriteClient; `endif interface HdmiDisplayRequest displayRequest; interface HdmiGeneratorRequest internalRequest; interface Vector#(1, MemReadClient#(64)) dmaClient; interface HDMI#(Bit#(HdmiBits)) hdmi; interface XADC xadc; endinterface typedef 3 NumOutstandingRequests; typedef 64 FrameBufferBurstLenInBytes; module mkHdmiDisplay#(Clock hdmi_clock, HdmiDisplayIndication hdmiDisplayIndication, HdmiGeneratorIndication hdmiGeneratorIndication `ifdef HDMI_BLUESCOPE , BlueScopeIndication bluescopeIndication `endif )(HdmiDisplay); let verbose = False; Clock defaultClock <- exposeCurrentClock; Reset defaultReset <- exposeCurrentReset; Reset hdmi_reset <- mkAsyncReset(2, defaultReset, hdmi_clock); MakeResetIfc fifo_reset <- mkReset(2, True, defaultClock); Reset fifo_reset_hdmi <- mkAsyncReset(2, fifo_reset.new_rst, hdmi_clock); Reg#(UInt#(24)) byteCountReg <- mkReg(1080*1920); Reg#(Bit#(24)) frameByte <- mkReg(99, clocked_by hdmi_clock, reset_by hdmi_reset); Reg#(Bit#(24)) frameByteSaved <- mkSyncReg(1234, hdmi_clock, hdmi_reset, defaultClock); Reg#(Bool) frameByteReady <- mkReg(False, clocked_by hdmi_clock, reset_by hdmi_reset); Reg#(Bool) sendVsyncIndication <- mkReg(False); SyncPulseIfc startDMA <- mkSyncHandshake(hdmi_clock, hdmi_reset, defaultClock); Reg#(Bit#(1)) bozobit <- mkReg(0, clocked_by hdmi_clock, reset_by hdmi_reset); Reg#(Maybe#(Bit#(32))) referenceReg <- mkReg(tagged Invalid); MemReadEngine#(64,64,NumOutstandingRequests,1) memreadEngine <- mkMemReadEngine; HdmiGenerator#(Rgb888) hdmiGen <- mkHdmiGenerator(defaultClock, defaultReset, startDMA, hdmiGeneratorIndication, clocked_by hdmi_clock, reset_by hdmi_reset); `ifndef ZC706 Rgb888ToYyuv converter <- mkRgb888ToYyuv(clocked_by hdmi_clock, reset_by fifo_reset_hdmi); mkConnection(hdmiGen.rgb888, converter.rgb888); HDMI#(Bit#(HdmiBits)) hdmisignals <- mkHDMI(converter.yyuv, clocked_by hdmi_clock, reset_by hdmi_reset); `else HDMI#(Bit#(HdmiBits)) hdmisignals <- mkHDMI(hdmiGen.rgb888, clocked_by hdmi_clock, reset_by hdmi_reset); `endif `ifdef HDMI_BLUESCOPE let bluescope <- mkSyncBlueScope(65536, bluescopeIndication, hdmi_clock, hdmi_reset, defaultClock, defaultReset); MIMO#(1, 16, 64, Bit#(4)) mimo <- mkMIMO(MIMOConfiguration { unguarded: False, bram_based: False }, clocked_by hdmi_clock, reset_by hdmi_reset); Reg#(Bool) triggered <- mkReg(False, clocked_by hdmi_clock, reset_by hdmi_reset); rule toGearbox if ((hdmisignals.hdmi_vsync == 1) || triggered); Bit#(4) v = 0; v[0] = hdmisignals.hdmi_vsync; v[1] = hdmisignals.hdmi_de; v[2] = hdmisignals.hdmi_hsync; v[3] = hdmisignals.hdmi_vsync; triggered <= True; if (mimo.enqReadyN(1)) mimo.enq(1, cons(v,nil)); else $display("mimo.stalled mimo.count=%d", mimo.count); endrule rule gearboxToBlueScope if (mimo.deqReadyN(16)); Bit#(64) v = pack(mimo.first()); mimo.deq(16); bluescope.dataIn(v, v); endrule `endif rule toSaved if (hdmisignals.hdmi_vsync == 1); if (frameByteReady && frameByte != 0) begin frameByteSaved <= frameByte; frameByte <= 0; end frameByteReady <= False; endrule rule endsync if (hdmisignals.hdmi_vsync != 1); frameByteReady <= True; endrule SyncFIFOIfc#(Bit#(64)) synchronizer <- mkSyncBRAMFIFO(1024, defaultClock, fifo_reset.new_rst, hdmi_clock, fifo_reset_hdmi); //SyncFIFOIfc#(Bit#(64)) synchronizer <- mkSyncFIFO(16, defaultClock, fifo_reset.new_rst, hdmi_clock); Reg#(Bool) evenOdd <- mkReg(True, clocked_by hdmi_clock, reset_by fifo_reset_hdmi); Reg#(Bit#(32)) savedPixelReg <- mkReg(0, clocked_by hdmi_clock, reset_by fifo_reset_hdmi); Reg#(Bit#(32)) transferCount <- mkReg(0); Reg#(Bit#(32)) transferCyclesSnapshot <- mkReg(0); Reg#(Bit#(32)) transferCycles <- mkReg(0); Reg#(Bit#(48)) transferSumOfCycles<- mkReg(0); Reg#(UInt#(24)) transferWord <- mkReg(0); Reg#(Bit#(32)) transferLast <- mkReg(0); ClockDividerIfc slowClock <- mkClockDivider(64); Reset slowReset <- mkAsyncReset(2, defaultReset, slowClock.slowClock); SyncPulseIfc dmastartPulse <- mkSyncPulse(defaultClock, defaultReset, slowClock.slowClock); SyncPulseIfc dmaendPulse <- mkSyncPulse(defaultClock, defaultReset, slowClock.slowClock); Reg#(Bool) dmastart <- mkReg(False, clocked_by slowClock.slowClock, reset_by slowReset); Reg#(Bool) dmaend <- mkReg(False, clocked_by slowClock.slowClock, reset_by slowReset); Reg#(Bool) dmaendDelay <- mkReg(False, clocked_by slowClock.slowClock, reset_by slowReset); Reg#(Bit#(3)) dmaCount <- mkReg(0); Reg#(Bool) traceTransfers <- mkReg(False); Reg#(Bool) dumpstarted <- mkReg(False); Reg#(Bool) dumpover <- mkReg(False); Reg#(Bool) duringDma <- mkReg(False); //Reg#(Bool) dmaReady <- mkReg(False); FIFO#(void) doneFifo <- mkFIFO; rule dmaPulserule; dmastart <= dmastartPulse.pulse; dmaend <= dmaendPulse.pulse; dmaendDelay <= dmaend; endrule rule fromMemread; let v <- toGet(memreadEngine.readServers[0].data).get; synchronizer.enq(v.data); if (verbose) $display("hdmiDisplay: dmadata [%d]=%x cycle %d", transferWord, v.data, transferCycles - transferCyclesSnapshot); transferWord <= transferWord + 1; transferLast <= transferCycles; if (v.last) doneFifo.enq(?); endrule rule doPut1 if (evenOdd); Vector#(2,Bit#(32)) doublePixel = unpack(synchronizer.first); synchronizer.deq; savedPixelReg <= doublePixel[1]; frameByte <= frameByte + 1; //if (dmaReady) begin //if (verbose) //$display("hdmiDisplay: SKIP sync.deq %x:%x cycle %d", doublePixel[0], doublePixel[1], transferCycles - transferCyclesSnapshot); //end //else begin if (verbose) $display("hdmiDisplay: even sync.deq %x:%x cycle %d", doublePixel[0], doublePixel[1], transferCycles - transferCyclesSnapshot); hdmiGen.pdata.put(doublePixel[0]); evenOdd <= !evenOdd; //end endrule rule doPut2 if (!evenOdd); if (verbose) $display("hdmiDisplay: odd cycle %d", transferCycles - transferCyclesSnapshot); hdmiGen.pdata.put(savedPixelReg); evenOdd <= !evenOdd; endrule rule vsyncrule if (startDMA.pulse()); fifo_reset.assertReset(); endrule rule startTransfer if (startDMA.pulse() &&& referenceReg matches tagged Valid .reference); // /dmaReady <= True; ///endrule //rule startd if (dmaReady && !duringDma &&& referenceReg matches tagged Valid .reference); memreadEngine.readServers[0].request.put(MemengineCmd{sglId:reference, base:0, len:pack(extend(byteCountReg)), burstLen:fromInteger(valueOf(FrameBufferBurstLenInBytes)), tag: 0}); if (traceTransfers) hdmiDisplayIndication.transferStarted(transferCount); transferCyclesSnapshot <= transferCycles; transferWord <= 0; $display("hdmiDisplay: startdma %d residual %d gap %d", transferCycles - transferCyclesSnapshot, byteCountReg - 8 * transferWord, transferCycles - transferLast); dmastartPulse.send(); dmaCount <= dmaCount + 1; if (dmaCount == 7 && !dumpover) begin $dumpoff; dumpover <= True; end //dmaReady <= False; duringDma <= True; endrule rule countCycles; transferCycles <= transferCycles + 1; endrule rule finishTransferRule; doneFifo.deq; transferCount <= transferCount + 1; let tc = transferCycles - transferCyclesSnapshot; transferSumOfCycles <= transferSumOfCycles + extend(tc); if (traceTransfers) hdmiDisplayIndication.transferFinished(transferCount, extend(frameByteSaved)); $display("hdmiDisplay: enddma %d", transferCycles - transferCyclesSnapshot); dmaendPulse.send(); duringDma <= False; if (!dumpstarted) begin //$dumpfile("dump.vcd"); $dumpvars; $dumpon; $display("VCDDUMP starting"); dumpstarted <= True; end endrule rule bozobit_rule; bozobit <= ~bozobit; endrule interface HdmiDisplayRequest displayRequest; method Action startFrameBuffer(Int#(32) base, UInt#(32) byteCount); byteCountReg <= truncate(byteCount); $display("startFrameBuffer base %x count %d", base, byteCount); referenceReg <= tagged Valid truncate(pack(base)); endmethod method Action stopFrameBuffer(); referenceReg <= tagged Invalid; endmethod method Action getTransferStats(); hdmiDisplayIndication.transferStats(transferCount, transferCycles-transferCyclesSnapshot, extend(transferSumOfCycles)); endmethod method Action setTraceTransfers(Bit#(1) trace); traceTransfers <= unpack(trace); endmethod endinterface: displayRequest interface MemReadClient dmaClient = cons(memreadEngine.dmaClient, nil); interface HDMI hdmi = hdmisignals; interface HdmiGeneratorRequest internalRequest = hdmiGen.request; `ifdef HDMI_BLUESCOPE interface BlueScopeRequest bluescopeRequest = bluescope.requestIfc; interface MemWriteClient bluescopeWriteClient = bluescope.writeClient; `endif interface XADC xadc; method Bit#(4) gpio; return { bozobit, hdmisignals.hdmi_vsync, //hdmisignals.hdmi_data[8], hdmisignals.hdmi_data[0]}; hdmisignals.hdmi_hsync, hdmisignals.hdmi_de}; endmethod endinterface: xadc endmodule ================================================ FILE: lib/bsv/ImageonVita.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Vector::*; import Clocks::*; import DefaultValue::*; import XilinxCells::*; import ConnectalClocks::*; import ConnectalXilinxCells::*; typedef struct { Bool increment; Bit#(1) ce; Bit#(1) bitslip; } SerdesStart deriving (Bits); interface IserdesCore; method Action io_vita_data_p(Bit#(1) v); method Action io_vita_data_n(Bit#(1) v); method Bit#(10) data(); endinterface: IserdesCore module mkIserdesCore#(Clock serdes_clock, Reset serdes_reset, Clock serdest, Clock serdest_inverted, Bit#(1) astate_reset, SerdesStart param)(IserdesCore); Wire#(Bit#(1)) vita_data_p <- mkDWire(0); Wire#(Bit#(1)) vita_data_n <- mkDWire(0); `ifndef SIMULATION Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); IdelayE2 delaye2 <- mkIDELAYE2(IDELAYE2_Config { cinvctrl_sel: "FALSE", delay_src: "IDATAIN", high_performance_mode: "TRUE", idelay_type: "VARIABLE", idelay_value: 0, pipe_sel: "FALSE", refclk_frequency: 200, signal_pattern: "DATA"}, defaultClock, clocked_by serdes_clock); Vector#(2, IserdesE2) iserdes_v; iserdes_v[0] <- mkISERDESE2( ISERDESE2_Config{ data_rate: "DDR", data_width: 10, dyn_clk_inv_en: "FALSE", dyn_clkdiv_inv_en: "FALSE", interface_type: "NETWORKING", num_ce: 2, ofb_used: "FALSE", init_q1: 0, init_q2: 0, init_q3: 0, init_q4: 0, srval_q1: 0, srval_q2: 0, srval_q3: 0, srval_q4: 0, serdes_mode: "MASTER", iobdelay: "IFD"}, serdest, serdest_inverted, clocked_by serdes_clock, reset_by serdes_reset); iserdes_v[1] <- mkISERDESE2( ISERDESE2_Config{ data_rate: "DDR", data_width: 10, dyn_clk_inv_en: "FALSE", dyn_clkdiv_inv_en: "FALSE", interface_type: "NETWORKING", num_ce: 2, ofb_used: "FALSE", init_q1: 0, init_q2: 0, init_q3: 0, init_q4: 0, srval_q1: 0, srval_q2: 0, srval_q3: 0, srval_q4: 0, serdes_mode: "SLAVE", iobdelay: "NONE"}, serdest, serdest_inverted, clocked_by serdes_clock, reset_by serdes_reset); ReadOnly#(Bit#(1))ibufds_v <- mkIBUFDS(vita_data_p, vita_data_n); (* no_implicit_conditions *) rule setruledata; delaye2.idatain(ibufds_v); endrule (* no_implicit_conditions *) rule setrule; delaye2.reset(astate_reset); delaye2.cinvctrl(0); delaye2.cntvaluein(0); delaye2.ld(0); delaye2.ldpipeen(0); delaye2.datain(0); delaye2.inc(param.increment); delaye2.ce(param.ce); for (Integer i = 0; i < 2; i = i + 1) begin iserdes_v[i].d(0); iserdes_v[i].bitslip(param.bitslip); iserdes_v[i].ce1(1); iserdes_v[i].ce2(1); iserdes_v[i].ofb(0); iserdes_v[i].dynclkdivsel(0); iserdes_v[i].dynclksel(0); iserdes_v[i].oclk(0); iserdes_v[i].oclkb(0); iserdes_v[i].reset(astate_reset); end iserdes_v[0].ddly(delaye2.dataout()); iserdes_v[0].shiftin1(0); iserdes_v[0].shiftin2(0); iserdes_v[1].ddly(0); iserdes_v[1].shiftin1(iserdes_v[0].shiftout1()); iserdes_v[1].shiftin2(iserdes_v[0].shiftout2()); endrule method Bit#(10) data(); return {iserdes_v[1].q4(), iserdes_v[1].q3(), iserdes_v[0].q8(), iserdes_v[0].q7(), iserdes_v[0].q6(), iserdes_v[0].q5(), iserdes_v[0].q4(), iserdes_v[0].q3(), iserdes_v[0].q2(), iserdes_v[0].q1()}; `else method Bit#(10) data(); return 0; `endif endmethod method Action io_vita_data_p(Bit#(1) v); vita_data_p <= v; endmethod method Action io_vita_data_n(Bit#(1) v); vita_data_n <= v; endmethod endmodule interface SerdesClock; interface Clock serdes_clkif; interface Reset serdes_resetif; interface Clock serdest_clkif; method Action io_vita_clk_p(Bit#(1) v); method Action io_vita_clk_n(Bit#(1) v); endinterface (* synthesize *) module mkSerdesClock(SerdesClock); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); `ifdef SIMULATION Wire#(Bit#(1)) vita_clk_p <- mkDWire(0); Wire#(Bit#(1)) vita_clk_n <- mkDWire(0); interface Clock serdes_clkif = defaultClock; interface Reset serdes_resetif = defaultReset; interface Clock serdest_clkif = defaultClock; method Action io_vita_clk_p(Bit#(1) v); endmethod method Action io_vita_clk_n(Bit#(1) v); endmethod `else B2C1 vita_clk_p <- mkB2C1(); B2C1 vita_clk_n <- mkB2C1(); Clock ibufds_clk <- mkClockIBUFDS( `ifdef ClockDefaultParam defaultValue, `endif vita_clk_p.c, vita_clk_n.c); ClockGenIfc serdes_clk <- mkBUFR5(ibufds_clk); ClockGenIfc serdest_clk <- mkBUFIO(ibufds_clk); Reset serdes_reset <- mkAsyncReset(2, defaultReset, serdes_clk.gen_clk); interface Clock serdes_clkif = serdes_clk.gen_clk; interface Reset serdes_resetif = serdes_reset; interface Clock serdest_clkif = serdest_clk.gen_clk; method Action io_vita_clk_p(Bit#(1) v); vita_clk_p.inputclock(v); endmethod method Action io_vita_clk_n(Bit#(1) v); vita_clk_n.inputclock(v); endmethod `endif endmodule interface ImageClocks; interface Clock imageon; interface Clock hdmi; endinterface (* synthesize *) module mkImageClocks#(Clock fmc_imageon_clk1)(ImageClocks); `ifndef SIMULATION ClockGenerator7AdvParams clockParams = defaultValue; clockParams.bandwidth = "OPTIMIZED"; clockParams.compensation = "ZHOLD"; clockParams.clkfbout_mult_f = 8.000; clockParams.clkfbout_phase = 0.0; clockParams.clkin1_period = 6.734007; // 148.5 MHz clockParams.clkin2_period = 6.734007; clockParams.clkout0_divide_f = 8.000; // 148.5 MHz clockParams.clkout0_duty_cycle = 0.5; clockParams.clkout0_phase = 0.0000; clockParams.clkout1_divide = 32; // 37.125 MHz clockParams.clkout1_duty_cycle = 0.5; clockParams.clkout1_phase = 0.0000; clockParams.divclk_divide = 1; clockParams.ref_jitter1 = 0.010; clockParams.ref_jitter2 = 0.010; XClockGenerator7 clockGen <- mkClockGenerator7Adv(clockParams, clocked_by fmc_imageon_clk1); C2B c2b_fb <- mkC2B(clockGen.clkfbout, clocked_by clockGen.clkfbout); rule txoutrule5; clockGen.clkfbin(c2b_fb.o()); endrule Clock hdmi_clock <- mkClockBUFG(clocked_by clockGen.clkout0); // 148.5 MHz Clock imageon_clock <- mkClockBUFG(clocked_by clockGen.clkout1); // 37.125 MHz `else Clock defaultClock <- exposeCurrentClock(); Clock hdmi_clock = defaultClock; Clock imageon_clock = defaultClock; `endif interface hdmi = hdmi_clock; interface imageon = imageon_clock; endmodule ================================================ FILE: lib/bsv/IserdesDatadeser.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import Clocks::*; import FIFO::*; import FIFOF::*; import SyncBits::*; import ImageonVita::*; import IserdesDatadeserIF::*; typedef Vector#(10, Reg#(Bit#(10))) TrainRotate; typedef enum { AIdle, AReset, AEdge, AWait, AShift, ARotated, AFirst, ASecond, AFound, AAlign} AState deriving (Bits,Eq); //(* synthesize *) module mkIserdesDatadeser#(Clock serdes_clock, Reset serdes_reset, Clock serdest, Bit#(1) align_start, Bit#(1) autoalign, Bit#(10) training, Bit#(10) manual_tap, TrainRotate trainrot, Bool bvi_reset_reg, Bool fifo_wren_sync)(IserdesDatadeser); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); FIFOF#(Bit#(10)) dfifo <- mkFIFOF(clocked_by serdes_clock, reset_by serdes_reset); SyncBitIfc#(Bit#(10)) dfifo_data <- mkSyncBits(0, serdes_clock, serdes_reset, defaultClock, defaultReset); SyncBitIfc#(Bit#(1)) dfifo_empty <- mkSyncBit(serdes_clock, serdes_reset, defaultClock); SyncBitIfc#(Bool) bvi_resets_reg <- mkSyncBit(serdes_clock, serdes_reset, defaultClock); Reg#(Bit#(3)) ctrl_sample <- mkReg(0); Reg#(AState) astate <- mkReg(AIdle); Reg#(Bit#(1)) astate_reset <- mkSyncReg(0, defaultClock, defaultReset, serdes_clock); Reg#(Bit#(10)) data_init1 <- mkReg(0); Reg#(Bit#(10)) data_init2 <- mkReg(0); Reg#(Bit#(10)) edge_init <- mkReg(0); Reg#(Bit#(10)) edge_int <- mkSyncReg(0, serdes_clock, serdes_reset, defaultClock); Reg#(Bit#(11)) maxcount <- mkReg(0); Reg#(Bit#(10)) windowcount <- mkReg(0); Reg#(Bit#(16)) retrycounter <- mkReg(0); Reg#(Bit#(16)) gencounter <- mkReg(0); SyncFIFOIfc#(SerdesStart) serdes_start <- mkSyncFIFO(2, defaultClock, defaultReset, serdes_clock); SyncFIFOIfc#(Bit#(1)) serdes_end <- mkSyncFIFO(2, serdes_clock, serdes_reset, defaultClock); Reg#(Bit#(1)) serdes_running <- mkReg(0, clocked_by serdes_clock, reset_by serdes_reset); Reg#(Bit#(10)) serdes_data <- mkReg(0, clocked_by serdes_clock, reset_by serdes_reset); Reg#(SerdesStart) syncparam <- mkReg(unpack(0), clocked_by serdes_clock, reset_by serdes_reset); Reg#(Bit#(3)) sync_counter <- mkReg(0, clocked_by serdes_clock, reset_by serdes_reset); Reg#(Bit#(10)) ctrl_data <- mkSyncReg(0, serdes_clock, serdes_reset, defaultClock); ClockDividerIfc serdest_inverted <- mkClockInverter(clocked_by serdest); IserdesCore core <- mkIserdesCore(serdes_clock, serdes_reset, serdest, serdest_inverted.slowClock, astate_reset, syncparam); //*************************** alignment operation FSM ***************** rule afsminit_rule if (!bvi_resets_reg.read()); ctrl_sample <= 0; edge_init <= 0; data_init1 <= 0; data_init2 <= 0; maxcount <= -1; windowcount <= 0; retrycounter <= -1; gencounter <= -1; astate <= AIdle; endrule rule afsmidle2_rule if (bvi_resets_reg.read() && astate == AIdle && align_start == 1); windowcount <= 0; retrycounter <= 'h7ffd; ctrl_sample <= 0; astate <= AReset; serdes_start.enq(SerdesStart{increment: False, ce:0, bitslip:0}); endrule rule afsmdelay_rule if (bvi_resets_reg.read() && astate == AReset); serdes_end.deq(); let gc = 15; if (autoalign == 0) begin gc = {6'b0, manual_tap}; astate <= AFound; end else astate <= AEdge; maxcount <= 31; gencounter <= gc; serdes_start.enq(SerdesStart{increment: False, ce:~autoalign, bitslip:0}); endrule rule afsmcedge1_rule if (bvi_resets_reg.read() && astate == AEdge && retrycounter < 'h8000); serdes_end.deq(); astate <= AIdle; endrule rule afsmcedge2_rule if (bvi_resets_reg.read() && astate == AEdge && retrycounter >= 'h8000); serdes_end.deq(); let mc = maxcount; let inctemp = False; if (edge_int != 0) begin data_init1 <= rotateBitsBy(ctrl_data, 10-1); data_init2 <= rotateBitsBy(ctrl_data, 10-2); edge_init <= edge_int; astate <= AWait; end else if (maxcount[10] == 1) astate <= AReset; else begin maxcount <= maxcount - 1; inctemp = True; astate <= AEdge; end retrycounter <= retrycounter - 1; serdes_start.enq(SerdesStart{increment: inctemp, ce:pack(inctemp), bitslip:0}); endrule rule afsmwait_rule if (bvi_resets_reg.read() && astate == AWait); serdes_end.deq(); let gc = gencounter - 1; if (gencounter >= 'h8000) begin gc = 9; astate <= AShift; end else begin let inctemp = False; if (edge_init != edge_int) begin if (maxcount[10] == 1) astate <= AReset; else begin gc = 14; inctemp = True; astate <= AEdge; end retrycounter <= retrycounter - 1; maxcount <= maxcount - 1; end serdes_start.enq(SerdesStart{increment: inctemp, ce:pack(inctemp), bitslip:0}); end gencounter <= gc; endrule rule afsmcompare_rule if (bvi_resets_reg.read() && astate == AShift); let gc = gencounter - 1; if (gencounter >= 'h8000) begin let inctemp = False; if (maxcount[10] == 1) astate <= AReset; else begin retrycounter <= retrycounter - 1; gc = 14; inctemp = True; astate <= AEdge; end serdes_start.enq(SerdesStart{increment: inctemp, ce:pack(inctemp), bitslip:0}); end else if (ctrl_data == trainrot[gencounter]) begin let csamplein = 3'b001; if (gencounter == 9) csamplein = 3'b010; else if (gencounter == 8) csamplein = 3'b100; ctrl_sample <= csamplein; astate <= ARotated; serdes_start.enq(SerdesStart{increment: True, ce:1, bitslip:0}); end gencounter <= gc; maxcount <= maxcount - 1; endrule rule afsm1changed_rule if (bvi_resets_reg.read() && astate == ARotated); serdes_end.deq(); let inctemp = False; if (ctrl_data == data_init1) begin gencounter <= 15; astate <= AFirst; end else if (maxcount[10] == 1) astate <= AReset; else begin inctemp = True; maxcount <= maxcount - 1; end serdes_start.enq(SerdesStart{increment: inctemp, ce:pack(inctemp), bitslip:0}); endrule rule afsm1stable_rule if (bvi_resets_reg.read() && astate == AFirst); serdes_end.deq(); let mc = maxcount; let inctemp = True; if (gencounter >= 'h8000) begin windowcount <= windowcount + 1; mc = mc - 1; astate <= ASecond; end else begin let gc = gencounter - 1; if (ctrl_data == data_init1) inctemp = False; else begin mc = mc - 1; gc = 15; astate <= ARotated; end gencounter <= gc; end maxcount <= mc; serdes_start.enq(SerdesStart{increment: inctemp, ce:pack(inctemp), bitslip:0}); endrule rule afsmsecond_rule if (bvi_resets_reg.read() && astate == ASecond); serdes_end.deq(); let inctemp = False; if (ctrl_data == data_init2) begin gencounter <= {7'b0, windowcount[9:1]} - 16'b10; astate <= AFound; end else if (maxcount[10] == 1) astate <= AReset; else begin windowcount <= windowcount + 1; inctemp = True; maxcount <= maxcount - 1; end serdes_start.enq(SerdesStart{increment: inctemp, ce:pack(inctemp), bitslip:0}); endrule rule afsmfound_rule if (bvi_resets_reg.read() && astate == AFound); serdes_end.deq(); let gc = gencounter; if (gencounter >= 'h8000) begin if (ctrl_data != training) begin gc = 8; astate <= AAlign; serdes_start.enq(SerdesStart{increment: False, ce:1, bitslip:0}); end else astate <= AIdle; end else begin gc = gc - 1; serdes_start.enq(SerdesStart{increment: autoalign == 1, ce:1, bitslip:0}); end gencounter <= gc; endrule rule afsmalign_rule if (bvi_resets_reg.read() && astate == AAlign); serdes_end.deq(); if (ctrl_data == training || gencounter >= 'h8000) astate <= AIdle; else begin gencounter <= gencounter - 1; serdes_start.enq(SerdesStart{increment: False, ce:0, bitslip:1}); end endrule //*************************** serdes setting FSM ***************** rule serdes_idle_rule if (bvi_reset_reg); if (serdes_start.notEmpty) begin serdes_start.deq(); syncparam <= serdes_start.first; serdes_running <= 1; sync_counter <= 3; end else begin syncparam <= unpack(0); sync_counter <= sync_counter - 1; end endrule rule serdes_running2_rule if (bvi_reset_reg && serdes_running == 1 && sync_counter[2] == 1); ctrl_data <= serdes_data; Bit#(10) edgeo = 0; for (Integer i = 0; i < 9; i = i + 1) edgeo[i] = serdes_data[i] ^ serdes_data[i+1]; edgeo[9] = serdes_data[0] ^ serdes_data[9]; edge_int <= edgeo; serdes_end.enq(1); serdes_running <= 0; endrule rule reset_clock_rule; bvi_resets_reg.send(bvi_reset_reg); endrule rule qfsmall; astate_reset <= pack(astate == AReset); endrule rule serdesreset_rule if (!bvi_reset_reg); syncparam <= unpack(0); serdes_running <= 0; dfifo.clear(); endrule rule clear_fifo if (astate_reset == 1); dfifo.clear(); endrule rule serdesda2_rule; let dout = core.data(); serdes_data <= dout; if (fifo_wren_sync) dfifo.enq(dout); endrule rule serdesrule; dfifo_data.send(dfifo.first); dfifo.deq(); endrule rule fifoe_rule; dfifo_empty.send(pack(!dfifo.notEmpty())); endrule SyncBitIfc#(Bit#(14)) serdes_capture <- mkSyncBits(0, serdes_clock, serdes_reset, defaultClock, defaultReset); Reg#(Bool) startCapture <- mkReg(False); rule startcap; if (bvi_resets_reg.read()) startCapture <= True; endrule rule capstateser; serdes_capture.send({pack(syncparam), pack(fifo_wren_sync), serdes_data}); endrule method Bit#(64) capture() if (startCapture); // early time capture return {edge_int, windowcount[4:0], pack(astate), ctrl_data, gencounter, ctrl_sample, align_start, autoalign, serdes_capture.read}; endmethod method Bit#(1) align_busy(); return pack(astate != AIdle); endmethod method Bit#(3) samplein(); return ctrl_sample; endmethod method Bit#(1) empty(); return dfifo_empty.read(); endmethod method Bit#(10) dataout(); return dfifo_data.read(); endmethod method io_vita_data_p = core.io_vita_data_p; method io_vita_data_n = core.io_vita_data_n; endmodule: mkIserdesDatadeser module mkISerdes#(Clock axi_clock, Reset axi_reset, ImageonSerdesIndication indication)(ISerdes); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); SerdesClock coreClock <- mkSerdesClock(); Clock serdes_clock = coreClock.serdes_clkif; Reset serdes_reset = coreClock.serdes_resetif; Reg#(Bit#(1)) decoder_enable_reg <- mkSyncReg(0, axi_clock, axi_reset, defaultClock); Reg#(Bit#(1)) serdes_auto_align_reg <- mkSyncReg(0, axi_clock, axi_reset, defaultClock); Reg#(Bit#(1)) serdes_align_start_reg <- mkSyncReg(0, axi_clock, axi_reset, defaultClock); Reg#(Bit#(1)) serdes_fifo_enable_reg <- mkSyncReg(0, axi_clock, axi_reset, defaultClock); ReadOnly#(Bit#(1)) serdes_fifo_enable_null <- mkNullCrossingWire(serdes_clock, serdes_fifo_enable_reg); Reg#(Bit#(10)) serdes_manual_tap_reg <- mkSyncReg(0, axi_clock, axi_reset, defaultClock); Reg#(Bit#(10)) serdes_training_reg <- mkSyncReg(0, axi_clock, axi_reset, defaultClock); Reg#(Bit#(1)) serdes_reset_reg <- mkSyncReg(1, axi_clock, axi_reset, defaultClock); ReadOnly#(Bit#(1)) serdes_reset_null <- mkNullCrossingWire(serdes_clock, serdes_reset_reg); Wire#(Bit#(50)) raw_data_wire <- mkDWire(0); Wire#(Bit#(1)) empty_wire <- mkDWire(0); SyncBitIfc#(Bit#(1)) serdes_align_busy_reg <- mkSyncBit(defaultClock, defaultReset, axi_clock); Reg#(Bit#(1)) new_raw_empty_reg <- mkReg(1); TrainRotate trainrot <- replicateM(mkSyncReg(0, axi_clock, axi_reset, defaultClock)); Vector#(5, IserdesDatadeser) pin_v <- replicateM(mkIserdesDatadeser(serdes_clock, serdes_reset, coreClock.serdest_clkif, serdes_align_start_reg, serdes_auto_align_reg, serdes_training_reg, serdes_manual_tap_reg, trainrot, serdes_reset_null != 0, serdes_fifo_enable_null != 0)); Reg#(Bit#(25)) control_data <- mkReg(0); Reg#(Bit#(50)) dump_data <- mkReg(0); rule sendup_imageon_clock; Bit#(5) alignbusyw = 0; Bit#(5) emptyw = 0; Bit#(15) samplein = 0; Bit#(50) rawdataw = 0; for (Bit#(8) i = 0; i < 5; i = i+1) begin alignbusyw[i] = pin_v[i].align_busy(); emptyw[i] = pin_v[i].empty(); samplein[(i+1)*3-1: i*3] = pin_v[i].samplein(); rawdataw[(i+1)*10-1: i*10] = pin_v[i].dataout(); end serdes_align_busy_reg.send(pack(~alignbusyw == 0)); //bittest_wire <= pack(samplein == 3'b110); empty_wire <= pack(emptyw != 0); raw_data_wire <= rawdataw; control_data <= {alignbusyw, emptyw, samplein}; dump_data <= rawdataw; endrule rule serdes_calc2; new_raw_empty_reg <= empty_wire; endrule //rule clear_align if (serdes_align_busy_reg.read() == 1); //serdes_align_start_reg <= 0; //endrule Reg#(Bool) runCapture <- mkSyncReg(False, axi_clock, axi_reset, defaultClock); interface ImageonSerdesRequest request; method Action set_serdes_manual_tap(Bit#(10) v); serdes_manual_tap_reg <= v; endmethod method Action set_serdes_training(Bit#(10) v); serdes_training_reg <= v; for (UInt#(4) i = 0; i < 10; i = i + 1) trainrot[i] <= rotateBitsBy(v, i+6); endmethod method Action set_iserdes_control(Bit#(32) v); serdes_reset_reg <= ~v[0]; serdes_auto_align_reg <= v[1]; serdes_align_start_reg <= v[2]; serdes_fifo_enable_reg <= v[3]; endmethod method Action get_iserdes_control(); let v = 0; v[9] = serdes_align_busy_reg.read(); indication.iserdes_control_value(v); endmethod method Action set_decoder_control(Bit#(32) v); decoder_enable_reg <= v[1]; endmethod endinterface interface ImageonSerdesPins pins; method Action io_vita_sync_p(Bit#(1) v); pin_v[0].io_vita_data_p(v); endmethod method Action io_vita_sync_n(Bit#(1) v); pin_v[0].io_vita_data_n(v); endmethod method Action io_vita_data_p(Bit#(4) v); for (Integer i = 0; i < 4; i = i + 1) pin_v[i+1].io_vita_data_p(v[i]); endmethod method Action io_vita_data_n(Bit#(4) v); for (Integer i = 0; i < 4; i = i + 1) pin_v[i+1].io_vita_data_n(v[i]); endmethod method io_vita_clk_p = coreClock.io_vita_clk_p; method io_vita_clk_n = coreClock.io_vita_clk_n; endinterface interface SerdesData data; method Reg#(Bit#(1)) reset(); return serdes_reset_reg; endmethod method Vector#(5, Bit#(10)) raw_data() if (new_raw_empty_reg == 0 && serdes_reset_reg != 0); Vector#(5, Bit#(10)) in = unpack(raw_data_wire); return in; endmethod method Bit#(64) capture(); // late-time capture if (runCapture); return pin_v[0].capture(); //{control_data, dump_data[38:0]}; endmethod method Action start_capture(); runCapture <= True; endmethod endinterface endmodule ================================================ FILE: lib/bsv/IserdesDatadeserIF.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; interface IserdesDatadeser; method Bit#(1) align_busy(); method Bit#(3) samplein(); method Bit#(1) empty(); method Bit#(10) dataout(); method Action io_vita_data_p(Bit#(1) v); method Action io_vita_data_n(Bit#(1) v); method Bit#(64) capture(); endinterface: IserdesDatadeser (* always_enabled *) interface ImageonSerdesPins; method Action io_vita_sync_p(Bit#(1) v); method Action io_vita_sync_n(Bit#(1) v); method Action io_vita_data_p(Bit#(4) v); method Action io_vita_data_n(Bit#(4) v); method Action io_vita_clk_p(Bit#(1) v); method Action io_vita_clk_n(Bit#(1) v); endinterface interface ImageonSerdesRequest; method Action set_decoder_control(Bit#(32) v); method Action set_iserdes_control(Bit#(32) v); method Action set_serdes_manual_tap(Bit#(10) v); method Action set_serdes_training(Bit#(10) v); method Action get_iserdes_control(); endinterface interface ImageonSerdesIndication; method Action iserdes_control_value(Bit#(32) v); method Action iserdes_dma(Bit#(32) v); endinterface interface SerdesData; method Reg#(Bit#(1)) reset(); method Vector#(5, Bit#(10)) raw_data(); method Bit#(64) capture(); method Action start_capture(); endinterface interface ISerdes; interface ImageonSerdesRequest request; interface ImageonSerdesPins pins; interface SerdesData data; endinterface ================================================ FILE: lib/bsv/Leds.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" `ifdef NUMBER_OF_LEDS typedef `NUMBER_OF_LEDS LedsWidth; `else `ifdef XILINX `ifdef Artix7 typedef 4 LedsWidth; `else `ifdef BOARD_zybo typedef 4 LedsWidth; `else `ifdef BOARD_zc706 typedef 4 LedsWidth; `else `ifdef BOARD_nfsume typedef 2 LedsWidth; `else typedef 8 LedsWidth; `endif `endif `endif `endif `elsif ALTERA typedef 4 LedsWidth; `elsif VSIM typedef 4 LedsWidth; `else typedef 8 LedsWidth; `endif `endif interface LEDS; method Bit#(LedsWidth) leds; endinterface ================================================ FILE: lib/bsv/PipeMul.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import FIFO::*; import SpecialFIFOs::*; import Complex::*; import FIFOF::*; import Vector::*; import StmtFSM::*; interface PipeMul#(numeric type stages, numeric type dsz, type marker); method Action put(UInt#(dsz) x, UInt#(dsz) y, marker m); method ActionValue#(Tuple2#(UInt#(dsz),marker)) get(); endinterface module mkPipeMul(PipeMul#(stages,dsz,marker)) provisos(Mul#(2,dsz,buff_width), Add#(a__,dsz,buff_width), Bits#(marker, b__)); Vector#(stages, Reg#(UInt#(buff_width))) mul_data <- replicateM(mkReg(0)); Vector#(TAdd#(stages,1),FIFO#(marker)) mul_ctrl <- replicateM(mkLFIFO); Reg#(UInt#(dsz)) a <- mkRegU; Reg#(UInt#(dsz)) b <- mkRegU; FIFO#(UInt#(dsz)) out <- mkLFIFO; FIFO#(Tuple3#(UInt#(dsz),UInt#(dsz),marker)) inf <- mkLFIFO; FIFO#(Tuple2#(UInt#(dsz),marker)) outf <- mkLFIFO; rule do_mul; UInt#(buff_width) bits = extend(b) * extend(a); mul_data[0] <= bits; for(Integer i = 1; i < valueOf(stages); i = i+1) mul_data[i] <= mul_data[i-1]; endrule for(Integer i = 0; i < valueOf(stages); i = i+1) rule do_ctrl; mul_ctrl[i+1].enq(mul_ctrl[i].first); mul_ctrl[i].deq; endrule rule final_xfer; mul_ctrl[valueOf(stages)].deq; UInt#(buff_width) bits = mul_data[valueOf(stages)-1]; UInt#(dsz) rv = truncate(bits); outf.enq(tuple2(rv,mul_ctrl[valueOf(stages)].first)); endrule rule start; inf.deq; a <= tpl_1(inf.first); b <= tpl_2(inf.first); mul_ctrl[0].enq(tpl_3(inf.first)); endrule method Action put(UInt#(dsz) x, UInt#(dsz) y, marker m); inf.enq(tuple3(x,y,m)); endmethod method ActionValue#(Tuple2#(UInt#(dsz),marker)) get(); outf.deq; return outf.first; endmethod endmodule interface PipeMul2#(numeric type stages, numeric type dsz, type marker); method Action put(UInt#(dsz) x, UInt#(dsz) y, marker m); method ActionValue#(Tuple2#(UInt#(TMul#(dsz,2)),marker)) get(); endinterface module mkPipeMul2(PipeMul2#(2,dsz,marker)) provisos(Add#(2,0,stages), Mul#(2,dsz,odsz), Add#(16,aszm16,dsz), Add#(16,c__,odsz), Add#(a__,dsz,odsz), Bits#(marker, b__)); Vector#(stages, Reg#(Tuple2#(UInt#(odsz),UInt#(odsz)))) mul_data <- replicateM(mkReg(unpack(0))); Vector#(TAdd#(stages,1),FIFO#(marker)) mul_ctrl <- replicateM(mkLFIFO); Reg#(UInt#(dsz)) a <- mkRegU; Reg#(UInt#(dsz)) b <- mkRegU; FIFO#(UInt#(dsz)) out <- mkLFIFO; FIFO#(Tuple3#(UInt#(dsz),UInt#(dsz),marker)) inf <- mkLFIFO; FIFO#(Tuple2#(UInt#(odsz),marker)) outf <- mkLFIFO; rule do_mul; UInt#(odsz) lsbits = extend(b) * extend(unpack(pack(a)[15:0])); UInt#(odsz) amsbits = unpack(pack(a)[valueOf(dsz)-1:16]); UInt#(odsz) msbits = extend(b) * amsbits; mul_data[0] <= tuple2(lsbits,msbits); endrule rule do_add; match { .lsbits, .msbits } = mul_data[0]; UInt#(odsz) prod = lsbits + (msbits << 16); mul_data[1] <= tuple2(0, prod); endrule for(Integer i = 0; i < valueOf(stages); i = i+1) rule do_ctrl; mul_ctrl[i+1].enq(mul_ctrl[i].first); mul_ctrl[i].deq; endrule rule final_xfer; mul_ctrl[valueOf(stages)].deq; match { .zero, .rv } = mul_data[valueOf(stages)-1]; outf.enq(tuple2(rv,mul_ctrl[valueOf(stages)].first)); endrule rule start; inf.deq; a <= tpl_1(inf.first); b <= tpl_2(inf.first); mul_ctrl[0].enq(tpl_3(inf.first)); endrule method Action put(UInt#(dsz) x, UInt#(dsz) y, marker m); inf.enq(tuple3(x,y,m)); endmethod method ActionValue#(Tuple2#(UInt#(odsz),marker)) get(); outf.deq; return outf.first; endmethod endmodule // module mkTestBench(); // PipeMul#(1,FixedPoint#(8,24)) multiplier <- mkPipeMul; // Stmt test = // seq // multiplier.put(fromReal(-1.0),fromReal(2.0)); // action // let rv <- multiplier.get; // $write("mul: "); // dispFP824(rv); // endaction // endseq; // mkAutoFSM(test); // endmodule ================================================ FILE: lib/bsv/SharedMemoryFifo.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import GetPut::*; import ClientServer::*; import Gearbox::*; import DefaultValue::*; import FIFO::*; import FIFOF::*; import MIMO::*; import Pipe::*; import Portal::*; import ConnectalMemTypes::*; import ConnectalMemory::*; interface SharedMemoryPipeOut#(numeric type dataBusWidth, numeric type pipeCount); interface SharedMemoryPortalConfig cfg; interface PipeOut#(Bit#(32)) data; endinterface interface SharedMemoryPipeIn#(numeric type dataBusWidth); interface SharedMemoryPortalConfig cfg; endinterface typedef enum { Idle, WrPtrRequested, // 1 RdPtrRequested, // 2 RequestMessage, // 3 MessageHeaderRequested, // 4 MessageRequested, // 5 Drain, UpdateRdPtr, UpdateWrPtr, UpdateWrPtr2, Waiting, SendHeader, SendMessage, SendPadding, Stop } SharedMemoryPortalState deriving (Bits,Eq); module mkSharedMemoryPipeOut#(Vector#(2, MemReadEngineServer#(64)) readEngine, Vector#(2, MemWriteEngineServer#(64)) writeEngine)(SharedMemoryPipeOut#(64,pipeCount)); // read the wrPtr and rdPtr pointers, if they are different, then read a request Reg#(Bit#(32)) limitReg <- mkReg(0); Reg#(Bit#(32)) wrPtrReg <- mkReg(0); Reg#(Bit#(32)) rdPtrReg <- mkReg(0); Reg#(Bit#(16)) countReg <- mkReg(0); Reg#(Bit#(16)) messageWordsReg <- mkReg(0); Reg#(Bit#(16)) methodIdReg <- mkReg(0); Reg#(SharedMemoryPortalState) state <- mkReg(Idle); Reg#(Bit#(32)) sglIdReg <- mkReg(0); Reg#(Bool) readyReg <- mkReg(False); MIMOConfiguration mimoConfig = defaultValue; MIMO#(2,1,2,Bit#(32)) readMimo <- mkMIMO(mimoConfig); FIFOF#(Bit#(32)) dataFifo <- mkFIFOF(); let verbose = False; rule updateReqRdWrPtr if (state == Idle && readyReg); if (verbose) $display("updateReqRdWrPtr"); readEngine[0].request.put( MemengineCmd {sglId: sglIdReg, base: 0, burstLen: 16, len: 16, tag: 0}); state <= WrPtrRequested; endrule rule receiveReqRdWrPtr if (state == WrPtrRequested || state == RdPtrRequested); let v <- toGet(readEngine[0].data).get(); let w0 = v.data[31:0]; let w1 = v.data[63:32]; let wrPtr = wrPtrReg; let rdPtr = rdPtrReg; let limit = limitReg; if (state == WrPtrRequested) begin limit = w0; limitReg <= w0; wrPtrReg <= w1; wrPtr = w1; state <= RdPtrRequested; end else begin if (rdPtrReg == 0) begin rdPtr = w0; rdPtrReg <= rdPtr; end if (rdPtr != wrPtrReg) state <= RequestMessage; else state <= Idle; end if (verbose) $display("receiveReqRdWrPtr state=%d w0=%x w1=%x wrPtr=%d rdPtr=%d limit=%d", state, w0, w1, wrPtr, rdPtr, limit); endrule rule requestMessage if (state == RequestMessage); Bit#(32) wordCount = wrPtrReg - rdPtrReg; if ((rdPtrReg & 1) == 1) begin $display("WARNING requestMessage: reqRdPtr=%d is odd.", rdPtrReg); end let rdPtr = rdPtrReg + wordCount; if (wrPtrReg < rdPtrReg) begin $display("requestMessage wrapped: wrPtr=%d rdPtr=%d", wrPtrReg, rdPtrReg); wordCount = limitReg - rdPtrReg; rdPtr = 4; end if (verbose) $display("requestMessage id=%d rdPtr=%d wrPtr=%d wordCount=%d", sglIdReg, rdPtrReg, wrPtrReg, wordCount); rdPtrReg <= rdPtr; countReg <= truncate(wordCount); readEngine[1].request.put( MemengineCmd {sglId: sglIdReg, base: extend(rdPtrReg << 2), burstLen: 16, len: wordCount << 2, tag: 0}); state <= MessageHeaderRequested; endrule let enqCount = 2; rule demuxwords if (readMimo.enqReadyN(enqCount)); let v <- toGet(readEngine[1].data).get(); Vector#(2,Bit#(32)) dvec = unpack(v.data); readMimo.enq(enqCount, dvec); endrule rule receiveMessageHeader if (state == MessageHeaderRequested); let vec <- toGet(toPipeOut(readMimo)).get(); let hdr = vec[0]; let methodId = hdr[31:16]; let messageWords = hdr[15:0]; if (verbose) $display("receiveMessageHeader hdr=%x methodId=%x messageWords=%d wordCount=%d", hdr, methodId, messageWords, countReg); methodIdReg <= methodId; countReg <= countReg - 1; messageWordsReg <= messageWords - 1; dataFifo.enq(hdr); if (hdr == 0) begin if (countReg == 1) state <= UpdateRdPtr; else state <= Drain; end else if (countReg == 1) state <= UpdateRdPtr; else if (messageWords == 1) state <= MessageHeaderRequested; else state <= MessageRequested; endrule rule drain if (state == Drain); let vec <- toGet(readMimo).get(); if (countReg == 1) state <= UpdateRdPtr; countReg <= countReg - 1; endrule rule receiveMessage if (state == MessageRequested); let vec <- toGet(toPipeOut(readMimo)).get(); let data = vec[0]; if (verbose) $display("receiveMessage data=%x messageWords=%d wordCount=%d", data, messageWordsReg, countReg); if (methodIdReg != 16'hFFFF) dataFifo.enq(data); messageWordsReg <= messageWordsReg - 1; countReg <= countReg - 1; if (countReg <= 1) state <= UpdateRdPtr; else if (messageWordsReg == 1) state <= MessageHeaderRequested; endrule rule updateRdPtr if (state == UpdateRdPtr); if (verbose) $display("updateRdPtr: rdPtr=%d", rdPtrReg); // update the rdPtr pointer writeEngine[0].request.put( MemengineCmd {sglId: sglIdReg, base: 8, len: 8, burstLen: 8, tag: 0}); writeEngine[0].data.enq(extend(rdPtrReg)); state <= Waiting; endrule rule waiting if (state == Waiting); let done <- writeEngine[0].done.get(); state <= Idle; endrule interface SharedMemoryPortalConfig cfg; method Action setSglId(Bit#(32) id); if (verbose) $display("setSglId id=%d", id); sglIdReg <= id; readyReg <= True; endmethod endinterface interface data = toPipeOut(dataFifo); endmodule module mkSharedMemoryPipeIn#(PipeOut#(Bit#(32)) pipe, Vector#(2,MemReadEngineServer#(64)) readEngine, Vector#(2, MemWriteEngineServer#(64)) writeEngine)(SharedMemoryPipeIn#(64)); let defaultClock <- exposeCurrentClock; let defaultReset <- exposeCurrentReset; // read the wrPtr and rdPtr pointers, if they are different, then read a request Reg#(Bit#(16)) limitReg <- mkReg(0); Reg#(Bit#(16)) wrPtrReg <- mkReg(0); Reg#(Bit#(16)) rdPtrReg <- mkReg(0); Reg#(Bit#(16)) messageWordsReg <- mkReg(0); Reg#(Bit#(16)) methodIdReg <- mkReg(0); Reg#(Bool) paddingReg <- mkReg(False); Reg#(SharedMemoryPortalState) state <- mkReg(Idle); Reg#(Bit#(32)) sglIdReg <- mkReg(0); Reg#(Bool) readyReg <- mkReg(False); function Bool pipeOutNotEmpty(PipeOut#(a) po); return po.notEmpty(); endfunction Gearbox#(1,2,Bit#(32)) gb <- mk1toNGearbox(defaultClock, defaultReset, defaultClock, defaultReset); let verbose = False; rule updateIndRdWrPtr if (state == Idle && readyReg); readEngine[0].request.put( MemengineCmd {sglId: sglIdReg, base: 0, burstLen: 16, len: 16, tag: 0}); state <= WrPtrRequested; endrule rule receiveIndRdWrPtr if (state == WrPtrRequested || state == RdPtrRequested); let md <- toGet(readEngine[0].data).get(); let data = md.data; let w0 = data[31:0]; let w1 = data[63:32]; let wrPtr = wrPtrReg; let rdPtr = rdPtrReg; if (state == WrPtrRequested) begin limitReg <= truncate(w0); wrPtrReg <= truncate(w1); wrPtr = truncate(w1); state <= RdPtrRequested; end else begin if (rdPtrReg == 0) begin rdPtr = truncate(w0); rdPtrReg <= rdPtr; end //if (rdPtr != wrPtrReg) state <= SendHeader; //else //state <= Idle; end if (verbose) $display("receiveIndRdWrPtr state=%d w0=%x w1=%x wrPtr=%d rdPtr=%d limit=%d", state, w0, w1, wrPtr, rdPtr, limitReg); endrule rule send64bits; let v = gb.first; gb.deq(); if (verbose) $display("send64bits v=%h", v); writeEngine[0].data.enq(pack(v)); endrule rule sendHeader if (state == SendHeader); Bit#(32) hdr <- toGet(pipe).get(); Bit#(16) totalWords = hdr[15:0]; let messageWords = totalWords-1; let padding = totalWords[0] == 1; let paddedWords = (padding) ? totalWords+1 : totalWords; let wrPtr = wrPtrReg + paddedWords; if (wrPtr > limitReg) begin $display("wrPtr wrapping"); wrPtr = 4; end $display("sendHeader hdr=%h messageWords=%d totalWords=%d paddingReg=%d wrPtrReg=%d wrPtr=%d", hdr, messageWords, totalWords, paddingReg, wrPtrReg, wrPtr); wrPtrReg <= wrPtr; messageWordsReg <= messageWords; paddingReg <= padding; gb.enq(vec(hdr)); writeEngine[0].request.put( MemengineCmd {sglId: sglIdReg, base: extend(wrPtrReg) << 2, burstLen: 8, len: extend(paddedWords) << 2, tag: 0}); state <= SendMessage; endrule rule sendMessage if (state == SendMessage); messageWordsReg <= messageWordsReg - 1; let v <- toGet(pipe).get(); gb.enq(vec(v)); $display("sendMessage v=%h messageWords=%d paddingReg=%d", v, messageWordsReg, paddingReg); if (messageWordsReg == 1) begin if (paddingReg) state <= SendPadding; else state <= UpdateWrPtr; end endrule rule sendPadding if (state == SendPadding); $display("sendPadding"); gb.enq(vec(32'hffff0001)); state <= UpdateWrPtr; endrule rule updateWrPtr if (state == UpdateWrPtr); $display("updateWrPtr limit=%d wrPtr=%d", limitReg, wrPtrReg); Bit#(64) metadata = extend(limitReg); gb.enq(vec(extend(limitReg))); writeEngine[0].request.put( MemengineCmd {sglId: sglIdReg, base: 0 << 2, burstLen: 8, len: 2 << 2, tag: 0}); state <= UpdateWrPtr2; endrule rule updateWrPtr2 if (state == UpdateWrPtr2); $display("updateWrPtr2"); gb.enq(vec(extend(wrPtrReg))); state <= SendHeader; endrule rule done; let done <- writeEngine[0].done.get(); endrule rule done2; let done <- writeEngine[1].done.get(); endrule interface SharedMemoryPortalConfig cfg; method Action setSglId(Bit#(32) id); sglIdReg <= id; readyReg <= True; endmethod endinterface endmodule ================================================ FILE: lib/bsv/SharedMemoryPortal.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BuildVector::*; import ClientServer::*; import Connectable::*; import DefaultValue::*; import FIFOF::*; import Gearbox::*; import GetPut::*; import MIMO::*; import Probe::*; import Vector::*; import Pipe::*; import Portal::*; import ConnectalMemTypes::*; import ConnectalMemory::*; import SharedMemoryFifo::*; module mkSharedMemoryRequestPortal#(PipePortal#(numRequests, numIndications, 32) portal, function Bit#(16) messageSize(Bit#(16) methodNumber), Vector#(2, MemReadEngineServer#(64)) readEngine, Vector#(2, MemWriteEngineServer#(64)) writeEngine)(SharedMemoryPortal#(64)); SharedMemoryPipeOut#(64,numRequests) pipeOut <- mkSharedMemoryPipeOut(readEngine, writeEngine); SerialPortalDemux#(numRequests) demux <- mkSerialPortalDemux(Method); mkConnection(pipeOut.data, demux.inputPipe); mapM_(uncurry(mkConnection), zip(demux.data, portal.requests)); interface SharedMemoryPortalConfig cfg = pipeOut.cfg; endmodule // adds a header word to each message out of an indication pipe module mkFramedMessagePipe#(Integer portalNumber, PipePortal#(numRequests,numIndications,32) pipePortal, function Bit#(16) messageSize(Bit#(16) methodNumber), Integer i)(PipeOut#(Bit#(32))); let pipeOut = pipePortal.indications[i]; Bit#(16) messageBits = messageSize(fromInteger(i)); Bit#(16) roundup = messageBits[4:0] == 0 ? 0 : 1; Bit#(16) numWords = (messageBits >> 5) + roundup; Bit#(16) totalWords = numWords + 1; Bit#(32) hdr = (fromInteger(portalNumber) << 24) | (fromInteger(i) << 16) | extend(numWords + 1); let sendHeader <- mkReg(True); Reg#(Bit#(16)) burstLenReg <- mkReg(0); PipeOut#(Bit#(32)) framedPipe = (interface PipeOut; method Bit#(32) first() if (pipeOut.notEmpty()); if (sendHeader) return hdr; else return pipeOut.first(); endmethod method Action deq() if (pipeOut.notEmpty()); if (sendHeader) begin sendHeader <= False; burstLenReg <= numWords; end else begin pipeOut.deq(); burstLenReg <= burstLenReg - 1; if (burstLenReg == 1) sendHeader <= True; end endmethod method Bool notEmpty(); return pipeOut.notEmpty(); endmethod endinterface); if (False) begin // optional pipeline stage FIFOF#(Bit#(32)) framedFifo <- mkFIFOF(); mkConnection(framedPipe, toPipeIn(framedFifo)); return toPipeOut(framedFifo); end else begin return framedPipe; end endmodule module mkSharedMemoryIndicationPortal#(PipePortal#(numRequests,numIndications,32) pipePortal, function Bit#(16) messageSize(Bit#(16) methodNumber), Vector#(2, MemReadEngineServer#(64)) readEngines, Vector#(2, MemWriteEngineServer#(64)) writeEngines) (SharedMemoryPortal#(64)); Vector#(numIndications, PipeOut#(Bit#(32))) indicationPipes <- genWithM(mkFramedMessagePipe(0,pipePortal,messageSize)); SerialPortalMux#(numIndications) serialPortalMux <- mkSerialPortalMux(); mkConnection(indicationPipes, serialPortalMux.data); SharedMemoryPipeIn#(64) pipeIn <- mkSharedMemoryPipeIn(serialPortalMux.outputPipe, readEngines, writeEngines); interface SharedMemoryPortalConfig cfg = pipeIn.cfg; endmodule interface SerialPortalDemux#(numeric type pipeCount); interface Vector#(pipeCount, PipeOut#(Bit#(32))) data; interface PipeIn#(Bit#(32)) inputPipe; endinterface interface SerialPortalMux#(numeric type pipeCount); interface Vector#(pipeCount, PipeIn#(Bit#(32))) data; interface PipeOut#(Bit#(32)) outputPipe; endinterface typedef enum { Idle, MessageHeader, MessageBody, Stop } SerialPortalState deriving (Bits,Eq); typedef enum { Portal, Method } SerialPortalDemuxLevel deriving (Bits,Eq); module mkSerialPortalDemux#(SerialPortalDemuxLevel portalDemux)(SerialPortalDemux#(pipeCount)); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Reg#(Bit#(16)) messageWordsReg <- mkReg(0); Reg#(Bit#(8)) selectorReg <- mkReg(0); Reg#(SerialPortalState) state <- mkReg(Idle); FIFOF#(Bit#(32)) inputFifo <- mkFIFOF(); Vector#(pipeCount, FIFOF#(Bit#(32))) dataFifo <- replicateM(mkFIFOF); let verbose = False; rule idle if (state == Idle); state <= MessageHeader; endrule rule receiveMessageHeader if (state == MessageHeader); let hdr <- toGet(inputFifo).get(); let selector = (portalDemux == Portal) ? hdr[31:24] : hdr[23:16]; let messageWords = hdr[15:0]; selectorReg <= selector; if (verbose) $display("receiveMessageHeader hdr=%x selector=%x messageWords=%d", hdr, selector, messageWords); if (portalDemux == Portal) // methodDemux need the header dataFifo[selector].enq(hdr); messageWordsReg <= messageWords - 1; if (messageWords == 1) state <= MessageHeader; else state <= MessageBody; endrule rule receiveMessage if (state == MessageBody); let data <- toGet(inputFifo).get(); if (verbose) $display("receiveMessage data=%x messageWords=%d", data, messageWordsReg); if (selectorReg != 8'hFF) dataFifo[selectorReg].enq(data); messageWordsReg <= messageWordsReg - 1; if (messageWordsReg == 1) state <= MessageHeader; endrule interface data = map(toPipeOut, dataFifo); interface inputPipe = toPipeIn(inputFifo); endmodule module mkSerialPortalMux(SerialPortalMux#(pipeCount)); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; Reg#(Bit#(16)) messageWordsReg <- mkReg(0); Reg#(Bit#(16)) readyChannelReg <- mkReg(0); Reg#(Bool) interruptStatusReg <- mkReg(False); Reg#(Bool) paddingReg <- mkReg(False); Reg#(SerialPortalState) state <- mkReg(Idle); Reg#(Bit#(32)) sglIdReg <- mkReg(0); function Bool fifoNotEmpty(FIFOF#(a) fifo); return fifo.notEmpty(); endfunction Vector#(pipeCount, FIFOF#(Bit#(32))) inputFifos <- replicateM(mkFIFOF()); Vector#(pipeCount, PipeOut#(Bit#(32))) pipes = map(toPipeOut, inputFifos); Vector#(pipeCount, Bool) readyBits = map(fifoNotEmpty, inputFifos); Bool interruptStatus = False; Bit#(16) readyChannel = -1; FIFOF#(Bit#(32)) outputFifo <- mkFIFOF(); let verbose = True; let stateProbe <- mkProbe(); let messageWordsProbe <- mkProbe(); let messageDataProbe <- mkProbe(); for (Integer i = valueOf(pipeCount) - 1; i >= 0; i = i - 1) begin if (readyBits[i]) begin interruptStatus = True; readyChannel = fromInteger(i); end end rule idle if (state == Idle); readyChannelReg <= readyChannel; interruptStatusReg <= interruptStatus; SerialPortalState nextState = Idle; if (interruptStatus) nextState = MessageHeader; state <= nextState; stateProbe <= nextState; endrule rule sendHeader if (state == MessageHeader && interruptStatusReg); Bit#(32) hdr <- toGet(inputFifos[readyChannelReg]).get(); Bit#(16) totalWords = hdr[15:0]; let messageWords = totalWords-1; messageWordsProbe <= messageWords; messageWordsReg <= messageWords; outputFifo.enq(hdr); state <= MessageBody; stateProbe <= MessageBody; messageDataProbe <= hdr; endrule rule sendMessage if (state == MessageBody); messageWordsReg <= messageWordsReg - 1; let v <- toGet(inputFifos[readyChannelReg]).get(); outputFifo.enq(v); $display("sendMessage v=%h messageWords=%d paddingReg=%d", v, messageWordsReg, paddingReg); if (messageWordsReg == 1) begin state <= Idle; stateProbe <= Idle; end messageDataProbe <= v; endrule interface data = map(toPipeIn, inputFifos); interface outputPipe = toPipeOut(outputFifo); endmodule ================================================ FILE: lib/bsv/SpiRoot.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import SpiTap::*; typedef struct { Bit#(32) a; Bit#(32) d; } SpiItem deriving(Bits); module mkSpiRoot#(SpiTap root)(FIFO#(SpiItem)); FIFO#(SpiItem) request <- mkSizedFIFO(8); FIFO#(SpiItem) response <- mkSizedFIFO(8); Reg#(Bit#(6)) countin <- mkReg(0); /* overflow at 63 -> 0 */ Reg#(Bit#(6)) countout <- mkReg(0); Reg#(Bit#(64)) shifter <- mkReg(0); Wire#(bit) framedrive <- mkDWire(0); /* implicit dependence on request fifo not empty */ rule send_item; if (countin < 32) begin root.in.data(request.first.a[countin&31]); framedrive <= 1; countin <= countin + 1; end else begin root.in.data(request.first.d[countin&31]); framedrive <= 1; countin <= countin + 1; end if (countin == 63) request.deq(); endrule rule genframe; root.in.frame(framedrive); endrule rule handleFrame; Bit#(64) tmp; if (root.out.frame() == 0) begin tmp = 0; countout <= 0; end else begin countout <= countout + 1; tmp = shifter; tmp = tmp >> 1; tmp[63] = root.out.data(); shifter <= tmp; end if (countout == 63) response.enq(SpiItem{a: tmp[31:0], d: tmp[63:32]}); endrule // method Action enq = request.enq; method Action enq(SpiItem x); request.enq(x); endmethod method Action deq(); response.deq(); endmethod method SpiItem first(); return response.first(); endmethod method Action clear(); request.clear(); response.clear(); countout <= 0; endmethod endmodule ================================================ FILE: lib/bsv/SpiTap.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; /* This is a simple serial bus * The frame bit indicates the valid period of a message * */ interface SpiTapIn; method Action frame(bit f); method Action data(bit d); endinterface interface SpiTapOut; method bit frame(); method bit data(); endinterface interface SpiTap; interface SpiTapIn in; interface SpiTapOut out; endinterface interface SpiReg#(type a); interface SpiTap tap; interface Reg#(a) r; endinterface instance Connectable#(SpiTapOut, SpiTapIn); module mkConnection#(SpiTapOut out, SpiTapIn in)(Empty); rule move_data; in.frame(out.frame()); in.data(out.data()); endrule endmodule endinstance module mkSpiReg#(Bit#(32) id)(SpiReg#(a)) provisos(Bits#(a,asize), Add#(a__, asize, 32)); Reg#(bit) frameinbit <- mkReg(0); Reg#(bit) datainbit <- mkReg(0); Wire#(bit) dataoutwire <- mkDWire(0); Reg#(Bit#(6)) count <- mkReg(0); Reg#(Bit#(32)) shifter <- mkReg(0); Reg#(Bool) addressmatch <- mkReg(False); Reg#(Bool) iswrite <- mkReg(False); Reg#(Bit#(asize)) data <- mkReg(0); rule handleFrame (frameinbit == 0); count <= 0; addressmatch <= False; endrule rule handleShift (frameinbit == 1); Bit#(32) tmp = shifter; tmp = tmp >> 1; tmp[31] = datainbit; shifter <= tmp; if (count == 31) begin iswrite <= tmp[0] == 1; addressmatch <= (id[31:1] == tmp[31:1]); end if ((count == 63) && addressmatch && iswrite) data <= truncate(tmp); if ((count[5] == 1) && addressmatch && (!iswrite)) begin if (valueof(asize) == 32) dataoutwire <= data[count & 31]; else begin if ((count & 31) < fromInteger(valueof(asize))) dataoutwire <= data[count & 31]; end end else dataoutwire <= datainbit; count <= count + 1; endrule interface SpiTap tap; interface SpiTapIn in; method Action frame(bit i ); frameinbit <= i ; endmethod method Action data( bit i ); datainbit <= i; endmethod endinterface interface SpiTapOut out; method bit frame(); return frameinbit; endmethod method bit data(); return dataoutwire; endmethod endinterface endinterface interface Reg r; method Action _write(a v); data <= pack(v); endmethod method a _read(); return(unpack(data)); endmethod endinterface endmodule ================================================ FILE: lib/bsv/Stack.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. /* * Implementation of: * simple stack */ import BRAM::*; /* the methods for load are split. loadstart puts a request to the BRAM * and loadfinish gets the result */ interface Stack#(numeric type stackSize, numeric type frameSize, type a); method Action store(Bit#(TLog#(frameSize)) offset, a v); method Action loadstart(Bit#(TLog#(frameSize)) offset); method ActionValue#(a) loadfinish(); method Action push(); method Action pop(); method Action reset(); endinterface module mkStack#(int stackSize, int frameSize)(Stack#(stackSize, frameSize, a)) provisos(Log#(stackSize, fpBits), Log#(frameSize, frameBits), Add#(fpBits, frameBits, addressBits), Literal#(a), Bits#(a, a__)); BRAM1Port#(Bit#(addressBits), a) stack <- mkBRAM1Server(defaultValue); Reg#(UInt#(fpBits)) fp <- mkReg(0); method Action reset(); fp <= 0; endmethod method Action push(); fp <= min(fp+1, maxBound); endmethod method Action pop(); fp <= max(fp-1, 0); endmethod method Action store(Bit#(TLog#(frameSize)) offset, a v); stack.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {pack(fp), offset}, datain: v}); endmethod /* read a value from current stack frame */ method Action loadstart(Bit#(TLog#(frameSize)) offset); stack.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {pack(fp), offset}, datain: 0}); endmethod /* maybe this should just expose a server interface? */ method ActionValue#(a) loadfinish(); let v = ?; v <- stack.portA.response.get(); return(v); endmethod endmodule ================================================ FILE: lib/bsv/StackReg.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. /* * Implementation of: * simple stack for a type * * Single cycle push and pop, provided that consecutive pops aren't * too far apart */ import BRAM::*; interface StackReg#(numeric type stackSize, type pctype, type argstype, type varstype); method Action doreturn(); method Action docall(pctype jumpto, pctype returnto, argstype args, varstype vars); method Action nextpc(pctype jumpto); method Bit#(16) setjmp(); method Action longjump(Bit#(16) where); interface Reg#(pctype) pc; interface Reg#(argstype) args; interface Reg#(varstype) vars; endinterface module mkStackReg#(int stackSize, pctype initialpc)(StackReg#(stackSize, pctype, argstype, varstype)) provisos(Log#(stackSize, addressBits), Bits#(pctype, a__), Bits#(argstype, b__), Bits#(varstype, c__)); BRAM1Port#(Bit#(addressBits), pctype) pcstack <- mkBRAM1Server(defaultValue); BRAM1Port#(Bit#(addressBits), argstype) argsstack <- mkBRAM1Server(defaultValue); BRAM1Port#(Bit#(addressBits), varstype) varsstack <- mkBRAM1Server(defaultValue); Reg#(pctype) pctop <- mkReg(initialpc); Reg#(pctype) pcnext <- mkReg(?); Reg#(argstype) argstop <- mkReg(?); Reg#(argstype) argsnext <- mkReg(?); Reg#(varstype) varstop <- mkReg(?); Reg#(varstype) varsnext <- mkReg(?); Reg#(Bit#(addressBits)) fp <- mkReg(0); PulseWire calling <- mkPulseWire(); PulseWire returning <- mkPulseWire(); Reg#(Bool) returningd1 <- mkReg(False); /* The "next" registers are there to compensate for the pipelined reads * of the BRAMs. * A return in isolation pops next to top, and then replaces the contents of * next the following cycle when the BRAM read completes. * In the event that there are multiple returns in consecutive cycles, the * first return values are fed from the next registers into top, and the * following values are bypassed from the BRAMs direct to TOP. * Once return cycles stop happening, the final pending BRAM read data is * loaded into next * * If a call happens in the cycle after a return, the BRAM read next and * the bram write next are both supressed, and next is pushed from top * * The wire calling says there is a call in the current cycle. The signal * returning says there is a return in the current cycle. The signal returningd1 * says there was a return in the previous cycle. */ /* Reg#(Bit#(8)) cyc <- mkReg(0); rule cc; cyc <= cyc + 1; endrule */ /* The pop rules fire exactly when returningd1 is true */ rule poppc; let v = ?; //$display("%d poppc (c %d)", cyc, calling); v <- pcstack.portA.response.get(); if (!calling) pcnext <= v; if (returning) pctop <= v; endrule rule popargs; let v = ?; v <- argsstack.portA.response.get(); if (!calling) argsnext <= v; if (returning) argstop <= v; endrule rule popvars; let v = ?; v <- varsstack.portA.response.get(); if (!calling) varsnext <= v; if (returning) varstop <= v; endrule (* fire_when_enabled, no_implicit_conditions *) rule returning_delay; returningd1 <= returning; endrule method Action docall(pctype jumpto, pctype returnto, argstype args, varstype vars); fp <= min(fp+1, maxBound); calling.send(); //$display("%d docall jumpto %d returnto %d (d1 %d)", cyc, jumpto, returnto, returningd1); if (! returningd1) begin pcstack.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: fp, datain: pcnext}); argsstack.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: fp, datain: argsnext}); varsstack.portA.request.put(BRAMRequest{write: True, responseOnWrite: False, address: fp, datain: varsnext}); end pcnext <= returnto; pctop <= jumpto; argsnext <= argstop; argstop <= args; varsnext <= vars; varstop <= vars; endmethod method Action doreturn(); fp <= max(fp-1, 0); returning.send(); pcstack.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fp-1, datain: ?}); argsstack.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fp-1, datain: ?}); varsstack.portA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: fp-1, datain: ?}); //$display("%d doreturn pctop getting %d", cyc, pcnext); if (!returningd1) begin pctop <= pcnext; argstop <= argsnext; varstop <= varsnext; end endmethod method Action nextpc(pctype jumpto); pctop <= jumpto; endmethod method Bit#(16) setjmp(); return 0; endmethod method Action longjump(Bit#(16) where); // set fp <= where and pop? something like that endmethod interface pc = pctop; interface args = argstop; interface vars = varstop; endmodule ================================================ FILE: lib/bsv/XADC.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface XADC; method Bit#(4) gpio; endinterface ================================================ FILE: lib/bsv/XilinxVirtex7PCIE.bsv ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2012 Bluespec, Inc. ALL RIGHTS RESERVED. // $Revision$ // $Date$ //////////////////////////////////////////////////////////////////////////////// // Filename : XilinxVirtex7PCIE.bsv // Description : //////////////////////////////////////////////////////////////////////////////// package XilinxVirtex7PCIE; // Notes : // PART 1 of this file is pre-2014-10, for PCIE Gen 1&2, for VC707 etc. // PART 2 of this file is 2014-11, for PCIE3 (Gen 3), for VC709 etc. // (search for "PART 1: PCIE" and "PART 2: PCIE3" //////////////////////////////////////////////////////////////////////////////// /// Imports //////////////////////////////////////////////////////////////////////////////// import Clocks ::*; import Vector ::*; import Connectable ::*; import GetPut ::*; import Reserved ::*; import TieOff ::*; import DefaultValue ::*; import DReg ::*; import Gearbox ::*; import FIFO ::*; import FIFOF ::*; import SpecialFIFOs ::*; import BRAMFIFO ::*; import ClientServer ::*; import BUtils ::*; import XilinxCells ::*; import XilinxClocks ::*; import PCIE ::*; //////////////////////////////////////////////////////////////////////////////// /// PART 1: PCIE (Gen 1 and 2, for VC707 etc.) /// This code existed in 2014-10 //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// Types //////////////////////////////////////////////////////////////////////////////// typedef struct { Bit#(22) user; Bool last; Bit#(8) keep; Bit#(64) data; } AxiRx deriving (Bits, Eq); typedef struct { Bool last; Bit#(8) keep; Bit#(64) data; } AxiTx deriving (Bits, Eq); //////////////////////////////////////////////////////////////////////////////// /// Interfaces PCIE: raw interface from wrapped verilog endpoint //////////////////////////////////////////////////////////////////////////////// (* always_ready, always_enabled *) interface PCIE_V7#(numeric type lanes); interface PCIE_EXP#(lanes) pcie; interface PCIE_TRN_V7 trn; interface PCIE_AXI_TX_V7 axi_tx; interface PCIE_AXI_RX_V7 axi_rx; interface PCIE_PL_V7 pl; interface PCIE_CFG_V7 cfg; interface PCIE_INT_V7 cfg_interrupt; interface PCIE_ERR_V7 cfg_err; endinterface (* always_ready, always_enabled *) interface PCIE_TRN_V7; interface Clock clk; interface Reset reset; method Bool lnk_up; method Bit#(8) fc_ph; method Bit#(12) fc_pd; method Bit#(8) fc_nph; method Bit#(12) fc_npd; method Bit#(8) fc_cplh; method Bit#(12) fc_cpld; method Action fc_sel(FlowControlInfoSelect i); endinterface (* always_ready, always_enabled *) interface PCIE_AXI_TX_V7; method Action tlast(Bool i); method Action tdata(Bit#(64) i); method Action tkeep(Bit#(8) i); method Action tvalid(Bool i); method Bool tready(); method Action tuser(Bit#(4) i); method Bit#(6) tbuf_av(); method Bool terr_drop(); method Bool tcfg_req(); method Action tcfg_gnt(Bool i); endinterface (* always_ready, always_enabled *) interface PCIE_AXI_RX_V7; method Bool rlast(); method Bit#(64) rdata(); method Bit#(8) rkeep(); method Bit#(22) ruser(); method Bool rvalid(); method Action rready(Bool i); method Action rnp_ok(Bool i); method Action rnp_req(Bool i); endinterface (* always_ready, always_enabled *) interface PCIE_PL_V7; method Bit#(3) initial_link_width; method Bool phy_link_up; method Bit#(2) lane_reversal_mode; method Bit#(1) link_gen2_capable; method Bit#(1) link_partner_gen2_supported; method Bit#(1) link_upcfg_capable; method Bit#(1) sel_link_rate; method Bit#(2) sel_link_width; method Bit#(6) ltssm_state; method Bit#(2) rx_pm_state; method Bit#(3) tx_pm_state; method Action directed_link_auton(Bit#(1) i); method Action directed_link_change(Bit#(2) i); method Action directed_link_speed(Bit#(1) i); method Action directed_link_width(Bit#(2) i); method Bit#(1) directed_change_done; method Action upstream_prefer_deemph(Bit#(1) i); method Bit#(1) received_hot_rst; endinterface (* always_ready, always_enabled *) interface PCIE_CFG_V7; method Bit#(32) dout; method Bit#(1) rd_wr_done; method Action di(Bit#(32) i); method Action dwaddr(Bit#(10) i); method Action byte_en(Bit#(4) i); method Action wr_en(Bit#(1) i); method Action rd_en(Bit#(1) i); method Action wr_readonly(Bit#(1) i); method Bit#(8) bus_number; method Bit#(5) device_number; method Bit#(3) function_number; method Bit#(16) status; method Bit#(16) command; method Bit#(16) dstatus; method Bit#(16) dcommand; method Bit#(16) dcommand2; method Bit#(16) lstatus; method Bit#(16) lcommand; method Bit#(1) aer_ecrc_gen_en; method Bit#(1) aer_ecrc_check_en; method Bit#(3) pcie_link_state; method Action trn_pending(Bit#(1) i); method Action dsn(Bit#(64) i); method Bit#(1) pmcsr_pme_en; method Bit#(1) pmcsr_pme_status; method Bit#(2) pmcsr_powerstate; method Action pm_halt_aspm_l0s(Bit#(1) i); method Action pm_halt_aspm_l1(Bit#(1) i); method Action pm_force_state(Bit#(2) i); method Action pm_force_state_en(Bit#(1) i); method Bit#(1) received_func_lvl_rst; method Bit#(7) vc_tcvc_map; method Bit#(1) to_turnoff; method Action turnoff_ok(Bit#(1) i); method Action pm_wake(Bit#(1) i); endinterface (* always_ready, always_enabled *) interface PCIE_INT_V7; method Action req(Bit#(1) i); method Bit#(1) rdy; method Action assrt(Bit#(1) i); method Action di(Bit#(8) i); method Bit#(8) dout; method Bit#(3) mmenable; method Bit#(1) msienable; method Bit#(1) msixenable; method Bit#(1) msixfm; method Action pciecap_msgnum(Bit#(5) i); method Action stat(Bit#(1) i); endinterface (* always_ready, always_enabled *) interface PCIE_ERR_V7; method Action ecrc(Bit#(1) i); method Action ur(Bit#(1) i); method Action cpl_timeout(Bit#(1) i); method Action cpl_unexpect(Bit#(1) i); method Action cpl_abort(Bit#(1) i); method Action posted(Bit#(1) i); method Action cor(Bit#(1) i); method Action atomic_egress_blocked(Bit#(1) i); method Action internal_cor(Bit#(1) i); method Action internal_uncor(Bit#(1) i); method Action malformed(Bit#(1) i); method Action mc_blocked(Bit#(1) i); method Action poisoned(Bit#(1) i); method Action no_recovery(Bit#(1) i); method Action tlp_cpl_header(Bit#(48) i); method Bit#(1) cpl_rdy; method Action locked(Bit#(1) i); method Action aer_headerlog(Bit#(128) i); method Bit#(1) aer_headerlog_set; method Action aer_interrupt_msgnum(Bit#(5) i); method Action acs(Bit#(1) i); endinterface //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation: original PCIE (pre-PCIE3) /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// import "BVI" xilinx_v7_pcie_wrapper = module vMkVirtex7PCIExpress#(PCIEParams params)(PCIE_V7#(lanes)) provisos( Add#(1, z, lanes)); let sys_reset <- invertCurrentReset; default_clock clk(sys_clk); // 100 MHz refclk default_reset rstn(sys_reset) = sys_reset; parameter PL_FAST_TRAIN = (params.fast_train_sim_only) ? "TRUE" : "FALSE"; parameter PCIE_EXT_CLK = "TRUE"; interface PCIE_EXP pcie; method rxp(pci_exp_rxp) enable((*inhigh*)en0) reset_by(no_reset); method rxn(pci_exp_rxn) enable((*inhigh*)en1) reset_by(no_reset); method pci_exp_txp txp reset_by(no_reset); method pci_exp_txn txn reset_by(no_reset); endinterface interface PCIE_TRN_V7 trn; output_clock clk(user_clk_out); output_reset reset(user_reset_out); method user_lnk_up lnk_up clocked_by(no_clock) reset_by(no_reset); /* semi-static */ method fc_ph fc_ph clocked_by(trn_clk) reset_by(no_reset); method fc_pd fc_pd clocked_by(trn_clk) reset_by(no_reset); method fc_nph fc_nph clocked_by(trn_clk) reset_by(no_reset); method fc_npd fc_npd clocked_by(trn_clk) reset_by(no_reset); method fc_cplh fc_cplh clocked_by(trn_clk) reset_by(no_reset); method fc_cpld fc_cpld clocked_by(trn_clk) reset_by(no_reset); method fc_sel(fc_sel) enable((*inhigh*)en01) clocked_by(trn_clk) reset_by(no_reset); endinterface interface PCIE_AXI_TX_V7 axi_tx; method tlast(s_axis_tx_tlast) enable((*inhigh*)en02) clocked_by(trn_clk) reset_by(no_reset); method tdata(s_axis_tx_tdata) enable((*inhigh*)en03) clocked_by(trn_clk) reset_by(no_reset); method tkeep(s_axis_tx_tkeep) enable((*inhigh*)en04) clocked_by(trn_clk) reset_by(no_reset); method tvalid(s_axis_tx_tvalid) enable((*inhigh*)en05) clocked_by(trn_clk) reset_by(no_reset); method s_axis_tx_tready tready clocked_by(trn_clk) reset_by(no_reset); method tuser(s_axis_tx_tuser) enable((*inhigh*)en06) clocked_by(trn_clk) reset_by(no_reset); method tx_buf_av tbuf_av clocked_by(trn_clk) reset_by(no_reset); method tx_err_drop terr_drop clocked_by(trn_clk) reset_by(no_reset); method tx_cfg_req tcfg_req clocked_by(trn_clk) reset_by(no_reset); method tcfg_gnt(tx_cfg_gnt) enable((*inhigh*)en07) clocked_by(trn_clk) reset_by(no_reset); endinterface interface PCIE_AXI_RX_V7 axi_rx; method m_axis_rx_tlast rlast clocked_by(trn_clk) reset_by(no_reset); method m_axis_rx_tdata rdata clocked_by(trn_clk) reset_by(no_reset); method m_axis_rx_tkeep rkeep clocked_by(trn_clk) reset_by(no_reset); method m_axis_rx_tuser ruser clocked_by(trn_clk) reset_by(no_reset); method m_axis_rx_tvalid rvalid clocked_by(trn_clk) reset_by(no_reset); method rready(m_axis_rx_tready) enable((*inhigh*)en08) clocked_by(trn_clk) reset_by(no_reset); method rnp_ok(rx_np_ok) enable((*inhigh*)en09) clocked_by(trn_clk) reset_by(no_reset); method rnp_req(rx_np_req) enable((*inhigh*)en10) clocked_by(trn_clk) reset_by(no_reset); endinterface interface PCIE_PL_V7 pl; method pl_initial_link_width initial_link_width clocked_by(trn_clk) reset_by(no_reset); method pl_phy_lnk_up phy_link_up clocked_by(trn_clk) reset_by(no_reset); method pl_lane_reversal_mode lane_reversal_mode clocked_by(trn_clk) reset_by(no_reset); method pl_link_gen2_cap link_gen2_capable clocked_by(trn_clk) reset_by(no_reset); method pl_link_partner_gen2_supported link_partner_gen2_supported clocked_by(trn_clk) reset_by(no_reset); method pl_link_upcfg_cap link_upcfg_capable clocked_by(trn_clk) reset_by(no_reset); method pl_sel_lnk_rate sel_link_rate clocked_by(trn_clk) reset_by(no_reset); method pl_sel_lnk_width sel_link_width clocked_by(trn_clk) reset_by(no_reset); method pl_ltssm_state ltssm_state clocked_by(trn_clk) reset_by(no_reset); method pl_rx_pm_state rx_pm_state clocked_by(trn_clk) reset_by(no_reset); method pl_tx_pm_state tx_pm_state clocked_by(trn_clk) reset_by(no_reset); method directed_link_auton(pl_directed_link_auton) enable((*inhigh*)en13) clocked_by(trn_clk) reset_by(no_reset); method directed_link_change(pl_directed_link_change) enable((*inhigh*)en14) clocked_by(trn_clk) reset_by(no_reset); method directed_link_speed(pl_directed_link_speed) enable((*inhigh*)en15) clocked_by(trn_clk) reset_by(no_reset); method directed_link_width(pl_directed_link_width) enable((*inhigh*)en16) clocked_by(trn_clk) reset_by(no_reset); method pl_directed_change_done directed_change_done clocked_by(trn_clk) reset_by(no_reset); method upstream_prefer_deemph(pl_upstream_prefer_deemph) enable((*inhigh*)en17) clocked_by(trn_clk) reset_by(no_reset); method pl_received_hot_rst received_hot_rst clocked_by(trn_clk) reset_by(no_reset); endinterface interface PCIE_CFG_V7 cfg; method cfg_mgmt_do dout clocked_by(trn_clk) reset_by(no_reset); method cfg_mgmt_rd_wr_done rd_wr_done clocked_by(trn_clk) reset_by(no_reset); method di(cfg_mgmt_di) enable((*inhigh*)en18) clocked_by(trn_clk) reset_by(no_reset); method dwaddr(cfg_mgmt_dwaddr) enable((*inhigh*)en19) clocked_by(trn_clk) reset_by(no_reset); method byte_en(cfg_mgmt_byte_en) enable((*inhigh*)en20) clocked_by(trn_clk) reset_by(no_reset); method wr_en(cfg_mgmt_wr_en) enable((*inhigh*)en21) clocked_by(trn_clk) reset_by(no_reset); method rd_en(cfg_mgmt_rd_en) enable((*inhigh*)en22) clocked_by(trn_clk) reset_by(no_reset); method wr_readonly(cfg_mgmt_wr_readonly) enable((*inhigh*)en23) clocked_by(trn_clk) reset_by(no_reset); method cfg_bus_number bus_number clocked_by(no_clock) reset_by(no_reset); method cfg_device_number device_number clocked_by(no_clock) reset_by(no_reset); method cfg_function_number function_number clocked_by(no_clock) reset_by(no_reset); method cfg_status status clocked_by(trn_clk) reset_by(no_reset); method cfg_command command clocked_by(trn_clk) reset_by(no_reset); method cfg_dstatus dstatus clocked_by(trn_clk) reset_by(no_reset); method cfg_dcommand dcommand clocked_by(trn_clk) reset_by(no_reset); method cfg_dcommand2 dcommand2 clocked_by(trn_clk) reset_by(no_reset); method cfg_lstatus lstatus clocked_by(trn_clk) reset_by(no_reset); method cfg_lcommand lcommand clocked_by(trn_clk) reset_by(no_reset); method cfg_aer_ecrc_gen_en aer_ecrc_gen_en clocked_by(trn_clk) reset_by(no_reset); method cfg_aer_ecrc_check_en aer_ecrc_check_en clocked_by(trn_clk) reset_by(no_reset); method cfg_pcie_link_state pcie_link_state clocked_by(trn_clk) reset_by(no_reset); method trn_pending(cfg_trn_pending) enable((*inhigh*)en24) clocked_by(trn_clk) reset_by(no_reset); method dsn(cfg_dsn) enable((*inhigh*)en25) clocked_by(trn_clk) reset_by(no_reset); method cfg_pmcsr_pme_en pmcsr_pme_en clocked_by(trn_clk) reset_by(no_reset); method cfg_pmcsr_pme_status pmcsr_pme_status clocked_by(trn_clk) reset_by(no_reset); method cfg_pmcsr_powerstate pmcsr_powerstate clocked_by(trn_clk) reset_by(no_reset); method pm_halt_aspm_l0s(cfg_pm_halt_aspm_l0s) enable((*inhigh*)en26) clocked_by(trn_clk) reset_by(no_reset); method pm_halt_aspm_l1(cfg_pm_halt_aspm_l1) enable((*inhigh*)en27) clocked_by(trn_clk) reset_by(no_reset); method pm_force_state(cfg_pm_force_state) enable((*inhigh*)en28) clocked_by(trn_clk) reset_by(no_reset); method pm_force_state_en(cfg_pm_force_state_en) enable((*inhigh*)en29) clocked_by(trn_clk) reset_by(no_reset); method cfg_received_func_lvl_rst received_func_lvl_rst clocked_by(trn_clk) reset_by(no_reset); method cfg_vc_tcvc_map vc_tcvc_map clocked_by(trn_clk) reset_by(no_reset); method cfg_to_turnoff to_turnoff clocked_by(trn_clk) reset_by(no_reset); method turnoff_ok(cfg_turnoff_ok) enable((*inhigh*)en30) clocked_by(trn_clk) reset_by(no_reset); method pm_wake(cfg_pm_wake) enable((*inhigh*)en31) clocked_by(trn_clk) reset_by(no_reset); endinterface interface PCIE_INT_V7 cfg_interrupt; method req(cfg_interrupt) enable((*inhigh*)en32) clocked_by(trn_clk) reset_by(no_reset); method cfg_interrupt_rdy rdy clocked_by(trn_clk) reset_by(no_reset); method assrt(cfg_interrupt_assert) enable((*inhigh*)en33) clocked_by(trn_clk) reset_by(no_reset); method di(cfg_interrupt_di) enable((*inhigh*)en34) clocked_by(trn_clk) reset_by(no_reset); method cfg_interrupt_do dout clocked_by(trn_clk) reset_by(no_reset); method cfg_interrupt_mmenable mmenable clocked_by(trn_clk) reset_by(no_reset); method cfg_interrupt_msienable msienable clocked_by(trn_clk) reset_by(no_reset); method cfg_interrupt_msixenable msixenable clocked_by(trn_clk) reset_by(no_reset); method cfg_interrupt_msixfm msixfm clocked_by(trn_clk) reset_by(no_reset); method pciecap_msgnum(cfg_pciecap_interrupt_msgnum) enable((*inhigh*)en35) clocked_by(trn_clk) reset_by(no_reset); method stat(cfg_interrupt_stat) enable((*inhigh*)en36) clocked_by(trn_clk) reset_by(no_reset); endinterface interface PCIE_ERR_V7 cfg_err; method ecrc(cfg_err_ecrc) enable((*inhigh*)en37) clocked_by(trn_clk) reset_by(no_reset); method ur(cfg_err_ur) enable((*inhigh*)en38) clocked_by(trn_clk) reset_by(no_reset); method cpl_timeout(cfg_err_cpl_timeout) enable((*inhigh*)en39) clocked_by(trn_clk) reset_by(no_reset); method cpl_unexpect(cfg_err_cpl_unexpect) enable((*inhigh*)en40) clocked_by(trn_clk) reset_by(no_reset); method cpl_abort(cfg_err_cpl_abort) enable((*inhigh*)en41) clocked_by(trn_clk) reset_by(no_reset); method posted(cfg_err_posted) enable((*inhigh*)en42) clocked_by(trn_clk) reset_by(no_reset); method cor(cfg_err_cor) enable((*inhigh*)en43) clocked_by(trn_clk) reset_by(no_reset); method atomic_egress_blocked(cfg_err_atomic_egress_blocked) enable((*inhigh*)en44) clocked_by(trn_clk) reset_by(no_reset); method internal_cor(cfg_err_internal_cor) enable((*inhigh*)en45) clocked_by(trn_clk) reset_by(no_reset); method internal_uncor(cfg_err_internal_uncor) enable((*inhigh*)en46) clocked_by(trn_clk) reset_by(no_reset); method malformed(cfg_err_malformed) enable((*inhigh*)en47) clocked_by(trn_clk) reset_by(no_reset); method mc_blocked(cfg_err_mc_blocked) enable((*inhigh*)en48) clocked_by(trn_clk) reset_by(no_reset); method poisoned(cfg_err_poisoned) enable((*inhigh*)en49) clocked_by(trn_clk) reset_by(no_reset); method no_recovery(cfg_err_norecovery) enable((*inhigh*)en50) clocked_by(trn_clk) reset_by(no_reset); method tlp_cpl_header(cfg_err_tlp_cpl_header) enable((*inhigh*)en51) clocked_by(trn_clk) reset_by(no_reset); method cfg_err_cpl_rdy cpl_rdy clocked_by(trn_clk) reset_by(no_reset); method locked(cfg_err_locked) enable((*inhigh*)en52) clocked_by(trn_clk) reset_by(no_reset); method aer_headerlog(cfg_err_aer_headerlog) enable((*inhigh*)en53) clocked_by(trn_clk) reset_by(no_reset); method cfg_err_aer_headerlog_set aer_headerlog_set clocked_by(trn_clk) reset_by(no_reset); method aer_interrupt_msgnum(cfg_aer_interrupt_msgnum) enable((*inhigh*)en54) clocked_by(trn_clk) reset_by(no_reset); method acs(cfg_err_acs) enable((*inhigh*)en55) clocked_by(trn_clk) reset_by(no_reset); endinterface schedule (trn_lnk_up, trn_fc_ph, trn_fc_pd, trn_fc_nph, trn_fc_npd, trn_fc_cplh, trn_fc_cpld, trn_fc_sel, axi_tx_tlast, axi_tx_tdata, axi_tx_tkeep, axi_tx_tvalid, axi_tx_tready, axi_tx_tuser, axi_tx_tbuf_av, axi_tx_terr_drop, axi_tx_tcfg_req, axi_tx_tcfg_gnt, axi_rx_rlast, axi_rx_rdata, axi_rx_rkeep, axi_rx_ruser, axi_rx_rvalid, axi_rx_rready, axi_rx_rnp_ok, axi_rx_rnp_req, pl_initial_link_width, pl_phy_link_up, pl_lane_reversal_mode, pl_link_gen2_capable, pl_link_partner_gen2_supported, pl_link_upcfg_capable, pl_sel_link_rate, pl_sel_link_width, pl_ltssm_state, pl_rx_pm_state, pl_tx_pm_state, pl_directed_link_auton, pl_directed_link_change, pl_directed_link_speed, pl_directed_link_width, pl_directed_change_done, pl_upstream_prefer_deemph, pl_received_hot_rst, cfg_dout, cfg_rd_wr_done, cfg_di, cfg_dwaddr, cfg_byte_en, cfg_wr_en, cfg_rd_en, cfg_wr_readonly, cfg_bus_number, cfg_device_number, cfg_function_number, cfg_status, cfg_command, cfg_dstatus, cfg_dcommand, cfg_dcommand2, cfg_lstatus, cfg_lcommand, cfg_aer_ecrc_gen_en, cfg_aer_ecrc_check_en, cfg_pcie_link_state, cfg_trn_pending, cfg_dsn, cfg_pmcsr_pme_en, cfg_pmcsr_pme_status, cfg_pmcsr_powerstate, cfg_pm_halt_aspm_l0s, cfg_pm_halt_aspm_l1, cfg_pm_force_state, cfg_pm_force_state_en, cfg_received_func_lvl_rst, cfg_vc_tcvc_map, cfg_to_turnoff, cfg_turnoff_ok, cfg_pm_wake, cfg_interrupt_req, cfg_interrupt_rdy, cfg_interrupt_assrt, cfg_interrupt_di, cfg_interrupt_dout, cfg_interrupt_mmenable, cfg_interrupt_msienable, cfg_interrupt_msixenable, cfg_interrupt_msixfm, cfg_interrupt_pciecap_msgnum, cfg_interrupt_stat, cfg_err_ecrc, cfg_err_ur, cfg_err_cpl_timeout, cfg_err_cpl_unexpect, cfg_err_cpl_abort, cfg_err_posted, cfg_err_cor, cfg_err_atomic_egress_blocked, cfg_err_internal_cor, cfg_err_internal_uncor, cfg_err_malformed, cfg_err_mc_blocked, cfg_err_poisoned, cfg_err_no_recovery, cfg_err_tlp_cpl_header, cfg_err_cpl_rdy, cfg_err_locked, cfg_err_aer_headerlog, cfg_err_aer_headerlog_set, cfg_err_aer_interrupt_msgnum, cfg_err_acs, pcie_txp, pcie_txn, pcie_rxp, pcie_rxn ) CF (trn_lnk_up, trn_fc_ph, trn_fc_pd, trn_fc_nph, trn_fc_npd, trn_fc_cplh, trn_fc_cpld, trn_fc_sel, axi_tx_tlast, axi_tx_tdata, axi_tx_tkeep, axi_tx_tvalid, axi_tx_tready, axi_tx_tuser, axi_tx_tbuf_av, axi_tx_terr_drop, axi_tx_tcfg_req, axi_tx_tcfg_gnt, axi_rx_rlast, axi_rx_rdata, axi_rx_rkeep, axi_rx_ruser, axi_rx_rvalid, axi_rx_rready, axi_rx_rnp_ok, axi_rx_rnp_req, pl_initial_link_width, pl_phy_link_up, pl_lane_reversal_mode, pl_link_gen2_capable, pl_link_partner_gen2_supported, pl_link_upcfg_capable, pl_sel_link_rate, pl_sel_link_width, pl_ltssm_state, pl_rx_pm_state, pl_tx_pm_state, pl_directed_link_auton, pl_directed_link_change, pl_directed_link_speed, pl_directed_link_width, pl_directed_change_done, pl_upstream_prefer_deemph, pl_received_hot_rst, cfg_dout, cfg_rd_wr_done, cfg_di, cfg_dwaddr, cfg_byte_en, cfg_wr_en, cfg_rd_en, cfg_wr_readonly, cfg_bus_number, cfg_device_number, cfg_function_number, cfg_status, cfg_command, cfg_dstatus, cfg_dcommand, cfg_dcommand2, cfg_lstatus, cfg_lcommand, cfg_aer_ecrc_gen_en, cfg_aer_ecrc_check_en, cfg_pcie_link_state, cfg_trn_pending, cfg_dsn, cfg_pmcsr_pme_en, cfg_pmcsr_pme_status, cfg_pmcsr_powerstate, cfg_pm_halt_aspm_l0s, cfg_pm_halt_aspm_l1, cfg_pm_force_state, cfg_pm_force_state_en, cfg_received_func_lvl_rst, cfg_vc_tcvc_map, cfg_to_turnoff, cfg_turnoff_ok, cfg_pm_wake, cfg_interrupt_req, cfg_interrupt_rdy, cfg_interrupt_assrt, cfg_interrupt_di, cfg_interrupt_dout, cfg_interrupt_mmenable, cfg_interrupt_msienable, cfg_interrupt_msixenable, cfg_interrupt_msixfm, cfg_interrupt_pciecap_msgnum, cfg_interrupt_stat, cfg_err_ecrc, cfg_err_ur, cfg_err_cpl_timeout, cfg_err_cpl_unexpect, cfg_err_cpl_abort, cfg_err_posted, cfg_err_cor, cfg_err_atomic_egress_blocked, cfg_err_internal_cor, cfg_err_internal_uncor, cfg_err_malformed, cfg_err_mc_blocked, cfg_err_poisoned, cfg_err_no_recovery, cfg_err_tlp_cpl_header, cfg_err_cpl_rdy, cfg_err_locked, cfg_err_aer_headerlog, cfg_err_aer_headerlog_set, cfg_err_aer_interrupt_msgnum, cfg_err_acs, pcie_txp, pcie_txn, pcie_rxp, pcie_rxn ); endmodule: vMkVirtex7PCIExpress //////////////////////////////////////////////////////////////////////////////// /// Interfaces original PCIE (pre-PCIE3) TRN for bridge //////////////////////////////////////////////////////////////////////////////// interface PCIE_TRN_COMMON_V7; interface Clock clk; interface Clock clk2; interface Reset reset_n; method Bool link_up; endinterface interface PCIE_TRN_XMIT_V7; method Action xmit(TLPData#(8) data); method Action discontinue(Bool i); method Action ecrc_generate(Bool i); method Action error_forward(Bool i); method Action cut_through_mode(Bool i); method Bool dropped; method Bit#(6) buffers_available; method Bool configuration_completion_request; method Action configuration_completion_grant(Bool i); endinterface interface PCIE_TRN_RECV_V7; method ActionValue#(Tuple3#(Bool, Bool, TLPData#(8))) recv(); method Action non_posted_ok(Bool i); method Action non_posted_req(Bool i); endinterface interface PCIExpressV7#(numeric type lanes); interface PCIE_EXP#(lanes) pcie; interface PCIE_TRN_COMMON_V7 trn; interface PCIE_TRN_XMIT_V7 trn_tx; interface PCIE_TRN_RECV_V7 trn_rx; interface PCIE_CFG_V7 cfg; interface PCIE_INT_V7 cfg_interrupt; interface PCIE_ERR_V7 cfg_err; interface PCIE_PL_V7 pl; interface XilinxClkServer clks; interface Clock scemi_clk; endinterface interface PCIExpressNoClkV7#(numeric type lanes); interface PCIE_EXP#(lanes) pcie; interface PCIE_TRN_COMMON_V7 trn; interface PCIE_TRN_XMIT_V7 trn_tx; interface PCIE_TRN_RECV_V7 trn_rx; interface PCIE_CFG_V7 cfg; interface PCIE_INT_V7 cfg_interrupt; interface PCIE_ERR_V7 cfg_err; interface PCIE_PL_V7 pl; endinterface //////////////////////////////////////////////////////////////////////////////// /// For original PCIE (pre-PCIE3) /// Typeclass to select vMkVirtex7PCIExpress() for 1, 4, 8 lanes //////////////////////////////////////////////////////////////////////////////// typeclass SelectVirtex7PCIE#(numeric type lanes); module selectVirtex7PCIE(PCIEParams params, PCIE_V7#(lanes) ifc); endtypeclass instance SelectVirtex7PCIE#(8); module selectVirtex7PCIE(PCIEParams params, PCIE_V7#(8) ifc); let _ifc <- vMkVirtex7PCIExpress(params); return _ifc; endmodule endinstance instance SelectVirtex7PCIE#(4); module selectVirtex7PCIE(PCIEParams params, PCIE_V7#(4) ifc); let _ifc <- vMkVirtex7PCIExpress(params); return _ifc; endmodule endinstance instance SelectVirtex7PCIE#(1); module selectVirtex7PCIE(PCIEParams params, PCIE_V7#(1) ifc); let _ifc <- vMkVirtex7PCIExpress(params); return _ifc; endmodule endinstance //////////////////////////////////////////////////////////////// // The BSV PCIE endpoint (original pre-PCIE3 version) //////////////////////////////////////////////////////////////// module mkPCIExpressEndpointV7#(PCIEParams params)(PCIExpressV7#(lanes)) provisos(Add#(1, z, lanes), SelectVirtex7PCIE#(lanes)); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// PCIE_V7#(lanes) pcie_ep <- selectVirtex7PCIE(params); Clock user_clk = pcie_ep.trn.clk; Reset user_reset_n <- mkResetInverter(pcie_ep.trn.reset); Wire#(Bit#(1)) wDiscontinue <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(1)) wEcrcGen <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(1)) wErrFwd <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(1)) wCutThrough <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bool) wAxiTxValid <- mkDWire(False, clocked_by user_clk, reset_by noReset); Wire#(Bool) wAxiTxLast <- mkDWire(False, clocked_by user_clk, reset_by noReset); Wire#(Bit#(64)) wAxiTxData <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(8)) wAxiTxKeep <- mkDWire(0, clocked_by user_clk, reset_by noReset); FIFO#(AxiTx) fAxiTx <- mkBypassFIFO(clocked_by user_clk, reset_by noReset); FIFOF#(AxiRx) fAxiRx <- mkBypassFIFOF(clocked_by user_clk, reset_by noReset); Wire#(Bool) wAxiRxReady <- mkDWire(False, clocked_by user_clk, reset_by noReset); ClockGenerator7Params clk_params = defaultValue; clk_params.clkin1_period = 4.000; clk_params.clkin_buffer = False; clk_params.clkfbout_mult_f = 4.000; clk_params.clkout0_divide_f = 8.000; ClockGenerator7 clkgen <- mkClockGenerator7(clk_params, clocked_by user_clk, reset_by user_reset_n); Clock user_clk_half = clkgen.clkout0; Reset user_reset_half <- mkAsyncReset(1, user_reset_n, user_clk_half); XilinxClockParams scemiclk_params = defaultValue; scemiclk_params.e_type = E2; scemiclk_params.clkin1_period = 8.000; scemiclk_params.clkfbout_mult_f = 8.000; scemiclk_params.clkout0_divide_f = params.clock_period; XilinxClockController scemi_clkgen <- mkXilinxClockController(scemiclk_params, user_clk_half, clocked_by user_clk_half, reset_by user_reset_half); //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// (* fire_when_enabled, no_implicit_conditions *) rule others; pcie_ep.trn.fc_sel(RECEIVE_BUFFER_AVAILABLE_SPACE); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_tx; pcie_ep.axi_tx.tuser({ wDiscontinue, wCutThrough, wErrFwd, wEcrcGen }); pcie_ep.axi_tx.tvalid(wAxiTxValid); pcie_ep.axi_tx.tlast(wAxiTxLast); pcie_ep.axi_tx.tdata(wAxiTxData); pcie_ep.axi_tx.tkeep(wAxiTxKeep); endrule (* fire_when_enabled *) rule drive_axi_tx_info if (pcie_ep.axi_tx.tready); let info <- toGet(fAxiTx).get; wAxiTxValid <= True; wAxiTxLast <= info.last; wAxiTxData <= info.data; wAxiTxKeep <= info.keep; endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rx_ready; pcie_ep.axi_rx.rready(fAxiRx.notFull); endrule (* fire_when_enabled *) rule sink_axi_rx if (pcie_ep.axi_rx.rvalid); let info = AxiRx { user: pcie_ep.axi_rx.ruser, last: pcie_ep.axi_rx.rlast, keep: pcie_ep.axi_rx.rkeep, data: pcie_ep.axi_rx.rdata }; fAxiRx.enq(info); endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface pcie = pcie_ep.pcie; interface PCIE_TRN_COMMON_V7 trn; interface clk = user_clk; interface clk2 = user_clk_half; interface reset_n = user_reset_n; method link_up = pcie_ep.trn.lnk_up; endinterface interface PCIE_TRN_XMIT_V7 trn_tx; method Action xmit(data); fAxiTx.enq(AxiTx { last: data.eof, keep: dwordSwap64BE(data.be), data: dwordSwap64(data.data) }); endmethod method discontinue(i) = wDiscontinue._write(pack(i)); method ecrc_generate(i) = wEcrcGen._write(pack(i)); method error_forward(i) = wErrFwd._write(pack(i)); method cut_through_mode(i) = wCutThrough._write(pack(i)); method dropped = pcie_ep.axi_tx.terr_drop; method buffers_available = pcie_ep.axi_tx.tbuf_av; method configuration_completion_request = pcie_ep.axi_tx.tcfg_req; method configuration_completion_grant(i) = pcie_ep.axi_tx.tcfg_gnt(i); endinterface interface PCIE_TRN_RECV_V7 trn_rx; method ActionValue#(Tuple3#(Bool, Bool, TLPData#(8))) recv(); let info <- toGet(fAxiRx).get; TLPData#(8) retval = defaultValue; retval.sof = (info.user[14] == 1); retval.eof = info.last; retval.hit = info.user[8:2]; retval.be = dwordSwap64BE(info.keep); retval.data = dwordSwap64(info.data); return tuple3(info.user[1] == 1, info.user[0] == 1, retval); endmethod method non_posted_ok(i) = pcie_ep.axi_rx.rnp_ok(i); method non_posted_req(i) = pcie_ep.axi_rx.rnp_req(i); endinterface interface pl = pcie_ep.pl; interface cfg = pcie_ep.cfg; interface cfg_interrupt = pcie_ep.cfg_interrupt; interface cfg_err = pcie_ep.cfg_err; interface scemi_clk = scemi_clkgen.clkout0; interface XilinxClkServer clks; interface Put request; method Action put(Bit#(32) x); let request = XilinxClockRequest { rnw: unpack(x[31]), addr: x[20:16], data: x[15:0] }; scemi_clkgen.csr.request.put(request); endmethod endinterface interface Get response; method ActionValue#(Bit#(32)) get; let response <- scemi_clkgen.csr.response.get; return cExtend(response); endmethod endinterface endinterface endmodule: mkPCIExpressEndpointV7 // The BSV PCIE endpoint, without exported clocks (original pre-PCIE3 version) module mkPCIExpressEndpointNoClkV7#(PCIEParams params)(PCIExpressNoClkV7#(lanes)) provisos(Add#(1, z, lanes), SelectVirtex7PCIE#(lanes)); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// PCIE_V7#(lanes) pcie_ep <- selectVirtex7PCIE(params); Clock user_clk = pcie_ep.trn.clk; Reset user_reset_n <- mkResetInverter(pcie_ep.trn.reset); Wire#(Bit#(1)) wDiscontinue <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(1)) wEcrcGen <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(1)) wErrFwd <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(1)) wCutThrough <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bool) wAxiTxValid <- mkDWire(False, clocked_by user_clk, reset_by noReset); Wire#(Bool) wAxiTxLast <- mkDWire(False, clocked_by user_clk, reset_by noReset); Wire#(Bit#(64)) wAxiTxData <- mkDWire(0, clocked_by user_clk, reset_by noReset); Wire#(Bit#(8)) wAxiTxKeep <- mkDWire(0, clocked_by user_clk, reset_by noReset); FIFO#(AxiTx) fAxiTx <- mkBypassFIFO(clocked_by user_clk, reset_by noReset); FIFOF#(AxiRx) fAxiRx <- mkBypassFIFOF(clocked_by user_clk, reset_by noReset); Wire#(Bool) wAxiRxReady <- mkDWire(False, clocked_by user_clk, reset_by noReset); ClockGenerator7Params clk_params = defaultValue; clk_params.clkin1_period = 4.000; clk_params.clkin_buffer = False; clk_params.clkfbout_mult_f = 4.000; clk_params.clkout0_divide_f = 8.000; ClockGenerator7 clkgen <- mkClockGenerator7(clk_params, clocked_by user_clk, reset_by user_reset_n); Clock user_clk_half = clkgen.clkout0; //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// (* fire_when_enabled, no_implicit_conditions *) rule others; pcie_ep.trn.fc_sel(RECEIVE_BUFFER_AVAILABLE_SPACE); endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_tx; pcie_ep.axi_tx.tuser({ wDiscontinue, wCutThrough, wErrFwd, wEcrcGen }); pcie_ep.axi_tx.tvalid(wAxiTxValid); pcie_ep.axi_tx.tlast(wAxiTxLast); pcie_ep.axi_tx.tdata(wAxiTxData); pcie_ep.axi_tx.tkeep(wAxiTxKeep); endrule (* fire_when_enabled *) rule drive_axi_tx_info if (pcie_ep.axi_tx.tready); let info <- toGet(fAxiTx).get; wAxiTxValid <= True; wAxiTxLast <= info.last; wAxiTxData <= info.data; wAxiTxKeep <= info.keep; endrule (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rx_ready; pcie_ep.axi_rx.rready(fAxiRx.notFull); endrule (* fire_when_enabled *) rule sink_axi_rx if (pcie_ep.axi_rx.rvalid); let info = AxiRx { user: pcie_ep.axi_rx.ruser, last: pcie_ep.axi_rx.rlast, keep: pcie_ep.axi_rx.rkeep, data: pcie_ep.axi_rx.rdata }; fAxiRx.enq(info); endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface pcie = pcie_ep.pcie; interface PCIE_TRN_COMMON_V7 trn; interface clk = user_clk; interface clk2 = user_clk_half; interface reset_n = user_reset_n; method link_up = pcie_ep.trn.lnk_up; endinterface interface PCIE_TRN_XMIT_V7 trn_tx; method Action xmit(data); fAxiTx.enq(AxiTx { last: data.eof, keep: dwordSwap64BE(data.be), data: dwordSwap64(data.data) }); endmethod method discontinue(i) = wDiscontinue._write(pack(i)); method ecrc_generate(i) = wEcrcGen._write(pack(i)); method error_forward(i) = wErrFwd._write(pack(i)); method cut_through_mode(i) = wCutThrough._write(pack(i)); method dropped = pcie_ep.axi_tx.terr_drop; method buffers_available = pcie_ep.axi_tx.tbuf_av; method configuration_completion_request = pcie_ep.axi_tx.tcfg_req; method configuration_completion_grant(i) = pcie_ep.axi_tx.tcfg_gnt(i); endinterface interface PCIE_TRN_RECV_V7 trn_rx; method ActionValue#(Tuple3#(Bool, Bool, TLPData#(8))) recv(); let info <- toGet(fAxiRx).get; TLPData#(8) retval = defaultValue; retval.sof = (info.user[14] == 1); retval.eof = info.last; retval.hit = info.user[8:2]; retval.be = dwordSwap64BE(info.keep); retval.data = dwordSwap64(info.data); return tuple3(info.user[1] == 1, info.user[0] == 1, retval); endmethod method non_posted_ok(i) = pcie_ep.axi_rx.rnp_ok(i); method non_posted_req(i) = pcie_ep.axi_rx.rnp_req(i); endinterface interface pl = pcie_ep.pl; interface cfg = pcie_ep.cfg; interface cfg_interrupt = pcie_ep.cfg_interrupt; interface cfg_err = pcie_ep.cfg_err; endmodule: mkPCIExpressEndpointNoClkV7 //////////////////////////////////////////////////////////////////////////////// /// Connection Instances //////////////////////////////////////////////////////////////////////////////// // Basic TLPData#(8) connections to PCIE endpoint instance Connectable#(Get#(TLPData#(8)), PCIE_TRN_XMIT_V7); module mkConnection#(Get#(TLPData#(8)) g, PCIE_TRN_XMIT_V7 p)(Empty); rule every; p.cut_through_mode(False); p.configuration_completion_grant(True); // Core gets to choose p.error_forward(False); p.ecrc_generate(False); p.discontinue(False); endrule rule connect; let data <- g.get; p.xmit(data); endrule endmodule endinstance instance Connectable#(PCIE_TRN_XMIT_V7, Get#(TLPData#(8))); module mkConnection#(PCIE_TRN_XMIT_V7 p, Get#(TLPData#(8)) g)(Empty); mkConnection(g, p); endmodule endinstance instance Connectable#(Put#(TLPData#(8)), PCIE_TRN_RECV_V7); module mkConnection#(Put#(TLPData#(8)) p, PCIE_TRN_RECV_V7 r)(Empty); (* no_implicit_conditions, fire_when_enabled *) rule every; r.non_posted_ok(True); r.non_posted_req(True); endrule rule connect; let data <- r.recv; p.put(tpl_3(data)); endrule endmodule endinstance instance Connectable#(PCIE_TRN_RECV_V7, Put#(TLPData#(8))); module mkConnection#(PCIE_TRN_RECV_V7 r, Put#(TLPData#(8)) p)(Empty); mkConnection(p, r); endmodule endinstance // Connections between TLPData#(16) and a PCIE endpoint. // These are all using the same clock, so the TLPData#(16) accesses // will not be back-to-back. instance Connectable#(Get#(TLPData#(16)), PCIE_TRN_XMIT_V7); module mkConnection#(Get#(TLPData#(16)) g, PCIE_TRN_XMIT_V7 t)(Empty); FIFO#(TLPData#(8)) outFifo <- mkFIFO(); (* no_implicit_conditions, fire_when_enabled *) rule every; t.cut_through_mode(False); t.configuration_completion_grant(True); // True means core gets to choose t.error_forward(False); t.ecrc_generate(False); t.discontinue(False); endrule rule connect; let data = outFifo.first; outFifo.deq; if (data.be != 0) t.xmit(data); endrule Put#(TLPData#(8)) p = fifoToPut(outFifo); mkConnection(g,p); endmodule endinstance instance Connectable#(PCIE_TRN_XMIT_V7, Get#(TLPData#(16))); module mkConnection#(PCIE_TRN_XMIT_V7 p, Get#(TLPData#(16)) g)(Empty); mkConnection(g, p); endmodule endinstance instance Connectable#(Put#(TLPData#(16)), PCIE_TRN_RECV_V7); module mkConnection#(Put#(TLPData#(16)) p, PCIE_TRN_RECV_V7 r)(Empty); FIFO#(TLPData#(8)) inFifo <- mkFIFO(); (* no_implicit_conditions, fire_when_enabled *) rule every; r.non_posted_ok(True); r.non_posted_req(True); endrule rule connect; let data <- r.recv; inFifo.enq(tpl_3(data)); endrule Get#(TLPData#(8)) g = fifoToGet(inFifo); mkConnection(g,p); endmodule endinstance instance Connectable#(PCIE_TRN_RECV_V7, Put#(TLPData#(16))); module mkConnection#(PCIE_TRN_RECV_V7 r, Put#(TLPData#(16)) p)(Empty); mkConnection(p, r); endmodule endinstance // Connections between TLPData#(16) and a PCIE endpoint, using a gearbox // to match data rates between the endpoint and design clocks. instance ConnectableWithClocks#(PCIE_TRN_XMIT_V7, Get#(TLPData#(16))); module mkConnectionWithClocks#(PCIE_TRN_XMIT_V7 p, Get#(TLPData#(16)) g, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset)(Empty); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// FIFO#(TLPData#(8)) outFifo <- mkFIFO(clocked_by fastClock, reset_by fastReset); Gearbox#(2, 1, TLPData#(8)) fifoTxData <- mkNto1Gearbox(slowClock, slowReset, fastClock, fastReset); //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// (* no_implicit_conditions, fire_when_enabled *) rule every; p.cut_through_mode(False); p.configuration_completion_grant(True); // Means the core gets to choose p.error_forward(False); p.ecrc_generate(False); p.discontinue(False); endrule rule get_data; function Vector#(2, TLPData#(8)) split(TLPData#(16) in); Vector#(2, TLPData#(8)) v = defaultValue; v[0].sof = in.sof; v[0].eof = (in.be[7:0] == 0) ? in.eof : False; v[0].hit = in.hit; v[0].be = in.be[15:8]; v[0].data = in.data[127:64]; v[1].sof = False; v[1].eof = in.eof; v[1].hit = in.hit; v[1].be = in.be[7:0]; v[1].data = in.data[63:0]; return v; endfunction let data <- g.get; fifoTxData.enq(split(data)); endrule rule process_outgoing_packets; let data = fifoTxData.first; fifoTxData.deq; outFifo.enq(head(data)); endrule rule send_data; let data = outFifo.first; outFifo.deq; // filter out TLPs with 00 byte enable if (data.be != 0) p.xmit(data); endrule endmodule endinstance instance ConnectableWithClocks#(Get#(TLPData#(16)), PCIE_TRN_XMIT_V7); module mkConnectionWithClocks#(Get#(TLPData#(16)) g, PCIE_TRN_XMIT_V7 p, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset)(Empty); mkConnectionWithClocks(p, g, fastClock, fastReset, slowClock, slowReset); endmodule endinstance instance ConnectableWithClocks#(Put#(TLPData#(16)), PCIE_TRN_RECV_V7); module mkConnectionWithClocks#(Put#(TLPData#(16)) p, PCIE_TRN_RECV_V7 g, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset)(Empty); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// FIFO#(TLPData#(8)) inFifo <- mkFIFO(clocked_by fastClock, reset_by fastReset); Gearbox#(1, 2, TLPData#(8)) fifoRxData <- mk1toNGearbox(fastClock, fastReset, slowClock, slowReset); Reg#(Bool) rOddBeat <- mkRegA(False, clocked_by fastClock, reset_by fastReset); Reg#(Bool) rSendInvalid <- mkRegA(False, clocked_by fastClock, reset_by fastReset); //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// (* no_implicit_conditions, fire_when_enabled *) rule every; g.non_posted_ok(True); g.non_posted_req(True); endrule rule accept_data; let data <- g.recv; inFifo.enq(tpl_3(data)); endrule rule process_incoming_packets(!rSendInvalid); let data = inFifo.first; inFifo.deq; rOddBeat <= !rOddBeat; rSendInvalid <= !rOddBeat && data.eof; Vector#(1, TLPData#(8)) v = defaultValue; v[0] = data; fifoRxData.enq(v); endrule rule send_invalid_packets(rSendInvalid); rOddBeat <= !rOddBeat; rSendInvalid <= False; Vector#(1, TLPData#(8)) v = defaultValue; v[0].eof = True; v[0].be = 0; fifoRxData.enq(v); endrule rule send_data; function TLPData#(16) combine(Vector#(2, TLPData#(8)) in); return TLPData { sof: in[0].sof, eof: in[1].eof, hit: in[0].hit, be: { in[0].be, in[1].be }, data: { in[0].data, in[1].data } }; endfunction fifoRxData.deq; p.put(combine(fifoRxData.first)); endrule endmodule endinstance instance ConnectableWithClocks#(PCIE_TRN_RECV_V7, Put#(TLPData#(16))); module mkConnectionWithClocks#(PCIE_TRN_RECV_V7 g, Put#(TLPData#(16)) p, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset)(Empty); mkConnectionWithClocks(p, g, fastClock, fastReset, slowClock, slowReset); endmodule endinstance // interface tie-offs instance TieOff#(PCIE_CFG_V7); module mkTieOff#(PCIE_CFG_V7 ifc)(Empty); rule tie_off_inputs; ifc.di(0); ifc.dwaddr(0); ifc.byte_en(0); ifc.wr_en(0); ifc.rd_en(0); ifc.wr_readonly(0); ifc.trn_pending(0); ifc.dsn({ 32'h0000_0001, {{ 8'h1 } , 24'h000A35 }}); ifc.pm_halt_aspm_l0s(0); ifc.pm_halt_aspm_l1(0); ifc.pm_force_state(0); ifc.pm_force_state_en(0); ifc.turnoff_ok(0); ifc.pm_wake(0); endrule endmodule endinstance instance TieOff#(PCIE_INT_V7); module mkTieOff#(PCIE_INT_V7 ifc)(Empty); rule tie_off_inputs; ifc.req(0); ifc.assrt(0); ifc.di(0); ifc.pciecap_msgnum(0); ifc.stat(0); endrule endmodule endinstance instance TieOff#(PCIE_ERR_V7); module mkTieOff#(PCIE_ERR_V7 ifc)(Empty); rule tie_off_inputs; ifc.ecrc(0); ifc.ur(0); ifc.cpl_timeout(0); ifc.cpl_unexpect(0); ifc.cpl_abort(0); ifc.posted(0); ifc.cor(0); ifc.atomic_egress_blocked(0); ifc.internal_cor(0); ifc.internal_uncor(0); ifc.malformed(0); ifc.mc_blocked(0); ifc.poisoned(0); ifc.no_recovery(0); ifc.tlp_cpl_header(0); ifc.locked(0); ifc.aer_headerlog(0); ifc.aer_interrupt_msgnum(0); ifc.acs(0); endrule endmodule endinstance instance TieOff#(PCIE_PL_V7); module mkTieOff#(PCIE_PL_V7 ifc)(Empty); rule tie_off_inputs; ifc.directed_link_auton(0); ifc.directed_link_change(0); ifc.directed_link_speed(0); ifc.directed_link_width(0); ifc.upstream_prefer_deemph(1); endrule endmodule endinstance //////////////////////////////////////////////////////////////////////////////// /// PART 2: PCIE3 (PCIE3, for VC709 etc.) /// This code was initially created in 2014-11 //////////////////////////////////////////////////////////////////////////////// // ================================================================ // Types of PCIE3 info connecting to bridge (mkPCIE3toBNocFull) via gearboxes etc. typedef struct { Bit #(64) data; Bool sop; Bool eop; Bit #(2) keep; TLPFirstDWBE first_be; TLPFirstDWBE last_be; } AxiStCq deriving (Bits, Eq); typedef struct { Bit #(64) data; Bit #(2) keep; Bool last; } AxiStCc deriving (Bits, Eq); typedef struct { Bit #(64) data; Bool last; Bit #(2) keep; Bit #(4) first_be; Bit #(4) last_be; } AxiStRq deriving (Bits, Eq); typedef struct { Bit #(64) data; Bool sop; Bool eop; Bit #(2) keep; Bit #(8) be; } AxiStRc deriving (Bits, Eq); // ================================================================ /// Raw interface from wrapped verilog PCIE3 endpoint (* always_ready, always_enabled *) interface PCIE3_V7#(numeric type lanes); interface PCIE_EXP#(lanes) pcie; interface Clock user_clk; interface Reset user_reset; interface PCIE3_STATUS_V7 status; interface PCIE3_AXI_RQ_V7 axi_rq; interface PCIE3_AXI_RC_V7 axi_rc; interface PCIE3_AXI_CQ_V7 axi_cq; interface PCIE3_AXI_CC_V7 axi_cc; interface PCIE3_INT_V7 cfg_interrupt; interface PCIE3_INT_MSIX_V7 cfg_interrupt_msix; endinterface (* always_ready, always_enabled *) interface PCIE3_STATUS_V7; method Bool lnk_up; method Bool app_rdy; method Bit#(3) max_payload; method Bit#(3) max_read_req; method Bit#(2) rcb_status; method Bit#(8) function_status; endinterface (* always_ready, always_enabled *) interface PCIE3_AXI_RQ_V7; method Action tlast(Bool i); method Action tdata(Bit#(64) i); method Action tuser(Bit#(60) i); method Action tkeep(Bit#(2) i); method Bit#(4) tready(); method Action tvalid(Bool i); endinterface (* always_ready, always_enabled *) interface PCIE3_AXI_RC_V7; method Bit#(64) tdata(); method Bit#(75) tuser(); method Bool tlast(); method Bit#(2) tkeep(); method Bool tvalid(); method Action tready(Bit#(22) i); endinterface (* always_ready, always_enabled *) interface PCIE3_AXI_CQ_V7; method Bit#(64) tdata(); method Bit#(85) tuser(); method Bool tlast(); method Bit#(2) tkeep(); method Bool tvalid(); method Action tready(Bit#(22) i); endinterface (* always_ready, always_enabled *) interface PCIE3_AXI_CC_V7; method Action tlast(Bool i); method Action tdata(Bit#(64) i); method Action tuser(Bit#(33) i); method Action tkeep(Bit#(2) i); method Bit#(4) tready(); method Action tvalid(Bool i); endinterface (* always_ready, always_enabled *) interface PCIE3_INT_V7; method Action int_vect(Bit#(4) i); method Action pending(Bit#(2) i); method Bool sent(); endinterface (* always_ready, always_enabled *) interface PCIE3_INT_MSI_V7; method Bit#(2) enabled(); method Bit#(6) vf_enable(); method Bit#(6) mmenable(); method Bool mask_update(); method Bit#(32) data(); method Action select(Bit#(4) i); method Action valid(Bit#(32) i); method Action pending_status(Bit#(64) i); method Bool sent(); method Bool fail(); method Action attr(Bit#(3) i); method Action tph_present(Bool i); method Action tph_type(Bit#(2) i); method Action tph_st_tag(Bit#(9) i); method Action function_number(Bit#(3) i); endinterface (* always_ready, always_enabled *) interface PCIE3_INT_MSIX_V7; method Bit#(2) enabled(); method Bit#(2) mask(); method Bit#(6) vf_enable(); method Bit#(6) vf_mask(); method Action data(Bit#(32) i); method Action address(Bit#(64) i); method Action valid(Bit#(1) i); // int method Bool sent(); method Bool fail(); endinterface // ================================================================ // Immediate wrapper for imported Verilog PCIE3 endpoint import "BVI" xilinx_v7_pcie3_wrapper = module vMkVirtex7PCIExpress3#(PCIEParams params)(PCIE3_V7#(lanes)) provisos( Add#(1, z, lanes) ); let sys_reset <- invertCurrentReset; default_clock sys_clk(sys_clk); // 100 MHz refclk default_reset sys_rstn(sys_reset) = sys_reset; interface PCIE_EXP pcie; method rxp(pci_exp_rxp) enable((*inhigh*)en0) reset_by(no_reset); method rxn(pci_exp_rxn) enable((*inhigh*)en1) reset_by(no_reset); method pci_exp_txp txp reset_by(no_reset); method pci_exp_txn txn reset_by(no_reset); endinterface output_clock user_clk(user_clk); output_reset user_reset(user_reset); interface PCIE3_STATUS_V7 status; method user_lnk_up lnk_up clocked_by(no_clock) reset_by(no_reset); /* semi-static */ method user_app_rdy app_rdy clocked_by(user_clk) reset_by(no_reset); method cfg_max_payload max_payload clocked_by(user_clk) reset_by(no_reset); method cfg_max_read_req max_read_req clocked_by(user_clk) reset_by(no_reset); method cfg_rcb_status rcb_status clocked_by(user_clk) reset_by(no_reset); method cfg_function_status function_status clocked_by(user_clk) reset_by(no_reset); endinterface interface PCIE3_AXI_RQ_V7 axi_rq; method tlast(s_axis_rq_tlast) enable((*inhigh*)en01) clocked_by(user_clk) reset_by(no_reset); method tdata(s_axis_rq_tdata) enable((*inhigh*)en02) clocked_by(user_clk) reset_by(no_reset); method tuser(s_axis_rq_tuser) enable((*inhigh*)en03) clocked_by(user_clk) reset_by(no_reset); method tkeep(s_axis_rq_tkeep) enable((*inhigh*)en04) clocked_by(user_clk) reset_by(no_reset); method s_axis_rq_tready tready clocked_by(user_clk) reset_by(no_reset); method tvalid(s_axis_rq_tvalid) enable((*inhigh*)en05) clocked_by(user_clk) reset_by(no_reset); endinterface interface PCIE3_AXI_RC_V7 axi_rc; method m_axis_rc_tdata tdata clocked_by(user_clk) reset_by(no_reset); method m_axis_rc_tuser tuser clocked_by(user_clk) reset_by(no_reset); method m_axis_rc_tlast tlast clocked_by(user_clk) reset_by(no_reset); method m_axis_rc_tkeep tkeep clocked_by(user_clk) reset_by(no_reset); method m_axis_rc_tvalid tvalid clocked_by(user_clk) reset_by(no_reset); method tready(m_axis_rc_tready) enable((*inhigh*)en06) clocked_by(user_clk) reset_by(no_reset); endinterface interface PCIE3_AXI_CQ_V7 axi_cq; method m_axis_cq_tdata tdata clocked_by(user_clk) reset_by(no_reset); method m_axis_cq_tuser tuser clocked_by(user_clk) reset_by(no_reset); method m_axis_cq_tlast tlast clocked_by(user_clk) reset_by(no_reset); method m_axis_cq_tkeep tkeep clocked_by(user_clk) reset_by(no_reset); method m_axis_cq_tvalid tvalid clocked_by(user_clk) reset_by(no_reset); method tready(m_axis_cq_tready) enable((*inhigh*)en07) clocked_by(user_clk) reset_by(no_reset); endinterface interface PCIE3_AXI_CC_V7 axi_cc; method tlast(s_axis_cc_tlast) enable((*inhigh*)en08) clocked_by(user_clk) reset_by(no_reset); method tdata(s_axis_cc_tdata) enable((*inhigh*)en09) clocked_by(user_clk) reset_by(no_reset); method tuser(s_axis_cc_tuser) enable((*inhigh*)en10) clocked_by(user_clk) reset_by(no_reset); method tkeep(s_axis_cc_tkeep) enable((*inhigh*)en11) clocked_by(user_clk) reset_by(no_reset); method s_axis_cc_tready tready clocked_by(user_clk) reset_by(no_reset); method tvalid(s_axis_cc_tvalid) enable((*inhigh*)en12) clocked_by(user_clk) reset_by(no_reset); endinterface interface PCIE3_INT_V7 cfg_interrupt; method int_vect(cfg_interrupt_int) enable((*inhigh*)en13) clocked_by(user_clk) reset_by(no_reset); method pending(cfg_interrupt_pending) enable((*inhigh*)en14) clocked_by(user_clk) reset_by(no_reset); method cfg_interrupt_sent sent clocked_by(user_clk) reset_by(no_reset); endinterface interface PCIE3_INT_MSIX_V7 cfg_interrupt_msix; method cfg_interrupt_msix_enable enabled clocked_by(user_clk) reset_by(no_reset); method cfg_interrupt_msix_mask mask clocked_by(user_clk) reset_by(no_reset); method cfg_interrupt_msix_vf_enable vf_enable clocked_by(user_clk) reset_by(no_reset); method cfg_interrupt_msix_vf_mask vf_mask clocked_by(user_clk) reset_by(no_reset); method data(cfg_interrupt_msix_data) enable((*inhigh*)en23) clocked_by(user_clk) reset_by(no_reset); method address(cfg_interrupt_msix_address) enable((*inhigh*)en24) clocked_by(user_clk) reset_by(no_reset); method valid(cfg_interrupt_msix_int) enable((*inhigh*)en25) clocked_by(user_clk) reset_by(no_reset); method cfg_interrupt_msix_sent sent clocked_by(user_clk) reset_by(no_reset); method cfg_interrupt_msix_fail fail clocked_by(user_clk) reset_by(no_reset); endinterface schedule (status_lnk_up, status_app_rdy, axi_rq_tlast, axi_rq_tdata, axi_rq_tuser, axi_rq_tkeep, axi_rq_tready, axi_rq_tvalid, axi_rc_tdata, axi_rc_tuser, axi_rc_tlast, axi_rc_tkeep, axi_rc_tvalid, axi_rc_tready, axi_cq_tdata, axi_cq_tuser, axi_cq_tlast, axi_cq_tkeep, axi_cq_tvalid, axi_cq_tready, axi_cc_tlast, axi_cc_tdata, axi_cc_tuser, axi_cc_tkeep, axi_cc_tready, axi_cc_tvalid, cfg_interrupt_int_vect, cfg_interrupt_pending, cfg_interrupt_sent, cfg_interrupt_msix_enabled, cfg_interrupt_msix_mask, cfg_interrupt_msix_vf_enable, cfg_interrupt_msix_vf_mask, cfg_interrupt_msix_data, cfg_interrupt_msix_address, cfg_interrupt_msix_valid, cfg_interrupt_msix_sent, cfg_interrupt_msix_fail, pcie_txp, pcie_txn, pcie_rxp, pcie_rxn, status_max_payload, status_max_read_req, status_rcb_status, status_function_status) CF (status_lnk_up, status_app_rdy, axi_rq_tlast, axi_rq_tdata, axi_rq_tuser, axi_rq_tkeep, axi_rq_tready, axi_rq_tvalid, axi_rc_tdata, axi_rc_tuser, axi_rc_tlast, axi_rc_tkeep, axi_rc_tvalid, axi_rc_tready, axi_cq_tdata, axi_cq_tuser, axi_cq_tlast, axi_cq_tkeep, axi_cq_tvalid, axi_cq_tready, axi_cc_tlast, axi_cc_tdata, axi_cc_tuser, axi_cc_tkeep, axi_cc_tready, axi_cc_tvalid, cfg_interrupt_int_vect, cfg_interrupt_pending, cfg_interrupt_sent, cfg_interrupt_msix_enabled, cfg_interrupt_msix_mask, cfg_interrupt_msix_vf_enable, cfg_interrupt_msix_vf_mask, cfg_interrupt_msix_data, cfg_interrupt_msix_address, cfg_interrupt_msix_valid, cfg_interrupt_msix_sent, cfg_interrupt_msix_fail, pcie_txp, pcie_txn, pcie_rxp, pcie_rxn, status_max_payload, status_max_read_req, status_rcb_status, status_function_status); endmodule // ================================================================ // Interfaces PCIE3 for bridge interface PCIExpress3V7 #(numeric type lanes); interface PCIE_EXP#(lanes) pcie; interface Clock uclk; interface Reset ureset; interface Clock uclk_half; interface Reset ureset_half; interface PCIE3_STATUS_V7 status; interface Get #(AxiStCq) cq_recv; interface Put #(AxiStCc) cc_xmit; interface Put #(AxiStRq) rq_xmit; interface Get #(AxiStRc) rc_recv; interface PCIE3_INT_V7 cfg_interrupt; interface PCIE3_INT_MSIX_V7 cfg_interrupt_msix; interface XilinxClkServer clks; interface Clock cclk; endinterface //////////////////////////////////////////////////////////////////////////////// /// For PCIE3 /// Typeclass to select vMkVirtex7PCIExpress3() for 1, 4, 8 lanes //////////////////////////////////////////////////////////////////////////////// typeclass SelectVirtex7PCIE3#(numeric type lanes); module selectVirtex7PCIE3(PCIEParams params, PCIE3_V7#(lanes) ifc); endtypeclass instance SelectVirtex7PCIE3#(8); module selectVirtex7PCIE3(PCIEParams params, PCIE3_V7#(8) ifc); let _ifc <- vMkVirtex7PCIExpress3(params); return _ifc; endmodule endinstance instance SelectVirtex7PCIE3#(4); module selectVirtex7PCIE3(PCIEParams params, PCIE3_V7#(4) ifc); let _ifc <- vMkVirtex7PCIExpress3(params); return _ifc; endmodule endinstance instance SelectVirtex7PCIE3#(1); module selectVirtex7PCIE3(PCIEParams params, PCIE3_V7#(1) ifc); let _ifc <- vMkVirtex7PCIExpress3(params); return _ifc; endmodule endinstance //////////////////////////////////////////////////////////////// // The BSV PCIE3 endpoint //////////////////////////////////////////////////////////////// module mkPCIExpress3EndpointV7 #(PCIEParams params) (PCIExpress3V7 #(lanes)) provisos(Add #(1, z, lanes), SelectVirtex7PCIE3 #(lanes)); // Instantiate Vivado-generated, wrapped Verilog endpoint PCIE3_V7 #(lanes) pcie_ep <- selectVirtex7PCIE3 (params); Clock user_clk = pcie_ep.user_clk; Reset user_reset_raw <- mkResetInverter (pcie_ep.user_reset, clocked_by user_clk); Reset user_reset <- mkAsyncReset(4, user_reset_raw, user_clk); ClockGenerator7Params clk_params = defaultValue; clk_params.clkin1_period = 4.000; clk_params.clkin_buffer = False; clk_params.clkfbout_mult_f = 4.000; clk_params.clkout0_divide_f = 8.000; ClockGenerator7 clkgen <- mkClockGenerator7 (clk_params, clocked_by user_clk, reset_by user_reset_raw); Clock user_clk_half = clkgen.clkout0; Reset user_reset_half <- mkAsyncReset(4, user_reset_raw, user_clk_half); XilinxClockParams cclk_params = defaultValue; cclk_params.e_type = E2; cclk_params.clkin1_period = 8.000; cclk_params.clkfbout_mult_f = 8.000; cclk_params.clkout0_divide_f = params.clock_period; // XXX Can we use "user_reset_half" here? Reset cclk_clkgen_reset <- mkAsyncReset(1, user_reset_raw, user_clk_half); XilinxClockController cclk_clkgen <- mkXilinxClockController (cclk_params, user_clk_half, clocked_by user_clk_half, reset_by cclk_clkgen_reset); // ---------------- // FIFOs that drain the CQ and RC AXI Stream interfaces FIFOF #(AxiStCq) fAxiCq <- mkBypassFIFOF (clocked_by user_clk, reset_by user_reset); // RC FIFOF #(AxiStRc) fAxiRc <- mkBypassFIFOF (clocked_by user_clk, reset_by user_reset); // ---------------- // FIFOs that feed the CC and RQ AXI Stream interfaces // CC FIFO#(AxiStCc) fAxiCc <- mkCCBuffer(clocked_by user_clk, reset_by user_reset); Wire#(Bit#(64)) wAxiCcData <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiCcLast <- mkDWire(False, clocked_by user_clk, reset_by user_reset); Wire#(Bit#(2)) wAxiCcKeep <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bit #(33)) wAxiCcUser <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiCcValid <- mkDWire(False, clocked_by user_clk, reset_by user_reset); // RQ FIFO#(AxiStRq) fAxiRq <- mkRQBuffer(clocked_by user_clk, reset_by user_reset); Wire#(Bit#(64)) wAxiRqData <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiRqLast <- mkDWire(False, clocked_by user_clk, reset_by user_reset); Wire#(Bit#(2)) wAxiRqKeep <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bit#(60)) wAxiRqUser <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiRqValid <- mkDWire(False, clocked_by user_clk, reset_by user_reset); // ---------------------------------------------------------------- // RULES // ---------------- // CQ (requests from host): here at 250 MHz we only collect the // info we need and pass it on; the actual parsing of descriptors // and payloads happens in the 125 MHz domain which can accommodate // more complex circuits. // Collect cq from AXI into FIFO fAxiCq (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cq_ready; pcie_ep.axi_cq.tready (duplicate (pack (fAxiCq.notFull))); endrule rule process_ax_cq_beat (pcie_ep.axi_cq.tvalid && fAxiCq.notFull); let cq = AxiStCq {data: pcie_ep.axi_cq.tdata, sop: unpack (pcie_ep.axi_cq.tuser [40]), // tuser.sop eop: pcie_ep.axi_cq.tlast, keep: pcie_ep.axi_cq.tkeep, first_be: pcie_ep.axi_cq.tuser [3:0], // tuser.first_be, last_be: pcie_ep.axi_cq.tuser [7:4]}; // tuser.last_be fAxiCq.enq (cq); endrule // ---------------- // RC (completions from host): here at 250 MHz we only collect the // info we need and pass it on; the actual parsing of descriptors // and payloads happens in the 125 MHz domain which can accommodate // more complex circuits (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rc_ready; pcie_ep.axi_rc.tready (duplicate (pack (fAxiRc.notFull))); endrule rule process_ax_rc_beat (pcie_ep.axi_rc.tvalid && fAxiRc.notFull); let rc = AxiStRc {data:pcie_ep.axi_rc.tdata, sop: unpack (pcie_ep.axi_rc.tuser [32]), // tuser.is_sof_0 eop: pcie_ep.axi_rc.tlast, keep:pcie_ep.axi_rc.tkeep, be: truncate (pcie_ep.axi_rc.tuser [31:0])}; // tuser.byte_en fAxiRc.enq (rc); endrule // Move rc from FIFO fAxiRc_a to fAxiRc_b, injecting an 'empty' // pad, if necessary, to ensure that sop is on an even enq // ---------------- // CC (completions to host): here at 250 MHz we just pass on the // info we get from the bridge, which was created at 125 MHz. (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cc; pcie_ep.axi_cc.tdata (wAxiCcData); pcie_ep.axi_cc.tkeep (wAxiCcKeep); pcie_ep.axi_cc.tlast (wAxiCcLast); pcie_ep.axi_cc.tuser (wAxiCcUser); pcie_ep.axi_cc.tvalid (wAxiCcValid); endrule (* fire_when_enabled *) rule drive_axi_cc_info (pcie_ep.axi_cc.tready != 0); let cc <- toGet (fAxiCc).get; wAxiCcValid <= True; wAxiCcLast <= cc.last; wAxiCcData <= cc.data; wAxiCcKeep <= cc.keep; wAxiCcUser <= 0; // tuser.discontinue and tuser.parity[31:0] endrule // ---------------- // RQ (requests to host): here at 250 MHz we just pass on the // info we get from the bridge, which was created at 125 MHz. (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rq; pcie_ep.axi_rq.tdata (wAxiRqData); pcie_ep.axi_rq.tkeep (wAxiRqKeep); pcie_ep.axi_rq.tlast (wAxiRqLast); pcie_ep.axi_rq.tuser (wAxiRqUser); pcie_ep.axi_rq.tvalid (wAxiRqValid); endrule (* fire_when_enabled *) rule drive_axi_rq_info (pcie_ep.axi_rq.tready != 0); let rq <- toGet (fAxiRq).get; wAxiRqValid <= True; wAxiRqData <= rq.data; wAxiRqLast <= rq.last; wAxiRqKeep <= rq.keep; wAxiRqUser <= { 0, rq.last_be, rq.first_be}; endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface pcie = pcie_ep.pcie; interface uclk = user_clk; interface ureset = user_reset; interface uclk_half = user_clk_half; interface ureset_half = user_reset_half; interface PCIE3_STATUS_V7 status; method lnk_up = pcie_ep.status.lnk_up; method app_rdy = pcie_ep.status.app_rdy; method max_payload = pcie_ep.status.max_payload; method max_read_req = pcie_ep.status.max_read_req; method rcb_status = pcie_ep.status.rcb_status; method function_status = pcie_ep.status.function_status; endinterface interface cq_recv = toGet (fAxiCq); interface rc_recv = toGet (fAxiRc); interface cc_xmit = toPut (fAxiCc); interface rq_xmit = toPut (fAxiRq); interface cfg_interrupt = pcie_ep.cfg_interrupt; interface cfg_interrupt_msix = pcie_ep.cfg_interrupt_msix; interface cclk = cclk_clkgen.clkout0; interface XilinxClkServer clks; interface Put request; method Action put(Bit#(32) x); let request = XilinxClockRequest { rnw: unpack(x[31]), addr: x[20:16], data: x[15:0] }; cclk_clkgen.csr.request.put(request); endmethod endinterface interface Get response; method ActionValue#(Bit#(32)) get; let response <- cclk_clkgen.csr.response.get; return cExtend(response); endmethod endinterface endinterface endmodule module mkPCIExpress3EndpointNoClkV7 #(PCIEParams params) (PCIExpress3V7 #(lanes)) provisos(Add #(1, z, lanes), SelectVirtex7PCIE3 #(lanes)); // Instantiate Vivado-generated, wrapped Verilog endpoint PCIE3_V7 #(lanes) pcie_ep <- selectVirtex7PCIE3 (params); Clock user_clk = pcie_ep.user_clk; Reset user_reset_raw <- mkResetInverter (pcie_ep.user_reset, clocked_by user_clk); Reset user_reset <- mkAsyncReset(4, user_reset_raw, user_clk); ClockGenerator7Params clk_params = defaultValue; clk_params.clkin1_period = 4.000; clk_params.clkin_buffer = False; clk_params.clkfbout_mult_f = 4.000; clk_params.clkout0_divide_f = 8.000; ClockGenerator7 clkgen <- mkClockGenerator7 (clk_params, clocked_by user_clk, reset_by user_reset_raw); Clock user_clk_half = clkgen.clkout0; Reset user_reset_half <- mkAsyncReset(4, user_reset_raw, user_clk_half); // ---------------- // FIFOs that drain the CQ and RC AXI Stream interfaces FIFOF #(AxiStCq) fAxiCq <- mkBypassFIFOF (clocked_by user_clk, reset_by user_reset); // RC FIFOF #(AxiStRc) fAxiRc <- mkBypassFIFOF (clocked_by user_clk, reset_by user_reset); // ---------------- // FIFOs that feed the CC and RQ AXI Stream interfaces // CC FIFO#(AxiStCc) fAxiCc <- mkCCBuffer(clocked_by user_clk, reset_by user_reset); Wire#(Bit#(64)) wAxiCcData <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiCcLast <- mkDWire(False, clocked_by user_clk, reset_by user_reset); Wire#(Bit#(2)) wAxiCcKeep <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bit #(33)) wAxiCcUser <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiCcValid <- mkDWire(False, clocked_by user_clk, reset_by user_reset); // RQ FIFO#(AxiStRq) fAxiRq <- mkRQBuffer(clocked_by user_clk, reset_by user_reset); Wire#(Bit#(64)) wAxiRqData <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiRqLast <- mkDWire(False, clocked_by user_clk, reset_by user_reset); Wire#(Bit#(2)) wAxiRqKeep <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bit#(60)) wAxiRqUser <- mkDWire(0, clocked_by user_clk, reset_by user_reset); Wire#(Bool) wAxiRqValid <- mkDWire(False, clocked_by user_clk, reset_by user_reset); // ---------------------------------------------------------------- // RULES // ---------------- // CQ (requests from host): here at 250 MHz we only collect the // info we need and pass it on; the actual parsing of descriptors // and payloads happens in the 125 MHz domain which can accommodate // more complex circuits. // Collect cq from AXI into FIFO fAxiCq (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cq_ready; pcie_ep.axi_cq.tready (duplicate (pack (fAxiCq.notFull))); endrule rule process_ax_cq_beat (pcie_ep.axi_cq.tvalid && fAxiCq.notFull); let cq = AxiStCq {data: pcie_ep.axi_cq.tdata, sop: unpack (pcie_ep.axi_cq.tuser [40]), // tuser.sop eop: pcie_ep.axi_cq.tlast, keep: pcie_ep.axi_cq.tkeep, first_be: pcie_ep.axi_cq.tuser [3:0], // tuser.first_be, last_be: pcie_ep.axi_cq.tuser [7:4]}; // tuser.last_be fAxiCq.enq (cq); endrule // ---------------- // RC (completions from host): here at 250 MHz we only collect the // info we need and pass it on; the actual parsing of descriptors // and payloads happens in the 125 MHz domain which can accommodate // more complex circuits (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rc_ready; pcie_ep.axi_rc.tready (duplicate (pack (fAxiRc.notFull))); endrule rule process_ax_rc_beat (pcie_ep.axi_rc.tvalid && fAxiRc.notFull); let rc = AxiStRc {data:pcie_ep.axi_rc.tdata, sop: unpack (pcie_ep.axi_rc.tuser [32]), // tuser.is_sof_0 eop: pcie_ep.axi_rc.tlast, keep:pcie_ep.axi_rc.tkeep, be: truncate (pcie_ep.axi_rc.tuser [31:0])}; // tuser.byte_en fAxiRc.enq (rc); endrule // Move rc from FIFO fAxiRc_a to fAxiRc_b, injecting an 'empty' // pad, if necessary, to ensure that sop is on an even enq // ---------------- // CC (completions to host): here at 250 MHz we just pass on the // info we get from the bridge, which was created at 125 MHz. (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_cc; pcie_ep.axi_cc.tdata (wAxiCcData); pcie_ep.axi_cc.tkeep (wAxiCcKeep); pcie_ep.axi_cc.tlast (wAxiCcLast); pcie_ep.axi_cc.tuser (wAxiCcUser); pcie_ep.axi_cc.tvalid (wAxiCcValid); endrule (* fire_when_enabled *) rule drive_axi_cc_info (pcie_ep.axi_cc.tready != 0); let cc <- toGet (fAxiCc).get; wAxiCcValid <= True; wAxiCcLast <= cc.last; wAxiCcData <= cc.data; wAxiCcKeep <= cc.keep; wAxiCcUser <= 0; // tuser.discontinue and tuser.parity[31:0] endrule // ---------------- // RQ (requests to host): here at 250 MHz we just pass on the // info we get from the bridge, which was created at 125 MHz. (* fire_when_enabled, no_implicit_conditions *) rule drive_axi_rq; pcie_ep.axi_rq.tdata (wAxiRqData); pcie_ep.axi_rq.tkeep (wAxiRqKeep); pcie_ep.axi_rq.tlast (wAxiRqLast); pcie_ep.axi_rq.tuser (wAxiRqUser); pcie_ep.axi_rq.tvalid (wAxiRqValid); endrule (* fire_when_enabled *) rule drive_axi_rq_info (pcie_ep.axi_rq.tready != 0); let rq <- toGet (fAxiRq).get; wAxiRqValid <= True; wAxiRqData <= rq.data; wAxiRqLast <= rq.last; wAxiRqKeep <= rq.keep; wAxiRqUser <= { 0, rq.last_be, rq.first_be}; endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface pcie = pcie_ep.pcie; interface uclk = user_clk; interface ureset = user_reset; interface uclk_half = user_clk_half; interface ureset_half = user_reset_half; interface PCIE3_STATUS_V7 status; method lnk_up = pcie_ep.status.lnk_up; method app_rdy = pcie_ep.status.app_rdy; method max_payload = pcie_ep.status.max_payload; method max_read_req = pcie_ep.status.max_read_req; method rcb_status = pcie_ep.status.rcb_status; method function_status = pcie_ep.status.function_status; endinterface interface cq_recv = toGet (fAxiCq); interface rc_recv = toGet (fAxiRc); interface cc_xmit = toPut (fAxiCc); interface rq_xmit = toPut (fAxiRq); interface cfg_interrupt = pcie_ep.cfg_interrupt; interface cfg_interrupt_msix = pcie_ep.cfg_interrupt_msix; endmodule // ================================================================ // Connecting/converting stream AxiCq ==> stream TLPData#(16) instance ConnectableWithClocks #(Get #(AxiStCq), Put #(TLPData #(16))); module mkConnectionWithClocks #(Get #(AxiStCq) g, Put #(TLPData #(16)) p, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); // Data path: g -> gearbox_1_2 -> f_cq -> p Reg #(Bool) rg_even_enq <- mkReg (True, clocked_by fastClock, reset_by fastReset); Reg #(Bool) rg_pad_odd_tail <- mkReg (False, clocked_by fastClock, reset_by fastReset); // Buffer incoming messages for timing FIFO #(AxiStCq) in_buf <- mkFIFO(clocked_by fastClock, reset_by fastReset); mkConnection(g, toPut(in_buf)); let g_buf = toGet(in_buf); Gearbox #(1, 2, AxiStCq) gearbox <- mk1toNGearbox (fastClock, fastReset, slowClock, slowReset); // f_cq provides one extra level of buffering, allowing us to // examine 3 AxiStCqs (two at head of f_cq, and one at head of // gearbox). This is needed for write packets, where we have to // look descriptor (64b,64b) + 32b data (1st. half of 3rd 64b) FIFOF #(Vector #(2, AxiStCq)) f_cq <- mkPipelineFIFOF (clocked_by slowClock, reset_by slowReset); // ---------------- // g -> gearbox // If eop happens on an even enq, we insert a dummy odd enq, for two reasons: // (1) sop is always an even enq, so it is in element [0] of the gearbox output // (2) to avoid deadlock/delay: the gearbox output does not show // up until it has received both an even and an odd enq // Incoming AxiStCq: g ==> gearbox (fast clock) rule rl_g_to_gearbox (! rg_pad_odd_tail); let cq <- g_buf.get; // Assert: cq.sop => rg_even_enq Vector #(1, AxiStCq) v1 = replicate (cq); gearbox.enq (v1); rg_pad_odd_tail <= (cq.eop && rg_even_enq); rg_even_enq <= ! rg_even_enq; endrule rule rl_g_to_gearbox_pad_odd_tail (rg_pad_odd_tail); AxiStCq cq = unpack (0); Vector #(1, AxiStCq) v1 = replicate (cq); gearbox.enq (v1); rg_pad_odd_tail <= False; rg_even_enq <= True; endrule // ---------------- // gearbox -> f_cq (slow clock) rule rl_slowclock; Vector #(2, AxiStCq) v2 = gearbox.first; gearbox.deq; f_cq.enq (v2); endrule Reg #(DWCount) rg_dwcount <- mkRegU (clocked_by slowClock, reset_by slowReset); CQDescriptor cq_desc = unpack ({ f_cq.first [1].data, f_cq.first [0].data }); // 'Write' headers rule rl_wr_header (f_cq.first [0].sop && ((cq_desc.reqtype == MEMORY_WRITE) || (cq_desc.reqtype == IO_WRITE))); // Consume 1st 32b of data of next axi beat (head of gearbox FIFO) // Note: gearbox.first will move into f_cq, where remaining 32 bits will be consumed Bit #(32) data = gearbox.first [0].data [31:0]; // this takes the data in the Xilinx byte order and converts it TLPData #(16) tlp16 = convertCQDescriptorToTLP16 (cq_desc, data, f_cq.first [0].first_be, f_cq.first [0].last_be); p.put (tlp16); rg_dwcount <= cq_desc.dwcount - 1; // Since first DW is in the tlp16 f_cq.deq; endrule // 'Read' headers rule rl_rd_header (f_cq.first [0].sop && ((cq_desc.reqtype == MEMORY_READ) || (cq_desc.reqtype == IO_READ))); Bit #(32) data = 0; // don't care, but set to 0 for deterministic debugging TLPData #(16) tlp16 = convertCQDescriptorToTLP16 (cq_desc, data, f_cq.first [0].first_be, f_cq.first [0].last_be); p.put (tlp16); f_cq.deq; endrule // 'Write' data payload; no data remaining rule rl_data_0 ((! f_cq.first [0].sop) && (rg_dwcount == 0)); // f_cq.first [0].data [31:0] already consumed // f_cq.first [0].data [64:32] and f_cq.first [1].data [64:0] are just padding f_cq.deq; endrule // 'Write' data payload 1 to 3 DWs remaining rule rl_data_1_to_3 ((! f_cq.first [0].sop) && (rg_dwcount > 0) && (rg_dwcount < 4)); Bit #(16) be16 = 0; case (rg_dwcount) 1: be16 = 16'hF000; 2: be16 = 16'hFF00; 3: be16 = 16'hFFF0; endcase Vector#(4, Bit#(32)) data_vec = replicate(0); data_vec[3] = convertDW(f_cq.first [0].data [63:32]) ; data_vec[2] = convertDW(f_cq.first [1].data [31:0]) ; data_vec[1] = convertDW(f_cq.first [1].data [63:32]) ; TLPData #(16) tlp16 = TLPData {sof: False, eof: True, hit: 0, be: be16, data: pack(data_vec)}; p.put (tlp16); f_cq.deq; rg_dwcount <= 0; endrule // 'Write' data payload >= 4 DWs remaining rule rl_data_4 ((! f_cq.first [0].sop) && (rg_dwcount > 3)); Vector#(4, Bit#(32)) data_vec; data_vec[3] = convertDW(f_cq.first [0].data [63:32]) ; data_vec[2] = convertDW(f_cq.first [1].data [31:0]) ; data_vec[1] = convertDW(f_cq.first [1].data [63:32]) ; data_vec[0] = convertDW(gearbox.first [0].data [31:0]) ; TLPData #(16) tlp16 = TLPData {sof: False, eof: (rg_dwcount == 4), hit: 0, be: '1, data: pack(data_vec)}; p.put (tlp16); f_cq.deq; rg_dwcount <= rg_dwcount - 4; endrule endmodule endinstance instance ConnectableWithClocks #(Put #(TLPData #(16)), Get #(AxiStCq)); module mkConnectionWithClocks #(Put #(TLPData #(16)) p, Get #(AxiStCq) g, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); mkConnectionWithClocks (g, p, fastClock, fastReset, slowClock, slowReset); endmodule endinstance // ================================================================ // Connecting/converting stream AxiCc <== stream TLPData#(16) instance ConnectableWithClocks #(Get #(TLPData #(16)), Put #(AxiStCc)); module mkConnectionWithClocks #(Get #(TLPData #(16)) g, Put #(AxiStCc) p, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); // Data path: p <- gearbox_1_2 <- f_tlps <- g FIFOF #(TLPData #(16)) f_tlps <- mkPipelineFIFOF (clocked_by slowClock, reset_by slowReset); Gearbox #(2, 1, AxiStCc) gearbox <- mkNto1Gearbox (slowClock, slowReset, fastClock, fastReset); Reg #(DWCount) rg_dwcount <- mkReg (0, clocked_by slowClock, reset_by slowReset); // ---------------- // f_tlps <== g // This step would not be necessary if we could examine the .sof // of g.get tlp without dequeueing. // TODO: is this redundant with rg_dwcount == 0? i.e., does sof <=> (rg_dwcount == 0)? rule rl_get_tlps; // (slow clock) let tlp <- g.get; f_tlps.enq (tlp); endrule // ---------------- // gearbox <== f_tlps for completion header (slow clock) rule rl_header (f_tlps.first.sof); Vector #(2, AxiStCc) v2 = newVector; // this returns the data in the Xilinx byte order match { .cc_desc, .dw } = convertTLP16ToCCDescriptor (f_tlps.first); rg_dwcount <= cc_desc.dwcount - 1; // since AxiStCC contains first DW v2[0] = AxiStCc {data: pack (cc_desc) [63:0], last: False, keep: 2'b11 }; v2[1] = AxiStCc {data: { dw, pack (cc_desc) [95:64] }, last: f_tlps.first.eof, keep: 2'b11 }; gearbox.enq (v2); f_tlps.deq; endrule // ---------------- // gearbox <== f_tlps for data (slow clock) rule rl_data ((! f_tlps.first.sof) && (rg_dwcount != 0)); Vector #(2, AxiStCc) v2 = newVector; Bit #(128) x = f_tlps.first.data; v2[0] = AxiStCc {data: { convertDW(x[95:64]), convertDW(x[127:96]) }, last: (rg_dwcount <= 2), keep: ((rg_dwcount == 1) ? 2'b01 : 2'b11) }; v2[1] = AxiStCc {data: { convertDW(x[31:0]), convertDW(x[63:32]) }, last: (rg_dwcount <= 4), keep: ((rg_dwcount <= 2) ? 2'b00 : ((rg_dwcount == 3) ? 2'b01 : 2'b11)) }; gearbox.enq (v2); rg_dwcount <= ((rg_dwcount < 4) ? 0 : (rg_dwcount - 4)); f_tlps.deq; endrule // ---------------- // Move out of head of gearbox (fast clock) rule rl_fastclock; AxiStCc x = gearbox.first[0]; gearbox.deq; // do not propagate empty beats if (x.keep != 0) p.put (x); endrule endmodule endinstance instance ConnectableWithClocks #(Put #(AxiStCc), Get #(TLPData #(16))); module mkConnectionWithClocks #(Put #(AxiStCc) p, Get #(TLPData #(16)) g, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); mkConnectionWithClocks (g, p, fastClock, fastReset, slowClock, slowReset); endmodule endinstance // ================================================================ // Connecting/converting stream AxiRq <== stream TLPData#(16) instance ConnectableWithClocks #(Get #(TLPData #(16)), Put #(AxiStRq)); module mkConnectionWithClocks #(Get #(TLPData #(16)) g, Put #(AxiStRq) p, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); // Data path: p <- gearbox_1_2 <- f_tlps <- g FIFOF #(TLPData #(16)) f_tlps <- mkPipelineFIFOF (clocked_by slowClock, reset_by slowReset); Gearbox #(2, 1, AxiStRq) gearbox <- mkNto1Gearbox (slowClock, slowReset, fastClock, fastReset); Reg #(DWCount) rg_dwcount <- mkReg (0, clocked_by slowClock, reset_by slowReset); // This stores an extra data word, in the converted Xilinx byte order Reg #(Maybe #(Bit #(32))) rg_mdw <- mkRegU (clocked_by slowClock, reset_by slowReset); // Record the first and last BE from header // so that we hold the value for the entire packet Reg #(Bit# (4)) rg_first_be <- mkRegU (clocked_by slowClock, reset_by slowReset); Reg #(Bit# (4)) rg_last_be <- mkRegU (clocked_by slowClock, reset_by slowReset); // ---------------- // Move tlps from g into f_tlps // This step would not be necessary if we could examine the .sof // of g.get tlp without dequeueing. // TODO: is this redundant with rg_dwcount == 0? i.e., does sof <=> (rg_dwcount == 0)? rule rl_get_tlps; // (slow clock) let tlp <- g.get; f_tlps.enq (tlp); endrule // ---------------- // Move header into gearbox (slow clock) rule rl_header (rg_mdw matches tagged Invalid &&& f_tlps.first.sof); Vector #(2, AxiStRq) v2 = newVector; // this returns the data in the Xilinx byte order match { .rq_desc, .first_be, .last_be, .mdata } = convertTLP16ToRQDescriptor (f_tlps.first); rg_dwcount <= ((rq_desc.reqtype == MEMORY_WRITE) ? rq_desc.dwcount : 0); rg_mdw <= mdata; rg_first_be <= first_be; rg_last_be <= last_be; v2[0] = AxiStRq {data: pack (rq_desc) [63:0], last: False, keep: 2'b11, first_be: first_be, last_be: last_be }; v2[1] = AxiStRq {data: pack (rq_desc) [127:64], last: f_tlps.first.eof && !isValid(mdata), keep: 2'b11, first_be: first_be, last_be: last_be }; gearbox.enq (v2); f_tlps.deq; endrule // ---------------- // Move write-payload into gearbox (slow clock) // rg_mdw contains last DW rule rl_data_a (rg_mdw matches tagged Valid .dw &&& (rg_dwcount == 1)); Vector #(2, AxiStRq) v2 = newVector; v2[0] = AxiStRq {data: { 32'b0, dw }, last: True, keep: 2'b01, first_be: rg_first_be, last_be: rg_last_be }; v2[1] = AxiStRq {data: 0, last: True, keep: 2'b00, first_be: rg_first_be, last_be: rg_last_be }; gearbox.enq (v2); rg_dwcount <= 0; rg_mdw <= tagged Invalid; endrule // rg_mdw contains DW, and there are more DWs rule rl_data_b (rg_mdw matches tagged Valid .dw &&& (rg_dwcount != 1)); Vector #(2, AxiStRq) v2 = newVector; Bit #(128) x = f_tlps.first.data; v2[0] = AxiStRq {data: { convertDW(x[127:96]), dw }, last: (rg_dwcount == 2), keep: 2'b11, first_be: rg_first_be, last_be: rg_last_be }; v2[1] = AxiStRq {data: { convertDW(x[63:32]), convertDW(x[95:64]) }, last: (rg_dwcount <= 4), keep: ((rg_dwcount == 2) ? 2'b00 : ((rg_dwcount == 3) ? 2'b01 : 2'b11)), first_be: rg_first_be, last_be: rg_last_be }; gearbox.enq (v2); if (rg_dwcount <= 4) begin rg_dwcount <= 0; rg_mdw <= tagged Invalid; end else begin rg_dwcount <= rg_dwcount - 4; rg_mdw <= tagged Valid convertDW(x [31:0]); end f_tlps.deq; endrule // rg_mdw is Invalid, and there are more DWs rule rl_data_c (rg_mdw matches tagged Invalid &&& (! f_tlps.first.sof) &&& (rg_dwcount != 0)); Vector #(2, AxiStRq) v2 = newVector; Bit #(128) x = f_tlps.first.data; v2[0] = AxiStRq {data: { convertDW(x[95:64]), convertDW(x[127:96]) }, last: (rg_dwcount <= 2), keep: ((rg_dwcount == 1) ? 2'b01 : 2'b11), first_be: rg_first_be, last_be: rg_last_be }; v2[1] = AxiStRq {data: { convertDW(x[31:0]), convertDW(x[63:32]) }, last: (rg_dwcount <= 4), keep: ((rg_dwcount <= 2) ? 2'b00 : ((rg_dwcount == 3) ? 2'b01 : 2'b11)), first_be: rg_first_be, last_be: rg_last_be }; gearbox.enq (v2); rg_dwcount <= ((rg_dwcount < 4) ? 0 : (rg_dwcount - 4)); f_tlps.deq; endrule // ---------------- // Move out of head of gearbox (fast clock) rule rl_fastclock; AxiStRq x = gearbox.first[0]; gearbox.deq; // do not propagate empty beats if (x.keep != 0) p.put (x); endrule endmodule endinstance instance ConnectableWithClocks #(Put #(AxiStRq), Get #(TLPData #(16))); module mkConnectionWithClocks #( Put #(AxiStRq) p, Get #(TLPData #(16)) g, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); mkConnectionWithClocks (g, p, fastClock, fastReset, slowClock, slowReset); endmodule endinstance // ================================================================ // Connecting/converting stream AxiRc ==> stream TLPData#(16) instance ConnectableWithClocks #(Get #(AxiStRc), Put #(TLPData #(16))); module mkConnectionWithClocks #(Get #(AxiStRc) g, Put #(TLPData #(16)) p, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); // Data path: g -> gearbox_1_2 -> p Reg #(Bool) rg_even_enq <- mkReg (True, clocked_by fastClock, reset_by fastReset); Reg #(Bool) rg_pad_odd_tail <- mkReg (False, clocked_by fastClock, reset_by fastReset); // Buffer incoming messages for timing FIFO #(AxiStRc) in_buf <- mkFIFO(clocked_by fastClock, reset_by fastReset); mkConnection(g, toPut(in_buf)); let g_buf = toGet(in_buf); Gearbox #(1, 2, AxiStRc) gearbox <- mk1toNGearbox (fastClock, fastReset, slowClock, slowReset); // ---------------- // g -> gearbox // If eop happens on an even enq, we insert a dummy odd enq, for two reasons: // (1) sop is always an even enq, so it is in element [0] of the gearbox output // (2) to avoid deadlock/delay: the gearbox output does not show // up until it has received both an even and an odd enq // Incoming AxiStRc: g ==> gearbox (fast clock) rule rl_g_to_gearbox (! rg_pad_odd_tail); let rc <- g_buf.get; // Assert: rc.sop => rg_even_enq Vector #(1, AxiStRc) v1 = replicate (rc); gearbox.enq (v1); rg_pad_odd_tail <= (rc.eop && rg_even_enq); rg_even_enq <= ! rg_even_enq; endrule rule rl_g_to_gearbox_pad_odd_tail (rg_pad_odd_tail); AxiStRc rc = unpack (0); Vector #(1, AxiStRc) v1 = replicate (rc); gearbox.enq (v1); rg_pad_odd_tail <= False; rg_even_enq <= True; endrule // ---------------- // gearbox -> f_cq (slow clock) Reg #(DWCount) rg_dwcount <- mkRegU (clocked_by slowClock, reset_by slowReset); // 3DW Header + 1DW data: gearbox ==> p rule rl_header (gearbox.first [0].sop); RCDescriptor rc_desc = unpack ({ gearbox.first [1].data [31:0], gearbox.first [0].data }); Bit #(32) data = gearbox.first [1].data [63:32]; // this takes the data in Xilinx byte order and converts it TLPData #(16) tlp16 = convertRCDescriptorToTLP16 (rc_desc, data); p.put (tlp16); rg_dwcount <= (rc_desc.dwcount == 0) ? 0 : rc_desc.dwcount - 1; gearbox.deq; endrule // Data payload: gearbox => p rule rl_data_a ((! (gearbox.first [0].sop)) && (rg_dwcount != 0)); Bit #(16) be16; case (rg_dwcount) 1: be16 = 16'hF000; 2: be16 = 16'hFF00; 3: be16 = 16'hFFF0; default: be16 = 16'hFFFF; endcase Vector#(4, Bit#(32)) data_vec; data_vec[3] = convertDW(gearbox.first [0].data [31:0]); data_vec[2] = convertDW(gearbox.first [0].data [63:32]); data_vec[1] = convertDW(gearbox.first [1].data [31:0]); data_vec[0] = convertDW(gearbox.first [1].data [63:32]); TLPData #(16) tlp16 = TLPData {sof: False, eof: (rg_dwcount <= 4), hit: 0, be: be16, data: pack(data_vec)}; p.put (tlp16); gearbox.deq; rg_dwcount <= ((rg_dwcount < 4) ? 0 : rg_dwcount - 4); endrule endmodule endinstance instance ConnectableWithClocks #(Put #(TLPData #(16)), Get #(AxiStRc)); module mkConnectionWithClocks #(Put #(TLPData #(16)) p, Get #(AxiStRc) g, Clock fastClock, Reset fastReset, Clock slowClock, Reset slowReset) (Empty); mkConnectionWithClocks (g, p, fastClock, fastReset, slowClock, slowReset); endmodule endinstance // ================================================================ // Tie-offs for unused interfaces instance TieOff #(PCIE3_INT_V7); module mkTieOff #(PCIE3_INT_V7 ifc) (Empty); rule tie_off_inputs; ifc.int_vect (0); ifc.pending (0); endrule endmodule endinstance instance TieOff #(PCIE3_INT_MSIX_V7); module mkTieOff #(PCIE3_INT_MSIX_V7 ifc) (Empty); rule tie_off_inputs; ifc.valid (0); ifc.data (0); ifc.address (0); endrule endmodule endinstance // ================================================================ // PCIE3 AXI-Stream Descriptor Formats typedef struct { ReservedZero#(1) r1; TLPAttrIDBasedOrdering idbased; TLPAttrRelaxedOrdering relaxed; TLPAttrNoSnoop nosnoop; TLPTrafficClass tclass; BARAperture aperture; BARID barid; TargetFunction targetfn; TLPTag tag; PciId reqid; ReservedZero#(1) r2; RequestType reqtype; DWCount dwcount; DWAddress64 address; TLPAddressType addrtype; } CQDescriptor deriving (Bits, Eq); typedef struct { Bool forceecrc; TLPAttrIDBasedOrdering idbased; TLPAttrRelaxedOrdering relaxed; TLPAttrNoSnoop nosnoop; TLPTrafficClass tclass; Bool compliden; PciId complid; TLPTag tag; PciId reqid; ReservedZero#(1) r1; TLPPoison poisoned; TLPCompletionStatus status; DWCount dwcount; ReservedZero#(2) r2; Bool lockedcmpl; ByteCount bytecount; ReservedZero#(6) r3; TLPAddressType addrtype; ReservedZero#(1) r4; TLPLowerAddr loweraddr; } CCDescriptor deriving (Bits, Eq); typedef struct { Bool forceecrc; TLPAttrIDBasedOrdering idbased; TLPAttrRelaxedOrdering relaxed; TLPAttrNoSnoop nosnoop; TLPTrafficClass tclass; Bool reqiden; PciId complid; TLPTag tag; PciId reqid; TLPPoison poisoned; RequestType reqtype; DWCount dwcount; DWAddress64 address; TLPAddressType addrtype; } RQDescriptor deriving (Bits, Eq); typedef struct { ReservedZero#(1) r1; TLPAttrIDBasedOrdering idbased; TLPAttrRelaxedOrdering relaxed; TLPAttrNoSnoop nosnoop; TLPTrafficClass tclass; ReservedZero#(1) r2; PciId complid; TLPTag tag; PciId reqid; ReservedZero#(1) r3; TLPPoison poisoned; TLPCompletionStatus status; DWCount dwcount; ReservedZero#(1) r4; Bool reqcompleted; Bool lockedcmpl; ByteCount bytecount; ErrorCode errcode; Bit#(12) loweraddr; } RCDescriptor deriving (Bits, Eq); // ------------------------- // Conversion functions for PCIE3 AXI-Stream descriptors. One thing to note // here is that the TLPData#(n).be field is only ever set in the logic that // utilizes these functions. It was a required field for the original PCIE // design by Xilinx, but is no longer used for PCIE3. Therefore, the .be // field will not be assigned in the TLPData#(n) type for traffic going to // the DMA and CSR blocks. function TLPData#(16) convertCQDescriptorToTLP16(CQDescriptor desc, Bit#(32) data, TLPFirstDWBE first, TLPLastDWBE last); TLPMemoryIO3DWHeader header = defaultValue; header.format = tpl_1(convertCQReqTypeToTLPFmtType(desc.reqtype)); header.pkttype = tpl_2(convertCQReqTypeToTLPFmtType(desc.reqtype)); header.tclass = desc.tclass; header.relaxed = desc.relaxed; header.nosnoop = desc.nosnoop; header.length = (desc.dwcount == 1024) ? 0 : truncate(desc.dwcount); header.reqid = desc.reqid; header.tag = desc.tag; header.lastbe = last; header.firstbe = first; header.addr = truncate(desc.address); header.data = convertDW(data); Bool is3DW = isReadReqType(desc.reqtype); Bool is3Or4DW = isReadReqType(desc.reqtype) || (desc.dwcount == 1); TLPData#(16) retval = defaultValue; retval.sof = True; retval.eof = is3Or4DW; retval.hit = (1 << pack(desc.barid)); retval.data = pack(header); retval.be = (is3DW ? 16'hFFF0 : 16'hFFFF); return retval; endfunction // this only expects Memory and IO types function Bool isReadReqType(RequestType t); return ((t == MEMORY_READ) || (t == IO_READ)); endfunction // this only expects Memory and IO types function Tuple2#(TLPPacketFormat,TLPPacketType) convertCQReqTypeToTLPFmtType(RequestType t); case (t) MEMORY_READ : return tuple2(MEM_READ_3DW_NO_DATA, MEMORY_READ_WRITE); MEMORY_WRITE : return tuple2(MEM_WRITE_3DW_DATA, MEMORY_READ_WRITE); IO_READ : return tuple2(MEM_READ_3DW_NO_DATA, IO_REQUEST); IO_WRITE : return tuple2(MEM_WRITE_3DW_DATA, IO_REQUEST); default : return ?; endcase endfunction function Tuple2#(CCDescriptor, Bit#(32)) convertTLP16ToCCDescriptor(TLPData#(16) header); TLPCompletionHeader cmplheader = unpack(header.data); CCDescriptor desc = unpack(0); desc.relaxed = cmplheader.relaxed; desc.nosnoop = cmplheader.nosnoop; desc.tclass = cmplheader.tclass; desc.compliden = False; desc.complid = cmplheader.cmplid; desc.tag = cmplheader.tag; desc.reqid = cmplheader.reqid; desc.poisoned = cmplheader.poison; desc.status = cmplheader.cstatus; desc.dwcount = (cmplheader.length == 0) ? 1024 : zeroExtend(cmplheader.length); desc.lockedcmpl = False; desc.bytecount = (cmplheader.bytecount == 0) ? 4096 : zeroExtend(cmplheader.bytecount); desc.loweraddr = cmplheader.loweraddr; return tuple2(desc, convertDW(cmplheader.data)); endfunction function TLPData#(16) convertRCDescriptorToTLP16(RCDescriptor desc, Bit#(32) data); TLPCompletionHeader header = defaultValue; header.tclass = desc.tclass; header.relaxed = desc.relaxed; header.nosnoop = desc.nosnoop; header.cmplid = desc.complid; header.tag = desc.tag; header.reqid = desc.reqid; header.poison = desc.poisoned; header.cstatus = desc.status; header.length = (desc.dwcount == 1024) ? 0 : truncate(desc.dwcount); header.bytecount = (desc.bytecount == 4096) ? 0 : truncate(desc.bytecount); header.loweraddr = truncate(desc.loweraddr); header.data = convertDW(data); Bool is3DW = (desc.dwcount == 0); Bool is3Or4DW = (desc.dwcount == 0) || (desc.dwcount == 1); TLPData#(16) retval = defaultValue; retval.sof = True; retval.eof = is3Or4DW; retval.hit = 1; // XXX retval.data = pack(header); retval.be = (is3DW ? 16'hFFF0 : 16'hFFFF); return retval; endfunction function Tuple4 #(RQDescriptor, TLPFirstDWBE, TLPLastDWBE, Maybe#(Bit#(32))) convertTLP16ToRQDescriptor (TLPData #(16) header); // Note: other than .addr and .data, remaining fields are same for // the two header formats below TLPMemoryIO3DWHeader header3dw = unpack(header.data); TLPMemory4DWHeader header4dw = unpack(header.data); RQDescriptor desc = unpack(0); Maybe#(Bit#(32)) data = tagged Invalid; desc.relaxed = header4dw.relaxed; desc.nosnoop = header4dw.nosnoop; desc.tclass = header4dw.tclass; desc.reqiden = False; desc.tag = header4dw.tag; desc.reqid = header4dw.reqid; desc.poisoned = header4dw.poison; case(header4dw.format) MEM_READ_3DW_NO_DATA: desc.reqtype = MEMORY_READ; MEM_READ_4DW_NO_DATA: desc.reqtype = MEMORY_READ; MEM_WRITE_3DW_DATA: desc.reqtype = MEMORY_WRITE; MEM_WRITE_4DW_DATA: desc.reqtype = MEMORY_WRITE; default: desc.reqtype = MEMORY_READ; endcase desc.dwcount = (header4dw.length == 0) ? 1024 : zeroExtend(header4dw.length); if (header4dw.format == MEM_WRITE_4DW_DATA || header4dw.format == MEM_READ_4DW_NO_DATA) begin desc.address = header4dw.addr; end else begin desc.address = zeroExtend(header3dw.addr); if (header3dw.format == MEM_WRITE_3DW_DATA) begin data = tagged Valid convertDW(header3dw.data); end end return tuple4 (desc, header4dw.firstbe, header4dw.lastbe, data); endfunction // Functions to convert between the byte order inside data words of // Xilinx AXI packets and PCIe TLP packets function Bit#(32) convertDW(Bit#(32) dw); Vector#(4, Bit#(8)) bytes = unpack(dw); return pack(reverse(bytes)); endfunction // ------------------------- // Buffer to hold at least one maximum size CC packet. // Max size = 3 Dword header + 1024 Dwords = 1027 Dwords. // At 64-bit beats, a buffer of 514 beats is needed. // module mkCCBuffer(FIFO#(AxiStCc)); function Bool isEOF(AxiStCc x) = x.last; (* hide *) let _buf <- mkAXISBuffer(516, isEOF); return _buf; endmodule // Buffer to hold at least one maximum size RQ packet. // Max size = 4 Dword header + 256 Dwords = 260 Dwords. // At 64-bit beats, a buffer of 130 beats is needed. // module mkRQBuffer(FIFO#(AxiStRq)); function Bool isEOF(AxiStRq x) = x.last; (* hide *) let _buf <- mkAXISBuffer(132, isEOF); return _buf; endmodule // The timing is tight through the core module, so we try to reduce the // path length with this wrapper that adds a buffer on both the // input and output. module mkAXISBuffer#( Integer depth , function Bool isEOF(t x) ) (FIFO#(t)) provisos (Bits#(t,tsz), Add#(1, j, tsz)); (* hide *) FIFO#(t) _core <- mkAXISBufferCore(depth, isEOF); FIFO#(t) in_buf <- mkFIFO; FIFO#(t) out_buf <- mkFIFO; (* fire_when_enabled *) rule moveIn; _core.enq(in_buf.first); in_buf.deq; endrule (* fire_when_enabled *) rule moveOut; out_buf.enq(_core.first); _core.deq; endrule method enq(x) = in_buf.enq(x); method first() = out_buf.first; method deq() = out_buf.deq; method Action clear(); _core.clear; in_buf.clear; out_buf.clear; endmethod endmodule module mkAXISBufferCore#( Integer depth , function Bool isEOF(t x) ) (FIFO#(t)) provisos (Bits#(t,tsz), Add#(1, j, tsz)); FIFO#(t) data_buf <- mkSizedBRAMFIFO(depth); FIFOF#(void) eof_buf <- mkSizedFIFOF(4); Bool has_data = eof_buf.notEmpty; method Action enq(t x); data_buf.enq(x); if (isEOF(x)) eof_buf.enq(?); endmethod method t first() if (has_data) = data_buf.first; method Action deq() if (has_data); data_buf.deq; if (isEOF(data_buf.first)) eof_buf.deq(); endmethod method Action clear(); data_buf.clear; eof_buf.clear; endmethod endmodule // ------------------------- endpackage: XilinxVirtex7PCIE ================================================ FILE: lib/bsv/YUV.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import Arith::*; // little endian RGB typedef struct { Bit#(8) r; Bit#(8) b; Bit#(8) g; } Rgb888 deriving (Bits); typedef struct { Bit#(1) vsync; Bit#(1) hsync; Bit#(1) de; pixelType pixel; } VideoData#(type pixelType) deriving (Bits); typedef struct { Bit#(8) y; Bit#(8) u; Bit#(8) v; } Yuv444 deriving (Bits); typedef struct { Bit#(8) y1; Bit#(8) u; Bit#(8) y2; Bit#(8) v; } Yuv422 deriving (Bits); typedef struct { Bit#(8) uv; Bit#(8) yy; } Yyuv deriving (Bits); interface Rgb888ToYuv422; method Action putRgb888(Rgb888 rgb888); method ActionValue#(Yuv422) getYuv422(); endinterface function Yuv444 rgbtoyuv(Rgb888 rgb); Bit#(16) y = 77*extend(rgb.r) + 150 * extend(rgb.g) + 29 * extend(rgb.b) + 0; Bit#(16) u = -43*extend(rgb.r) - 85*extend(rgb.g) + 128*extend(rgb.b) + 128; Bit#(16) v = 128*extend(rgb.r) - 107*extend(rgb.g) - 21*extend(rgb.b) + 128; return Yuv444 { y: truncate(y>>8), u: truncate(u >> 8), v: truncate(v >> 8) }; endfunction typedef Vector#(4, Vector#(3, Bit#(16))) Yuv444Intermediates; function Vector#(3, Bit#(n)) rgbToVector(Rgb888 rgb) provisos (Add#(a__, 8, n)); Vector#(3, Bit#(n)) vec; vec[0] = zeroExtend(rgb.r); vec[1] = zeroExtend(rgb.g); vec[2] = zeroExtend(rgb.b); return vec; endfunction function Yuv444 yuv444FromVector(Vector#(3, Bit#(n)) vec) provisos (Add#(a__, 8, n)); return Yuv444 { y: truncate(vec[0]), u: truncate(vec[1]), v: truncate(vec[2]) }; endfunction function Yuv444Intermediates rgbToYuvIntermediates(Rgb888 rgb); Vector#(3, Vector#(4, Bit#(16))) rgbv = replicate(append(rgbToVector(rgb), replicate(1))); Vector#(3, Vector#(4, Bit#(16))) coeffs = replicate(newVector()); coeffs[0][0] = 77; coeffs[0][1] = 150; coeffs[0][2] = 29; coeffs[0][3] = 0; coeffs[1][0] = -43; coeffs[1][1] = -85; coeffs[1][2] = 128; coeffs[1][3] = 128; coeffs[2][0] = 128; coeffs[2][1] = -107; coeffs[2][2] = -21; coeffs[2][3] = 128; return transpose(map(uncurry(vmul), zip(rgbv, coeffs))); endfunction function Yuv444 yuvIntermediatesToYuv444(Yuv444Intermediates w); Vector#(3, Bit#(16)) v0 = vadd(w[0], w[1]); Vector#(3, Bit#(16)) v1 = vadd(w[2], w[3]); return yuv444FromVector(vrshift(vadd(vadd(w[0], w[1]), vadd(w[2], w[3])), 8)); endfunction function Yuv422 yuv444toyuv422(Yuv444 yuv0, Yuv444 yuv1); Bit#(9) u = (extend(yuv0.u) + extend(yuv1.u)) >> 1; Bit#(9) v = (extend(yuv0.u) + extend(yuv1.v)) >> 1; return Yuv422 { y1: yuv0.y, u: truncate(u), y2: yuv1.y, v: truncate(v) }; endfunction ================================================ FILE: lib/cpp/connectal_conv.cpp ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "ConvIndication.h" #include "ConvRequest.h" #include "dmaManager.h" #include "connectal_conv.h" #define COUNTER_INTERVAL 100000 #define MIN_XFER 8 static ConvRequestProxy *convRequest; static DmaManager *dma; static sem_t outputp_sem; class ConvIndication : public ConvIndicationWrapper { ParamStruct *param; public: void outputp(uint32_t addr, float v) { if (param->elementSize_ == sizeof(float)) *(float *)(param->basePtr + addr) = v; else *(double *)(param->basePtr + addr) = v; sem_post(&outputp_sem); } ConvIndication(unsigned int id, ParamStruct *p) : ConvIndicationWrapper(id), param(p) {} }; static ConvIndication *indication; static void forward_kernel_hardware(ParamStruct *param, uint32_t p_limit, uint32_t q_limit, float temp, uint32_t bpx, uint32_t wpx, uint32_t outputp) { static int once = 1; if (once) { once = 0; printf("[%s:%d] create proxy\n", __FUNCTION__, __LINE__); indication = new ConvIndication(IfcNames_ConvIndicationH2S, param); convRequest = new ConvRequestProxy(IfcNames_ConvRequestS2H); dma = platformInit(); } if (param->objectId_ == -1) { param->objectId_ = dma->reference(param->portalFd_); ConnectalParamType hparam; hparam.bottom_hw = param->conv_in_height_ * param->conv_in_width_ * param->elementSize_; hparam.kernel_hw = param->kernel_h_ * param->kernel_w_ * param->elementSize_; hparam.in_group_size = param->conv_in_channels_ / param->group_; hparam.baseSize = param->elementSize_; hparam.conv_in_width = param->conv_in_width_ * param->elementSize_; hparam.kernel_w = param->kernel_w_ * param->elementSize_; hparam.objectId = param->objectId_; convRequest->init(hparam); } int len = q_limit* param->elementSize_; int alen = ((len + MIN_XFER - 1) / MIN_XFER) * MIN_XFER; convRequest->forward_kernel(p_limit, alen, alen != len, temp, bpx, wpx, outputp); sem_wait(&outputp_sem); } #define MIN(A,B) (((int)(A) < (int)(B)) ? (A) : (B)) #define MAX(A,B) (((int)(A) > (int)(B)) ? (A) : (B)) template void forward_kernel(const ParamType *param, int p_limit, int q_limit, float temp, CPtr bpx, CPtr wpx, CPtr outputp, int run_hardware) { int bottom_hw = param->conv_in_height_ * param->conv_in_width_ * param->elementSize_; int kernel_hw = param->kernel_h_ * param->kernel_w_ * param->elementSize_; int in_group_size = param->conv_in_channels_ / param->group_; // for each 'in_group', add contribution into convolution for (int k = 0; k < in_group_size; k++) { CPtr bpk = bpx, wpk = wpx; // Calculate single 2D filter convolution for (int p = 0; p < p_limit; p++) { CPtr bp = bpk, wp = wpk; for (int q = 0; q < q_limit; q++) { temp += *CACCESS(bp) * *CACCESS(wp); bp += param->elementSize_; wp += param->elementSize_; } bpk += param->conv_in_width_ * param->elementSize_; wpk += param->kernel_w_ * param->elementSize_; } bpx += bottom_hw; wpx += kernel_hw; } // Write convolution result into output (image, channel, y, x) if (run_hardware) { if (*CACCESS(outputp) != temp) printf("[%s:%d] [%lx] hardware %f software %f\n", __FUNCTION__, __LINE__, outputp, (double)*CACCESS(outputp), (double)temp); } else *CACCESS(outputp) = temp; } template void ParamType::forward_process(void) { ParamType *param = this; int out_group_size = conv_out_channels_ / group_; int in_group_size = conv_in_channels_ / group_; int bottom_hw = in_group_size * conv_in_height_ * conv_in_width_ * elementSize_; int kernel_hw = in_group_size * kernel_h_ * kernel_w_ * elementSize_; int output_hw = out_group_size * height_out_ * width_out_ * elementSize_; static int counter = 0; // For each input, ... CPtr bottom_data = bottom[0]; CPtr top_data = top[0]; for (int imageind_unused = 0; imageind_unused < bottom_size; ++imageind_unused) { // For each image in input batch for (int nunused = 0; nunused < num_; ++nunused) { CPtr biasptr = bias; // if group_ > 1, restrict connectivity to a subset of inputs CPtr wp_base = weight; for (int g = 0; g < group_; ++g) { CPtr outputp = top_data; CPtr wp_item = wp_base; // for each 'out_group', calculate convolution over input data for (int ounused = 0; ounused < out_group_size; ounused++) { CPtr bpg = bottom_data; const Dtype bias_val = bias ? *CACCESS(biasptr) : 0; if (bias) biasptr += elementSize_; // Scan over source 2D input data for (int y = 0; y < height_out_; y++) { CPtr bpx = bpg; for (int x = 0; x < width_out_; x++) { int run_hardware = (counter-- <= 0); int p_limit = MIN(kernel_h_ - pad_h_, conv_in_height_ - y * stride_h_); int q_limit = MIN(kernel_w_ - pad_w_, conv_in_width_ - x * stride_w_); if (run_hardware) { forward_kernel_hardware(this, p_limit, q_limit, bias_val, bpx, wp_item, outputp); counter = COUNTER_INTERVAL; } forward_kernel(this, p_limit, q_limit, bias_val, bpx, wp_item, outputp, run_hardware); outputp += elementSize_; bpx += stride_w_ * elementSize_; } bpg += conv_in_width_ * stride_h_ * elementSize_; } wp_item += kernel_hw; } bottom_data += bottom_hw; top_data += output_hw; wp_base += weight_offset_ * elementSize_; } } } } template void backward_bias(const ParamType *param, CPtr tptr) { int output_hw = param->height_out_ * param->width_out_ * param->elementSize_; for (int j = 0; j < param->num_output_ * param->elementSize_; j += param->elementSize_) { Dtype temp = 0; for (int i = 0; i < output_hw; i += param->elementSize_) { temp += *CACCESS(tptr) * *CACCESS(param->bias_multiplier_ + i); tptr += param->elementSize_; } *CACCESS(param->bias_diff + j) += temp; } } template void backward_kernel(const ParamType *param, int pad_x, int pad_y, int gchan, int wchan, Dtype chain_grad, CPtr bottom_bp, CPtr bottom_diff_bp) { int p_start = MAX(0, pad_y); int p_limit = MIN(param->kernel_h_ * param->elementSize_, param->conv_in_height_ * param->elementSize_ + pad_y); int q_start = MAX(0, pad_x); int q_limit = MIN(param->kernel_w_ * param->elementSize_, param->conv_in_width_ * param->elementSize_ + pad_x); for (int p = p_start; p < p_limit; p += param->elementSize_) { for (int q = q_start; q < q_limit; q += param->elementSize_) { int belement = gchan + p * param->conv_in_width_ + q; int welement = wchan + p * param->kernel_w_ + q; // gradient w.r.t. weight. Note that we will accumulate diffs. if (param->weight_diff) *CACCESS(param->weight_diff + welement) += *CACCESS(bottom_bp + belement) * chain_grad; // gradient w.r.t. bottom data, if necessary. if (bottom_diff_bp) *CACCESS(bottom_diff_bp + belement) += *CACCESS(param->weight + welement) * chain_grad; } } } template void ParamType::backward_process(void) { ParamType *param = this; int out_group_size = conv_out_channels_ / group_; int in_group_size = conv_in_channels_ / group_; int bottom_hw = conv_in_height_ * conv_in_width_ * elementSize_; int kernel_hw = kernel_h_ * kernel_w_ * elementSize_; int output_hw = height_out_ * width_out_ * elementSize_; int usable_height = conv_in_height_ + 2 * pad_h_ - kernel_h_; int usable_width = conv_in_width_ + 2 * pad_w_ - kernel_w_; memset(CACCESS(zero_region), 0, zero_region_len); // For all images CPtr toff = top_diff[0]; CPtr bottom_ptr = bottom[0]; CPtr bottom_diff_ptr = bottom_diff[0]; for (int imageind_unused = 0; imageind_unused < top_size; ++imageind_unused) { int gbase = 0; for (int n = 0; n < num_; ++n) { // Bias gradient, if necessary. if (bias_diff) backward_bias(this, toff); int wbase = 0; for (int g = 0; g < group_; ++g) { int wchan = wbase; for (int outindex = 0; outindex < out_group_size; ++outindex) { int gchan = gbase; for (int cchan = 0; cchan < in_group_size; ++cchan) { for (int y = 0; y <= usable_height; y += stride_h_){ for (int x = 0; x <= usable_width; x += stride_w_) { Dtype chain_grad = *CACCESS(toff + ((y * (usable_width + stride_w_) / stride_h_ + x) / stride_w_) * elementSize_); int pad_x = (pad_w_ - x) * elementSize_; int pad_y = (pad_h_ - y) * elementSize_; if (chain_grad != 0.0) backward_kernel(this, pad_x, pad_y, gchan - pad_y * conv_in_width_ - pad_x, wchan, chain_grad, bottom_ptr, bottom_diff_ptr); } } wchan += kernel_hw; gchan += bottom_hw; } toff += output_hw; } gbase += in_group_size * bottom_hw; wbase += weight_offset_ * elementSize_; } } bottom_ptr += num_ * in_group_size * bottom_hw; bottom_diff_ptr += num_ * in_group_size * bottom_hw; } } extern "C" void *alloc_connectal_conv(int size) { if (size == sizeof(float)) return new ParamType(size); else return new ParamType(size); } extern "C" void *alloc_portalMem(size_t size, int cached, int *fdptr) { int fd = portalAlloc(size, cached); if (fdptr) *fdptr = fd; return portalMmap(fd, size); } //int portalCacheFlush(int fd, void *__p, long size, int flush) ================================================ FILE: lib/cpp/connectal_conv.h ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef __CONNECTAL_CONV_H__ #define __CONNECTAL_CONV_H__ #include #include #define CACCESS(A) ((Dtype *)(param->basePtr + (A))) typedef unsigned long CPtr; class ParamStruct { public: volatile uint8_t *basePtr; CPtr *bottom; CPtr *top_diff; CPtr *bottom_diff; CPtr *top; CPtr bias_multiplier_; CPtr weight; CPtr bias; CPtr weight_diff; CPtr bias_diff; CPtr zero_region; int zero_region_len; int top_size; int bottom_size; int weight_diff_count; int num_; int num_output_; int group_; int height_out_, width_out_; int kernel_h_, kernel_w_; int conv_in_height_, conv_in_width_; int conv_in_channels_, conv_out_channels_; int weight_offset_; int pad_h_, pad_w_; int stride_h_, stride_w_; int portalFd_; int propdone_; int objectId_; int elementSize_; ParamStruct(): bottom(NULL), top_diff(NULL), bottom_diff(NULL), top(NULL), bias_multiplier_(0), weight(0), bias(0), weight_diff(0), bias_diff(0), zero_region(0), zero_region_len(0), top_size(0), bottom_size(0), weight_diff_count(0), num_(0), num_output_(0), group_(0), height_out_(0), width_out_(0), kernel_h_(0), kernel_w_(0), conv_in_height_(0), conv_in_width_(0), conv_in_channels_(0), conv_out_channels_(0), weight_offset_(0), pad_h_(0), pad_w_(0), stride_h_(0), stride_w_(0), portalFd_(-1), propdone_(0), objectId_(-1), elementSize_(0) { } }; template class ParamType: public ParamStruct { public: ParamType(int size) { elementSize_ = size; } virtual void forward_process(void); virtual void backward_process(void); }; class ConnectalMemory { public: ConnectalMemory() : buffer_ptr_(NULL), cpu_ptr_(NULL), size_(0), head_(UNINITIALIZED), own_cpu_data_(false), controlFd_(-1) {} explicit ConnectalMemory(size_t size) : buffer_ptr_(NULL), cpu_ptr_(NULL), size_(size), head_(UNINITIALIZED), own_cpu_data_(false), controlFd_(-1) {} ~ConnectalMemory(); const void* cpu_data(); void set_cpu_data(void* data); const void* gpu_data() { printf("[%s:%d]\n", __FUNCTION__, __LINE__); exit(-1); return NULL; } void* mutable_cpu_data(); void* mutable_gpu_data() { printf("[%s:%d]\n", __FUNCTION__, __LINE__); exit(-1); return NULL; } enum ConnectalHead { UNINITIALIZED, HEAD_AT_CPU, SYNCED }; ConnectalHead head() { return head_; } size_t size() { return size_; } private: void to_cpu(); void to_gpu(); void* buffer_ptr_; void* cpu_ptr_; size_t size_; ConnectalHead head_; bool own_cpu_data_; int controlFd_; private: // Disable the copy and assignment operator for a class. ConnectalMemory(const ConnectalMemory&); ConnectalMemory& operator=(const ConnectalMemory&); }; // class ConnectalMemory void init_connectal_conv_library(int size); void *connectal_conv_library_param(int size); void *alloc_portal_memory(size_t size, int cached, int *fdptr); #ifdef DECLARE_CONNECTAL_CONV typedef void *(*ALLOCPARAM)(int size); typedef void *(*ALLOCMEM)(size_t size, int cached, int *fdptr); static ALLOCPARAM creatme; static ALLOCMEM pAlloc; void init_connectal_conv_library() { static void *handle; if (!handle) { char *libname = getenv("CONNECTAL_CONV_LIBRARY"); if (!libname) { printf("%s: The environment variable CONNECTAL_CONV_LIBRARY must contain the filename of the shared library for connectal conv support\n", __FUNCTION__); exit(-1); } printf("%s: libname is %s\n", __FUNCTION__, libname); handle = dlopen(libname, RTLD_NOW); if (handle) { creatme = (ALLOCPARAM)dlsym(handle,"alloc_connectal_conv"); pAlloc = (ALLOCMEM)dlsym(handle,"alloc_portalMem"); } else { printf("%s: dlopen(%s) failed, %s", __FUNCTION__, libname, dlerror()); exit(-1); } if (!creatme || !pAlloc) { printf("%s: dlsym('alloc_connectal_conv') failed, %s", __FUNCTION__, dlerror()); exit(-1); } } } void *connectal_conv_library_param(int size) { init_connectal_conv_library(); return creatme(size); } ConnectalMemory::~ConnectalMemory() { if (cpu_ptr_ && own_cpu_data_) { free(buffer_ptr_); buffer_ptr_ = NULL; } } inline void ConnectalMemory::to_cpu() { switch (head_) { case UNINITIALIZED: buffer_ptr_ = malloc(size_); cpu_ptr_ = buffer_ptr_; memset(cpu_ptr_, 0, size_); head_ = HEAD_AT_CPU; own_cpu_data_ = true; break; case HEAD_AT_CPU: case SYNCED: break; } } const void* ConnectalMemory::cpu_data() { to_cpu(); return (const void*)cpu_ptr_; } void ConnectalMemory::set_cpu_data(void* data) { CHECK(data); //printf("[%s:%d] prev %p new %p\n", __FUNCTION__, __LINE__, cpu_ptr_, data); if (buffer_ptr_) memcpy(data, buffer_ptr_, size_); if (own_cpu_data_) { free(buffer_ptr_); buffer_ptr_ = NULL; //close(controlFd_); } cpu_ptr_ = data; head_ = HEAD_AT_CPU; own_cpu_data_ = false; } void* ConnectalMemory::mutable_cpu_data() { to_cpu(); head_ = HEAD_AT_CPU; return cpu_ptr_; } void *alloc_portal_memory(size_t size, int cached, int *fdptr) { init_connectal_conv_library(); return pAlloc(size, cached, fdptr); } #endif #endif // __CONNECTAL_CONV_H__ ================================================ FILE: lib/cpp/connectal_convmm.cpp ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include "connectal_conv.h" template void ParamType::im2col_cpu(const Dtype* data_im) { int height_col = (conv_in_height_ + 2 * pad_h_ - kernel_h_) / stride_h_ + 1; int width_col = (conv_in_width_ + 2 * pad_w_ - kernel_w_) / stride_w_ + 1; int channels_col = conv_in_channels_ * kernel_h_ * kernel_w_; for (int c = 0; c < channels_col; ++c) { int w_offset = c % kernel_w_; int h_offset = (c / kernel_w_) % kernel_h_; int c_im = c / kernel_h_ / kernel_w_; for (int h = 0; h < height_col; ++h) { for (int w = 0; w < width_col; ++w) { int h_pad = h * stride_h_ - pad_h_ + h_offset; int w_pad = w * stride_w_ - pad_w_ + w_offset; if (h_pad >= 0 && h_pad < conv_in_height_ && w_pad >= 0 && w_pad < conv_in_width_) col_buffer_[(c * height_col + h) * width_col + w] = data_im[(c_im * conv_in_height_ + h_pad) * conv_in_width_ + w_pad]; else col_buffer_[(c * height_col + h) * width_col + w] = 0; } } } } template void caffe_cpu_gemm(const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const Dtype* A, const Dtype* B, const Dtype beta, Dtype* C); template<> void caffe_cpu_gemm(const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const float* A, const float* B, const float beta, float* C) { cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, 1., A, (TransA == CblasNoTrans) ? K : M, B, (TransB == CblasNoTrans) ? N : K, beta, C, N); } template<> void caffe_cpu_gemm(const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double* A, const double* B, const double beta, double* C) { cblas_dgemm(CblasRowMajor, TransA, TransB, M, N, K, 1., A, (TransA == CblasNoTrans) ? K : M, B, (TransB == CblasNoTrans) ? N : K, beta, C, N); } template void ParamType::forward_process(void) { // For each input, ... for (int i = 0; i < bottom_size; ++i) { const Dtype* bottom_data = bottom[i]; Dtype* top_data = top[i]; // Convolution // For each image in input batch for (int n = 0; n < num_; ++n) { int kernel_dim_ = conv_in_channels_ * kernel_h_ * kernel_w_; const Dtype* col_buff = bottom_data + bottom_mult * n; if (!is_1x1_) { im2col_cpu(col_buff); col_buff = col_buffer_; } for (int g = 0; g < group_; ++g) { caffe_cpu_gemm(CblasNoTrans, CblasNoTrans, conv_out_channels_/group_, conv_out_spatial_dim_, kernel_dim_ / group_, weight + weight_offset_ * g, col_buff + col_offset_ * g, (Dtype)0., top_data + top_mult * n + output_offset_ * g); } // Bias if (bias) { caffe_cpu_gemm(CblasNoTrans, CblasNoTrans, num_output_, height_out_ * width_out_, 1, bias, bias_multiplier_, (Dtype)1., top_data + top_mult * n); } } } } template void caffe_cpu_gemv(const int M, const int N, const Dtype* A, const Dtype* x, Dtype* y); template <> void caffe_cpu_gemv(const int M, const int N, const float* A, const float* x, float* y) { cblas_sgemv(CblasRowMajor, CblasNoTrans, M, N, 1., A, N, x, 1, 1., y, 1); } template <> void caffe_cpu_gemv(const int M, const int N, const double* A, const double* x, double* y) { cblas_dgemv(CblasRowMajor, CblasNoTrans, M, N, 1., A, N, x, 1, 1., y, 1); } template void ParamType::backward_process(void) { if (weight_diff) memset(weight_diff, 0, weight_diff_count); if (bias_diff) memset(bias_diff, 0, bias_diff_count); // For all images for (int i = 0; i < top_size; ++i) { int kernel_dim_ = conv_in_channels_ * kernel_h_ * kernel_w_; // Bias gradient, if necessary. if (bias && this->param_propagate_down_[1]) { for (int n = 0; n < num_; ++n) { caffe_cpu_gemv(num_output_, height_out_ * width_out_, top_diff[i] + top_mult * n, bias_multiplier_, bias_diff); } } if (this->param_propagate_down_[0] || propagate_down[i]) { for (int n = 0; n < num_; ++n) { // gradient w.r.t. weight. Note that we will accumulate diffs. if (this->param_propagate_down_[0]) { const Dtype* col_buff = bottom[i] + bottom_mult * n; if (!is_1x1_) { im2col_cpu(col_buff); col_buff = col_buffer_; } for (int g = 0; g < group_; ++g) { caffe_cpu_gemm(CblasNoTrans, CblasTrans, conv_out_channels_ / group_, kernel_dim_ / group_, conv_out_spatial_dim_, top_diff[i] + top_mult * n + output_offset_ * g, col_buff + col_offset_ * g, (Dtype)1., weight_diff + weight_offset_ * g); } } // gradient w.r.t. bottom data, if necessary. if (propagate_down[i]) { Dtype* col_buff = col_buffer_; if (is_1x1_) col_buff = bottom_diff[i] + bottom_mult * n; for (int g = 0; g < group_; ++g) { caffe_cpu_gemm(CblasTrans, CblasNoTrans, kernel_dim_ / group_, conv_out_spatial_dim_, conv_out_channels_ / group_, weight + weight_offset_ * g, top_diff[i] + top_mult * n + output_offset_ * g, (Dtype)0., col_buff + col_offset_ * g); } if (!is_1x1_) { Dtype *data_im = bottom_diff[i] + bottom_mult * n; memset(data_im, 0, sizeof(Dtype) * conv_in_height_ * conv_in_width_ * conv_in_channels_); int height_col = (conv_in_height_ + 2 * pad_h_ - kernel_h_) / stride_h_ + 1; int width_col = (conv_in_width_ + 2 * pad_w_ - kernel_w_) / stride_w_ + 1; int channels_col = conv_in_channels_ * kernel_h_ * kernel_w_; for (int c = 0; c < channels_col; ++c) { int w_offset = c % kernel_w_; int h_offset = (c / kernel_w_) % kernel_h_; int c_im = c / kernel_h_ / kernel_w_; for (int h = 0; h < height_col; ++h) { for (int w = 0; w < width_col; ++w) { int h_pad = h * stride_h_ - pad_h_ + h_offset; int w_pad = w * stride_w_ - pad_w_ + w_offset; if (h_pad >= 0 && h_pad < conv_in_height_ && w_pad >= 0 && w_pad < conv_in_width_) data_im[(c_im * conv_in_height_ + h_pad) * conv_in_width_ + w_pad] += col_buff[(c * height_col + h) * width_col + w]; } } } } } } } } } extern "C" void *alloc_connectal_conv(int size) { if (size == sizeof(float)) return new ParamType; else return new ParamType; } ================================================ FILE: lib/cpp/edid.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include struct edid { unsigned char raw[256]; struct edid_timing { } simple_timing[8]; struct edid_detailed_timing { unsigned short pixclk; unsigned short npixels; unsigned short bpixels; unsigned short nlines; unsigned short blines; unsigned short hsyncoff; unsigned short hsyncwidth; unsigned short vsyncoff; unsigned short vsyncwidth; unsigned short widthmm; unsigned short heightmm; unsigned char hborderpxls; unsigned char vborderpxls; unsigned char features; } timing[4]; }; static void parseEdid(struct edid &edid) { for (int i = 0; i < 4; i++) { unsigned char *rec = &edid.raw[54+18*i]; memset(&edid.timing[i], 0, sizeof(edid.timing[i])); if (*(unsigned short*)&rec[0] == 0) { unsigned char descriptor_type = rec[3]; switch (descriptor_type) { case 0xFF: // monitor serial number fprintf(stderr, "monitor serial number %13.13s\n", &rec[5]); break; case 0xFE: // text fprintf(stderr, "monitor text %.13s\n", &rec[5]); break; case 0xFC: // monitor name fprintf(stderr, "monitor name %.13s\n", &rec[5]); break; case 0xFA: // more standard timing identifiers fprintf(stderr, "standard timing identifiers\n"); break; } continue; } edid.timing[i].pixclk = *(unsigned short*)&rec[0]; edid.timing[i].npixels = rec[2] | ((rec[4] >> 4) << 8); edid.timing[i].bpixels = rec[3] | ((rec[4] & 0xF) << 8); edid.timing[i].nlines = rec[5] | ((rec[7] >> 4) << 8); edid.timing[i].blines = rec[6] | ((rec[7] & 0xF) << 8); edid.timing[i].hsyncoff = rec[8] | ((rec[11] >> 6) << 8); edid.timing[i].hsyncwidth = rec[9] | (((rec[11] & 0x30) >> 4) << 8); edid.timing[i].vsyncoff = (rec[10] >> 4) | (((rec[11] & 0x0c) >> 2) << 4); edid.timing[i].vsyncwidth = (rec[10] & 0xf) | (((rec[11] & 0x03) >> 0) << 4); edid.timing[i].widthmm = rec[12] | ((rec[14] >> 4) << 8); edid.timing[i].heightmm = rec[13] | ((rec[14] & 0xf) << 8); edid.timing[i].hborderpxls = rec[15]; edid.timing[i].vborderpxls = rec[16]; edid.timing[i].features = rec[17]; } for (int i = 0; i < 4; i++) if (edid.timing[i].pixclk) { fprintf(stderr, "pixclk=%d w=%dmm h=%dmm features=%x\n", edid.timing[i].pixclk, edid.timing[i].widthmm, edid.timing[i].heightmm, edid.timing[i].features); fprintf(stderr, " npixels=%d bpixels=%d hsyncoff=%d hsyncwidth=%d hbpxls=%d\n", edid.timing[i].npixels, edid.timing[i].bpixels, edid.timing[i].hsyncoff, edid.timing[i].hsyncwidth, edid.timing[i].hborderpxls); fprintf(stderr, " nlines=%d blines=%d vsyncoff=%d vsyncwidth=%d vbpxls=%d\n", edid.timing[i].nlines, edid.timing[i].blines, edid.timing[i].vsyncoff, edid.timing[i].vsyncwidth, edid.timing[i].vborderpxls); } fprintf(stderr, "\n"); } ================================================ FILE: lib/cpp/i2chdmi.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include "/usr/include/linux/i2c.h" #include "/usr/include/linux/i2c-dev.h" #define I2C_HDMI_ADDR (0x72/2) // == 0x39 (LSB is just 'W/nR', so elided on linux) //#define I2C_EDID_ADDR 0x3f #define I2C_ZC702_MUX_ADDR 0x74 static int i2c_write_array(int fd, int device, unsigned char *datap, int size, int byte_write) { struct i2c_smbus_ioctl_data args; union i2c_smbus_data ioctl_data; args.read_write = I2C_SMBUS_WRITE; args.size = I2C_SMBUS_BYTE_DATA; args.data = &ioctl_data; int status = ioctl(fd, I2C_SLAVE, device); if (status != 0) { fprintf(stderr, "[i2chdmi] i2c_write_array: ioctl I2C_SLAVE status=%d errno=%d\n", status, errno); return -1; } while (size) { args.command = *datap++ | byte_write; ioctl_data.byte = *datap++; status = ioctl(fd, I2C_SMBUS, &args); if (status != 0) { fprintf(stderr, "[i2chdmi] i2c_write_array: ioctl I2C_SMBUS status=%d errno=%d\n", status, errno); return -1; } size -= 2; } return 0; } unsigned char i2c_read_reg(int fd, int device, unsigned char reg) { struct i2c_smbus_ioctl_data args; union i2c_smbus_data ioctl_data; args.read_write = I2C_SMBUS_READ; args.size = I2C_SMBUS_BYTE_DATA; args.data = &ioctl_data; int status = ioctl(fd, I2C_SLAVE, device); if (status != 0) fprintf(stderr, "[i2chdmi] i2c_read_reg: ioctl I2C_SLAVE status=%d errno=%d\n", status, errno); args.command = reg; ioctl_data.byte = 0; status = ioctl(fd, I2C_SMBUS, &args); if (status != 0) fprintf(stderr, "[i2chdmi] i2c_read_reg: ioctl I2C_SMBUS status=%d errno=%d\n", status, errno); return ioctl_data.byte; } void init_i2c_hdmi(void) { static unsigned char muxdata[] = {2, 2}; static unsigned char hdmidata[] = { #if 1 0x01, 0x00, // Set N Value(6144) 0x02, 0x18, // Set N Value(6144) 0x03, 0x00, // Set N Value(6144) 0x41, 0x10, /* Powerup the Tx */ 0xA1, 0x3c, // power off TMDS clock and data 0xD6, 0xC0 | 0x10, /* HPD control (and TMDS CLK soft turn on) */ // Fixed registers that must be set on powerup 0x98, 0x03, 0x9A, 0xE0, 0x9C, 0x30, 0x9D, 0x61, 0xA2, 0xA4, 0xA3, 0xA4, 0xE0, 0xD0, 0xF9, 0x00, /* Coefficient Update */ 0x1A, 0x08, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x1A, 0x1F, 0x86, 0x20, 0x1A, 0x21, 0x49, 0x22, 0x08, 0x23, 0x00, 0x24, 0x1D, 0x25, 0x3F, 0x26, 0x04, 0x27, 0x22, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x08, 0x2B, 0x00, 0x2C, 0x0E, 0x2D, 0x2D, 0x2E, 0x19, 0x2F, 0x14, 0x48, 0x08, /* video input justification */ 0x55, 0x00, 0x56, 0x28, /* AVI InfoFrame */ // Fixed registers that must be set on powerup 0xAF, 0x04, 0xDE, 0x9C, // ADI required write 0xE4, 0x60, // ADI required Write #else 0x15, 0x00, // Input 444 (RGB or YCrCb) with Separate Syncs 0x16, 0x61, // 44.1kHz fs, YPrPb 444 0x18, 0x46, // CSC disabled 0x40, 0x80, // General Control Packet Enable 0x41, 0x10, // Power Down control 0x48, 0x48, // Reverse bus, Data right justified 0x48, 0xA8, // Set Dither_mode - 12-to-10 bit 0x4C, 0x06, // 12 bit Output 0x55, 0x00, // Set RGB444 in AVinfo Frame 0x55, 0x08, // Set active format Aspect 0x96, 0x20, // HPD Interrupt clear 0x9D, 0x61, // Set clock divide 0xAF, 0x16, // Set HDMI Mode 0xBA, 0x60, // No clock delay 0xFA, 0x7D // Nbr of times to search for good phase #endif }; printf("[%s:%d]\n", __FUNCTION__, __LINE__); int fd = open("/dev/i2c-0", O_RDWR); if (fd < 0) printf("[%s] open failed\n", __FUNCTION__); #ifndef BOARD_zedboard // only initialize mux if not a zedboard //set mux for hdmi if (i2c_write_array(fd, I2C_ZC702_MUX_ADDR, muxdata, sizeof(muxdata), 0)) printf("[%s] write mux failed\n", __FUNCTION__); #endif //set hdmi data if (i2c_write_array(fd, I2C_HDMI_ADDR, hdmidata, sizeof(hdmidata), 0)) printf("[%s] write data failed\n", __FUNCTION__); close(fd); } void i2c_hdmi_start(void) { static unsigned char hdmidata[] = { 0x15, 0x01, 0x16, 0x38, /* Video input mode */ 0x18, 0xAB, 0x19, 0x37, /* Video output mode */ 0xA1, 0x00 // power on TMDS clock and data }; printf("[%s:%d]\n", __FUNCTION__, __LINE__); int fd = open("/dev/i2c-0", O_RDWR); if (fd < 0) printf("[%s] open failed\n", __FUNCTION__); //set hdmi data if (i2c_write_array(fd, I2C_HDMI_ADDR, hdmidata, sizeof(hdmidata), 0)) printf("[%s] write data failed\n", __FUNCTION__); for (int i = 0; i <= 0x8; i++) { int val = i2c_read_reg(fd, I2C_HDMI_ADDR, i); printf("[%s:%d] HDMI [%x] = %x\n", __FUNCTION__, __LINE__, i, val); } close(fd); } void init_i2c_hdmi_rgb24(void) { static unsigned char muxdata[] = {2, 2}; static unsigned char hdmidata[] = { 0x41, 0x10, 0xD6, 0xC0, 0x15, 0x00, 0x16, 0x38, 0x18, 0xAB, 0x19, 0x37, 0x1A, 0x08, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x1A, 0x1F, 0x86, 0x20, 0x1A, 0x21, 0x49, 0x22, 0x08, 0x23, 0x00, 0x24, 0x1D, 0x25, 0x3F, 0x26, 0x04, 0x27, 0x22, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x08, 0x2B, 0x00, 0x2C, 0x0E, 0x2D, 0x2D, 0x2E, 0x19, 0x2F, 0x14, 0x48, 0x08, 0x55, 0x00, 0x56, 0x28, 0x98, 0x03, 0x9A, 0xE0, 0x9C, 0x30, 0x9D, 0x61, 0xA2, 0xA4, 0xA3, 0xA4, 0xAF, 0x04, 0xE0, 0xD0, 0xF9, 0x00}; int fd = open("/dev/i2c-0", O_RDWR); if (fd < 0) printf("[%s] open failed\n", __FUNCTION__); //set mux for hdmi if (i2c_write_array(fd, I2C_ZC702_MUX_ADDR, muxdata, sizeof(muxdata), 0)) printf("[%s] write mux failed\n", __FUNCTION__); //set hdmi data if (i2c_write_array(fd, I2C_HDMI_ADDR, hdmidata, sizeof(hdmidata), 0)) printf("[%s] write data failed\n", __FUNCTION__); close(fd); } ================================================ FILE: lib/cpp/printfInd.h ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* Dummy stub for when printf not enabled */ class DisplayInd : public DisplayIndWrapper { public: DisplayInd(unsigned int id, PortalPoller *poller) : DisplayIndWrapper(id, poller) {} }; ================================================ FILE: lib/cpp/userReference.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #define PAGE_SHIFT0 12 #define PAGE_SHIFT4 16 #define PAGE_SHIFT8 20 static int shifts[] = {PAGE_SHIFT8, PAGE_SHIFT4, PAGE_SHIFT0, 0}; #include "dmaManager.h" #include "drivers/portalmem/portalmem.h" // PortalAlloc #ifdef CONNECTAL_DRIVER_CODE #include "DmaConfigProxy.c" static int trace_memory = 1; #endif #include "GeneratedTypes.h" // generated in project directory #define DMAsglist(P, A, B, C, D) MMURequest_sglist((P), (A), (B), (C), (D)); #define DMAregion(P, PTR, B12, I12, B8, I8, B4, I4, B0, I0) MMURequest_region((P), (PTR), (B12), (I12), (B8), (I8), (B4), (I4), (B0), (I0)) typedef struct { long dma_address; long length; } RegionRef; int send_reference_to_portal(PortalInternal *device, int numEntries, RegionRef *data, int id) { int rc = 0; int i, j; uint32_t regions[3] = {0,0,0}; uint64_t border = 0; unsigned char entryCount = 0; uint64_t borderVal[3]; uint32_t indexVal[3]; unsigned char idxOffset; rc = id; PORTAL_PRINTF("[%s:%d] num %d\n", __FUNCTION__, __LINE__, numEntries); for(i = 0; i < numEntries; i++) { long addr = data[i].dma_address; long len = data[i].length; for(j = 0; j < 3; j++) if (len == 1<>= shifts[j]; break; } if (j >= 3) PORTAL_PRINTF("DmaManager:unsupported sglist size %lx\n", len); if (trace_memory) PORTAL_PRINTF("DmaManager:sglist(id=%08x, i=%d dma_addr=%08lx, len=%08lx)\n", id, i, (long)addr, len); DMAsglist(device, id, i, addr, len); } // HW interprets zeros as end of sglist if (trace_memory) PORTAL_PRINTF("DmaManager:sglist(id=%08x, i=%d end of list)\n", id, i); DMAsglist(device, id, i, 0, 0); // end list for(i = 0; i < 3; i++){ idxOffset = entryCount - border; entryCount += regions[i]; border += regions[i]; borderVal[i] = border; indexVal[i] = idxOffset; border <<= (shifts[i] - shifts[i+1]); } if (trace_memory) { PORTAL_PRINTF("regions %d (%x %x %x)\n", id,regions[0], regions[1], regions[2]); PORTAL_PRINTF("borders %d (%"PRIx64" %"PRIx64" %"PRIx64")\n", id,borderVal[0], borderVal[1], borderVal[2]); } DMAregion(device, id, 0, 0, borderVal[0], indexVal[0], borderVal[1], indexVal[1], borderVal[2], indexVal[2]); return rc; } ================================================ FILE: lib/deprecated/BurstFunnel.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFOF::*; import FIFO::*; import GetPut::*; import ClientServer::*; import BRAM::*; import BRAMFIFO::*; import Connectable::*; import ConfigCounter::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import Pipe::*; import ConnectalMemUtils::*; typedef struct { Bit#(busWidth) data; Bool last; } BFunnelData#(numeric type busWidth) deriving (Bits, Eq); typedef struct { Bit#(nameWidth) name; BFunnelData#(busWidth) data; } BFunnelNameData#(numeric type nameWidth, numeric type busWidth) deriving (Bits, Eq); typedef struct { Bit#(nameWidth) name; Bit#(busWidth) data; } BFunnelFunnel#(numeric type nameWidth, numeric type busWidth) deriving (Bits, Eq); typedef struct { Bit#(oldWidth) oldName; Bit#(newWidth) newName; } BFunnelRename#(numeric type oldWidth, numeric type newWidth) deriving (Bits, Eq); interface BurstFunnel#(numeric type k, numeric type w); method Action loadIdx(Bit#(TLog#(k)) i); interface Vector#(k, PipeIn#(Bit#(w))) dataIn; interface Vector#(k, Reg#(Bit#(BurstLenSize))) burstLen; interface PipeOut#(BFunnelFunnel#(TLog#(k),w)) dataOut; endinterface module mkBurstFunnel#(Integer maxBurstLen)(BurstFunnel#(k,w)) provisos( Log#(k,logk) ,Min#(2,logk,bpc) ,FunnelPipesPipelined#(1, k, BFunnelNameData#(2,w), bpc) ); Reg#(Bit#(2)) nameGen <- mkReg(0); UGBramFifos#(4,16,BFunnelData#(w)) complBuff <- mkUGBramFifos; Vector#(4, ConfigCounter#(16)) compCnts <- replicateM(mkConfigCounter(0)); Vector#(k,FIFOF#(BFunnelNameData#(2, w))) data_in <- replicateM(mkFIFOF); Vector#(k,Reg#(Bit#(BurstLenSize))) burst_len <- replicateM(mkReg(0)); Vector#(k,Reg#(Bit#(BurstLenSize))) drain_cnt <- replicateM(mkReg(0)); Reg#(Bit#(BurstLenSize)) inj_ctrl <- mkReg(0); FIFO#(BFunnelRename#(TAdd#(1,logk),2)) loadIdxs <- mkSizedBRAMFIFO(32); FIFO#(BFunnelRename#(TAdd#(1,logk),2)) inFlight <- mkSizedBRAMFIFO(4); FunnelPipe#(1, k, BFunnelNameData#(2,w),bpc) data_in_funnel <- mkFunnelPipesPipelined(map(toPipeOut,data_in)); Reg#(Bit#(BurstLenSize)) drainCnt <- mkReg(0); FIFOF#(BFunnelFunnel#(TLog#(k),w)) exit_data <- mkFIFOF; FIFO#(Bit#(logk)) drainRename <- mkFIFO; Reg#(Bit#(32)) cycle <- mkReg(0); Reg#(Bit#(32)) last_entry <- mkReg(0); rule cyc; cycle <= cycle+1; endrule function PipeIn#(Bit#(w)) enter_data(FIFOF#(BFunnelNameData#(2, w)) f, Integer i) = (interface PipeIn; method Bool notFull = f.notFull; method Action enq(Bit#(w) data) if (loadIdxs.first.oldName == fromInteger(i)); last_entry <= cycle; let first = inj_ctrl == 0; let cnt = first ? burst_len[i] : inj_ctrl; let new_cnt = cnt-1; let last = new_cnt == 0; inj_ctrl <= new_cnt; if (first) inFlight.enq(loadIdxs.first); if (last) loadIdxs.deq; f.enq(BFunnelNameData{name:loadIdxs.first.newName, data:BFunnelData{data:data, last:last}}); //$display("%d enq %d", cycle-last_entry, i); endmethod endinterface); Vector#(k, PipeIn#(Bit#(w))) data_in_pipes = zipWith(enter_data, data_in, genVector); function Reg#(Bit#(BurstLenSize)) check(Reg#(Bit#(BurstLenSize)) r) = (interface Reg; method Action _write(Bit#(BurstLenSize) v); if(v > 16) begin $display("ERROR mkBurstFunnel: burstLen too large"); $finish; end r <= v; endmethod method Bit#(BurstLenSize) _read = r._read; endinterface); rule drain_funnel; let v <- toGet(data_in_funnel[0]).get; complBuff.enq(v.name,v.data); compCnts[v.name].increment(1); endrule rule drain_req (compCnts[inFlight.first.newName].read > 0); let new_drainCnt = drainCnt-1; if (drainCnt == 0) begin new_drainCnt = burst_len[inFlight.first.oldName]-1; drainRename.enq(truncate(inFlight.first.oldName)); end if (new_drainCnt == 0) begin inFlight.deq; end complBuff.first_req(inFlight.first.newName); drainCnt <= new_drainCnt; compCnts[inFlight.first.newName].decrement(1); complBuff.deq(inFlight.first.newName); endrule rule drain_resp; let v <- complBuff.first_resp; if (v.last) drainRename.deq; exit_data.enq(BFunnelFunnel{name:drainRename.first,data:v.data}); endrule method Action loadIdx(Bit#(logk) idx); loadIdxs.enq(BFunnelRename{oldName:extend(idx), newName: nameGen}); nameGen <= nameGen+1; endmethod interface burstLen = map(check,burst_len); interface dataIn = data_in_pipes; interface PipeOut dataOut = toPipeOut(exit_data); endmodule ================================================ FILE: lib/deprecated/DirectoryRF.bsv ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // bsv libraries import Vector::*; import FIFO::*; import RegFile::*; import SpecialFIFOs::*; //Connectal libraries import Portal::*; import ConnectalMemTypes::*; import RegFileA::*; interface Directory#(numeric type _n, numeric type _a, numeric type _d); interface Portal#(_a,_d) portalIfc; endinterface typedef Directory#(16,16,32) StdDirectory; module mkStdDirectoryPortalIfc#(RegFileA#(Bit#(16), Bit#(32)) rf)(StdPortal); MemSlave#(16,32) ctrl <- mkMemSlaveFromRegFile(rf); method Bit#(32) ifcId(); return 0; endmethod method Bit#(32) ifcType(); return 0; endmethod interface MemSlave slave = ctrl; interface ReadOnly interrupt; method Bool _read; return False; endmethod endinterface endmodule module mkStdDirectory#(Vector#(n,StdPortal) portals) (StdDirectory); Reg#(Bit#(64)) cycle_count <- mkReg(0); Reg#(Bit#(32)) snapshot <- mkReg(0); rule count; cycle_count <= cycle_count+1; endrule let rf = (interface RegFileA#(Bit#(16), Bit#(32)); method Action upd(Bit#(16) addr, Bit#(32) data); noAction; endmethod method ActionValue#(Bit#(32)) sub(Bit#(16) _addr); let base = 128; let cco = fromInteger(valueOf(TAdd#(TMul#(2,n),4)))+base; let addr = _addr[15:0]; if (addr == 0+base) return 1; // directory version else if (addr == 1+base) return `TimeStamp; else if (addr == 2+base) return fromInteger(valueOf(n)); else if (addr == 3+base) return 16; // portal Addr bits else if (addr < cco) begin let idx = (addr-4-base); if (idx[0] == 0) return portals[idx>>1].ifcId; else return portals[idx>>1].ifcType; end else if (addr == cco) begin snapshot <= truncate(cycle_count); return cycle_count[63:32]; end else if (addr == cco+1) return snapshot; else begin $display("directory addr out bounds %d", addr); return 0; end endmethod endinterface); let ifc <- mkStdDirectoryPortalIfc(rf); interface StdPortal portalIfc = ifc; endmodule ================================================ FILE: lib/deprecated/DmaUtils.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BRAM::*; import FIFO::*; import Vector::*; import Gearbox::*; import FIFOF::*; import SpecialFIFOs::*; import ConfigCounter::*; import BRAMFIFOFLevel::*; import GetPut::*; import ConnectalMemTypes::*; function MemReadClient#(dataWidth) orc(DmaReadBuffer#(dataWidth,bufferDepth) rb) = rb.dmaClient; function MemWriteClient#(dataWidth) owc(DmaWriteBuffer#(dataWidth,bufferDepth) wb) = wb.dmaClient; function MemReadServer#(dataWidth) ors(DmaReadBuffer#(dataWidth,bufferDepth) rb) = rb.dmaServer; function MemWriteServer#(dataWidth) ows(DmaWriteBuffer#(dataWidth,bufferDepth) wb) = wb.dmaServer; // // @brief A buffer for reading from a bus of width dataWidth. // // @param dataWidth The number of bits in the bus. // @param bufferDepth The depth of the internal buffer // interface DmaReadBuffer#(numeric type dataWidth, numeric type bufferDepth); interface MemReadServer #(dataWidth) dmaServer; interface MemReadClient#(dataWidth) dmaClient; endinterface // // @brief A buffer for writing to a bus of width dataWidth. // // @param dataWidth The number of bits in the bus. // @param bufferDepth The depth of the internal buffer // interface DmaWriteBuffer#(numeric type dataWidth, numeric type bufferDepth); interface MemWriteServer#(dataWidth) dmaServer; interface MemWriteClient#(dataWidth) dmaClient; endinterface // // @brief Makes a Dma buffer for reading wordSize words from memory. // // @param dataWidth The width of the bus in bits. // @param bufferDepth The depth of the internal buffer // module mkDmaReadBuffer(DmaReadBuffer#(dataWidth, bufferDepth)) provisos(Add#(b__, TAdd#(1,TLog#(bufferDepth)), BurstLenSize), Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift)); FIFOFLevel#(MemData#(dataWidth),bufferDepth) readBuffer <- mkBRAMFIFOFLevel; FIFOF#(MemRequest) reqOutstanding <- mkFIFOF(); ConfigCounter#(TAdd#(1,TLog#(bufferDepth))) unfulfilled <- mkConfigCounter(0); let beat_shift = fromInteger(valueOf(beatShift)); // only issue the readRequest when sufficient buffering is available. This includes the bufering we have already comitted. Bit#(TAdd#(1,TLog#(bufferDepth))) sreq = pack(satPlus(Sat_Bound, unpack(truncate(reqOutstanding.first.burstLen>>beat_shift)), unfulfilled.read())); interface MemReadServer dmaServer; interface Put readReq = toPut(reqOutstanding); interface Get readData = toGet(readBuffer); endinterface interface MemReadClient dmaClient; interface Get readReq; method ActionValue#(MemRequest) get if (readBuffer.lowWater(sreq)); reqOutstanding.deq; unfulfilled.increment(unpack(truncate(reqOutstanding.first.burstLen>>beat_shift))); return reqOutstanding.first; endmethod endinterface interface Put readData; method Action put(MemData#(dataWidth) x); readBuffer.fifo.enq(x); unfulfilled.decrement(1); endmethod endinterface endinterface endmodule // // @brief Makes a Dma channel for writing wordSize words from memory. // // @param dataWidth The width of the bus in bits. // @param bufferDepth The depth of the internal buffer // module mkDmaWriteBuffer(DmaWriteBuffer#(dataWidth, bufferDepth)) provisos(Add#(b__, TAdd#(1, TLog#(bufferDepth)), BurstLenSize), Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift)); FIFOFLevel#(MemData#(dataWidth),bufferDepth) writeBuffer <- mkBRAMFIFOFLevel; FIFOF#(MemRequest) reqOutstanding <- mkFIFOF(); FIFOF#(Bit#(6)) doneTags <- mkFIFOF(); ConfigCounter#(TAdd#(1,TLog#(bufferDepth))) unfulfilled <- mkConfigCounter(0); let beat_shift = fromInteger(valueOf(beatShift)); // only issue the writeRequest when sufficient data is available. This includes the data we have already comitted. Bit#(TAdd#(1,TLog#(bufferDepth))) sreq = pack(satPlus(Sat_Bound, unpack(truncate(reqOutstanding.first.burstLen>>beat_shift)), unfulfilled.read())); interface MemWriteServer dmaServer; interface Put writeReq = toPut(reqOutstanding); interface Put writeData = toPut(writeBuffer); interface Get writeDone = toGet(doneTags); endinterface interface MemWriteClient dmaClient; interface Get writeReq; method ActionValue#(MemRequest) get if (writeBuffer.highWater(sreq)); reqOutstanding.deq; unfulfilled.increment(unpack(truncate(reqOutstanding.first.burstLen>>beat_shift))); return reqOutstanding.first; endmethod endinterface interface Get writeData; method ActionValue#(MemData#(dataWidth)) get(); unfulfilled.decrement(1); writeBuffer.fifo.deq; return writeBuffer.fifo.first; endmethod endinterface interface Put writeDone = toPut(doneTags); endinterface endmodule module mkDmaReadMux#(Vector#(numClients,MemReadClient#(dataWidth)) readClients)(MemReadClient#(dataWidth)) provisos(Log#(numClients,tagsz), Add#(tagsz,a__,MemTagSize)); FIFO#(MemRequest) readReqFifo <- mkFIFO(); FIFO#(MemData#(dataWidth)) readRespFifo <- mkFIFO(); for (Integer i = 0; i < valueOf(numClients); i = i + 1) begin // assume fixed tag per client Reg#(Bit#(MemTagSize)) tagReg <- mkReg(0); rule getreq; let req <- readClients[i].readReq.get(); tagReg <= req.tag; req.tag = fromInteger(i); readReqFifo.enq(req); endrule rule sendresp if (readRespFifo.first.tag == fromInteger(i)); let resp <- toGet(readRespFifo).get(); resp.tag = tagReg; readClients[i].readData.put(resp); endrule end interface Get readReq = toGet(readReqFifo); interface Put readData = toPut(readRespFifo); endmodule module mkDmaWriteMux#(Vector#(numClients,MemWriteClient#(dataWidth)) writeClients)(MemWriteClient#(dataWidth)) provisos(Log#(numClients,tagsz), Add#(tagsz,a__,MemTagSize)); FIFO#(MemRequest) writeReqFifo <- mkFIFO(); FIFO#(MemData#(dataWidth)) writeDataFifo <- mkFIFO(); FIFO#(Bit#(MemTagSize)) writeDoneFifo <- mkFIFO(); FIFO#(Bit#(MemTagSize)) arbFifo <- mkFIFO(); for (Integer i = 0; i < valueOf(numClients); i = i + 1) begin // assume fixed tag per client Reg#(Bit#(MemTagSize)) tagReg <- mkReg(0); rule getreq; let req <- writeClients[i].writeReq.get(); tagReg <= req.tag; req.tag = fromInteger(i); writeReqFifo.enq(req); arbFifo.enq(req.tag); endrule rule senddata if (fromInteger(i) == arbFifo.first); let data <- writeClients[i].writeData.get(); data.tag = tagReg; writeDataFifo.enq(data); endrule rule senddone if (writeDoneFifo.first == fromInteger(i)); arbFifo.deq(); let done <- toGet(writeDoneFifo).get(); writeClients[i].writeDone.put(tagReg); endrule end interface Get writeReq = toGet(writeReqFifo); interface Get writeData = toGet(writeDataFifo); interface Put writeDone = toPut(writeDoneFifo); endmodule ================================================ FILE: lib/deprecated/OldMemServer.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // BSV Libraries `include "ConnectalProjectConfig.bsv" import FIFO::*; import Vector::*; import GetPut::*; import ClientServer::*; import Assert::*; // CONNECTAL Libraries import ConnectalMemTypes::*; import ConnectalMemory::*; import ConnectalMMU::*; `ifdef SIMULATION import "BDPI" function ActionValue#(Bit#(32)) pareff(Bit#(32) handle, Bit#(32) size); `endif interface MemServer#(numeric type addrWidth, numeric type dataWidth); interface DmaConfig request; interface MemMaster#(addrWidth, dataWidth) master; endinterface interface MemWriteInternal#(numeric type addrWidth, numeric type dataWidth); interface DmaDbg dbg; interface MemWriteClient#(addrWidth,dataWidth) write_client; interface Get#(Tuple2#(Bit#(6),Bit#(6))) tagMismatch; endinterface interface MemReadInternal#(numeric type addrWidth, numeric type dataWidth); interface DmaDbg dbg; interface MemReadClient#(addrWidth,dataWidth) read_client; interface Get#(Tuple2#(Bit#(6),Bit#(6))) tagMismatch; endinterface function Bool bad_pointer(SGLId p); return (p > fromInteger(valueOf(MaxNumSGLists)) || p == 0); endfunction typedef struct {MemRequest req; Bit#(6) rename_tag; Bit#(addrWidth) pa; DmaChannelId chan; } IRec#(type addrWidth) deriving(Bits); module mkMemReadInternal#(Vector#(numReadClients, MemReadClient#(dataWidth)) readClients, DmaIndication dmaIndication, Server#(Tuple2#(SGListId,Bit#(MemOffsetSize)),Bit#(addrWidth)) sgl) (MemReadInternal#(addrWidth, dataWidth)) provisos(Add#(b__, addrWidth, 64), Add#(c__, 12, addrWidth), Add#(1, c__, d__), Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift)); FIFO#(IRec#(addrWidth)) lreqFifo <- mkSizedFIFO(1); FIFO#(IRec#(addrWidth)) reqFifo <- mkSizedFIFO(1); FIFO#(IRec#(addrWidth)) dreqFifo <- mkSizedFIFO(32); Reg#(Bit#(8)) burstReg <- mkReg(0); Vector#(numReadClients, Reg#(Bit#(64))) beatCounts <- replicateM(mkReg(0)); let beat_shift = fromInteger(valueOf(beatShift)); // report a tag mismatch for oo completions (in which // case we will need to introduce completion buffers) FIFO#(Tuple2#(Bit#(6),Bit#(6))) tag_mismatch <- mkSizedFIFO(32); `ifdef INTERVAL_ANAlYSIS Reg#(Bit#(32)) bin1 <- mkReg(0); Reg#(Bit#(32)) bin4 <- mkReg(0); Reg#(Bit#(32)) binx <- mkReg(0); Reg#(Bit#(64)) cycle_cnt <- mkReg(0); Reg#(Bit#(64)) last_resp_read <- mkReg(0); (* fire_when_enabled *) rule cycle; cycle_cnt <= cycle_cnt+1; endrule `endif for (Integer selectReg = 0; selectReg < valueOf(numReadClients); selectReg = selectReg + 1) rule loadChannel; MemRequest req <- readClients[selectReg].readReq.get(); //$display("dmaread.loadChannel activeChan=%d handle=%h addr=%h burst=%h", selectReg, req.sglId, req.offset, req.burstLen); if (bad_pointer(req.sglId)) dmaIndication.badPointer(req.sglId); else begin lreqFifo.enq(IRec{req:req, rename_tag:?, pa:?, chan:fromInteger(selectReg)}); sgl.request.put(tuple2(truncate(req.sglId),req.offset)); end endrule rule checkSglResp; let physAddr <- sgl.response.get; let req = lreqFifo.first.req; let chan = lreqFifo.first.chan; lreqFifo.deq(); if (physAddr <= (1 << valueOf(SGListPageShift0))) begin // squash request $display("dmaRead: badAddr pointer=%d offset=%h physAddr=%h", req.sglId, req.offset, physAddr); dmaIndication.badAddr(req.sglId, extend(req.offset), extend(physAddr)); end else begin if (False && physAddr[31:24] != 0) $display("checkSglResp: funny physAddr req.sglId=%d req.offset=%h physAddr=%h", req.sglId, req.offset, physAddr); reqFifo.enq(IRec{req:req, rename_tag:truncate(chan), pa:physAddr, chan:chan}); end endrule interface DmaDbg dbg; method ActionValue#(DmaDbgRec) dbg(); `ifdef INTERVAL_ANAlYSIS return DmaDbgRec{x:fromInteger(valueOf(numReadClients)), y:bin1, z:bin4, w:binx}; `else return DmaDbgRec{x:fromInteger(valueOf(numReadClients)), y:0, z:0, w:0}; `endif endmethod method ActionValue#(Bit#(64)) getMemoryTraffic(Bit#(32) client); return (valueOf(numReadClients) > 0 && client < fromInteger(valueOf(numReadClients))) ? beatCounts[client] : 0; endmethod endinterface interface MemReadClient read_client; interface Get readReq; method ActionValue#(PhysMemRequest#(addrWidth)) get; let req = reqFifo.first.req; let physAddr = reqFifo.first.pa; let rename_tag = reqFifo.first.rename_tag; reqFifo.deq; //$display("mkMemReadInternal::req_ar tag=%d rename_tag=%d len=%d activeChan=%d", req.tag, rename_tag, req.burstLen, reqFifo.first.chan); if (False && physAddr[31:24] != 0) $display("req_ar: funny physAddr req.sglId=%d req.offset=%h physAddr=%h", req.sglId, req.offset, physAddr); dreqFifo.enq(reqFifo.first); return PhysMemRequest{addr:physAddr, burstLen:req.burstLen, tag:rename_tag}; endmethod endinterface interface Put readData; method Action put(MemData#(dataWidth) response); let activeChan = dreqFifo.first.chan; let req = dreqFifo.first.req; let rename_tag = dreqFifo.first.rename_tag; if (valueOf(numReadClients) > 0) readClients[activeChan].readData.put(MemData { data: response.data, tag: req.tag}); let burstLen = burstReg; if (burstLen == 0) burstLen = req.burstLen >> beat_shift; if (burstLen == 1) dreqFifo.deq(); if (response.tag != rename_tag) begin tag_mismatch.enq(tuple2(response.tag,rename_tag)); $display("mkMemReadInternal::tag_mismatch %d %d", response.tag, rename_tag); end //$display("mkMemReadInternal::resp_read rename_tag=%d response.tag=%d burstLen=%d activeChan=%d", rename_tag, response.tag, burstLen, activeChan); burstReg <= burstLen-1; if(valueOf(numReadClients) > 0) beatCounts[activeChan] <= beatCounts[activeChan]+1; `ifdef INTERVAL_ANAlYSIS last_resp_read <= cycle_cnt; let interval = cycle_cnt - last_resp_read; if (interval <= 1) bin1 <= bin1+1; else if (interval <= 4) bin4 <= bin4+1; else binx <= binx+1; `endif endmethod endinterface endinterface interface Get tagMismatch = fifoToGet(tag_mismatch); endmodule module mkMemWriteInternal#(Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients, DmaIndication dmaIndication, Server#(Tuple2#(SGListId,Bit#(MemOffsetSize)),Bit#(addrWidth)) sgl) (MemWriteInternal#(addrWidth, dataWidth)) provisos(Add#(b__, addrWidth, 64), Add#(c__, 12, addrWidth), Add#(1, c__, d__), Div#(dataWidth,8,dataWidthBytes), Mul#(dataWidthBytes,8,dataWidth), Log#(dataWidthBytes,beatShift)); FIFO#(IRec#(addrWidth)) lreqFifo <- mkSizedFIFO(1); FIFO#(IRec#(addrWidth)) reqFifo <- mkSizedFIFO(1); FIFO#(IRec#(addrWidth)) dreqFifo <- mkSizedFIFO(32); FIFO#(IRec#(addrWidth)) respFifo <- mkSizedFIFO(32); Reg#(Bit#(8)) burstReg <- mkReg(0); Vector#(numWriteClients, Reg#(Bit#(64))) beatCounts <- replicateM(mkReg(0)); let beat_shift = fromInteger(valueOf(beatShift)); // report a tag mismatch for oo completions (in which // case we will need to introduce completion buffers) FIFO#(Tuple2#(Bit#(6),Bit#(6))) tag_mismatch <- mkSizedFIFO(32); for (Integer selectReg = 0; selectReg < valueOf(numWriteClients); selectReg = selectReg + 1) rule loadChannel; MemRequest req <- writeClients[selectReg].writeReq.get(); //$display("dmawrite.loadChannel activeChan=%d handle=%h addr=%h burst=%h debugReq=%d", selectReg, req.sglId, req.offset, req.burstLen, debugReg); if (bad_pointer(req.sglId)) dmaIndication.badPointer(req.sglId); else begin lreqFifo.enq(IRec{req:req, rename_tag:?, pa:?, chan:fromInteger(selectReg)}); sgl.request.put(tuple2(truncate(req.sglId),req.offset)); end endrule rule checkSglResp; let physAddr <- sgl.response.get; let req = lreqFifo.first.req; let chan = lreqFifo.first.chan; lreqFifo.deq(); if (physAddr <= (1 << valueOf(SGListPageShift0))) begin // squash request $display("dmaWrite: badAddr handle=%d addr=%h physAddr=%h", req.sglId, req.offset, physAddr); dmaIndication.badAddr(req.sglId, extend(req.offset), extend(physAddr)); end else begin reqFifo.enq(IRec{req:req, rename_tag:truncate(chan), pa:physAddr, chan:chan}); end endrule interface DmaDbg dbg; method ActionValue#(DmaDbgRec) dbg(); return DmaDbgRec{x:fromInteger(valueOf(numWriteClients)), y:?, z:?, w:?}; endmethod method ActionValue#(Bit#(64)) getMemoryTraffic(Bit#(32) client); return (valueOf(numWriteClients) > 0 && client < fromInteger(valueOf(numWriteClients))) ? beatCounts[client] : 0; endmethod endinterface interface MemWriteClient write_client; interface Get writeReq; method ActionValue#(PhysMemRequest#(addrWidth)) get(); let req = reqFifo.first.req; let physAddr = reqFifo.first.pa; let rename_tag = reqFifo.first.rename_tag; reqFifo.deq; //$display("dmaWrite addr physAddr=%h burstReg=%d", physAddr, req.burstLen); dreqFifo.enq(reqFifo.first); return PhysMemRequest{addr:physAddr, burstLen:req.burstLen, tag:rename_tag}; endmethod endinterface interface Get writeData; method ActionValue#(MemData#(dataWidth)) get(); let activeChan = dreqFifo.first.chan; let req = dreqFifo.first.req; let rename_tag = dreqFifo.first.rename_tag; MemData#(dataWidth) tagdata = unpack(0); if (valueOf(numWriteClients) > 0) tagdata <- writeClients[activeChan].writeData.get(); let burstLen = burstReg; if (burstLen == 0) burstLen = req.burstLen >> beat_shift; if (burstLen == 1) begin dreqFifo.deq(); respFifo.enq(dreqFifo.first); end //$display("dmaWrite data data=%h burstLen=%d", tagdata.data, burstLen); burstReg <= burstLen-1; if(valueOf(numWriteClients) > 0) beatCounts[activeChan] <= beatCounts[activeChan]+1; return MemData { data: tagdata.data, tag: rename_tag }; endmethod endinterface interface Put writeDone; method Action put(Bit#(6) resp); let activeChan = respFifo.first.chan; let rename_tag = respFifo.first.rename_tag; let orig_tag = respFifo.first.req.tag; if (resp != rename_tag) begin tag_mismatch.enq(tuple2(resp,rename_tag)); $display("mkMemWriteInternal::tag_mismatch %d %d", resp, rename_tag); end respFifo.deq(); if (valueOf(numWriteClients) > 0) begin writeClients[activeChan].writeDone.put(orig_tag); end endmethod endinterface endinterface interface Get tagMismatch = fifoToGet(tag_mismatch); endmodule // // @brief Creates a Dma controller for Dma read and write clients // // @param dmaIndication Interface for notifying software // @param readClients The read clients. // @param writeClients The writeclients. // module mkMemServer#(DmaIndication dmaIndication, Vector#(numReadClients, MemReadClient#(dataWidth)) readClients, Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients) (MemServer#(addrWidth, dataWidth)) provisos (Add#(1,a__,dataWidth), Add#(b__, TSub#(addrWidth, 12), 32), Add#(c__, 12, addrWidth), Add#(d__, addrWidth, 64), Add#(e__, TSub#(addrWidth, 12), MemOffsetSize), Add#(f__, c__, MemOffsetSize), Add#(g__, addrWidth, 40), Mul#(TDiv#(dataWidth, 8), 8, dataWidth)); MMU#(addrWidth) sgl <- mkMMU(dmaIndication); FIFO#(void) addrReqFifo <- mkFIFO; MemReadInternal#(addrWidth, dataWidth) reader <- mkMemReadInternal(readClients, dmaIndication, sgl.addr[0]); MemWriteInternal#(addrWidth, dataWidth) writer <- mkMemWriteInternal(writeClients, dmaIndication, sgl.addr[1]); rule tag_mismatch_read; let rv <- reader.tagMismatch.get; dmaIndication.tagMismatch(ChannelType_Read, extend(tpl_1(rv)), extend(tpl_2(rv))); endrule rule tag_mismatch_write; let rv <- writer.tagMismatch.get; dmaIndication.tagMismatch(ChannelType_Write, extend(tpl_1(rv)), extend(tpl_2(rv))); endrule rule sglistEntry; addrReqFifo.deq; let physAddr <- sgl.addr[0].response.get; dmaIndication.addrResponse(zeroExtend(physAddr)); endrule interface DmaConfig request; method Action getStateDbg(ChannelType rc); let rv = ?; if (rc == ChannelType_Read) rv <- reader.dbg.dbg; else rv <- writer.dbg.dbg; dmaIndication.reportStateDbg(rv); endmethod method Action getMemoryTraffic(ChannelType rc, Bit#(32) client); if (rc == ChannelType_Read) begin let rv <- reader.dbg.getMemoryTraffic(client); dmaIndication.reportMemoryTraffic(rv); end else begin let rv <- writer.dbg.getMemoryTraffic(client); dmaIndication.reportMemoryTraffic(rv); end endmethod method Action sglist(Bit#(32) pref, Bit#(MemOffsetSize) addr, Bit#(32) len); if (bad_pointer(pref)) dmaIndication.badPointer(pref); `ifdef SIMULATION let va <- pareff(pref, len); addr[39:32] = truncate(pref); `endif sgl.sglist(pref, addr, len); endmethod method Action region(Bit#(32) pointer, Bit#(40) barr8, Bit#(8) off8, Bit#(40) barr4, Bit#(8) off4, Bit#(40) barr0, Bit#(8) off0); sgl.region(pointer,barr8,off8,barr4,off4,barr0,off0); endmethod method Action addrRequest(Bit#(32) pointer, Bit#(32) offset); addrReqFifo.enq(?); sgl.addr[0].request.put(tuple2(truncate(pointer), extend(offset))); endmethod endinterface interface MemMaster master; interface MemReadClient read_client = reader.read_client; interface MemWriteClient write_client = writer.write_client; endinterface endmodule ================================================ FILE: lib/deprecated/RegFileA.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import FIFO::*; import GetPut::*; import Connectable::*; import RegFile::*; import ConnectalMemTypes::*; interface RegFileA#(type index_t, type data_t); method Action upd(index_t addr, data_t d); method ActionValue#(data_t) sub(index_t addr); endinterface typedef struct { Bit#(addrWidth) addr; Bit#(8) bc; Bit#(6) tag; Bool last; } AddrBeat#(numeric type addrWidth) deriving (Bits); interface AddressGenerator#(numeric type addrWidth); interface Put#(PhysMemRequest#(addrWidth)) request; interface Get#(AddrBeat#(addrWidth)) addrBeat; endinterface module mkAddressGenerator(AddressGenerator#(addrWidth)); FIFOF#(PhysMemRequest#(addrWidth)) requestFifo <- mkFIFOF(); FIFOF#(AddrBeat#(addrWidth)) addrBeatFifo <- mkFIFOF(); Reg#(Bit#(addrWidth)) addrReg <- mkReg(0); Reg#(Bit#(8)) burstCountReg <- mkReg(0); Reg#(Bool) isLastReg <- mkReg(False); rule addrBeatRule; let req = requestFifo.first(); let addr = addrReg; let burstCount = burstCountReg; let isLast = isLastReg; let nextIsLast = burstCount == 2; let nextBurstCount = burstCount - 1; addrReg <= addr + 1; burstCountReg <= nextBurstCount; isLastReg <= nextIsLast; if (isLast) begin requestFifo.deq(); end addrBeatFifo.enq(AddrBeat { addr: addr, bc: burstCount, last: isLast, tag: req.tag}); endrule interface Put request; method Action put(PhysMemRequest#(addrWidth) req); requestFifo.enq(req); addrReg <= req.addr; burstCountReg <= req.burstLen; isLastReg <= (req.burstLen == 1); endmethod endinterface interface Get addrBeat; method ActionValue#(AddrBeat#(addrWidth)) get(); addrBeatFifo.deq(); return addrBeatFifo.first(); endmethod endinterface endmodule module mkMemSlaveFromRegFile#(RegFileA#(Bit#(regFileAddrWidth), Bit#(busDataWidth)) rf) (MemSlave#(busAddrWidth, busDataWidth)) provisos(Add#(a__, regFileAddrWidth, busAddrWidth)); Reg#(Bit#(regFileAddrWidth)) writeAddrReg <- mkReg(0); Reg#(Bit#(8)) writeBurstCountReg <- mkReg(0); FIFOF#(void) writeRespFifo <- mkFIFOF(); FIFOF#(Bit#(6)) writeTagFifo <- mkFIFOF(); FIFO#(PhysMemRequest#(busAddrWidth)) req_aw_fifo <- mkSizedFIFO(1); AddressGenerator#(busAddrWidth) readAddrGenerator <- mkAddressGenerator(); Bool verbose = False; interface MemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(busAddrWidth) req); if (verbose) $display("axiSlave.read.readAddr %h bc %d", req.addr, req.burstLen); readAddrGenerator.request.put(req); endmethod endinterface interface Get readData; method ActionValue#(MemData#(busDataWidth)) get(); let addrBeat <- readAddrGenerator.addrBeat.get(); let addr = addrBeat.addr; let tag = addrBeat.tag; let burstCount = addrBeat.bc; Bit#(regFileAddrWidth) regFileAddr = truncate(addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); let data <- rf.sub(regFileAddr); if (verbose) $display("read_server.readData %h %h %d", addr, data, burstCount); return MemData { data: data, tag: tag, last: addrBeat.last }; endmethod endinterface endinterface interface MemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(busAddrWidth) req); req_aw_fifo.enq(req); if (verbose) $display("write_server.writeAddr %h bc %d", req.addr, req.burstLen); endmethod endinterface interface Put writeData; method Action put(MemData#(busDataWidth) resp); let addr = writeAddrReg; let burstCount = writeBurstCountReg; if (burstCount == 0) begin let req = req_aw_fifo.first; addr = truncate(req.addr/fromInteger(valueOf(TDiv#(busDataWidth,8)))); burstCount = req.burstLen; writeTagFifo.enq(req.tag); req_aw_fifo.deq; end if (verbose) $display("writeData %h %h %d", addr, resp.data, burstCount); rf.upd(addr, resp.data); writeAddrReg <= addr + 1; writeBurstCountReg <= burstCount - 1; if (verbose) $display("write_server.writeData %h %h %d", addr, resp.data, burstCount); if (burstCount == 1) writeRespFifo.enq(?); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(6)) get(); writeRespFifo.deq; writeTagFifo.deq; return writeTagFifo.first; endmethod endinterface endinterface endmodule ================================================ FILE: lib/deprecated/SGListComb.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // BSV Libraries import RegFile::*; import FIFO::*; import FIFOF::*; import Vector::*; import GetPut::*; import BRAMFIFO::*; import BRAM::*; import ConnectalMemTypes::*; import StmtFSM::*; import ClientServer::*; import ConnectalMemory::*; typedef 32 MaxNumSGLists; typedef Bit#(TLog#(MaxNumSGLists)) SGListId; typedef 12 SGListPageShift0; typedef 16 SGListPageShift4; typedef 20 SGListPageShift8; typedef Bit#(TLog#(MaxNumSGLists)) RegionsIdx; typedef Tuple2#(SGListId,Bit#(MemOffsetSize)) ReqTup; interface MMU#(numeric type addrWidth); method Action sglist(Bit#(32) pointer, Bit#(40) paddr, Bit#(32) len); method Action region(Bit#(32) ptr, Bit#(40) barr8, Bit#(8) off8, Bit#(40) barr4, Bit#(8) off4, Bit#(40) barr0, Bit#(8) off0); interface Vector#(2,Server#(ReqTup,Bit#(addrWidth))) addr; endinterface typedef union tagged{ Bit#(SGListPageShift0) OOrd0; Bit#(SGListPageShift4) OOrd4; Bit#(SGListPageShift8) OOrd8; } Offset deriving (Eq,Bits,FShow); typedef union tagged{ Bit#(TSub#(MemOffsetSize,SGListPageShift0)) POrd0; Bit#(TSub#(MemOffsetSize,SGListPageShift4)) POrd4; Bit#(TSub#(MemOffsetSize,SGListPageShift8)) POrd8; } Page deriving (Eq,Bits,FShow); typedef struct { Bit#(MemOffsetSize) barrier; Bit#(8) idxOffset; } Region deriving (Eq,Bits,FShow); module mkMMU#(DmaIndication dmaIndication)(MMU#(addrWidth)) provisos(Log#(MaxNumSGLists, listIdxSize), Add#(listIdxSize,8, entryIdxSize), Add#(c__, addrWidth, MemOffsetSize)); BRAM_Configure bramConfig = defaultValue; bramConfig.latency = 1; BRAM2Port#(Bit#(entryIdxSize),Page) pages <- mkBRAM2Server(bramConfig); BRAM2Port#(RegionsIdx, Region) reg8 <- mkBRAM2Server(bramConfig); BRAM2Port#(RegionsIdx, Region) reg4 <- mkBRAM2Server(bramConfig); BRAM2Port#(RegionsIdx, Region) reg0 <- mkBRAM2Server(bramConfig); Vector#(2,FIFOF#(Bit#(entryIdxSize))) rp <- replicateM(mkFIFOF); Vector#(2,FIFOF#(Offset)) offs <- replicateM(mkFIFOF); Vector#(2,FIFOF#(ReqTup)) reqs <- replicateM(mkFIFOF); Reg#(Bit#(8)) idxReg <- mkReg(0); let page_shift0 = fromInteger(valueOf(SGListPageShift0)); let page_shift4 = fromInteger(valueOf(SGListPageShift4)); let page_shift8 = fromInteger(valueOf(SGListPageShift8)); let ord0 = 40'd1 << page_shift0; let ord4 = 40'd1 << page_shift4; let ord8 = 40'd1 << page_shift8; function BRAMServer#(a,b) portsel(BRAM2Port#(a,b) x, Integer i); if(i==0) return x.portA; else return x.portB; endfunction FIFO#(Tuple4#(RegionsIdx,Region,Region,Region)) regionFifo <- mkFIFO(); for(Integer i = 0; i < 2; i=i+1) begin rule req; Region region8 <- portsel(reg8,i).response.get; Region region4 <- portsel(reg4,i).response.get; Region region0 <- portsel(reg0,i).response.get; reqs[i].deq; let ptr = tpl_1(reqs[i].first); let off = tpl_2(reqs[i].first); Offset o = tagged OOrd0 0; Bit#(8) pbase = 0; Bit#(8) idxOffset = 0; Bit#(40) barrier8 = region8.barrier; Bit#(40) barrier4 = region4.barrier; Bit#(40) barrier0 = region0.barrier; Bit#(3) pageSize = 0; if (off < barrier8) begin //$display("request: ptr=%h off=%h barrier8=%h", ptr, off, barrier8); o = tagged OOrd8 truncate(off); pbase = truncate(off>>page_shift8); pageSize = 3; idxOffset = region8.idxOffset; end else if (off < barrier4) begin //$display("request: ptr=%h off=%h barrier4=%h", ptr, off, barrier4); o = tagged OOrd4 truncate(off); pbase = truncate(off>>page_shift4); pageSize = 2; idxOffset = region4.idxOffset; end else if (off < barrier0) begin //$display("request: ptr=%h off=%h barrier0=%h", ptr, off, barrier0); o = tagged OOrd0 truncate(off); pbase = truncate(off>>page_shift0); pageSize = 1; idxOffset = region0.idxOffset; end else begin pageSize = 0; //dmaIndication.badAddrTrans(extend(ptr), extend(off), barrier0); end offs[i].enq(o); Bit#(8) p = pbase + idxOffset; if (pageSize == 3) begin //$display("request: ptr=%h off=%h barrier8=%h", ptr, off, barrier8); end else if (pageSize == 2) begin end else if (pageSize == 1) begin end else if (pageSize == 0) begin //FIXME offset //$display("mkMMU.addr[%d].request.put: ERROR ptr=%h off=%h\n", i, ptr, off); dmaIndication.badAddrTrans(extend(ptr), -1, 0); end let address = {ptr-1,p}; //$display("pages[%d].read %h", i, rp[i].first()); portsel(pages, i).request.put(BRAMRequest{write:False, responseOnWrite:False, address:address, datain:?}); endrule end Vector#(2,Server#(ReqTup,Bit#(addrWidth))) addrServers; for(Integer i = 0; i < 2; i=i+1) addrServers[i] = (interface Server#(ReqTup,Bit#(addrWidth)); interface Put request; method Action put(ReqTup req); match { .ptr, .off } = req; portsel(reg8, i).request.put(BRAMRequest{write:False, responseOnWrite:False, address:truncate(ptr-1), datain:?}); portsel(reg4, i).request.put(BRAMRequest{write:False, responseOnWrite:False, address:truncate(ptr-1), datain:?}); portsel(reg0, i).request.put(BRAMRequest{write:False, responseOnWrite:False, address:truncate(ptr-1), datain:?}); reqs[i].enq(req); endmethod endinterface interface Get response; method ActionValue#(Bit#(addrWidth)) get(); let page <- portsel(pages, i).response.get; let offset <- toGet(offs[i]).get(); //$display("pages[%d].response page=%h offset=%h", i, page, offset); Bit#(MemOffsetSize) rv = 0; case (offset) matches tagged OOrd0 .o: begin case (page) matches tagged POrd4 .p: $display("OOrd0 vs POrd4"); tagged POrd8 .p: $display("OOrd0 vs POrd8"); endcase rv = {page.POrd0,o}; end tagged OOrd4 .o: begin case (page) matches tagged POrd0 .p: $display("OOrd4 vs POrd0"); tagged POrd8 .p: $display("OOrd4 vs POrd8"); endcase rv = {page.POrd4,o}; end tagged OOrd8 .o: begin case (page) matches tagged POrd0 .p: $display("OOrd8 vs POrd0"); tagged POrd4 .p: $display("OOrd8 vs POrd4"); endcase rv = {page.POrd8,o}; end endcase return truncate(rv); endmethod endinterface endinterface); FIFO#(Tuple2#(SGListId,Bit#(40))) configRespFifo <- mkFIFO; rule sendConfigResp; match { .ptr, .barr0 } <- toGet(configRespFifo).get(); dmaIndication.configResp(extend(ptr), barr0); endrule FIFO#(Tuple3#(SGListId,Bit#(40),Bit#(32))) sglistFifo <- mkFIFO(); rule sglistRule; match { .ptr, .paddr, .len } <- toGet(sglistFifo).get(); // $display("sglist(ptr=%d, paddr=%h, len=%h", ptr, paddr,len); if (idxReg+1 == 0) begin $display("sglist: exceeded maximun length of sglist"); dmaIndication.badNumberEntries(extend(ptr),len, extend(idxReg)); end else begin Page page = tagged POrd0 0; if (len == 0) begin idxReg <= 0; end else begin idxReg <= idxReg+1; if (extend(len) == ord0) begin page = tagged POrd0 truncate(paddr>>page_shift0); end else if (extend(len) == ord4) begin page = tagged POrd4 truncate(paddr>>page_shift4); end else if (extend(len) == ord8) begin page = tagged POrd8 truncate(paddr>>page_shift8); end if (extend(len) > ord8) begin $display("mkMMU::sglist unsupported length %h", len); dmaIndication.badPageSize(extend(ptr), len); end end configRespFifo.enq(tuple2(truncate(ptr), 40'haaaaaaaa)); portsel(pages, 0).request.put(BRAMRequest{write:True, responseOnWrite:False, address:{truncate(ptr-1),idxReg}, datain:page}); end endrule rule regionRule; match { .ptr, .region8, .region4, .region0 } <- toGet(regionFifo).get(); let idx = ptr-1; portsel(reg8, 0).request.put(BRAMRequest{write:True, responseOnWrite:False, address: idx, datain: region8}); portsel(reg4, 0).request.put(BRAMRequest{write:True, responseOnWrite:False, address: idx, datain: region4}); portsel(reg0, 0).request.put(BRAMRequest{write:True, responseOnWrite:False, address: idx, datain: region0}); //$display("region ptr=%d off8=%h off4=%h off0=%h", ptr, off8, off4, off0); configRespFifo.enq(tuple2(ptr, region0.barrier)); endrule // FIXME: split this into three methods? method Action region(Bit#(32) ptr, Bit#(40) barr8, Bit#(8) off8, Bit#(40) barr4, Bit#(8) off4, Bit#(40) barr0, Bit#(8) off0); Region region8 = Region { barrier: barr8, idxOffset: off8 }; Region region4 = Region { barrier: barr4, idxOffset: off4 }; Region region0 = Region { barrier: barr0, idxOffset: off0 }; regionFifo.enq(tuple4(truncate(ptr),region8,region4,region0)); endmethod method Action sglist(Bit#(32) ptr, Bit#(40) paddr, Bit#(32) len); sglistFifo.enq(tuple3(truncate(ptr), paddr, len)); endmethod interface addr = addrServers; endmodule interface SglAddrServer#(numeric type addrWidth, numeric type numServers); interface Vector#(numServers,Server#(ReqTup,Bit#(addrWidth))) servers; endinterface module mkSglAddrServer#(Server#(ReqTup,Bit#(addrWidth)) server) (SglAddrServer#(addrWidth,numServers)); FIFOF#(Bit#(TAdd#(1,TLog#(numServers)))) tokFifo <- mkSizedFIFOF(3); Vector#(numServers, Server#(ReqTup,Bit#(addrWidth))) addrServers; Reg#(Bit#(TLog#(numServers))) arb <- mkReg(0); // this is a very crude arbiter. something more sophisticated may be required (mdk) rule inc_arb; arb <= arb+1; endrule for(Integer i = 0; i < valueOf(numServers); i=i+1) addrServers[i] = (interface Server#(ReqTup,Bit#(addrWidth)); interface Put request; method Action put(ReqTup req) if (arb == fromInteger(i)); tokFifo.enq(fromInteger(i)); server.request.put(req); endmethod endinterface interface Get response; method ActionValue#(Bit#(addrWidth)) get() if (tokFifo.first == fromInteger(i)); tokFifo.deq; let rv <- server.response.get; return rv; endmethod endinterface endinterface); interface servers = addrServers; endmodule ================================================ FILE: lib/deprecated/bsv_Makefile ================================================ test: testspi testAdapter testspi: ConnectalSpi.bsv bsc -check-assert -sim -u -g mkSpiTestBench ConnectalSpi.bsv bsc -check-assert -sim -u -e mkSpiTestBench -o spiTestBench mkSpiTestBench.ba ./spiTestBench -V spi.vcd testgearbox: GearboxTb.bsv bsc -sim -u -g mkGearboxTb GearboxTb.bsv bsc -sim -u -e mkGearboxTb -o testGearbox mkGearboxTb.ba ./testGearbox mkGearboxTb.v: GearboxTb.bsv bsc -verilog -u -g mkGearboxTb GearboxTb.bsv testAdapter: Adapter.bsv bsc -p +:../lib/bsv -check-assert -sim -u -g mkAdapterTb Adapter.bsv bsc -check-assert -sim -u -e mkAdapterTb -o testAdapter mkAdapterTb.ba ./testAdapter testConnectalReadyQueue: ConnectalReadyQueue.bsv bsc -check-assert -sim -u -g mkRQTB ConnectalReadyQueue.bsv bsc -check-assert -sim -u -e mkRQTB -o testConnectalReadyQueue mkRQTB.ba ./testConnectalReadyQueue mkSPI20.v: ConnectalSpi.bsv bsc -verilog -u -g mkSPI20 ConnectalSpi.bsv ================================================ FILE: lib/deprecated/pcietestbench/Makefile ================================================ INTERFACES = PcieTestBenchRequest PcieTestBenchIndication BSVFILES = PcieTestBench.bsv Top.bsv CPPFILES=testpcie.cpp include ../../Makefile.common ================================================ FILE: lib/deprecated/pcietestbench/PcieTestBench.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks :: *; import Connectable :: *; import DefaultValue :: *; import FIFO :: *; import GetPut :: *; import PCIE :: *; import AxiCsr :: *; import AxiSlaveEngine :: *; import AxiMasterEngine :: *; import PcieSplitter :: *; // copied from PCIE.bsv because connectalgen cannot handle TMul#() typedef struct { Bit#(1) sof; Bit#(1) eof; Bit#(7) hit; Bit#(16) be; Bit#(32) data0; Bit#(32) data1; Bit#(32) data2; Bit#(32) data3; } TLPData16 deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef enum { MEM_READ_3DW_NO_DATA = 0, MEM_READ_4DW_NO_DATA = 1, MEM_WRITE_3DW_DATA = 2, MEM_WRITE_4DW_DATA = 3 } TLPPacketFormat deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef enum { MEMORY_READ_WRITE = 0, MEMORY_READ_LOCKED = 1, IO_REQUEST = 2, UNKNOWN_TYPE_3 = 3, CONFIG_0_READ_WRITE = 4, CONFIG_1_READ_WRITE = 5, UNKNOWN_TYPE_6 = 6, UNKNOWN_TYPE_7 = 7, UNKNOWN_TYPE_8 = 8, UNKNOWN_TYPE_9 = 9, COMPLETION = 10, COMPLETION_LOCKED = 11, UNKNOWN_TYPE_12 = 12, UNKNOWN_TYPE_13 = 13, UNKNOWN_TYPE_14 = 14, UNKNOWN_TYPE_15 = 15, MSG_ROUTED_TO_ROOT = 16, MSG_ROUTED_BY_ADDR = 17, MSG_ROUTED_BY_ID = 18, MSG_ROOT_BROADCAST = 19, MSG_LOCAL = 20, MSG_GATHER = 21, UNKNOWN_TYPE_22 = 22, UNKNOWN_TYPE_23 = 23, UNKNOWN_TYPE_24 = 24, UNKNOWN_TYPE_25 = 25, UNKNOWN_TYPE_26 = 26, UNKNOWN_TYPE_27 = 27, UNKNOWN_TYPE_28 = 28, UNKNOWN_TYPE_29 = 29, UNKNOWN_TYPE_30 = 30, UNKNOWN_TYPE_31 = 31 } TLPPacketType deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef struct {Bit#(8) hit; Bit#(8) sof; Bit#(8) eof; Bit#(16) tlpbe; Bit#(16) tag; Bit#(16) length; TLPPacketType pkttype; TLPPacketFormat format; Bit#(8) firstbe; Bit#(8) lastbe; Bit#(32) addr; Bit#(32) data; } Pcie3dwHeader deriving (Bits); interface PcieTestBenchIndication; method Action tlpout(TLPData16 tlp); endinterface interface PcieTestBenchRequest; method Action sendReadRequest(Bit#(8) hit, Bit#(32) addr, Bit#(8) length, Bit#(8) tag); endinterface module mkPcieTestBenchRequest#(PcieTestBenchIndication indication)(PcieTestBenchRequest); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); MakeResetIfc portalResetIfc <- mkReset(10, False, defaultClock); PciId my_id = PciId { bus: 1, dev: 1, func: 0}; Bit#(64) board_content_id = 'hdeadbeefd00df00d; Reg#(Bit#(32)) tlp_portal_drop_count <- mkReg(0); Reg#(Bit#(32)) tlp_axi_drop_count <- mkReg(0); AxiMasterEngine axiMasterEngine <- mkAxiMasterEngine(my_id); AxiControlAndStatusRegs axiCsr <- mkAxiControlAndStatusRegs( board_content_id, my_id, 0, 0, tlp_portal_drop_count, tlp_axi_drop_count, portalResetIfc); Reg#(Bit#(32)) timestamp <- mkReg(0); rule timebase; timestamp <= timestamp + 1; endrule mkConnection(axiMasterEngine.master, axiCsr.slave); rule tlp_out; let tlp <- axiMasterEngine.tlp_out.get(); TimestampedTlpData ttd = TimestampedTlpData { timestamp: timestamp, source: 4, tlp: tlp }; $display("%h", ttd); indication.tlpout(unpack(pack(tlp))); endrule method Action sendReadRequest(Bit#(8) hit, Bit#(32) addr, Bit#(8) length, Bit#(8) tag); $display("send3dwRequest hit=%d addr=%h length=%h tag=%d", hit, addr, length, tag); TLPMemoryIO3DWHeader hdr = defaultValue; hdr.tag = truncate(tag); hdr.length = extend(length); hdr.format = PCIE::MEM_READ_3DW_NO_DATA; hdr.pkttype = PCIE::MEMORY_READ_WRITE; hdr.firstbe = 4'hf; hdr.lastbe = (length == 1) ? 0 : 4'hf; hdr.addr = truncate(addr >> 2); hdr.data = 0; TLPData#(16) tlp; tlp.be = 16'hfff0; tlp.sof = True; tlp.eof = True; tlp.hit = truncate(hit); tlp.data = pack(hdr); $display("tlp_in=%h", tlp); axiMasterEngine.tlp_in.put(tlp); endmethod endmodule ================================================ FILE: lib/deprecated/pcietestbench/Top.bsv ================================================ import Vector::*; import FIFO::*; import Connectable::*; import Directory::*; import CtrlMux::*; import Portal::*; import ConnectalMemTypes::*; import PcieTestBenchIndicationProxy::*; import PcieTestBenchRequestWrapper::*; import PcieTestBench::*; typedef enum {IfcNames_PcieTestBenchIndication, IfcNames_PcieTestBenchRequest} IfcNames deriving (Eq,Bits); module mkConnectalTop(StdConnectalTop#(addrWidth)); PcieTestBenchIndicationProxy pcieTestBenchIndicationProxy <- mkPcieTestBenchIndicationProxy(IfcNames_PcieTestBenchIndication); PcieTestBenchRequest pcieTestBenchRequest <- mkPcieTestBenchRequest(pcieTestBenchIndicationProxy.ifc); PcieTestBenchRequestWrapper pcieTestBenchRequestWrapper <- mkPcieTestBenchRequestWrapper(IfcNames_PcieTestBenchRequest,pcieTestBenchRequest); Vector#(2,StdPortal) portals; portals[0] = pcieTestBenchRequestWrapper.portalIfc; portals[1] = pcieTestBenchIndicationProxy.portalIfc; StdDirectory dir <- mkStdDirectory(portals); let ctrl_mux <- mkSlaveMux(dir,portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop ================================================ FILE: lib/deprecated/pcietestbench/testpcie.cpp ================================================ #include #include #include #include #include #include "PcieTestBenchIndication.h" #include "PcieTestBenchRequest.h" #include "GeneratedTypes.h" class PcieTestBenchIndication : public PcieTestBenchIndicationWrapper { sem_t sem; public: uint32_t cnt; void incr_cnt(){ if (++cnt == 7) exit(0); } void tlpout(const TLPData16 &tlp) { fprintf(stderr, "Received tlp: %08x%08x%08x%08x\n", tlp.data3, tlp.data2, tlp.data1, tlp.data0); sem_post(&sem); } PcieTestBenchIndication(unsigned int id) : PcieTestBenchIndicationWrapper(id), cnt(0) { sem_init(&sem, 0, 0); } void wait() { sem_wait(&sem); } }; int main(int argc, const char **argv) { PcieTestBenchIndication *indication = new PcieTestBenchIndication(IfcNames_PcieTestBenchIndication); PcieTestBenchRequestProxy *device = new PcieTestBenchRequestProxy(IfcNames_PcieTestBenchRequest); device->sendReadRequest(1, 4, 1, 5); indication->wait(); device->sendReadRequest(1, 0, 2, 7); indication->wait(); device->sendReadRequest(1, 0, 3, 9); indication->wait(); device->sendReadRequest(1, 0, 4, 10); indication->wait(); device->sendReadRequest(1, 0, 5, 11); indication->wait(); device->sendReadRequest(1, 0, 6, 12); indication->wait(); device->sendReadRequest(1, 0, 7, 12); indication->wait(); device->sendReadRequest(1, 0, 8, 12); indication->wait(); } ================================================ FILE: lib/deprecated/pcietestbench_dma_io/Makefile ================================================ INTERFACES = PcieTestBenchRequest PcieTestBenchIndication BSVFILES = PcieTestBench.bsv Top.bsv CPPFILES=testpcie.cpp include ../../Makefile.common ================================================ FILE: lib/deprecated/pcietestbench_dma_io/Memread.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import ConnectalMemTypes::*; import MemReadEngine::*; interface MemreadRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) iterCnt); method Action getStateDbg(); endinterface interface Memread; interface MemreadRequest request; interface MemReadClient#(64) dmaClient; endinterface interface MemreadIndication; method Action started(Bit#(32) numWords); method Action reportStateDbg(Bit#(32) streamRdCnt, Bit#(32) mismatchCount); method Action readDone(Bit#(32) mismatchCount); endinterface module mkMemread#(MemreadIndication indication) (Memread); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) iterCnt <- mkReg(0); Reg#(Bit#(32)) srcGen <- mkReg(0); Reg#(Bit#(32)) mismatchCount <- mkReg(0); FIFOF#(Bit#(64)) readFifo <- mkFIFOF; let re <- mkMemReadEngine(1, readFifo); rule start (iterCnt > 0); iterCnt <= iterCnt-1; re.start(pointer, 0, numWords*4, burstLen*4); endrule rule finish; let rv <- re.finish; if (iterCnt == 0) indication.readDone(mismatchCount); endrule rule check; readFifo.deq; let v = readFifo.first; let expectedV = {srcGen+1,srcGen}; let misMatch = v != expectedV; mismatchCount <= mismatchCount + (misMatch ? 1 : 0); if (srcGen+2 == numWords) srcGen <= 0; else srcGen <= srcGen+2; endrule interface MemReadClient dmaClient = re.dmaClient; interface MemreadRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nw, Bit#(32) bl, Bit#(32) ic); $display("startRead rdPointer=%d numWords=%h burstLen=%d iterCnt=%d", rp, nw, bl, ic); indication.started(nw); pointer <= rp; numWords <= nw; burstLen <= bl; iterCnt <= ic; mismatchCount <= 0; srcGen <= 0; endmethod method Action getStateDbg(); indication.reportStateDbg(iterCnt, mismatchCount); endmethod endinterface endmodule ================================================ FILE: lib/deprecated/pcietestbench_dma_io/PcieTestBench.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Clocks :: *; import Connectable :: *; import DefaultValue :: *; import FIFO :: *; import GetPut :: *; import FIFOF :: *; import Vector :: *; import AxiCsr :: *; import PCIE :: *; import AxiSlaveEngine :: *; import Portal :: *; import MemServer :: *; import SGList::*; import MemReadEngine :: *; import AxiDma :: *; import ConnectalMemTypes :: *; import AxiMasterSlave :: *; import MemServerRequestWrapper::*; import SGListConfigRequestWrapper::*; import MemServerIndicationProxy::*; import SGListConfigIndicationProxy::*; // copied from PCIE.bsv because connectalgen cannot handle TMul#() typedef struct { Bit#(32) data0; Bit#(32) data1; Bit#(32) data2; Bit#(32) data3; Bit#(32) data4; Bit#(32) data5; } TsTLPData16 deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef enum { MEM_READ_3DW_NO_DATA = 0, MEM_READ_4DW_NO_DATA = 1, MEM_WRITE_3DW_DATA = 2, MEM_WRITE_4DW_DATA = 3 } TLPPacketFormat deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef enum { MEMORY_READ_WRITE = 0, MEMORY_READ_LOCKED = 1, IO_REQUEST = 2, UNKNOWN_TYPE_3 = 3, CONFIG_0_READ_WRITE = 4, CONFIG_1_READ_WRITE = 5, UNKNOWN_TYPE_6 = 6, UNKNOWN_TYPE_7 = 7, UNKNOWN_TYPE_8 = 8, UNKNOWN_TYPE_9 = 9, COMPLETION = 10, COMPLETION_LOCKED = 11, UNKNOWN_TYPE_12 = 12, UNKNOWN_TYPE_13 = 13, UNKNOWN_TYPE_14 = 14, UNKNOWN_TYPE_15 = 15, MSG_ROUTED_TO_ROOT = 16, MSG_ROUTED_BY_ADDR = 17, MSG_ROUTED_BY_ID = 18, MSG_ROOT_BROADCAST = 19, MSG_LOCAL = 20, MSG_GATHER = 21, UNKNOWN_TYPE_22 = 22, UNKNOWN_TYPE_23 = 23, UNKNOWN_TYPE_24 = 24, UNKNOWN_TYPE_25 = 25, UNKNOWN_TYPE_26 = 26, UNKNOWN_TYPE_27 = 27, UNKNOWN_TYPE_28 = 28, UNKNOWN_TYPE_29 = 29, UNKNOWN_TYPE_30 = 30, UNKNOWN_TYPE_31 = 31 } TLPPacketType deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef struct {Bit#(8) hit; Bit#(8) sof; Bit#(8) eof; Bit#(16) tlpbe; Bit#(16) tag; Bit#(16) length; TLPPacketType pkttype; TLPPacketFormat format; Bit#(8) firstbe; Bit#(8) lastbe; Bit#(32) addr; Bit#(32) data; } Pcie3dwHeader deriving (Bits); interface PcieTestBenchIndication; method Action tlpout(TsTLPData16 tlp); method Action started(Bit#(32) numWords); method Action finished(Bit#(32) v); endinterface interface PcieTestBenchRequest; method Action tlpin(TsTLPData16 tlp); method Action startRead(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface PcieTestBench#(numeric type addrWidth, numeric type dataWidth); interface PcieTestBenchRequest request; interface StdPortal dmaConfig; interface StdPortal dmaIndication; interface Vector#(1,MemMaster#(addrWidth,dataWidth)) masters; endinterface typedef enum {TestBenchIndication, TestBenchRequest, HostmemMemServerIndication, HostmemMemServerRequest, HostmemSGListConfigRequest, HostmemSGListConfigIndication} IfcNames deriving (Eq,Bits); //`define SANITY module mkPcieTestBench#(PcieTestBenchIndication indication)(PcieTestBench#(40,64)); // memread state FIFOF#(Bit#(64)) readFifo <- mkFIFOF; let re <- mkMemReadEngine(1, readFifo); // dma state SGListConfigIndicationProxy hostmemSGListConfigIndicationProxy <- mkSGListConfigIndicationProxy(HostmemSGListConfigIndication); SGListMMU#(PhysAddrWidth) hostmemSGList <- mkSGListMMU(0, True, hostmemSGListConfigIndicationProxy.ifc); SGListConfigRequestWrapper hostmemSGListConfigRequestWrapper <- mkSGListConfigRequestWrapper(HostmemSGListConfigRequest, hostmemSGList.request); MemServerIndicationProxy hostmemMemServerIndicationProxy <- mkMemServerIndicationProxy(HostmemMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(cons(re.dmaClient,nil), nil, hostmemSGList, hostmemMemServerIndicationProxy.ifc); MemServerRequestWrapper hostmemMemServerRequestWrapper <- mkMemServerRequestWrapper(HostmemMemServerRequest, dma.request); `ifdef SANITY Axi3Master#(40,64,6) m_axi = ?; `else Axi3Master#(40,64,6) m_axi <- mkAxiDmaMaster(dma.masters[0]); `endif // tlp state PciId my_id = PciId { bus: 1, dev: 1, func: 0}; Bit#(64) board_content_id = 'hdeadbeefd00df00d; Reg#(Bit#(32)) tlp_portal_drop_count <- mkReg(0); Reg#(Bit#(32)) tlp_axi_drop_count <- mkReg(0); AxiSlaveEngine#(64) axiSlaveEngine <- mkAxiSlaveEngine(my_id); Reg#(Bit#(32)) timestamp <- mkReg(0); mkConnection(m_axi, axiSlaveEngine.slave); FIFO#(TimestampedTlpData) tlpin_fifo <- mkSizedFIFO(20); // tlp rules rule timebase; timestamp <= timestamp + 1; endrule rule tlp_out; let tlp <- tpl_1(axiSlaveEngine.tlps).get(); TimestampedTlpData ttd = TimestampedTlpData { timestamp: timestamp, source: 4, tlp: tlp }; indication.tlpout(unpack(pack(ttd))); //$display("%h",ttd); endrule rule tlp_in; let ttd = tlpin_fifo.first; tlpin_fifo.deq; tpl_2(axiSlaveEngine.tlps).put(unpack(pack(ttd.tlp))); endrule // memread rules rule finish; let rv <- re.finish; indication.finished(0); endrule rule drain; readFifo.deq; endrule interface PcieTestBenchRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nw, Bit#(32) bl); $display("startRead rdPointer=%d numWords=%h burstLen=%d", rp, nw, bl); indication.started(nw); re.start(rp, 0, nw*4, bl*4); endmethod method Action tlpin(TsTLPData16 tstlp); TimestampedTlpData ttd = unpack(pack(tstlp)); tlpin_fifo.enq(ttd); endmethod endinterface interface StdPortal dmaConfig = hostmemMemServerRequestWrapper.portalIfc; interface StdPortal dmaIndication = hostmemMemServerIndicationProxy.portalIfc; //portals[z] = hostmemSGListConfigRequestWrapper.portalIfc; //portals[z] = hostmemSGListConfigIndicationProxy.portalIfc; `ifdef SANITY interface masters = dma.masters; `else interface masters = ?; `endif endmodule ================================================ FILE: lib/deprecated/pcietestbench_dma_io/Top.bsv ================================================ import Vector::*; import FIFO::*; import Connectable::*; import Directory::*; import CtrlMux::*; import Portal::*; import ConnectalMemTypes::*; import PcieTestBenchIndicationProxy::*; import PcieTestBenchRequestWrapper::*; import PcieTestBench::*; module mkConnectalTop(StdConnectalDmaTop#(40)); PcieTestBenchIndicationProxy pcieTestBenchIndicationProxy <- mkPcieTestBenchIndicationProxy(IfcNames_TestBenchIndication); PcieTestBench#(40,64) pcieTestBench <- mkPcieTestBench(pcieTestBenchIndicationProxy.ifc); PcieTestBenchRequestWrapper pcieTestBenchRequestWrapper <- mkPcieTestBenchRequestWrapper(IfcNames_TestBenchRequest,pcieTestBench.request); Vector#(4,StdPortal) portals; portals[0] = pcieTestBenchRequestWrapper.portalIfc; portals[1] = pcieTestBenchIndicationProxy.portalIfc; portals[2] = pcieTestBench.dmaConfig; portals[3] = pcieTestBench.dmaIndication; // instantiate system directory StdDirectory dir <- mkStdDirectory(portals); let ctrl_mux <- mkSlaveMux(dir,portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = pcieTestBench.masters; endmodule : mkConnectalTop ================================================ FILE: lib/deprecated/pcietestbench_dma_io/memread_nobuff_io.tstlp ================================================ 00cdb9771184ffff4a000001020000040018001800000000 cb408b610981ffff400000010000030fdf400c6400000000 cb408b710981fff0000000010018000fdf400c1cde8ef1c7 000000000000000000000000000000000000000000000000 cb408be10981fff0000000010018000fdf400c1842930a1d 000000000000000000000000000000000000000000000000 cb408c530981ffff400000010000000fdf400c1c00000000 000000000000000000000000000000000000000000000000 00cdbb360984ffff400000010000030fdf51c00401000000 00cdbb450984fff0000000010018000fdf53c018356b8254 000000000000000000000000000000000000000000000000 00cdbbbb0984ffff400000010000000fdf53c00401000000 00cdbbcb0984fff0000000010018000fdf52c01849b41c35 000000000000000000000000000000000000000000000000 00cdbc410984ffff400000010000010fdf52c00401000000 00cdbc510984fff0000000010018000fdf54c0189162707f 000000000000000000000000000000000000000000000000 00cdbcc70984ffff400000010000020fdf54c00401000000 00cdbd1f0984fff0000000010018000fdf51c0183115e719 000000000000000000000000000000000000000000000000 00cdbd950984ffff400000010000030fdf51c00401000000 00cdbda50984fff0000000010018000fdf53c018821e86ba 000000000000000000000000000000000000000000000000 00cdbe1b0984ffff400000010000000fdf53c00401000000 00cdbe2b0984fff0000000010018000fdf52c018fec118db 000000000000000000000000000000000000000000000000 00cdbea10984ffff400000010000010fdf52c00401000000 00cdbeb10984fff0000000010018000fdf54c018fcb17325 000000000000000000000000000000000000000000000000 00cdbf270984ffff400000010000020fdf54c00401000000 00cdbf7f0984fff0000000010018000fdf51c0185cc6e443 000000000000000000000000000000000000000000000000 00cdbff50984ffff400000010000030fdf51c00401000000 00cdc0040984fff0000000010018000fdf53c018efcd85e0 000000000000000000000000000000000000000000000000 00cdc07b0984ffff400000010000000fdf53c00401000000 00cdc08a0984fff0000000010018000fdf52c01893121b81 000000000000000000000000000000000000000000000000 00cdc1010984ffff400000010000010fdf52c00401000000 00cdc1100984fff0000000010018000fdf54c018f48f7a33 000000000000000000000000000000000000000000000000 00cdc1860984ffff400000010000020fdf54c00401000000 00cdc1de0984fff0000000010018000fdf51c01854f8ed55 000000000000000000000000000000000000000000000000 00cdc2540984ffff400000010000030fdf51c00401000000 00cdc2640984fff0000000010018000fdf53c018e7f38cf6 000000000000000000000000000000000000000000000000 00cdc2da0984ffff400000010000000fdf53c00401000000 00cdc2ea0984fff0000000010018000fdf52c0189b2c1297 000000000000000000000000000000000000000000000000 00cdc3600984ffff400000010000010fdf52c00401000000 00cdc3700984fff0000000010018000fdf54c018995c7969 000000000000000000000000000000000000000000000000 00cdc3e70984ffff400000010000020fdf54c00401000000 00cdc4400984fff0000000010018000fdf51c018392bee0f 000000000000000000000000000000000000000000000000 00cdc4b60984ffff400000010000030fdf51c00401000000 00cdc4c60984fff0000000010018000fdf53c0188a208fac 000000000000000000000000000000000000000000000000 00cdc53c0984ffff400000010000000fdf53c00401000000 00cdc54c0984fff0000000010018000fdf52c018f6ff11cd 000000000000000000000000000000000000000000000000 00cdc5c20984ffff400000010000010fdf52c00401000000 00cdc5d10984fff0000000010018000fdf54c0182e297d87 000000000000000000000000000000000000000000000000 00cdc6480984ffff400000010000020fdf54c00401000000 00cdc6a00984fff0000000010018000fdf51c0188e5eeae1 000000000000000000000000000000000000000000000000 00cdc7150984ffff400000010000030fdf51c00401000000 00cdc7250984fff0000000010018000fdf53c0183d558b42 000000000000000000000000000000000000000000000000 00cdc79b0984ffff400000010000000fdf53c00401000000 00cdc7ab0984fff0000000010018000fdf52c018418a1523 000000000000000000000000000000000000000000000000 00cdc8210984ffff400000010000010fdf52c00401000000 00cdc8310984fff0000000010018000fdf54c01843fa7edd 000000000000000000000000000000000000000000000000 00cdc8a70984ffff400000010000020fdf54c00401000000 00cdc8ff0984fff0000000010018000fdf51c018e38de9bb 000000000000000000000000000000000000000000000000 00cdc9750984ffff400000010000030fdf51c00401000000 00cdc9850984fff0000000010018000fdf53c01850868818 000000000000000000000000000000000000000000000000 00cdc9fb0984ffff400000010000000fdf53c00401000000 00cdca0b0984fff0000000010018000fdf52c0182c591679 000000000000000000000000000000000000000000000000 00cdca810984ffff400000010000010fdf52c00401000000 00cdca910984fff0000000010018000fdf54c01801c40480 000000000000000000000000000000000000000000000000 00cdcb070984ffff400000010000020fdf54c00401000000 00cdcb5f0984fff0000000010018000fdf51c018a1b393e6 000000000000000000000000000000000000000000000000 00cdcbd50984ffff400000010000030fdf51c00401000000 00cdcbe40984fff0000000010018000fdf53c01812b8f245 000000000000000000000000000000000000000000000000 00cdcc5b0984ffff400000010000000fdf53c00401000000 00cdcc6a0984fff0000000010018000fdf52c0186e676c24 000000000000000000000000000000000000000000000000 00cdccda0984fff0000000010018000fdf500230037be1cc 00cdcce00984ffff400000010000010fdf52c00401000000 000000000000000000000000000000000000000000000000 00cdccf00984fff0000000010018010fdf54c01807a891ac 000000000000000000000000000000000000000000000000 00cdcd4c0984fff0000000010018000fdf500234d4d34676 000000000000000000000000000000000000000000000000 00cdcd660984ffff400000010000020fdf54c00401000000 00cdcdbe0984fff0000000010018000fdf51c01811bf751c 000000000000000000000000000000000000000000000000 00cdce270984ffff400000010000030fdf51000001000000 00cdce340984ffff400000010000000fdf51c00401000000 00cdce3a0984ffff400000010000010fdf51000040000000 00cdce440984fff0000000010018000fdf53c0185e744c31 00cdce4e0984ffff400000010000020fdf51000010000000 000000000000000000000000000000000000000000000000 00cdce610984ffff400000010000030fdf51000001000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdceba0984ffff400000010000000fdf53c00401000000 00cdceca0984fff0000000010018000fdf52c018ff7437f0 000000000000000000000000000000000000000000000000 00cdcee30900ffff4a000010000000400200000000000000 00cdcee40800ffff01000000020000000300000004000000 00cdcee50800ffff05000000060000000700000008000000 00cdcee60800ffff090000000a0000000b0000000c000000 00cdcee70880fff00d0000000e0000000f000000a35b5dfa 00cdcee90900ffff4a000010000000400200004010000000 00cdceea0800ffff11000000120000001300000014000000 00cdceeb0800ffff15000000160000001700000018000000 00cdceec0800ffff190000001a0000001b0000001c000000 00cdceee0880fff01d0000001e0000001f0000003a3cc92b 00cdceef0900ffff4a000010000000400200000020000000 00cdcef00800ffff21000000220000002300000024000000 00cdcef20800ffff25000000260000002700000028000000 00cdcef40800ffff290000002a0000002b0000002c000000 00cdcef60880fff02d0000002e0000002f0000004510b620 00cdcef70900ffff4a000010000000400200004030000000 00cdcef80800ffff31000000320000003300000034000000 00cdcefa0800ffff35000000360000003700000038000000 00cdcefc0800ffff390000003a0000003b0000003c000000 00cdcefe0880fff03d0000003e0000003f000000dc7722f1 00cdcf410984fff0000000010018000fdf52800099765234 000000000000000000000000000000000000000000000000 00cdde150984fff0000000010018000fdf52c0184f78d10a 000000000000000000000000000000000000000000000000 00cddea00984fff0000000010018000fdf528200c6cb81a6 000000000000000000000000000000000000000000000000 00cde5a30984fff0000000010018000fdf52c01892a734aa 000000000000000000000000000000000000000000000000 00cde6180984ffff400000010000010fdf52c00401000000 00cde6280984fff0000000010018000fdf54c0186b6ee5ce 000000000000000000000000000000000000000000000000 00cde69e0984ffff400000010000020fdf54c00401000000 00cde7120984fff0000000010018000fdf51c018b4dc3c88 000000000000000000000000000000000000000000000000 00cde7880984ffff400000010000030fdf51c00401000000 00cde7980984fff0000000010018000fdf53c01891bde4eb 000000000000000000000000000000000000000000000000 00cde7b80984fff0000000010018010fdf50023003cbf493 000000000000000000000000000000000000000000000000 00cde80e0984ffff400000010000000fdf53c00401000000 00cde81e0984fff0000000010018000fdf52c018b56409f7 00cde8290984fff0000000010018010fdf500234d4635329 000000000000000000000000000000000000000000000000 00cde8940984ffff400000010000010fdf52c00401000000 00cde8a40984fff0000000010018000fdf54c01832cdf4d4 000000000000000000000000000000000000000000000000 00cde8cf0984ffff400000010000020fdf53030000000000 00cde91a0984ffff400000010000030fdf54c00401000000 00cde9720984fff0000000010018000fdf51c018cabc10cf 000000000000000000000000000000000000000000000000 00cde9e70984ffff400000010000000fdf51c00401000000 00cde9f70984fff0000000010018000fdf53c018efddc8ac 000000000000000000000000000000000000000000000000 00cdea6d0984ffff400000010000010fdf53c00401000000 00cdea7d0984fff0000000010018000fdf52c018b21debe3 000000000000000000000000000000000000000000000000 00cdeaf30984ffff400000010000020fdf52c00401000000 00cdeb030984fff0000000010018000fdf54c0184bd43a87 000000000000000000000000000000000000000000000000 00cdeb8b0984fff0000000010018000fdf5486001b7de3ef 000000000000000000000000000000000000000000000000 00cdebff0984fff0000000010018000fdf548600437b9092 000000000000000000000000000000000000000000000000 00cdec720984fff0000000010018000fdf548600c6a2064f 000000000000000000000000000000000000000000000000 00cdece60984fff0000000010018000fdf54860008ceccf2 000000000000000000000000000000000000000000000000 00cdee4b0984fff0000000010018000fdf54c0185867159a 000000000000000000000000000000000000000000000000 00cdeec00984ffff400000010000030fdf54c00401000000 00cdef180984fff0000000010018000fdf51c01803a93866 000000000000000000000000000000000000000000000000 00cdef8e0984ffff400000010000000fdf51c00401000000 00cdef9e0984fff0000000010018000fdf53c01826c8e005 000000000000000000000000000000000000000000000000 00cdf0140984ffff400000010000010fdf53c00401000000 00cdf0240984fff0000000010018000fdf52c018cc7dc7a4 000000000000000000000000000000000000000000000000 00cdf0590984ffff400000010000020fdf53040000000000 00cdf06c0984ffff400000010000030fdf53040000000000 00cdf09a0984ffff400000010000000fdf52c00401000000 00cdf0aa0984fff0000000010018000fdf54c018aa55893d 000000000000000000000000000000000000000000000000 00cdf1220984fff0000000010018000fdf548700f078172c 000000000000000000000000000000000000000000000000 00cdf1950984fff0000000010018000fdf54870075a181f1 000000000000000000000000000000000000000000000000 00cdf4760984fff0000000010018000fdf54c018b9e6a620 000000000000000000000000000000000000000000000000 00cdf4eb0984ffff400000010000010fdf54c00401000000 00cdf5430984fff0000000010018000fdf51c01819913146 000000000000000000000000000000000000000000000000 00cdf5b90984ffff400000010000020fdf51c00401000000 00cdf5c90984fff0000000010018000fdf53c018c74953bf 000000000000000000000000000000000000000000000000 00cdf63f0984ffff400000010000030fdf53c00401000000 00cdf64f0984fff0000000010018000fdf52c018bb96cdde 000000000000000000000000000000000000000000000000 00cdf6c50984ffff400000010000000fdf52c00401000000 00cdf6d50984fff0000000010018000fdf54c018d435a57a 000000000000000000000000000000000000000000000000 00cdf74b0984ffff400000010000010fdf54c00401000000 00cdf7a30984fff0000000010018000fdf51c0187442321c 000000000000000000000000000000000000000000000000 00cdf8190984ffff400000010000020fdf51c00401000000 00cdf8290984fff0000000010018000fdf53c018703c5751 000000000000000000000000000000000000000000000000 00cdf89f0984ffff400000010000030fdf53c00401000000 00cdf8ae0984fff0000000010018000fdf52c0180ce3c930 000000000000000000000000000000000000000000000000 00cdf9250984ffff400000010000000fdf52c00401000000 00cdf9340984fff0000000010018000fdf54c0186340a194 000000000000000000000000000000000000000000000000 00cdf9ab0984ffff400000010000010fdf54c00401000000 00cdfa020984fff0000000010018000fdf51c018c33736f2 000000000000000000000000000000000000000000000000 00cdfa790984ffff400000010000020fdf51c00401000000 00cdfa880984fff0000000010018000fdf53c0181def540b 000000000000000000000000000000000000000000000000 00cdfafe0984ffff400000010000030fdf53c00401000000 00cdfb0e0984fff0000000010018000fdf52c0186130ca6a 000000000000000000000000000000000000000000000000 00cdfb840984ffff400000010000000fdf52c00401000000 00cdfb940984fff0000000010018000fdf54c0180e93a2ce 000000000000000000000000000000000000000000000000 00cdfc0a0984ffff400000010000010fdf54c00401000000 00cdfc620984fff0000000010018000fdf51c018aee435a8 000000000000000000000000000000000000000000000000 00cdfcd80984ffff400000010000020fdf51c00401000000 00cdfce80984fff0000000010018000fdf53c018e365c94b 000000000000000000000000000000000000000000000000 00cdfd5e0984ffff400000010000030fdf53c00401000000 00cdfd6e0984fff0000000010018000fdf52c0189fba572a 000000000000000000000000000000000000000000000000 00cdfde40984ffff400000010000000fdf52c00401000000 00cdfdf30984fff0000000010018000fdf54c018f0193f8e 000000000000000000000000000000000000000000000000 00cdfe6a0984ffff400000010000010fdf54c00401000000 00cdfec20984fff0000000010018000fdf51c018506ea8e8 000000000000000000000000000000000000000000000000 00cdff380984ffff400000010000020fdf51c00401000000 00cdff470984fff0000000010018000fdf53c0188eb6ca11 000000000000000000000000000000000000000000000000 00cdffbd0984ffff400000010000030fdf53c00401000000 00cdffcd0984fff0000000010018000fdf52c018f2695470 000000000000000000000000000000000000000000000000 00ce00430984ffff400000010000000fdf52c00401000000 00ce00530984fff0000000010018000fdf54c0189dca3cd4 000000000000000000000000000000000000000000000000 00ce00c90984ffff400000010000010fdf54c00401000000 00ce01210984fff0000000010018000fdf51c0183dbdabb2 000000000000000000000000000000000000000000000000 00ce01970984ffff400000010000020fdf51c00401000000 00ce01a70984fff0000000010018000fdf53c01839c3ceff 000000000000000000000000000000000000000000000000 00ce021d0984ffff400000010000030fdf53c00401000000 00ce022d0984fff0000000010018000fdf52c018451c509e 000000000000000000000000000000000000000000000000 00ce02a30984ffff400000010000000fdf52c00401000000 00ce02b30984fff0000000010018000fdf54c0182abf383a 000000000000000000000000000000000000000000000000 00ce03290984ffff400000010000010fdf54c00401000000 00ce03810984fff0000000010018000fdf51c0188ac8af5c 000000000000000000000000000000000000000000000000 00ce03f60984ffff400000010000020fdf51c00401000000 00ce04060984fff0000000010018000fdf53c0185410cda5 000000000000000000000000000000000000000000000000 00ce047c0984ffff400000010000030fdf53c00401000000 00ce048e0984fff0000000010018000fdf52c01828cf53c4 000000000000000000000000000000000000000000000000 00ce05040984ffff400000010000000fdf52c00401000000 00ce05140984fff0000000010018000fdf54c018476c3b60 000000000000000000000000000000000000000000000000 00ce058a0984ffff400000010000010fdf54c00401000000 00ce05e30984fff0000000010018000fdf51c018e71bac06 000000000000000000000000000000000000000000000000 00ce06580984ffff400000010000020fdf51c00401000000 00ce06680984fff0000000010018000fdf53c018162eb7f8 000000000000000000000000000000000000000000000000 00ce06e00984ffff400000010000030fdf53c00401000000 00ce06ee0984fff0000000010018000fdf52c0186af12999 000000000000000000000000000000000000000000000000 00ce07640984ffff400000010000000fdf52c00401000000 00ce07740984fff0000000010018000fdf54c0180552413d 000000000000000000000000000000000000000000000000 00ce07ea0984ffff400000010000010fdf54c00401000000 00ce08420984fff0000000010018000fdf51c018a525d65b 000000000000000000000000000000000000000000000000 00ce08b80984ffff400000010000020fdf51c00401000000 00ce08c80984fff0000000010018000fdf53c0187bfdb4a2 000000000000000000000000000000000000000000000000 00ce093e0984ffff400000010000030fdf53c00401000000 00ce094d0984fff0000000010018000fdf52c01807222ac3 000000000000000000000000000000000000000000000000 00ce09c30984ffff400000010000000fdf52c00401000000 00ce09d30984fff0000000010018000fdf54c01868814267 000000000000000000000000000000000000000000000000 00ce0a490984ffff400000010000010fdf54c00401000000 00ce0aa50984fff0000000010018000fdf51c018c8f6d501 000000000000000000000000000000000000000000000000 00ce0b1c0984ffff400000010000020fdf51c00401000000 00ce0b2c0984fff0000000010018000fdf53c018cc88b04c 000000000000000000000000000000000000000000000000 00ce0ba20984ffff400000010000030fdf53c00401000000 00ce0bb20984fff0000000010018000fdf52c018b0572e2d 000000000000000000000000000000000000000000000000 00ce0c270984ffff400000010000000fdf52c00401000000 00ce0c370984fff0000000010018000fdf54c018dff44689 000000000000000000000000000000000000000000000000 00ce0cad0984ffff400000010000010fdf54c00401000000 00ce0d050984fff0000000010018000fdf51c0187f83d1ef 000000000000000000000000000000000000000000000000 00ce0d7b0984ffff400000010000020fdf51c00401000000 00ce0d8b0984fff0000000010018000fdf53c018a15bb316 000000000000000000000000000000000000000000000000 00ce0e020984ffff400000010000030fdf53c00401000000 00ce0e110984fff0000000010018000fdf52c018dd842d77 000000000000000000000000000000000000000000000000 00ce0e870984ffff400000010000000fdf52c00401000000 00ce0e970984fff0000000010018000fdf54c018b22745d3 000000000000000000000000000000000000000000000000 00ce0f0d0984ffff400000010000010fdf54c00401000000 00ce0f640984fff0000000010018000fdf51c0181250d2b5 000000000000000000000000000000000000000000000000 00ce0fdb0984ffff400000010000020fdf51c00401000000 00ce0feb0984fff0000000010018000fdf53c01848f444f6 000000000000000000000000000000000000000000000000 00ce10610984ffff400000010000030fdf53c00401000000 00ce10710984fff0000000010018000fdf52c018342bda97 000000000000000000000000000000000000000000000000 00ce10e70984ffff400000010000000fdf52c00401000000 00ce10f70984fff0000000010018000fdf54c0185b88b233 000000000000000000000000000000000000000000000000 00ce116d0984ffff400000010000010fdf54c00401000000 00ce11c40984fff0000000010018000fdf51c018fbff2555 000000000000000000000000000000000000000000000000 00ce123a0984ffff400000010000020fdf51c00401000000 00ce124a0984fff0000000010018000fdf53c018252747ac 000000000000000000000000000000000000000000000000 00ce12c00984ffff400000010000030fdf53c00401000000 00ce12d00984fff0000000010018000fdf52c01859f8d9cd 000000000000000000000000000000000000000000000000 00ce13460984ffff400000010000000fdf52c00401000000 00ce13560984fff0000000010018000fdf54c018365bb169 000000000000000000000000000000000000000000000000 00ce13cc0984ffff400000010000010fdf54c00401000000 00ce14260984fff0000000010018000fdf51c018962c260f 000000000000000000000000000000000000000000000000 00ce149c0984ffff400000010000020fdf51c00401000000 00ce14ab0984fff0000000010018000fdf53c01892524342 000000000000000000000000000000000000000000000000 00ce15210984ffff400000010000030fdf53c00401000000 00ce15310984fff0000000010018000fdf52c018ee8ddd23 000000000000000000000000000000000000000000000000 00ce15a70984ffff400000010000000fdf52c00401000000 00ce15b70984fff0000000010018000fdf54c018812eb587 000000000000000000000000000000000000000000000000 00ce162d0984ffff400000010000010fdf54c00401000000 00ce16860984fff0000000010018000fdf51c018215922e1 000000000000000000000000000000000000000000000000 00ce16fc0984ffff400000010000020fdf51c00401000000 00ce170c0984fff0000000010018000fdf53c018ff814018 000000000000000000000000000000000000000000000000 00ce17810984ffff400000010000030fdf53c00401000000 00ce17910984fff0000000010018000fdf52c018835ede79 000000000000000000000000000000000000000000000000 00ce18070984ffff400000010000000fdf52c00401000000 00ce18170984fff0000000010018000fdf54c018ecfdb6dd 000000000000000000000000000000000000000000000000 00ce188e0984ffff400000010000010fdf54c00401000000 00ce18f60984fff0000000010018000fdf51c0184c8a21bb 000000000000000000000000000000000000000000000000 00ce196b0984ffff400000010000020fdf51c00401000000 00ce197b0984fff0000000010018000fdf53c018bdbf3a45 000000000000000000000000000000000000000000000000 00ce19f10984ffff400000010000030fdf53c00401000000 00ce1a010984fff0000000010018000fdf52c018c160a424 000000000000000000000000000000000000000000000000 00ce1a770984ffff400000010000000fdf52c00401000000 00ce1a860984fff0000000010018000fdf54c018aec3cc80 000000000000000000000000000000000000000000000000 00ce1afc0984ffff400000010000010fdf54c00401000000 00ce1b540984fff0000000010018000fdf51c0180eb45be6 000000000000000000000000000000000000000000000000 00ce1bcb0984ffff400000010000020fdf51c00401000000 00ce1bdb0984fff0000000010018000fdf53c018d06c391f 000000000000000000000000000000000000000000000000 00ce1c510984ffff400000010000030fdf53c00401000000 00ce1c610984fff0000000010018000fdf52c018acb3a77e 000000000000000000000000000000000000000000000000 00ce1cd70984ffff400000010000000fdf52c00401000000 00ce1ce70984fff0000000010018000fdf54c018c310cfda 000000000000000000000000000000000000000000000000 00ce1d5c0984ffff400000010000010fdf54c00401000000 00ce1db30984fff0000000010018000fdf51c018636758bc 000000000000000000000000000000000000000000000000 00ce1e280984ffff400000010000020fdf51c00401000000 00ce1e380984fff0000000010018000fdf53c01867193df1 000000000000000000000000000000000000000000000000 00ce1eae0984ffff400000010000030fdf53c00401000000 00ce1ebe0984fff0000000010018000fdf52c0181bc6a390 000000000000000000000000000000000000000000000000 00ce1f340984ffff400000010000000fdf52c00401000000 00ce1f440984fff0000000010018000fdf54c0187465cb34 000000000000000000000000000000000000000000000000 00ce1fba0984ffff400000010000010fdf54c00401000000 00ce20120984fff0000000010018000fdf51c018d4125c52 000000000000000000000000000000000000000000000000 00ce20880984ffff400000010000020fdf51c00401000000 00ce20980984fff0000000010018000fdf53c0180aca3eab 000000000000000000000000000000000000000000000000 00ce210e0984ffff400000010000030fdf53c00401000000 00ce211e0984fff0000000010018000fdf52c0187615a0ca 000000000000000000000000000000000000000000000000 00ce21940984ffff400000010000000fdf52c00401000000 00ce21a30984fff0000000010018000fdf54c01819b6c86e 000000000000000000000000000000000000000000000000 00ce221a0984ffff400000010000010fdf54c00401000000 00ce22720984fff0000000010018000fdf51c018b9c15f08 000000000000000000000000000000000000000000000000 00ce22e90984ffff400000010000020fdf51c00401000000 00ce22f90984fff0000000010018000fdf53c01882a1ac76 000000000000000000000000000000000000000000000000 00ce236f0984ffff400000010000030fdf53c00401000000 00ce237f0984fff0000000010018000fdf52c018fe7e3217 000000000000000000000000000000000000000000000000 00ce23f50984ffff400000010000000fdf52c00401000000 00ce24050984fff0000000010018000fdf54c01891dd5ab3 000000000000000000000000000000000000000000000000 00ce247b0984ffff400000010000010fdf54c00401000000 00ce24d30984fff0000000010018000fdf51c01831aacdd5 000000000000000000000000000000000000000000000000 00ce25490984ffff400000010000020fdf51c00401000000 00ce25590984fff0000000010018000fdf53c018ef72af2c 000000000000000000000000000000000000000000000000 00ce25cf0984ffff400000010000030fdf53c00401000000 00ce25df0984fff0000000010018000fdf52c01893ad314d 000000000000000000000000000000000000000000000000 00ce26550984ffff400000010000000fdf52c00401000000 00ce26650984fff0000000010018000fdf54c018fc0e59e9 000000000000000000000000000000000000000000000000 00ce26db0984ffff400000010000010fdf54c00401000000 00ce27320984fff0000000010018000fdf51c0185c79ce8f 000000000000000000000000000000000000000000000000 00ce27a90984ffff400000010000020fdf51c00401000000 00ce27b80984fff0000000010018000fdf53c0185807abc2 000000000000000000000000000000000000000000000000 00ce282f0984ffff400000010000030fdf53c00401000000 00ce283f0984fff0000000010018000fdf52c01824d835a3 000000000000000000000000000000000000000000000000 00ce28b40984ffff400000010000000fdf52c00401000000 00ce28c40984fff0000000010018000fdf54c0184b7b5d07 000000000000000000000000000000000000000000000000 00ce293a0984ffff400000010000010fdf54c00401000000 00ce29920984fff0000000010018000fdf51c018eb0cca61 000000000000000000000000000000000000000000000000 00ce2a080984ffff400000010000020fdf51c00401000000 00ce2a180984fff0000000010018000fdf53c01835d4a898 000000000000000000000000000000000000000000000000 00ce2a8e0984ffff400000010000030fdf53c00401000000 00ce2a9e0984fff0000000010018000fdf52c018490b36f9 000000000000000000000000000000000000000000000000 00ce2b140984ffff400000010000000fdf52c00401000000 00ce2b240984fff0000000010018000fdf54c01826a85e5d 000000000000000000000000000000000000000000000000 00ce2b9a0984ffff400000010000010fdf54c00401000000 00ce2bf20984fff0000000010018000fdf51c01886dfc93b 000000000000000000000000000000000000000000000000 00ce2c680984ffff400000010000020fdf51c00401000000 00ce2c770984fff0000000010018000fdf53c01877ead2c5 000000000000000000000000000000000000000000000000 00ce2cee0984ffff400000010000030fdf53c00401000000 00ce2cfe0984fff0000000010018000fdf52c0180b354ca4 000000000000000000000000000000000000000000000000 00ce2d740984ffff400000010000000fdf52c00401000000 00ce2d830984fff0000000010018000fdf54c01864962400 000000000000000000000000000000000000000000000000 00ce2df90984ffff400000010000010fdf54c00401000000 00ce2e720984fff0000000010018000fdf51c018c4e1b366 000000000000000000000000000000000000000000000000 00ce2ee70984ffff400000010000020fdf51c00401000000 00ce2ef70984fff0000000010018000fdf53c0181a39d19f 000000000000000000000000000000000000000000000000 00ce2f6d0984ffff400000010000030fdf53c00401000000 00ce2f7d0984fff0000000010018000fdf52c01866e64ffe 000000000000000000000000000000000000000000000000 00ce2ff30984ffff400000010000000fdf52c00401000000 00ce30030984fff0000000010018000fdf54c0180945275a 000000000000000000000000000000000000000000000000 00ce30790984ffff400000010000010fdf54c00401000000 00ce30d50984fff0000000010018000fdf51c018a932b03c 000000000000000000000000000000000000000000000000 00ce314b0984ffff400000010000020fdf51c00401000000 00ce315b0984fff0000000010018000fdf53c018ad4cd571 000000000000000000000000000000000000000000000000 00ce31d10984ffff400000010000030fdf53c00401000000 00ce31e10984fff0000000010018000fdf52c018d1934b10 000000000000000000000000000000000000000000000000 00ce32570984ffff400000010000000fdf52c00401000000 00ce32660984fff0000000010018000fdf54c018be3023b4 000000000000000000000000000000000000000000000000 00ce32dd0984ffff400000010000010fdf54c00401000000 00ce33340984fff0000000010018000fdf51c0181e47b4d2 000000000000000000000000000000000000000000000000 00ce33ab0984ffff400000010000020fdf51c00401000000 00ce33bb0984fff0000000010018000fdf53c018c09fd62b 000000000000000000000000000000000000000000000000 00ce34320984ffff400000010000030fdf53c00401000000 00ce34420984fff0000000010018000fdf52c018bc40484a 000000000000000000000000000000000000000000000000 00ce34b80984ffff400000010000000fdf52c00401000000 00ce34c80984fff0000000010018000fdf54c018d3e320ee 000000000000000000000000000000000000000000000000 00ce353e0984ffff400000010000010fdf54c00401000000 00ce35950984fff0000000010018000fdf51c0187394b788 000000000000000000000000000000000000000000000000 00ce360a0984ffff400000010000020fdf51c00401000000 00ce361a0984fff0000000010018000fdf53c018293021cb 000000000000000000000000000000000000000000000000 00ce36900984ffff400000010000030fdf53c00401000000 00ce36a00984fff0000000010018000fdf52c01855efbfaa 000000000000000000000000000000000000000000000000 00ce37160984ffff400000010000000fdf52c00401000000 00ce37250984fff0000000010018000fdf54c0183a4cd70e 000000000000000000000000000000000000000000000000 00ce379c0984ffff400000010000010fdf54c00401000000 00ce37f30984fff0000000010018000fdf51c0189a3b4068 000000000000000000000000000000000000000000000000 00ce386a0984ffff400000010000020fdf51c00401000000 00ce387a0984fff0000000010018000fdf53c01844e32291 000000000000000000000000000000000000000000000000 00ce38f00984ffff400000010000030fdf53c00401000000 00ce38ff0984fff0000000010018000fdf52c018383cbcf0 000000000000000000000000000000000000000000000000 00ce39760984ffff400000010000000fdf52c00401000000 00ce39850984fff0000000010018000fdf54c018579fd454 000000000000000000000000000000000000000000000000 00ce39fb0984ffff400000010000010fdf54c00401000000 00ce3a530984fff0000000010018000fdf51c018f7e84332 000000000000000000000000000000000000000000000000 00ce3ac90984ffff400000010000020fdf51c00401000000 00ce3ad90984fff0000000010018000fdf53c018f396267f 000000000000000000000000000000000000000000000000 00ce3b4f0984ffff400000010000030fdf53c00401000000 00ce3b5f0984fff0000000010018000fdf52c0188f49b81e 000000000000000000000000000000000000000000000000 00ce3bd50984ffff400000010000000fdf52c00401000000 00ce3be50984fff0000000010018000fdf54c018e0ead0ba 000000000000000000000000000000000000000000000000 00ce3c5b0984ffff400000010000010fdf54c00401000000 00ce3cb30984fff0000000010018000fdf51c018409d47dc 000000000000000000000000000000000000000000000000 00ce3d290984ffff400000010000020fdf51c00401000000 00ce3d390984fff0000000010018000fdf53c0189e452525 000000000000000000000000000000000000000000000000 00ce3daf0984ffff400000010000030fdf53c00401000000 00ce3dbe0984fff0000000010018000fdf52c018e29abb44 000000000000000000000000000000000000000000000000 00ce3e350984ffff400000010000000fdf52c00401000000 00ce3e440984fff0000000010018000fdf54c0188d39d3e0 000000000000000000000000000000000000000000000000 00ce3eba0984ffff400000010000010fdf54c00401000000 00ce3f330984fff0000000010018000fdf51c0182d4e4486 000000000000000000000000000000000000000000000000 00ce3fa90984ffff400000010000020fdf51c00401000000 00ce3fb90984fff0000000010018000fdf53c018dc7b5f78 000000000000000000000000000000000000000000000000 00ce402e0984ffff400000010000030fdf53c00401000000 00ce403e0984fff0000000010018000fdf52c018a0a4c119 000000000000000000000000000000000000000000000000 00ce40b40984ffff400000010000000fdf52c00401000000 00ce40c40984fff0000000010018000fdf54c018cf07a9bd 000000000000000000000000000000000000000000000000 00ce413a0984ffff400000010000010fdf54c00401000000 00ce41920984fff0000000010018000fdf51c0186f703edb 000000000000000000000000000000000000000000000000 00ce42080984ffff400000010000020fdf51c00401000000 00ce42180984fff0000000010018000fdf53c018b1a85c22 000000000000000000000000000000000000000000000000 00ce428f0984ffff400000010000030fdf53c00401000000 00ce429e0984fff0000000010018000fdf52c018cd77c243 000000000000000000000000000000000000000000000000 00ce43140984ffff400000010000000fdf52c00401000000 00ce43240984fff0000000010018000fdf54c018a2d4aae7 000000000000000000000000000000000000000000000000 00ce439a0984ffff400000010000010fdf54c00401000000 00ce43f20984fff0000000010018000fdf51c01802a33d81 000000000000000000000000000000000000000000000000 00ce44680984ffff400000010000020fdf51c00401000000 00ce44780984fff0000000010018000fdf53c01806dd58cc 000000000000000000000000000000000000000000000000 00ce44ee0984ffff400000010000030fdf53c00401000000 00ce44fe0984fff0000000010018000fdf52c0187a02c6ad 000000000000000000000000000000000000000000000000 00ce45750984ffff400000010000000fdf52c00401000000 00ce45870984fff0000000010018000fdf54c01815a1ae09 000000000000000000000000000000000000000000000000 00ce45fd0984ffff400000010000010fdf54c00401000000 00ce46550984fff0000000010018000fdf51c018b5d6396f 000000000000000000000000000000000000000000000000 00ce46cb0984ffff400000010000020fdf51c00401000000 00ce46db0984fff0000000010018000fdf53c0186b0e5b96 000000000000000000000000000000000000000000000000 00ce47510984ffff400000010000030fdf53c00401000000 00ce47610984fff0000000010018000fdf52c01817d1c5f7 000000000000000000000000000000000000000000000000 00ce47d90984ffff400000010000000fdf52c00401000000 00ce47e70984fff0000000010018000fdf54c0187872ad53 000000000000000000000000000000000000000000000000 00ce485d0984ffff400000010000010fdf54c00401000000 00ce48b40984fff0000000010018000fdf51c018d8053a35 000000000000000000000000000000000000000000000000 00ce492b0984ffff400000010000020fdf51c00401000000 00ce493a0984fff0000000010018000fdf53c0189584c6d6 000000000000000000000000000000000000000000000000 00ce49b10984ffff400000010000030fdf53c00401000000 00ce49c00984fff0000000010018000fdf52c018e95b58b7 000000000000000000000000000000000000000000000000 00ce4a370984ffff400000010000000fdf52c00401000000 00ce4a460984fff0000000010018000fdf54c01886f83013 000000000000000000000000000000000000000000000000 00ce4abc0984ffff400000010000010fdf54c00401000000 00ce4b150984fff0000000010018000fdf51c018268fa775 000000000000000000000000000000000000000000000000 00ce4b8a0984ffff400000010000020fdf51c00401000000 00ce4b9a0984fff0000000010018000fdf53c018f857c58c 000000000000000000000000000000000000000000000000 00ce4c100984ffff400000010000030fdf53c00401000000 00ce4c200984fff0000000010018000fdf52c01884885bed 000000000000000000000000000000000000000000000000 00ce4c960984ffff400000010000000fdf52c00401000000 00ce4ca60984fff0000000010018000fdf54c018eb2b3349 000000000000000000000000000000000000000000000000 00ce4d1c0984ffff400000010000010fdf54c00401000000 00ce4d740984fff0000000010018000fdf51c0184b5ca42f 000000000000000000000000000000000000000000000000 00ce4dea0984ffff400000010000020fdf51c00401000000 00ce4dfa0984fff0000000010018000fdf53c0184f22c162 000000000000000000000000000000000000000000000000 00ce4e700984ffff400000010000030fdf53c00401000000 00ce4e7f0984fff0000000010018000fdf52c01833fd5f03 000000000000000000000000000000000000000000000000 00ce4ef60984ffff400000010000000fdf52c00401000000 00ce4f050984fff0000000010018000fdf54c0185c5e37a7 000000000000000000000000000000000000000000000000 00ce4f7b0984ffff400000010000010fdf54c00401000000 00ce4fd30984fff0000000010018000fdf51c018fc29a0c1 000000000000000000000000000000000000000000000000 00ce504a0984ffff400000010000020fdf51c00401000000 00ce505a0984fff0000000010018000fdf53c01822f1c238 000000000000000000000000000000000000000000000000 00ce50d00984ffff400000010000030fdf53c00401000000 00ce50e00984fff0000000010018000fdf52c0185e2e5c59 000000000000000000000000000000000000000000000000 00ce51550984ffff400000010000000fdf52c00401000000 00ce51650984fff0000000010018000fdf54c018318d34fd 000000000000000000000000000000000000000000000000 00ce51db0984ffff400000010000010fdf54c00401000000 00ce52330984fff0000000010018000fdf51c01891faa39b 000000000000000000000000000000000000000000000000 00ce52a90984ffff400000010000020fdf51c00401000000 00ce52b90984fff0000000010018000fdf53c01860cfb865 000000000000000000000000000000000000000000000000 00ce532f0984ffff400000010000030fdf53c00401000000 00ce533f0984fff0000000010018000fdf52c0181c102604 000000000000000000000000000000000000000000000000 00ce53b50984ffff400000010000000fdf52c00401000000 00ce53c50984fff0000000010018000fdf54c01873b34ea0 000000000000000000000000000000000000000000000000 00ce543a0984ffff400000010000010fdf54c00401000000 00ce54930984fff0000000010018000fdf51c018d3c4d9c6 000000000000000000000000000000000000000000000000 00ce55090984ffff400000010000020fdf51c00401000000 00ce55190984fff0000000010018000fdf53c0180d1cbb3f 000000000000000000000000000000000000000000000000 00ce558f0984ffff400000010000030fdf53c00401000000 00ce559f0984fff0000000010018000fdf52c01871c3255e 000000000000000000000000000000000000000000000000 00ce56150984ffff400000010000000fdf52c00401000000 00ce56250984fff0000000010018000fdf54c0181e604dfa 000000000000000000000000000000000000000000000000 00ce569b0984ffff400000010000010fdf54c00401000000 00ce56f60984fff0000000010018000fdf51c018be17da9c 000000000000000000000000000000000000000000000000 00ce576c0984ffff400000010000020fdf51c00401000000 00ce577c0984fff0000000010018000fdf53c018ba69bfd1 000000000000000000000000000000000000000000000000 00ce57f20984ffff400000010000030fdf53c00401000000 00ce58020984fff0000000010018000fdf52c018c6b621b0 000000000000000000000000000000000000000000000000 00ce58780984ffff400000010000000fdf52c00401000000 00ce58880984fff0000000010018000fdf54c018a9154914 000000000000000000000000000000000000000000000000 00ce58fe0984ffff400000010000010fdf54c00401000000 00ce59560984fff0000000010018000fdf51c0180962de72 000000000000000000000000000000000000000000000000 00ce59cb0984ffff400000010000020fdf51c00401000000 00ce59db0984fff0000000010018000fdf53c018d7babc8b 000000000000000000000000000000000000000000000000 00ce5a520984ffff400000010000030fdf53c00401000000 00ce5a620984fff0000000010018000fdf52c018ab6522ea 000000000000000000000000000000000000000000000000 00ce5ad80984ffff400000010000000fdf52c00401000000 00ce5ae80984fff0000000010018000fdf54c018c4c64a4e 000000000000000000000000000000000000000000000000 00ce5b5e0984ffff400000010000010fdf54c00401000000 00ce5bb60984fff0000000010018000fdf51c01864b1dd28 000000000000000000000000000000000000000000000000 00ce5c2c0984ffff400000010000020fdf51c00401000000 00ce5c3b0984fff0000000010018000fdf53c0183e154b6b 000000000000000000000000000000000000000000000000 00ce5cb10984ffff400000010000030fdf53c00401000000 00ce5cc10984fff0000000010018000fdf52c01842cad50a 000000000000000000000000000000000000000000000000 00ce5e110984ffff400000010000000fdf52c00401000000 00ce5e210984fff0000000010018000fdf54c0182d69bdae 000000000000000000000000000000000000000000000000 00ce5e970984ffff400000010000010fdf54c00401000000 00ce5ef30984fff0000000010018000fdf51c0188d1e2ac8 000000000000000000000000000000000000000000000000 00ce5f690984ffff400000010000020fdf51c00401000000 00ce5f790984fff0000000010018000fdf53c01853c64831 000000000000000000000000000000000000000000000000 00ce5fef0984ffff400000010000030fdf53c00401000000 00ce5fff0984fff0000000010018000fdf52c0182f19d650 000000000000000000000000000000000000000000000000 00ce60750984ffff400000010000000fdf52c00401000000 00ce60850984fff0000000010018000fdf54c01840babef4 000000000000000000000000000000000000000000000000 00ce60fb0984ffff400000010000010fdf54c00401000000 00ce61520984fff0000000010018000fdf51c018e0cd2992 000000000000000000000000000000000000000000000000 00ce61c90984ffff400000010000020fdf51c00401000000 00ce61d80984fff0000000010018000fdf53c018e4b34cdf 000000000000000000000000000000000000000000000000 00ce624e0984ffff400000010000030fdf53c00401000000 00ce625e0984fff0000000010018000fdf52c018986cd2be 000000000000000000000000000000000000000000000000 00ce62d40984ffff400000010000000fdf52c00401000000 00ce62e40984fff0000000010018000fdf54c018f7cfba1a 000000000000000000000000000000000000000000000000 00ce635a0984ffff400000010000010fdf54c00401000000 00ce63c20984fff0000000010018000fdf51c01857b82d7c 000000000000000000000000000000000000000000000000 00ce64380984ffff400000010000020fdf51c00401000000 00ce64480984fff0000000010018000fdf53c01889604f85 000000000000000000000000000000000000000000000000 00ce64be0984ffff400000010000030fdf53c00401000000 00ce64ce0984fff0000000010018000fdf52c018f5bfd1e4 000000000000000000000000000000000000000000000000 00ce65440984ffff400000010000000fdf52c00401000000 00ce65540984fff0000000010018000fdf54c0189a1cb940 000000000000000000000000000000000000000000000000 00ce65ca0984ffff400000010000010fdf54c00401000000 00ce66220984fff0000000010018000fdf51c0183a6b2e26 000000000000000000000000000000000000000000000000 00ce66980984ffff400000010000020fdf51c00401000000 00ce66a70984fff0000000010018000fdf53c018cb5e35d8 000000000000000000000000000000000000000000000000 00ce671e0984ffff400000010000030fdf53c00401000000 00ce672d0984fff0000000010018000fdf52c018b781abb9 000000000000000000000000000000000000000000000000 00ce67a40984ffff400000010000000fdf52c00401000000 00ce67b40984fff0000000010018000fdf54c018d822c31d 000000000000000000000000000000000000000000000000 00ce68290984ffff400000010000010fdf54c00401000000 00ce68810984fff0000000010018000fdf51c0187855547b 000000000000000000000000000000000000000000000000 00ce68f70984ffff400000010000020fdf51c00401000000 00ce69070984fff0000000010018000fdf53c018a68d3682 000000000000000000000000000000000000000000000000 00ce697d0984ffff400000010000030fdf53c00401000000 00ce698d0984fff0000000010018000fdf52c018da52a8e3 000000000000000000000000000000000000000000000000 00ce6a030984ffff400000010000000fdf52c00401000000 00ce6a130984fff0000000010018000fdf54c018b5f1c047 000000000000000000000000000000000000000000000000 00ce6a890984ffff400000010000010fdf54c00401000000 cb406bee0981fff0000000010018000fdf4040087dc7871a 000000000000000000000000000000000000000000000000 cb406c5e0981fff0000000010018000fdf404000ca96cac9 000000000000000000000000000000000000000000000000 cb406cce0981fff0000000010018000fdf4040043c21d05d 000000000000000000000000000000000000000000000000 cb406e180981fff0000000010018000fdf404018f6a44794 000000000000000000000000000000000000000000000000 cb406e880981fff0000000010018000fdf4040100a405627 000000000000000000000000000000000000000000000000 cb406ef80981fff0000000010018000fdf404014965dadfd 000000000000000000000000000000000000000000000000 cb40700f0981fff0000000010018000fdf4040284927b1af 000000000000000000000000000000000000000000000000 cb4070800981fff0000000010018000fdf404020fe76fc7c 000000000000000000000000000000000000000000000000 cb4070f00981fff0000000010018000fdf40402429de5bc6 000000000000000000000000000000000000000000000000 cb4071ff0981fff0000000010018000fdf404038e35bcc0f 000000000000000000000000000000000000000000000000 cb4072700981fff0000000010018000fdf404030e4066726 000000000000000000000000000000000000000000000000 cb4072e20981fff0000000010018000fdf404034781b9cfc 000000000000000000000000000000000000000000000000 cb4073e50981fff0000000010018000fdf404048a14ae518 000000000000000000000000000000000000000000000000 cb4074550981fff0000000010018000fdf404040161ba8cb 000000000000000000000000000000000000000000000000 cb4074c50981fff0000000010018000fdf40404457d9b6b1 000000000000000000000000000000000000000000000000 cb4075c30981fff0000000010018000fdf4040589d5c2178 000000000000000000000000000000000000000000000000 cb4076330981fff0000000010018000fdf40405061b830cb 000000000000000000000000000000000000000000000000 cb4076a30981fff0000000010018000fdf404054fda5cb11 000000000000000000000000000000000000000000000000 cb4077a20981fff0000000010018000fdf40406807702b7f 000000000000000000000000000000000000000000000000 cb4078130981fff0000000010018000fdf404060b02166ac 000000000000000000000000000000000000000000000000 cb4078850981fff0000000010018000fdf4040646789c116 000000000000000000000000000000000000000000000000 cb40798c0981fff0000000010018000fdf404078ad0c56df 000000000000000000000000000000000000000000000000 cb4079fe0981fff0000000010018000fdf404070c782feac 000000000000000000000000000000000000000000000000 cb407a6e0981fff0000000010018000fdf4040745b9f0576 000000000000000000000000000000000000000000000000 cb407b6c0981fff0000000010018000fdf404088a24dc47f 000000000000000000000000000000000000000000000000 cb407bdc0981fff0000000010018000fdf404080151c89ac 000000000000000000000000000000000000000000000000 cb407c4c0981fff0000000010018000fdf404084390d948c 000000000000000000000000000000000000000000000000 cb407d4b0981fff0000000010018000fdf404098f3880345 000000000000000000000000000000000000000000000000 cb407dbc0981fff0000000010018000fdf4040900f6c12f6 000000000000000000000000000000000000000000000000 cb407e2e0981fff0000000010018000fdf4040949371e92c 000000000000000000000000000000000000000000000000 cb407f2d0981fff0000000010018000fdf4040a84c0bf57e 000000000000000000000000000000000000000000000000 cb407f9e0981fff0000000010018000fdf4040a0fb5ab8ad 000000000000000000000000000000000000000000000000 cb40800f0981fff0000000010018000fdf4040a42cf21f17 000000000000000000000000000000000000000000000000 cb4081180981fff0000000010018000fdf4040b8e67788de 000000000000000000000000000000000000000000000000 cb4081890981fff0000000010018000fdf4040b03b8c2443 000000000000000000000000000000000000000000000000 cb4081f90981fff0000000010018000fdf4040b4a791df99 000000000000000000000000000000000000000000000000 cb4083000981fff0000000010018000fdf4040c87ec0a67d 000000000000000000000000000000000000000000000000 cb4083710981fff0000000010018000fdf4040c0c991ebae 000000000000000000000000000000000000000000000000 cb4083e20981fff0000000010018000fdf4040c48853f5d4 000000000000000000000000000000000000000000000000 cb4084e10981fff0000000010018000fdf4040d842d6621d 000000000000000000000000000000000000000000000000 cb4085520981fff0000000010018000fdf4040d0be3273ae 000000000000000000000000000000000000000000000000 cb4085c20981fff0000000010018000fdf4040d4222f8874 000000000000000000000000000000000000000000000000 cb4086c00981fff0000000010018000fdf4040e89086977c 000000000000000000000000000000000000000000000000 cb4087300981fff0000000010018000fdf4040e027d7daaf 000000000000000000000000000000000000000000000000 cb4087a00981fff0000000010018000fdf4040e4f07f7d15 000000000000000000000000000000000000000000000000 cb40889e0981fff0000000010018000fdf4040f83afaeadc 000000000000000000000000000000000000000000000000 cb4089100981fff0000000010018000fdf4040f0507442af 000000000000000000000000000000000000000000000000 cb4089820981fff0000000010018000fdf4040f4cc69b975 000000000000000000000000000000000000000000000000 cb408b4f0981ffff400000010000020fdf400c6000000000 00cccca50984fff0000000010018000fdf54c0184d3ef317 000000000000000000000000000000000000000000000000 00cccd1b0984ffff400000010000000fdf54c00401000000 00cccd730984fff0000000010018000fdf51c01816f0deeb 000000000000000000000000000000000000000000000000 00cccde90984ffff400000010000010fdf51c00401000000 00cccdf80984fff0000000010018000fdf53c01833910688 000000000000000000000000000000000000000000000000 00ccce6f0984ffff400000010000020fdf53c00401000000 00ccce7e0984fff0000000010018000fdf52c018d9242129 000000000000000000000000000000000000000000000000 00cccef50984ffff400000010000030fdf52c00401000000 00cccf040984fff0000000010018000fdf54c01820edf04d 000000000000000000000000000000000000000000000000 00cccf7a0984ffff400000010000000fdf54c00401000000 00cccfd20984fff0000000010018000fdf51c018a185da05 000000000000000000000000000000000000000000000000 00ccd0480984ffff400000010000010fdf51c00401000000 00ccd0580984fff0000000010018000fdf53c01884e40266 000000000000000000000000000000000000000000000000 00ccd0ce0984ffff400000010000020fdf53c00401000000 00ccd0de0984fff0000000010018000fdf52c0186e5125c7 000000000000000000000000000000000000000000000000 00ccd1540984ffff400000010000030fdf52c00401000000 00ccd1640984fff0000000010018000fdf54c0189798f4a3 000000000000000000000000000000000000000000000000 00ccd1da0984ffff400000010000000fdf54c00401000000 00ccd2320984fff0000000010018000fdf51c018cc56d95f 000000000000000000000000000000000000000000000000 00ccd2a80984ffff400000010000010fdf51c00401000000 00ccd2b70984fff0000000010018000fdf53c018e937013c 000000000000000000000000000000000000000000000000 00ccd32e0984ffff400000010000020fdf53c00401000000 00ccd33d0984fff0000000010018000fdf52c0180382269d 000000000000000000000000000000000000000000000000 00ccd3b40984ffff400000010000030fdf52c00401000000 00ccd3c30984fff0000000010018000fdf54c018fa4bf7f9 000000000000000000000000000000000000000000000000 00ccd43a0984ffff400000010000000fdf54c00401000000 00ccd4920984fff0000000010018000fdf51c018443d4b82 000000000000000000000000000000000000000000000000 00ccd5070984ffff400000010000010fdf51c00401000000 00ccd5170984fff0000000010018000fdf53c018615c93e1 000000000000000000000000000000000000000000000000 00ccd58d0984ffff400000010000020fdf53c00401000000 00ccd59d0984fff0000000010018000fdf52c0188be9b440 000000000000000000000000000000000000000000000000 00ccd6130984ffff400000010000030fdf52c00401000000 00ccd6230984fff0000000010018000fdf54c01872206524 000000000000000000000000000000000000000000000000 00ccd6990984ffff400000010000000fdf54c00401000000 00ccd6f10984fff0000000010018000fdf51c01829ee48d8 000000000000000000000000000000000000000000000000 00ccd7670984ffff400000010000010fdf51c00401000000 00ccd7770984fff0000000010018000fdf53c0180c8f90bb 000000000000000000000000000000000000000000000000 00ccd7ed0984ffff400000010000020fdf53c00401000000 00ccd7fc0984fff0000000010018000fdf52c018e63ab71a 000000000000000000000000000000000000000000000000 00ccd8730984ffff400000010000030fdf52c00401000000 00ccd8820984fff0000000010018000fdf54c0181ff3667e 000000000000000000000000000000000000000000000000 00ccd8f90984ffff400000010000000fdf54c00401000000 00ccd9510984fff0000000010018000fdf51c0189e9b4c36 000000000000000000000000000000000000000000000000 00ccd9c60984ffff400000010000010fdf51c00401000000 00ccd9d60984fff0000000010018000fdf53c018bbfa9455 000000000000000000000000000000000000000000000000 00ccda4c0984ffff400000010000020fdf53c00401000000 00ccda5c0984fff0000000010018000fdf52c018514fb3f4 000000000000000000000000000000000000000000000000 00ccdad20984ffff400000010000030fdf52c00401000000 00ccdae20984fff0000000010018000fdf54c018a8866290 000000000000000000000000000000000000000000000000 00ccdb580984ffff400000010000000fdf54c00401000000 00ccdbb00984fff0000000010018000fdf51c018f3484f6c 000000000000000000000000000000000000000000000000 00ccdc260984ffff400000010000010fdf51c00401000000 00ccdc360984fff0000000010018000fdf53c018d629970f 000000000000000000000000000000000000000000000000 00ccdcac0984ffff400000010000020fdf53c00401000000 00ccdcbc0984fff0000000010018000fdf52c0183c9cb0ae 000000000000000000000000000000000000000000000000 00ccdd320984ffff400000010000030fdf52c00401000000 00ccdd420984fff0000000010018000fdf54c018c55561ca 000000000000000000000000000000000000000000000000 00ccddb80984ffff400000010000000fdf54c00401000000 00ccde0f0984fff0000000010018000fdf51c018b1763531 000000000000000000000000000000000000000000000000 00ccde850984ffff400000010000010fdf51c00401000000 00ccde950984fff0000000010018000fdf53c0189417ed52 000000000000000000000000000000000000000000000000 00ccdf0b0984ffff400000010000020fdf53c00401000000 00ccdf1b0984fff0000000010018000fdf52c0187ea2caf3 000000000000000000000000000000000000000000000000 00ccdf920984ffff400000010000030fdf52c00401000000 00ccdfa20984fff0000000010018000fdf54c018876b1b97 000000000000000000000000000000000000000000000000 00cce0180984ffff400000010000000fdf54c00401000000 00cce0700984fff0000000010018000fdf51c018dca5366b 000000000000000000000000000000000000000000000000 00cce0e50984ffff400000010000010fdf51c00401000000 00cce0f50984fff0000000010018000fdf53c018f9c4ee08 000000000000000000000000000000000000000000000000 00cce16b0984ffff400000010000020fdf53c00401000000 00cce17b0984fff0000000010018000fdf52c0181371c9a9 000000000000000000000000000000000000000000000000 00cce1f10984ffff400000010000030fdf52c00401000000 00cce2010984fff0000000010018000fdf54c018eab818cd 000000000000000000000000000000000000000000000000 00cce2770984ffff400000010000000fdf54c00401000000 00cce2cf0984fff0000000010018000fdf51c0186bd03285 000000000000000000000000000000000000000000000000 00cce3450984ffff400000010000010fdf51c00401000000 00cce3550984fff0000000010018000fdf53c0184eb1eae6 000000000000000000000000000000000000000000000000 00cce3ca0984ffff400000010000020fdf53c00401000000 00cce3da0984fff0000000010018000fdf52c018a404cd47 000000000000000000000000000000000000000000000000 00cce4510984ffff400000010000030fdf52c00401000000 00cce4610984fff0000000010018000fdf54c0185dcd1c23 000000000000000000000000000000000000000000000000 00cce4d70984ffff400000010000000fdf54c00401000000 00cce5320984fff0000000010018000fdf51c018060331df 000000000000000000000000000000000000000000000000 00cce5a80984ffff400000010000010fdf51c00401000000 00cce5b80984fff0000000010018000fdf53c0182362e9bc 000000000000000000000000000000000000000000000000 00cce62f0984ffff400000010000020fdf53c00401000000 00cce63f0984fff0000000010018000fdf52c018c9d7ce1d 000000000000000000000000000000000000000000000000 00cce6b40984ffff400000010000030fdf52c00401000000 00cce6c40984fff0000000010018000fdf54c018301e1f79 000000000000000000000000000000000000000000000000 00cce73a0984ffff400000010000000fdf54c00401000000 00cce7910984fff0000000010018000fdf51c018efacc63f 000000000000000000000000000000000000000000000000 00cce8060984ffff400000010000010fdf51c00401000000 00cce8160984fff0000000010018000fdf53c018cacd1e5c 000000000000000000000000000000000000000000000000 00cce88c0984ffff400000010000020fdf53c00401000000 00cce89c0984fff0000000010018000fdf52c018207839fd 000000000000000000000000000000000000000000000000 00cce9120984ffff400000010000030fdf52c00401000000 00cce9220984fff0000000010018000fdf54c018d9b1e899 000000000000000000000000000000000000000000000000 00cce9970984ffff400000010000000fdf54c00401000000 00cce9f00984fff0000000010018000fdf51c018827fc565 000000000000000000000000000000000000000000000000 00ccea660984ffff400000010000010fdf51c00401000000 00ccea760984fff0000000010018000fdf53c018a71e1d06 000000000000000000000000000000000000000000000000 00cceaec0984ffff400000010000020fdf53c00401000000 00cceafc0984fff0000000010018000fdf52c0184dab3aa7 000000000000000000000000000000000000000000000000 00cceb720984ffff400000010000030fdf52c00401000000 00cceb810984fff0000000010018000fdf54c018b462ebc3 000000000000000000000000000000000000000000000000 00ccebf80984ffff400000010000000fdf54c00401000000 00ccec500984fff0000000010018000fdf51c018350ac18b 000000000000000000000000000000000000000000000000 00ccecc50984ffff400000010000010fdf51c00401000000 00ccecd50984fff0000000010018000fdf53c018106b19e8 000000000000000000000000000000000000000000000000 00cced4b0984ffff400000010000020fdf53c00401000000 00cced5b0984fff0000000010018000fdf52c018fade3e49 000000000000000000000000000000000000000000000000 00ccedd10984ffff400000010000030fdf52c00401000000 00ccede10984fff0000000010018000fdf54c0180317ef2d 000000000000000000000000000000000000000000000000 00ccee570984ffff400000010000000fdf54c00401000000 00cceeaf0984fff0000000010018000fdf51c01858d9c2d1 000000000000000000000000000000000000000000000000 00ccef250984ffff400000010000010fdf51c00401000000 00ccef350984fff0000000010018000fdf53c0187db81ab2 000000000000000000000000000000000000000000000000 00ccefab0984ffff400000010000020fdf53c00401000000 00ccefbb0984fff0000000010018000fdf52c018970d3d13 000000000000000000000000000000000000000000000000 00ccf0310984ffff400000010000030fdf52c00401000000 00ccf0410984fff0000000010018000fdf54c0186ec4ec77 000000000000000000000000000000000000000000000000 00ccf0b70984ffff400000010000000fdf54c00401000000 00ccf10f0984fff0000000010018000fdf51c0181ae7b88c 000000000000000000000000000000000000000000000000 00ccf1850984ffff400000010000010fdf51c00401000000 00ccf1950984fff0000000010018000fdf53c0183f8660ef 000000000000000000000000000000000000000000000000 00ccf20a0984ffff400000010000020fdf53c00401000000 00ccf21a0984fff0000000010018000fdf52c018d533474e 000000000000000000000000000000000000000000000000 00ccf2900984ffff400000010000030fdf52c00401000000 00ccf2a00984fff0000000010018000fdf54c0182cfa962a 000000000000000000000000000000000000000000000000 00ccf3160984ffff400000010000000fdf54c00401000000 00ccf36e0984fff0000000010018000fdf51c0187734bbd6 000000000000000000000000000000000000000000000000 00ccf3e40984ffff400000010000010fdf51c00401000000 00ccf3f40984fff0000000010018000fdf53c018525563b5 000000000000000000000000000000000000000000000000 00ccf46a0984ffff400000010000020fdf53c00401000000 00ccf47a0984fff0000000010018000fdf52c018b8e04414 000000000000000000000000000000000000000000000000 00ccf4f00984ffff400000010000030fdf52c00401000000 00ccf5000984fff0000000010018000fdf54c01841299570 000000000000000000000000000000000000000000000000 00ccf5760984ffff400000010000000fdf54c00401000000 00ccf5cd0984fff0000000010018000fdf51c018c041bf38 000000000000000000000000000000000000000000000000 00ccf6440984ffff400000010000010fdf51c00401000000 00ccf6540984fff0000000010018000fdf53c018e520675b 000000000000000000000000000000000000000000000000 00ccf6ca0984ffff400000010000020fdf53c00401000000 00ccf6d90984fff0000000010018000fdf52c0180f9540fa 000000000000000000000000000000000000000000000000 00ccf7500984ffff400000010000030fdf52c00401000000 00ccf75f0984fff0000000010018000fdf54c018f65c919e 000000000000000000000000000000000000000000000000 00ccf7d50984ffff400000010000000fdf54c00401000000 00ccf82d0984fff0000000010018000fdf51c018ad92bc62 000000000000000000000000000000000000000000000000 00ccf8a30984ffff400000010000010fdf51c00401000000 00ccf8b30984fff0000000010018000fdf53c01888f36401 000000000000000000000000000000000000000000000000 00ccf9290984ffff400000010000020fdf53c00401000000 00ccf9390984fff0000000010018000fdf52c018624643a0 000000000000000000000000000000000000000000000000 00ccf9af0984ffff400000010000030fdf52c00401000000 00ccf9bf0984fff0000000010018000fdf54c0189b8f92c4 000000000000000000000000000000000000000000000000 00ccfa350984ffff400000010000000fdf54c00401000000 00ccfa8d0984fff0000000010018000fdf51c01853182122 000000000000000000000000000000000000000000000000 00ccfb030984ffff400000010000010fdf51c00401000000 00ccfb130984fff0000000010018000fdf53c0187679f941 000000000000000000000000000000000000000000000000 00ccfb890984ffff400000010000020fdf53c00401000000 00ccfb980984fff0000000010018000fdf52c0189cccdee0 000000000000000000000000000000000000000000000000 00ccfc0f0984ffff400000010000030fdf52c00401000000 00ccfc1e0984fff0000000010018000fdf54c01865050f84 000000000000000000000000000000000000000000000000 00ccfc950984ffff400000010000000fdf54c00401000000 00ccfcec0984fff0000000010018000fdf51c0183ecb2278 000000000000000000000000000000000000000000000000 00ccfd620984ffff400000010000010fdf51c00401000000 00ccfd720984fff0000000010018000fdf53c0181baafa1b 000000000000000000000000000000000000000000000000 00ccfde80984ffff400000010000020fdf53c00401000000 00ccfdf80984fff0000000010018000fdf52c018f11fddba 000000000000000000000000000000000000000000000000 00ccfe6e0984ffff400000010000030fdf52c00401000000 00ccfe7e0984fff0000000010018000fdf54c01808d60cde 000000000000000000000000000000000000000000000000 00ccfef40984ffff400000010000000fdf54c00401000000 00ccff4c0984fff0000000010018000fdf51c01889be2696 000000000000000000000000000000000000000000000000 00ccffc20984ffff400000010000010fdf51c00401000000 00ccffd20984fff0000000010018000fdf53c018acdffef5 000000000000000000000000000000000000000000000000 00cd00480984ffff400000010000020fdf53c00401000000 00cd00570984fff0000000010018000fdf52c018466ad954 000000000000000000000000000000000000000000000000 00cd00ce0984ffff400000010000030fdf52c00401000000 00cd00dd0984fff0000000010018000fdf54c018bfa30830 000000000000000000000000000000000000000000000000 00cd01540984ffff400000010000000fdf54c00401000000 00cd01ac0984fff0000000010018000fdf51c018e46d25cc 000000000000000000000000000000000000000000000000 00cd02230984ffff400000010000010fdf51c00401000000 00cd02320984fff0000000010018000fdf53c018c10cfdaf 000000000000000000000000000000000000000000000000 00cd02a80984ffff400000010000020fdf53c00401000000 00cd02b80984fff0000000010018000fdf52c0182bb9da0e 000000000000000000000000000000000000000000000000 00cd032d0984ffff400000010000030fdf52c00401000000 00cd033d0984fff0000000010018000fdf54c018d2700b6a 000000000000000000000000000000000000000000000000 00cd03b30984ffff400000010000000fdf54c00401000000 00cd040b0984fff0000000010018000fdf51c018a6535f91 000000000000000000000000000000000000000000000000 00cd04810984ffff400000010000010fdf51c00401000000 00cd04910984fff0000000010018000fdf53c018833287f2 000000000000000000000000000000000000000000000000 00cd05070984ffff400000010000020fdf53c00401000000 00cd05170984fff0000000010018000fdf52c0186987a053 000000000000000000000000000000000000000000000000 00cd058d0984ffff400000010000030fdf52c00401000000 00cd059d0984fff0000000010018000fdf54c018904e7137 000000000000000000000000000000000000000000000000 00cd06120984ffff400000010000000fdf54c00401000000 00cd066b0984fff0000000010018000fdf51c018cb805ccb 000000000000000000000000000000000000000000000000 00cd06e10984ffff400000010000010fdf51c00401000000 00cd06f10984fff0000000010018000fdf53c018eee184a8 000000000000000000000000000000000000000000000000 00cd07670984ffff400000010000020fdf53c00401000000 00cd07770984fff0000000010018000fdf52c0180454a309 000000000000000000000000000000000000000000000000 00cd07ed0984ffff400000010000030fdf52c00401000000 00cd07fd0984fff0000000010018000fdf54c018fd9d726d 000000000000000000000000000000000000000000000000 00cd08730984ffff400000010000000fdf54c00401000000 00cd08cb0984fff0000000010018000fdf51c0187cf55825 000000000000000000000000000000000000000000000000 00cd09400984ffff400000010000010fdf51c00401000000 00cd09500984fff0000000010018000fdf53c01859948046 000000000000000000000000000000000000000000000000 00cd09c60984ffff400000010000020fdf53c00401000000 00cd09d60984fff0000000010018000fdf52c018b321a7e7 000000000000000000000000000000000000000000000000 00cd0a4c0984ffff400000010000030fdf52c00401000000 00cd0a5c0984fff0000000010018000fdf54c0184ae87683 000000000000000000000000000000000000000000000000 00cd0ad20984ffff400000010000000fdf54c00401000000 00cd0b2d0984fff0000000010018000fdf51c01811265b7f 000000000000000000000000000000000000000000000000 00cd0ba20984ffff400000010000010fdf51c00401000000 00cd0bb20984fff0000000010018000fdf53c0183447831c 000000000000000000000000000000000000000000000000 00cd0c280984ffff400000010000020fdf53c00401000000 00cd0c380984fff0000000010018000fdf52c018def2a4bd 000000000000000000000000000000000000000000000000 00cd0cae0984ffff400000010000030fdf52c00401000000 00cd0cbe0984fff0000000010018000fdf54c018273b75d9 000000000000000000000000000000000000000000000000 00cd0d340984ffff400000010000000fdf54c00401000000 00cd0d8b0984fff0000000010018000fdf51c018f889ac9f 000000000000000000000000000000000000000000000000 00cd0e020984ffff400000010000010fdf51c00401000000 00cd0e110984fff0000000010018000fdf53c018dde874fc 000000000000000000000000000000000000000000000000 00cd0e8a0984ffff400000010000020fdf53c00401000000 00cd0e9b0984fff0000000010018000fdf52c018375d535d 000000000000000000000000000000000000000000000000 00cd0f110984ffff400000010000030fdf52c00401000000 00cd0f210984fff0000000010018000fdf54c018ce948239 000000000000000000000000000000000000000000000000 00cd0f980984ffff400000010000000fdf54c00401000000 00cd0ff00984fff0000000010018000fdf51c018955aafc5 000000000000000000000000000000000000000000000000 00cd10650984ffff400000010000010fdf51c00401000000 00cd10750984fff0000000010018000fdf53c018b03b77a6 000000000000000000000000000000000000000000000000 00cd10ed0984ffff400000010000020fdf53c00401000000 00cd10fb0984fff0000000010018000fdf52c0185a8e5007 000000000000000000000000000000000000000000000000 00cd11700984ffff400000010000030fdf52c00401000000 00cd11800984fff0000000010018000fdf54c018a3478163 000000000000000000000000000000000000000000000000 00cd11f60984ffff400000010000000fdf54c00401000000 00cd124f0984fff0000000010018000fdf51c018222fab2b 000000000000000000000000000000000000000000000000 00cd12c50984ffff400000010000010fdf51c00401000000 00cd12d50984fff0000000010018000fdf53c018074e7348 000000000000000000000000000000000000000000000000 00cd134b0984ffff400000010000020fdf53c00401000000 00cd135b0984fff0000000010018000fdf52c018edfb54e9 000000000000000000000000000000000000000000000000 00cd13d10984ffff400000010000030fdf52c00401000000 00cd13e00984fff0000000010018000fdf54c0181432858d 000000000000000000000000000000000000000000000000 00cd14570984ffff400000010000000fdf54c00401000000 00cd14ae0984fff0000000010018000fdf51c0184ffca871 000000000000000000000000000000000000000000000000 00cd15240984ffff400000010000010fdf51c00401000000 00cd15340984fff0000000010018000fdf53c0186a9d7012 000000000000000000000000000000000000000000000000 00cd15aa0984ffff400000010000020fdf53c00401000000 00cd15ba0984fff0000000010018000fdf52c018802857b3 000000000000000000000000000000000000000000000000 00cd16300984ffff400000010000030fdf52c00401000000 00cd16400984fff0000000010018000fdf54c01879e186d7 000000000000000000000000000000000000000000000000 00cd16b60984ffff400000010000000fdf54c00401000000 00cd170e0984fff0000000010018000fdf51c0180dc2d22c 000000000000000000000000000000000000000000000000 00cd17840984ffff400000010000010fdf51c00401000000 00cd17940984fff0000000010018000fdf53c01828a30a4f 000000000000000000000000000000000000000000000000 00cd180a0984ffff400000010000020fdf53c00401000000 00cd181a0984fff0000000010018000fdf52c018c2162dee 000000000000000000000000000000000000000000000000 00cd18900984ffff400000010000030fdf52c00401000000 00cd18a00984fff0000000010018000fdf54c0183bdffc8a 000000000000000000000000000000000000000000000000 00cd19160984ffff400000010000000fdf54c00401000000 00cd196e0984fff0000000010018000fdf51c0186011d176 000000000000000000000000000000000000000000000000 00cd19e40984ffff400000010000010fdf51c00401000000 00cd19f40984fff0000000010018000fdf53c01845700915 000000000000000000000000000000000000000000000000 00cd1a690984ffff400000010000020fdf53c00401000000 00cd1a790984fff0000000010018000fdf52c018afc52eb4 000000000000000000000000000000000000000000000000 00cd1aef0984ffff400000010000030fdf52c00401000000 00cd1aff0984fff0000000010018000fdf54c018560cffd0 000000000000000000000000000000000000000000000000 00cd1b750984ffff400000010000000fdf54c00401000000 00cd1bcd0984fff0000000010018000fdf51c018d764d598 000000000000000000000000000000000000000000000000 00cd1c430984ffff400000010000010fdf51c00401000000 00cd1c530984fff0000000010018000fdf53c018f2050dfb 000000000000000000000000000000000000000000000000 00cd1cc90984ffff400000010000020fdf53c00401000000 00cd1cd90984fff0000000010018000fdf52c01818b02a5a 000000000000000000000000000000000000000000000000 00cd1d4f0984ffff400000010000030fdf52c00401000000 00cd1d5f0984fff0000000010018000fdf54c018e179fb3e 000000000000000000000000000000000000000000000000 00cd1dd50984ffff400000010000000fdf54c00401000000 00cd1e2d0984fff0000000010018000fdf51c018bab7d6c2 000000000000000000000000000000000000000000000000 00cd1ea30984ffff400000010000010fdf51c00401000000 00cd1eb30984fff0000000010018000fdf53c0189fd60ea1 000000000000000000000000000000000000000000000000 00cd1f290984ffff400000010000020fdf53c00401000000 00cd1f380984fff0000000010018000fdf52c01875632900 000000000000000000000000000000000000000000000000 00cd1faf0984ffff400000010000030fdf52c00401000000 00cd1fbe0984fff0000000010018000fdf54c0188caaf864 000000000000000000000000000000000000000000000000 00cd20340984ffff400000010000000fdf54c00401000000 00cd208c0984fff0000000010018000fdf51c0189f182afe 000000000000000000000000000000000000000000000000 00cd21020984ffff400000010000010fdf51c00401000000 00cd21120984fff0000000010018000fdf53c018ba79f29d 000000000000000000000000000000000000000000000000 00cd21880984ffff400000010000020fdf53c00401000000 00cd21980984fff0000000010018000fdf52c01850ccd53c 000000000000000000000000000000000000000000000000 00cd220e0984ffff400000010000030fdf52c00401000000 00cd221e0984fff0000000010018000fdf54c018a9050458 000000000000000000000000000000000000000000000000 00cd22940984ffff400000010000000fdf54c00401000000 00cd22ec0984fff0000000010018000fdf51c018f2cb29a4 000000000000000000000000000000000000000000000000 00cd23620984ffff400000010000010fdf51c00401000000 00cd23720984fff0000000010018000fdf53c018d7aaf1c7 000000000000000000000000000000000000000000000000 00cd23e80984ffff400000010000020fdf53c00401000000 00cd23f70984fff0000000010018000fdf52c0183d1fd666 000000000000000000000000000000000000000000000000 00cd246e0984ffff400000010000030fdf52c00401000000 00cd247d0984fff0000000010018000fdf54c018c4d60702 000000000000000000000000000000000000000000000000 00cd24f30984ffff400000010000000fdf54c00401000000 00cd254c0984fff0000000010018000fdf51c01845be2d4a 000000000000000000000000000000000000000000000000 00cd25c10984ffff400000010000010fdf51c00401000000 00cd25d10984fff0000000010018000fdf53c01860dff529 000000000000000000000000000000000000000000000000 00cd26470984ffff400000010000020fdf53c00401000000 00cd26570984fff0000000010018000fdf52c0188a6ad288 000000000000000000000000000000000000000000000000 00cd26cd0984ffff400000010000030fdf52c00401000000 00cd26dd0984fff0000000010018000fdf54c01873a303ec 000000000000000000000000000000000000000000000000 00cd27530984ffff400000010000000fdf54c00401000000 00cd27ab0984fff0000000010018000fdf51c018286d2e10 000000000000000000000000000000000000000000000000 00cd28210984ffff400000010000010fdf51c00401000000 00cd28310984fff0000000010018000fdf53c0180d0cf673 000000000000000000000000000000000000000000000000 00cd28a60984ffff400000010000020fdf53c00401000000 00cd28b60984fff0000000010018000fdf52c018e7b9d1d2 000000000000000000000000000000000000000000000000 00cd292c0984ffff400000010000030fdf52c00401000000 00cd293c0984fff0000000010018000fdf54c0181e7000b6 000000000000000000000000000000000000000000000000 00cd29b20984ffff400000010000000fdf54c00401000000 00cd2a0a0984fff0000000010018000fdf51c0186a53544d 000000000000000000000000000000000000000000000000 00cd2a810984ffff400000010000010fdf51c00401000000 00cd2a910984fff0000000010018000fdf53c0184f328c2e 000000000000000000000000000000000000000000000000 00cd2b070984ffff400000010000020fdf53c00401000000 00cd2b170984fff0000000010018000fdf52c018a587ab8f 000000000000000000000000000000000000000000000000 00cd2b8c0984ffff400000010000030fdf52c00401000000 00cd2b9c0984fff0000000010018000fdf54c0185c4e7aeb 000000000000000000000000000000000000000000000000 00cd2c120984ffff400000010000000fdf54c00401000000 00cd2c6a0984fff0000000010018000fdf51c01807805717 000000000000000000000000000000000000000000000000 00cd2ce00984ffff400000010000010fdf51c00401000000 00cd2cf00984fff0000000010018000fdf53c01822e18f74 000000000000000000000000000000000000000000000000 00cd2d660984ffff400000010000020fdf53c00401000000 00cd2d760984fff0000000010018000fdf52c018c854a8d5 000000000000000000000000000000000000000000000000 00cd2dec0984ffff400000010000030fdf52c00401000000 00cd2dfc0984fff0000000010018000fdf54c018319d79b1 000000000000000000000000000000000000000000000000 00cd2e710984ffff400000010000000fdf54c00401000000 00cd2eca0984fff0000000010018000fdf51c018b0f553f9 000000000000000000000000000000000000000000000000 00cd2f400984ffff400000010000010fdf51c00401000000 00cd2f500984fff0000000010018000fdf53c01895948b9a 000000000000000000000000000000000000000000000000 00cd2fc60984ffff400000010000020fdf53c00401000000 00cd2fd60984fff0000000010018000fdf52c0187f21ac3b 000000000000000000000000000000000000000000000000 00cd304c0984ffff400000010000030fdf52c00401000000 00cd305c0984fff0000000010018000fdf54c01886e87d5f 000000000000000000000000000000000000000000000000 00cd30d20984ffff400000010000000fdf54c00401000000 00cd312d0984fff0000000010018000fdf51c018dd2650a3 000000000000000000000000000000000000000000000000 00cd31a30984ffff400000010000010fdf51c00401000000 00cd31b30984fff0000000010018000fdf53c018f84788c0 000000000000000000000000000000000000000000000000 00cd322a0984ffff400000010000020fdf53c00401000000 00cd32390984fff0000000010018000fdf52c01812f2af61 000000000000000000000000000000000000000000000000 00cd32af0984ffff400000010000030fdf52c00401000000 00cd32bf0984fff0000000010018000fdf54c018eb3b7e05 000000000000000000000000000000000000000000000000 00cd33350984ffff400000010000000fdf54c00401000000 00cd338d0984fff0000000010018000fdf51c0183489a743 000000000000000000000000000000000000000000000000 00cd34030984ffff400000010000010fdf51c00401000000 00cd34130984fff0000000010018000fdf53c01811e87f20 000000000000000000000000000000000000000000000000 00cd34890984ffff400000010000020fdf53c00401000000 00cd34990984fff0000000010018000fdf52c018fb5d5881 000000000000000000000000000000000000000000000000 00cd350f0984ffff400000010000030fdf52c00401000000 00cd351f0984fff0000000010018000fdf54c018029489e5 000000000000000000000000000000000000000000000000 00cd35950984ffff400000010000000fdf54c00401000000 00cd35ed0984fff0000000010018000fdf51c018595aa419 000000000000000000000000000000000000000000000000 00cd36630984ffff400000010000010fdf51c00401000000 00cd36720984fff0000000010018000fdf53c0187c3b7c7a 000000000000000000000000000000000000000000000000 00cd36e90984ffff400000010000020fdf53c00401000000 00cd36f80984fff0000000010018000fdf52c018968e5bdb 000000000000000000000000000000000000000000000000 00cd376e0984ffff400000010000030fdf52c00401000000 00cd377e0984fff0000000010018000fdf54c0186f478abf 000000000000000000000000000000000000000000000000 00cd37f40984ffff400000010000000fdf54c00401000000 00cd384c0984fff0000000010018000fdf51c018ee2fa0f7 000000000000000000000000000000000000000000000000 00cd38c20984ffff400000010000010fdf51c00401000000 00cd38d20984fff0000000010018000fdf53c018cb4e7894 000000000000000000000000000000000000000000000000 00cd39480984ffff400000010000020fdf53c00401000000 00cd39580984fff0000000010018000fdf52c01821fb5f35 000000000000000000000000000000000000000000000000 00cd39ce0984ffff400000010000030fdf52c00401000000 00cd39de0984fff0000000010018000fdf54c018d8328e51 000000000000000000000000000000000000000000000000 00cd3a540984ffff400000010000000fdf54c00401000000 00cd3aab0984fff0000000010018000fdf51c01883fca3ad 000000000000000000000000000000000000000000000000 00cd3b220984ffff400000010000010fdf51c00401000000 00cd3b310984fff0000000010018000fdf53c018a69d7bce 000000000000000000000000000000000000000000000000 00cd3ba80984ffff400000010000020fdf53c00401000000 00cd3bb70984fff0000000010018000fdf52c0184c285c6f 000000000000000000000000000000000000000000000000 00cd3c2e0984ffff400000010000030fdf52c00401000000 00cd3c3d0984fff0000000010018000fdf54c018b5e18d0b 000000000000000000000000000000000000000000000000 00cd3cb30984ffff400000010000000fdf54c00401000000 00cd3d0b0984fff0000000010018000fdf51c018c1c2d9f0 000000000000000000000000000000000000000000000000 00cd3d810984ffff400000010000010fdf51c00401000000 00cd3d910984fff0000000010018000fdf53c018e4a30193 000000000000000000000000000000000000000000000000 00cd3e070984ffff400000010000020fdf53c00401000000 00cd3e170984fff0000000010018000fdf52c0180e162632 000000000000000000000000000000000000000000000000 00cd3e8d0984ffff400000010000030fdf52c00401000000 00cd3e9d0984fff0000000010018000fdf54c018f7dff756 000000000000000000000000000000000000000000000000 00cd3f130984ffff400000010000000fdf54c00401000000 00cd3f6b0984fff0000000010018000fdf51c018ac11daaa 000000000000000000000000000000000000000000000000 00cd3fe10984ffff400000010000010fdf51c00401000000 00cd3ff00984fff0000000010018000fdf53c018897002c9 000000000000000000000000000000000000000000000000 00cd40670984ffff400000010000020fdf53c00401000000 00cd40760984fff0000000010018000fdf52c01863c52568 000000000000000000000000000000000000000000000000 00cd40ed0984ffff400000010000030fdf52c00401000000 00cd40fc0984fff0000000010018000fdf54c0189a0cf40c 000000000000000000000000000000000000000000000000 00cd41730984ffff400000010000000fdf54c00401000000 00cd41ca0984fff0000000010018000fdf51c0181b64de44 000000000000000000000000000000000000000000000000 00cd42410984ffff400000010000010fdf51c00401000000 00cd42500984fff0000000010018000fdf53c0183e050627 000000000000000000000000000000000000000000000000 00cd42c60984ffff400000010000020fdf53c00401000000 00cd42d60984fff0000000010018000fdf52c018d4b02186 000000000000000000000000000000000000000000000000 00cd434c0984ffff400000010000030fdf52c00401000000 00cd435c0984fff0000000010018000fdf54c0182d79f0e2 000000000000000000000000000000000000000000000000 00cd43d20984ffff400000010000000fdf54c00401000000 00cd442a0984fff0000000010018000fdf51c01876b7dd1e 000000000000000000000000000000000000000000000000 00cd44a00984ffff400000010000010fdf51c00401000000 00cd44b00984fff0000000010018000fdf53c01853d6057d 000000000000000000000000000000000000000000000000 00cd45260984ffff400000010000020fdf53c00401000000 00cd45360984fff0000000010018000fdf52c018b96322dc 000000000000000000000000000000000000000000000000 00cd45ac0984ffff400000010000030fdf52c00401000000 00cd45bb0984fff0000000010018000fdf54c01840aaf3b8 000000000000000000000000000000000000000000000000 00cd46320984ffff400000010000000fdf54c00401000000 00cd468a0984fff0000000010018000fdf51c018883d405e 000000000000000000000000000000000000000000000000 00cd47000984ffff400000010000010fdf51c00401000000 00cd470f0984fff0000000010018000fdf53c018ad5c983d 000000000000000000000000000000000000000000000000 00cd47850984ffff400000010000020fdf53c00401000000 00cd47950984fff0000000010018000fdf52c01847e9bf9c 000000000000000000000000000000000000000000000000 00cd480b0984ffff400000010000030fdf52c00401000000 00cd481b0984fff0000000010018000fdf54c018be206ef8 000000000000000000000000000000000000000000000000 00cd48910984ffff400000010000000fdf54c00401000000 00cd48e90984fff0000000010018000fdf51c018e5ee4304 000000000000000000000000000000000000000000000000 00cd495f0984ffff400000010000010fdf51c00401000000 00cd496f0984fff0000000010018000fdf53c018c08f9b67 000000000000000000000000000000000000000000000000 00cd49e50984ffff400000010000020fdf53c00401000000 00cd49f50984fff0000000010018000fdf52c0182a3abcc6 000000000000000000000000000000000000000000000000 00cd4a6b0984ffff400000010000030fdf52c00401000000 00cd4a7b0984fff0000000010018000fdf54c018d3f36da2 000000000000000000000000000000000000000000000000 00cd4af10984ffff400000010000000fdf54c00401000000 00cd4b490984fff0000000010018000fdf51c018529b47ea 000000000000000000000000000000000000000000000000 00cd4bbf0984ffff400000010000010fdf51c00401000000 00cd4bce0984fff0000000010018000fdf53c01877fa9f89 000000000000000000000000000000000000000000000000 00cd4c440984ffff400000010000020fdf53c00401000000 00cd4c540984fff0000000010018000fdf52c0189d4fb828 000000000000000000000000000000000000000000000000 00cd4cca0984ffff400000010000030fdf52c00401000000 00cd4cda0984fff0000000010018000fdf54c0186486694c 000000000000000000000000000000000000000000000000 00cd4d510984ffff400000010000000fdf54c00401000000 00cd4da90984fff0000000010018000fdf51c0183f4844b0 000000000000000000000000000000000000000000000000 00cd4e1e0984ffff400000010000010fdf51c00401000000 00cd4e2e0984fff0000000010018000fdf53c0181a299cd3 000000000000000000000000000000000000000000000000 00cd4ea40984ffff400000010000020fdf53c00401000000 00cd4eb40984fff0000000010018000fdf52c018f09cbb72 000000000000000000000000000000000000000000000000 00cd4f2b0984ffff400000010000030fdf52c00401000000 00cd4f3a0984fff0000000010018000fdf54c01809556a16 000000000000000000000000000000000000000000000000 00cd4fb00984ffff400000010000000fdf54c00401000000 00cd50080984fff0000000010018000fdf51c0187d763eed 000000000000000000000000000000000000000000000000 00cd507e0984ffff400000010000010fdf51c00401000000 00cd508e0984fff0000000010018000fdf53c0185817e68e 000000000000000000000000000000000000000000000000 00cd51030984ffff400000010000020fdf53c00401000000 00cd51130984fff0000000010018000fdf52c018b2a2c12f 000000000000000000000000000000000000000000000000 00cd51890984ffff400000010000030fdf52c00401000000 00cd51990984fff0000000010018000fdf54c0184b6b104b 000000000000000000000000000000000000000000000000 00cd520f0984ffff400000010000000fdf54c00401000000 00cd52680984fff0000000010018000fdf51c01810a53db7 000000000000000000000000000000000000000000000000 00cd52de0984ffff400000010000010fdf51c00401000000 00cd52ee0984fff0000000010018000fdf53c01835c4e5d4 000000000000000000000000000000000000000000000000 00cd53640984ffff400000010000020fdf53c00401000000 00cd53740984fff0000000010018000fdf52c018df71c275 000000000000000000000000000000000000000000000000 00cd53e90984ffff400000010000030fdf52c00401000000 00cd53f90984fff0000000010018000fdf54c01826b81311 000000000000000000000000000000000000000000000000 00cd546f0984ffff400000010000000fdf54c00401000000 00cd54c70984fff0000000010018000fdf51c018a7d03959 000000000000000000000000000000000000000000000000 00cd553d0984ffff400000010000010fdf51c00401000000 00cd554d0984fff0000000010018000fdf53c01882b1e13a 000000000000000000000000000000000000000000000000 00cd55c30984ffff400000010000020fdf53c00401000000 00cd55d30984fff0000000010018000fdf52c0186804c69b 000000000000000000000000000000000000000000000000 00cd56490984ffff400000010000030fdf52c00401000000 00cd56590984fff0000000010018000fdf54c01891cd17ff 000000000000000000000000000000000000000000000000 00cd56ce0984ffff400000010000000fdf54c00401000000 00cd572a0984fff0000000010018000fdf51c018ca033a03 000000000000000000000000000000000000000000000000 00cd57a00984ffff400000010000010fdf51c00401000000 00cd57b00984fff0000000010018000fdf53c018ef62e260 000000000000000000000000000000000000000000000000 00cd58270984ffff400000010000020fdf53c00401000000 00cd58370984fff0000000010018000fdf52c01805d7c5c1 000000000000000000000000000000000000000000000000 00cd58ad0984ffff400000010000030fdf52c00401000000 00cd58bd0984fff0000000010018000fdf54c018fc1e14a5 000000000000000000000000000000000000000000000000 00cd59330984ffff400000010000000fdf54c00401000000 00cd598a0984fff0000000010018000fdf51c01823accde3 000000000000000000000000000000000000000000000000 00cd5a000984ffff400000010000010fdf51c00401000000 00cd5a100984fff0000000010018000fdf53c01806cd1580 000000000000000000000000000000000000000000000000 00cd5a860984ffff400000010000020fdf53c00401000000 00cd5a960984fff0000000010018000fdf52c018ec783221 000000000000000000000000000000000000000000000000 00cd5b0c0984ffff400000010000030fdf52c00401000000 00cd5b1c0984fff0000000010018000fdf54c01815b1e345 000000000000000000000000000000000000000000000000 00cd5b920984ffff400000010000000fdf54c00401000000 00cd5bea0984fff0000000010018000fdf51c0184e7fceb9 000000000000000000000000000000000000000000000000 00cd5c5f0984ffff400000010000010fdf51c00401000000 00cd5c6f0984fff0000000010018000fdf53c0186b1e16da 000000000000000000000000000000000000000000000000 00cd5ce60984ffff400000010000020fdf53c00401000000 00cd5cf60984fff0000000010018000fdf52c01881ab317b 000000000000000000000000000000000000000000000000 00cd5d6c0984ffff400000010000030fdf52c00401000000 00cd5d7e0984fff0000000010018000fdf54c0187862e01f 000000000000000000000000000000000000000000000000 00cd5df40984ffff400000010000000fdf54c00401000000 00cd5e4c0984fff0000000010018000fdf51c018f90aca57 000000000000000000000000000000000000000000000000 00cd5ec20984ffff400000010000010fdf51c00401000000 00cd5ed20984fff0000000010018000fdf53c018dc6b1234 000000000000000000000000000000000000000000000000 00cd5f470984ffff400000010000020fdf53c00401000000 00cd5f570984fff0000000010018000fdf52c01836de3595 000000000000000000000000000000000000000000000000 00cd5fcd0984ffff400000010000030fdf52c00401000000 00cd5fdd0984fff0000000010018000fdf54c018cf17e4f1 000000000000000000000000000000000000000000000000 00cd60530984ffff400000010000000fdf54c00401000000 00cd60ab0984fff0000000010018000fdf51c01894d9c90d 000000000000000000000000000000000000000000000000 00cd61210984ffff400000010000010fdf51c00401000000 00cd61310984fff0000000010018000fdf53c018b1b8116e 000000000000000000000000000000000000000000000000 00cd61a70984ffff400000010000020fdf53c00401000000 00cd61b70984fff0000000010018000fdf52c0185b0d36cf 000000000000000000000000000000000000000000000000 00cd622d0984ffff400000010000030fdf52c00401000000 00cd623d0984fff0000000010018000fdf54c018a2c4e7ab 000000000000000000000000000000000000000000000000 00cd62b30984ffff400000010000000fdf54c00401000000 00cd630b0984fff0000000010018000fdf51c018d6e7b350 000000000000000000000000000000000000000000000000 00cd63810984ffff400000010000010fdf51c00401000000 00cd63910984fff0000000010018000fdf53c018f3866b33 000000000000000000000000000000000000000000000000 00cd64070984ffff400000010000020fdf53c00401000000 00cd64170984fff0000000010018000fdf52c01819334c92 000000000000000000000000000000000000000000000000 00cd648d0984ffff400000010000030fdf52c00401000000 00cd649c0984fff0000000010018000fdf54c018e0fa9df6 000000000000000000000000000000000000000000000000 00cd65120984ffff400000010000000fdf54c00401000000 00cd656a0984fff0000000010018000fdf51c018bb34b00a 000000000000000000000000000000000000000000000000 00cd65e00984ffff400000010000010fdf51c00401000000 00cd65f00984fff0000000010018000fdf53c0189e556869 000000000000000000000000000000000000000000000000 00cd66660984ffff400000010000020fdf53c00401000000 00cd66760984fff0000000010018000fdf52c01874e04fc8 000000000000000000000000000000000000000000000000 00cd66ec0984ffff400000010000030fdf52c00401000000 00cd66fc0984fff0000000010018000fdf54c0188d299eac 000000000000000000000000000000000000000000000000 00cd67720984ffff400000010000000fdf54c00401000000 00cd67ca0984fff0000000010018000fdf51c0180c41b4e4 000000000000000000000000000000000000000000000000 00cd68400984ffff400000010000010fdf51c00401000000 00cd68500984fff0000000010018000fdf53c01829206c87 000000000000000000000000000000000000000000000000 00cd68c60984ffff400000010000020fdf53c00401000000 00cd68d50984fff0000000010018000fdf52c018c3954b26 000000000000000000000000000000000000000000000000 00cd694c0984ffff400000010000030fdf52c00401000000 00cd695b0984fff0000000010018000fdf54c0183a5c9a42 000000000000000000000000000000000000000000000000 00cd69d20984ffff400000010000000fdf54c00401000000 00cd6a2a0984fff0000000010018000fdf51c0186192b7be 000000000000000000000000000000000000000000000000 00cd6aa00984ffff400000010000010fdf51c00401000000 00cd6aaf0984fff0000000010018000fdf53c01844f36fdd 000000000000000000000000000000000000000000000000 00cd6b250984ffff400000010000020fdf53c00401000000 00cd6b350984fff0000000010018000fdf52c018ae46487c 000000000000000000000000000000000000000000000000 00cd6bab0984ffff400000010000030fdf52c00401000000 00cd6bbb0984fff0000000010018000fdf54c018578f9918 000000000000000000000000000000000000000000000000 00cd6c310984ffff400000010000000fdf54c00401000000 00cd6c890984fff0000000010018000fdf51c018e9f92563 000000000000000000000000000000000000000000000000 00cd6cff0984ffff400000010000010fdf51c00401000000 00cd6d0f0984fff0000000010018000fdf53c018cc98fd00 000000000000000000000000000000000000000000000000 00cd6d850984ffff400000010000020fdf53c00401000000 00cd6d950984fff0000000010018000fdf52c018262ddaa1 000000000000000000000000000000000000000000000000 00cd6e0b0984ffff400000010000030fdf52c00401000000 00cd6e1a0984fff0000000010018000fdf54c018dfe40bc5 000000000000000000000000000000000000000000000000 00cd6e910984ffff400000010000000fdf54c00401000000 00cd6ee80984fff0000000010018000fdf51c018842a2639 000000000000000000000000000000000000000000000000 00cd6f5e0984ffff400000010000010fdf51c00401000000 00cd6f6e0984fff0000000010018000fdf53c018a14bfe5a 000000000000000000000000000000000000000000000000 00cd6fe50984ffff400000010000020fdf53c00401000000 00cd6ff50984fff0000000010018000fdf52c0184bfed9fb 000000000000000000000000000000000000000000000000 00cd706c0984ffff400000010000030fdf52c00401000000 00cd707c0984fff0000000010018000fdf54c018b237089f 000000000000000000000000000000000000000000000000 00cd70f20984ffff400000010000000fdf54c00401000000 00cd714a0984fff0000000010018000fdf51c018335f22d7 000000000000000000000000000000000000000000000000 00cd71c00984ffff400000010000010fdf51c00401000000 00cd71d00984fff0000000010018000fdf53c018163efab4 000000000000000000000000000000000000000000000000 00cd72460984ffff400000010000020fdf53c00401000000 00cd72560984fff0000000010018000fdf52c018fc8bdd15 000000000000000000000000000000000000000000000000 00cd72cc0984ffff400000010000030fdf52c00401000000 00cd72dc0984fff0000000010018000fdf54c01805420c71 000000000000000000000000000000000000000000000000 00cd73520984ffff400000010000000fdf54c00401000000 00cd73aa0984fff0000000010018000fdf51c0185e8c218d 000000000000000000000000000000000000000000000000 00cd74200984ffff400000010000010fdf51c00401000000 00cd74300984fff0000000010018000fdf53c0187bedf9ee 000000000000000000000000000000000000000000000000 00cd74a50984ffff400000010000020fdf53c00401000000 00cd74b50984fff0000000010018000fdf52c0189158de4f 000000000000000000000000000000000000000000000000 00cd752b0984ffff400000010000030fdf52c00401000000 00cd753b0984fff0000000010018000fdf54c01868910f2b 000000000000000000000000000000000000000000000000 00cd75b10984ffff400000010000000fdf54c00401000000 00cd76090984fff0000000010018000fdf51c0181cb25bd0 000000000000000000000000000000000000000000000000 00cd767f0984ffff400000010000010fdf51c00401000000 00cd768f0984fff0000000010018000fdf53c01839d383b3 000000000000000000000000000000000000000000000000 00cd77050984ffff400000010000020fdf53c00401000000 00cd77150984fff0000000010018000fdf52c018d366a412 000000000000000000000000000000000000000000000000 00cd778b0984ffff400000010000030fdf52c00401000000 00cd779b0984fff0000000010018000fdf54c0182aaf7576 000000000000000000000000000000000000000000000000 00cd78110984ffff400000010000000fdf54c00401000000 00cd78690984fff0000000010018000fdf51c0187161588a 000000000000000000000000000000000000000000000000 00cd78df0984ffff400000010000010fdf51c00401000000 00cd78ef0984fff0000000010018000fdf53c018540080e9 000000000000000000000000000000000000000000000000 00cd79650984ffff400000010000020fdf53c00401000000 00cd79740984fff0000000010018000fdf52c018beb5a748 000000000000000000000000000000000000000000000000 00cd79eb0984ffff400000010000030fdf52c00401000000 00cd79fa0984fff0000000010018000fdf54c018477c762c 000000000000000000000000000000000000000000000000 00cd7a700984ffff400000010000000fdf54c00401000000 00cd7ac90984fff0000000010018000fdf51c018c6145c64 000000000000000000000000000000000000000000000000 00cd7b3f0984ffff400000010000010fdf51c00401000000 00cd7b4f0984fff0000000010018000fdf53c018e3758407 000000000000000000000000000000000000000000000000 00cd7bc50984ffff400000010000020fdf53c00401000000 00cd7bd50984fff0000000010018000fdf52c01809c0a3a6 000000000000000000000000000000000000000000000000 00cd7c4a0984ffff400000010000030fdf52c00401000000 00cd7c5a0984fff0000000010018000fdf54c018f00972c2 000000000000000000000000000000000000000000000000 00cd7cd00984ffff400000010000000fdf54c00401000000 00cd7d2b0984fff0000000010018000fdf51c018abc75f3e 000000000000000000000000000000000000000000000000 00cd7da00984ffff400000010000010fdf51c00401000000 00cd7db00984fff0000000010018000fdf53c0188ea6875d 000000000000000000000000000000000000000000000000 00cd7e260984ffff400000010000020fdf53c00401000000 00cd7e360984fff0000000010018000fdf52c0186413a0fc 000000000000000000000000000000000000000000000000 00cd7eac0984ffff400000010000030fdf52c00401000000 00cd7ebc0984fff0000000010018000fdf54c0189dda7198 000000000000000000000000000000000000000000000000 00cd7f320984ffff400000010000000fdf54c00401000000 00cd7f890984fff0000000010018000fdf51c0184268a8de 000000000000000000000000000000000000000000000000 00cd80000984ffff400000010000010fdf51c00401000000 00cd80100984fff0000000010018000fdf53c018670970bd 000000000000000000000000000000000000000000000000 00cd80860984ffff400000010000020fdf53c00401000000 00cd80960984fff0000000010018000fdf52c0188dbc571c 000000000000000000000000000000000000000000000000 00cd810c0984ffff400000010000030fdf52c00401000000 00cd811c0984fff0000000010018000fdf54c01874758678 000000000000000000000000000000000000000000000000 00cd81920984ffff400000010000000fdf54c00401000000 00cd81ea0984fff0000000010018000fdf51c0182fbbab84 000000000000000000000000000000000000000000000000 00cd825f0984ffff400000010000010fdf51c00401000000 00cd826f0984fff0000000010018000fdf53c0180ada73e7 000000000000000000000000000000000000000000000000 00cd82e50984ffff400000010000020fdf53c00401000000 00cd82f50984fff0000000010018000fdf52c018e06f5446 000000000000000000000000000000000000000000000000 00cd836b0984ffff400000010000030fdf52c00401000000 00cd837b0984fff0000000010018000fdf54c01819a68522 000000000000000000000000000000000000000000000000 00cd83f10984ffff400000010000000fdf54c00401000000 00cd84490984fff0000000010018000fdf51c01898ceaf6a 000000000000000000000000000000000000000000000000 00cd84bf0984ffff400000010000010fdf51c00401000000 00cd84cf0984fff0000000010018000fdf53c018bdaf7709 000000000000000000000000000000000000000000000000 00cd85450984ffff400000010000020fdf53c00401000000 00cd85550984fff0000000010018000fdf52c018571a50a8 000000000000000000000000000000000000000000000000 00cd85cb0984ffff400000010000030fdf52c00401000000 00cd85db0984fff0000000010018000fdf54c018aed381cc 000000000000000000000000000000000000000000000000 00cd86510984ffff400000010000000fdf54c00401000000 00cd86a80984fff0000000010018000fdf51c018f51dac30 000000000000000000000000000000000000000000000000 00cd871f0984ffff400000010000010fdf51c00401000000 00cd872e0984fff0000000010018000fdf53c018d07c7453 000000000000000000000000000000000000000000000000 00cd87a40984ffff400000010000020fdf53c00401000000 00cd87b40984fff0000000010018000fdf52c0183ac953f2 000000000000000000000000000000000000000000000000 00cd882a0984ffff400000010000030fdf52c00401000000 00cd883a0984fff0000000010018000fdf54c018c3008296 000000000000000000000000000000000000000000000000 00cd88b00984ffff400000010000000fdf54c00401000000 00cd89080984fff0000000010018000fdf51c018b723d66d 000000000000000000000000000000000000000000000000 00cd897e0984ffff400000010000010fdf51c00401000000 00cd898e0984fff0000000010018000fdf53c01892420e0e 000000000000000000000000000000000000000000000000 00cd8a040984ffff400000010000020fdf53c00401000000 00cd8a140984fff0000000010018000fdf52c01878f729af 000000000000000000000000000000000000000000000000 00cd8a8a0984ffff400000010000030fdf52c00401000000 00cd8a9a0984fff0000000010018000fdf54c018813ef8cb 000000000000000000000000000000000000000000000000 00cd8b100984ffff400000010000000fdf54c00401000000 00cd8b680984fff0000000010018000fdf51c018daf0d537 000000000000000000000000000000000000000000000000 00cd8bde0984ffff400000010000010fdf51c00401000000 00cd8bee0984fff0000000010018000fdf53c018ff910d54 000000000000000000000000000000000000000000000000 00cd8c640984ffff400000010000020fdf53c00401000000 00cd8c730984fff0000000010018000fdf52c01815242af5 000000000000000000000000000000000000000000000000 00cd8cea0984ffff400000010000030fdf52c00401000000 00cd8cf90984fff0000000010018000fdf54c018ecedfb91 000000000000000000000000000000000000000000000000 00cd8d6f0984ffff400000010000000fdf54c00401000000 00cd8dc70984fff0000000010018000fdf51c0186d85d1d9 000000000000000000000000000000000000000000000000 00cd8e3d0984ffff400000010000010fdf51c00401000000 00cd8e4d0984fff0000000010018000fdf53c01848e409ba 000000000000000000000000000000000000000000000000 00cd8ec30984ffff400000010000020fdf53c00401000000 00cd8ed30984fff0000000010018000fdf52c018a2512e1b 000000000000000000000000000000000000000000000000 00cd8f490984ffff400000010000030fdf52c00401000000 00cd8f590984fff0000000010018000fdf54c0185b98ff7f 000000000000000000000000000000000000000000000000 00cd8fcf0984ffff400000010000000fdf54c00401000000 00cd90270984fff0000000010018000fdf51c0180056d283 000000000000000000000000000000000000000000000000 00cd909d0984ffff400000010000010fdf51c00401000000 00cd90ac0984fff0000000010018000fdf53c01825370ae0 000000000000000000000000000000000000000000000000 00cd91230984ffff400000010000020fdf53c00401000000 00cd91320984fff0000000010018000fdf52c018cf822d41 000000000000000000000000000000000000000000000000 00cd91a90984ffff400000010000030fdf52c00401000000 00cd91b80984fff0000000010018000fdf54c018364bfc25 000000000000000000000000000000000000000000000000 00cd922f0984ffff400000010000000fdf54c00401000000 00cd92870984fff0000000010018000fdf51c018fedc4fc3 000000000000000000000000000000000000000000000000 00cd92fc0984ffff400000010000010fdf51c00401000000 00cd930c0984fff0000000010018000fdf53c018dbbd97a0 000000000000000000000000000000000000000000000000 00cd93180984ffff400000010000020fdf53000000000000 00cd932b0984ffff400000010000030fdf53000006010000 00cd933e0984ffff400000010000000fdf5300000030bf2d 00cd93510984ffff400000010000010fdf53000000100000 00cd93820984ffff400000010000020fdf53c00401000000 00cd93920984fff0000000010018000fdf52c018cab10a9b 000000000000000000000000000000000000000000000000 00cd94080984ffff400000010000030fdf52c00401000000 00cd94180984fff0000000010018000fdf54c0183378dbff 000000000000000000000000000000000000000000000000 00cd94c80984fff0000000010018000fdf54800038a9bd61 000000000000000000000000000000000000000000000000 00cd964b0984fff0000000010018000fdf548000bd702bbc 000000000000000000000000000000000000000000000000 00cd96bf0984fff0000000010018000fdf548000731ce101 000000000000000000000000000000000000000000000000 00cd9a1c0984fff0000000010018000fdf54c018a512623f 000000000000000000000000000000000000000000000000 00cd9a940984ffff400000010000000fdf54c00401000000 00cd9af10984fff0000000010018000fdf51c018247a4877 000000000000000000000000000000000000000000000000 00cd9b670984ffff400000010000010fdf51c00401000000 00cd9b770984fff0000000010018000fdf53c018011b9014 000000000000000000000000000000000000000000000000 00cd9bed0984ffff400000010000020fdf53c00401000000 00cd9bfd0984fff0000000010018000fdf52c018ebaeb7b5 000000000000000000000000000000000000000000000000 00cd9c750984ffff400000010000030fdf52c00401000000 00cd9c850984fff0000000010018000fdf54c018126766d1 000000000000000000000000000000000000000000000000 00cd9cfb0984ffff400000010000000fdf54c00401000000 00cd9d520984fff0000000010018000fdf51c01849a94b2d 000000000000000000000000000000000000000000000000 00cd9dc90984ffff400000010000010fdf51c00401000000 00cd9dd90984fff0000000010018000fdf53c0186cc8934e 000000000000000000000000000000000000000000000000 00cd9e4f0984ffff400000010000020fdf53c00401000000 00cd9e5e0984fff0000000010018000fdf52c018867db4ef 000000000000000000000000000000000000000000000000 00cd9ed40984ffff400000010000030fdf52c00401000000 00cd9ee40984fff0000000010018000fdf54c0187fb4658b 000000000000000000000000000000000000000000000000 00cd9f5a0984ffff400000010000000fdf54c00401000000 00cd9fb20984fff0000000010018000fdf51c0180b973170 000000000000000000000000000000000000000000000000 00cda0280984ffff400000010000010fdf51c00401000000 00cda0380984fff0000000010018000fdf53c0182ef6e913 000000000000000000000000000000000000000000000000 00cda0ae0984ffff400000010000020fdf53c00401000000 00cda0be0984fff0000000010018000fdf52c018c443ceb2 000000000000000000000000000000000000000000000000 00cda1340984ffff400000010000030fdf52c00401000000 00cda1440984fff0000000010018000fdf54c0183d8a1fd6 000000000000000000000000000000000000000000000000 00cda1ba0984ffff400000010000000fdf54c00401000000 00cda2120984fff0000000010018000fdf51c0186644322a 000000000000000000000000000000000000000000000000 00cda2880984ffff400000010000010fdf51c00401000000 00cda2980984fff0000000010018000fdf53c0184325ea49 000000000000000000000000000000000000000000000000 00cda3070984ffff400000010000020fdf53000000000000 00cda30e0984ffff400000010000030fdf53c00401000000 00cda31b0984ffff400000010000000fdf53000000010000 00cda31d0984fff0000000010018000fdf52c018e2259188 000000000000000000000000000000000000000000000000 00cda32d0984ffff400000010000010fdf53000000000000 00cda3400984ffff400000010000020fdf53000000000000 00cda3940984ffff400000010000030fdf52c00401000000 00cda3a30984fff0000000010018000fdf54c0187146a1a2 000000000000000000000000000000000000000000000000 00cda41b0984fff0000000010018000fdf5480007a97c73c 000000000000000000000000000000000000000000000000 00cda48f0984fff0000000010018000fdf548000ff4e51e1 000000000000000000000000000000000000000000000000 00cda5020984fff0000000010018000fdf54800031229b5c 000000000000000000000000000000000000000000000000 00cda75d0984fff0000000010018000fdf54c018e72c1862 000000000000000000000000000000000000000000000000 00cda7d30984ffff400000010000000fdf54c00401000000 00cda82c0984fff0000000010018000fdf51c018bce2359e 000000000000000000000000000000000000000000000000 00cda8a30984ffff400000010000010fdf51c00401000000 00cda8b20984fff0000000010018000fdf53c0189983edfd 000000000000000000000000000000000000000000000000 00cda9290984ffff400000010000020fdf53c00401000000 00cda9380984fff0000000010018000fdf52c0187336ca5c 000000000000000000000000000000000000000000000000 00cda9af0984ffff400000010000030fdf52c00401000000 00cda9be0984fff0000000010018000fdf54c0188aff1b38 000000000000000000000000000000000000000000000000 00cdaa340984ffff400000010000000fdf54c00401000000 00cdaa8c0984fff0000000010018000fdf51c018554dc27e 000000000000000000000000000000000000000000000000 00cdab020984ffff400000010000010fdf51c00401000000 00cdab120984fff0000000010018000fdf53c018702c1a1d 000000000000000000000000000000000000000000000000 00cdab880984ffff400000010000020fdf53c00401000000 00cdab980984fff0000000010018000fdf52c0189a993dbc 000000000000000000000000000000000000000000000000 00cdac0e0984ffff400000010000030fdf52c00401000000 00cdac1e0984fff0000000010018000fdf54c0186350ecd8 000000000000000000000000000000000000000000000000 00cdac940984ffff400000010000000fdf54c00401000000 00cdacb20984ffff400000010000010fdf53010000000000 00cdacc50984ffff400000010000020fdf53010000000100 00cdacd90984ffff400000010000030fdf53010000000000 00cdacec0984ffff400000010000000fdf53010000000000 00cdacf00984fff0000000010018000fdf51c018aef478e4 000000000000000000000000000000000000000000000000 00cdacff0984ffff400000010000010fdf53010000000000 00cdad120984ffff400000010000020fdf53010000001000 00cdad660984ffff400000010000030fdf51c00401000000 00cdad760984fff0000000010018000fdf53c018e13f41c9 000000000000000000000000000000000000000000000000 00cdadec0984ffff400000010000000fdf53c00401000000 00cdadfc0984fff0000000010018000fdf52c0189de0dfa8 000000000000000000000000000000000000000000000000 00cdae720984ffff400000010000010fdf52c00401000000 00cdae820984fff0000000010018000fdf54c018f243b70c 000000000000000000000000000000000000000000000000 00cdaef80984fff0000000010018000fdf5480006ff86852 000000000000000000000000000000000000000000000000 00cdaf6b0984fff0000000010018000fdf548000ea21fe8f 000000000000000000000000000000000000000000000000 00cdafdf0984fff0000000010018000fdf548000dff48ea8 000000000000000000000000000000000000000000000000 00cdb52f0984fff0000000010018000fdf54c01809fa0d96 000000000000000000000000000000000000000000000000 00cdb5a40984ffff400000010000020fdf54c00401000000 00cdb5fc0984fff0000000010018000fdf51c018a98d9af0 000000000000000000000000000000000000000000000000 00cdb6720984ffff400000010000030fdf51c00401000000 00cdb6820984fff0000000010018000fdf53c0181a86fb53 000000000000000000000000000000000000000000000000 00cdb6f80984ffff400000010000000fdf53c00401000000 00cdb7080984fff0000000010018000fdf52c01866596532 000000000000000000000000000000000000000000000000 00cdb77e0984ffff400000010000010fdf52c00401000000 00cdb78e0984fff0000000010018000fdf54c0184bc477cb 000000000000000000000000000000000000000000000000 00cdb8060984ffff400000010000020fdf54c00401000000 00cdb85f0984fff0000000010018000fdf51c018ebb3e0ad 000000000000000000000000000000000000000000000000 00cdb8d50984ffff400000010000030fdf51c00401000000 00cdb8e50984fff0000000010018000fdf53c01858b8810e 000000000000000000000000000000000000000000000000 00cdb95c0984ffff400000010000000fdf53c00401000000 00cdb96c0984fff0000000010018000fdf52c01824671f6f 000000000000000000000000000000000000000000000000 cb408b7a1181ffff4a000001020000040018001c01000000 000000000000000000000000000000000000000000000000 cb408bea1181ffff4a000001020000040018001800100000 000000000000000000000000000000000000000000000000 00cdbacb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbb501184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbbd61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbc5c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbd2a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbdb01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbe361184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbebc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdbf8a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc00f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc0951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc11b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc1e91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc26f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc2f51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc37b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc44b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc4d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc5571184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc5dc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc6ab1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc7301184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc7b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc83c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc90a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdc9901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdca161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdca9c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdcb6a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdcbef1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdcc751184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdcce31184ffff4a000001020000040018003000000000 000000000000000000000000000000000000000000000000 00cdccfb1184ffff4a000001020000040018011800000000 000000000000000000000000000000000000000000000000 00cdcd551184ffff4a0000010200000400180034d8cccd00 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdcdc91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdce4f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 00cdce6f1180ffff20000010020000ff000000062dbf3000 00cdce721180ffff20000010020000ff000000062dbf3040 00cdce751180ffff20000010020000ff000000062dbf3080 00cdce781180ffff20000010020000ff000000062dbf30c0 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdced51184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdcf4c1184ffff4a000001020000040018000040000000 000000000000000000000000000000000000000000000000 00cdde201184ffff4a000001020000040018001803000000 000000000000000000000000000000000000000000000000 00cddeab1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cde5ae1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cde6331184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cde71d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cde7a31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 00cde7c11184ffff4a000001020000040018013000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cde8291184ffff4a000001020000040018001800000000 00cde8321184ffff4a0000010200000400180134b6e7cd00 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cde8af1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cde97d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdea021184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdea881184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdeb0e1184ffff4a000001020000040018001807000000 000000000000000000000000000000000000000000000000 00cdeb961184ffff4a000001020000040018000001000000 000000000000000000000000000000000000000000000000 00cdec0a1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cdec7d1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cdecf11184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cdee561184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdef231184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdefa91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf02f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf0b51184ffff4a000001020000040018001808000000 000000000000000000000000000000000000000000000000 00cdf12d1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cdf1a01184ffff4a000001020000040018000020000000 000000000000000000000000000000000000000000000000 00cdf4811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf54e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf5d41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf65a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf6e01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf7ae1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf8341184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf8b91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdf93f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfa0d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfa931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfb191184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfb9f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfc6d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfcf31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfd791184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfdfe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdfecd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdff521184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdffd81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce005e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce012c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce01b21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce02381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce02be1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce038c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce04111184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce04991184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce051f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce05ee1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce06731184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce06f91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce077f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce084d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce08d31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce09581184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce09de1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0ab01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0b371184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0bbd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0c421184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0d101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0d961184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0e1c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0ea21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0f6f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce0ff61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce107c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce11021184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce11cf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce12551184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce12db1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce13611184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce14311184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce14b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce153c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce15c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce16911184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce17171184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce179c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce18221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce19011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce19861184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1a0c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1a911184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1b5f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1be61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1c6c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1cf21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1dbe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1e431184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1ec91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce1f4f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce201d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce20a31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce21291184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce21ae1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce227d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce23041184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce238a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce24101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce24de1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce25641184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce25ea1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce26701184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce273d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce27c31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce284a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce28cf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce299d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2a231184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2aa91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2b2f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2bfd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2c821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2d091184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2d8e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2e7d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2f021184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce2f881184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce300e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce30e01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce31661184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce31ec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce32711184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce333f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce33c61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce344d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce34d31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce35a01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce36251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce36ab1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce37301184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce37fe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce38851184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce390a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce39901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3a5e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3ae41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3b6a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3bf01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3cbe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3d441184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3dc91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3e4f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3f3e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce3fc41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce40491184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce40cf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce419d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce42231184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce42a91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce432f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce43fd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce44831184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce45091184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce45921184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce46601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce46e61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce476c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce47f21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce48bf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce49451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce49cb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4a511184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4b201184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4ba51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4c2b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4cb11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4d7f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4e051184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4e8a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4f101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce4fde1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce50651184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce50eb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce51701184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce523e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce52c41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce534a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce53d01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce549e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce55241184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce55aa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce56301184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce57011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce57871184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce580d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce58931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce59611184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce59e61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5a6d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5af31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5bc11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5c461184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5ccc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5e2c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5efe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce5f841184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce600a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce60901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce615d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce61e31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce62691184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce62ef1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce63cd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce64531184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce64d91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce655f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce662d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce66b21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce67381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce67bf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce688c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce69121184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce69981184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ce6a1e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 cb406bf71181ffff4a000001020000040018000874400000 000000000000000000000000000000000000000000000000 cb406c671181ffff4a00000102000004001800000000e0fe 000000000000000000000000000000000000000000000000 cb406cd71181ffff4a000001020000040018000400000000 000000000000000000000000000000000000000000000000 cb406e211181ffff4a000001020000040018001884400000 000000000000000000000000000000000000000000000000 cb406e911181ffff4a00000102000004001800100000e0fe 000000000000000000000000000000000000000000000000 cb406f011181ffff4a000001020000040018001400000000 000000000000000000000000000000000000000000000000 cb4070181181ffff4a000001020000040018002894400000 000000000000000000000000000000000000000000000000 cb4070891181ffff4a00000102000004001800200000e0fe 000000000000000000000000000000000000000000000000 cb4070f91181ffff4a000001020000040018002400000000 000000000000000000000000000000000000000000000000 cb4072081181ffff4a0000010200000400180038a4400000 000000000000000000000000000000000000000000000000 cb4072791181ffff4a00000102000004001800300000e0fe 000000000000000000000000000000000000000000000000 cb4072eb1181ffff4a000001020000040018003400000000 000000000000000000000000000000000000000000000000 cb4073ee1181ffff4a0000010200000400180048b4400000 000000000000000000000000000000000000000000000000 cb40745e1181ffff4a00000102000004001800400000e0fe 000000000000000000000000000000000000000000000000 cb4074ce1181ffff4a000001020000040018004400000000 000000000000000000000000000000000000000000000000 cb4075cc1181ffff4a0000010200000400180058c4400000 000000000000000000000000000000000000000000000000 cb40763c1181ffff4a00000102000004001800500000e0fe 000000000000000000000000000000000000000000000000 cb4076ac1181ffff4a000001020000040018005400000000 000000000000000000000000000000000000000000000000 cb4077ab1181ffff4a0000010200000400180068d4400000 000000000000000000000000000000000000000000000000 cb40781c1181ffff4a00000102000004001800600000e0fe 000000000000000000000000000000000000000000000000 cb40788e1181ffff4a000001020000040018006400000000 000000000000000000000000000000000000000000000000 cb4079951181ffff4a0000010200000400180078e4400000 000000000000000000000000000000000000000000000000 cb407a071181ffff4a00000102000004001800700000e0fe 000000000000000000000000000000000000000000000000 cb407a771181ffff4a000001020000040018007400000000 000000000000000000000000000000000000000000000000 cb407b751181ffff4a000001020000040018000825400000 000000000000000000000000000000000000000000000000 cb407be51181ffff4a00000102000004001800000000e0fe 000000000000000000000000000000000000000000000000 cb407c551181ffff4a000001020000040018000400000000 000000000000000000000000000000000000000000000000 cb407d541181ffff4a000001020000040018001845400000 000000000000000000000000000000000000000000000000 cb407dc51181ffff4a00000102000004001800100000e0fe 000000000000000000000000000000000000000000000000 cb407e371181ffff4a000001020000040018001400000000 000000000000000000000000000000000000000000000000 cb407f361181ffff4a000001020000040018002855400000 000000000000000000000000000000000000000000000000 cb407fa71181ffff4a00000102000004001800200000e0fe 000000000000000000000000000000000000000000000000 cb4080181181ffff4a000001020000040018002400000000 000000000000000000000000000000000000000000000000 cb4081211181ffff4a000001020000040018003865400000 000000000000000000000000000000000000000000000000 cb4081921181ffff4a00000102000004001800300000e0fe 000000000000000000000000000000000000000000000000 cb4082021181ffff4a000001020000040018003400000000 000000000000000000000000000000000000000000000000 cb4083091181ffff4a000001020000040018004875400000 000000000000000000000000000000000000000000000000 cb40837a1181ffff4a00000102000004001800400000e0fe 000000000000000000000000000000000000000000000000 cb4083eb1181ffff4a000001020000040018004400000000 000000000000000000000000000000000000000000000000 cb4084ea1181ffff4a000001020000040018005885400000 000000000000000000000000000000000000000000000000 cb40855b1181ffff4a00000102000004001800500000e0fe 000000000000000000000000000000000000000000000000 cb4085cb1181ffff4a000001020000040018005400000000 000000000000000000000000000000000000000000000000 cb4086c91181ffff4a000001020000040018006895400000 000000000000000000000000000000000000000000000000 cb4087391181ffff4a00000102000004001800600000e0fe 000000000000000000000000000000000000000000000000 cb4087a91181ffff4a000001020000040018006400000000 000000000000000000000000000000000000000000000000 cb4088a71181ffff4a0000010200000400180078a5400000 000000000000000000000000000000000000000000000000 cb4089191181ffff4a00000102000004001800700000e0fe 000000000000000000000000000000000000000000000000 cb40898b1181ffff4a000001020000040018007400000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccccb01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cccd7e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccce031184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccce891184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cccf0f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cccfdd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd0631184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd0e91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd16f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd23d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd2c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd3481184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd3ce1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd49d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd5221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd5a81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd62e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd6fc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd7821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd8071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd88d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd95c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccd9e11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccda671184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdaed1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdbbb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdc411184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdcc71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdd4d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccde1a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdea01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdf261184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccdfad1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce07b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce1001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce1861184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce20c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce2da1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce3601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce3e51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce46c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce53d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce5c31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce64a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce6cf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce79c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce8211184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce8a71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce92d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cce9fb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccea811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cceb071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cceb8c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccec5b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccece01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cced661184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccedec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cceeba1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccef401184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccefc61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf04c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf11a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf1a01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf2251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf2ab1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf3791184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf3ff1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf4851184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf50b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf5d81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf65f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf6e41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf76a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf8381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf8be1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf9441184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccf9ca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfa981184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfb1e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfba31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfc291184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfcf71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfd7d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfe031184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccfe891184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccff571184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00ccffdd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd00621184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd00e81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd01b71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd023d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd02c31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd03481184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd04161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd049c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd05221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd05a81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd06761184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd06fc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd07821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd08081184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd08d61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd095b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd09e11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0a671184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0b381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0bbd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0c431184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0cc91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0d961184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0e1c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0ea61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0f2c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd0ffb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd10801184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd11061184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd118b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd125a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd12e01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd13661184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd13eb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd14b91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd153f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd15c51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd164b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd17191184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd179f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd18251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd18ab1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd19791184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd19ff1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1a841184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1b0a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1bd81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1c5e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1ce41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1d6a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1e381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1ebe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1f431184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd1fc91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd20971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd211d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd21a31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd22291184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd22f71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd237d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd24021184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd24881184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd25571184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd25dc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd26621184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd26e81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd27b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd283c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd28c11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd29471184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2a151184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2a9c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2b221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2ba71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2c751184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2cfb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2d811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2e071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2ed51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2f5b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd2fe11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd30671184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd31381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd31be1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd32441184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd32ca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd33981184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd341e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd34a41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd352a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd35f81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd367d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd37031184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd37891184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd38571184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd38dd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd39631184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd39e91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3ab61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3b3c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3bc21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3c481184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3d161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3d9c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3e221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3ea81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3f761184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd3ffb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd40811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd41071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd41d51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd425b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd42e11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd43671184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd44351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd44bb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd45411184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd45c61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd46951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd471a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd47a01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd48261184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd48f41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd497a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4a001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4a861184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4b541184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4bd91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4c5f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4ce51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4db41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4e391184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4ebf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd4f451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd50131184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd50991184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd511e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd51a41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd52731184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd52f91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd537f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd54041184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd54d21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd55581184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd55de1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd56641184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd57351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd57bb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd58421184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd58c81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd59951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5a1b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5aa11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5b271184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5bf51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5c7a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5d011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5d891184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5e571184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5edd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5f621184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd5fe81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd60b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd613c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd61c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd62481184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd63161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd639c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd64221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd64a71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd65751184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd65fb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd66811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd67071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd67d51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd685b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd68e01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd69661184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6a351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6aba1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6b401184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6bc61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6c941184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6d1a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6da01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6e251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6ef31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd6f791184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd70001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd70871184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd71551184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd71db1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd72611184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd72e71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd73b51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd743b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd74c01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd75461184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd76141184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd769a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd77201184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd77a61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd78741184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd78fa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd797f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7a051184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7ad41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7b5a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7be01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7c651184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7d361184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7dbb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7e411184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7ec71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd7f941184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd801b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd80a11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd81271184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd81f51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd827a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd83001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd83861184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd84541184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd84da1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd85601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd85e61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd86b31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd87391184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd87bf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd88451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd89131184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd89991184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8a1f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8aa51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8b731184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8bf91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8c7e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8d041184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8dd21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8e581184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8ede1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd8f641184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd90321184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd90b71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd913d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd91c31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd92921184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd93171184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd939d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd94231184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 00cd94d31184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cd96561184ffff4a000001020000040018000000010000 000000000000000000000000000000000000000000000000 00cd96ca1184ffff4a0000010200000400180000aaaaaaaa 000000000000000000000000000000000000000000000000 00cd9a271184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9afc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9b821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9c081184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9c901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9d5d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9de41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9e691184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9eef1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cd9fbd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda0431184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda0c91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda14f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda21d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda2a31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda3281184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda3ae1184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 00cda4261184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cda49a1184ffff4a000001020000040018000000010000 000000000000000000000000000000000000000000000000 00cda50d1184ffff4a0000010200000400180000aaaaaaaa 000000000000000000000000000000000000000000000000 00cda7681184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda8371184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda8bd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda9431184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cda9c91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdaa971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdab1d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdaba31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdac291184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdacfb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdad811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdae071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdae8d1184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 00cdaf031184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 00cdaf761184ffff4a000001020000040018000000010000 000000000000000000000000000000000000000000000000 00cdafea1184ffff4a000001020000040018000000100000 000000000000000000000000000000000000000000000000 00cdb53a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdb6071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdb68d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdb7131184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdb7991184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdb86a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 00cdb8f01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 ================================================ FILE: lib/deprecated/pcietestbench_dma_io/testpcie.cpp ================================================ #include #include #include "dmaManager.h" #include "SGListConfigRequest.h" #include "PcieTestBenchIndication.h" #include "PcieTestBenchRequest.h" sem_t test_sem; sem_t tlp_sem; sem_t tlp_ack; int numWords = 64; size_t test_sz = numWords*sizeof(unsigned int); size_t alloc_sz = test_sz; int burstLen = 16; uint32_t scan_int(const char *str) { uint32_t rv; sscanf(str, "%x", &rv); return rv; } enum PktClass {trace, MCont, SCont, MResp, SWReq, SReq, SResp, MWReq, MReq, Misc}; PktClass pktClassification(uint32_t tlpsof, uint32_t tlpeof, uint32_t tlpbe, uint32_t pktformat, uint32_t pkttype, uint32_t portnum) { if (tlpbe == 0) return trace; if (tlpsof == 0) if (portnum == 4) return MCont; else return SCont; if (portnum == 4) if (pkttype == 10) // COMPLETION return MResp; else if (pktformat == 2 or pktformat == 3) return SWReq; else return SReq; else if(portnum == 8) if (pkttype == 10) // COMPLETION return SResp; else if (pktformat == 2 or pktformat == 3) return MWReq; else return MReq; else return Misc; } class PcieTestBenchIndication : public PcieTestBenchIndicationWrapper { public: virtual void finished(uint32_t v){ fprintf(stderr, "finished(%x)\n", v); sem_post(&test_sem); } virtual void started(uint32_t words){ fprintf(stderr, "started(%x)\n", words); } void tlpout(const TsTLPData16 &tlp) { //fprintf(stderr, "Received data= %08x%08x%08x%08x%08x%08x\n", tlp.data0, tlp.data1, tlp.data2, tlp.data3, tlp.data4, tlp.data5); sem_post(&tlp_sem); sem_wait(&tlp_ack); } PcieTestBenchIndication(unsigned int id) : PcieTestBenchIndicationWrapper(id){} }; int main(int argc, const char **argv) { PcieTestBenchRequestProxy *device = new PcieTestBenchRequestProxy(IfcNames_TestBenchRequest); PcieTestBenchIndication *deviceIndication = new PcieTestBenchIndication(IfcNames_TestBenchIndication); DmaManager *dma = platformInit(); int srcAlloc; unsigned int *srcBuffer = 0; std::ifstream infile("../memread_nobuff_io.tstlp"); srcAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); for (int i = 0; i < numWords; i++) srcBuffer[i] = i; portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); unsigned int ref_srcAlloc = dma->reference(srcAlloc); device->startRead(ref_srcAlloc, numWords, burstLen); #ifndef SANITY int i; while(i++ < 4){ sem_wait(&tlp_sem); uint32_t cnt = 0; while(cnt < 5){ std::string line; std::getline(infile,line); uint32_t tlpsof = scan_int(line.substr(48-39,1).c_str()) & 1; uint32_t tlpeof = scan_int(line.substr(48-38,2).c_str()) >> 7; uint32_t tlpbe = scan_int(line.substr(48-36,4).c_str()); uint32_t tlphit = scan_int(line.substr(48-38,2).c_str()) & 0x7f; uint32_t pktformat = (scan_int(line.substr(48-32,1).c_str()) >> 1) & 3; uint32_t pkttype = (scan_int(line.substr(48-32,2).c_str()) & 0x1f); uint32_t portnum = scan_int(line.substr(48-40,2).c_str()) >> 1; PktClass pc = pktClassification(tlpsof, tlpeof, tlpbe, pktformat, pkttype, portnum); if(pc == MResp || pc == MCont){ TsTLPData16 rv; uint32_t tmp; rv.data0 = scan_int(line.substr(0 ,8).c_str()); rv.data1 = scan_int(line.substr(8 ,8).c_str()); rv.data2 = scan_int(line.substr(16,8).c_str()); rv.data3 = scan_int(line.substr(24,8).c_str()); rv.data4 = scan_int(line.substr(32,8).c_str()); rv.data5 = scan_int(line.substr(40,8).c_str()); //fprintf(stdout, "%08x%08x%08x%08x%08x%08x\n", rv.data0, rv.data1, rv.data2, rv.data3, rv.data4, rv.data5); //fprintf(stdout, "%s\n", line.c_str()); device->tlpin(rv); cnt++; } } sem_post(&tlp_ack); } #endif sem_wait(&test_sem); } ================================================ FILE: lib/deprecated/pcietestbench_dma_oo/Makefile ================================================ INTERFACES = PcieTestBenchRequest PcieTestBenchIndication BSVFILES = PcieTestBench.bsv Top.bsv ../../lib/deprecated/DmaUtils.bsv CPPFILES=testpcie.cpp include ../../Makefile.common ================================================ FILE: lib/deprecated/pcietestbench_dma_oo/Memread.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import ConnectalMemTypes::*; import MemReadEngine::*; interface MemreadRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen, Bit#(32) iterCnt); method Action getStateDbg(); endinterface interface Memread; interface MemreadRequest request; interface MemReadClient#(64) dmaClient; endinterface interface MemreadIndication; method Action started(Bit#(32) numWords); method Action reportStateDbg(Bit#(32) streamRdCnt, Bit#(32) mismatchCount); method Action readDone(Bit#(32) mismatchCount); endinterface module mkMemread#(MemreadIndication indication) (Memread); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) iterCnt <- mkReg(0); Reg#(Bit#(32)) srcGen <- mkReg(0); Reg#(Bit#(32)) mismatchCount <- mkReg(0); FIFOF#(Bit#(64)) readFifo <- mkFIFOF; let re <- mkMemReadEngine(1, readFifo); rule start (iterCnt > 0); iterCnt <= iterCnt-1; re.start(pointer, 0, numWords*4, burstLen*4); endrule rule finish; let rv <- re.finish; if (iterCnt == 0) indication.readDone(mismatchCount); endrule rule check; readFifo.deq; let v = readFifo.first; let expectedV = {srcGen+1,srcGen}; let misMatch = v != expectedV; mismatchCount <= mismatchCount + (misMatch ? 1 : 0); if (srcGen+2 == numWords) srcGen <= 0; else srcGen <= srcGen+2; endrule interface MemReadClient dmaClient = re.dmaClient; interface MemreadRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nw, Bit#(32) bl, Bit#(32) ic); $display("startRead rdPointer=%d numWords=%h burstLen=%d iterCnt=%d", rp, nw, bl, ic); indication.started(nw); pointer <= rp; numWords <= nw; burstLen <= bl; iterCnt <= ic; mismatchCount <= 0; srcGen <= 0; endmethod method Action getStateDbg(); indication.reportStateDbg(iterCnt, mismatchCount); endmethod endinterface endmodule ================================================ FILE: lib/deprecated/pcietestbench_dma_oo/PcieTestBench.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Clocks :: *; import Connectable :: *; import DefaultValue :: *; import FIFO :: *; import GetPut :: *; import FIFOF :: *; import Vector :: *; import AxiCsr :: *; import PCIE :: *; import AxiSlaveEngine :: *; import Portal :: *; import MemServer :: *; import SGList::*; import MemReadEngine :: *; import AxiDma :: *; import ConnectalMemTypes :: *; import AxiMasterSlave :: *; import DmaUtils :: *; import MemServerRequestWrapper::*; import SGListConfigRequestWrapper::*; import MemServerIndicationProxy::*; import SGListConfigIndicationProxy::*; // copied from PCIE.bsv because connectalgen cannot handle TMul#() typedef struct { Bit#(32) data0; Bit#(32) data1; Bit#(32) data2; Bit#(32) data3; Bit#(32) data4; Bit#(32) data5; } TsTLPData16 deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef enum { MEM_READ_3DW_NO_DATA = 0, MEM_READ_4DW_NO_DATA = 1, MEM_WRITE_3DW_DATA = 2, MEM_WRITE_4DW_DATA = 3 } TLPPacketFormat deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef enum { MEMORY_READ_WRITE = 0, MEMORY_READ_LOCKED = 1, IO_REQUEST = 2, UNKNOWN_TYPE_3 = 3, CONFIG_0_READ_WRITE = 4, CONFIG_1_READ_WRITE = 5, UNKNOWN_TYPE_6 = 6, UNKNOWN_TYPE_7 = 7, UNKNOWN_TYPE_8 = 8, UNKNOWN_TYPE_9 = 9, COMPLETION = 10, COMPLETION_LOCKED = 11, UNKNOWN_TYPE_12 = 12, UNKNOWN_TYPE_13 = 13, UNKNOWN_TYPE_14 = 14, UNKNOWN_TYPE_15 = 15, MSG_ROUTED_TO_ROOT = 16, MSG_ROUTED_BY_ADDR = 17, MSG_ROUTED_BY_ID = 18, MSG_ROOT_BROADCAST = 19, MSG_LOCAL = 20, MSG_GATHER = 21, UNKNOWN_TYPE_22 = 22, UNKNOWN_TYPE_23 = 23, UNKNOWN_TYPE_24 = 24, UNKNOWN_TYPE_25 = 25, UNKNOWN_TYPE_26 = 26, UNKNOWN_TYPE_27 = 27, UNKNOWN_TYPE_28 = 28, UNKNOWN_TYPE_29 = 29, UNKNOWN_TYPE_30 = 30, UNKNOWN_TYPE_31 = 31 } TLPPacketType deriving (Bits, Eq); // copied from PCIE.bsv because connectalgen cannot parse the file typedef struct {Bit#(8) hit; Bit#(8) sof; Bit#(8) eof; Bit#(16) tlpbe; Bit#(16) tag; Bit#(16) length; TLPPacketType pkttype; TLPPacketFormat format; Bit#(8) firstbe; Bit#(8) lastbe; Bit#(32) addr; Bit#(32) data; } Pcie3dwHeader deriving (Bits); interface PcieTestBenchIndication; method Action tlpout(TsTLPData16 tlp); method Action started(Bit#(32) numWords); method Action finished(Bit#(32) v); endinterface interface PcieTestBenchRequest; method Action tlpin(TsTLPData16 tlp); method Action startRead(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface PcieTestBench#(numeric type addrWidth, numeric type dataWidth); interface PcieTestBenchRequest request; interface StdPortal dmaConfig; interface StdPortal dmaIndication; interface Vector#(1,MemMaster#(addrWidth,dataWidth)) masters; endinterface typedef enum {TestBenchIndication, TestBenchRequest, HostmemMemServerIndication, HostmemMemServerRequest, HostmemSGListConfigRequest, HostmemSGListConfigIndication} IfcNames deriving (Eq,Bits); //`define SANITY module mkPcieTestBench#(PcieTestBenchIndication indication)(PcieTestBench#(40,64)); // memread state Reg#(SGLId) rdPointer <- mkReg(0); Reg#(Bit#(8)) burstLen <- mkReg(0); Reg#(Bit#(32)) reqLen <- mkReg(0); Reg#(Bit#(3)) rdTag <- mkReg(0); Reg#(Bit#(32)) respCnt <- mkReg(0); Reg#(Bit#(32)) rdOff <- mkReg(0); DmaReadBuffer#(64, 32) rb <- mkDmaReadBuffer(); // dma state SGListConfigIndicationProxy hostmemSGListConfigIndicationProxy <- mkSGListConfigIndicationProxy(HostmemSGListConfigIndication); SGListMMU#(PhysAddrWidth) hostmemSGList <- mkSGListMMU(0, True, hostmemSGListConfigIndicationProxy.ifc); SGListConfigRequestWrapper hostmemSGListConfigRequestWrapper <- mkSGListConfigRequestWrapper(HostmemSGListConfigRequest, hostmemSGList.request); MemServerIndicationProxy hostmemMemServerIndicationProxy <- mkMemServerIndicationProxy(HostmemMemServerIndication); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServerOOR(hostmemMemServerIndicationProxy.ifc, cons(rb.dmaClient,nil), hostmemSGList); MemServerRequestWrapper hostmemMemServerRequestWrapper <- mkMemServerRequestWrapper(HostmemMemServerRequest, dma.request); `ifdef SANITY Axi3Master#(40,64,6) m_axi = ?; `else Axi3Master#(40,64,6) m_axi <- mkAxiDmaMaster(dma.masters[0]); `endif // tlp state PciId my_id = PciId { bus: 1, dev: 1, func: 0}; Bit#(64) board_content_id = 'hdeadbeefd00df00d; Reg#(Bit#(32)) tlp_portal_drop_count <- mkReg(0); Reg#(Bit#(32)) tlp_axi_drop_count <- mkReg(0); AxiSlaveEngine#(64) axiSlaveEngine <- mkAxiSlaveEngine(my_id); Reg#(Bit#(32)) timestamp <- mkReg(0); mkConnection(m_axi, axiSlaveEngine.slave); FIFO#(TimestampedTlpData) tlpin_fifo <- mkSizedFIFO(20); // tlp rules rule timebase; timestamp <= timestamp + 1; endrule rule tlp_out; let tlp <- tpl_1(axiSlaveEngine.tlps).get(); TimestampedTlpData ttd = TimestampedTlpData { timestamp: timestamp, source: 4, tlp: tlp }; indication.tlpout(unpack(pack(ttd))); //$display("%h",ttd); endrule rule tlp_in; let ttd = tlpin_fifo.first; tlpin_fifo.deq; tpl_2(axiSlaveEngine.tlps).put(unpack(pack(ttd.tlp))); endrule // memread rules rule rdReq if (rdOff < reqLen); rdOff <= rdOff + extend(burstLen); rb.dmaServer.readReq.put(MemRequest { sglId: rdPointer, offset: extend(rdOff), burstLen: burstLen, tag: extend(rdTag) }); rdTag <= rdTag+1; endrule rule rdData; MemData#(64) d <- rb.dmaServer.readData.get; let new_respCnt = respCnt+(64/8); respCnt <= new_respCnt; if (new_respCnt >= reqLen) indication.finished(0); endrule interface PcieTestBenchRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nw, Bit#(32) bl); $display("startRead rdPointer=%d numWords=%h burstLen=%d", rp, nw, bl); indication.started(nw); rdPointer <= rp; burstLen <= truncate(bl*4); reqLen <= nw*4; respCnt <= 0; rdOff <= 0; endmethod method Action tlpin(TsTLPData16 tstlp); TimestampedTlpData ttd = unpack(pack(tstlp)); tlpin_fifo.enq(ttd); endmethod endinterface interface StdPortal dmaConfig = hostmemMemServerRequestWrapper.portalIfc; interface StdPortal dmaIndication = hostmemMemServerIndicationProxy.portalIfc; //portals[z] = hostmemSGListConfigRequestWrapper.portalIfc; //portals[z] = hostmemSGListConfigIndicationProxy.portalIfc; `ifdef SANITY interface masters = dma.masters; `else interface masters = ?; `endif endmodule ================================================ FILE: lib/deprecated/pcietestbench_dma_oo/Top.bsv ================================================ import Vector::*; import FIFO::*; import Connectable::*; import Directory::*; import CtrlMux::*; import Portal::*; import ConnectalMemTypes::*; import PcieTestBenchIndicationProxy::*; import PcieTestBenchRequestWrapper::*; import PcieTestBench::*; module mkConnectalTop(StdConnectalDmaTop#(40)); // instantiate user portals PcieTestBenchIndicationProxy pcieTestBenchIndicationProxy <- mkPcieTestBenchIndicationProxy(IfcNames_TestBenchIndication); PcieTestBench#(40,64) pcieTestBench <- mkPcieTestBench(pcieTestBenchIndicationProxy.ifc); PcieTestBenchRequestWrapper pcieTestBenchRequestWrapper <- mkPcieTestBenchRequestWrapper(IfcNames_TestBenchRequest,pcieTestBench.request); Vector#(4,StdPortal) portals; portals[0] = pcieTestBenchRequestWrapper.portalIfc; portals[1] = pcieTestBenchIndicationProxy.portalIfc; portals[2] = pcieTestBench.dmaConfig; portals[3] = pcieTestBench.dmaIndication; StdDirectory dir <- mkStdDirectory(portals); let ctrl_mux <- mkSlaveMux(dir,portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = pcieTestBench.masters; endmodule : mkConnectalTop ================================================ FILE: lib/deprecated/pcietestbench_dma_oo/memread_nobuff_oo.tstlp ================================================ 000000000000000000000000000000000000000000000000 d38e112c0981ffff400000010000030fdf400c6400000000 d38e113c0981fff0000000010018000fdf400c1c75961f55 000000000000000000000000000000000000000000000000 d38e11aa0981fff0000000010018000fdf400c1859870275 000000000000000000000000000000000000000000000000 d38e121a0981ffff400000010000000fdf400c1c00000000 54d6652b0984fff0000000010018000fdf51c01899c4aa8d 000000000000000000000000000000000000000000000000 54d665a80984ffff400000010000030fdf51c00401000000 54d665b80984fff0000000010018000fdf53c018471cc874 000000000000000000000000000000000000000000000000 54d6662c0984ffff400000010000000fdf53c00401000000 54d6663b0984fff0000000010018000fdf52c0183bc35615 000000000000000000000000000000000000000000000000 54d666b80984ffff400000010000010fdf52c00401000000 54d666c70984fff0000000010018000fdf54c01854603eb1 000000000000000000000000000000000000000000000000 54d6673c0984ffff400000010000020fdf54c00401000000 54d667940984fff0000000010018000fdf51c018f417a9d7 000000000000000000000000000000000000000000000000 54d668100984ffff400000010000030fdf51c00401000000 54d6681f0984fff0000000010018000fdf53c018f069cc9a 000000000000000000000000000000000000000000000000 54d6689c0984ffff400000010000000fdf53c00401000000 54d668ac0984fff0000000010018000fdf52c0188cb652fb 000000000000000000000000000000000000000000000000 54d669280984ffff400000010000010fdf52c00401000000 54d669380984fff0000000010018000fdf54c018e3153a5f 000000000000000000000000000000000000000000000000 54d669b40984ffff400000010000020fdf54c00401000000 54d66a0a0984fff0000000010018000fdf51c0184362ad39 000000000000000000000000000000000000000000000000 54d66a860984ffff400000010000030fdf51c00401000000 54d66a960984fff0000000010018000fdf53c0189dbacfc0 000000000000000000000000000000000000000000000000 54d66b130984ffff400000010000000fdf53c00401000000 54d66b220984fff0000000010018000fdf52c018e16551a1 000000000000000000000000000000000000000000000000 54d66b960984ffff400000010000010fdf52c00401000000 54d66ba60984fff0000000010018000fdf54c0188ec63905 000000000000000000000000000000000000000000000000 54d66c230984ffff400000010000020fdf54c00401000000 54d66c680984fff0000000010018000fdf51c0182eb1ae63 000000000000000000000000000000000000000000000000 54d66cdc0984ffff400000010000030fdf51c00401000000 54d66cec0984fff0000000010018000fdf53c01863305280 000000000000000000000000000000000000000000000000 54d66d600984ffff400000010000000fdf53c00401000000 54d66d700984fff0000000010018000fdf52c0181fefcce1 000000000000000000000000000000000000000000000000 54d66de50984ffff400000010000010fdf52c00401000000 54d66df40984fff0000000010018000fdf54c018704ca445 000000000000000000000000000000000000000000000000 54d66e690984ffff400000010000020fdf54c00401000000 54d66eb30984fff0000000010018000fdf51c018d03b3323 000000000000000000000000000000000000000000000000 54d66f260984ffff400000010000030fdf51c00401000000 54d66f350984fff0000000010018000fdf53c0180ee351da 000000000000000000000000000000000000000000000000 54d66fa80984ffff400000010000000fdf53c00401000000 54d66fb70984fff0000000010018000fdf52c018723ccfbb 000000000000000000000000000000000000000000000000 54d670330984ffff400000010000010fdf52c00401000000 54d670420984fff0000000010018000fdf54c0181d9fa71f 000000000000000000000000000000000000000000000000 54d670b60984ffff400000010000020fdf54c00401000000 54d671050984fff0000000010018000fdf51c018bde83079 000000000000000000000000000000000000000000000000 54d671790984ffff400000010000030fdf51c00401000000 54d671890984fff0000000010018000fdf53c018b9965534 000000000000000000000000000000000000000000000000 54d672060984ffff400000010000000fdf53c00401000000 54d672150984fff0000000010018000fdf52c018c549cb55 000000000000000000000000000000000000000000000000 54d672890984ffff400000010000010fdf52c00401000000 54d672980984fff0000000010018000fdf54c018aaeaa3f1 000000000000000000000000000000000000000000000000 54d6730b0984ffff400000010000020fdf54c00401000000 54d6736c0984fff0000000010018000fdf51c0180a9d3497 000000000000000000000000000000000000000000000000 54d673df0984ffff400000010000030fdf51c00401000000 54d673ee0984fff0000000010018000fdf53c018d445566e 000000000000000000000000000000000000000000000000 54d674610984ffff400000010000000fdf53c00401000000 54d674700984fff0000000010018000fdf52c018a89ac80f 000000000000000000000000000000000000000000000000 54d674ec0984ffff400000010000010fdf52c00401000000 54d674fb0984fff0000000010018000fdf54c018c739a0ab 000000000000000000000000000000000000000000000000 54d6756f0984ffff400000010000020fdf54c00401000000 54d675b50984fff0000000010018000fdf51c018674e37cd 000000000000000000000000000000000000000000000000 54d676300984ffff400000010000030fdf51c00401000000 54d676400984fff0000000010018000fdf53c018967b2c33 000000000000000000000000000000000000000000000000 54d676b40984ffff400000010000000fdf53c00401000000 54d676c40984fff0000000010018000fdf52c018eaa4b252 000000000000000000000000000000000000000000000000 54d677410984ffff400000010000010fdf52c00401000000 54d677510984fff0000000010018000fdf54c0188507daf6 000000000000000000000000000000000000000000000000 54d677c40984ffff400000010000020fdf54c00401000000 54d6780b0984fff0000000010018000fdf51c01825704d90 000000000000000000000000000000000000000000000000 54d6787e0984ffff400000010000030fdf51c00401000000 54d6788d0984fff0000000010018000fdf53c018fba82f69 000000000000000000000000000000000000000000000000 54d679090984ffff400000010000000fdf53c00401000000 54d679180984fff0000000010018000fdf52c0188777b108 000000000000000000000000000000000000000000000000 54d6798c0984ffff400000010000010fdf52c00401000000 54d6799c0984fff0000000010018000fdf54c018e8d4d9ac 000000000000000000000000000000000000000000000000 54d67a100984ffff400000010000020fdf54c00401000000 54d67a510984fff0000000010018000fdf51c01848a34eca 000000000000000000000000000000000000000000000000 54d67ac40984ffff400000010000030fdf51c00401000000 54d67ad30984fff0000000010018000fdf53c0184cdd2b87 000000000000000000000000000000000000000000000000 54d67b460984ffff400000010000000fdf53c00401000000 54d67b560984fff0000000010018000fdf52c0183002b5e6 000000000000000000000000000000000000000000000000 54d67bd30984ffff400000010000010fdf52c00401000000 54d67be20984fff0000000010018000fdf54c0185fa1dd42 000000000000000000000000000000000000000000000000 54d67c550984ffff400000010000020fdf54c00401000000 54d67c990984fff0000000010018000fdf51c018ffd64a24 000000000000000000000000000000000000000000000000 54d67d0d0984ffff400000010000030fdf51c00401000000 54d67d1d0984fff0000000010018000fdf53c018210e28dd 000000000000000000000000000000000000000000000000 54d67d910984ffff400000010000000fdf53c00401000000 54d67da20984fff0000000010018000fdf52c0185dd1b6bc 000000000000000000000000000000000000000000000000 54d67e150984ffff400000010000010fdf52c00401000000 54d67e250984fff0000000010018000fdf54c0183272de18 000000000000000000000000000000000000000000000000 54d67ea20984ffff400000010000020fdf54c00401000000 54d67ee10984fff0000000010018000fdf51c0189205497e 000000000000000000000000000000000000000000000000 54d67f550984ffff400000010000030fdf51c00401000000 54d67f650984fff0000000010018000fdf53c018c8a1df3d 000000000000000000000000000000000000000000000000 54d67fd90984ffff400000010000000fdf53c00401000000 54d67fe90984fff0000000010018000fdf52c018b47e415c 000000000000000000000000000000000000000000000000 54d6805d0984ffff400000010000010fdf52c00401000000 54d6806c0984fff0000000010018000fdf54c018dbdd29f8 000000000000000000000000000000000000000000000000 54d680df0984ffff400000010000020fdf54c00401000000 54d681240984fff0000000010018000fdf51c0187baabe9e 000000000000000000000000000000000000000000000000 54d681970984ffff400000010000030fdf51c00401000000 54d681a60984fff0000000010018000fdf53c018a572dc67 000000000000000000000000000000000000000000000000 54d6821a0984ffff400000010000000fdf53c00401000000 54d6822a0984fff0000000010018000fdf52c018d9ad4206 000000000000000000000000000000000000000000000000 54d6829e0984ffff400000010000010fdf52c00401000000 54d682ae0984fff0000000010018000fdf54c018b60e2aa2 000000000000000000000000000000000000000000000000 54d6832b0984ffff400000010000020fdf54c00401000000 54d6836a0984fff0000000010018000fdf51c0181679bdc4 000000000000000000000000000000000000000000000000 54d683e60984ffff400000010000030fdf51c00401000000 54d683f60984fff0000000010018000fdf53c0181207d889 000000000000000000000000000000000000000000000000 54d6846a0984ffff400000010000000fdf53c00401000000 54d6847a0984fff0000000010018000fdf52c0186ed846e8 000000000000000000000000000000000000000000000000 54d684ee0984ffff400000010000010fdf52c00401000000 54d684fd0984fff0000000010018000fdf54c018017b2e4c 000000000000000000000000000000000000000000000000 54d685790984ffff400000010000020fdf54c00401000000 54d685b80984fff0000000010018000fdf51c018a10cb92a 000000000000000000000000000000000000000000000000 54d6862c0984ffff400000010000030fdf51c00401000000 54d6863b0984fff0000000010018000fdf53c0187fd4dbd3 000000000000000000000000000000000000000000000000 54d686ae0984ffff400000010000000fdf53c00401000000 54d686bd0984fff0000000010018000fdf52c018030b45b2 000000000000000000000000000000000000000000000000 54d687300984ffff400000010000010fdf52c00401000000 54d6873f0984fff0000000010018000fdf54c0186ca82d16 000000000000000000000000000000000000000000000000 54d687b30984ffff400000010000020fdf54c00401000000 54d687f40984fff0000000010018000fdf51c018ccdfba70 000000000000000000000000000000000000000000000000 54d688670984ffff400000010000030fdf51c00401000000 54d688760984fff0000000010018000fdf53c0183deaa18e 000000000000000000000000000000000000000000000000 54d688f20984ffff400000010000000fdf53c00401000000 54d689010984fff0000000010018000fdf52c01841353fef 000000000000000000000000000000000000000000000000 54d689750984ffff400000010000010fdf52c00401000000 54d689840984fff0000000010018000fdf54c0182e96574b 000000000000000000000000000000000000000000000000 54d689f70984ffff400000010000020fdf54c00401000000 54d68a3f0984fff0000000010018000fdf51c0188ee1c02d 000000000000000000000000000000000000000000000000 54d68ab30984ffff400000010000030fdf51c00401000000 54d68ac20984fff0000000010018000fdf53c0185039a2d4 000000000000000000000000000000000000000000000000 54d68b350984ffff400000010000000fdf53c00401000000 54d68b450984fff0000000010018000fdf52c0182ce63cb5 000000000000000000000000000000000000000000000000 54d68bb90984ffff400000010000010fdf52c00401000000 54d68bc80984fff0000000010018000fdf54c01843455411 000000000000000000000000000000000000000000000000 54d68c460984ffff400000010000020fdf54c00401000000 54d68c870984fff0000000010018000fdf51c018e332c377 000000000000000000000000000000000000000000000000 54d68cfb0984ffff400000010000030fdf51c00401000000 54d68d0a0984fff0000000010018000fdf53c018e74ca63a 000000000000000000000000000000000000000000000000 54d68d7e0984ffff400000010000000fdf53c00401000000 54d68d8d0984fff0000000010018000fdf52c0189b93385b 000000000000000000000000000000000000000000000000 54d68e000984ffff400000010000010fdf52c00401000000 54d68e0f0984fff0000000010018000fdf54c018f43050ff 000000000000000000000000000000000000000000000000 54d68e8b0984ffff400000010000020fdf54c00401000000 54d68eda0984fff0000000010018000fdf51c0185447c799 000000000000000000000000000000000000000000000000 54d68f570984ffff400000010000030fdf51c00401000000 54d68f660984fff0000000010018000fdf53c0188a9fa560 000000000000000000000000000000000000000000000000 54d68fda0984ffff400000010000000fdf53c00401000000 54d68fea0984fff0000000010018000fdf52c018f6403b01 000000000000000000000000000000000000000000000000 54d6905e0984ffff400000010000010fdf52c00401000000 54d6906e0984fff0000000010018000fdf54c01899e353a5 000000000000000000000000000000000000000000000000 54d690e20984ffff400000010000020fdf54c00401000000 54d691300984fff0000000010018000fdf51c0183994c4c3 000000000000000000000000000000000000000000000000 54d691a40984ffff400000010000030fdf51c00401000000 54d691b30984fff0000000010018000fdf53c01802f437bd 000000000000000000000000000000000000000000000000 54d692260984ffff400000010000000fdf53c00401000000 54d692350984fff0000000010018000fdf52c0187e2ba9dc 000000000000000000000000000000000000000000000000 54d692b10984ffff400000010000010fdf52c00401000000 54d692c00984fff0000000010018000fdf54c0181188c178 000000000000000000000000000000000000000000000000 54d693340984ffff400000010000020fdf54c00401000000 54d693730984fff0000000010018000fdf51c018b1ff561e 000000000000000000000000000000000000000000000000 54d693e80984ffff400000010000030fdf51c00401000000 54d693f70984fff0000000010018000fdf53c0186f2734e7 000000000000000000000000000000000000000000000000 54d6946b0984ffff400000010000000fdf53c00401000000 54d6947b0984fff0000000010018000fdf52c01813f8aa86 000000000000000000000000000000000000000000000000 54d694ef0984ffff400000010000010fdf52c00401000000 54d694ff0984fff0000000010018000fdf54c0187c5bc222 000000000000000000000000000000000000000000000000 54d6957c0984ffff400000010000020fdf54c00401000000 54d695bf0984fff0000000010018000fdf51c018dc2c5544 000000000000000000000000000000000000000000000000 54d6963c0984ffff400000010000030fdf51c00401000000 54d6964b0984fff0000000010018000fdf53c018d8523009 000000000000000000000000000000000000000000000000 54d696bf0984ffff400000010000000fdf53c00401000000 54d696cf0984fff0000000010018000fdf52c018a48dae68 000000000000000000000000000000000000000000000000 54d6974c0984ffff400000010000010fdf52c00401000000 54d6975b0984fff0000000010018000fdf54c018cb2ec6cc 000000000000000000000000000000000000000000000000 54d697cf0984ffff400000010000020fdf54c00401000000 54d698230984fff0000000010018000fdf51c0186b5951aa 000000000000000000000000000000000000000000000000 54d698a00984ffff400000010000030fdf51c00401000000 54d698af0984fff0000000010018000fdf53c018b5813353 000000000000000000000000000000000000000000000000 54d699220984ffff400000010000000fdf53c00401000000 54d699310984fff0000000010018000fdf52c018c95ead32 000000000000000000000000000000000000000000000000 54d699a40984ffff400000010000010fdf52c00401000000 54d699b40984fff0000000010018000fdf54c018a6fdc596 000000000000000000000000000000000000000000000000 54d69a280984ffff400000010000020fdf54c00401000000 54d69a740984fff0000000010018000fdf51c018068a52f0 000000000000000000000000000000000000000000000000 54d69ae80984ffff400000010000030fdf51c00401000000 54d69af70984fff0000000010018000fdf53c018f7bf490e 000000000000000000000000000000000000000000000000 54d69b730984ffff400000010000000fdf53c00401000000 54d69b820984fff0000000010018000fdf52c0188b60d76f 000000000000000000000000000000000000000000000000 54d69bf60984ffff400000010000010fdf52c00401000000 54d69c050984fff0000000010018000fdf54c018e4c3bfcb 000000000000000000000000000000000000000000000000 54d69c790984ffff400000010000020fdf54c00401000000 54d69cc50984fff0000000010018000fdf51c01844b428ad 000000000000000000000000000000000000000000000000 54d69d380984ffff400000010000030fdf51c00401000000 54d69d480984fff0000000010018000fdf53c0189a6c4a54 000000000000000000000000000000000000000000000000 54d69dc50984ffff400000010000000fdf53c00401000000 54d69dd40984fff0000000010018000fdf52c018e6b3d435 000000000000000000000000000000000000000000000000 54d69e480984ffff400000010000010fdf52c00401000000 54d69e580984fff0000000010018000fdf54c0188910bc91 000000000000000000000000000000000000000000000000 54d69ecb0984ffff400000010000020fdf54c00401000000 54d69f0d0984fff0000000010018000fdf51c01829672bf7 000000000000000000000000000000000000000000000000 54d69f820984ffff400000010000030fdf51c00401000000 54d69f910984fff0000000010018000fdf53c0182d194eba 000000000000000000000000000000000000000000000000 54d6a0050984ffff400000010000000fdf53c00401000000 54d6a0150984fff0000000010018000fdf52c01851c6d0db 000000000000000000000000000000000000000000000000 54d6a0890984ffff400000010000010fdf52c00401000000 54d6a0990984fff0000000010018000fdf54c0183e65b87f 000000000000000000000000000000000000000000000000 54d6a10d0984ffff400000010000020fdf54c00401000000 54d6a1560984fff0000000010018000fdf51c0189e122f19 000000000000000000000000000000000000000000000000 54d6a1c90984ffff400000010000030fdf51c00401000000 54d6a1d80984fff0000000010018000fdf53c01840ca4de0 000000000000000000000000000000000000000000000000 54d6a24c0984ffff400000010000000fdf53c00401000000 54d6a25b0984fff0000000010018000fdf52c0183c15d381 000000000000000000000000000000000000000000000000 54d6a2d70984ffff400000010000010fdf52c00401000000 54d6a2e70984fff0000000010018000fdf54c01853b6bb25 000000000000000000000000000000000000000000000000 54d6a35b0984ffff400000010000020fdf54c00401000000 54d6a3a20984fff0000000010018000fdf51c018f3c12c43 000000000000000000000000000000000000000000000000 54d6a41f0984ffff400000010000030fdf51c00401000000 54d6a42e0984fff0000000010018000fdf53c018a965ba00 000000000000000000000000000000000000000000000000 54d6a4a20984ffff400000010000000fdf53c00401000000 54d6a4b20984fff0000000010018000fdf52c018d5ba2461 000000000000000000000000000000000000000000000000 54d6a52f0984ffff400000010000010fdf52c00401000000 54d6a53e0984fff0000000010018000fdf54c018ba194cc5 000000000000000000000000000000000000000000000000 54d6a5bb0984ffff400000010000020fdf54c00401000000 54d6a6010984fff0000000010018000fdf51c0181a6edba3 000000000000000000000000000000000000000000000000 54d6a6740984ffff400000010000030fdf51c00401000000 54d6a6840984fff0000000010018000fdf53c018c4b6b95a 000000000000000000000000000000000000000000000000 54d6a6f80984ffff400000010000000fdf53c00401000000 54d6a7090984fff0000000010018000fdf52c018b869273b 000000000000000000000000000000000000000000000000 54d6a7860984ffff400000010000010fdf52c00401000000 54d6a7950984fff0000000010018000fdf54c018d7ca4f9f 000000000000000000000000000000000000000000000000 54d6a8080984ffff400000010000020fdf54c00401000000 54d6a8470984fff0000000010018000fdf51c01877bdd8f9 000000000000000000000000000000000000000000000000 54d6a8ba0984ffff400000010000030fdf51c00401000000 54d6a8c90984fff0000000010018000fdf53c01873c3bdb4 000000000000000000000000000000000000000000000000 54d6a93c0984ffff400000010000000fdf53c00401000000 54d6a94b0984fff0000000010018000fdf52c0180f1c23d5 000000000000000000000000000000000000000000000000 54d6a9be0984ffff400000010000010fdf52c00401000000 54d6a9cd0984fff0000000010018000fdf54c01860bf4b71 000000000000000000000000000000000000000000000000 54d6aa410984ffff400000010000020fdf54c00401000000 54d6aa810984fff0000000010018000fdf51c018c0c8dc17 000000000000000000000000000000000000000000000000 54d6aaf50984ffff400000010000030fdf51c00401000000 54d6ab070984fff0000000010018000fdf53c0181e10beee 000000000000000000000000000000000000000000000000 54d6ab840984ffff400000010000000fdf53c00401000000 54d6ab930984fff0000000010018000fdf52c01862cf208f 000000000000000000000000000000000000000000000000 54d6ac070984ffff400000010000010fdf52c00401000000 54d6ac170984fff0000000010018000fdf54c0180d6c482b 000000000000000000000000000000000000000000000000 54d6ac8b0984ffff400000010000020fdf54c00401000000 54d6acd50984fff0000000010018000fdf51c018ad1bdf4d 000000000000000000000000000000000000000000000000 54d6ad490984ffff400000010000030fdf51c00401000000 54d6ad590984fff0000000010018000fdf53c0185c2ec4b3 000000000000000000000000000000000000000000000000 54d6adcd0984ffff400000010000000fdf53c00401000000 54d6addd0984fff0000000010018000fdf52c01820f15ad2 000000000000000000000000000000000000000000000000 54d6ae5a0984ffff400000010000010fdf52c00401000000 54d6ae690984fff0000000010018000fdf54c0184f523276 000000000000000000000000000000000000000000000000 54d6aedd0984ffff400000010000020fdf54c00401000000 54d6af1c0984fff0000000010018000fdf51c018ef25a510 000000000000000000000000000000000000000000000000 54d6af980984ffff400000010000030fdf51c00401000000 54d6afaa0984fff0000000010018000fdf53c01831fdc7e9 000000000000000000000000000000000000000000000000 54d6b01e0984ffff400000010000000fdf53c00401000000 54d6b02e0984fff0000000010018000fdf52c0184d225988 000000000000000000000000000000000000000000000000 54d6b0a20984ffff400000010000010fdf52c00401000000 54d6b0b20984fff0000000010018000fdf54c0182281312c 000000000000000000000000000000000000000000000000 54d6b12f0984ffff400000010000020fdf54c00401000000 54d6b1740984fff0000000010018000fdf51c01882f6a64a 000000000000000000000000000000000000000000000000 54d6b1f10984ffff400000010000030fdf51c00401000000 54d6b2010984fff0000000010018000fdf53c0188688c307 000000000000000000000000000000000000000000000000 54d6b2740984ffff400000010000000fdf53c00401000000 54d6b2830984fff0000000010018000fdf52c018fa575d66 000000000000000000000000000000000000000000000000 54d6b2f60984ffff400000010000010fdf52c00401000000 54d6b3050984fff0000000010018000fdf54c01895f435c2 000000000000000000000000000000000000000000000000 54d6b3780984ffff400000010000020fdf54c00401000000 54d6b3b90984fff0000000010018000fdf51c0183583a2a4 000000000000000000000000000000000000000000000000 54d6b42c0984ffff400000010000030fdf51c00401000000 54d6b43c0984fff0000000010018000fdf53c018eb5bc05d 000000000000000000000000000000000000000000000000 54d6b4b00984ffff400000010000000fdf53c00401000000 54d6b4c00984fff0000000010018000fdf52c01897845e3c 000000000000000000000000000000000000000000000000 54d6b5340984ffff400000010000010fdf52c00401000000 54d6b5430984fff0000000010018000fdf54c018f8273698 000000000000000000000000000000000000000000000000 54d6b5b70984ffff400000010000020fdf54c00401000000 54d6b6070984fff0000000010018000fdf51c0185850a1fe 000000000000000000000000000000000000000000000000 54d6b67b0984ffff400000010000030fdf51c00401000000 54d6b68b0984fff0000000010018000fdf53c01815d15d1d 000000000000000000000000000000000000000000000000 54d6b6ff0984ffff400000010000000fdf53c00401000000 54d6b70e0984fff0000000010018000fdf52c018690ec37c 000000000000000000000000000000000000000000000000 54d6b7810984ffff400000010000010fdf52c00401000000 54d6b7910984fff0000000010018000fdf54c01806adabd8 000000000000000000000000000000000000000000000000 54d6b8050984ffff400000010000020fdf54c00401000000 54d6b8450984fff0000000010018000fdf51c018a6da3cbe 000000000000000000000000000000000000000000000000 54d6b8b90984ffff400000010000030fdf51c00401000000 54d6b8c80984fff0000000010018000fdf53c01878025e47 000000000000000000000000000000000000000000000000 54d6b9440984ffff400000010000000fdf53c00401000000 54d6b9540984fff0000000010018000fdf52c01804ddc026 000000000000000000000000000000000000000000000000 54d6b9cf0984ffff400000010000010fdf52c00401000000 54d6b9df0984fff0000000010018000fdf54c0186b7ea882 000000000000000000000000000000000000000000000000 54d6ba530984ffff400000010000020fdf54c00401000000 54d6baa50984fff0000000010018000fdf51c018cb093fe4 000000000000000000000000000000000000000000000000 54d6bb190984ffff400000010000030fdf51c00401000000 54d6bb280984fff0000000010018000fdf53c018cf775aa9 000000000000000000000000000000000000000000000000 54d6bb9c0984ffff400000010000000fdf53c00401000000 54d6bbac0984fff0000000010018000fdf52c018b3a8c4c8 000000000000000000000000000000000000000000000000 54d6bc210984ffff400000010000010fdf52c00401000000 54d6bc310984fff0000000010018000fdf54c018dc0bac6c 000000000000000000000000000000000000000000000000 54d6bca40984ffff400000010000020fdf54c00401000000 54d6bce40984fff0000000010018000fdf51c0187c7c3b0a 000000000000000000000000000000000000000000000000 54d6bd580984ffff400000010000030fdf51c00401000000 54d6bd670984fff0000000010018000fdf53c018a2a459f3 000000000000000000000000000000000000000000000000 54d6bdda0984ffff400000010000000fdf53c00401000000 54d6bde90984fff0000000010018000fdf52c018de7bc792 000000000000000000000000000000000000000000000000 54d6be650984ffff400000010000010fdf52c00401000000 54d6be740984fff0000000010018000fdf54c018b1d8af36 000000000000000000000000000000000000000000000000 54d6bee80984ffff400000010000020fdf54c00401000000 54d6bf300984fff0000000010018000fdf51c01811af3850 000000000000000000000000000000000000000000000000 54d6bfa40984ffff400000010000030fdf51c00401000000 54d6bfb30984fff0000000010018000fdf53c018e09a23ae 000000000000000000000000000000000000000000000000 54d6c0260984ffff400000010000000fdf53c00401000000 54d6c0350984fff0000000010018000fdf52c0189c45bdcf 000000000000000000000000000000000000000000000000 54d6c0a80984ffff400000010000010fdf52c00401000000 54d6c0b70984fff0000000010018000fdf54c018f3e6d56b 000000000000000000000000000000000000000000000000 54d6c12b0984ffff400000010000020fdf54c00401000000 54d6c16a0984fff0000000010018000fdf51c0185391420d 000000000000000000000000000000000000000000000000 54d6c1e60984ffff400000010000030fdf51c00401000000 54d6c1f60984fff0000000010018000fdf53c0188d4920f4 000000000000000000000000000000000000000000000000 54d6c2690984ffff400000010000000fdf53c00401000000 54d6c2780984fff0000000010018000fdf52c018f196be95 000000000000000000000000000000000000000000000000 54d6c2eb0984ffff400000010000010fdf52c00401000000 54d6c2fa0984fff0000000010018000fdf54c0189e35d631 000000000000000000000000000000000000000000000000 54d6c3760984ffff400000010000020fdf54c00401000000 54d6c3ba0984fff0000000010018000fdf51c0183e424157 000000000000000000000000000000000000000000000000 54d6c42d0984ffff400000010000030fdf51c00401000000 54d6c43c0984fff0000000010018000fdf53c0183a3c241a 000000000000000000000000000000000000000000000000 54d6c4b70984ffff400000010000000fdf53c00401000000 54d6c4c70984fff0000000010018000fdf52c01846e3ba7b 000000000000000000000000000000000000000000000000 54d6c53b0984ffff400000010000010fdf52c00401000000 54d6c54a0984fff0000000010018000fdf54c0182940d2df 000000000000000000000000000000000000000000000000 54d6c5bd0984ffff400000010000020fdf54c00401000000 54d6c5ff0984fff0000000010018000fdf51c018893745b9 000000000000000000000000000000000000000000000000 54d6c6740984ffff400000010000030fdf51c00401000000 54d6c6830984fff0000000010018000fdf53c01857ef2740 000000000000000000000000000000000000000000000000 54d6c6f60984ffff400000010000000fdf53c00401000000 54d6c7060984fff0000000010018000fdf52c0182b30b921 000000000000000000000000000000000000000000000000 54d6c77a0984ffff400000010000010fdf52c00401000000 54d6c7890984fff0000000010018000fdf54c0184493d185 000000000000000000000000000000000000000000000000 54d6c7fc0984ffff400000010000020fdf54c00401000000 54d6c8450984fff0000000010018000fdf51c018e4e446e3 000000000000000000000000000000000000000000000000 54d6c8b80984ffff400000010000030fdf51c00401000000 54d6c8c70984fff0000000010018000fdf53c018be40d0a0 000000000000000000000000000000000000000000000000 54d6c93a0984ffff400000010000000fdf53c00401000000 54d6c9490984fff0000000010018000fdf52c018c29f4ec1 000000000000000000000000000000000000000000000000 54d6c9bc0984ffff400000010000010fdf52c00401000000 54d6c9cb0984fff0000000010018000fdf54c018ad3c2665 000000000000000000000000000000000000000000000000 54d6ca3e0984ffff400000010000020fdf54c00401000000 54d6ca860984fff0000000010018000fdf51c0180d4bb103 000000000000000000000000000000000000000000000000 54d6cafa0984ffff400000010000030fdf51c00401000000 54d6cb090984fff0000000010018000fdf53c018d393d3fa 000000000000000000000000000000000000000000000000 54d6cb7c0984ffff400000010000000fdf53c00401000000 54d6cb8b0984fff0000000010018000fdf52c018af4c4d9b 000000000000000000000000000000000000000000000000 54d6cbff0984ffff400000010000010fdf52c00401000000 54d6cc0e0984fff0000000010018000fdf54c018c0ef253f 000000000000000000000000000000000000000000000000 54d6cc830984ffff400000010000020fdf54c00401000000 54d6cccc0984fff0000000010018000fdf51c0186098b259 000000000000000000000000000000000000000000000000 54d6cd3f0984ffff400000010000030fdf51c00401000000 54d6cd4f0984fff0000000010018000fdf53c01864e6d714 000000000000000000000000000000000000000000000000 54d6cdc30984ffff400000010000000fdf53c00401000000 54d6cdd50984fff0000000010018000fdf52c01818394975 000000000000000000000000000000000000000000000000 54d6ce490984ffff400000010000010fdf52c00401000000 54d6ce590984fff0000000010018000fdf54c018779a21d1 000000000000000000000000000000000000000000000000 54d6cece0984ffff400000010000020fdf54c00401000000 54d6cf150984fff0000000010018000fdf51c018d7edb6b7 000000000000000000000000000000000000000000000000 54d6cf890984ffff400000010000030fdf51c00401000000 54d6cf980984fff0000000010018000fdf53c0180935d44e 000000000000000000000000000000000000000000000000 54d6d00b0984ffff400000010000000fdf53c00401000000 54d6d01b0984fff0000000010018000fdf52c01875ea4a2f 000000000000000000000000000000000000000000000000 54d6d08f0984ffff400000010000010fdf52c00401000000 54d6d09e0984fff0000000010018000fdf54c0181a49228b 000000000000000000000000000000000000000000000000 54d6d1110984ffff400000010000020fdf54c00401000000 54d6d1570984fff0000000010018000fdf51c018ba3eb5ed 000000000000000000000000000000000000000000000000 54d6d1cb0984ffff400000010000030fdf51c00401000000 54d6d1db0984fff0000000010018000fdf53c0184b0bae13 000000000000000000000000000000000000000000000000 54d6d2fc0984ffff400000010000000fdf53c00401000000 54d6d30b0984fff0000000010018000fdf52c01837d43072 000000000000000000000000000000000000000000000000 54d6d3870984ffff400000010000010fdf52c00401000000 54d6d3960984fff0000000010018000fdf54c018587758d6 000000000000000000000000000000000000000000000000 54d6d40a0984ffff400000010000020fdf54c00401000000 54d6d44f0984fff0000000010018000fdf51c018f800cfb0 000000000000000000000000000000000000000000000000 54d6d4c30984ffff400000010000030fdf51c00401000000 54d6d4d30984fff0000000010018000fdf53c01826d8ad49 000000000000000000000000000000000000000000000000 54d6d5460984ffff400000010000000fdf53c00401000000 54d6d5560984fff0000000010018000fdf52c0185a073328 000000000000000000000000000000000000000000000000 54d6d5d20984ffff400000010000010fdf52c00401000000 54d6d5e30984fff0000000010018000fdf54c01835a45b8c 000000000000000000000000000000000000000000000000 54d6d6560984ffff400000010000020fdf54c00401000000 54d6d6a30984fff0000000010018000fdf51c01895d3ccea 000000000000000000000000000000000000000000000000 54d6d7160984ffff400000010000030fdf51c00401000000 54d6d7250984fff0000000010018000fdf53c01891ada9a7 000000000000000000000000000000000000000000000000 54d6d7990984ffff400000010000000fdf53c00401000000 54d6d7a80984fff0000000010018000fdf52c018ed7237c6 000000000000000000000000000000000000000000000000 54d6d81b0984ffff400000010000010fdf52c00401000000 54d6d82a0984fff0000000010018000fdf54c01882d15f62 000000000000000000000000000000000000000000000000 54d6d89d0984ffff400000010000020fdf54c00401000000 54d6d8dd0984fff0000000010018000fdf51c01822a6c804 000000000000000000000000000000000000000000000000 54d6d9510984ffff400000010000030fdf51c00401000000 54d6d9600984fff0000000010018000fdf53c018fc7eaafd 000000000000000000000000000000000000000000000000 54d6d9d30984ffff400000010000000fdf53c00401000000 54d6d9e20984fff0000000010018000fdf52c01880a1349c 000000000000000000000000000000000000000000000000 54d6da550984ffff400000010000010fdf52c00401000000 54d6da640984fff0000000010018000fdf54c018ef025c38 000000000000000000000000000000000000000000000000 54d6dad70984ffff400000010000020fdf54c00401000000 54d6db240984fff0000000010018000fdf51c0184f75cb5e 000000000000000000000000000000000000000000000000 54d6db970984ffff400000010000030fdf51c00401000000 54d6dba60984fff0000000010018000fdf53c018f440a3eb 000000000000000000000000000000000000000000000000 54d6dc190984ffff400000010000000fdf53c00401000000 54d6dc280984fff0000000010018000fdf52c018889f3d8a 000000000000000000000000000000000000000000000000 54d6dc9b0984ffff400000010000010fdf52c00401000000 54d6dcaa0984fff0000000010018000fdf54c018e73c552e 000000000000000000000000000000000000000000000000 54d6dd1d0984ffff400000010000020fdf54c00401000000 54d6dd6d0984fff0000000010018000fdf51c018474bc248 000000000000000000000000000000000000000000000000 54d6dde00984ffff400000010000030fdf51c00401000000 54d6ddef0984fff0000000010018000fdf53c0189993a0b1 000000000000000000000000000000000000000000000000 54d6de620984ffff400000010000000fdf53c00401000000 54d6de720984fff0000000010018000fdf52c018e54c3ed0 000000000000000000000000000000000000000000000000 54d6dee60984ffff400000010000010fdf52c00401000000 54d6def50984fff0000000010018000fdf54c0188aef5674 000000000000000000000000000000000000000000000000 54d6df680984ffff400000010000020fdf54c00401000000 54d6dfab0984fff0000000010018000fdf51c0182a98c112 000000000000000000000000000000000000000000000000 54d6e01e0984ffff400000010000030fdf51c00401000000 54d6e02d0984fff0000000010018000fdf53c0182ee6a45f 000000000000000000000000000000000000000000000000 54d6e0a90984ffff400000010000000fdf53c00401000000 54d6e0b80984fff0000000010018000fdf52c01852393a3e 000000000000000000000000000000000000000000000000 54d6e12c0984ffff400000010000010fdf52c00401000000 54d6e13c0984fff0000000010018000fdf54c0183d9a529a 000000000000000000000000000000000000000000000000 d38df2dd0981fff0000000010018000fdf4040083bc0df7a 000000000000000000000000000000000000000000000000 d38df34c0981fff0000000010018000fdf404000c724cec9 000000000000000000000000000000000000000000000000 d38df3ba0981fff0000000010018000fdf4040045b393513 000000000000000000000000000000000000000000000000 d38df5040981fff0000000010018000fdf40401821b04420 000000000000000000000000000000000000000000000000 d38df5730981fff0000000010018000fdf40401096e109f3 000000000000000000000000000000000000000000000000 d38df5e10981fff0000000010018000fdf4040144149ae49 000000000000000000000000000000000000000000000000 d38df6e90981fff0000000010018000fdf40402843ec57bb 000000000000000000000000000000000000000000000000 d38df7570981fff0000000010018000fdf4040202962ffc8 000000000000000000000000000000000000000000000000 d38df7c50981fff0000000010018000fdf404024b57f0412 000000000000000000000000000000000000000000000000 d38df8bb0981fff0000000010018000fdf404038344fcfbb 000000000000000000000000000000000000000000000000 d38df92a0981fff0000000010018000fdf404030831e8268 000000000000000000000000000000000000000000000000 d38df9990981fff0000000010018000fdf40403480e2e64f 000000000000000000000000000000000000000000000000 d38dfa900981fff0000000010018000fdf4040481206c3cb 000000000000000000000000000000000000000000000000 d38dfafe0981fff0000000010018000fdf404040eee2d278 000000000000000000000000000000000000000000000000 d38dfb6b0981fff0000000010018000fdf40404472ff29a2 000000000000000000000000000000000000000000000000 d38dfc5f0981fff0000000010018000fdf40405865a55bcb 000000000000000000000000000000000000000000000000 d38dfcce0981fff0000000010018000fdf404050d2f41618 000000000000000000000000000000000000000000000000 d38dfd3c0981fff0000000010018000fdf404054055cb1a2 000000000000000000000000000000000000000000000000 d38dfe2f0981fff0000000010018000fdf40406807f94850 000000000000000000000000000000000000000000000000 d38dfe9e0981fff0000000010018000fdf40406000a4e379 000000000000000000000000000000000000000000000000 d38dff0c0981fff0000000010018000fdf4040649cb918a3 000000000000000000000000000000000000000000000000 d38e00040981fff0000000010018000fdf4040781d89d30a 000000000000000000000000000000000000000000000000 d38e00730981fff0000000010018000fdf404070aad89ed9 000000000000000000000000000000000000000000000000 d38e00e10981fff0000000010018000fdf404074eb1a80a3 000000000000000000000000000000000000000000000000 d38e01d50981fff0000000010018000fdf404088597d1dca 000000000000000000000000000000000000000000000000 d38e02430981fff0000000010018000fdf404080a5990c79 000000000000000000000000000000000000000000000000 d38e02b00981fff0000000010018000fdf4040843984f7a3 000000000000000000000000000000000000000000000000 d38e03a60981fff0000000010018000fdf40409899ab8124 000000000000000000000000000000000000000000000000 d38e04150981fff0000000010018000fdf4040902efaccf7 000000000000000000000000000000000000000000000000 d38e04830981fff0000000010018000fdf404094f9526b4d 000000000000000000000000000000000000000000000000 d38e05770981fff0000000010018000fdf4040a8fbf792bf 000000000000000000000000000000000000000000000000 d38e05e60981fff0000000010018000fdf4040a091793acc 000000000000000000000000000000000000000000000000 d38e06540981fff0000000010018000fdf4040a40d64c116 000000000000000000000000000000000000000000000000 d38e07530981fff0000000010018000fdf4040b88c540abf 000000000000000000000000000000000000000000000000 d38e07c20981fff0000000010018000fdf4040b03b05476c 000000000000000000000000000000000000000000000000 d38e08300981fff0000000010018000fdf4040b417145a4c 000000000000000000000000000000000000000000000000 d38e092c0981fff0000000010018000fdf4040c885f07fc8 000000000000000000000000000000000000000000000000 d38e09990981fff0000000010018000fdf4040c079146e7b 000000000000000000000000000000000000000000000000 d38e0a070981fff0000000010018000fdf4040c4e50995a1 000000000000000000000000000000000000000000000000 d38e0afd0981fff0000000010018000fdf4040d8f253e7c8 000000000000000000000000000000000000000000000000 d38e0b6d0981fff0000000010018000fdf4040d04502aa1b 000000000000000000000000000000000000000000000000 d38e0bdb0981fff0000000010018000fdf4040d492aa0da1 000000000000000000000000000000000000000000000000 d38e0ccf0981fff0000000010018000fdf4040e8900ff453 000000000000000000000000000000000000000000000000 d38e0d3d0981fff0000000010018000fdf4040e0132eabc0 000000000000000000000000000000000000000000000000 d38e0dab0981fff0000000010018000fdf4040e48f33501a 000000000000000000000000000000000000000000000000 d38e0ea00981fff0000000010018000fdf4040f80e039bb3 000000000000000000000000000000000000000000000000 d38e0f0f0981fff0000000010018000fdf4040f0b952d660 000000000000000000000000000000000000000000000000 d38e0f7d0981fff0000000010018000fdf4040f4f890c81a 000000000000000000000000000000000000000000000000 d38e111a0981ffff400000010000020fdf400c6000000000 54d55cc00984fff0000000010018000fdf54c018a9b8a486 000000000000000000000000000000000000000000000000 54d55d330984ffff400000010000010fdf54c00401000000 54d55d970984fff0000000010018000fdf51c01828d08ece 000000000000000000000000000000000000000000000000 54d55e0b0984ffff400000010000020fdf51c00401000000 54d55e1b0984fff0000000010018000fdf53c0180db156ad 000000000000000000000000000000000000000000000000 54d55e8f0984ffff400000010000030fdf53c00401000000 54d55ea00984fff0000000010018000fdf52c018e704710c 000000000000000000000000000000000000000000000000 54d55f130984ffff400000010000000fdf52c00401000000 54d55f220984fff0000000010018000fdf54c0181ecda068 000000000000000000000000000000000000000000000000 54d55f950984ffff400000010000010fdf54c00401000000 54d560140984fff0000000010018000fdf51c01845038d94 000000000000000000000000000000000000000000000000 54d560880984ffff400000010000020fdf51c00401000000 54d560970984fff0000000010018000fdf53c018606255f7 000000000000000000000000000000000000000000000000 54d5610b0984ffff400000010000030fdf53c00401000000 54d5611b0984fff0000000010018000fdf52c0188ad77256 000000000000000000000000000000000000000000000000 54d561900984ffff400000010000000fdf52c00401000000 54d5619f0984fff0000000010018000fdf54c018731ea332 000000000000000000000000000000000000000000000000 54d562120984ffff400000010000010fdf54c00401000000 54d562820984fff0000000010018000fdf51c018073df7c9 000000000000000000000000000000000000000000000000 54d562f60984ffff400000010000020fdf51c00401000000 54d563060984fff0000000010018000fdf53c018225c2faa 000000000000000000000000000000000000000000000000 54d5637a0984ffff400000010000030fdf53c00401000000 54d563890984fff0000000010018000fdf52c018c8e9080b 000000000000000000000000000000000000000000000000 54d563fc0984ffff400000010000000fdf52c00401000000 54d5640c0984fff0000000010018000fdf54c0183120d96f 000000000000000000000000000000000000000000000000 54d564890984ffff400000010000010fdf54c00401000000 54d564df0984fff0000000010018000fdf51c0186aeef493 000000000000000000000000000000000000000000000000 54d565520984ffff400000010000020fdf51c00401000000 54d565610984fff0000000010018000fdf53c0184f8f2cf0 000000000000000000000000000000000000000000000000 54d565d40984ffff400000010000030fdf53c00401000000 54d565e30984fff0000000010018000fdf52c018a53a0b51 000000000000000000000000000000000000000000000000 54d566570984ffff400000010000000fdf52c00401000000 54d566660984fff0000000010018000fdf54c0185cf3da35 000000000000000000000000000000000000000000000000 54d566da0984ffff400000010000010fdf54c00401000000 54d567310984fff0000000010018000fdf51c018dd9bf07d 000000000000000000000000000000000000000000000000 54d567a50984ffff400000010000020fdf51c00401000000 54d567b40984fff0000000010018000fdf53c018f8fa281e 000000000000000000000000000000000000000000000000 54d568280984ffff400000010000030fdf53c00401000000 54d568370984fff0000000010018000fdf52c018124f0fbf 000000000000000000000000000000000000000000000000 54d568b40984ffff400000010000000fdf52c00401000000 54d568c30984fff0000000010018000fdf54c018eb86dedb 000000000000000000000000000000000000000000000000 54d569370984ffff400000010000010fdf54c00401000000 54d569a20984fff0000000010018000fdf51c018b048f327 000000000000000000000000000000000000000000000000 54d56a150984ffff400000010000020fdf51c00401000000 54d56a240984fff0000000010018000fdf53c01895292b44 000000000000000000000000000000000000000000000000 54d56a970984ffff400000010000030fdf53c00401000000 54d56aa70984fff0000000010018000fdf52c0187f9c0ce5 000000000000000000000000000000000000000000000000 54d56b240984ffff400000010000000fdf52c00401000000 54d56b330984fff0000000010018000fdf54c0188655dd81 000000000000000000000000000000000000000000000000 54d56bb00984ffff400000010000010fdf54c00401000000 54d56c1a0984fff0000000010018000fdf51c01859e704c7 000000000000000000000000000000000000000000000000 54d56c8e0984ffff400000010000020fdf51c00401000000 54d56c9d0984fff0000000010018000fdf53c0187c86dca4 000000000000000000000000000000000000000000000000 54d56d1a0984ffff400000010000030fdf53c00401000000 54d56d290984fff0000000010018000fdf52c0189633fb05 000000000000000000000000000000000000000000000000 54d56d9c0984ffff400000010000000fdf52c00401000000 54d56dac0984fff0000000010018000fdf54c0186ffa2a61 000000000000000000000000000000000000000000000000 54d56e290984ffff400000010000010fdf54c00401000000 54d56e8d0984fff0000000010018000fdf51c0183434079d 000000000000000000000000000000000000000000000000 54d56f000984ffff400000010000020fdf51c00401000000 54d56f0f0984fff0000000010018000fdf53c0181155dffe 000000000000000000000000000000000000000000000000 54d56f8b0984ffff400000010000030fdf53c00401000000 54d56f9a0984fff0000000010018000fdf52c018fbe0f85f 000000000000000000000000000000000000000000000000 54d5700e0984ffff400000010000000fdf52c00401000000 54d5701e0984fff0000000010018000fdf54c0180229293b 000000000000000000000000000000000000000000000000 54d5709b0984ffff400000010000010fdf54c00401000000 54d570ff0984fff0000000010018000fdf51c01883410373 000000000000000000000000000000000000000000000000 54d5717b0984ffff400000010000020fdf51c00401000000 54d5718a0984fff0000000010018000fdf53c018a620db10 000000000000000000000000000000000000000000000000 54d571fe0984ffff400000010000030fdf53c00401000000 54d5720d0984fff0000000010018000fdf52c0184c95fcb1 000000000000000000000000000000000000000000000000 54d572890984ffff400000010000000fdf52c00401000000 54d572980984fff0000000010018000fdf54c018b55c2dd5 000000000000000000000000000000000000000000000000 54d5730d0984ffff400000010000010fdf54c00401000000 54d573860984fff0000000010018000fdf51c018ee920029 000000000000000000000000000000000000000000000000 54d573f90984ffff400000010000020fdf51c00401000000 54d574090984fff0000000010018000fdf53c018cbf3d84a 000000000000000000000000000000000000000000000000 54d574860984ffff400000010000030fdf53c00401000000 54d574950984fff0000000010018000fdf52c0182146ffeb 000000000000000000000000000000000000000000000000 54d575090984ffff400000010000000fdf52c00401000000 54d575180984fff0000000010018000fdf54c018d88f2e8f 000000000000000000000000000000000000000000000000 54d575940984ffff400000010000010fdf54c00401000000 54d575ef0984fff0000000010018000fdf51c018acac7a74 000000000000000000000000000000000000000000000000 54d5766d0984ffff400000010000020fdf51c00401000000 54d5767b0984fff0000000010018000fdf53c01889cda217 000000000000000000000000000000000000000000000000 54d576ef0984ffff400000010000030fdf53c00401000000 54d576fe0984fff0000000010018000fdf52c018637885b6 000000000000000000000000000000000000000000000000 54d5777a0984ffff400000010000000fdf52c00401000000 54d577890984fff0000000010018000fdf54c0189ab154d2 000000000000000000000000000000000000000000000000 54d578060984ffff400000010000010fdf54c00401000000 54d5785f0984fff0000000010018000fdf51c018c17f792e 000000000000000000000000000000000000000000000000 54d578d20984ffff400000010000020fdf51c00401000000 54d578e20984fff0000000010018000fdf53c018e41ea14d 000000000000000000000000000000000000000000000000 54d5795f0984ffff400000010000030fdf53c00401000000 54d5796e0984fff0000000010018000fdf52c0180eab86ec 000000000000000000000000000000000000000000000000 54d579e20984ffff400000010000000fdf52c00401000000 54d579f10984fff0000000010018000fdf54c018f7625788 000000000000000000000000000000000000000000000000 54d57a6d0984ffff400000010000010fdf54c00401000000 54d57ac10984fff0000000010018000fdf51c018760a7dc0 000000000000000000000000000000000000000000000000 54d57b340984ffff400000010000020fdf51c00401000000 54d57b430984fff0000000010018000fdf53c018536ba5a3 000000000000000000000000000000000000000000000000 54d57bb80984ffff400000010000030fdf53c00401000000 54d57bc70984fff0000000010018000fdf52c018b9de8202 000000000000000000000000000000000000000000000000 54d57c3a0984ffff400000010000000fdf52c00401000000 54d57c4a0984fff0000000010018000fdf54c01840175366 000000000000000000000000000000000000000000000000 54d57cc70984ffff400000010000010fdf54c00401000000 54d57d1e0984fff0000000010018000fdf51c0181bd97e9a 000000000000000000000000000000000000000000000000 54d57d920984ffff400000010000020fdf51c00401000000 54d57da20984fff0000000010018000fdf53c0183eb8a6f9 000000000000000000000000000000000000000000000000 54d57e160984ffff400000010000030fdf53c00401000000 54d57e260984fff0000000010018000fdf52c018d40d8158 000000000000000000000000000000000000000000000000 54d57e990984ffff400000010000000fdf52c00401000000 54d57ea80984fff0000000010018000fdf54c0182dc4503c 000000000000000000000000000000000000000000000000 54d57f1b0984ffff400000010000010fdf54c00401000000 54d57f770984fff0000000010018000fdf51c018e553e3da 000000000000000000000000000000000000000000000000 54d57feb0984ffff400000010000020fdf51c00401000000 54d57ffb0984fff0000000010018000fdf53c018c0323bb9 000000000000000000000000000000000000000000000000 54d580780984ffff400000010000030fdf53c00401000000 54d580870984fff0000000010018000fdf52c0182a871c18 000000000000000000000000000000000000000000000000 54d580fb0984ffff400000010000000fdf52c00401000000 54d5810a0984fff0000000010018000fdf54c018d34ecd7c 000000000000000000000000000000000000000000000000 54d581830984ffff400000010000010fdf54c00401000000 54d581eb0984fff0000000010018000fdf51c0188880e080 000000000000000000000000000000000000000000000000 54d5825f0984ffff400000010000020fdf51c00401000000 54d5826e0984fff0000000010018000fdf53c018ade138e3 000000000000000000000000000000000000000000000000 54d582e10984ffff400000010000030fdf53c00401000000 54d582f10984fff0000000010018000fdf52c01847541f42 000000000000000000000000000000000000000000000000 54d583650984ffff400000010000000fdf52c00401000000 54d583740984fff0000000010018000fdf54c018be9dce26 000000000000000000000000000000000000000000000000 54d583fd0984ffff400000010000010fdf54c00401000000 54d584530984fff0000000010018000fdf51c0183ff5e46e 000000000000000000000000000000000000000000000000 54d584c60984ffff400000010000020fdf51c00401000000 54d584d50984fff0000000010018000fdf53c0181a943c0d 000000000000000000000000000000000000000000000000 54d585490984ffff400000010000030fdf53c00401000000 54d585590984fff0000000010018000fdf52c018f0211bac 000000000000000000000000000000000000000000000000 54d585cc0984ffff400000010000000fdf52c00401000000 54d585db0984fff0000000010018000fdf54c01809e8cac8 000000000000000000000000000000000000000000000000 54d5864e0984ffff400000010000010fdf54c00401000000 54d586980984fff0000000010018000fdf51c0185226e734 000000000000000000000000000000000000000000000000 54d5870c0984ffff400000010000020fdf51c00401000000 54d5871c0984fff0000000010018000fdf53c01877473f57 000000000000000000000000000000000000000000000000 54d587900984ffff400000010000030fdf53c00401000000 54d5879f0984fff0000000010018000fdf52c0189df218f6 000000000000000000000000000000000000000000000000 54d588120984ffff400000010000000fdf52c00401000000 54d588210984fff0000000010018000fdf54c018643bc992 000000000000000000000000000000000000000000000000 54d588940984ffff400000010000010fdf54c00401000000 54d588de0984fff0000000010018000fdf51c01810189d69 000000000000000000000000000000000000000000000000 54d589530984ffff400000010000020fdf51c00401000000 54d589620984fff0000000010018000fdf53c0183579450a 000000000000000000000000000000000000000000000000 54d589d60984ffff400000010000030fdf53c00401000000 54d589e50984fff0000000010018000fdf52c018dfcc62ab 000000000000000000000000000000000000000000000000 54d58a590984ffff400000010000000fdf52c00401000000 54d58a690984fff0000000010018000fdf54c0182605b3cf 000000000000000000000000000000000000000000000000 54d58add0984ffff400000010000010fdf54c00401000000 54d58b260984fff0000000010018000fdf51c0187dcb9e33 000000000000000000000000000000000000000000000000 54d58b990984ffff400000010000020fdf51c00401000000 54d58ba80984fff0000000010018000fdf53c01858aa4650 000000000000000000000000000000000000000000000000 54d58c1b0984ffff400000010000030fdf53c00401000000 54d58c2b0984fff0000000010018000fdf52c018b21f61f1 000000000000000000000000000000000000000000000000 54d58c9f0984ffff400000010000000fdf52c00401000000 54d58cae0984fff0000000010018000fdf54c0184bd6b095 000000000000000000000000000000000000000000000000 54d58d210984ffff400000010000010fdf54c00401000000 54d58d6b0984fff0000000010018000fdf51c018cabe9add 000000000000000000000000000000000000000000000000 54d58ddf0984ffff400000010000020fdf51c00401000000 54d58dee0984fff0000000010018000fdf53c018efdf42be 000000000000000000000000000000000000000000000000 54d58e610984ffff400000010000030fdf53c00401000000 54d58e700984fff0000000010018000fdf52c018056a651f 000000000000000000000000000000000000000000000000 54d58ee30984ffff400000010000000fdf52c00401000000 54d58ef20984fff0000000010018000fdf54c018fca3b47b 000000000000000000000000000000000000000000000000 54d58f660984ffff400000010000010fdf54c00401000000 54d58fb40984fff0000000010018000fdf51c018a76d9987 000000000000000000000000000000000000000000000000 54d590280984ffff400000010000020fdf51c00401000000 54d590380984fff0000000010018000fdf53c018820c41e4 000000000000000000000000000000000000000000000000 54d590ac0984ffff400000010000030fdf53c00401000000 54d590bb0984fff0000000010018000fdf52c01868b96645 000000000000000000000000000000000000000000000000 54d5912e0984ffff400000010000000fdf52c00401000000 54d5913d0984fff0000000010018000fdf54c0189170b721 000000000000000000000000000000000000000000000000 54d591b00984ffff400000010000010fdf54c00401000000 54d591fa0984fff0000000010018000fdf51c0184ec26e67 000000000000000000000000000000000000000000000000 54d5926e0984ffff400000010000020fdf51c00401000000 54d5927e0984fff0000000010018000fdf53c0186ba3b604 000000000000000000000000000000000000000000000000 54d592f20984ffff400000010000030fdf53c00401000000 54d593020984fff0000000010018000fdf52c018811691a5 000000000000000000000000000000000000000000000000 54d593760984ffff400000010000000fdf52c00401000000 54d593850984fff0000000010018000fdf54c01878df40c1 000000000000000000000000000000000000000000000000 54d593f80984ffff400000010000010fdf54c00401000000 54d594450984fff0000000010018000fdf51c01823116d3d 000000000000000000000000000000000000000000000000 54d594b80984ffff400000010000020fdf51c00401000000 54d594c70984fff0000000010018000fdf53c0180670b55e 000000000000000000000000000000000000000000000000 54d5953a0984ffff400000010000030fdf53c00401000000 54d595490984fff0000000010018000fdf52c018ecc592ff 000000000000000000000000000000000000000000000000 54d595bd0984ffff400000010000000fdf52c00401000000 54d595cc0984fff0000000010018000fdf54c018150c439b 000000000000000000000000000000000000000000000000 54d5963f0984ffff400000010000010fdf54c00401000000 54d596880984fff0000000010018000fdf51c018946469d3 000000000000000000000000000000000000000000000000 54d596fb0984ffff400000010000020fdf51c00401000000 54d5970a0984fff0000000010018000fdf53c018b105b1b0 000000000000000000000000000000000000000000000000 54d5977d0984ffff400000010000030fdf53c00401000000 54d5978d0984fff0000000010018000fdf52c0185bb09611 000000000000000000000000000000000000000000000000 54d598010984ffff400000010000000fdf52c00401000000 54d598100984fff0000000010018000fdf54c018a2794775 000000000000000000000000000000000000000000000000 54d598830984ffff400000010000010fdf54c00401000000 54d598cc0984fff0000000010018000fdf51c018f9b76a89 000000000000000000000000000000000000000000000000 54d5993f0984ffff400000010000020fdf51c00401000000 54d5994f0984fff0000000010018000fdf53c018dcd6b2ea 000000000000000000000000000000000000000000000000 54d599c30984ffff400000010000030fdf53c00401000000 54d599d20984fff0000000010018000fdf52c0183663954b 000000000000000000000000000000000000000000000000 54d59a450984ffff400000010000000fdf52c00401000000 54d59a540984fff0000000010018000fdf54c018cfaa442f 000000000000000000000000000000000000000000000000 54d59ac80984ffff400000010000010fdf54c00401000000 54d59b110984fff0000000010018000fdf51c018bb8910d4 000000000000000000000000000000000000000000000000 54d59b840984ffff400000010000020fdf51c00401000000 54d59b930984fff0000000010018000fdf53c0189ee8c8b7 000000000000000000000000000000000000000000000000 54d59c060984ffff400000010000030fdf53c00401000000 54d59c150984fff0000000010018000fdf52c018745def16 000000000000000000000000000000000000000000000000 54d59c880984ffff400000010000000fdf52c00401000000 54d59c980984fff0000000010018000fdf54c0188d943e72 000000000000000000000000000000000000000000000000 54d59d0c0984ffff400000010000010fdf54c00401000000 54d59d560984fff0000000010018000fdf51c018d65a138e 000000000000000000000000000000000000000000000000 54d59dca0984ffff400000010000020fdf51c00401000000 54d59dda0984fff0000000010018000fdf53c018f33bcbed 000000000000000000000000000000000000000000000000 54d59e4e0984ffff400000010000030fdf53c00401000000 54d59e5d0984fff0000000010018000fdf52c018198eec4c 000000000000000000000000000000000000000000000000 54d59ed00984ffff400000010000000fdf52c00401000000 54d59edf0984fff0000000010018000fdf54c018e0473d28 000000000000000000000000000000000000000000000000 54d59f520984ffff400000010000010fdf54c00401000000 54d59f9b0984fff0000000010018000fdf51c018612f1760 000000000000000000000000000000000000000000000000 54d5a00e0984ffff400000010000020fdf51c00401000000 54d5a01d0984fff0000000010018000fdf53c018444ecf03 000000000000000000000000000000000000000000000000 54d5a0900984ffff400000010000030fdf53c00401000000 54d5a0a00984fff0000000010018000fdf52c018aefbe8a2 000000000000000000000000000000000000000000000000 54d5a1140984ffff400000010000000fdf52c00401000000 54d5a1240984fff0000000010018000fdf54c018573239c6 000000000000000000000000000000000000000000000000 54d5a1970984ffff400000010000010fdf54c00401000000 54d5a1e10984fff0000000010018000fdf51c0180cfc143a 000000000000000000000000000000000000000000000000 54d5a2560984ffff400000010000020fdf51c00401000000 54d5a2650984fff0000000010018000fdf53c018299dcc59 000000000000000000000000000000000000000000000000 54d5a2d90984ffff400000010000030fdf53c00401000000 54d5a2e80984fff0000000010018000fdf52c018c328ebf8 000000000000000000000000000000000000000000000000 54d5a35b0984ffff400000010000000fdf52c00401000000 54d5a36b0984fff0000000010018000fdf54c0183ae13a9c 000000000000000000000000000000000000000000000000 54d5a3df0984ffff400000010000010fdf54c00401000000 54d5a4270984fff0000000010018000fdf51c01832dc441f 000000000000000000000000000000000000000000000000 54d5a49b0984ffff400000010000020fdf51c00401000000 54d5a4aa0984fff0000000010018000fdf53c01817bd9c7c 000000000000000000000000000000000000000000000000 54d5a51d0984ffff400000010000030fdf53c00401000000 54d5a52d0984fff0000000010018000fdf52c018fd08bbdd 000000000000000000000000000000000000000000000000 54d5a5a10984ffff400000010000000fdf52c00401000000 54d5a5b00984fff0000000010018000fdf54c01804c16ab9 000000000000000000000000000000000000000000000000 54d5a6230984ffff400000010000010fdf54c00401000000 54d5a6720984fff0000000010018000fdf51c0185f0f4745 000000000000000000000000000000000000000000000000 54d5a6e60984ffff400000010000020fdf51c00401000000 54d5a6f60984fff0000000010018000fdf53c0187a6e9f26 000000000000000000000000000000000000000000000000 54d5a76a0984ffff400000010000030fdf53c00401000000 54d5a7790984fff0000000010018000fdf52c01890dbb887 000000000000000000000000000000000000000000000000 54d5a7ec0984ffff400000010000000fdf52c00401000000 54d5a7fc0984fff0000000010018000fdf54c018691269e3 000000000000000000000000000000000000000000000000 54d5a8700984ffff400000010000010fdf54c00401000000 54d5a8bc0984fff0000000010018000fdf51c018e87a43ab 000000000000000000000000000000000000000000000000 54d5a9300984ffff400000010000020fdf51c00401000000 54d5a93f0984fff0000000010018000fdf53c018cd1b9bc8 000000000000000000000000000000000000000000000000 54d5a9b20984ffff400000010000030fdf53c00401000000 54d5a9c10984fff0000000010018000fdf52c01827aebc69 000000000000000000000000000000000000000000000000 54d5aa340984ffff400000010000000fdf52c00401000000 54d5aa430984fff0000000010018000fdf54c018de676d0d 000000000000000000000000000000000000000000000000 54d5aab60984ffff400000010000010fdf54c00401000000 54d5ab060984fff0000000010018000fdf51c01885a940f1 000000000000000000000000000000000000000000000000 54d5ab7a0984ffff400000010000020fdf51c00401000000 54d5ab8a0984fff0000000010018000fdf53c018a0c89892 000000000000000000000000000000000000000000000000 54d5abfe0984ffff400000010000030fdf53c00401000000 54d5ac0d0984fff0000000010018000fdf52c0184a7dbf33 000000000000000000000000000000000000000000000000 54d5ac800984ffff400000010000000fdf52c00401000000 54d5ac8f0984fff0000000010018000fdf54c018b3b46e57 000000000000000000000000000000000000000000000000 54d5ad030984ffff400000010000010fdf54c00401000000 54d5ad4f0984fff0000000010018000fdf51c018c7973aac 000000000000000000000000000000000000000000000000 54d5adc30984ffff400000010000020fdf51c00401000000 54d5add20984fff0000000010018000fdf53c018e2f6e2cf 000000000000000000000000000000000000000000000000 54d5ae450984ffff400000010000030fdf53c00401000000 54d5ae540984fff0000000010018000fdf52c0180843c56e 000000000000000000000000000000000000000000000000 54d5aec70984ffff400000010000000fdf52c00401000000 54d5aed60984fff0000000010018000fdf54c018f18a140a 000000000000000000000000000000000000000000000000 54d5af490984ffff400000010000010fdf54c00401000000 54d5af920984fff0000000010018000fdf51c018aa4439f6 000000000000000000000000000000000000000000000000 54d5b0050984ffff400000010000020fdf51c00401000000 54d5b0150984fff0000000010018000fdf53c0188f25e195 000000000000000000000000000000000000000000000000 54d5b0890984ffff400000010000030fdf53c00401000000 54d5b0980984fff0000000010018000fdf52c0186590c634 000000000000000000000000000000000000000000000000 54d5b10b0984ffff400000010000000fdf52c00401000000 54d5b11a0984fff0000000010018000fdf54c0189c591750 000000000000000000000000000000000000000000000000 54d5b18d0984ffff400000010000010fdf54c00401000000 54d5b1f80984fff0000000010018000fdf51c0181d313d18 000000000000000000000000000000000000000000000000 54d5b26c0984ffff400000010000020fdf51c00401000000 54d5b27b0984fff0000000010018000fdf53c0183850e57b 000000000000000000000000000000000000000000000000 54d5b2ef0984ffff400000010000030fdf53c00401000000 54d5b2fe0984fff0000000010018000fdf52c018d2e5c2da 000000000000000000000000000000000000000000000000 54d5b3720984ffff400000010000000fdf52c00401000000 54d5b3810984fff0000000010018000fdf54c0182b2c13be 000000000000000000000000000000000000000000000000 54d5b3f40984ffff400000010000010fdf54c00401000000 54d5b43d0984fff0000000010018000fdf51c01870e23e42 000000000000000000000000000000000000000000000000 54d5b4b00984ffff400000010000020fdf51c00401000000 54d5b4bf0984fff0000000010018000fdf53c0185583e621 000000000000000000000000000000000000000000000000 54d5b5330984ffff400000010000030fdf53c00401000000 54d5b5420984fff0000000010018000fdf52c018bf36c180 000000000000000000000000000000000000000000000000 54d5b5b60984ffff400000010000000fdf52c00401000000 54d5b5c50984fff0000000010018000fdf54c01846ff10e4 000000000000000000000000000000000000000000000000 54d5b6380984ffff400000010000010fdf54c00401000000 54d5b6a00984fff0000000010018000fdf51c018994dc9a2 000000000000000000000000000000000000000000000000 54d5b7140984ffff400000010000020fdf51c00401000000 54d5b7230984fff0000000010018000fdf53c018bc2c11c1 000000000000000000000000000000000000000000000000 54d5b7960984ffff400000010000030fdf53c00401000000 54d5b7a50984fff0000000010018000fdf52c01856993660 000000000000000000000000000000000000000000000000 54d5b8180984ffff400000010000000fdf52c00401000000 54d5b8270984fff0000000010018000fdf54c018af50e704 000000000000000000000000000000000000000000000000 54d5b89c0984ffff400000010000010fdf54c00401000000 54d5b8e40984fff0000000010018000fdf51c018f49ecaf8 000000000000000000000000000000000000000000000000 54d5b9570984ffff400000010000020fdf51c00401000000 54d5b9660984fff0000000010018000fdf53c018d1ff129b 000000000000000000000000000000000000000000000000 54d5b9d90984ffff400000010000030fdf53c00401000000 54d5b9e80984fff0000000010018000fdf52c0183b4a353a 000000000000000000000000000000000000000000000000 54d5ba5b0984ffff400000010000000fdf52c00401000000 54d5ba6a0984fff0000000010018000fdf54c018c283e45e 000000000000000000000000000000000000000000000000 54d5badd0984ffff400000010000010fdf54c00401000000 54d5bb290984fff0000000010018000fdf51c01843ebce16 000000000000000000000000000000000000000000000000 54d5bb9d0984ffff400000010000020fdf51c00401000000 54d5bbad0984fff0000000010018000fdf53c018668a1675 000000000000000000000000000000000000000000000000 54d5bc210984ffff400000010000030fdf53c00401000000 54d5bc300984fff0000000010018000fdf52c0188c3f31d4 000000000000000000000000000000000000000000000000 54d5bca30984ffff400000010000000fdf52c00401000000 54d5bcb20984fff0000000010018000fdf54c01875f6e0b0 000000000000000000000000000000000000000000000000 54d5bd250984ffff400000010000010fdf54c00401000000 54d5bd6e0984fff0000000010018000fdf51c0182e38cd4c 000000000000000000000000000000000000000000000000 54d5bde10984ffff400000010000020fdf51c00401000000 54d5bdf00984fff0000000010018000fdf53c0180b59152f 000000000000000000000000000000000000000000000000 54d5be640984ffff400000010000030fdf53c00401000000 54d5be730984fff0000000010018000fdf52c018e1ec328e 000000000000000000000000000000000000000000000000 54d5bee60984ffff400000010000000fdf52c00401000000 54d5bef50984fff0000000010018000fdf54c0181825e3ea 000000000000000000000000000000000000000000000000 54d5bf680984ffff400000010000010fdf54c00401000000 54d5bfb10984fff0000000010018000fdf51c0186c06b711 000000000000000000000000000000000000000000000000 54d5c0240984ffff400000010000020fdf51c00401000000 54d5c0330984fff0000000010018000fdf53c01849676f72 000000000000000000000000000000000000000000000000 54d5c0a60984ffff400000010000030fdf53c00401000000 54d5c0b50984fff0000000010018000fdf52c018a3d248d3 000000000000000000000000000000000000000000000000 54d5c1280984ffff400000010000000fdf52c00401000000 54d5c1380984fff0000000010018000fdf54c0185a1b99b7 000000000000000000000000000000000000000000000000 54d5c1ac0984ffff400000010000010fdf54c00401000000 54d5c1f60984fff0000000010018000fdf51c01801d5b44b 000000000000000000000000000000000000000000000000 54d5c26a0984ffff400000010000020fdf51c00401000000 54d5c2790984fff0000000010018000fdf53c01824b46c28 000000000000000000000000000000000000000000000000 54d5c2ec0984ffff400000010000030fdf53c00401000000 54d5c2fb0984fff0000000010018000fdf52c018ce014b89 000000000000000000000000000000000000000000000000 54d5c36e0984ffff400000010000000fdf52c00401000000 54d5c37d0984fff0000000010018000fdf54c01837c89aed 000000000000000000000000000000000000000000000000 54d5c3f10984ffff400000010000010fdf54c00401000000 54d5c4450984fff0000000010018000fdf51c018b6a0b0a5 000000000000000000000000000000000000000000000000 54d5c4b90984ffff400000010000020fdf51c00401000000 54d5c4c90984fff0000000010018000fdf53c01893c168c6 000000000000000000000000000000000000000000000000 54d5c53d0984ffff400000010000030fdf53c00401000000 54d5c54c0984fff0000000010018000fdf52c01879744f67 000000000000000000000000000000000000000000000000 54d5c5bf0984ffff400000010000000fdf52c00401000000 54d5c5ce0984fff0000000010018000fdf54c01880bd9e03 000000000000000000000000000000000000000000000000 54d5c6410984ffff400000010000010fdf54c00401000000 54d5c68a0984fff0000000010018000fdf51c018db73b3ff 000000000000000000000000000000000000000000000000 54d5c6fd0984ffff400000010000020fdf51c00401000000 54d5c70c0984fff0000000010018000fdf53c018fe126b9c 000000000000000000000000000000000000000000000000 54d5c77f0984ffff400000010000030fdf53c00401000000 54d5c78e0984fff0000000010018000fdf52c01814a74c3d 000000000000000000000000000000000000000000000000 54d5c8010984ffff400000010000000fdf52c00401000000 54d5c8100984fff0000000010018000fdf54c018ed6e9d59 000000000000000000000000000000000000000000000000 54d5c8830984ffff400000010000010fdf54c00401000000 54d5c8cb0984fff0000000010018000fdf51c01825f92ebf 000000000000000000000000000000000000000000000000 54d5c93f0984ffff400000010000020fdf51c00401000000 54d5c94e0984fff0000000010018000fdf53c0180098f6dc 000000000000000000000000000000000000000000000000 54d5c9c20984ffff400000010000030fdf53c00401000000 54d5c9d10984fff0000000010018000fdf52c018ea2dd17d 000000000000000000000000000000000000000000000000 54d5ca440984ffff400000010000000fdf52c00401000000 54d5ca540984fff0000000010018000fdf54c01813e40019 000000000000000000000000000000000000000000000000 54d5cac80984ffff400000010000010fdf54c00401000000 54d5cb140984fff0000000010018000fdf51c018482a2de5 000000000000000000000000000000000000000000000000 54d5cb880984ffff400000010000020fdf51c00401000000 54d5cb970984fff0000000010018000fdf53c0186d4bf586 000000000000000000000000000000000000000000000000 54d5cc0a0984ffff400000010000030fdf53c00401000000 54d5cc1a0984fff0000000010018000fdf52c01887fed227 000000000000000000000000000000000000000000000000 54d5cc8e0984ffff400000010000000fdf52c00401000000 54d5cc9e0984fff0000000010018000fdf54c0187e370343 000000000000000000000000000000000000000000000000 54d5cd120984ffff400000010000010fdf54c00401000000 54d5cd5b0984fff0000000010018000fdf51c018ff5f290b 000000000000000000000000000000000000000000000000 54d5cdce0984ffff400000010000020fdf51c00401000000 54d5cdde0984fff0000000010018000fdf53c018da3ef168 000000000000000000000000000000000000000000000000 54d5ce520984ffff400000010000030fdf53c00401000000 54d5ce610984fff0000000010018000fdf52c018308bd6c9 000000000000000000000000000000000000000000000000 54d5ced40984ffff400000010000000fdf52c00401000000 54d5cee30984fff0000000010018000fdf54c018c94207ad 000000000000000000000000000000000000000000000000 54d5cf570984ffff400000010000010fdf54c00401000000 54d5cfa10984fff0000000010018000fdf51c018928c2a51 000000000000000000000000000000000000000000000000 54d5d0150984ffff400000010000020fdf51c00401000000 54d5d0250984fff0000000010018000fdf53c018b7edf232 000000000000000000000000000000000000000000000000 54d5d0990984ffff400000010000030fdf53c00401000000 54d5d0a80984fff0000000010018000fdf52c0185d58d593 000000000000000000000000000000000000000000000000 54d5d11b0984ffff400000010000000fdf52c00401000000 54d5d12b0984fff0000000010018000fdf54c018a49104f7 000000000000000000000000000000000000000000000000 54d5d19f0984ffff400000010000010fdf54c00401000000 54d5d1e90984fff0000000010018000fdf51c018d0b2500c 000000000000000000000000000000000000000000000000 54d5d25d0984ffff400000010000020fdf51c00401000000 54d5d26c0984fff0000000010018000fdf53c018f5d3886f 000000000000000000000000000000000000000000000000 54d5d2df0984ffff400000010000030fdf53c00401000000 54d5d2ee0984fff0000000010018000fdf52c0181f66afce 000000000000000000000000000000000000000000000000 54d5d3610984ffff400000010000000fdf52c00401000000 54d5d3700984fff0000000010018000fdf54c018e6af7eaa 000000000000000000000000000000000000000000000000 54d5d3e30984ffff400000010000010fdf54c00401000000 54d5d42c0984fff0000000010018000fdf51c018bd615356 000000000000000000000000000000000000000000000000 54d5d49f0984ffff400000010000020fdf51c00401000000 54d5d4ae0984fff0000000010018000fdf53c01898008b35 000000000000000000000000000000000000000000000000 54d5d5220984ffff400000010000030fdf53c00401000000 54d5d5310984fff0000000010018000fdf52c01872b5ac94 000000000000000000000000000000000000000000000000 54d5d5a40984ffff400000010000000fdf52c00401000000 54d5d5b30984fff0000000010018000fdf54c0188b7c7df0 000000000000000000000000000000000000000000000000 54d5d6260984ffff400000010000010fdf54c00401000000 54d5d6700984fff0000000010018000fdf51c0180a1457b8 000000000000000000000000000000000000000000000000 54d5d6e40984ffff400000010000020fdf51c00401000000 54d5d6f30984fff0000000010018000fdf53c0182f758fdb 000000000000000000000000000000000000000000000000 54d5d7660984ffff400000010000030fdf53c00401000000 54d5d7750984fff0000000010018000fdf52c018c5c0a87a 000000000000000000000000000000000000000000000000 54d5d7e80984ffff400000010000000fdf52c00401000000 54d5d7f70984fff0000000010018000fdf54c0183c09791e 000000000000000000000000000000000000000000000000 54d5d86a0984ffff400000010000010fdf54c00401000000 54d5d8b20984fff0000000010018000fdf51c01867c754e2 000000000000000000000000000000000000000000000000 54d5d9260984ffff400000010000020fdf51c00401000000 54d5d9350984fff0000000010018000fdf53c01842a68c81 000000000000000000000000000000000000000000000000 54d5d9a80984ffff400000010000030fdf53c00401000000 54d5d9b70984fff0000000010018000fdf52c018a813ab20 000000000000000000000000000000000000000000000000 54d5da2a0984ffff400000010000000fdf52c00401000000 54d5da390984fff0000000010018000fdf54c01851da7a44 000000000000000000000000000000000000000000000000 54d5daac0984ffff400000010000010fdf54c00401000000 54d5daf50984fff0000000010018000fdf51c0188e68a302 000000000000000000000000000000000000000000000000 54d5db690984ffff400000010000020fdf51c00401000000 54d5db780984fff0000000010018000fdf53c018ab097b61 000000000000000000000000000000000000000000000000 54d5dbeb0984ffff400000010000030fdf53c00401000000 54d5dbfa0984fff0000000010018000fdf52c01841bc5cc0 000000000000000000000000000000000000000000000000 54d5dc6d0984ffff400000010000000fdf52c00401000000 54d5dc7c0984fff0000000010018000fdf54c018b8758da4 000000000000000000000000000000000000000000000000 54d5dcef0984ffff400000010000010fdf54c00401000000 54d5dd380984fff0000000010018000fdf51c018e3bba058 000000000000000000000000000000000000000000000000 54d5ddab0984ffff400000010000020fdf51c00401000000 54d5ddba0984fff0000000010018000fdf53c018c6da783b 000000000000000000000000000000000000000000000000 54d5de2d0984ffff400000010000030fdf53c00401000000 54d5de3c0984fff0000000010018000fdf52c0182c6f5f9a 000000000000000000000000000000000000000000000000 54d5deaf0984ffff400000010000000fdf52c00401000000 54d5debe0984fff0000000010018000fdf54c018d5a68efe 000000000000000000000000000000000000000000000000 54d5df310984ffff400000010000010fdf54c00401000000 54d5df7a0984fff0000000010018000fdf51c01854cea4b6 000000000000000000000000000000000000000000000000 54d5dfed0984ffff400000010000020fdf51c00401000000 54d5dffc0984fff0000000010018000fdf53c01871af7cd5 000000000000000000000000000000000000000000000000 54d5e0700984ffff400000010000030fdf53c00401000000 54d5e07f0984fff0000000010018000fdf52c0189b1a5b74 000000000000000000000000000000000000000000000000 54d5e0f20984ffff400000010000000fdf52c00401000000 54d5e1010984fff0000000010018000fdf54c01862d38a10 000000000000000000000000000000000000000000000000 54d5e1740984ffff400000010000010fdf54c00401000000 54d5e1c00984fff0000000010018000fdf51c018391da7ec 000000000000000000000000000000000000000000000000 54d5e2340984ffff400000010000020fdf51c00401000000 54d5e2430984fff0000000010018000fdf53c0181c7c7f8f 000000000000000000000000000000000000000000000000 54d5e2b60984ffff400000010000030fdf53c00401000000 54d5e2c50984fff0000000010018000fdf52c018f6c9582e 000000000000000000000000000000000000000000000000 54d5e3380984ffff400000010000000fdf52c00401000000 54d5e3470984fff0000000010018000fdf54c0180f00894a 000000000000000000000000000000000000000000000000 54d5e3ba0984ffff400000010000010fdf54c00401000000 54d5e4030984fff0000000010018000fdf51c0187b23ddb1 000000000000000000000000000000000000000000000000 54d5e4760984ffff400000010000020fdf51c00401000000 54d5e4850984fff0000000010018000fdf53c0185e4205d2 000000000000000000000000000000000000000000000000 54d5e4f80984ffff400000010000030fdf53c00401000000 54d5e5070984fff0000000010018000fdf52c018b4f72273 000000000000000000000000000000000000000000000000 54d5e57a0984ffff400000010000000fdf52c00401000000 54d5e5890984fff0000000010018000fdf54c0184d3ef317 000000000000000000000000000000000000000000000000 54d5e5fc0984ffff400000010000010fdf54c00401000000 54d5e6450984fff0000000010018000fdf51c01816f0deeb 000000000000000000000000000000000000000000000000 54d5e6b90984ffff400000010000020fdf51c00401000000 54d5e6c80984fff0000000010018000fdf53c01833910688 000000000000000000000000000000000000000000000000 54d5e73b0984ffff400000010000030fdf53c00401000000 54d5e74a0984fff0000000010018000fdf52c018d9242129 000000000000000000000000000000000000000000000000 54d5e7bd0984ffff400000010000000fdf52c00401000000 54d5e7cd0984fff0000000010018000fdf54c01820edf04d 000000000000000000000000000000000000000000000000 54d5e8410984ffff400000010000010fdf54c00401000000 54d5e88b0984fff0000000010018000fdf51c018a185da05 000000000000000000000000000000000000000000000000 54d5e9000984ffff400000010000020fdf51c00401000000 54d5e90f0984fff0000000010018000fdf53c01884e40266 000000000000000000000000000000000000000000000000 54d5e9830984ffff400000010000030fdf53c00401000000 54d5e9930984fff0000000010018000fdf52c0186e5125c7 000000000000000000000000000000000000000000000000 54d5ea070984ffff400000010000000fdf52c00401000000 54d5ea160984fff0000000010018000fdf54c0189798f4a3 000000000000000000000000000000000000000000000000 54d5ea890984ffff400000010000010fdf54c00401000000 54d5ead20984fff0000000010018000fdf51c018cc56d95f 000000000000000000000000000000000000000000000000 54d5eb450984ffff400000010000020fdf51c00401000000 54d5eb550984fff0000000010018000fdf53c018e937013c 000000000000000000000000000000000000000000000000 54d5ebc90984ffff400000010000030fdf53c00401000000 54d5ebd90984fff0000000010018000fdf52c0180382269d 000000000000000000000000000000000000000000000000 54d5ec4c0984ffff400000010000000fdf52c00401000000 54d5ec5b0984fff0000000010018000fdf54c018fa4bf7f9 000000000000000000000000000000000000000000000000 54d5ecce0984ffff400000010000010fdf54c00401000000 54d5ed170984fff0000000010018000fdf51c018443d4b82 000000000000000000000000000000000000000000000000 54d5ed8a0984ffff400000010000020fdf51c00401000000 54d5ed9a0984fff0000000010018000fdf53c018615c93e1 000000000000000000000000000000000000000000000000 54d5ee0e0984ffff400000010000030fdf53c00401000000 54d5ee1d0984fff0000000010018000fdf52c0188be9b440 000000000000000000000000000000000000000000000000 54d5ee900984ffff400000010000000fdf52c00401000000 54d5ee9f0984fff0000000010018000fdf54c01872206524 000000000000000000000000000000000000000000000000 54d5ef140984ffff400000010000010fdf54c00401000000 54d5ef5f0984fff0000000010018000fdf51c01829ee48d8 000000000000000000000000000000000000000000000000 54d5efd20984ffff400000010000020fdf51c00401000000 54d5efe20984fff0000000010018000fdf53c0180c8f90bb 000000000000000000000000000000000000000000000000 54d5f0560984ffff400000010000030fdf53c00401000000 54d5f0650984fff0000000010018000fdf52c018e63ab71a 000000000000000000000000000000000000000000000000 54d5f0d80984ffff400000010000000fdf52c00401000000 54d5f0e70984fff0000000010018000fdf54c0181ff3667e 000000000000000000000000000000000000000000000000 54d5f15b0984ffff400000010000010fdf54c00401000000 54d5f1a40984fff0000000010018000fdf51c0189e9b4c36 000000000000000000000000000000000000000000000000 54d5f2170984ffff400000010000020fdf51c00401000000 54d5f2270984fff0000000010018000fdf53c018bbfa9455 000000000000000000000000000000000000000000000000 54d5f29b0984ffff400000010000030fdf53c00401000000 54d5f2aa0984fff0000000010018000fdf52c018514fb3f4 000000000000000000000000000000000000000000000000 54d5f31d0984ffff400000010000000fdf52c00401000000 54d5f32d0984fff0000000010018000fdf54c018a8866290 000000000000000000000000000000000000000000000000 54d5f3a10984ffff400000010000010fdf54c00401000000 54d5f3ed0984fff0000000010018000fdf51c018f3484f6c 000000000000000000000000000000000000000000000000 54d5f4610984ffff400000010000020fdf51c00401000000 54d5f4700984fff0000000010018000fdf53c018d629970f 000000000000000000000000000000000000000000000000 54d5f4e30984ffff400000010000030fdf53c00401000000 54d5f4f20984fff0000000010018000fdf52c0183c9cb0ae 000000000000000000000000000000000000000000000000 54d5f5650984ffff400000010000000fdf52c00401000000 54d5f5740984fff0000000010018000fdf54c018c55561ca 000000000000000000000000000000000000000000000000 54d5f5e70984ffff400000010000010fdf54c00401000000 54d5f6300984fff0000000010018000fdf51c018b1763531 000000000000000000000000000000000000000000000000 54d5f6a30984ffff400000010000020fdf51c00401000000 54d5f6b20984fff0000000010018000fdf53c0189417ed52 000000000000000000000000000000000000000000000000 54d5f7250984ffff400000010000030fdf53c00401000000 54d5f7340984fff0000000010018000fdf52c0187ea2caf3 000000000000000000000000000000000000000000000000 54d5f7a80984ffff400000010000000fdf52c00401000000 54d5f7b70984fff0000000010018000fdf54c018876b1b97 000000000000000000000000000000000000000000000000 54d5f82a0984ffff400000010000010fdf54c00401000000 54d5f87c0984fff0000000010018000fdf51c018dca5366b 000000000000000000000000000000000000000000000000 54d5f8f00984ffff400000010000020fdf51c00401000000 54d5f8ff0984fff0000000010018000fdf53c018f9c4ee08 000000000000000000000000000000000000000000000000 54d5f9720984ffff400000010000030fdf53c00401000000 54d5f9810984fff0000000010018000fdf52c0181371c9a9 000000000000000000000000000000000000000000000000 54d5f9f40984ffff400000010000000fdf52c00401000000 54d5fa030984fff0000000010018000fdf54c018eab818cd 000000000000000000000000000000000000000000000000 54d5fa760984ffff400000010000010fdf54c00401000000 54d5fac00984fff0000000010018000fdf51c0186bd03285 000000000000000000000000000000000000000000000000 54d5fb340984ffff400000010000020fdf51c00401000000 54d5fb430984fff0000000010018000fdf53c0184eb1eae6 000000000000000000000000000000000000000000000000 54d5fbb60984ffff400000010000030fdf53c00401000000 54d5fbc50984fff0000000010018000fdf52c018a404cd47 000000000000000000000000000000000000000000000000 54d5fc380984ffff400000010000000fdf52c00401000000 54d5fc470984fff0000000010018000fdf54c0185dcd1c23 000000000000000000000000000000000000000000000000 54d5fcba0984ffff400000010000010fdf54c00401000000 54d5fd040984fff0000000010018000fdf51c018060331df 000000000000000000000000000000000000000000000000 54d5fd770984ffff400000010000020fdf51c00401000000 54d5fd860984fff0000000010018000fdf53c0182362e9bc 000000000000000000000000000000000000000000000000 54d5fdf90984ffff400000010000030fdf53c00401000000 54d5fe080984fff0000000010018000fdf52c018c9d7ce1d 000000000000000000000000000000000000000000000000 54d5fe7b0984ffff400000010000000fdf52c00401000000 54d5fe8a0984fff0000000010018000fdf54c018301e1f79 000000000000000000000000000000000000000000000000 54d5fefd0984ffff400000010000010fdf54c00401000000 54d5ff460984fff0000000010018000fdf51c018efacc63f 000000000000000000000000000000000000000000000000 54d5ffb90984ffff400000010000020fdf51c00401000000 54d5ffc80984fff0000000010018000fdf53c018cacd1e5c 000000000000000000000000000000000000000000000000 54d6003b0984ffff400000010000030fdf53c00401000000 54d6004b0984fff0000000010018000fdf52c018207839fd 000000000000000000000000000000000000000000000000 54d600bf0984ffff400000010000000fdf52c00401000000 54d600ce0984fff0000000010018000fdf54c018d9b1e899 000000000000000000000000000000000000000000000000 54d601420984ffff400000010000010fdf54c00401000000 54d6018b0984fff0000000010018000fdf51c018827fc565 000000000000000000000000000000000000000000000000 54d601ff0984ffff400000010000020fdf51c00401000000 54d6020e0984fff0000000010018000fdf53c018a71e1d06 000000000000000000000000000000000000000000000000 54d602810984ffff400000010000030fdf53c00401000000 54d602900984fff0000000010018000fdf52c0184dab3aa7 000000000000000000000000000000000000000000000000 54d603040984ffff400000010000000fdf52c00401000000 54d603140984fff0000000010018000fdf54c018b462ebc3 000000000000000000000000000000000000000000000000 54d603880984ffff400000010000010fdf54c00401000000 54d603c10984fff0000000010018000fdf51c018350ac18b 000000000000000000000000000000000000000000000000 54d604340984ffff400000010000020fdf51c00401000000 54d604440984fff0000000010018000fdf53c018106b19e8 000000000000000000000000000000000000000000000000 54d604b80984ffff400000010000030fdf53c00401000000 54d604c70984fff0000000010018000fdf52c018fade3e49 000000000000000000000000000000000000000000000000 54d6053a0984ffff400000010000000fdf52c00401000000 54d605490984fff0000000010018000fdf54c0180317ef2d 000000000000000000000000000000000000000000000000 54d605bc0984ffff400000010000010fdf54c00401000000 54d605f40984fff0000000010018000fdf51c01858d9c2d1 000000000000000000000000000000000000000000000000 54d606690984ffff400000010000020fdf51c00401000000 54d606780984fff0000000010018000fdf53c0187db81ab2 000000000000000000000000000000000000000000000000 54d606ec0984ffff400000010000030fdf53c00401000000 54d606fb0984fff0000000010018000fdf52c018970d3d13 000000000000000000000000000000000000000000000000 54d6076e0984ffff400000010000000fdf52c00401000000 54d6077d0984fff0000000010018000fdf54c0186ec4ec77 000000000000000000000000000000000000000000000000 54d607f00984ffff400000010000010fdf54c00401000000 54d608280984fff0000000010018000fdf51c0181ae7b88c 000000000000000000000000000000000000000000000000 54d6089c0984ffff400000010000020fdf51c00401000000 54d608ac0984fff0000000010018000fdf53c0183f8660ef 000000000000000000000000000000000000000000000000 54d6091f0984ffff400000010000030fdf53c00401000000 54d6092e0984fff0000000010018000fdf52c018d533474e 000000000000000000000000000000000000000000000000 54d609a10984ffff400000010000000fdf52c00401000000 54d609b00984fff0000000010018000fdf54c0182cfa962a 000000000000000000000000000000000000000000000000 54d60a230984ffff400000010000010fdf54c00401000000 54d60a5c0984fff0000000010018000fdf51c0187734bbd6 000000000000000000000000000000000000000000000000 54d60acf0984ffff400000010000020fdf51c00401000000 54d60ade0984fff0000000010018000fdf53c018525563b5 000000000000000000000000000000000000000000000000 54d60b510984ffff400000010000030fdf53c00401000000 54d60b600984fff0000000010018000fdf52c018b8e04414 000000000000000000000000000000000000000000000000 54d60bd30984ffff400000010000000fdf52c00401000000 54d60be20984fff0000000010018000fdf54c01841299570 000000000000000000000000000000000000000000000000 54d60c550984ffff400000010000010fdf54c00401000000 54d60c8d0984fff0000000010018000fdf51c018c041bf38 000000000000000000000000000000000000000000000000 54d60d010984ffff400000010000020fdf51c00401000000 54d60d100984fff0000000010018000fdf53c018e520675b 000000000000000000000000000000000000000000000000 54d60d830984ffff400000010000030fdf53c00401000000 54d60d920984fff0000000010018000fdf52c0180f9540fa 000000000000000000000000000000000000000000000000 54d60e050984ffff400000010000000fdf52c00401000000 54d60e140984fff0000000010018000fdf54c018f65c919e 000000000000000000000000000000000000000000000000 54d60e880984ffff400000010000010fdf54c00401000000 54d60ec00984fff0000000010018000fdf51c018ad92bc62 000000000000000000000000000000000000000000000000 54d60f340984ffff400000010000020fdf51c00401000000 54d60f430984fff0000000010018000fdf53c01888f36401 000000000000000000000000000000000000000000000000 54d60fb60984ffff400000010000030fdf53c00401000000 54d60fc50984fff0000000010018000fdf52c018624643a0 000000000000000000000000000000000000000000000000 54d610380984ffff400000010000000fdf52c00401000000 54d610470984fff0000000010018000fdf54c0189b8f92c4 000000000000000000000000000000000000000000000000 54d610ba0984ffff400000010000010fdf54c00401000000 54d610f20984fff0000000010018000fdf51c01853182122 000000000000000000000000000000000000000000000000 54d611660984ffff400000010000020fdf51c00401000000 54d611750984fff0000000010018000fdf53c0187679f941 000000000000000000000000000000000000000000000000 54d611e80984ffff400000010000030fdf53c00401000000 54d611f70984fff0000000010018000fdf52c0189cccdee0 000000000000000000000000000000000000000000000000 54d6126a0984ffff400000010000000fdf52c00401000000 54d612790984fff0000000010018000fdf54c01865050f84 000000000000000000000000000000000000000000000000 54d612ec0984ffff400000010000010fdf54c00401000000 54d613240984fff0000000010018000fdf51c0183ecb2278 000000000000000000000000000000000000000000000000 54d613980984ffff400000010000020fdf51c00401000000 54d613a70984fff0000000010018000fdf53c0181baafa1b 000000000000000000000000000000000000000000000000 54d6141a0984ffff400000010000030fdf53c00401000000 54d614290984fff0000000010018000fdf52c018f11fddba 000000000000000000000000000000000000000000000000 54d6149d0984ffff400000010000000fdf52c00401000000 54d614ac0984fff0000000010018000fdf54c01808d60cde 000000000000000000000000000000000000000000000000 54d6151f0984ffff400000010000010fdf54c00401000000 54d615570984fff0000000010018000fdf51c01889be2696 000000000000000000000000000000000000000000000000 54d615cb0984ffff400000010000020fdf51c00401000000 54d615da0984fff0000000010018000fdf53c018acdffef5 000000000000000000000000000000000000000000000000 54d6164d0984ffff400000010000030fdf53c00401000000 54d6165c0984fff0000000010018000fdf52c018466ad954 000000000000000000000000000000000000000000000000 54d616cf0984ffff400000010000000fdf52c00401000000 54d616de0984fff0000000010018000fdf54c018bfa30830 000000000000000000000000000000000000000000000000 54d617510984ffff400000010000010fdf54c00401000000 54d617890984fff0000000010018000fdf51c018e46d25cc 000000000000000000000000000000000000000000000000 54d617fd0984ffff400000010000020fdf51c00401000000 54d6180c0984fff0000000010018000fdf53c018c10cfdaf 000000000000000000000000000000000000000000000000 54d6187f0984ffff400000010000030fdf53c00401000000 54d6188e0984fff0000000010018000fdf52c0182bb9da0e 000000000000000000000000000000000000000000000000 54d619010984ffff400000010000000fdf52c00401000000 54d619100984fff0000000010018000fdf54c018d2700b6a 000000000000000000000000000000000000000000000000 54d619830984ffff400000010000010fdf54c00401000000 54d619bb0984fff0000000010018000fdf51c018a6535f91 000000000000000000000000000000000000000000000000 54d61a2e0984ffff400000010000020fdf51c00401000000 54d61a3d0984fff0000000010018000fdf53c018833287f2 000000000000000000000000000000000000000000000000 54d61ab00984ffff400000010000030fdf53c00401000000 54d61abf0984fff0000000010018000fdf52c0186987a053 000000000000000000000000000000000000000000000000 54d61b320984ffff400000010000000fdf52c00401000000 54d61b410984fff0000000010018000fdf54c018904e7137 000000000000000000000000000000000000000000000000 54d61bb40984ffff400000010000010fdf54c00401000000 54d61bec0984fff0000000010018000fdf51c018cb805ccb 000000000000000000000000000000000000000000000000 54d61c600984ffff400000010000020fdf51c00401000000 54d61c6f0984fff0000000010018000fdf53c018eee184a8 000000000000000000000000000000000000000000000000 54d61ce20984ffff400000010000030fdf53c00401000000 54d61cf20984fff0000000010018000fdf52c0180454a309 000000000000000000000000000000000000000000000000 54d61d660984ffff400000010000000fdf52c00401000000 54d61d750984fff0000000010018000fdf54c018fd9d726d 000000000000000000000000000000000000000000000000 54d61de80984ffff400000010000010fdf54c00401000000 54d61e220984fff0000000010018000fdf51c0187cf55825 000000000000000000000000000000000000000000000000 54d61e960984ffff400000010000020fdf51c00401000000 54d61ea50984fff0000000010018000fdf53c01859948046 000000000000000000000000000000000000000000000000 54d61f180984ffff400000010000030fdf53c00401000000 54d61f270984fff0000000010018000fdf52c018b321a7e7 000000000000000000000000000000000000000000000000 54d61f9b0984ffff400000010000000fdf52c00401000000 54d61faa0984fff0000000010018000fdf54c0184ae87683 000000000000000000000000000000000000000000000000 54d6201e0984ffff400000010000010fdf54c00401000000 54d620560984fff0000000010018000fdf51c01811265b7f 000000000000000000000000000000000000000000000000 54d620ca0984ffff400000010000020fdf51c00401000000 54d620d90984fff0000000010018000fdf53c0183447831c 000000000000000000000000000000000000000000000000 54d621480984ffff400000010000030fdf53000000000000 54d6214d0984ffff400000010000000fdf53c00401000000 54d621590984ffff400000010000010fdf53000002010000 54d6215d0984fff0000000010018000fdf52c0189547f8dd 000000000000000000000000000000000000000000000000 54d6216b0984ffff400000010000020fdf53000000205282 54d6217d0984ffff400000010000030fdf53000000100000 54d621d10984ffff400000010000000fdf52c00401000000 54d621e00984fff0000000010018000fdf54c01858fe3bf9 000000000000000000000000000000000000000000000000 54d6228a0984fff0000000010018000fdf548000532f5d67 000000000000000000000000000000000000000000000000 54d624790984fff0000000010018000fdf548000d6f6cbba 000000000000000000000000000000000000000000000000 54d624eb0984fff0000000010018000fdf548000189a0107 000000000000000000000000000000000000000000000000 54d6278e0984fff0000000010018000fdf54c018ce948239 000000000000000000000000000000000000000000000000 54d628030984ffff400000010000010fdf54c00401000000 54d6284f0984fff0000000010018000fdf51c018955aafc5 000000000000000000000000000000000000000000000000 54d628c20984ffff400000010000020fdf51c00401000000 54d628d20984fff0000000010018000fdf53c018b03b77a6 000000000000000000000000000000000000000000000000 54d629470984ffff400000010000030fdf53c00401000000 54d629560984fff0000000010018000fdf52c0185a8e5007 000000000000000000000000000000000000000000000000 54d629cb0984ffff400000010000000fdf52c00401000000 54d629da0984fff0000000010018000fdf54c018a3478163 54d629de0984ffff400000010000010fdf53000000000000 000000000000000000000000000000000000000000000000 54d629f00984ffff400000010000020fdf53000000010000 54d62a010984ffff400000010000030fdf53000000000000 54d62a130984ffff400000010000000fdf53000000000000 54d62a4e0984ffff400000010000010fdf54c00401000000 54d62a9e0984fff0000000010018000fdf51c018b44512eb 000000000000000000000000000000000000000000000000 54d62b120984ffff400000010000020fdf51c00401000000 54d62b220984fff0000000010018000fdf53c0189124ca88 000000000000000000000000000000000000000000000000 54d62b950984ffff400000010000030fdf53c00401000000 54d62ba40984fff0000000010018000fdf52c0181642ee73 000000000000000000000000000000000000000000000000 54d62c180984ffff400000010000000fdf52c00401000000 54d62c270984fff0000000010018000fdf54c018ef8b3f17 000000000000000000000000000000000000000000000000 54d62c9b0984fff0000000010018000fdf548000e45a5989 000000000000000000000000000000000000000000000000 54d62d0e0984fff0000000010018000fdf5480006183cf54 000000000000000000000000000000000000000000000000 54d62d7f0984fff0000000010018000fdf548000afef05e9 000000000000000000000000000000000000000000000000 54d62fdf0984fff0000000010018000fdf54c01879e186d7 000000000000000000000000000000000000000000000000 54d630530984ffff400000010000010fdf54c00401000000 54d630a20984fff0000000010018000fdf51c0180dc2d22c 000000000000000000000000000000000000000000000000 54d6311b0984ffff400000010000020fdf51c00401000000 54d6312b0984fff0000000010018000fdf53c01828a30a4f 000000000000000000000000000000000000000000000000 54d6319e0984ffff400000010000030fdf53c00401000000 54d631ae0984fff0000000010018000fdf52c018c2162dee 000000000000000000000000000000000000000000000000 54d632220984ffff400000010000000fdf52c00401000000 54d632320984fff0000000010018000fdf54c0183bdffc8a 000000000000000000000000000000000000000000000000 54d632af0984ffff400000010000010fdf54c00401000000 54d632ee0984fff0000000010018000fdf51c0186011d176 000000000000000000000000000000000000000000000000 54d6333c0984ffff400000010000020fdf53010000000000 54d6334d0984ffff400000010000030fdf53010000000100 54d6335f0984ffff400000010000000fdf53010000000000 54d633620984ffff400000010000010fdf51c00401000000 54d633710984ffff400000010000020fdf53010000000000 54d633730984fff0000000010018000fdf53c018d31ab0d5 000000000000000000000000000000000000000000000000 54d633830984ffff400000010000030fdf53010000000000 54d633950984ffff400000010000000fdf53010000001000 54d633e60984ffff400000010000010fdf53c00401000000 54d633f50984fff0000000010018000fdf52c018c56fcffa 000000000000000000000000000000000000000000000000 54d634710984ffff400000010000020fdf52c00401000000 54d634800984fff0000000010018000fdf54c018aacca75e 000000000000000000000000000000000000000000000000 54d634f50984fff0000000010018000fdf54800037777800 000000000000000000000000000000000000000000000000 54d6356f0984fff0000000010018000fdf548000b2aeeedd 000000000000000000000000000000000000000000000000 54d635e00984fff0000000010018000fdf548000877b9efa 000000000000000000000000000000000000000000000000 54d638dc0984fff0000000010018000fdf54c01851751dc4 000000000000000000000000000000000000000000000000 54d639550984ffff400000010000030fdf54c00401000000 54d639b00984fff0000000010018000fdf51c018f1028aa2 000000000000000000000000000000000000000000000000 54d63a2c0984ffff400000010000000fdf51c00401000000 54d63a3b0984fff0000000010018000fdf53c0184209eb01 000000000000000000000000000000000000000000000000 54d63ab00984ffff400000010000010fdf53c00401000000 54d63abf0984fff0000000010018000fdf52c0183ed67560 000000000000000000000000000000000000000000000000 54d63b3c0984ffff400000010000020fdf52c00401000000 54d63b4b0984fff0000000010018000fdf54c01874dae1f8 000000000000000000000000000000000000000000000000 54d63bbf0984ffff400000010000030fdf54c00401000000 54d63c060984fff0000000010018000fdf51c018d4ad769e 000000000000000000000000000000000000000000000000 54d63c820984ffff400000010000000fdf51c00401000000 54d63c910984fff0000000010018000fdf53c01867a6173d 000000000000000000000000000000000000000000000000 54d63d050984ffff400000010000010fdf53c00401000000 54d63d140984fff0000000010018000fdf52c0181b79895c 000000000000000000000000000000000000000000000000 54d63d910984ffff400000010000020fdf52c00401000000 54d63da00984fff0000000010018000fdf54c0181909e2a2 000000000000000000000000000000000000000000000000 54d63e140984ffff400000010000030fdf54c00401000000 54d63e620984fff0000000010018000fdf51c018b97e75c4 000000000000000000000000000000000000000000000000 54d63ee00984ffff400000010000000fdf51c00401000000 54d63eef0984fff0000000010018000fdf53c0180a751467 000000000000000000000000000000000000000000000000 54d63f6a0984ffff400000010000010fdf53c00401000000 54d63f7a0984fff0000000010018000fdf52c01876aa8a06 000000000000000000000000000000000000000000000000 54d63fee0984ffff400000010000020fdf52c00401000000 54d63ffd0984fff0000000010018000fdf54c018ae7ce64c 000000000000000000000000000000000000000000000000 54d640790984ffff400000010000030fdf54c00401000000 54d640b80984fff0000000010018000fdf51c0180e0b712a 000000000000000000000000000000000000000000000000 54d6412c0984ffff400000010000000fdf51c00401000000 54d6413b0984fff0000000010018000fdf53c018bd001089 000000000000000000000000000000000000000000000000 54d641b70984ffff400000010000010fdf53c00401000000 54d641c70984fff0000000010018000fdf52c018c1df8ee8 000000000000000000000000000000000000000000000000 54d6423a0984ffff400000010000020fdf52c00401000000 54d642490984fff0000000010018000fdf54c018c3afe516 000000000000000000000000000000000000000000000000 54d642c60984ffff400000010000030fdf54c00401000000 54d642ef0984fff0000000010018000fdf50023062afc9bd 000000000000000000000000000000000000000000000000 54d643660984fff0000000010018000fdf500234236dd7c7 54d643690984fff0000000010018010fdf51c0181bd4cb1b 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d643dd0984ffff400000010000000fdf51c00401000000 54d643ec0984fff0000000010018000fdf53c0189b664fb3 000000000000000000000000000000000000000000000000 54d643fb0984ffff400000010000010fdf51000001000000 54d6440d0984ffff400000010000020fdf51000040000000 54d6441e0984ffff400000010000030fdf51000010000000 54d644300984ffff400000010000000fdf51000001000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6445f0984ffff400000010000010fdf53c00401000000 54d6446f0984fff0000000010018000fdf52c018a587ab8f 000000000000000000000000000000000000000000000000 54d644b00900ffff4a000010000000400200000000000000 54d644b10800ffff01000000020000000300000004000000 54d644b20800ffff05000000060000000700000008000000 54d644b30800ffff090000000a0000000b0000000c000000 54d644b40880fff00d0000000e0000000f000000f94436b2 54d644b60900ffff4a000010000000400200014010000000 54d644b70800ffff11000000120000001300000014000000 54d644b80800ffff15000000160000001700000018000000 54d644b90800ffff190000001a0000001b0000001c000000 54d644bb0880fff01d0000001e0000001f0000007f8e4b2a 54d644bc0900ffff4a000010000000400200020020000000 54d644bd0800ffff21000000220000002300000024000000 54d644bf0800ffff25000000260000002700000028000000 54d644c10800ffff290000002a0000002b0000002c000000 54d644c30880fff02d0000002e0000002f00000021550efb 54d644c40900ffff4a000010000000400200034030000000 54d644c50800ffff31000000320000003300000034000000 54d644c70800ffff35000000360000003700000038000000 54d644c90800ffff390000003a0000003b0000003c000000 54d644cb0880fff03d0000003e0000003f000000a79f7363 54d644ef0984fff0000000010018000fdf528000c385ce4b 000000000000000000000000000000000000000000000000 54d64dd60984fff0000000010018000fdf52c018158b4d75 000000000000000000000000000000000000000000000000 54d64e470984fff0000000010018000fdf5282009c381dd9 000000000000000000000000000000000000000000000000 54d652dd0984fff0000000010018000fdf52c018c854a8d5 000000000000000000000000000000000000000000000000 54d653510984ffff400000010000020fdf52c00401000000 54d653600984fff0000000010018000fdf54c018319d79b1 000000000000000000000000000000000000000000000000 54d653dd0984ffff400000010000030fdf54c00401000000 54d654490984fff0000000010018000fdf51c018b0f553f9 000000000000000000000000000000000000000000000000 54d654bc0984ffff400000010000000fdf51c00401000000 54d654cb0984fff0000000010018000fdf53c01895948b9a 000000000000000000000000000000000000000000000000 54d654e00984fff0000000010018010fdf50023007e29be2 000000000000000000000000000000000000000000000000 54d6553e0984ffff400000010000010fdf53c00401000000 54d6554e0984fff0000000010018000fdf52c018b14d6686 54d655500984fff0000000010018010fdf500234d04a3c58 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d655c20984ffff400000010000020fdf52c00401000000 54d655d10984fff0000000010018000fdf54c01836e49ba5 000000000000000000000000000000000000000000000000 54d6564d0984ffff400000010000030fdf54c00401000000 54d656630984ffff400000010000000fdf53030000000000 54d6569c0984fff0000000010018000fdf51c018ce957fbe 000000000000000000000000000000000000000000000000 54d657100984ffff400000010000010fdf51c00401000000 54d6571f0984fff0000000010018000fdf53c018ebf4a7dd 000000000000000000000000000000000000000000000000 54d6579b0984ffff400000010000020fdf53c00401000000 54d657ab0984fff0000000010018000fdf52c018e8ee779c 000000000000000000000000000000000000000000000000 54d6581e0984ffff400000010000030fdf52c00401000000 54d6582e0984fff0000000010018000fdf54c0181127a6f8 000000000000000000000000000000000000000000000000 54d658af0984fff0000000010018000fdf548600418e7f90 000000000000000000000000000000000000000000000000 54d659290984fff0000000010018000fdf54860019880ced 000000000000000000000000000000000000000000000000 54d659a00984fff0000000010018000fdf5486009c519a30 000000000000000000000000000000000000000000000000 54d65a110984fff0000000010018000fdf548600523d508d 000000000000000000000000000000000000000000000000 54d65b170984fff0000000010018000fdf54c018029489e5 000000000000000000000000000000000000000000000000 54d65b8b0984ffff400000010000000fdf54c00401000000 54d65c020984fff0000000010018000fdf51c018595aa419 000000000000000000000000000000000000000000000000 54d65c7e0984ffff400000010000010fdf51c00401000000 54d65c8d0984fff0000000010018000fdf53c0187c3b7c7a 000000000000000000000000000000000000000000000000 54d65d070984ffff400000010000020fdf53c00401000000 54d65d160984fff0000000010018000fdf52c018968e5bdb 000000000000000000000000000000000000000000000000 54d65d890984ffff400000010000030fdf52c00401000000 54d65d980984fff0000000010018000fdf54c0186f478abf 000000000000000000000000000000000000000000000000 54d65dac0984ffff400000010000000fdf53040000000000 54d65dbe0984ffff400000010000010fdf53040000000000 54d65e140984ffff400000010000020fdf54c00401000000 54d65e600984fff0000000010018000fdf51c018a59afc97 000000000000000000000000000000000000000000000000 54d65ed30984ffff400000010000030fdf51c00401000000 54d65ee20984fff0000000010018000fdf53c01816919d34 000000000000000000000000000000000000000000000000 54d65f560984ffff400000010000000fdf53c00401000000 54d65f650984fff0000000010018000fdf52c0186a4e0355 000000000000000000000000000000000000000000000000 54d65fd80984ffff400000010000010fdf52c00401000000 54d65fe80984fff0000000010018000fdf54c018683e68ab 000000000000000000000000000000000000000000000000 54d660670984fff0000000010018000fdf5487003213f6ba 000000000000000000000000000000000000000000000000 54d660dd0984fff0000000010018000fdf548700b7ca6067 000000000000000000000000000000000000000000000000 54d661de0984fff0000000010018000fdf54c0187b8d47b6 000000000000000000000000000000000000000000000000 54d662520984ffff400000010000020fdf54c00401000000 54d662d30984fff0000000010018000fdf51c018dbfad0d0 000000000000000000000000000000000000000000000000 54d663470984ffff400000010000030fdf51c00401000000 54d663570984fff0000000010018000fdf53c0182acfcb2e 000000000000000000000000000000000000000000000000 54d663d30984ffff400000010000000fdf53c00401000000 000000000000000000000000000000000000000000000000 d38e11431181ffff4a000001020000040018001c01000000 000000000000000000000000000000000000000000000000 d38e11b11181ffff4a000001020000040018001800100000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d665351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d665c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d666451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d666d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6679e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d668291184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d668b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d669421184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66a141184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66aa01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66b2c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66bb01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66c721184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66cf61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66d7a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66dfe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66ebd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66f3f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d66fc11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6704c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6710f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d671931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6721f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d672a21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d673761184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d673f81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6747a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d675051184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d675bf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6764a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d676ce1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6775b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d678151184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d678971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d679221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d679a61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67a5b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67add1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67b601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67bec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67ca31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67d271184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67dac1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67e2f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67eeb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67f6f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d67ff31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d680761184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6812e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d681b01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d682341184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d682b81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d683741184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d684001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d684841184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d685071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d685c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d686451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d686c71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d687491184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d687fe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d688801184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6890b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6898e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68a491184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68acc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68b4f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68bd21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68c911184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68d141184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68d971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68e191184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68ee41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68f701184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d68ff41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d690781184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6913a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d691bd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6923f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d692ca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6937d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d694011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d694851184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d695091184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d695c91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d696551184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d696d91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d697651184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6982d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d698b91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6993b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d699be1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69a7e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69b011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69b8c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69c0f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69ccf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69d521184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69dde1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69e621184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69f171184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d69f9b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a01f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a0a31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a1601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a1e21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a2651184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a2f11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a3ac1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a4381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a4bc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a5481184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a60b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a68e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a7131184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a79f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a8511184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a8d31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a9551184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6a9d71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6aa8b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ab111184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ab9d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ac211184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6acdf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ad631184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ade71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ae731184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6af261184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6afb41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b0381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b0bc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b17e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b20b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b28d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b30f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b3c31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b4461184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b4ca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b54d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b6111184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b6951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b7181184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b79b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b84f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b8d21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b95e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6b9e91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6baaf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bb321184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bbb61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bc3b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bcee1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bd711184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bdf31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6be7e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bf3a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6bfbd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c03f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c0c11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c1741184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c2001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c2821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c3041184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c3c41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c4461184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c4d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c5541184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c6091184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c68d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c7101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c7931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c84f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c8d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c9531184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6c9d51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ca901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cb131184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cb951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cc181184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ccd61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cd591184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cddf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ce631184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cf1f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6cfa21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d0251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d0a81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d1611184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d1e51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d3151184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d3a01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d4591184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d4dd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d5601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d5ed1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d6ad1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d72f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d7b21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d8341184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d8e71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d96a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6d9ec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6da6e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6db2e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6dbb01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6dc321184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6dcb41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6dd771184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6ddf91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6de7c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6deff1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6dfb51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6e0371184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6e0c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6e1461184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 d38df2e41181ffff4a000001020000040018000889400000 000000000000000000000000000000000000000000000000 d38df3531181ffff4a00000102000004001800000000e0fe 000000000000000000000000000000000000000000000000 d38df3c11181ffff4a000001020000040018000400000000 000000000000000000000000000000000000000000000000 d38df50b1181ffff4a000001020000040018001899400000 000000000000000000000000000000000000000000000000 d38df57a1181ffff4a00000102000004001800100000e0fe 000000000000000000000000000000000000000000000000 d38df5e81181ffff4a000001020000040018001400000000 000000000000000000000000000000000000000000000000 d38df6f01181ffff4a0000010200000400180028a9400000 000000000000000000000000000000000000000000000000 d38df75e1181ffff4a00000102000004001800200000e0fe 000000000000000000000000000000000000000000000000 d38df7cc1181ffff4a000001020000040018002400000000 000000000000000000000000000000000000000000000000 d38df8c21181ffff4a0000010200000400180038b9400000 000000000000000000000000000000000000000000000000 d38df9311181ffff4a00000102000004001800300000e0fe 000000000000000000000000000000000000000000000000 d38df9a01181ffff4a000001020000040018003400000000 000000000000000000000000000000000000000000000000 d38dfa971181ffff4a0000010200000400180048c9400000 000000000000000000000000000000000000000000000000 d38dfb051181ffff4a00000102000004001800400000e0fe 000000000000000000000000000000000000000000000000 d38dfb721181ffff4a000001020000040018004400000000 000000000000000000000000000000000000000000000000 d38dfc661181ffff4a0000010200000400180058d9400000 000000000000000000000000000000000000000000000000 d38dfcd51181ffff4a00000102000004001800500000e0fe 000000000000000000000000000000000000000000000000 d38dfd431181ffff4a000001020000040018005400000000 000000000000000000000000000000000000000000000000 d38dfe361181ffff4a0000010200000400180068e9400000 000000000000000000000000000000000000000000000000 d38dfea51181ffff4a00000102000004001800600000e0fe 000000000000000000000000000000000000000000000000 d38dff131181ffff4a000001020000040018006400000000 000000000000000000000000000000000000000000000000 d38e000b1181ffff4a00000102000004001800782a400000 000000000000000000000000000000000000000000000000 d38e007a1181ffff4a00000102000004001800700000e0fe 000000000000000000000000000000000000000000000000 d38e00e81181ffff4a000001020000040018007400000000 000000000000000000000000000000000000000000000000 d38e01dc1181ffff4a00000102000004001800084a400000 000000000000000000000000000000000000000000000000 d38e024a1181ffff4a00000102000004001800000000e0fe 000000000000000000000000000000000000000000000000 d38e02b71181ffff4a000001020000040018000400000000 000000000000000000000000000000000000000000000000 d38e03ad1181ffff4a00000102000004001800185a400000 000000000000000000000000000000000000000000000000 d38e041c1181ffff4a00000102000004001800100000e0fe 000000000000000000000000000000000000000000000000 d38e048a1181ffff4a000001020000040018001400000000 000000000000000000000000000000000000000000000000 d38e057e1181ffff4a00000102000004001800286a400000 000000000000000000000000000000000000000000000000 d38e05ed1181ffff4a00000102000004001800200000e0fe 000000000000000000000000000000000000000000000000 d38e065b1181ffff4a000001020000040018002400000000 000000000000000000000000000000000000000000000000 d38e075a1181ffff4a00000102000004001800387a400000 000000000000000000000000000000000000000000000000 d38e07c91181ffff4a00000102000004001800300000e0fe 000000000000000000000000000000000000000000000000 d38e08371181ffff4a000001020000040018003400000000 000000000000000000000000000000000000000000000000 d38e09331181ffff4a00000102000004001800488a400000 000000000000000000000000000000000000000000000000 d38e09a01181ffff4a00000102000004001800400000e0fe 000000000000000000000000000000000000000000000000 d38e0a0e1181ffff4a000001020000040018004400000000 000000000000000000000000000000000000000000000000 d38e0b041181ffff4a00000102000004001800589a400000 000000000000000000000000000000000000000000000000 d38e0b741181ffff4a00000102000004001800500000e0fe 000000000000000000000000000000000000000000000000 d38e0be21181ffff4a000001020000040018005400000000 000000000000000000000000000000000000000000000000 d38e0cd61181ffff4a0000010200000400180068aa400000 000000000000000000000000000000000000000000000000 d38e0d441181ffff4a00000102000004001800600000e0fe 000000000000000000000000000000000000000000000000 d38e0db21181ffff4a000001020000040018006400000000 000000000000000000000000000000000000000000000000 d38e0ea71181ffff4a0000010200000400180078ba400000 000000000000000000000000000000000000000000000000 d38e0f161181ffff4a00000102000004001800700000e0fe 000000000000000000000000000000000000000000000000 d38e0f841181ffff4a000001020000040018007400000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d55cca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d55da11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d55e251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d55eaa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d55f2c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5601e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d560a11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d561251184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d561a91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5628c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d563101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d563931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d564161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d564e91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5656b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d565ed1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d566701184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5673b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d567be1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d568411184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d568cd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d569ac1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56a2e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56ab11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56b3d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56c241184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56ca71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56d331184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56db61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56e971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56f191184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d56fa41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d570281184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d571091184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d571941184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d572171184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d572a21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d573901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d574131184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5749f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d575221184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d575f91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d576851184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d577081184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d577931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d578691184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d578ec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d579781184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d579fb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57acb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57b4d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57bd11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57c541184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57d281184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57dac1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57e301184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57eb21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d57f811184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d580051184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d580911184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d581141184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d581f51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d582781184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d582fb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5837e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5845d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d584df1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d585631184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d585e51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d586a21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d587261184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d587a91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5882b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d588e81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5896c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d589ef1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58a731184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58b301184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58bb21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58c351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58cb81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58d751184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58df81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58e7a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58efc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d58fbe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d590421184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d590c51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d591471184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d592041184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d592881184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5930c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5938f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5944f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d594d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d595531184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d595d61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d596921184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d597141184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d597971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5981a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d598d61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d599591184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d599dc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59a5e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59b1b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59b9d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59c1f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59ca21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59d601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59de41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59e671184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59ee91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d59fa51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a0271184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a0aa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a12e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a1eb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a26f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a2f21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a3751184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a4311184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a4b41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a5371184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a5ba1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a67c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a7001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a7831184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a8061184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a8c61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a9491184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5a9cb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5aa4d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ab101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ab941184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ac171184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ac991184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ad591184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5addc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ae5e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5aee01184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5af9c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b01f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b0a21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b1241184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b2021184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b2851184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b3081184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b38b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b4471184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b4c91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b54c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b5cf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b6aa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b72d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b7af1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b8311184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b8ee1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b9701184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5b9f21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ba741184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bb331184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bbb71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bc3a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bcbc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bd781184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bdfa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5be7d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5beff1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5bfbb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c03d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c0bf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c1421184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c2001184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c2831184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c3051184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c3871184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c44f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c4d31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c5561184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c5d81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c6941184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c7161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c7981184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c81a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c8d51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c9581184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5c9db1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ca5e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cb1e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cba11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cc241184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cca81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cd651184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cde81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ce6b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ceed1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5cfab1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d02f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d0b21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d1351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d1f31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d2761184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d2f81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d37a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d4361184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d4b81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d53b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d5bd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d67a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d6fd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d77f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d8011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d8bc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d93f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5d9c11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5da431184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5daff1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5db821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5dc041184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5dc861184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5dd421184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ddc41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5de461184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5dec81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5df841184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e0061184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e0891184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e10b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e1ca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e24d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e2cf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e3511184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e40d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e48f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e5111184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e5931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e64f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e6d21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e7541184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e7d71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e8951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e9191184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5e99d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ea201184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5eadc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5eb5f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ebe31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ec651184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ed211184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5eda41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ee271184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5eea91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ef691184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5efec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f06f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f0f11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f1ae1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f2311184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f2b41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f3371184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f3f71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f47a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f4fc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f57e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f63a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f6bc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f73e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f7c11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f8861184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f9091184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5f98b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fa0d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5faca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fb4d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fbcf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fc511184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fd0e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fd901184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fe121184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5fe941184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ff501184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d5ffd21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d600551184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d600d81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d601951184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d602181184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6029a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6031e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d603cb1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6044e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d604d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d605531184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d605fe1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d606821184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d607051184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d607871184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d608321184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d608b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d609381184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d609ba1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60a661184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60ae81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60b6a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60bec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60c971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60d1a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60d9c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60e1e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60eca1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60f4d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d60fcf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d610511184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d610fc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6117f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d612011184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d612831184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6132e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d613b11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d614331184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d614b61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d615611184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d615e41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d616661184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d616e81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d617931184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d618161184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d618981184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6191a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d619c51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61a471184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61ac91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61b4b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61bf61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61c791184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61cfc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61d7f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61e2c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61eaf1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61f311184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d61fb41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d620601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d620e31184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d621671184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d621ea1184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 54d622941184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d624831184ffff4a000001020000040018000000010000 000000000000000000000000000000000000000000000000 54d624f51184ffff4a0000010200000400180000aaaaaaaa 000000000000000000000000000000000000000000000000 54d627981184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d628591184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d628dc1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d629601184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d629e41184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d62aa81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d62b2c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d62bae1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d62c311184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 54d62ca51184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d62d181184ffff4a000001020000040018000000010000 000000000000000000000000000000000000000000000000 54d62d891184ffff4a0000010200000400180000aaaaaaaa 000000000000000000000000000000000000000000000000 54d62fe91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d630ac1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d631351184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d631b81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6323c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d632f81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6337d1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d633ff1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6348a1184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 54d634ff1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d635791184ffff4a000001020000040018000000010000 000000000000000000000000000000000000000000000000 54d635ea1184ffff4a000001020000040018000000100000 000000000000000000000000000000000000000000000000 54d638e61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d639ba1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63a451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63ac91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63b551184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63c101184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63c9b1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63d1e1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63daa1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63e6c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63ef91184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d63f841184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d640071184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d640c21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d641451184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d641d11184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d642531184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d642f61184ffff4a000001020000040018003000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6436d1184ffff4a0000010200000400180034ec42d654 54d643731184ffff4a000001020000040018011800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d643f61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6443e1180ffff20000010020000ff0000000282522000 54d644411180ffff20000010020001ff0000000282522040 54d644441180ffff20000010020002ff0000000282522080 54d644471180ffff20000010020003ff00000002825220c0 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d644791184ffff4a000001020000040018001801000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d644f91184ffff4a000001020000040018000040000000 000000000000000000000000000000000000000000000000 54d64de01184ffff4a000001020000040018001803000000 000000000000000000000000000000000000000000000000 54d64e511184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d652e71184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d6536a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d654531184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d654d51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 54d654e71184ffff4a000001020000040018013000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d655581184ffff4a000001020000040018001800000000 54d6555a1184ffff4a0000010200000400180134dd54d654 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d655db1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d656a61184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d657291184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d657b51184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d658381184ffff4a000001020000040018001807000000 000000000000000000000000000000000000000000000000 54d658b91184ffff4a000001020000040018000001000000 000000000000000000000000000000000000000000000000 54d659331184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d659aa1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d65a1b1184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d65b211184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65c0c1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65c971184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65d201184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65da21184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65e6a1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65eec1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65f6f1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d65ff21184ffff4a000001020000040018001808000000 000000000000000000000000000000000000000000000000 54d660711184ffff4a000001020000040018000000000000 000000000000000000000000000000000000000000000000 54d660e71184ffff4a000001020000040018000020000000 000000000000000000000000000000000000000000000000 54d661e81184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d662dd1184ffff4a000001020000040018001800000000 000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000 54d663611184ffff4a000001020000040018001800000000 ================================================ FILE: lib/deprecated/pcietestbench_dma_oo/testpcie.cpp ================================================ #include #include #include "dmaManager.h" #include "SGListConfigRequest.h" #include "PcieTestBenchIndication.h" #include "PcieTestBenchRequest.h" sem_t test_sem; sem_t tlp_sem; sem_t tlp_ack; int numWords = 64; size_t test_sz = numWords*sizeof(unsigned int); size_t alloc_sz = test_sz; int burstLen = 16; uint32_t scan_int(const char *str) { uint32_t rv; sscanf(str, "%x", &rv); return rv; } enum PktClass {trace, MCont, SCont, MResp, SWReq, SReq, SResp, MWReq, MReq, Misc}; PktClass pktClassification(uint32_t tlpsof, uint32_t tlpeof, uint32_t tlpbe, uint32_t pktformat, uint32_t pkttype, uint32_t portnum) { if (tlpbe == 0) return trace; if (tlpsof == 0) if (portnum == 4) return MCont; else return SCont; if (portnum == 4) if (pkttype == 10) // COMPLETION return MResp; else if (pktformat == 2 or pktformat == 3) return SWReq; else return SReq; else if(portnum == 8) if (pkttype == 10) // COMPLETION return SResp; else if (pktformat == 2 or pktformat == 3) return MWReq; else return MReq; else return Misc; } class PcieTestBenchIndication : public PcieTestBenchIndicationWrapper { public: virtual void finished(uint32_t v){ fprintf(stderr, "finished(%x)\n", v); sem_post(&test_sem); } virtual void started(uint32_t words){ fprintf(stderr, "started(%x)\n", words); } void tlpout(const TsTLPData16 &tlp) { //fprintf(stderr, "Received data= %08x%08x%08x%08x%08x%08x\n", tlp.data0, tlp.data1, tlp.data2, tlp.data3, tlp.data4, tlp.data5); sem_post(&tlp_sem); sem_wait(&tlp_ack); } PcieTestBenchIndication(unsigned int id) : PcieTestBenchIndicationWrapper(id){} }; int main(int argc, const char **argv) { PcieTestBenchRequestProxy *device = new PcieTestBenchRequestProxy(IfcNames_TestBenchRequest); PcieTestBenchIndication *deviceIndication = new PcieTestBenchIndication(IfcNames_TestBenchIndication); DmaManager *dma = platformInit(); int srcAlloc; unsigned int *srcBuffer = 0; std::ifstream infile("../memread_nobuff_oo.tstlp"); srcAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); for (int i = 0; i < numWords; i++) srcBuffer[i] = i; portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); unsigned int ref_srcAlloc = dma->reference(srcAlloc); device->startRead(ref_srcAlloc, numWords, burstLen); #ifndef SANITY int i; while(i++ < 4){ sem_wait(&tlp_sem); uint32_t cnt = 0; while(cnt < 5){ std::string line; std::getline(infile,line); uint32_t tlpsof = scan_int(line.substr(48-39,1).c_str()) & 1; uint32_t tlpeof = scan_int(line.substr(48-38,2).c_str()) >> 7; uint32_t tlpbe = scan_int(line.substr(48-36,4).c_str()); uint32_t tlphit = scan_int(line.substr(48-38,2).c_str()) & 0x7f; uint32_t pktformat = (scan_int(line.substr(48-32,1).c_str()) >> 1) & 3; uint32_t pkttype = (scan_int(line.substr(48-32,2).c_str()) & 0x1f); uint32_t portnum = scan_int(line.substr(48-40,2).c_str()) >> 1; PktClass pc = pktClassification(tlpsof, tlpeof, tlpbe, pktformat, pkttype, portnum); if(pc == MResp || pc == MCont){ TsTLPData16 rv; uint32_t tmp; rv.data0 = scan_int(line.substr(0 ,8).c_str()); rv.data1 = scan_int(line.substr(8 ,8).c_str()); rv.data2 = scan_int(line.substr(16,8).c_str()); rv.data3 = scan_int(line.substr(24,8).c_str()); rv.data4 = scan_int(line.substr(32,8).c_str()); rv.data5 = scan_int(line.substr(40,8).c_str()); //fprintf(stdout, "%08x%08x%08x%08x%08x%08x\n", rv.data0, rv.data1, rv.data2, rv.data3, rv.data4, rv.data5); //fprintf(stdout, "%s\n", line.c_str()); device->tlpin(rv); cnt++; } } sem_post(&tlp_ack); } #endif sem_wait(&test_sem); } ================================================ FILE: lib/matmul/bar.m ================================================ source("foo.m"); om3 = m1*m2; max_error_m3 = 0.0; max_error_tm3 = 0.0; max_error_om3 = 0.0; #calculate a few dot products along the diagonal #see if the dot products agree with m3 and tm3 for i = 1:size(m1)(1) printf("dp: %d\n", i); dp = m1(i,:)*m2(:,i); max_error_m3 = max(abs(m3(i,i)-dp),max_error_m3); max_error_tm3 = max(abs(tm3(i,i)-dp),max_error_tm3); max_error_om3 = max(abs(om3(i,i)-dp),max_error_om3); endfor max_error_m3 max_error_tm3 max_error_om3 ================================================ FILE: lib/matmul/bsv/DotProdServer.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import MIMO::*; import DefaultValue::*; import SpecialFIFOs::*; import Vector::*; import BRAM::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import ConnectalMemUtils::*; import FloatingPoint::*; import Pipe::*; import Arith::*; import FloatOps::*; import Timer::*; import RbmTypes::*; import Assert::*; import Connectable::*; import Clocks::*; import Gearbox::*; import XilinxCells::*; import HostInterface::*; interface SharedDotProdDebug#(numeric type k); interface PipeOut#(Bit#(32)) macCount; endinterface interface SharedDotProdServer#(numeric type k); interface Put#(MmToken) aInput; interface Put#(MmToken) bInput; interface Vector#(k, PipeOut#(MmToken)) pipes; interface SharedDotProdDebug#(k) debug; endinterface typedef struct { `ifdef TAGGED_TOKENS UInt#(32) row; UInt#(32) col; `endif Float v; Bool first; Bool last; } MmToken deriving (Eq,Bits); typedef 8 UB_MulLat; // upper bound on MUL latency? typedef 8 UB_AddLat; // upper bound on ADD latency? (* synthesize *) module mkSharedInterleavedDotProdServer#(UInt#(TLog#(TMul#(J,K))) label)(SharedDotProdServer#(K)); let rv <- mkSharedInterleavedDotProdServerConfig(label); return rv; endmodule module mkSharedInterleavedDotProdServerConfig#(UInt#(TLog#(TMul#(J,K))) label)(SharedDotProdServer#(k)) provisos(Div#(UB_AddLat,k,gatherSz)); let ub_MulLat = valueOf(UB_MulLat); let ub_AddLat = valueOf(UB_AddLat); let kk = valueOf(k); Bool verbose = False; //label == 0; Reg#(UInt#(20)) countReg <- mkReg(0); FloatAlu mul <- mkFloatMultiplier(defaultValue); FloatAlu adder <- mkFloatAdder(defaultValue); FIFOF#(Float) adder_buffer <- mkSizedFIFOF(valueOf(TMul#(k,gatherSz))); `ifdef TAGGED_TOKENS FIFO#(Tuple2#(UInt#(32),UInt#(32))) tag_fifo <- mkSizedFIFO(ub_MulLat); Vector#(k,Reg#(Tuple2#(UInt#(32),UInt#(32)))) tag_regs <- replicateM(mkRegU); `endif Reg#(Bit#(32)) cycles <- mkReg(0); rule countCycles; cycles <= cycles + 1; endrule FIFOF#(MmToken) afifo <- mkFIFOF(); PipeOut#(MmToken) aFunnel = toPipeOut(afifo); FIFOF#(MmToken) bfifo <- mkFIFOF(); PipeOut#(MmToken) bFunnel = toPipeOut(bfifo); Reg#(Bit#(16)) firstCnt <- mkReg(0); Reg#(Bool) gReg <- mkReg(False); FIFOF#(Float) gFifo <- mkSizedFIFOF(kk); Reg#(Bit#(16)) lastCnt <- mkReg(0); Reg#(Bit#(16))gatherCnt <- mkReg(0); Reg#(Bool) gather_phase <- mkReg(False); //invariant: gather_phase = lastCnt == fromInteger(kk); Reg#(Bool) lastPassReg <- mkReg((0+1) == fromInteger(valueOf(gatherSz))); FIFOF#(Tuple2#(Bool,Bool)) flFifo <- mkSizedFIFOF(ub_MulLat); Vector#(k,FIFOF#(MmToken)) dotfifos <- replicateM(mkFIFOF1); Reg#(Bit#(TAdd#(1,TLog#(k)))) rowReg <- mkReg(0); Reg#(Bool) lastRowReg <- mkReg(False); Reg#(Bit#(32)) lastMul <- mkReg(0); Reg#(Bit#(32)) lastAcc <- mkReg(0); Reg#(Bit#(32)) lastGather <- mkReg(0); Reg#(Bit#(32)) macs <- mkReg(0); (* fire_when_enabled *) rule connect_adder_buffer; match {.acc,.*} <- adder.response.get(); adder_buffer.enq(acc); macs <= macs+1; endrule (* fire_when_enabled *) rule multiply; lastMul <= cycles; let a <- toGet(aFunnel).get(); let b <- toGet(bFunnel).get(); flFifo.enq(tuple2(a.first,a.last)); if (a.first != b.first) $display("****\n Warning: a.first=%d != b.first=%d\n****", a.first, b.first); if (a.last != b.last) $display("****\n Warning: a.last=%d != b.last=%d\n****", a.last, b.last); if (verbose) $display("%08d multiply: label=%d mulin first=%d last=%d", cycles-lastMul, label, a.first, a.last); mul.request.put(tuple2(a.v, b.v)); `ifdef TAGGED_TOKENS if(label==0) $display("%d (%d,%d)(%d,%d)", label, a.row, a.col, b.row, b.col); tag_fifo.enq(tuple2(a.row,b.col)); `endif endrule function Action incrementRowReg = (action // I have to do this check (instead of relying on wrap-around) because // rowReg has an extra bit to compenseate for bsc's silly Bit#(0) handling if (rowReg+1 == fromInteger(kk)) begin rowReg <= 0; lastRowReg <= (0 == fromInteger(kk-1)); end else begin rowReg <= rowReg+1; lastRowReg <= (rowReg == fromInteger(kk-2)); end endaction); (* fire_when_enabled *) rule accumulate if (!gather_phase); incrementRowReg; lastAcc <= cycles; match {.first, .last} <- toGet(flFifo).get(); if (verbose) $display("%08d accumulate: label=%d mulout first=%d last=%d firstCnt=%d lastCnt=%d", cycles-lastAcc, label, first, last, firstCnt, lastCnt); match {.resp,.*} <- mul.response.get; let acc = unpack(0); if (firstCnt == fromInteger(valueOf(TMul#(k,gatherSz)))) acc <- toGet(adder_buffer).get; else begin firstCnt <= firstCnt+1; end adder.request.put(tuple2(resp,acc)); if(last) begin lastCnt <= lastCnt+1; gather_phase <= (lastCnt == fromInteger(kk)-1); end `ifdef TAGGED_TOKENS let row = rowReg; let t <- toGet(tag_fifo).get; tag_regs[row] <= t; `endif endrule rule checkInvariant; if (lastPassReg != ((gatherCnt+1) == fromInteger(valueOf(gatherSz)))) begin $display("last_pass invariant failure: last_pass=%d %d gatherCnt=%d gatherSz=%d", lastPassReg, ((gatherCnt+1) == fromInteger(valueOf(gatherSz))), gatherCnt, fromInteger(valueOf(gatherSz))); $finish(); end dynamicAssert(lastPassReg == (gatherCnt+1 == fromInteger(valueOf(gatherSz))), "gatherCnt invariant"); endrule (* fire_when_enabled *) rule gather if (gather_phase); incrementRowReg; lastGather <= cycles; let row = rowReg; let last_row = lastRowReg; let last_pass = lastPassReg; // invariant: lastPassReg == (gatherCnt+1 == fromInteger(valueOf(gatherSz));) if (verbose) $display("%08d gather: gather=%d row=%d last_pass=%d last_row=%d, gReg=%d", cycles-lastGather, gatherCnt, row, last_pass, last_row, gReg); let x <- toGet(adder_buffer).get; if (!last_pass) begin if (last_row) begin if (gReg) begin gatherCnt <= gatherCnt+1; lastPassReg <= ((gatherCnt+2) == fromInteger(valueOf(gatherSz))); end gReg <= !gReg; end if(gReg) begin let y <- toGet(gFifo).get; adder.request.put(tuple2(x,y)); end else begin gFifo.enq(x); end end else begin `ifdef TAGGED_TOKENS let row = tpl_1(tag_regs[row]); let col = tpl_2(tag_regs[row]); dotfifos[row].enq(MmToken{row:row, col:col, v:x}); `else dotfifos[row].enq(MmToken{v:x, last:False, first:False}); `endif if (last_row) begin gatherCnt <= 0; lastPassReg <= ((0+1) == fromInteger(valueOf(gatherSz))); lastCnt <= 0; firstCnt <= 0; gather_phase <= False; end end endrule Vector#(k,PipeOut#(MmToken)) dotpipes = map(toPipeOut, dotfifos); interface Put aInput; method Action put(MmToken a); afifo.enq(a); countReg <= countReg+1; endmethod endinterface interface Put bInput = toPut(bfifo); interface Vector pipes = dotpipes; interface SharedDotProdDebug debug; interface PipeOut macCount = toPipeOut(macs._read); endinterface endmodule : mkSharedInterleavedDotProdServerConfig interface MmTileDebug; interface PipeOut#(Bit#(32)) macCount; endinterface interface MmTile; interface Vector#(RowsPerTile, Put#(MmToken)) aInputs; interface Vector#(RowsPerTile, Put#(MmToken)) bInputs; interface Vector#(RowsPerTile, PipeOut#(Vector#(N, MmToken))) fxPipes; interface MmTileDebug debug; endinterface function Put#(a) toCountedPut(Reg#(Bit#(n)) r, Put#(a) p); return (interface Put#(a); method Action put(a v); r <= r+1; p.put(v); endmethod endinterface); endfunction (* synthesize *) module mkMmTile#(Clock slowClock, Reset slowReset, UInt#(TLog#(T)) tile)(MmTile); let rowsPerTile = valueOf(RowsPerTile); let kk = valueOf(K); Vector#(RowsPerTile, Reg#(Bit#(32))) aMmTokensPutRegs <- replicateM(mkReg(0)); Vector#(RowsPerTile, Reg#(Bit#(32))) bMmTokensPutRegs <- replicateM(mkReg(0)); Vector#(RowsPerTile, Reg#(Bit#(32))) aMmTokensReadRegs <- replicateM(mkReg(0)); Vector#(RowsPerTile, Reg#(Bit#(32))) bMmTokensReadRegs <- replicateM(mkReg(0)); Vector#(RowsPerTile, FIFOF#(MmToken)) aFifos <- replicateM(mkFIFOF); Vector#(RowsPerTile, PipeOut#(MmToken)) aPipes = zipWith(toCountedPipeOut, aMmTokensReadRegs, map(toPipeOut, aFifos)); Vector#(RowsPerTile, FIFOF#(MmToken)) bFifos <- replicateM(mkFIFOF); Vector#(RowsPerTile, PipeOut#(MmToken)) bPipes = zipWith(toCountedPipeOut, bMmTokensReadRegs, map(toPipeOut, bFifos)); function Vector#(k,PipeOut#(MmToken)) getDotProdServerPipes(SharedDotProdServer#(k) s); return s.pipes; endfunction Vector#(RowsPerTile, SharedDotProdServer#(K)) fxdotprods <- mapM(mkSharedInterleavedDotProdServer, map(fromInteger,genVector)); Vector#(RowsPerTile, Vector#(K, PipeOut#(MmToken))) fxpipes = map(getDotProdServerPipes, fxdotprods); //`define USE_MIMO_DFIFOS // this version is faster let fastClock <- exposeCurrentClock(); let fastReset <- exposeCurrentReset(); `ifndef USE_MIMO_DFIFOS Vector#(RowsPerTile, PipeOut#(Vector#(K, MmToken))) fxPipesK <- mapM(mkJoinVector(id), fxpipes); Vector#(RowsPerTile, PipeOut#(MmToken)) fxPipes1MmToken <- mapM(mkFunnel1, fxPipesK); Vector#(RowsPerTile, PipeOut#(Vector#(1, MmToken))) fxPipes1 = map(mapPipe(replicate), fxPipes1MmToken); `else MIMOConfiguration mimoCfg = defaultValue; Vector#(RowsPerTile, MIMO#(K,1,TAdd#(K,1),MmToken)) dfifos <- replicateM(mkMIMO(mimoCfg)); Vector#(RowsPerTile, PipeOut#(Vector#(1, MmToken))) fxPipes1 = map(toPipeOut, dfifos); `endif Vector#(RowsPerTile, Gearbox#(1, N, MmToken)) gearboxes <- replicateM(mk1toNGearbox(fastClock, fastReset, slowClock, slowReset)); Vector#(RowsPerTile, PipeIn#(Vector#(1,MmToken))) toGearboxes = map(toPipeIn, gearboxes); Vector#(RowsPerTile, PipeOut#(Vector#(N, MmToken))) fromGearboxes = map(toPipeOut, gearboxes); mapM(uncurry(mkConnection), zip(fxPipes1, toGearboxes)); // introduce a buffer to help vivado meet timing on vc707 Vector#(RowsPerTile, FIFOF#(Vector#(N,MmToken))) tokenfifos <- replicateM(mkFIFOF(clocked_by slowClock, reset_by slowReset)); Vector#(RowsPerTile, PipeIn#(Vector#(N,MmToken))) toMmTokenFifos = map(toPipeIn, tokenfifos); mapM(uncurry(mkConnection), zip(fromGearboxes, toMmTokenFifos), clocked_by slowClock, reset_by slowReset); Vector#(RowsPerTile, PipeOut#(Vector#(N, MmToken))) fxPipesN = map(toPipeOut, tokenfifos); FirstLastPipe#(UInt#(MMSize)) firstLastPipe <- mkFirstLastPipe(); Vector#(2, PipeOut#(Tuple2#(Bool,Bool))) firstLastPipes <- mkForkVector(firstLastPipe.pipe); for (Integer j = 0; j < rowsPerTile; j = j + 1) begin //mkConnection(toGet(aPipes[j]), fxdotprods[j].aInput); //mkConnection(toGet(bPipes[j]), fxdotprods[j].bInput); (* fire_when_enabled *) rule connectA; let x <- toGet(aPipes[j]).get; fxdotprods[j].aInput.put(x); endrule (* fire_when_enabled *) rule connectB; let x <- toGet(bPipes[j]).get; fxdotprods[j].bInput.put(x); endrule end `ifdef USE_MIMO_DFIFOS for (Integer j = 0; j < rowsPerTile; j = j + 1) begin rule dotProdValue; Vector#(K,MmToken) vs; for (Integer k = 0; k < kk; k = k + 1) begin let v <- toGet(fxpipes[j][k]).get(); vs[k] = v; end dfifos[j].enq(fromInteger(kk), vs); endrule end `endif function Bool fifofNotEmpty(FIFOF#(a) fifof); return fifof.notEmpty(); endfunction function PipeOut#(Bit#(32)) dotProdMacCount(SharedDotProdServer#(K) dotprodserver); return dotprodserver.debug.macCount; endfunction PipeOut#(Bit#(32)) macCountPipe <- mkReducePipes(uncurry(add), map(dotProdMacCount, fxdotprods)); interface Vector aInputs = zipWith(toCountedPut, aMmTokensPutRegs, map(toPut, aFifos)); interface Vector bInputs = zipWith(toCountedPut, bMmTokensPutRegs, map(toPut, bFifos)); interface Vector fxPipes = fxPipesN; interface MmTileDebug debug; interface PipeOut macCount = macCountPipe; endinterface endmodule : mkMmTile typedef struct { SGLId sglId; addrtype base; addrtype numRows; addrtype numColumns; } MatrixDescriptor#(type addrtype) deriving (Bits); interface DmaMatrixMultiplyDebug; method Bit#(32) macCount(); endinterface ================================================ FILE: lib/matmul/bsv/FloatOps.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ `include "ConnectalProjectConfig.bsv" import FIFOF::*; import GetPut::*; import ClientServer::*; import FloatingPoint::*; import DefaultValue::*; import Randomizable::*; import Vector::*; import StmtFSM::*; import Pipe::*; import FIFO::*; import FpMac::*; `ifdef SIMULATION `ifndef BOARD_xsim `define USE_BSV_FP `endif // xsim `else // !SIMULATION `ifndef XILINX `define USE_BSV_FP `endif // !XILINX `endif // !SIMULATION interface FloatAlu; interface Put#(Tuple2#(Float,Float)) request; interface Get#(Tuple2#(Float,Exception)) response; endinterface (* synthesize *) module mkDoubleToFloat(Server#(Double,Float)); FIFO#(Double) requestFifo <- mkFIFO(); FIFO#(Float) responseFifo <- mkFIFO(); rule cvt; Double d <- toGet(requestFifo).get(); Tuple2#(Float,Exception) tpl = convert(d, defaultValue, False); match { .f, .exc } = tpl; responseFifo.enq(f); endrule interface Put request = toPut(requestFifo); interface Get response = toGet(responseFifo); endmodule (* synthesize *) module mkFloatToDouble(Server#(Float,Double)); FIFO#(Float) requestFifo <- mkFIFO(); FIFO#(Double) responseFifo <- mkFIFO(); rule cvt; Float f <- toGet(requestFifo).get(); Tuple2#(Double,Exception) tpl = convert(f, defaultValue, False); match { .d, .exc } = tpl; responseFifo.enq(d); endrule interface Put request = toPut(requestFifo); interface Get response = toGet(responseFifo); endmodule (* synthesize *) module mkFloatAdder#(RoundMode rmode)(FloatAlu); `ifdef USE_BSV_FP let adder <- mkFPAdder(rmode); `else let adder <- mkXilinxFPAdder(rmode); `endif interface Put request; method Action put(Tuple2#(Float,Float) req); match { .a, .b } = req; let tpl3 = tuple3(a, b, rmode); adder.request.put(req); endmethod endinterface interface Get response; method ActionValue#(Tuple2#(Float,Exception)) get(); let resp <- adder.response.get(); return resp; endmethod endinterface endmodule module mkFloatAddPipe#(PipeOut#(Tuple2#(Float,Float)) xypipe)(PipeOut#(Float)); let adder <- mkFloatAdder(defaultValue); FIFOF#(Float) fifo <- mkFIFOF(); rule consumexy; let xy = xypipe.first(); xypipe.deq; adder.request.put(tuple2(tpl_1(xy),tpl_2(xy))); endrule rule enqout; let resp <- adder.response.get(); fifo.enq(tpl_1(resp)); endrule return toPipeOut(fifo); endmodule (* synthesize *) module mkFloatSubtracter#(RoundMode rmode)(FloatAlu); `ifdef USE_BSV_FP let adder <- mkFPAdder(rmode); `else let adder <- mkXilinxFPAdder(rmode); `endif interface Put request; method Action put(Tuple2#(Float,Float) req); match { .a, .b } = req; let tpl3 = tuple3(a, negate(b), rmode); adder.request.put(req); endmethod endinterface interface Get response; method ActionValue#(Tuple2#(Float,Exception)) get(); let resp <- adder.response.get(); return resp; endmethod endinterface endmodule module mkFloatSubPipe#(PipeOut#(Tuple2#(Float,Float)) xypipe)(PipeOut#(Float)); let subtracter <- mkFloatSubtracter(defaultValue); FIFOF#(Float) fifo <- mkFIFOF(); rule consumexy; let xy = xypipe.first(); xypipe.deq; subtracter.request.put(tuple2(tpl_1(xy),tpl_2(xy))); endrule rule enqout; let resp <- subtracter.response.get(); fifo.enq(tpl_1(resp)); endrule return toPipeOut(fifo); endmodule (* synthesize *) module mkFloatMultiplier#(RoundMode rmode)(FloatAlu); `ifdef USE_BSV_FP let multiplier <- mkFPMultiplier(rmode); `else let multiplier <- mkXilinxFPMultiplier(rmode); `endif interface Put request; method Action put(Tuple2#(Float,Float) req); multiplier.request.put(req); endmethod endinterface interface Get response; method ActionValue#(Tuple2#(Float,Exception)) get(); let resp <- multiplier.response.get(); return resp; endmethod endinterface endmodule /*********** missing fromInt32() (* synthesize *) module mkRandomPipe(PipeOut#(Float)); let randomizer <- mkConstrainedRandomizer(0, 1024); Reg#(Bool) initted <- mkReg(False); rule first if (!initted); randomizer.cntrl.init(); initted <= True; endrule let pipe_out <- mkPipeOut(interface Get#(Float); method ActionValue#(Float) get(); let v <- randomizer.next(); Float f = fromInt32(v); return f; endmethod endinterface); return pipe_out; endmodule */ ================================================ FILE: lib/matmul/bsv/FpAdd.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* /home/jamey/connectal/scripts/importbvi.py -o FpAdd.bsv -c aclk -f s_axis_a -f s_axis_b -f m_axis_result -I FpAdd -P FpAdd fp_add_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface FpaddM_axis_result; method Bit#(32) tdata(); method Action tready(Bit#(1) v); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface FpaddS_axis_a; method Action tdata(Bit#(32) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface FpaddS_axis_b; method Action tdata(Bit#(32) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface FpaddS_axis_operation; method Action tdata(Bit#(8) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface FpAdd; interface FpaddM_axis_result m_axis_result; interface FpaddS_axis_a s_axis_a; interface FpaddS_axis_b s_axis_b; interface FpaddS_axis_operation s_axis_operation; endinterface import "BVI" fp_add = module mkFpAdd(FpAdd); default_clock aclk(aclk); default_reset aresetn(aresetn); interface FpaddM_axis_result m_axis_result; method m_axis_result_tdata tdata(); method tready(m_axis_result_tready) enable((*inhigh*) EN_m_axis_result_tready); method m_axis_result_tvalid tvalid(); endinterface interface FpaddS_axis_a s_axis_a; method tdata(s_axis_a_tdata) enable((*inhigh*) EN_s_axis_a_tdata); method s_axis_a_tready tready(); method tvalid(s_axis_a_tvalid) enable((*inhigh*) EN_s_axis_a_tvalid); endinterface interface FpaddS_axis_b s_axis_b; method tdata(s_axis_b_tdata) enable((*inhigh*) EN_s_axis_b_tdata); method s_axis_b_tready tready(); method tvalid(s_axis_b_tvalid) enable((*inhigh*) EN_s_axis_b_tvalid); endinterface interface FpaddS_axis_operation s_axis_operation; method tdata(s_axis_operation_tdata) enable((*inhigh*) EN_s_axis_operation_tdata); method s_axis_operation_tready tready(); method tvalid(s_axis_operation_tvalid) enable((*inhigh*) EN_s_axis_operation_tvalid); endinterface schedule (m_axis_result.tdata, m_axis_result.tready, m_axis_result.tvalid, s_axis_a.tdata, s_axis_a.tready, s_axis_a.tvalid, s_axis_b.tdata, s_axis_b.tready, s_axis_b.tvalid, s_axis_operation.tdata, s_axis_operation.tready, s_axis_operation.tvalid) CF (m_axis_result.tdata, m_axis_result.tready, m_axis_result.tvalid, s_axis_a.tdata, s_axis_a.tready, s_axis_a.tvalid, s_axis_b.tdata, s_axis_b.tready, s_axis_b.tvalid, s_axis_operation.tdata, s_axis_operation.tready, s_axis_operation.tvalid); endmodule ================================================ FILE: lib/matmul/bsv/FpMac.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import FIFOF::*; import GetPut::*; import ClientServer::*; import FloatingPoint::*; import DefaultValue::*; import Randomizable::*; import Vector::*; import StmtFSM::*; import Pipe::*; import FIFO::*; import BUtils::*; import PipeMul::*; import FpMul::*; import FpAdd::*; //////////////////////////////////////////////////////////////////////////////// /// Floating point fused multiple accumulate //////////////////////////////////////////////////////////////////////////////// /// /// copied from FloatingPoint.bsv and modified. /// this version is no longer IEEE compliant :) /// //////////////////////////////////////////////////////////////////////////////// typedef struct { Maybe#(FloatingPoint#(e,m)) res; Exception exc; RoundMode rmode; } CommonState#(numeric type e, numeric type m) deriving (Bits, Eq); function Bit#(e) unbias( FloatingPoint#(e,m) din ); return (din.exp - fromInteger(bias(din))); endfunction function Bit#(m) zExtendLSB(Bit#(n) value) provisos( Add#(n,m,k) ); Bit#(k) out = { value, 0 }; return out[valueof(k)-1:valueof(n)]; endfunction function Integer minexp( FloatingPoint#(e,m) din ); return 1-bias(din); endfunction function Bit#(1) getHiddenBit( FloatingPoint#(e,m) din ); return (isSubNormal(din)) ? 0 : 1; endfunction function Integer bias( FloatingPoint#(e,m) din ); return (2 ** (valueof(e)-1)) - 1; endfunction function Integer minexp_subnormal( FloatingPoint#(e,m) din ); return minexp(din)-valueof(m); endfunction function Integer maxexp( FloatingPoint#(e,m) din ); return bias(din); endfunction function Tuple2#(FloatingPoint#(e,m),Exception) round( RoundMode rmode, FloatingPoint#(e,m) din, Bit#(2) guard ) provisos( Add#(m, 1, m1) , Add#(m, 2, m2) ); FloatingPoint#(e,m) out = defaultValue; Exception exc = defaultValue; if (isNaNOrInfinity(din)) begin out = din; end else begin let din_inc = din; Bit#(TAdd#(m,2)) sfd = unpack({1'b0, getHiddenBit(din), din.sfd}) + 1; if (msb(sfd) == 1) begin if (din.exp == fromInteger(maxexp(din) + bias(out))) begin din_inc = infinity(din_inc.sign); end else begin din_inc.exp = din_inc.exp + 1; din_inc.sfd = truncate(sfd >> 1); end end else if ((din.exp == 0) && (truncateLSB(sfd) == 2'b01)) begin din_inc.exp = 1; din_inc.sfd = truncate(sfd); end else begin din_inc.sfd = truncate(sfd); end if (guard != 0) begin exc.inexact = True; end case(rmode) Rnd_Nearest_Even: begin case (guard) 'b00: out = din; 'b01: out = din; 'b10: out = (lsb(din.sfd) == 1) ? din_inc : din; 'b11: out = din_inc; endcase end Rnd_Nearest_Away_Zero: begin case (guard) 'b00: out = din; 'b01: out = din_inc; 'b10: out = din_inc; 'b11: out = din_inc; endcase end Rnd_Plus_Inf: begin if (guard == 0) out = din; else if (din.sign) out = din; else out = din_inc; end Rnd_Minus_Inf: begin if (guard == 0) out = din; else if (din.sign) out = din_inc; else out = din; end Rnd_Zero: begin out = din; end endcase end if (isInfinity(out)) begin exc.overflow = True; end return tuple2(out,exc); endfunction function Tuple3#(FloatingPoint#(e,m),Bit#(2),Exception) normalize( FloatingPoint#(e,m) din, Bit#(x) sfdin ) provisos( Add#(1, a__, x), Add#(m, b__, x), // per request of bsc Add#(c__, TLog#(TAdd#(1, x)), TAdd#(e, 1)) ); FloatingPoint#(e,m) out = din; Bit#(2) guard = 0; Exception exc = defaultValue; Int#(TAdd#(e,1)) exp = isSubNormal(out) ? fromInteger(minexp(out)) : signExtend(unpack(unbias(out))); let zeros = countZerosMSB(sfdin); if ((zeros == 0) && (exp == fromInteger(maxexp(out)))) begin out.exp = maxBound - 1; out.sfd = maxBound; guard = '1; exc.overflow = True; exc.inexact = True; end else begin if (zeros == 0) begin // carry, no sfd adjust necessary if (out.exp == 0) out.exp = 2; else out.exp = out.exp + 1; // carry bit sfdin = sfdin << 1; end else if (zeros == 1) begin // already normalized if (out.exp == 0) out.exp = 1; // carry, hidden bits sfdin = sfdin << 2; end else if (zeros == fromInteger(valueOf(x))) begin // exactly zero out.exp = 0; end else begin // try to normalize Int#(TAdd#(e,1)) shift = zeroExtend(unpack(pack(zeros - 1))); Int#(TAdd#(e,1)) maxshift = exp - fromInteger(minexp(out)); if (shift > maxshift) begin // result will be subnormal sfdin = sfdin << maxshift; out.exp = 0; end else begin // result will be normal sfdin = sfdin << shift; out.exp = out.exp - truncate(pack(shift)); end // carry, hidden bits sfdin = sfdin << 2; end out.sfd = unpack(truncateLSB(sfdin)); sfdin = sfdin << fromInteger(valueOf(m)); guard[1] = unpack(truncateLSB(sfdin)); sfdin = sfdin << 1; guard[0] = |sfdin; end if ((out.exp == 0) && (guard != 0)) exc.underflow = True; return tuple3(out,guard,exc); endfunction function Bool isNaNOrInfinity( FloatingPoint#(e,m) din ); return (din.exp == '1); endfunction //////////////////////////////////////////////////////////////////////////////// /// Pipelined Floating Point Adder //////////////////////////////////////////////////////////////////////////////// module mkFPAdder#(RoundMode rmode)(Server#(Tuple2#(FloatingPoint#(e,m), FloatingPoint#(e,m)), Tuple2#(FloatingPoint#(e,m),Exception))) provisos( // per request of bsc Add#(a__, TLog#(TAdd#(1, TAdd#(m, 5))), TAdd#(e, 1)) ); //////////////////////////////////////////////////////////////////////////////// /// S0 //////////////////////////////////////////////////////////////////////////////// FIFOF#(Tuple2#(FloatingPoint#(e,m), FloatingPoint#(e,m))) fOperands_S0 <- mkLFIFOF; //////////////////////////////////////////////////////////////////////////////// /// S1 - subtract exponents //////////////////////////////////////////////////////////////////////////////// Reg#(Tuple7#(CommonState#(e,m), Bit#(TAdd#(m,5)), Bit#(TAdd#(m,5)), Bool, Bool, Bit#(e), Bit#(e))) rState_S1 <- mkReg(unpack(0)); Reg#(Bool) rValid_S1 <- mkReg(False); Reg#(Tuple6#(CommonState#(e,m), Bit#(TAdd#(m,5)), Bit#(TAdd#(m,5)), Bool, Bool, Bit#(e))) rState_S2 <- mkReg(unpack(0)); Reg#(Bool) rValid_S2 <- mkReg(False); Reg#(Tuple6#(CommonState#(e,m), Bit#(TAdd#(m,5)), Bit#(TAdd#(m,5)), Bool, Bool, Bit#(e))) rState_S3 <- mkReg(unpack(0)); Reg#(Bool) rValid_S3 <- mkReg(False); Reg#(Tuple4#(CommonState#(e,m), FloatingPoint#(e,m), Bit#(2), Bool)) rState_S4 <- mkReg(unpack(0)); Reg#(Bool) rValid_S4 <- mkReg(False); FIFO#(Tuple2#(FloatingPoint#(e,m),Exception)) fResult_S5 <- mkFIFO; rule s1_stage; begin let req = unpack(0); let valid = False; if (fOperands_S0.notEmpty) begin req <- toGet(fOperands_S0).get; valid = True; end match { .opA, .opB } = req; CommonState#(e,m) s = CommonState { res: tagged Invalid, exc: defaultValue, rmode: rmode }; Int#(TAdd#(e,2)) expA = isSubNormal(opA) ? fromInteger(minexp(opA)) : signExtend(unpack(unbias(opA))); Int#(TAdd#(e,2)) expB = isSubNormal(opB) ? fromInteger(minexp(opB)) : signExtend(unpack(unbias(opB))); Bit#(TAdd#(m,5)) sfdA = {1'b0, getHiddenBit(opA), opA.sfd, 3'b0}; Bit#(TAdd#(m,5)) sfdB = {1'b0, getHiddenBit(opB), opB.sfd, 3'b0}; Bit#(TAdd#(m,5)) x; Bit#(TAdd#(m,5)) y; Bool sgn; Bool sub; Bit#(e) exp; Bit#(e) expdiff; if ((expB > expA) || ((expB == expA) && (sfdB > sfdA))) begin exp = opB.exp; expdiff = truncate(pack(expB - expA)); x = sfdB; y = sfdA; sgn = opB.sign; sub = (opB.sign != opA.sign); end else begin exp = opA.exp; expdiff = truncate(pack(expA - expB)); x = sfdA; y = sfdB; sgn = opA.sign; sub = (opA.sign != opB.sign); end if (isSNaN(opA)) begin s.res = tagged Valid nanQuiet(opA); s.exc.invalid_op = True; end else if (isSNaN(opB)) begin s.res = tagged Valid nanQuiet(opB); s.exc.invalid_op = True; end else if (isQNaN(opA)) begin s.res = tagged Valid opA; end else if (isQNaN(opB)) begin s.res = tagged Valid opB; end else if (isInfinity(opA) && isInfinity(opB)) begin if (opA.sign == opB.sign) s.res = tagged Valid infinity(opA.sign); else begin s.res = tagged Valid qnan(); s.exc.invalid_op = True; end end else if (isInfinity(opA)) begin s.res = tagged Valid opA; end else if (isInfinity(opB)) begin s.res = tagged Valid opB; end rState_S1 <= tuple7(s, x, y, sgn, sub, exp, expdiff); rValid_S1 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S2 - align significands //////////////////////////////////////////////////////////////////////////////// //rule s2_stage; begin match {.s, .opA, .opB, .sign, .subtract, .exp, .diff} = rState_S1; let valid = rValid_S1; if (s.res matches tagged Invalid) begin if (diff < fromInteger(valueOf(m) + 5)) begin Bit#(TAdd#(m,5)) guard = opB; guard = opB << (fromInteger(valueOf(m) + 5) - diff); opB = opB >> diff; opB[0] = opB[0] | (|guard); end else if (|opB == 1) begin opB = 1; end end rState_S2 <= tuple6(s, opA, opB, sign, subtract, exp); rValid_S2 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S3 - add/subtract significands //////////////////////////////////////////////////////////////////////////////// //rule s3_stage; begin match {.s, .a, .b, .sign, .subtract, .exp} = rState_S2; let valid = rValid_S2; let sum = a + b; let diff = a - b; rState_S3 <= tuple6(s, sum, diff, sign, subtract, exp); rValid_S3 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S4 - normalize //////////////////////////////////////////////////////////////////////////////// //rule s4_stage; begin match {.s, .addres, .subres, .sign, .subtract, .exp} = rState_S3; let valid = rValid_S3; FloatingPoint#(e,m) out = defaultValue; Bit#(2) guard = 0; if (s.res matches tagged Invalid) begin Bit#(TAdd#(m,5)) result; if (subtract) begin result = subres; end else begin result = addres; end out.sign = sign; out.exp = exp; // $display("out = ", fshow(out)); // $display("result = 'h%x", result); // $display("zeros = %d", countZerosMSB(result)); let y = normalize(out, result); out = tpl_1(y); guard = tpl_2(y); s.exc = s.exc | tpl_3(y); end rState_S4 <= tuple4(s, out, guard, subtract); rValid_S4 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S5 - round result //////////////////////////////////////////////////////////////////////////////// //rule s5_stage; begin match {.s, .rnd, .guard, .subtract} = rState_S4; let valid = rValid_S4; FloatingPoint#(e,m) out = rnd; if (s.res matches tagged Valid .x) begin out = x; end else begin let y = round(s.rmode, out, guard); out = tpl_1(y); s.exc = s.exc | tpl_2(y); end // adjust sign for exact zero result if (isZero(out) && !s.exc.inexact && subtract) begin out.sign = (s.rmode == Rnd_Minus_Inf); end if (valid) fResult_S5.enq(tuple2(out,s.exc)); end endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface request = toPut(fOperands_S0); interface response = toGet(fResult_S5); endmodule: mkFPAdder //////////////////////////////////////////////////////////////////////////////// /// Pipelined Floating Point Multiplier //////////////////////////////////////////////////////////////////////////////// module mkFPMultiplier#(RoundMode rmode)(Server#(Tuple2#(FloatingPoint#(e,m), FloatingPoint#(e,m)), Tuple2#(FloatingPoint#(e,m),Exception))) provisos( // per request of bsc Add#(a__, TLog#(TAdd#(1, TAdd#(TAdd#(m, 1), TAdd#(m, 1)))), TAdd#(e, 1)), Add#(b__, 16, TAdd#(m, 1)) ); let implementSubnormal = False; //////////////////////////////////////////////////////////////////////////////// /// S0 //////////////////////////////////////////////////////////////////////////////// FIFOF#(Tuple2#(FloatingPoint#(e,m), FloatingPoint#(e,m))) fOperands_S0 <- mkLFIFOF; //////////////////////////////////////////////////////////////////////////////// /// S1 - calculate the new exponent/sign //////////////////////////////////////////////////////////////////////////////// Reg#(Tuple5#(CommonState#(e,m), Bit#(TAdd#(m,1)), Bit#(TAdd#(m,1)), Int#(TAdd#(e,2)), Bool)) rState_S1 <- mkReg(unpack(0)); Reg#(Bool) rValid_S1 <- mkReg(False); Reg#(Tuple3#(CommonState#(e,m), Int#(TAdd#(e,2)), Bool)) rState_S2 <- mkReg(unpack(0)); Reg#(Tuple3#(Bool, Bool, Bool)) rCond_S3 <- mkReg(unpack(0)); Reg#(Int#(TAdd#(e,2))) rShift_S3 <- mkReg(0); Reg#(UInt#(TAdd#(TAdd#(m,1),TAdd#(m,1)))) rsfdres_S2_lsb <- mkReg(0); Reg#(UInt#(TAdd#(TAdd#(m,1),TAdd#(m,1)))) rsfdres_S2_msb <- mkReg(0); Reg#(Bool) rValid_S2 <- mkReg(False); Reg#(Tuple3#(CommonState#(e,m), Int#(TAdd#(e,2)), Bool)) rState_S3 <- mkReg(unpack(0)); Reg#(UInt#(TAdd#(TAdd#(m,1),TAdd#(m,1)))) rsfdres_S3 <- mkReg(0); Reg#(Bool) rValid_S3 <- mkReg(False); Reg#(Tuple3#(CommonState#(e,m), FloatingPoint#(e,m), Bit#(2))) rState_S4 <- mkReg(unpack(0)); Reg#(Bool) rValid_S4 <- mkReg(False); FIFO#(Tuple2#(FloatingPoint#(e,m),Exception)) fResult_S5 <- mkFIFO; rule s1_stage; begin let req = unpack(0); let valid = False; if (fOperands_S0.notEmpty()) begin req <- toGet(fOperands_S0).get; valid = True; end match { .opA, .opB } = req; CommonState#(e,m) s = CommonState { res: tagged Invalid, exc: defaultValue, rmode: rmode }; Int#(TAdd#(e,2)) expA = isSubNormal(opA) ? fromInteger(minexp(opA)) : signExtend(unpack(unbias(opA))); Int#(TAdd#(e,2)) expB = isSubNormal(opB) ? fromInteger(minexp(opB)) : signExtend(unpack(unbias(opB))); Int#(TAdd#(e,2)) newexp = expA + expB; Bool sign = (opA.sign != opB.sign); Bit#(TAdd#(m,1)) opAsfd = { getHiddenBit(opA), opA.sfd }; Bit#(TAdd#(m,1)) opBsfd = { getHiddenBit(opB), opB.sfd }; if (isSNaN(opA)) begin s.res = tagged Valid nanQuiet(opA); s.exc.invalid_op = True; end else if (isSNaN(opB)) begin s.res = tagged Valid nanQuiet(opB); s.exc.invalid_op = True; end else if (isQNaN(opA)) begin s.res = tagged Valid opA; end else if (isQNaN(opB)) begin s.res = tagged Valid opB; end else if ((isInfinity(opA) && isZero(opB)) || (isZero(opA) && isInfinity(opB))) begin s.res = tagged Valid qnan(); s.exc.invalid_op = True; end else if (isInfinity(opA) || isInfinity(opB)) begin s.res = tagged Valid infinity(opA.sign != opB.sign); end else if (isZero(opA) || isZero(opB)) begin s.res = tagged Valid zero(opA.sign != opB.sign); end else if (newexp > fromInteger(maxexp(opA))) begin FloatingPoint#(e,m) out; out.sign = (opA.sign != opB.sign); out.exp = maxBound - 1; out.sfd = maxBound; s.exc.overflow = True; s.exc.inexact = True; let y = round(rmode, out, '1); s.res = tagged Valid tpl_1(y); s.exc = s.exc | tpl_2(y); end else if (newexp < (fromInteger(minexp_subnormal(opA))-2)) begin FloatingPoint#(e,m) out; out.sign = (opA.sign != opB.sign); out.exp = 0; out.sfd = 0; s.exc.underflow = True; s.exc.inexact = True; let y = round(rmode, out, 'b01); s.res = tagged Valid tpl_1(y); s.exc = s.exc | tpl_2(y); end rState_S1 <= tuple5(s, opAsfd, opBsfd, newexp, sign); rValid_S1 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S2 //////////////////////////////////////////////////////////////////////////////// //rule s2_stage; begin match {.s, .opAsfd, .opBsfd, .exp, .sign} = rState_S1; let valid = rValid_S1; //Bit#(TAdd#(TAdd#(m,1),TAdd#(m,1))) sfdres = primMul(opAsfd, opBsfd); UInt#(TAdd#(m,1)) opBsfd_lsb = extend(unpack(opBsfd[15:0])); UInt#(TSub#(TAdd#(m,1),16)) opBsfd_msb = unpack(opBsfd[valueOf(TAdd#(m,1))-1:16]); rsfdres_S2_lsb <= extend(unpack(opAsfd))*extend(opBsfd_lsb); rsfdres_S2_msb <= extend(unpack(opAsfd))*extend(opBsfd_msb); rState_S2 <= tuple3(s, exp, sign); rValid_S2 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S3 //////////////////////////////////////////////////////////////////////////////// //rule s3_stage; begin let x = rState_S2; let valid = rValid_S2; rsfdres_S3 <= (rsfdres_S2_msb << 16) + rsfdres_S2_lsb; rState_S3 <= x; rValid_S3 <= valid; match {.s, .exp, .sign} = x; FloatingPoint#(e,m) result = defaultValue; Bit#(2) guard = ?; let sresInvalid = False; let subnormal = False; let inbounds = False; let shift = fromInteger(minexp(result)) - exp; if (s.res matches tagged Invalid) begin sresInvalid = True; if (shift > 0) begin subnormal = True; // subnormal end else begin inbounds = True; end end rCond_S3 <= tuple3(sresInvalid, subnormal, inbounds); if (implementSubnormal) rShift_S3 <= shift; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S4 //////////////////////////////////////////////////////////////////////////////// //rule s4_stage; begin match {.s, .exp, .sign} = rState_S3; match {.sresInvalid, .subnormal, .inbounds} = rCond_S3; let shift = 0; if (implementSubnormal) shift = rShift_S3; let sfdres = pack(rsfdres_S3); let valid = rValid_S3; FloatingPoint#(e,m) result = defaultValue; Bit#(2) guard = ?; //if (s.res matches tagged Invalid) begin if (sresInvalid) begin //$display("sfdres = 'h%x", sfdres); //let shift = fromInteger(minexp(result)) - exp; //if (shift > 0) begin if (subnormal) begin // subnormal if (implementSubnormal) begin Bit#(1) sfdlsb = |(sfdres << (fromInteger(valueOf(TAdd#(TAdd#(m,1),TAdd#(m,1)))) - shift)); //$display("sfdlsb = |'h%x = 'b%b", (sfdres << (fromInteger(valueOf(TAdd#(TAdd#(m,1),TAdd#(m,1)))) - shift)), sfdlsb); sfdres = sfdres >> shift; sfdres[0] = sfdres[0] | sfdlsb; end else begin sfdres = 0; end result.exp = 0; end else begin // inbounds result.exp = cExtend(exp + fromInteger(bias(result))); end // $display("shift = %d", shift); // $display("sfdres = 'h%x", sfdres); // $display("result = ", fshow(result)); // $display("exc = 'b%b", pack(exc)); // $display("zeros = %d", countZerosMSB(sfdres)); result.sign = sign; let y = normalize(result, sfdres); result = tpl_1(y); guard = tpl_2(y); s.exc = s.exc | tpl_3(y); // $display("result = ", fshow(result)); // $display("exc = 'b%b", pack(exc)); end rState_S4 <= tuple3(s, result, guard); rValid_S4 <= valid; end //endrule //////////////////////////////////////////////////////////////////////////////// /// S5 //////////////////////////////////////////////////////////////////////////////// //rule s5_stage; begin match {.s, .rnd, .guard} = rState_S4; let valid = rValid_S4; FloatingPoint#(e,m) out = rnd; if (s.res matches tagged Valid .x) out = x; else begin let y = round(s.rmode, out, guard); out = tpl_1(y); s.exc = s.exc | tpl_2(y); end if (valid) fResult_S5.enq(tuple2(out,s.exc)); end endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface request = toPut(fOperands_S0); interface response = toGet(fResult_S5); endmodule: mkFPMultiplier //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// Wrap Xilinx FP MUL //////////////////////////////////////////////////////////////////////////////// module mkXilinxFPMultiplier#(RoundMode rmode)(Server#(Tuple2#(Float,Float), Tuple2#(Float,Exception))); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); let fpMul <- mkFpMul(); Wire#(Bit#(1)) s_axis_ab_ready <- mkDWire(0); Wire#(Bit#(1)) m_axis_tready <- mkDWire(0); rule ab_ready; fpMul.s_axis_a.tvalid(s_axis_ab_ready); fpMul.s_axis_b.tvalid(s_axis_ab_ready); endrule rule c_ready; fpMul.m_axis_result.tready(m_axis_tready); endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface Put request; method Action put(Tuple2#(Float,Float) req) if (fpMul.s_axis_a.tready() == 1 && fpMul.s_axis_b.tready() == 1); match { .a, .b } = req; fpMul.s_axis_a.tdata(pack(a)); fpMul.s_axis_b.tdata(pack(b)); s_axis_ab_ready <= 1; endmethod endinterface interface Get response; method ActionValue#(Tuple2#(Float,Exception)) get() if (fpMul.m_axis_result.tvalid() == 1); m_axis_tready <= 1; return tuple2(unpack(fpMul.m_axis_result.tdata()), defaultValue); endmethod endinterface endmodule: mkXilinxFPMultiplier //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// Wrap Xilinx FP ADD //////////////////////////////////////////////////////////////////////////////// module mkXilinxFPAdder#(RoundMode rmode)(Server#(Tuple2#(Float, Float), Tuple2#(Float,Exception))); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); let fpAdd <- mkFpAdd(); Wire#(Bit#(1)) s_axis_ab_ready <- mkDWire(0); Wire#(Bit#(1)) m_axis_tready <- mkDWire(0); rule ab_ready; fpAdd.s_axis_a.tvalid(s_axis_ab_ready); fpAdd.s_axis_b.tvalid(s_axis_ab_ready); fpAdd.s_axis_operation.tvalid(s_axis_ab_ready); endrule rule c_ready; fpAdd.m_axis_result.tready(m_axis_tready); endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface Put request; method Action put(Tuple2#(Float,Float) req) if (fpAdd.s_axis_a.tready() == 1 && fpAdd.s_axis_b.tready() == 1); match { .a, .b } = req; fpAdd.s_axis_a.tdata(pack(a)); fpAdd.s_axis_b.tdata(pack(b)); fpAdd.s_axis_operation.tdata(0); s_axis_ab_ready <= 1; endmethod endinterface interface Get response; method ActionValue#(Tuple2#(Float,Exception)) get() if (fpAdd.m_axis_result.tvalid() == 1); m_axis_tready <= 1; return tuple2(unpack(fpAdd.m_axis_result.tdata()), defaultValue); endmethod endinterface endmodule: mkXilinxFPAdder //////////////////////////////////////////////////////////////////////////////// ================================================ FILE: lib/matmul/bsv/FpMacTb.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ // bsv libraries import SpecialFIFOs::*; import Vector::*; import StmtFSM::*; import FIFO::*; import Connectable::*; import FloatingPoint::*; import ClientServer::*; import GetPut::*; import DefaultValue::*; import FIFOF::*; // Connectal libraries import RbmTypes::*; import FpMac::*; import FloatOps::*; interface FpMacRequest; method Action mac(Bit#(32) x, Bit#(32) y); endinterface interface FpMacIndication; method Action res(Bit#(32) v, Bit#(32) e); endinterface module mkFpMacRequest#(FpMacIndication indication) (FpMacRequest); let fpmac <- mkFloatMac(Rnd_Nearest_Even); //defaultValue Reg#(Float) accum <- mkReg(0); rule res; let resp <- fpmac.response.get; accum <= tpl_1(resp); indication.res(pack(tpl_1(resp)), extend(pack(tpl_2(resp)))); endrule method Action mac(Bit#(32) x, Bit#(32) y); fpmac.request.put(tuple3(tagged Valid accum, unpack(x), unpack(y))); endmethod endmodule interface FpMulRequest; method Action mul_req(Bit#(32) x, Bit#(32) y); endinterface interface FpMulIndication; method Action mul_resp(Bit#(32) v); endinterface module mkFpMulRequest#(FpMulIndication indication) (FpMulRequest); FloatAlu mul <- mkFloatMultiplier(defaultValue); Reg#(Float) accum <- mkReg(0); Reg#(int) cycles <- mkReg(0); Reg#(int) last_mul <- mkReg(0); Reg#(int) num_reqs <- mkReg(0); Reg#(int) num_resps <- mkReg(0); let req_fifo <- mkFIFOF; rule cycle; cycles <= cycles+1; endrule rule feed if (num_reqs > 0); num_reqs <= num_reqs-1; mul.request.put(req_fifo.first); endrule rule drain; match {.resp,.*} <- mul.response.get; accum <= resp; num_resps <= num_resps-1; last_mul <= cycles; $display("drain %d", cycles-last_mul); endrule rule res if (num_reqs == 0 && req_fifo.notEmpty); indication.mul_resp(pack(accum)); req_fifo.deq; endrule method Action mul_req(Bit#(32) x, Bit#(32) y); req_fifo.enq(tuple2(unpack(x), unpack(y))); num_reqs <= 64; num_resps <= 64; endmethod endmodule ================================================ FILE: lib/matmul/bsv/FpMul.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* /home/jamey/connectal/scripts/importbvi.py -o FpMul.bsv -c aclk -f s_axis_a -f s_axis_b -f m_axis_result -I FpMul -P FpMul fp_mul_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface FpmulM_axis_result; method Bit#(32) tdata(); method Action tready(Bit#(1) v); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface FpmulS_axis_a; method Action tdata(Bit#(32) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface FpmulS_axis_b; method Action tdata(Bit#(32) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface FpMul; interface FpmulM_axis_result m_axis_result; interface FpmulS_axis_a s_axis_a; interface FpmulS_axis_b s_axis_b; endinterface import "BVI" fp_mul = module mkFpMul(FpMul); default_clock aclk(aclk); default_reset aresetn(aresetn); interface FpmulM_axis_result m_axis_result; method m_axis_result_tdata tdata(); method tready(m_axis_result_tready) enable((*inhigh*) EN_m_axis_result_tready); method m_axis_result_tvalid tvalid(); endinterface interface FpmulS_axis_a s_axis_a; method tdata(s_axis_a_tdata) enable((*inhigh*) EN_s_axis_a_tdata); method s_axis_a_tready tready(); method tvalid(s_axis_a_tvalid) enable((*inhigh*) EN_s_axis_a_tvalid); endinterface interface FpmulS_axis_b s_axis_b; method tdata(s_axis_b_tdata) enable((*inhigh*) EN_s_axis_b_tdata); method s_axis_b_tready tready(); method tvalid(s_axis_b_tvalid) enable((*inhigh*) EN_s_axis_b_tvalid); endinterface schedule (m_axis_result.tdata, m_axis_result.tready, m_axis_result.tvalid, s_axis_a.tdata, s_axis_a.tready, s_axis_a.tvalid, s_axis_b.tdata, s_axis_b.tready, s_axis_b.tvalid) CF (m_axis_result.tdata, m_axis_result.tready, m_axis_result.tvalid, s_axis_a.tdata, s_axis_a.tready, s_axis_a.tvalid, s_axis_b.tdata, s_axis_b.tready, s_axis_b.tvalid); endmodule ================================================ FILE: lib/matmul/bsv/MatrixNT.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import MIMO::*; import DefaultValue::*; import SpecialFIFOs::*; import Vector::*; import BRAM::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import ConnectalMemUtils::*; import FloatingPoint::*; import Pipe::*; import Arith::*; import FloatOps::*; import Timer::*; import RbmTypes::*; import Assert::*; import Connectable::*; import Clocks::*; import Gearbox::*; import XilinxCells::*; import HostInterface::*; import DotProdServer::*; import DmaVector::*; interface RowColSource#(numeric type dsz, type a); interface PipeOut#(a) pipe; method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l, UInt#(32) tag); method ActionValue#(Bool) finish(); endinterface interface RowColSink#(numeric type dsz, type a); interface PipeIn#(a) pipe; method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); method ActionValue#(Bool) finish(); endinterface function PipeOut#(dtype) getRowColSourcePipe(RowColSource#(dsz,dtype) vs); return vs.pipe; endfunction function PipeIn#(a) getRowColSinkPipe(RowColSink#(n,a) vs) = vs.pipe; module mkRowColSink#(VectorSink#(TMul#(N,32),Vector#(N,Float)) vs) (RowColSink#(TMul#(N,32), Vector#(N,MmToken))); function Float tokenValue(MmToken v) = v.v; method Action start(SGLId p, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); vs.start(p,a,l); endmethod method finish = vs.finish; interface PipeIn pipe; method Action enq(Vector#(N,MmToken) v); vs.pipe.enq(map(tokenValue,v)); endmethod method Bool notFull = vs.pipe.notFull; endinterface endmodule module mkRowSource#(VectorSource#(TMul#(N,32),Vector#(N,Float)) vs) (RowColSource#(TMul#(N,32), Vector#(N,MmToken))); `ifdef TAGGED_TOKENS Reg#(UInt#(32)) col <- mkReg(0); FIFOF#(UInt#(32)) tagFifo <- mkSizedFIFOF(4); `endif // perhaps memreadengine could do the labeling Reg#(Bit#(MemOffsetSize)) countReg <- mkReg(0); FIFOF#(Bit#(MemOffsetSize)) cmdFifo <- mkSizedFIFOF(4); method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l, UInt#(32) tag); `ifdef TAGGED_TOKENS tagFifo.enq(tag); `endif vs.start(h,a,l); cmdFifo.enq(l); endmethod method ActionValue#(Bool) finish; let rv <- vs.finish; return rv; endmethod interface PipeOut pipe; method Vector#(N,MmToken) first; Vector#(N,MmToken) rv; `ifdef TAGGED_TOKENS for(Integer i = 0; i < valueOf(N); i=i+1) rv[i] = MmToken{row:tagFifo.first, col:col+fromInteger(i), v:vs.pipe.first[i], first:False, last:False}; `else for(Integer i = 0; i < valueOf(N); i=i+1) rv[i] = MmToken{v:vs.pipe.first[i], first:False, last:False}; `endif if (countReg==0) rv[0].first = True; if (countReg+1==cmdFifo.first) rv[valueOf(N)-1].last = True; return rv; endmethod method Action deq; vs.pipe.deq; //$display("mkRowSource count=%d first=%d last=%d", countReg, firstReg, lastReg); if(countReg+1==cmdFifo.first) begin countReg <= 0; cmdFifo.deq; `ifdef TAGGED_TOKENS tagFifo.deq; col <= 0; `endif end else begin `ifdef TAGGED_TOKENS col <= col+fromInteger(valueOf(N)); `endif countReg <= countReg + 1; end endmethod method Bool notEmpty; `ifdef TAGGED_TOKENS return (tagFifo.notEmpty && vs.pipe.notEmpty); `else return (vs.pipe.notEmpty); `endif endmethod endinterface endmodule module mkColSource#(VectorSource#(TMul#(N,32),Vector#(N,Float)) vs) (RowColSource#(TMul#(N,32), Vector#(N,MmToken))); `ifdef TAGGED_TOKENS Reg#(UInt#(32)) row <- mkReg(0); FIFOF#(UInt#(32)) tagFifo <- mkSizedFIFOF(4); `endif // perhaps memreadengine could do the labeling Reg#(Bit#(MemOffsetSize)) countReg <- mkReg(0); FIFOF#(Bit#(MemOffsetSize)) cmdFifo <- mkSizedFIFOF(4); method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l, UInt#(32) tag); `ifdef TAGGED_TOKENS tagFifo.enq(tag); `endif vs.start(h,a,l); cmdFifo.enq(l); endmethod method ActionValue#(Bool) finish; let rv <- vs.finish; return rv; endmethod interface PipeOut pipe; method Vector#(N,MmToken) first; Vector#(N,MmToken) rv; `ifdef TAGGED_TOKENS for(Integer i = 0; i < valueOf(N); i=i+1) rv[i] = MmToken{row:row+fromInteger(i), col:tagFifo.first, v:vs.pipe.first[i], first:False, last:False}; `else for(Integer i = 0; i < valueOf(N); i=i+1) rv[i] = MmToken{v:vs.pipe.first[i], first:False, last:False}; `endif if (countReg==0) rv[0].first = True; if (countReg+1==cmdFifo.first) rv[valueOf(N)-1].last = True; return rv; endmethod method Action deq; vs.pipe.deq; if(countReg+1==cmdFifo.first) begin countReg <= 0; cmdFifo.deq; `ifdef TAGGED_TOKENS tagFifo.deq; row <= 0; `endif end else begin `ifdef TAGGED_TOKENS row <= row+fromInteger(valueOf(N)); `endif countReg <= countReg+1; end endmethod method Bool notEmpty; `ifdef TAGGED_TOKENS return (tagFifo.notEmpty && vs.pipe.notEmpty); `else return (vs.pipe.notEmpty); `endif endmethod endinterface endmodule: mkColSource // row major layout interface DmaMatrixMultiplyIfc#(numeric type addrwidth, numeric type dsz); method Action start(SGLId pointerA, UInt#(addrwidth) numRowsA, UInt#(addrwidth) numColumnsA, SGLId pointerB, UInt#(addrwidth) numRowsB, UInt#(addrwidth) numColumnsB, SGLId pointerC, UInt#(addrwidth) numRowsA_x_numColumnsA, UInt#(addrwidth) numColumnsA_x_J, UInt#(addrwidth) numRowsB_x_numColumnsB, UInt#(addrwidth) numColumnsB_x_K, UInt#(addrwidth) numRowsA_x_numRowsB, UInt#(addrwidth) numRowsB_x_J); method ActionValue#(Bool) finish(); interface DmaMatrixMultiplyDebug debug; endinterface typedef enum { Idle, Ready, Running, Done } MMState deriving (Bits, Eq); /*! * Multiplies two matrices A and B and writes the result to memory. * Fetches J rows at a time from A and K rows at a time from B. * Each cycle, it can fetch N elements of a row or column. * * Just considering memory bandwidth, every J+K cycles it is ready to perform J*K*N multiply accumulates. * */ module mkDmaMatrixMultiply#(Vector#(J, VectorSource#(dsz, Vector#(N, Float))) sA, Vector#(K, VectorSource#(dsz, Vector#(N, Float))) sB, Vector#(J, VectorSink#(dsz, Vector#(N,Float))) ss, HostInterface host )(DmaMatrixMultiplyIfc#(addrwidth, dsz)) provisos ( Mul#(N,n__,K) // K must be an integer multiple of N , Mul#(N,m__,J) // J must be an integer multiple of N , Add#(1,o__,J) , Log#(N,nshift) , FShow#(Float) , Arith#(Float) , Bits#(Vector#(N, Float), dsz) , Bits#(MatrixDescriptor#(UInt#(addrwidth)), mdsz) , Bits#(Tuple2#(UInt#(addrwidth), UInt#(addrwidth)), tplsz) , Add#(b__, 20, addrwidth) , Add#(a__, addrwidth, MemOffsetSize) , Add#(c__, addrwidth, 32) , Max#(1, TDiv#(TLog#(J),2), bpc_j) , Max#(1, TDiv#(TLog#(K),2), bpc_k) ); let n = valueOf(N); let jj = valueOf(J); let kk = valueOf(K); let tt = valueOf(T); let nshift = valueOf(nshift); Bool verbose = False; Bool verbose1 = False; Bool timing = False; let defaultClock <- exposeCurrentClock(); let defaultReset <- exposeCurrentReset(); let derivedClock = host.derivedClock; let currentReset <- exposeCurrentReset; let derivedReset <- mkAsyncReset(2, currentReset, derivedClock); Reg#(UInt#(32)) cycles <- mkReg(0); Reg#(Bool) doneReg <- mkReg(False); FIFOF#(MatrixDescriptor#(UInt#(addrwidth))) descFifoA <- mkSizedFIFOF(1); FIFOF#(MatrixDescriptor#(UInt#(addrwidth))) descFifoB <- mkSizedFIFOF(1); FIFOF#(MatrixDescriptor#(UInt#(addrwidth))) descFifoC <- mkSizedFIFOF(1); UnFunnelPipe#(1,J,MatrixDescriptor#(UInt#(addrwidth)),bpc_j) descriptorA <- mkPipelinedForkVector(toPipeOut(descFifoA), 0); UnFunnelPipe#(1,K,MatrixDescriptor#(UInt#(addrwidth)),bpc_k) descriptorB <- mkPipelinedForkVector(toPipeOut(descFifoB), 1); UnFunnelPipe#(1,J,MatrixDescriptor#(UInt#(addrwidth)),bpc_j) descriptorC <- mkPipelinedForkVector(toPipeOut(descFifoC), 2); Reg#(UInt#(addrwidth)) dotprodCount <- mkReg(0); Vector#(J, RowColSource#(TMul#(N,32), Vector#(N,MmToken))) sourceA <- mapM(mkRowSource, sA); Vector#(K, RowColSource#(TMul#(N,32), Vector#(N,MmToken))) sourceB <- mapM(mkColSource, sB); Vector#(J, RowColSink#(TMul#(N,32), Vector#(N,MmToken))) sinks <- mapM(mkRowColSink,ss); Vector#(J, PipeOut#(MmToken)) aPipes <- mapM(mkFunnelGB1(defaultClock, defaultReset, derivedClock, derivedReset), map(getRowColSourcePipe, sourceA)); Vector#(K, PipeOut#(MmToken)) bPipes <- mapM(mkFunnelGB1(defaultClock, defaultReset, derivedClock, derivedReset), map(getRowColSourcePipe, sourceB)); PipeOut#(MmToken) bFunnel <- mkFunnelPipes1(bPipes, clocked_by derivedClock, reset_by derivedReset); Vector#(J, PipeOut#(MmToken)) bFunnelPipes <- mkForkVector(bFunnel, clocked_by derivedClock, reset_by derivedReset); rule countCycles; cycles <= cycles+1; endrule UInt#(TAdd#(TLog#(K),1)) repetitions = fromInteger(valueOf(K)); Vector#(J, PipeOut#(MmToken)) aRepeaters <- mapM(mkRepeat(repetitions), aPipes, clocked_by derivedClock, reset_by derivedReset); Vector#(T, MmTile) mmTiles <- mapM(mkMmTile(defaultClock, defaultReset), map(fromInteger,genVector), clocked_by derivedClock, reset_by derivedReset); Vector#(J, PipeOut#(Vector#(N,MmToken))) fxpipes; for (Integer t = 0; t < valueOf(T); t = t+1) begin for (Integer i = 0; i < valueof(RowsPerTile); i = i+1) begin let j = t*valueOf(RowsPerTile) + i; mkConnection(toGet(aRepeaters[j]), mmTiles[t].aInputs[i], clocked_by derivedClock, reset_by derivedReset); mkConnection(toGet(bFunnelPipes[j]), mmTiles[t].bInputs[i], clocked_by derivedClock, reset_by derivedReset); fxpipes[j] = mmTiles[t].fxPipes[i]; end end zipWithM(mkConnection, fxpipes, map(getRowColSinkPipe, sinks)); XYIteratorIfc#(UInt#(addrwidth)) indexpipeifc <- mkXYIterator(); XYIteratorIfc#(UInt#(addrwidth)) offsetpipeA <- mkXYIterator(); XYIteratorIfc#(UInt#(addrwidth)) offsetpipeB <- mkXYIterator(); XYIteratorIfc#(UInt#(addrwidth)) offsetpipeC <- mkXYIterator(); Vector#(TAdd#(J,K), PipeOut#(Tuple2#(UInt#(addrwidth),UInt#(addrwidth)))) indexpipes <- mkForkVector(indexpipeifc.pipe); Vector#(J, PipeOut#(Tuple2#(UInt#(addrwidth),UInt#(addrwidth)))) offsetpipesA <- mkForkVector(offsetpipeA.pipe); Vector#(K, PipeOut#(Tuple2#(UInt#(addrwidth),UInt#(addrwidth)))) offsetpipesB <- mkForkVector(offsetpipeB.pipe); Vector#(J, PipeOut#(Tuple2#(UInt#(addrwidth),UInt#(addrwidth)))) offsetpipesC <- mkForkVector(offsetpipeC.pipe); Vector#(J, Reg#(UInt#(32))) lastStartAs <- replicateM(mkReg(0)); Vector#(K, Reg#(UInt#(32))) lastStartBs <- replicateM(mkReg(0)); Vector#(K, Reg#(UInt#(32))) lastStartCs <- replicateM(mkReg(0)); Reg#(Bool) running <- mkReg(False); FIFOF#(Bool) doneFifo <- mkFIFOF(); FIFOF#(Bool) initNumEltsFifo <- mkFIFOF(); Vector#(J, Reg#(UInt#(addrwidth))) startAOffset <- replicateM(mkReg(0)); Vector#(K, Reg#(UInt#(addrwidth))) startBOffset <- replicateM(mkReg(0)); Vector#(J, Reg#(UInt#(addrwidth))) startCOffset <- replicateM(mkReg(0)); Vector#(K, FIFO#(void)) controlDependenceB <- replicateM(mkFIFO); for (Integer k = 0; k < kk; k = k + 1) begin rule startSourceB if (!initNumEltsFifo.notEmpty); if(k > 0) controlDependenceB[k-1].deq; if(k < kk-1) controlDependenceB[k].enq(?); Tuple2#(UInt#(addrwidth),UInt#(addrwidth)) index <- toGet(indexpipes[k]).get(); match { .unusedB, .startBBase } <- toGet(offsetpipesB[k]).get(); int kint = fromInteger(k); let row = tpl_1(index); let col = tpl_2(index)+fromInteger(k); let startB = startBBase + startBOffset[k]; lastStartBs[k] <= cycles; let interval = cycles-lastStartBs[k]; if (timing || verbose) $display($format(fshow(interval)+fshow(" startB index=")+fshow(tuple2(row,col)) +fshow(" startB=")+fshow(startB) +fshow(" k=")+fshow(kint))); if (verbose || verbose1) $display($format(fshow(cycles)+fshow(" sourceB[")+fshow(kint)+fshow("].start")+fshow(startB))); sourceB[k].start(descriptorB[k].first.sglId, pack(extend(startB>>nshift)), pack(extend(descriptorB[k].first.numColumns>>nshift)), extend(col)); endrule rule finishSourceB; UInt#(TLog#(K)) in = fromInteger(k); int kint = fromInteger(k); if (timing || verbose || verbose1) $display($format(fshow(cycles)+fshow(" sourceB[")+fshow(kint)+fshow("].finish"))); let b <- sourceB[k].finish(); endrule end Vector#(J, FIFO#(void)) controlDependenceA <- replicateM(mkFIFO); for (Integer j = 0; j < jj; j = j + 1) begin int jint = fromInteger(j); rule startSourceAndSink if (!initNumEltsFifo.notEmpty); if(j > 0) controlDependenceA[j-1].deq; if(j < jj-1) controlDependenceA[j].enq(?); Tuple2#(UInt#(addrwidth),UInt#(addrwidth)) index <- toGet(indexpipes[j+kk]).get(); let row = tpl_1(index)+fromInteger(j); let col = tpl_2(index); match { .startABase, .unusedA } <- toGet(offsetpipesA[j]).get(); match { .startCBase, .offsetC } <- toGet(offsetpipesC[j]).get(); let startA = startABase + startAOffset[j]; let startC = startCBase + startCOffset[j] + offsetC; int jint = fromInteger(j); if (timing || verbose) $display($format(fshow(cycles)+fshow(" start A index=")+fshow(tuple2(row,col)) +fshow(" startA=")+fshow(startA) +fshow(" startC=")+fshow(startC) +fshow(" j=")+fshow(jint))); sourceA[j].start(descriptorA[j].first.sglId, pack(extend(startA>>nshift)), pack(extend(descriptorA[j].first.numColumns>>nshift)), extend(row)); if (verbose || verbose1) $display($format(fshow(cycles)+fshow(" sourceA[")+fshow(jint)+fshow("].start")+fshow(startA))); sinks[j].start(descriptorC[j].first.sglId, pack(extend(startC>>nshift)), fromInteger(kk/n)); if (verbose || verbose1) $display($format(fshow(cycles)+fshow(" sinks[")+fshow(jint)+fshow("].start")+fshow(startC))); endrule rule finishSourceA; if (timing || verbose || verbose1) $display($format(fshow(cycles)+fshow(" sourceA[")+fshow(jint)+fshow("].finish "))); let b <- sourceA[j].finish(); endrule rule finishSink; $dumpoff(); // each time we write a burst of k values via sinks //let index <- toGet(indexpipes[jj+kk+1]).get(); let b <- sinks[j].finish(); let c = dotprodCount-fromInteger(kk); int jint = fromInteger(j); if (timing || verbose1) $display($format(fshow(cycles)+fshow(" finishSink c")+fshow(c)+fshow(" j=")+fshow(jint))); dotprodCount <= c; if (c == 0) begin running <= False; doneFifo.enq(?); for(Integer i = 0; i < kk; i=i+1) descriptorB[i].deq; for(Integer i = 0; i < jj; i=i+1) begin descriptorA[i].deq; descriptorC[i].deq; end end endrule end rule dotProdsNumElts; initNumEltsFifo.deq(); let numColumnsA = descriptorA[0].first.numColumns; let numColumnsB = descriptorB[0].first.numColumns; let numRowsB = descriptorB[0].first.numRows; for (Integer j = 0; j < jj; j = j + 1) begin startAOffset[j] <= fromInteger(j)*numColumnsA; startCOffset[j] <= fromInteger(j)*numRowsB; end for (Integer k = 0; k < kk; k = k + 1) begin startBOffset[k] <= fromInteger(k)*numColumnsB; end endrule function PipeOut#(Bit#(32)) mmTileMacCount(MmTile mmtile); return mmtile.debug.macCount; endfunction Vector#(T, PipeOut#(Vector#(2,Bit#(32)))) macCountPipes <- mapM(mkUnfunnelGB(defaultClock, defaultReset, derivedClock, derivedReset), map(mapPipe(replicate), map(mmTileMacCount, mmTiles))); PipeOut#(Bit#(32)) macCountPipe <- mkReducePipes(uncurry(add), map(mapPipe(head),macCountPipes)); Reg#(Bit#(32)) macCountReg <- mkReg(0); rule updateMacCount; let mc <- toGet(macCountPipe).get(); macCountReg <= mc; endrule function Bool pipeNotEmpty(RowColSource#(asz, a) vs); return vs.pipe.notEmpty(); endfunction method Action start(SGLId pointerA, UInt#(addrwidth) numRowsA, UInt#(addrwidth) numColumnsA, SGLId pointerB, UInt#(addrwidth) numRowsB, UInt#(addrwidth) numColumnsB, SGLId pointerC, UInt#(addrwidth) numRowsA_x_numColumnsA, UInt#(addrwidth) numColumnsA_x_J, UInt#(addrwidth) numRowsB_x_numColumnsB, UInt#(addrwidth) numColumnsB_x_K, UInt#(addrwidth) numRowsA_x_numRowsB, UInt#(addrwidth) numRowsB_x_J ) if (!running); XYIteratorConfig#(UInt#(addrwidth)) indexcfg = XYIteratorConfig {xbase: 0, xlimit: numRowsA, xstep: fromInteger(jj), ybase: 0, ylimit: numRowsB, ystep: fromInteger(kk) }; XYIteratorConfig#(UInt#(addrwidth)) offsetcfgA = XYIteratorConfig {xbase: 0, xlimit: numRowsA_x_numColumnsA, xstep: numColumnsA_x_J, ybase: 0, ylimit: numRowsB, ystep: fromInteger(kk) }; XYIteratorConfig#(UInt#(addrwidth)) offsetcfgB = XYIteratorConfig {xbase: 0, xlimit: numRowsA, xstep: fromInteger(jj), ybase: 0, ylimit: numRowsB_x_numColumnsB, ystep: numColumnsB_x_K }; XYIteratorConfig#(UInt#(addrwidth)) offsetcfgC = XYIteratorConfig {xbase: 0, xlimit: numRowsA_x_numRowsB, xstep: numRowsB_x_J, ybase: 0, ylimit: numRowsB, ystep: fromInteger(kk) }; descFifoA.enq(MatrixDescriptor { sglId: pointerA, base: 0, numRows: numRowsA, numColumns: numColumnsA}); descFifoB.enq(MatrixDescriptor { sglId: pointerB, base: 0, numRows: numRowsB, numColumns: numColumnsB}); descFifoC.enq(MatrixDescriptor { sglId: pointerC, base: 0, numRows: numRowsA, numColumns: numRowsB}); dotprodCount <= numRowsA_x_numRowsB; running <= True; if (verbose) $display("mm pointerA=%d pointerB=%d pointerC=%d\n", pointerA, pointerB, pointerC); if (verbose) $display("mm.start ra=%d ca=%d rb=%d cb=%d dotprodCount=%d", numRowsA, numColumnsA, numRowsB, numColumnsB, dotprodCount); if (verbose) $display($format(fshow("mm.start ")+fshow(indexcfg))); if (verbose) $display($format(fshow("offsetcfgA ")+fshow(offsetcfgA))); if (verbose) $display($format(fshow("offsetcfgB ")+fshow(offsetcfgB))); if (verbose) $display($format(fshow("offsetcfgC ")+fshow(offsetcfgC))); indexpipeifc.start(indexcfg); offsetpipeA.start(offsetcfgA); offsetpipeB.start(offsetcfgB); offsetpipeC.start(offsetcfgC); $display("initNumElts"); initNumEltsFifo.enq(True); //$dumpfile("test.vcd"); //$dumpvars(); endmethod method ActionValue#(Bool) finish(); if (verbose) $display("mm.finish()"); doneFifo.deq(); return True; endmethod interface DmaMatrixMultiplyDebug debug; method Bit#(32) macCount(); return macCountReg; endmethod endinterface endmodule : mkDmaMatrixMultiply interface DramMatrixMultiply#(numeric type n, numeric type dmasz, numeric type nm); interface Vector#(nm, MemReadClient#(dmasz)) readClients; interface Vector#(nm, MemWriteClient#(dmasz)) writeClients; method Action start(SGLId pointerA, UInt#(MMSize) numRowsA, UInt#(MMSize) numColumnsA, SGLId pointerB, UInt#(MMSize) numRowsB, UInt#(MMSize) numColumnsB, SGLId pointerC, UInt#(MMSize) numRowsA_x_numColumnsA, UInt#(MMSize) numColumnsA_x_J, UInt#(MMSize) numRowsB_x_numColumnsB, UInt#(MMSize) numColumnsB_x_K, UInt#(MMSize) numRowsA_x_numRowsB, UInt#(MMSize) numRowsB_x_J); method ActionValue#(Bool) finish(); interface DmaMatrixMultiplyDebug debug; endinterface module mkDramMatrixMultiply#(HostInterface host)(DramMatrixMultiply#(N,TMul#(N,32),2)); MemWriteEngine#(TMul#(N,32),TMul#(N,32),2, J) writeEngine <- mkMemWriteEngine(); MemReadEngine#(TMul#(N,32), TMul#(N,32), 2, J) rowReadEngine <- mkMemReadEngineBuff(512); MemReadEngine#(TMul#(N,32), TMul#(N,32), 2, K) colReadEngine <- mkMemReadEngineBuff(512); Vector#(J, MemReadServer#(TMul#(N,32))) rowReadServers = rowReadEngine.readServers; Vector#(K, MemReadServer#(TMul#(N,32))) colReadServers = colReadEngine.readServers; MemWriter#(TMul#(32,N)) bogusWriter <- mkMemWriter; Vector#(J, VectorSource#(DmaSz, Vector#(N,Float))) xvfsources <- mapM(mkMemReadVectorSource, rowReadServers); Vector#(K, VectorSource#(DmaSz, Vector#(N,Float))) yvfsources <- mapM(mkMemReadVectorSource, colReadServers); Vector#(J, VectorSink#(DmaSz, Vector#(N,Float))) sinks <- mapM(mkMemWriteVectorSink, writeEngine); DmaMatrixMultiplyIfc#(MMSize,DmaSz) dmaMMF <- mkDmaMatrixMultiply(xvfsources, yvfsources, sinks, host); interface Vector readClients = cons(rowReadEngine.dmaClient, cons(colReadEngine.dmaClient, nil)); interface Vector writeClients = cons(writeEngine.dmaClient, cons(bogusWriter.writeClient, nil)); method start = dmaMMF.start; method finish = dmaMMF.finish; interface DmaMatrixMultiplyDebug debug = dmaMMF.debug; endmodule interface MmNT#(numeric type n); interface MmRequestNT mmRequest; interface TimerRequest timerRequest; interface Vector#(2, MemReadClient#(TMul#(32,n))) readClients; interface Vector#(2, MemWriteClient#(TMul#(32,n))) writeClients; endinterface module mkMmNT#(MmIndication ind, TimerIndication timerInd, HostInterface host)(MmNT#(N)) provisos (Add#(1,a__,N), Add#(N,0,n), Mul#(N,32,DmaSz) ); let n = valueOf(n); DramMatrixMultiply#(N,TMul#(N,32),2) dmaMMF <- mkDramMatrixMultiply(host); Reg#(Bit#(64)) mmfCycles <- mkReg(0); rule countMmfCycles; mmfCycles <= mmfCycles + 1; endrule FIFOF#(Bool) busyFifo <- mkFIFOF(); rule mmfDone; let d <- dmaMMF.finish(); busyFifo.deq(); ind.mmfDone(mmfCycles); endrule FIFOF#(Bool) timerRunning <- mkFIFOF(); Reg#(Bit#(64)) cycleCount <- mkReg(0); Reg#(Bit#(64)) idleCount <- mkReg(0); rule countCycles if (timerRunning.notEmpty()); cycleCount <= cycleCount + 1; if (!busyFifo.notEmpty()) idleCount <= idleCount + 1; endrule interface TimerRequest timerRequest; method Action startTimer() if (!timerRunning.notEmpty()); cycleCount <= 0; idleCount <= 0; timerRunning.enq(True); endmethod method Action stopTimer(); timerRunning.deq(); timerInd.elapsedCycles(cycleCount, idleCount); endmethod endinterface interface MmRequestNT mmRequest; method Action mmf(Bit#(32) h1, Bit#(32) r1, Bit#(32) c1, Bit#(32) h2, Bit#(32) r2, Bit#(32) c2, Bit#(32) h3, Bit#(32) r1_x_c1, Bit#(32) c1_x_j, Bit#(32) r2_x_c2, Bit#(32) c2_x_k, Bit#(32) r1_x_r2, Bit#(32) r2_x_j); check_dimension(r1); check_dimension(c1); check_dimension(r2); check_dimension(c2); dmaMMF.start(h1, unpack(truncate(r1)), unpack(truncate(c1)), h2, unpack(truncate(r2)), unpack(truncate(c2)), h3, unpack(truncate(r1_x_c1)), unpack(truncate(c1_x_j)), unpack(truncate(r2_x_c2)), unpack(truncate(c2_x_k)), unpack(truncate(r1_x_r2)), unpack(truncate(r2_x_j))); mmfCycles <= 0; busyFifo.enq(True); endmethod method Action debug(); let macCount = dmaMMF.debug.macCount(); ind.debug(macCount); endmethod endinterface interface Vector readClients = dmaMMF.readClients; interface Vector writeClients = dmaMMF.writeClients; endmodule ================================================ FILE: lib/matmul/bsv/MatrixTN.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import BRAMFIFO::*; import FIFO::*; import FIFOF::*; import MIMO::*; import DefaultValue::*; import SpecialFIFOs::*; import Vector::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import ConnectalMemUtils::*; import FloatingPoint::*; import Pipe::*; import Arith::*; import FloatOps::*; import Timer::*; import RbmTypes::*; import Assert::*; import Connectable::*; import Clocks::*; import Gearbox::*; import XilinxCells::*; import HostInterface::*; import DotProdServer::*; import ClientServer::*; import GetPut::*; interface RowColSource#(numeric type dsz, type a); interface PipeOut#(a) pipe; method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l, UInt#(32) tag); endinterface interface RowColSink#(numeric type dsz, type a); interface PipeIn#(a) pipe; method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); method ActionValue#(Bool) finish(); endinterface typedef struct { a xbase; a xlimit; a xstep; a ybase; a ylimit; a ystep; a zbase; a zlimit; a zstep; } XYZIteratorConfig#(type a) deriving (Bits, FShow); interface XYZIteratorIfc#(type a); interface PipeOut#(Tuple2#(a,a)) pipe; method Action start(XYZIteratorConfig#(a) cfg); method Action display(); endinterface typedef enum {RangeA,RangeB,RangeC} RangeBehavior deriving (Eq); module mkXYZIterator#(RangeBehavior alt) (XYZIteratorIfc#(a)) provisos (Arith#(a), Bits#(a,awidth), Eq#(a), Ord#(a)); Reg#(a) x <- mkReg(0); Reg#(a) y <- mkReg(0); Reg#(a) z <- mkReg(0); Reg#(a) xbase <- mkReg(0); Reg#(a) ybase <- mkReg(0); Reg#(a) zbase <- mkReg(0); Reg#(a) xstep <- mkReg(0); Reg#(a) ystep <- mkReg(0); Reg#(a) zstep <- mkReg(0); Reg#(a) xlimit <- mkReg(0); Reg#(a) ylimit <- mkReg(0); Reg#(a) zlimit <- mkReg(0); let guard = (x < xlimit && y < ylimit && z < zlimit); interface PipeOut pipe; method Tuple2#(a,a) first() if (guard); if (alt==RangeA) return tuple2(x,z); else if (alt == RangeB) return tuple2(x,y); else //if (alt == RangeC) return tuple2(x+y,z); endmethod method Action deq if (guard); let newx = x+xstep; let newy = y; let newz = z; if (newx >= xlimit) begin newx = xbase; newy = y + ystep; if (newy >= ylimit) begin newy = ybase; newz = z + zstep; end end x <= newx; y <= newy; z <= newz; endmethod method Bool notEmpty(); return guard; endmethod endinterface method Action start(XYZIteratorConfig#(a) cfg) if (!guard); x <= cfg.xbase; y <= cfg.ybase; z <= cfg.zbase; xbase <= cfg.xbase; ybase <= cfg.ybase; zbase <= cfg.zbase; xstep <= cfg.xstep; ystep <= cfg.ystep; zstep <= cfg.zstep; xlimit <= cfg.xlimit; ylimit <= cfg.ylimit; zlimit <= cfg.zlimit; endmethod method Action display(); $display("XYZIterator x=%d xlimit=%d y=%d ylimit=%d z=%d zlimit=%d xstep=%d ystep=%d zstep=%d", x, xlimit, y, ylimit, z, zlimit, xstep, ystep, zstep); endmethod endmodule: mkXYZIterator module mkRowSource#(MemReadServer#(TMul#(N,32)) vs, Reg#(UInt#(addrwidth)) numRows, Bit#(MemTagSize) id) (RowColSource#(TMul#(N,32), Vector#(N,MmToken))) provisos (Bits#(Vector#(N,Float),asz), Div#(asz,8,abytes), Log#(abytes,ashift), Mul#(abytes, 8, asz) ); let cmd_buffer_depth = 32; let verbose = False; let ashift = valueOf(ashift); `ifdef TAGGED_TOKENS Reg#(UInt#(32)) row <- mkReg(0); FIFOF#(UInt#(32)) tagFifo <- mkSizedBRAMFIFOF(cmd_buffer_depth); `endif // perhaps memreadengine could do the labeling Reg#(Bit#(MemOffsetSize)) countReg <- mkReg(0); Reg#(UInt#(addrwidth)) cmdCountReg <- mkReg(0); FIFOF#(Bit#(MemOffsetSize)) cmdFifo <- mkSizedBRAMFIFOF(cmd_buffer_depth); FIFOF#(Vector#(N,Float)) read_data_buffer <- mkFIFOF; rule read_data; let foo <- vs.readData.get; read_data_buffer.enq(unpack(foo.data)); endrule method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l, UInt#(32) tag); `ifdef TAGGED_TOKENS tagFifo.enq(tag); `endif let cmd = MemRequest{sglId:h, offset:a< #include #include void cuda_test() { struct timeval tv0; struct timeval tv1; struct timezone tz; int A = 100; int B = 100; cv::Mat src1(A,B,CV_32F); cv::Mat src2(A,B,CV_32F); cv::Mat src3(A,B,CV_32F); cv::Mat dst(A,B,CV_32F); cv::gpu::GpuMat d_src1, d_src2, d_src3, d_dst; for(int a = 0; a < A; a++){ for(int b = 0; b < B; b++){ src1.at(a,b) = a*b; src2.at(a,b) = a*b; src3.at(a,b) = 0; dst.at(a,b) = 0; } } cv::gemm(src1, src2, 1.0, src3, 1.0, dst); assert(!gettimeofday(&tv0, &tz)); cv::gemm(src1, src2, 1.0, src3, 1.0, dst); assert(!gettimeofday(&tv1, &tz)); fprintf(stderr, "cpu time: %d (usec)\n", tv1.tv_usec-tv0.tv_usec); d_src1.upload(src1); d_src2.upload(src2); d_src3.upload(src3); cv::gpu::gemm(d_src1, d_src2, 1.0, d_src3, 1.0, d_dst); assert(!gettimeofday(&tv0, &tz)); cv::gpu::gemm(d_src1, d_src2, 1.0, d_src3, 1.0, d_dst); assert(!gettimeofday(&tv1, &tz)); fprintf(stderr, "gpu time: %d (usec)\n", tv1.tv_usec-tv0.tv_usec); } long int cuda_mm(cv::Mat& src1, cv::Mat& src2, cv::Mat& dst) { struct timeval tv0; struct timeval tv1; struct timezone tz; cv::Mat src3 = cv::Mat::zeros(src1.rows,src2.cols,CV_32F); cv::gpu::GpuMat d_src1, d_src2, d_src3, d_dst; d_src1.upload(src1); d_src2.upload(src2); d_src3.upload(src3); d_dst.upload(dst); cv::gpu::gemm(d_src1, d_src2, 1.0, d_src3, 1.0, d_dst); assert(!gettimeofday(&tv0, &tz)); cv::gpu::gemm(d_src1, d_src2, 1.0, d_src3, 1.0, d_dst); assert(!gettimeofday(&tv1, &tz)); d_dst.download(dst); long int rv = tv1.tv_usec-tv0.tv_usec; fprintf(stderr, "gpu time: %d (usec)\n", rv); return rv; } ================================================ FILE: lib/matmul/cpp/portalmat.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "dmaManager.h" #include "portalmat.h" PortalMatAllocator *matAllocator = 0; sem_t mul_sem; void PortalMatAllocator::allocate(int dims, const int* sizes, int type, int*& refcount, uchar*& datastart, uchar*& data, size_t* step) { size_t arraysize = step[0]*sizes[0]; size_t totalsize = cv::alignSize(arraysize, 4096); int arraynum = numarrays++; int fd = portalAlloc(totalsize, 0); struct arrayInfo *info = &arrayInfo[arraynum]; info->fd = fd; info->refcount = 1; info->totalsize = totalsize; info->data = (uchar*)portalMmap(fd, totalsize); info->ref = 0; data = datastart = (uchar*)info->data; refcount = (int*)info; fprintf(stderr, "PortalMatAllocator::allocate arraynum=%d arraysize=%ld totalsize=%ld datastart=%p refcount=%p end of data=%p\n", arraynum, (long)arraysize, (long)totalsize, datastart, refcount, datastart+totalsize); } void PortalMatAllocator::deallocate(int* refcount, uchar* datastart, uchar* data) { struct arrayInfo *info = (struct arrayInfo *)refcount; size_t totalsize = info->totalsize; fprintf(stderr, "PortalMatAllocator::deallocate datastart=%p size=%ld ref=%d\n", datastart, (long)totalsize, info->ref); munmap(datastart, totalsize); dma->dereference(info->ref); close(info->fd); memset(info, 0, sizeof(struct arrayInfo)); } int PortalMatAllocator::reference(int* refcount, uchar* datastart, uchar* data) { struct arrayInfo *info = (struct arrayInfo *)refcount; int ref = info->ref; if (!ref) { ref = dma->reference(info->fd); info->ref = ref; } //fprintf(stderr, "PortalMatAllocator::reference returning %d\n", ref); return ref; } void PortalMatAllocator::cacheFlushInvalidate(int* refcount, uchar* datastart, uchar* data) { struct arrayInfo *info = (struct arrayInfo *)refcount; portalCacheFlush(info->fd, datastart, info->totalsize, 1); } PortalMat::PortalMat() : cv::Mat() { allocator = matAllocator; fprintf(stderr, "PortalMat::PortalMat() this=%p datastart=%p\n", this, datastart); } PortalMat::PortalMat(int rows, int cols, int type) : cv::Mat() { allocator = matAllocator; create(rows, cols, type); fprintf(stderr, "PortalMat::PortalMat(rows,cols) this=%p datastart=%p\n", this, datastart); } PortalMat::PortalMat(int rows, int cols, int type, const cv::Scalar& s) : cv::Mat() { allocator = matAllocator; create(rows, cols, type); *(cv::Mat*)this = s; fprintf(stderr, "PortalMat::PortalMat(Scalar&) this=%p datastart=%p\n", this, datastart); } PortalMat::PortalMat(const PortalMat &m) : Mat() { allocator = matAllocator; create(m.rows, m.cols, CV_32F); //*(cv::Mat*)this = m; for (int i = 0; i < m.rows; i++) for (int j = 0; j < m.cols; j++) { this->at(i,j) = m.at(i,j); } fprintf(stderr, "PortalMat::PortalMat(PortalMat&) this=%p datastart=%p\n", this, datastart); } PortalMat::PortalMat(const cv::Mat &m) : Mat() { allocator = matAllocator; create(m.rows, m.cols, CV_32F); //*(cv::Mat*)this = m; for (int i = 0; i < m.rows; i++) for (int j = 0; j < m.cols; j++) { this->at(i,j) = m.at(i,j); } fprintf(stderr, "PortalMat::PortalMat(Mat&) this=%p datastart=%p\n", this, datastart); } PortalMat::~PortalMat() {} PortalMat& PortalMat::operator = (const cv::MatExpr& expr) { *(cv::Mat*)this = expr; fprintf(stderr, "PortalMat::operator=(MatExpr&) this=%p datastart=%p\n", this, datastart); return *this; } PortalMat& PortalMat::operator = (const cv::Mat& o) { *(cv::Mat*)this = o; fprintf(stderr, "PortalMat::operator=(Mat&) this=%p datastart=%p\n", this, datastart); return *this; } int PortalMat::reference() { int ref = 0; //fprintf(stderr, "PortalMat::reference this=%p datastart=%p\n", this, datastart); ref = matAllocator->reference(refcount, datastart, data); return ref; } void PortalMat::cacheFlushInvalidate() { matAllocator->cacheFlushInvalidate(refcount, datastart, data); } bool PortalMat::copy(cv::Mat &other) { create(other.rows, other.cols, CV_32F); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { at(i, j) = other.at(i, j); } } return true; } bool PortalMat::copy(cv::MatExpr other) { cv::Mat m(other); create(m.rows, m.cols, CV_32F); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { at(i, j) = m.at(i, j); } } return true; } bool PortalMat::transpose(cv::Mat &other) { create(other.cols, other.rows, CV_32F); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { at(i, j) = other.at(j, i); } } return true; } bool PortalMat::compare(Mat &refMat, const char *file, int line, float epsilon, Mat *pm, bool verbose) { if (0) fprintf(stderr, "PortalMat.compare rows=%d cols=%d refMat.rows=%d refMat.cols=%d\n", rows, cols, refMat.rows, refMat.cols); if (rows != refMat.rows || cols != refMat.cols) { fprintf(stderr, "PortalMat.compare dimension mismatch rows=%d cols=%d refMat.rows=%d refMat.cols=%d\n", rows, cols, refMat.rows, refMat.cols); return false; } bool rv = true; bool first = true; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { float v = at(i, j); float refVal = refMat.at(i, j); float relativeError = fabs((v - refVal) / refVal); if (relativeError > epsilon) { if (verbose || first) { if (file) fprintf(stderr, "%s:%d: ", file, line); fprintf(stderr, "mismatch[%d,%d] expected %f got %f error=%f)", i, j, refVal, v, relativeError); if (pm) { float pmv = pm->at(i,j); fprintf(stderr, " pm[%d,%d]=%f %08x", i, j, pmv, *(int*)&pmv); } fprintf(stderr, "\n"); } rv = false; first = false; } } } if (!rv) { if (file) fprintf(stderr, "%s:%d: ", file, line); fprintf(stderr, "PortalMat::compare detected a mismatch\n"); } return rv; } void PortalMat::naive_mul(cv::Mat &a, cv::Mat &b, FILE *f) { fprintf(stderr, "a:(%d x %d) b:(%d x %d)", a.rows, a.cols, b.rows, b.cols); assert(a.cols == b.rows); create(a.rows, b.cols, CV_32F); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { double c = 0.0; #ifndef __FOO bool last = (i==(rows-1) && j==(cols-1)); if(last) fprintf(f, "c = 0.0;\n"); for(int l = 0; l < a.cols; l++) { double x = (double)a.at(i,l); double y = (double)b.at(l,j); double p = x*y; if(last){ fprintf(f, "assert(c==%f);\n", c); } c = c + p; if(last){ fprintf(f, "p = %f*%f;\n", x, y); fprintf(f, "assert(p==%f);\n", p); fprintf(f, "c = c + p;\n"); fprintf(f, "disp([c, %f])\n", c); fprintf(f, "assert(c==%f)\n", c); } } at(i, j) = (float)c; if (last) fprintf(f, "rez = %f;\n", c); #else int K = 2; int gatherSz = 8/K; float c_ij[gatherSz]; for(int k = 0; k < gatherSz; k++) c_ij[k] = 0.0; for(int l = 0; l < a.cols; l+=gatherSz) for(int k = 0; k < gatherSz; k++) c_ij[k] += a.at(i,l+k) * b.at(l+k,j); for(int k = 0; k < gatherSz; k++) c += c_ij[k]; at(i, j) = c; #endif } } } #ifdef MATRIX_NT void PortalMat::multf(PortalMat &a, PortalMat &b_transpose, MmIndication *mmind) { create(a.rows, b_transpose.rows, CV_32F); cacheFlushInvalidate(); if (a.cols != b_transpose.cols) { fprintf(stderr, "Mismatched matrices: a.rows=%d a.cols=%d b.rows=%d b.cols=%d\n", a.rows, a.cols, b_transpose.rows, b_transpose.cols); return; } long aref = a.reference(); long bref = b_transpose.reference(); long cref = reference(); if (0) fprintf(stderr, "mult: ref=%d rows=%d cols=%d a.ref=%d a.rows=%d a.cols=%d b.ref=%d b.rows=%d b.cols=%d\n", cref, rows, cols, aref, a.rows, a.cols, bref, b_transpose.rows, b_transpose.cols); mmdevice->mmf(aref, a.rows, a.cols, bref, b_transpose.rows, b_transpose.cols, cref, a.rows*a.cols, a.cols*J_VALUE, b_transpose.rows*b_transpose.cols, b_transpose.cols*K_VALUE, a.rows*b_transpose.rows, b_transpose.rows*J_VALUE); sem_wait(&mul_sem); if(mmind) { int macs = a.rows*a.cols*b_transpose.rows; if (0) fprintf(stderr, "macs %d cycles %f lap_timer %f macs/cycle: %f\n", macs, (float)mmind->ccnt, (float)portalTimerLap(0), ((float)macs)/((float)mmind->ccnt)); } } #else #ifdef MATRIX_TN void PortalMat::multf(PortalMat &a_transpose, PortalMat &b, MmIndication *mmind) { create(a_transpose.cols, b.cols, CV_32F); cacheFlushInvalidate(); if (a_transpose.rows != b.rows) { fprintf(stderr, "Mismatched matrices: a.rows=%d a.cols=%d b.rows=%d b.cols=%d\n", a_transpose.rows, a_transpose.cols, b.rows, b.cols); return; } long aref = a_transpose.reference(); long bref = b.reference(); long cref = reference(); fprintf(stderr, "mult: ref=%ld rows=%d cols=%d a.ref=%ld a.rows=%d a.cols=%d b.ref=%ld b.rows=%d b.cols=%d\n", cref, rows, cols, aref, a_transpose.rows, a_transpose.cols, bref, b.rows, b.cols); mmdevice->mmf(aref, a_transpose.rows, a_transpose.cols, bref, b.rows, b.cols, cref, a_transpose.rows*a_transpose.cols, a_transpose.cols*J_VALUE, a_transpose.rows*b.cols, b.cols*J_VALUE, a_transpose.cols*b.cols, b.rows*b.cols); sem_wait(&mul_sem); if(mmind) { int macs = a_transpose.rows*a_transpose.cols*b.rows; if (0) fprintf(stderr, "macs %d cycles %f lap_timer %f macs/cycle: %f\n", macs, (float)mmind->ccnt, (float)portalTimerLap(0), ((float)macs)/((float)mmind->ccnt)); } } #endif #endif template void dumpMatF(const char *prefix, const char *fmt, const cv::Mat &mat, FILE *ofile) { fprintf(ofile, "%s: rows=%d cols=%d mat=%p\n", prefix, mat.rows, mat.cols, &mat); for (int i = 0; i < mat.rows; i++) { fprintf(ofile, "%s: %03d:", prefix, i); for (int j = 0; j < mat.cols; j++) { fprintf(ofile, " "); fprintf(ofile, fmt, mat.at(i, j)); } fprintf(ofile, "\n"); } } template void dumpMatF(const char *prefix, const char *fmt, const cv::Mat &mat, FILE *ofile); template void dumpMatOctave(const char *name, const char *fmt, const cv::Mat &mat, FILE *ofile) { fprintf(ofile, "%s=[", name); for (int i = 0; i < mat.rows; i++) { for (int j = 0; j < mat.cols; j++) { fprintf(ofile, " "); fprintf(ofile, fmt, mat.at(i, j)); if(j+1 < mat.cols) fprintf(ofile, ","); } if(i+1 < mat.rows) fprintf(ofile, ";"); } fprintf(ofile,"];\n"); } template void dumpMatOctave(const char *name, const char *fmt, const cv::Mat &mat, FILE *ofile); template void dumpMat(const char *prefix, const char *fmt, const cv::Mat &mat) { dumpMatF(prefix,fmt,mat,stderr); } template void dumpMat(const char *prefix, const char *fmt, const cv::Mat &mat); template void dumpMat(const char *prefix, const char *fmt, const cv::Mat &mat); template void dumpMat(const char *prefix, const char *fmt, const cv::Mat &mat); void dynamicRange(cv::Mat mat, int *pmin_exp, int *pmax_exp, float *pmin_val, float *pmax_val) { int min_exp = 0; int max_exp = 0; float min_val = 0.0; float max_val = 0.0; for (int i = 0; i < mat.rows; i++) { for (int j = 0; j < mat.cols; j++) { float f = mat.at(i,j); int exp = 0; //float mantissa = frexpf(f, &exp); min_val = std::min(min_val, f); max_val = std::max(max_val, f); min_exp = std::min(min_exp, exp); max_exp = std::max(max_exp, exp); } } if (pmin_exp) *pmin_exp = min_exp; if (pmax_exp) *pmax_exp = max_exp; if (pmin_val) *pmin_val = min_val; if (pmax_val) *pmax_val = max_val; } ================================================ FILE: lib/matmul/cpp/portalmat.h ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef _PORTALMAT_H_ #define _PORTALMAT_H_ #include #include #include #include #include #include "dmaManager.h" #include "MemServerRequest.h" #include "MMURequest.h" #ifdef MATRIX_NT #include "MmRequestNT.h" extern MmRequestNTProxy *mmdevice; #else #ifdef MATRIX_TN #include "MmRequestTN.h" extern MmRequestTNProxy *mmdevice; #endif #endif #include "MmIndication.h" #include "TimerRequest.h" #include "TimerIndication.h" extern TimerRequestProxy *timerdevice; extern sem_t mul_sem; class PortalMatAllocator : public cv::MatAllocator { public: PortalMatAllocator(DmaManager *dma) : numarrays(1), dma(dma) {} virtual ~PortalMatAllocator() {} virtual void allocate(int dims, const int* sizes, int type, int*& refcount, uchar*& datastart, uchar*& data, size_t* step); virtual void deallocate(int* refcount, uchar* datastart, uchar* data); int reference(int* refcount, uchar* datastart, uchar* data); void cacheFlushInvalidate(int* refcount, uchar* datastart, uchar* data); private: struct arrayInfo { // refcount goes first int refcount; int fd; uchar *data; size_t totalsize; int ref; } arrayInfo[128]; int numarrays; DmaManager *dma; }; extern PortalMatAllocator *matAllocator; class MmIndication; class PortalMat : public cv::Mat { public: PortalMat(); PortalMat(int rows, int cols, int type); PortalMat(int rows, int cols, int type, const cv::Scalar& s); PortalMat(const PortalMat &m); PortalMat(const cv::Mat &m); ~PortalMat(); PortalMat& operator = (const cv::MatExpr& expr); PortalMat& operator = (const cv::Mat& o); int reference(); void cacheFlushInvalidate(); bool copy(cv::Mat &other); bool copy(cv::MatExpr other); bool transpose(cv::Mat &other); bool compare(Mat &other, const char *file=0, int line=0, float epsilon=0.01, Mat *pm = 0, bool verbose = false); void naive_mul(cv::Mat &a, cv::Mat &b, FILE *f); void multf(PortalMat &a, PortalMat &b_transpose, MmIndication *mmind = NULL); }; class MmIndication : public MmIndicationWrapper { public: uint64_t ccnt; MmIndication(int id) : MmIndicationWrapper(id) { ccnt = 0; } virtual ~MmIndication() {} virtual void mmfDone(uint64_t cycles) { ccnt = cycles; fprintf(stderr, "mmfDone cycles=%ld\n", (long)cycles); sem_post(&mul_sem); } void dpsVal(uint32_t v) { fprintf(stderr, "dpsVal v=%x %f\n", v, *(float *)&v); sem_post(&mul_sem); } void started() { fprintf(stderr, "mm.started:\n"); } virtual void startSourceAndSink ( const unsigned int startA, const unsigned int startC, const int jint ) { fprintf(stderr, "mm.startSourceAndSink: startA=%6d startC=%06d jint=%d\n", startA, startC, jint); } virtual void debug ( uint32_t macCount) { fprintf(stderr, "mm.debug: macCount=%d\n", macCount); } }; class TimerIndication : public TimerIndicationWrapper { public: TimerIndication(int id) : TimerIndicationWrapper(id) { } virtual ~TimerIndication() {} virtual void elapsedCycles(uint64_t cycles, uint64_t idleCycles) { fprintf(stderr, "elapsedCycles %lld idle %lld idle %f\n", (long long)cycles, (long long)idleCycles, (double)idleCycles / (double)cycles); } }; template void dumpMat(const char *prefix, const char *fmt, const cv::Mat &mat); template void dumpMatF(const char *prefix, const char *fmt, const cv::Mat &mat, FILE *ofile); template void dumpMatOctave(const char *name, const char *fmt, const cv::Mat &mat, FILE *ofile); void dynamicRange(cv::Mat mat, int *pmin_exp, int *pmax_exp, float *pmin_val=0, float *pmax_val=0); #endif // _PORTALMAT_H_ ================================================ FILE: lib/nandsim/bsv/NandSim.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import GetPut::*; import Vector::*; import BRAM::*; import GetPut::*; import Connectable::*; import ConnectalConfig::*; import ConnectalMemory::*; import Pipe::*; import ConnectalMemTypes::*; import HostInterface::*; import MemReadEngine::*; import MemWriteEngine::*; interface NandCfgRequest; method Action startRead(Bit#(32) drampointer, Bit#(32) dramOffset, Bit#(32) nandAddr, Bit#(32) numBytes, Bit#(32) burstLen); method Action startWrite(Bit#(32) drampointer, Bit#(32) dramOffset, Bit#(32) nandAddr, Bit#(32) numBytes, Bit#(32) burstLen); method Action startErase(Bit#(32) nandAddr, Bit#(32) numBytes); method Action configureNand(Bit#(32) ptr, Bit#(32) numBytes); endinterface interface NandCfgIndication; method Action readDone(Bit#(32) tag); method Action writeDone(Bit#(32) tag); method Action eraseDone(Bit#(32) tag); method Action configureNandDone(); endinterface interface NandSim; interface NandCfgRequest request; interface PhysMemSlave#(PhysAddrWidth,64) memSlave; interface Vector#(1, MemReadClient#(64)) readClient; interface Vector#(1, MemWriteClient#(64)) writeClient; endinterface interface NandSimControl; interface NandCfgRequest request; interface ReadOnly#(Bit#(32)) nandPtr; endinterface module mkNandSim#(NandCfgIndication indication) (NandSim); let verbose = False; MemReadEngine#(64,64,1,3) re <- mkMemReadEngine(); MemWriteEngine#(64,64,1,4) we <- mkMemWriteEngine(); NandSimControl ns <- mkNandSimControl(take(re.readServers), take(we.writeServers), indication); let slave_read_server = re.readServers[2]; let slave_write_server = we.writeServers[3]; FIFO#(Bit#(MemTagSize)) slaveWriteTag <- mkSizedFIFO(1); FIFO#(Bit#(MemTagSize)) slaveReadTag <- mkSizedFIFO(1); Reg#(Bit#(BurstLenSize)) slaveReadCnt <- mkReg(0); interface PhysMemSlave memSlave; interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(PhysAddrWidth,64) req); if (verbose) $display("mkNandSim.memSlave::writeReq %d %d %d", req.addr, req.burstLen, req.tag); slave_write_server.request.put(MemengineCmd{sglId:ns.nandPtr, base:truncate(req.addr), burstLen:req.burstLen, len:extend(req.burstLen), tag: 0}); slaveWriteTag.enq(req.tag); endmethod endinterface interface Put writeData; method Action put(MemData#(64) wdata); slave_write_server.data.enq(wdata.data); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get(); let rv <- slave_write_server.done.get; slaveWriteTag.deq; return slaveWriteTag.first; endmethod endinterface endinterface interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(PhysAddrWidth,64) req) if (slaveReadCnt == 0); if (verbose) $display("mkNandSim.memSlave::readReq %d %d %d", req.addr, req.burstLen, req.tag); slave_read_server.request.put(MemengineCmd{sglId:ns.nandPtr, base:truncate(req.addr), burstLen:req.burstLen, len:extend(req.burstLen), tag: 0}); slaveReadTag.enq(req.tag); slaveReadCnt <= req.burstLen; endmethod endinterface interface Get readData; method ActionValue#(MemData#(64)) get() if (slaveReadCnt != 0); let rv <- toGet(slave_read_server.data).get; let new_slaveReadCnt = slaveReadCnt-8; let last = new_slaveReadCnt==0; slaveReadCnt <= new_slaveReadCnt; if (rv.last) slaveReadTag.deq; if (verbose) $display("mkNandSim.memSlave::readData %d %d %h %d", slaveReadTag.first, last, rv.data, slaveReadCnt); return MemData{data:rv.data, tag:slaveReadTag.first,last:last}; endmethod endinterface endinterface endinterface interface request = ns.request; interface MemReadClient readClient = cons(re.dmaClient, nil); interface MemWriteClient writeClient = cons(we.dmaClient, nil); endmodule module mkNandSimControl#(Vector#(2, MemReadEngineServer#(64)) readSrvs, Vector#(3, MemWriteEngineServer#(64)) writeSrvs, NandCfgIndication indication) (NandSimControl); let dramReadServer = readSrvs[0]; let nandReadServer = readSrvs[1]; let dramWriteServer = writeSrvs[0]; let nandWriteServer = writeSrvs[1]; let nandEraseServer = writeSrvs[2]; Reg#(Maybe#(Bit#(32))) nandPointer <- mkReg(tagged Invalid); Reg#(Bit#(32)) nandLen <- mkReg(0); FIFOF#(Bit#(32)) readReqFifo <- mkFIFOF(); FIFOF#(Bit#(32)) writeReqFifo <- mkFIFOF(); Reg#(Bit#(32)) readCountReg <- mkReg(0); Reg#(Bit#(32)) writeCountReg <- mkReg(0); FIFOF#(Bool) readDoneFifo <- mkFIFOF(); FIFOF#(Bool) writeDoneFifo <- mkFIFOF(); FIFO#(void) dramReadDone <- mkFIFO; FIFO#(void) nandReadDone <- mkFIFO; rule countNandWrite; let v <- toGet(dramReadServer.data).get(); let count = writeCountReg; if (count == 0) count = writeReqFifo.first(); //$display("write v=%h count=%d", v, count); writeSrvs[1].data.enq(v.data); if (count == 8) begin writeReqFifo.deq(); writeDoneFifo.enq(True); end writeCountReg <= count-8; if (v.last) dramReadDone.enq(?); endrule rule countNandRead; let v <- toGet(nandReadServer.data).get(); let count = readCountReg; if (count == 0) count = readReqFifo.first(); //$display("read v=%h count=%d", v, count); writeSrvs[0].data.enq(v.data); if (count == 8) begin readReqFifo.deq(); readDoneFifo.enq(True); end readCountReg <= count-8; if (v.last) nandReadDone.enq(?); endrule PipeOut#(Bit#(64)) erasePipe = (interface PipeOut#(Bit#(64)); method Bit#(64) first(); return fromInteger(-1); endmethod method Action deq(); endmethod method Bool notEmpty(); return True; endmethod endinterface); mkConnection(erasePipe, writeSrvs[2].data); rule eraseDone; let done <- nandEraseServer.done.get(); $display("eraseDone"); indication.eraseDone(0); endrule rule writeDone; let nandWriteDone <- nandWriteServer.done.get(); dramReadDone.deq; let v <- toGet(writeDoneFifo).get(); $display("writeDone"); indication.writeDone(0); endrule rule readDone; nandReadDone.deq; let dramWriteDone <- dramWriteServer.done.get(); let v <- toGet(readDoneFifo).get(); $display("readDone"); indication.readDone(0); endrule interface NandCfgRequest request; /*! * Reads from NAND and writes to DRAM */ method Action startRead(Bit#(32) pointer, Bit#(32) dramOffset, Bit#(32) nandAddr,Bit#(32) numBytes, Bit#(32) burstLen); $display("startRead numBytes=%d burstLen=%d", numBytes, burstLen); readReqFifo.enq(numBytes); nandReadServer.request.put(MemengineCmd {sglId: fromMaybe(0,nandPointer), base: extend(nandAddr), burstLen: truncate(burstLen), len: extend(numBytes), tag: 0}); dramWriteServer.request.put(MemengineCmd {sglId: pointer, base: extend(dramOffset), burstLen: truncate(burstLen), len: extend(numBytes), tag: 0}); endmethod /*! * Reads from DRAM and writes to NAND */ method Action startWrite(Bit#(32) pointer, Bit#(32) dramOffset, Bit#(32) nandAddr,Bit#(32) numBytes, Bit#(32) burstLen); $display("startWrite numBytes=%d burstLen=%d", numBytes, burstLen); writeReqFifo.enq(numBytes); nandWriteServer.request.put(MemengineCmd {sglId: fromMaybe(0,nandPointer), base: extend(nandAddr), burstLen: truncate(burstLen), len: extend(numBytes), tag: 0}); dramReadServer.request.put(MemengineCmd {sglId: pointer, base: extend(dramOffset), burstLen: truncate(burstLen), len: extend(numBytes), tag: 0}); endmethod method Action startErase(Bit#(32) nandAddr, Bit#(32) numBytes); $display("startErase numBytes=%d burstLen=%d", numBytes, 16); nandEraseServer.request.put(MemengineCmd {sglId: fromMaybe(0,nandPointer), base: extend(nandAddr), burstLen: 16, len: extend(numBytes), tag: 0}); endmethod method Action configureNand(Bit#(32) ptr, Bit#(32) numBytes); nandPointer <= tagged Valid ptr; nandLen <= numBytes; indication.configureNandDone(); $display("configureNand ptr=%d", ptr); endmethod endinterface interface ReadOnly nandPtr; method Bit#(32) _read if (isValid(nandPointer)); return fromMaybe(0,nandPointer); endmethod endinterface endmodule ================================================ FILE: lib/nandsim/bsv/NandSimNames.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ typedef enum { IfcNames_MemServerRequestS2H, IfcNames_MemServerIndicationH2S, IfcNames_NandMemServerRequestS2H, IfcNames_NandMemServerIndicationH2S, IfcNames_BackingStoreMMURequestS2H, IfcNames_BackingStoreMMUIndicationH2S, IfcNames_MMURequestS2H, IfcNames_MMUIndicationH2S, IfcNames_AlgoMMURequestS2H, IfcNames_AlgoMMUIndicationH2S, IfcNames_NandMMURequestS2H, IfcNames_NandMMUIndicationH2S, IfcNames_NandCfgRequestS2H, IfcNames_NandCfgIndicationH2S, IfcNames_AlgoRequestS2H, IfcNames_AlgoIndicationH2S } IfcNames deriving (Eq,Bits); ================================================ FILE: lib/nandsim/cpp/nandsim.h ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include static int sockfd = -1; #define SOCK_NAME "socket_for_nandsim" void wait_for_connect_nandsim_exe() { int listening_socket; if ((listening_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "%s: socket error %s",__FUNCTION__, strerror(errno)); exit(1); } struct sockaddr_un local; local.sun_family = AF_UNIX; strcpy(local.sun_path, SOCK_NAME); unlink(local.sun_path); int len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(listening_socket, (struct sockaddr *)&local, len) == -1) { fprintf(stderr, "%s[%d]: bind error %s\n",__FUNCTION__, listening_socket, strerror(errno)); exit(1); } if (listen(listening_socket, 5) == -1) { fprintf(stderr, "%s[%d]: listen error %s\n",__FUNCTION__, listening_socket, strerror(errno)); exit(1); } //fprintf(stderr, "%s[%d]: waiting for a connection...\n",__FUNCTION__, listening_socket); if ((sockfd = accept(listening_socket, NULL, NULL)) == -1) { fprintf(stderr, "%s[%d]: accept error %s\n",__FUNCTION__, listening_socket, strerror(errno)); exit(1); } remove(SOCK_NAME); // we are connected now, so we can remove named socket } unsigned int read_from_nandsim_exe() { unsigned int rv; if(recv(sockfd, &rv, sizeof(rv), 0) == -1){ fprintf(stderr, "%s recv error\n",__FUNCTION__); exit(1); } return rv; } void connect_to_algo_exe(void) { int connect_attempts = 0; if (sockfd != -1) return; if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "%s (%s) socket error %s\n",__FUNCTION__, SOCK_NAME, strerror(errno)); exit(1); } //fprintf(stderr, "%s (%s) trying to connect...\n",__FUNCTION__, SOCK_NAME); struct sockaddr_un local; local.sun_family = AF_UNIX; strcpy(local.sun_path, SOCK_NAME); while (connect(sockfd, (struct sockaddr *)&local, strlen(local.sun_path) + sizeof(local.sun_family)) == -1) { if(connect_attempts++ > 100){ fprintf(stderr,"%s (%s) connect error %s\n",__FUNCTION__, SOCK_NAME, strerror(errno)); exit(1); } fprintf(stderr, "%s (%s) retrying connection\n",__FUNCTION__, SOCK_NAME); sleep(5); } fprintf(stderr, "%s (%s) connected\n",__FUNCTION__, SOCK_NAME); } void write_to_algo_exe(unsigned int x) { int retry = 0; while (retry++ < 10){ if (send(sockfd, &x, sizeof(x), 0) == -1) { fprintf(stderr, "%s send error\n",__FUNCTION__); sleep(1); } else { retry = 0; break; } } if(retry){ fprintf(stderr, "%s send failed\n",__FUNCTION__); exit(1); } } ================================================ FILE: lib/nvme/bsv/AxiPcie3RootPort.bsv ================================================ /* ../../generated/scripts/importbvi.py -I APRP -P APRP -c userclk -r sys_rst_n -r axi_aresetn -c axi_aclk -c axi_ctl_aclk -r axi_ctl_aresetn -c refclk -o AxiPcie3RootPort.bsv cores/vc709/axi_pcie_rp/axi_pcie_rp_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; (* always_ready, always_enabled *) interface AprpAxi; interface Clock aclk; method Reset aresetn(); method Reset ctl_aresetn(); endinterface (* always_ready, always_enabled *) interface AprpCfg; method Bit#(6) ltssm_state(); endinterface (* always_ready, always_enabled *) interface AprpInterrupt; method Bit#(1) out(); endinterface (* always_ready, always_enabled *) interface AprpIntx; method Bit#(1) msi_grant(); method Action msi_request(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AprpM_axi; method Bit#(32) araddr(); method Bit#(2) arburst(); method Bit#(4) arcache(); method Bit#(3) arid(); method Bit#(8) arlen(); method Bit#(1) arlock(); method Bit#(3) arprot(); method Action arready(Bit#(1) v); method Bit#(3) arsize(); method Bit#(1) arvalid(); method Bit#(32) awaddr(); method Bit#(2) awburst(); method Bit#(4) awcache(); method Bit#(3) awid(); method Bit#(8) awlen(); method Bit#(1) awlock(); method Bit#(3) awprot(); method Action awready(Bit#(1) v); method Bit#(3) awsize(); method Bit#(1) awvalid(); method Action bid(Bit#(3) v); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(128) v); method Action rid(Bit#(3) v); method Action rlast(Bit#(1) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action ruser(Bit#(32) v); method Action rvalid(Bit#(1) v); method Bit#(128) wdata(); method Bit#(1) wlast(); method Action wready(Bit#(1) v); method Bit#(16) wstrb(); method Bit#(32) wuser(); method Bit#(1) wvalid(); endinterface (* always_ready, always_enabled *) interface AprpMsi; method Bit#(1) enable(); method Action vector_num(Bit#(5) v); method Bit#(3) vector_width(); endinterface (* always_ready, always_enabled *) interface AprpPci; method Action exp_rxn(Bit#(4) v); method Action exp_rxp(Bit#(4) v); method Bit#(4) exp_txn(); method Bit#(4) exp_txp(); endinterface (* always_ready, always_enabled *) interface AprpS_axi; method Action araddr(Bit#(32) v); method Action arburst(Bit#(2) v); method Action arid(Bit#(4) v); method Action arlen(Bit#(8) v); method Bit#(1) arready(); method Action arregion(Bit#(4) v); method Action arsize(Bit#(3) v); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(32) v); method Action awburst(Bit#(2) v); method Action awid(Bit#(4) v); method Action awlen(Bit#(8) v); method Bit#(1) awready(); method Action awregion(Bit#(4) v); method Action awsize(Bit#(3) v); method Action awvalid(Bit#(1) v); method Bit#(4) bid(); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(128) rdata(); method Bit#(4) rid(); method Bit#(1) rlast(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(32) ruser(); method Bit#(1) rvalid(); method Action wdata(Bit#(128) v); method Action wlast(Bit#(1) v); method Bit#(1) wready(); method Action wstrb(Bit#(16) v); method Action wuser(Bit#(32) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AprpS_axi_ctl; method Action araddr(Bit#(28) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(28) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface AprpUser; method Bit#(1) link_up(); endinterface (* always_ready, always_enabled *) interface APRP; interface AprpAxi axi; interface AprpCfg cfg; interface AprpInterrupt interrupt; interface AprpIntx intx; interface AprpM_axi m_axi; interface AprpMsi msi; interface AprpPci pci; interface AprpS_axi s_axi; interface AprpS_axi_ctl s_axi_ctl; interface AprpUser user; endinterface import "BVI" axi_pcie_rp = module mkAPRP#(Clock axi_aclk_in, Reset axi_aresetn_in, Clock refclk, Reset sys_rst_n)(APRP); default_clock clk(); default_reset rst(); input_clock axi_ctl_aclk(axi_ctl_aclk) = axi_aclk_in; input_clock refclk(refclk) = refclk; input_reset sys_rst_n(sys_rst_n) = sys_rst_n; input_clock axi_aclk_in() = axi_aclk_in; input_reset axi_aresetn_in() clocked_by (axi_aclk_in) = axi_aresetn_in; interface AprpAxi axi; output_clock aclk(axi_aclk); output_reset aresetn(axi_aresetn) clocked_by (axi_aclk_in); output_reset ctl_aresetn(axi_ctl_aresetn) clocked_by (axi_aclk_in); endinterface interface AprpCfg cfg; method cfg_ltssm_state ltssm_state(); endinterface interface AprpInterrupt interrupt; method interrupt_out out() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); endinterface interface AprpIntx intx; method intx_msi_grant msi_grant() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method msi_request(intx_msi_request) enable((*inhigh*) EN_intx_msi_request) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); endinterface interface AprpM_axi m_axi; method m_axi_araddr araddr() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arburst arburst() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arcache arcache() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arid arid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arlen arlen() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arlock arlock() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arprot arprot() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arready(m_axi_arready) enable((*inhigh*) EN_m_axi_arready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arsize arsize() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_arvalid arvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awaddr awaddr() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awburst awburst() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awcache awcache() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awid awid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awlen awlen() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awlock awlock() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awprot awprot() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awready(m_axi_awready) enable((*inhigh*) EN_m_axi_awready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awsize awsize() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_awvalid awvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method bid(m_axi_bid) enable((*inhigh*) EN_m_axi_bid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_bready bready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method bresp(m_axi_bresp) enable((*inhigh*) EN_m_axi_bresp) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method bvalid(m_axi_bvalid) enable((*inhigh*) EN_m_axi_bvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rdata(m_axi_rdata) enable((*inhigh*) EN_m_axi_rdata) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rid(m_axi_rid) enable((*inhigh*) EN_m_axi_rid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rlast(m_axi_rlast) enable((*inhigh*) EN_m_axi_rlast) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_rready rready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rresp(m_axi_rresp) enable((*inhigh*) EN_m_axi_rresp) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method ruser(m_axi_ruser) enable((*inhigh*) EN_m_axi_ruser) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rvalid(m_axi_rvalid) enable((*inhigh*) EN_m_axi_rvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_wdata wdata() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_wlast wlast() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wready(m_axi_wready) enable((*inhigh*) EN_m_axi_wready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_wstrb wstrb() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_wuser wuser() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method m_axi_wvalid wvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); endinterface interface AprpMsi msi; method msi_enable enable() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method vector_num(msi_vector_num) enable((*inhigh*) EN_msi_vector_num) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method msi_vector_width vector_width() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); endinterface interface AprpPci pci; method exp_rxn(pci_exp_rxn) enable((*inhigh*) EN_pci_exp_rxn); method exp_rxp(pci_exp_rxp) enable((*inhigh*) EN_pci_exp_rxp); method pci_exp_txn exp_txn(); method pci_exp_txp exp_txp(); endinterface interface AprpS_axi s_axi; method araddr(s_axi_araddr) enable((*inhigh*) EN_s_axi_araddr) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arburst(s_axi_arburst) enable((*inhigh*) EN_s_axi_arburst) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arid(s_axi_arid) enable((*inhigh*) EN_s_axi_arid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arlen(s_axi_arlen) enable((*inhigh*) EN_s_axi_arlen) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_arready arready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arregion(s_axi_arregion) enable((*inhigh*) EN_s_axi_arregion) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arsize(s_axi_arsize) enable((*inhigh*) EN_s_axi_arsize) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arvalid(s_axi_arvalid) enable((*inhigh*) EN_s_axi_arvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awaddr(s_axi_awaddr) enable((*inhigh*) EN_s_axi_awaddr) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awburst(s_axi_awburst) enable((*inhigh*) EN_s_axi_awburst) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awid(s_axi_awid) enable((*inhigh*) EN_s_axi_awid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awlen(s_axi_awlen) enable((*inhigh*) EN_s_axi_awlen) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_awready awready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awregion(s_axi_awregion) enable((*inhigh*) EN_s_axi_awregion) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awsize(s_axi_awsize) enable((*inhigh*) EN_s_axi_awsize) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awvalid(s_axi_awvalid) enable((*inhigh*) EN_s_axi_awvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_bid bid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method bready(s_axi_bready) enable((*inhigh*) EN_s_axi_bready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_bresp bresp() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_bvalid bvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_rdata rdata() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_rid rid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_rlast rlast() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rready(s_axi_rready) enable((*inhigh*) EN_s_axi_rready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_rresp rresp() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ruser ruser() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_rvalid rvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wdata(s_axi_wdata) enable((*inhigh*) EN_s_axi_wdata) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wlast(s_axi_wlast) enable((*inhigh*) EN_s_axi_wlast) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_wready wready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wstrb(s_axi_wstrb) enable((*inhigh*) EN_s_axi_wstrb) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wuser(s_axi_wuser) enable((*inhigh*) EN_s_axi_wuser) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wvalid(s_axi_wvalid) enable((*inhigh*) EN_s_axi_wvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); endinterface interface AprpS_axi_ctl s_axi_ctl; method araddr(s_axi_ctl_araddr) enable((*inhigh*) EN_s_axi_ctl_araddr) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_arready arready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method arvalid(s_axi_ctl_arvalid) enable((*inhigh*) EN_s_axi_ctl_arvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awaddr(s_axi_ctl_awaddr) enable((*inhigh*) EN_s_axi_ctl_awaddr) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_awready awready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method awvalid(s_axi_ctl_awvalid) enable((*inhigh*) EN_s_axi_ctl_awvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method bready(s_axi_ctl_bready) enable((*inhigh*) EN_s_axi_ctl_bready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_bresp bresp() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_bvalid bvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_rdata rdata() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method rready(s_axi_ctl_rready) enable((*inhigh*) EN_s_axi_ctl_rready) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_rresp rresp() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_rvalid rvalid() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wdata(s_axi_ctl_wdata) enable((*inhigh*) EN_s_axi_ctl_wdata) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method s_axi_ctl_wready wready() clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wstrb(s_axi_ctl_wstrb) enable((*inhigh*) EN_s_axi_ctl_wstrb) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); method wvalid(s_axi_ctl_wvalid) enable((*inhigh*) EN_s_axi_ctl_wvalid) clocked_by (axi_aclk_in) reset_by (axi_aresetn_in); endinterface interface AprpUser user; method user_link_up link_up(); endinterface schedule (cfg.ltssm_state, interrupt.out, intx.msi_grant, intx.msi_request, m_axi.araddr, m_axi.arburst, m_axi.arcache, m_axi.arid, m_axi.arlen, m_axi.arlock, m_axi.arprot, m_axi.arready, m_axi.arsize, m_axi.arvalid, m_axi.awaddr, m_axi.awburst, m_axi.awcache, m_axi.awid, m_axi.awlen, m_axi.awlock, m_axi.awprot, m_axi.awready, m_axi.awsize, m_axi.awvalid, m_axi.bid, m_axi.bready, m_axi.bresp, m_axi.bvalid, m_axi.rdata, m_axi.rid, m_axi.rlast, m_axi.rready, m_axi.rresp, m_axi.ruser, m_axi.rvalid, m_axi.wdata, m_axi.wlast, m_axi.wready, m_axi.wstrb, m_axi.wuser, m_axi.wvalid, msi.enable, msi.vector_num, msi.vector_width, pci.exp_rxn, pci.exp_rxp, pci.exp_txn, pci.exp_txp, s_axi.araddr, s_axi.arburst, s_axi.arid, s_axi.arlen, s_axi.arready, s_axi.arregion, s_axi.arsize, s_axi.arvalid, s_axi.awaddr, s_axi.awburst, s_axi.awid, s_axi.awlen, s_axi.awready, s_axi.awregion, s_axi.awsize, s_axi.awvalid, s_axi.bid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rid, s_axi.rlast, s_axi.rready, s_axi.rresp, s_axi.ruser, s_axi.rvalid, s_axi.wdata, s_axi.wlast, s_axi.wready, s_axi.wstrb, s_axi.wuser, s_axi.wvalid, s_axi_ctl.araddr, s_axi_ctl.arready, s_axi_ctl.arvalid, s_axi_ctl.awaddr, s_axi_ctl.awready, s_axi_ctl.awvalid, s_axi_ctl.bready, s_axi_ctl.bresp, s_axi_ctl.bvalid, s_axi_ctl.rdata, s_axi_ctl.rready, s_axi_ctl.rresp, s_axi_ctl.rvalid, s_axi_ctl.wdata, s_axi_ctl.wready, s_axi_ctl.wstrb, s_axi_ctl.wvalid, user.link_up) CF (cfg.ltssm_state, interrupt.out, intx.msi_grant, intx.msi_request, m_axi.araddr, m_axi.arburst, m_axi.arcache, m_axi.arid, m_axi.arlen, m_axi.arlock, m_axi.arprot, m_axi.arready, m_axi.arsize, m_axi.arvalid, m_axi.awaddr, m_axi.awburst, m_axi.awcache, m_axi.awid, m_axi.awlen, m_axi.awlock, m_axi.awprot, m_axi.awready, m_axi.awsize, m_axi.awvalid, m_axi.bid, m_axi.bready, m_axi.bresp, m_axi.bvalid, m_axi.rdata, m_axi.rid, m_axi.rlast, m_axi.rready, m_axi.rresp, m_axi.ruser, m_axi.rvalid, m_axi.wdata, m_axi.wlast, m_axi.wready, m_axi.wstrb, m_axi.wuser, m_axi.wvalid, msi.enable, msi.vector_num, msi.vector_width, pci.exp_rxn, pci.exp_rxp, pci.exp_txn, pci.exp_txp, s_axi.araddr, s_axi.arburst, s_axi.arid, s_axi.arlen, s_axi.arready, s_axi.arregion, s_axi.arsize, s_axi.arvalid, s_axi.awaddr, s_axi.awburst, s_axi.awid, s_axi.awlen, s_axi.awready, s_axi.awregion, s_axi.awsize, s_axi.awvalid, s_axi.bid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rid, s_axi.rlast, s_axi.rready, s_axi.rresp, s_axi.ruser, s_axi.rvalid, s_axi.wdata, s_axi.wlast, s_axi.wready, s_axi.wstrb, s_axi.wuser, s_axi.wvalid, s_axi_ctl.araddr, s_axi_ctl.arready, s_axi_ctl.arvalid, s_axi_ctl.awaddr, s_axi_ctl.awready, s_axi_ctl.awvalid, s_axi_ctl.bready, s_axi_ctl.bresp, s_axi_ctl.bvalid, s_axi_ctl.rdata, s_axi_ctl.rready, s_axi_ctl.rresp, s_axi_ctl.rvalid, s_axi_ctl.wdata, s_axi_ctl.wready, s_axi_ctl.wstrb, s_axi_ctl.wvalid, user.link_up); endmodule ================================================ FILE: lib/nvme/bsv/AxiPcieRootPort.bsv ================================================ /* ../../generated/scripts/importbvi.py -I APRP -P APRP -r axi_aresetn -c axi_aclk_out -c axi_ctl_aclk_out -c REFCLK -o AxiPcieRootPort.bsv /home/jamey/miniitx100/miniitx100.srcs/sources_1/ip/axi_pcie_0/axi_pcie_0_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import NvmeIfc::*; // for PcieDataBusWidth (* always_ready, always_enabled *) interface AprpAxi; interface Clock aclk_out; interface Clock ctl_aclk_out; endinterface (* always_ready, always_enabled *) interface AprpInterrupt; method Bit#(1) out(); endinterface (* always_ready, always_enabled *) interface AprpIntx; method Bit#(1) msi_grant(); method Action msi_request(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AprpM_axi; method Bit#(32) araddr(); method Bit#(2) arburst(); method Bit#(4) arcache(); method Bit#(8) arlen(); method Bit#(1) arlock(); method Bit#(3) arprot(); method Action arready(Bit#(1) v); method Bit#(3) arsize(); method Bit#(1) arvalid(); method Bit#(32) awaddr(); method Bit#(2) awburst(); method Bit#(4) awcache(); method Bit#(8) awlen(); method Bit#(1) awlock(); method Bit#(3) awprot(); method Action awready(Bit#(1) v); method Bit#(3) awsize(); method Bit#(1) awvalid(); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(PcieDataBusWidth) v); method Action rlast(Bit#(1) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action rvalid(Bit#(1) v); method Bit#(PcieDataBusWidth) wdata(); method Bit#(1) wlast(); method Action wready(Bit#(1) v); method Bit#(TDiv#(PcieDataBusWidth,8)) wstrb(); method Bit#(1) wvalid(); endinterface (* always_ready, always_enabled *) interface AprpMmcm; method Bit#(1) lock(); endinterface (* always_ready, always_enabled *) interface AprpMsi; method Bit#(1) enable(); method Action vector_num(Bit#(5) v); method Bit#(3) vector_width(); endinterface (* always_ready, always_enabled *) interface AprpPci; method Action exp_rxn(Bit#(4) v); method Action exp_rxp(Bit#(4) v); method Bit#(4) exp_txn(); method Bit#(4) exp_txp(); endinterface (* always_ready, always_enabled *) interface AprpS_axi; method Action araddr(Bit#(32) v); method Action arburst(Bit#(2) v); method Action arid(Bit#(4) v); method Action arlen(Bit#(8) v); method Bit#(1) arready(); method Action arregion(Bit#(4) v); method Action arsize(Bit#(3) v); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(32) v); method Action awburst(Bit#(2) v); method Action awid(Bit#(4) v); method Action awlen(Bit#(8) v); method Bit#(1) awready(); method Action awregion(Bit#(4) v); method Action awsize(Bit#(3) v); method Action awvalid(Bit#(1) v); method Bit#(4) bid(); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(PcieDataBusWidth) rdata(); method Bit#(4) rid(); method Bit#(1) rlast(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(PcieDataBusWidth) v); method Action wlast(Bit#(1) v); method Bit#(1) wready(); method Action wstrb(Bit#(TDiv#(PcieDataBusWidth,8)) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AprpS_axi_ctl; method Action araddr(Bit#(32) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(32) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface APRP; interface AprpAxi axi; interface AprpInterrupt interrupt; interface AprpIntx intx; interface AprpM_axi m_axi; interface AprpMmcm mmcm; interface AprpMsi msi; interface AprpPci pci; interface AprpS_axi s_axi; interface AprpS_axi_ctl s_axi_ctl; endinterface import "BVI" axi_pcie_rp = module mkAPRP#(Clock refclk, Reset reset, Clock axi_aclk, Reset axi_aresetn, Clock axi_ctl_aclk, Reset axi_ctl_aresetn)(APRP); default_clock clk(); default_reset rst(); input_clock axi_aclk() = axi_aclk; input_clock axi_ctl_aclk() = axi_ctl_aclk; input_reset reset(axi_aresetn) = reset; input_reset axi_aresetn() clocked_by (axi_aclk) = axi_aresetn; input_reset axi_ctl_aresetn() clocked_by (axi_ctl_aclk) = axi_ctl_aresetn; input_clock refclk(REFCLK) = refclk; interface AprpAxi axi; output_clock aclk_out(axi_aclk_out); output_clock ctl_aclk_out(axi_ctl_aclk_out); endinterface interface AprpInterrupt interrupt; method interrupt_out out(); endinterface interface AprpIntx intx; method INTX_MSI_Grant msi_grant(); method msi_request(INTX_MSI_Request) enable((*inhigh*) EN_INTX_MSI_Request); endinterface interface AprpM_axi m_axi; method m_axi_araddr araddr(); method m_axi_arburst arburst(); method m_axi_arcache arcache(); method m_axi_arlen arlen(); method m_axi_arlock arlock(); method m_axi_arprot arprot(); method arready(m_axi_arready) enable((*inhigh*) EN_m_axi_arready); method m_axi_arsize arsize(); method m_axi_arvalid arvalid(); method m_axi_awaddr awaddr(); method m_axi_awburst awburst(); method m_axi_awcache awcache(); method m_axi_awlen awlen(); method m_axi_awlock awlock(); method m_axi_awprot awprot(); method awready(m_axi_awready) enable((*inhigh*) EN_m_axi_awready); method m_axi_awsize awsize(); method m_axi_awvalid awvalid(); method m_axi_bready bready(); method bresp(m_axi_bresp) enable((*inhigh*) EN_m_axi_bresp); method bvalid(m_axi_bvalid) enable((*inhigh*) EN_m_axi_bvalid); method rdata(m_axi_rdata) enable((*inhigh*) EN_m_axi_rdata); method rlast(m_axi_rlast) enable((*inhigh*) EN_m_axi_rlast); method m_axi_rready rready(); method rresp(m_axi_rresp) enable((*inhigh*) EN_m_axi_rresp); method rvalid(m_axi_rvalid) enable((*inhigh*) EN_m_axi_rvalid); method m_axi_wdata wdata(); method m_axi_wlast wlast(); method wready(m_axi_wready) enable((*inhigh*) EN_m_axi_wready); method m_axi_wstrb wstrb(); method m_axi_wvalid wvalid(); endinterface interface AprpMmcm mmcm; method mmcm_lock lock(); endinterface interface AprpMsi msi; method MSI_enable enable(); method vector_num(MSI_Vector_Num) enable((*inhigh*) EN_MSI_Vector_Num); method MSI_Vector_Width vector_width(); endinterface interface AprpPci pci; method exp_rxn(pci_exp_rxn) enable((*inhigh*) EN_pci_exp_rxn); method exp_rxp(pci_exp_rxp) enable((*inhigh*) EN_pci_exp_rxp); method pci_exp_txn exp_txn(); method pci_exp_txp exp_txp(); endinterface interface AprpS_axi s_axi; method araddr(s_axi_araddr) enable((*inhigh*) EN_s_axi_araddr) clocked_by(axi_aclk) reset_by (axi_aresetn); method arburst(s_axi_arburst) enable((*inhigh*) EN_s_axi_arburst) clocked_by(axi_aclk) reset_by (axi_aresetn); method arid(s_axi_arid) enable((*inhigh*) EN_s_axi_arid) clocked_by(axi_aclk) reset_by (axi_aresetn); method arlen(s_axi_arlen) enable((*inhigh*) EN_s_axi_arlen) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_arready arready() clocked_by(axi_aclk) reset_by (axi_aresetn); method arregion(s_axi_arregion) enable((*inhigh*) EN_s_axi_arregion) clocked_by(axi_aclk) reset_by (axi_aresetn); method arsize(s_axi_arsize) enable((*inhigh*) EN_s_axi_arsize) clocked_by(axi_aclk) reset_by (axi_aresetn); method arvalid(s_axi_arvalid) enable((*inhigh*) EN_s_axi_arvalid) clocked_by(axi_aclk) reset_by (axi_aresetn); method awaddr(s_axi_awaddr) enable((*inhigh*) EN_s_axi_awaddr) clocked_by(axi_aclk) reset_by (axi_aresetn); method awburst(s_axi_awburst) enable((*inhigh*) EN_s_axi_awburst) clocked_by(axi_aclk) reset_by (axi_aresetn); method awid(s_axi_awid) enable((*inhigh*) EN_s_axi_awid) clocked_by(axi_aclk) reset_by (axi_aresetn); method awlen(s_axi_awlen) enable((*inhigh*) EN_s_axi_awlen) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_awready awready() clocked_by(axi_aclk) reset_by (axi_aresetn); method awregion(s_axi_awregion) enable((*inhigh*) EN_s_axi_awregion) clocked_by(axi_aclk) reset_by (axi_aresetn); method awsize(s_axi_awsize) enable((*inhigh*) EN_s_axi_awsize) clocked_by(axi_aclk) reset_by (axi_aresetn); method awvalid(s_axi_awvalid) enable((*inhigh*) EN_s_axi_awvalid) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_bid bid() clocked_by(axi_aclk) reset_by (axi_aresetn); method bready(s_axi_bready) enable((*inhigh*) EN_s_axi_bready) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_bresp bresp() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_bvalid bvalid() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rdata rdata() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rid rid() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rlast rlast() clocked_by(axi_aclk) reset_by (axi_aresetn); method rready(s_axi_rready) enable((*inhigh*) EN_s_axi_rready) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rresp rresp() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rvalid rvalid() clocked_by(axi_aclk) reset_by (axi_aresetn); method wdata(s_axi_wdata) enable((*inhigh*) EN_s_axi_wdata) clocked_by(axi_aclk) reset_by (axi_aresetn); method wlast(s_axi_wlast) enable((*inhigh*) EN_s_axi_wlast) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_wready wready() clocked_by(axi_aclk) reset_by (axi_aresetn); method wstrb(s_axi_wstrb) enable((*inhigh*) EN_s_axi_wstrb) clocked_by(axi_aclk) reset_by (axi_aresetn); method wvalid(s_axi_wvalid) enable((*inhigh*) EN_s_axi_wvalid) clocked_by(axi_aclk) reset_by (axi_aresetn); endinterface interface AprpS_axi_ctl s_axi_ctl; method araddr(s_axi_ctl_araddr) enable((*inhigh*) EN_s_axi_ctl_araddr) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_arready arready() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method arvalid(s_axi_ctl_arvalid) enable((*inhigh*) EN_s_axi_ctl_arvalid) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method awaddr(s_axi_ctl_awaddr) enable((*inhigh*) EN_s_axi_ctl_awaddr) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_awready awready() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method awvalid(s_axi_ctl_awvalid) enable((*inhigh*) EN_s_axi_ctl_awvalid) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method bready(s_axi_ctl_bready) enable((*inhigh*) EN_s_axi_ctl_bready) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_bresp bresp() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_bvalid bvalid() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_rdata rdata() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method rready(s_axi_ctl_rready) enable((*inhigh*) EN_s_axi_ctl_rready) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_rresp rresp() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_rvalid rvalid() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method wdata(s_axi_ctl_wdata) enable((*inhigh*) EN_s_axi_ctl_wdata) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_wready wready() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method wstrb(s_axi_ctl_wstrb) enable((*inhigh*) EN_s_axi_ctl_wstrb) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method wvalid(s_axi_ctl_wvalid) enable((*inhigh*) EN_s_axi_ctl_wvalid) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); endinterface schedule (interrupt.out, intx.msi_grant, intx.msi_request, m_axi.araddr, m_axi.arburst, m_axi.arcache, m_axi.arlen, m_axi.arlock, m_axi.arprot, m_axi.arready, m_axi.arsize, m_axi.arvalid, m_axi.awaddr, m_axi.awburst, m_axi.awcache, m_axi.awlen, m_axi.awlock, m_axi.awprot, m_axi.awready, m_axi.awsize, m_axi.awvalid, m_axi.bready, m_axi.bresp, m_axi.bvalid, m_axi.rdata, m_axi.rlast, m_axi.rready, m_axi.rresp, m_axi.rvalid, m_axi.wdata, m_axi.wlast, m_axi.wready, m_axi.wstrb, m_axi.wvalid, mmcm.lock, msi.enable, msi.vector_num, msi.vector_width, pci.exp_rxn, pci.exp_rxp, pci.exp_txn, pci.exp_txp, s_axi.araddr, s_axi.arburst, s_axi.arid, s_axi.arlen, s_axi.arready, s_axi.arregion, s_axi.arsize, s_axi.arvalid, s_axi.awaddr, s_axi.awburst, s_axi.awid, s_axi.awlen, s_axi.awready, s_axi.awregion, s_axi.awsize, s_axi.awvalid, s_axi.bid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rid, s_axi.rlast, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wlast, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axi_ctl.araddr, s_axi_ctl.arready, s_axi_ctl.arvalid, s_axi_ctl.awaddr, s_axi_ctl.awready, s_axi_ctl.awvalid, s_axi_ctl.bready, s_axi_ctl.bresp, s_axi_ctl.bvalid, s_axi_ctl.rdata, s_axi_ctl.rready, s_axi_ctl.rresp, s_axi_ctl.rvalid, s_axi_ctl.wdata, s_axi_ctl.wready, s_axi_ctl.wstrb, s_axi_ctl.wvalid) CF (interrupt.out, intx.msi_grant, intx.msi_request, m_axi.araddr, m_axi.arburst, m_axi.arcache, m_axi.arlen, m_axi.arlock, m_axi.arprot, m_axi.arready, m_axi.arsize, m_axi.arvalid, m_axi.awaddr, m_axi.awburst, m_axi.awcache, m_axi.awlen, m_axi.awlock, m_axi.awprot, m_axi.awready, m_axi.awsize, m_axi.awvalid, m_axi.bready, m_axi.bresp, m_axi.bvalid, m_axi.rdata, m_axi.rlast, m_axi.rready, m_axi.rresp, m_axi.rvalid, m_axi.wdata, m_axi.wlast, m_axi.wready, m_axi.wstrb, m_axi.wvalid, mmcm.lock, msi.enable, msi.vector_num, msi.vector_width, pci.exp_rxn, pci.exp_rxp, pci.exp_txn, pci.exp_txp, s_axi.araddr, s_axi.arburst, s_axi.arid, s_axi.arlen, s_axi.arready, s_axi.arregion, s_axi.arsize, s_axi.arvalid, s_axi.awaddr, s_axi.awburst, s_axi.awid, s_axi.awlen, s_axi.awready, s_axi.awregion, s_axi.awsize, s_axi.awvalid, s_axi.bid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rid, s_axi.rlast, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wlast, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axi_ctl.araddr, s_axi_ctl.arready, s_axi_ctl.arvalid, s_axi_ctl.awaddr, s_axi_ctl.awready, s_axi_ctl.awvalid, s_axi_ctl.bready, s_axi_ctl.bresp, s_axi_ctl.bvalid, s_axi_ctl.rdata, s_axi_ctl.rready, s_axi_ctl.rresp, s_axi_ctl.rvalid, s_axi_ctl.wdata, s_axi_ctl.wready, s_axi_ctl.wstrb, s_axi_ctl.wvalid); endmodule ================================================ FILE: lib/nvme/bsv/Nvme.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Arbitrate::*; import BRAM::*; import BRAMFIFO::*; import BuildVector::*; import Clocks::*; import Connectable::*; import FIFOF::*; import Gearbox::*; import GetPut::*; import Probe::*; import StmtFSM::*; import Vector::*; import AddressGenerator::*; import AxiBits::*; import AxiStream::*; import ConnectalClocks::*; import ConnectalConfig::*; import DefaultValue::*; import GearboxGetPut::*; import GetPutWithClocks::*; import HostInterface::*; import MemReadEngine::*; import ConnectalMemTypes::*; import PhysMemSlaveFromBram::*; import Pipe::*; import TraceMemClient::*; import XilinxCells::*; `include "ConnectalProjectConfig.bsv" `ifndef PCIE3 import AxiPcieRootPort::*; `else import AxiPcie3RootPort::*; `endif import NvmeIfc::*; import NvmePins::*; `ifndef TOP_SOURCES_PORTAL_CLOCK import ConnectalBramFifo::*; `else import BRAMFIFO::*; module mkDualClockBramFIFOF#(Clock clock1, Reset reset1, Clock clock2, Reset reset2)(FIFOF#(a)) provisos (Bits#(a, asz), Add#(1, a__, asz)); FIFOF#(a) fifo <- mkSizedBRAMFIFOF(512, clocked_by clock1, reset_by reset1); return fifo; endmodule `endif function PipeIn#(t) sinkPipe(); return (interface PipeIn#(a); method Action enq(t v); endmethod method Bool notFull(); return False; endmethod endinterface); endfunction instance ArbRequestTC#(BRAMRequest#(a,b)); function Bool isReadRequest(BRAMRequest#(a,b) x); return !x.write; endfunction function Bool isWriteRequest(BRAMRequest#(a,b) x); return x.write; endfunction endinstance interface Nvme; interface NvmeRequest request; interface NvmeDriverRequest driverRequest; interface MemServerPortalRequest bramRequest; interface NvmeTrace trace; interface NvmePins pins; `ifndef NVME_ACCELERATOR_INTERFACE interface PipeIn#(MemData#(PcieDataBusWidth)) dataToNvme; interface PipeOut#(MemData#(PcieDataBusWidth)) dataFromNvme; `endif interface Vector#(1, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaWriteClient; `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource; `endif endinterface module mkNvme#(NvmeIndication nvmeInd, NvmeDriverIndication driverInd, NvmeTrace trace, MemServerPortalIndication bramIndication)(Nvme); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; let refclk_p <- mkB2C1(); let refclk_n <- mkB2C1(); let pcie_clk_100mhz_buf <- mkClockIBUFDS_GTE2( `ifdef ClockDefaultParam defaultValue, `endif True, refclk_p.c, refclk_n.c); `ifndef TOP_SOURCES_PORTAL_CLOCK let axiClockB2C <- mkB2C1(); let axiCtlClockB2C <- mkB2C1(); let axiClock = axiClockB2C.c; let axiCtlClock = axiClock; //axiCtlClockB2C.c; let axiReset <- mkSyncReset(10, reset, axiClock); let axiCtlReset = axiReset; //mkSyncReset(10, reset, axiCtlClock); `else let axiClock = clock; let axiCtlClock = clock; let axiReset = reset; let axiCtlReset = reset; `endif Reg#(Bool) inSetup <- mkReg(False); Reg#(Bit#(8)) sysResetCount <- mkReg(0); Reg#(Bit#(8)) nvmeResetCount <- mkReg(0); `ifndef PCIE3 let axiRootPort <- mkAPRP(pcie_clk_100mhz_buf, reset, axiClock, axiReset, axiCtlClock, axiCtlReset); `ifndef TOP_SOURCES_PORTAL_CLOCK let axiClockC2B <- mkC2B(axiRootPort.axi.aclk_out); rule rl_connect_clocks; axiClockB2C.inputclock(axiClockC2B.o); axiCtlClockB2C.inputclock(axiClockC2B.o); endrule `endif `else let sys_rst_n <- mkReset(10, True, clock); let nvme_rst_n <- mkReset(10, True, clock); let axiRootPort <- mkAPRP(axiClock, axiReset, pcie_clk_100mhz_buf, sys_rst_n.new_rst); let axiClockC2B <- mkC2B(axiRootPort.axi.aclk); rule rl_connect_clocks; axiClockB2C.inputclock(axiClockC2B.o); axiCtlClockB2C.inputclock(axiClockC2B.o); endrule rule rl_sys_reset if (sysResetCount > 0); sys_rst_n.assertReset(); sysResetCount <= sysResetCount - 1; endrule rule rl_nvme_reset if (nvmeResetCount > 0); nvme_rst_n.assertReset(); nvmeResetCount <= nvmeResetCount - 1; endrule `endif FIFOF#(Bit#(32)) dfifoCtl <- mkFIFOF(); Axi4SlaveBits#(32,PcieDataBusWidth,4,Empty) axiRootPortSlave = toAxi4SlaveBits(axiRootPort.s_axi); Axi4SlaveLiteBits#(32,32) axiRootPortSlaveCtl = toAxi4SlaveBits(axiRootPort.s_axi_ctl); PhysMemSlave#(32,PcieDataBusWidth) axiRootPortMemSlave <- mkPhysMemSlave(axiRootPortSlave, clocked_by axiClock, reset_by axiReset); PhysMemSlave#(32,32) axiRootPortMemSlaveCtl <- mkPhysMemSlave(axiRootPortSlaveCtl, clocked_by axiCtlClock, reset_by axiCtlReset); FIFOF#(PhysMemRequest#(32,PcieDataBusWidth)) araddrFifo <- mkFIFOF(); FIFOF#(PhysMemRequest#(32,PcieDataBusWidth)) awaddrFifo <- mkFIFOF(); FIFOF#(MemData#(PcieDataBusWidth)) rdataFifo <- mkFIFOF(); FIFOF#(MemData#(PcieDataBusWidth)) wdataFifo <- mkFIFOF(); FIFOF#(Bit#(6)) doneFifo <- mkFIFOF(); `ifndef PCIE let axiRootArAddrCnx <- mkConnection(toGet(araddrFifo), axiRootPortMemSlave.read_server.readReq); let axiRootAwAddrCnx <- mkConnection(toGet(awaddrFifo), axiRootPortMemSlave.write_server.writeReq); let axiRootRDataCnx <- mkConnection(axiRootPortMemSlave.read_server.readData, toPut(rdataFifo)); let axiRootWDataCnx <- mkConnection(toGet(wdataFifo), axiRootPortMemSlave.write_server.writeData); let axiRootWDoneCnx <- mkConnection(axiRootPortMemSlave.write_server.writeDone, toPut(doneFifo)); `else let axiRootArAddrCnx <- GetPutWithClocks::mkConnectionWithClocks(clock, reset, axiClock, axiReset, toPipeOut(araddrFifo), axiRootPortMemSlave.read_server.readReq); let axiRootAwAddrCnx <- GetPutWithClocks::mkConnectionWithClocks(clock, reset, axiClock, axiReset, toPipeOut(awaddrFifo), axiRootPortMemSlave.write_server.writeReq); let axiRootRDataCnx <- GetPutWithClocks::mkConnectionWithClocks(axiClock, axiReset, clock, reset, axiRootPortMemSlave.read_server.readData, toPipeIn(rdataFifo)); let axiRootWDataCnx <- GetPutWithClocks::mkConnectionWithClocks(clock, reset, axiClock, axiReset, toPipeOut(wdataFifo), axiRootPortMemSlave.write_server.writeData); let axiRootWDoneCnx <- GetPutWithClocks::mkConnectionWithClocks(axiClock, axiReset, clock, reset, axiRootPortMemSlave.write_server.writeDone, toPipeIn(doneFifo)); `endif rule rl_rdata if (!inSetup); let rdata <- toGet(rdataFifo).get(); if (rdata.tag == 0) driverInd.readDone(truncate(rdata.data)); endrule rule rl_writeDone if (!inSetup); let tag <- toGet(doneFifo).get(); if (tag == 0) driverInd.writeDone(); endrule FIFOF#(PhysMemRequest#(32,32)) araddrFifoCtl <- mkFIFOF(); FIFOF#(PhysMemRequest#(32,32)) awaddrFifoCtl <- mkFIFOF(); FIFOF#(MemData#(32)) rdataFifoCtl <- mkFIFOF(); FIFOF#(MemData#(32)) wdataFifoCtl <- mkFIFOF(); FIFOF#(Bit#(6)) doneFifoCtl <- mkFIFOF(); `ifndef PCIE let axiCtlArAddrCnx <- mkConnection(toGet(araddrFifoCtl), axiRootPortMemSlaveCtl.read_server.readReq); let axiCtlAwAddrCnx <- mkConnection(toGet(awaddrFifoCtl), axiRootPortMemSlaveCtl.write_server.writeReq); let axiCtlRDataCnx <- mkConnection(axiRootPortMemSlaveCtl.read_server.readData, toPut(rdataFifoCtl)); let axiCtlWDataCnx <- mkConnection(toGet(wdataFifoCtl), axiRootPortMemSlaveCtl.write_server.writeData); let axiCtlDoneCnx <- mkConnection(axiRootPortMemSlaveCtl.write_server.writeDone, toPut(doneFifoCtl)); `else let axiCtlArAddrCnx <- GetPutWithClocks::mkConnectionWithClocks(clock, reset, axiClock, axiReset, toPipeOut(araddrFifoCtl), axiRootPortMemSlaveCtl.read_server.readReq); let axiCtlAwAddrCnx <- GetPutWithClocks::mkConnectionWithClocks(clock, reset, axiClock, axiReset, toPipeOut(awaddrFifoCtl), axiRootPortMemSlaveCtl.write_server.writeReq); let axiCtlRDataCnx <- GetPutWithClocks::mkConnectionWithClocks(axiClock, axiReset, clock, reset, axiRootPortMemSlaveCtl.read_server.readData, toPipeIn(rdataFifoCtl)); let axiCtlWDataCnx <- GetPutWithClocks::mkConnectionWithClocks(clock, reset, axiClock, axiReset, toPipeOut(wdataFifoCtl), axiRootPortMemSlaveCtl.write_server.writeData); let axiCtlWDoneCnx <- GetPutWithClocks::mkConnectionWithClocks(axiClock, axiReset, clock, reset, axiRootPortMemSlaveCtl.write_server.writeDone, toPipeIn(doneFifoCtl)); `endif rule rl_rdata_ctl if (!inSetup); let rdata <- toGet(rdataFifoCtl).get(); driverInd.readDone(extend(rdata.data)); endrule rule rl_writeDone_ctl if (!inSetup); let tag <- toGet(doneFifoCtl).get(); driverInd.writeDone(); endrule let requestSize = 64; let responseSize = 16; let bytesPerEntry = valueOf(TDiv#(PcieDataBusWidth,8)); let wordsPerEntry = valueOf(TDiv#(PcieDataBusWidth,32)); BRAM_Configure bramConfig = defaultValue; bramConfig.latency = 2; bramConfig.memorySize = 4096*4/bytesPerEntry; // 4 pages BRAM2Port#(Bit#(32),Bit#(PcieDataBusWidth)) bram <- mkBRAM2Server(bramConfig); let arbIfc <- mkFixedPriority(); Arbiter#(4, BRAMRequest#(Bit#(32),Bit#(PcieDataBusWidth)),Bit#(PcieDataBusWidth)) arbiter <- mkArbiter(arbIfc,2); let arbCnx <- mkConnection(arbiter.master, bram.portB); MemServer#(PcieDataBusWidth) bramMemA <- mkMemServerFromBram(bram.portA); PhysMemSlave#(32,PcieDataBusWidth) bramMemB <- mkPhysMemSlaveFromBram(arbiter.users[0]); MemServerPortal bramMemServerPortal <- mkPhysMemSlavePortal(bramMemB,bramIndication); let portB1 = arbiter.users[1]; let portB2 = arbiter.users[2]; let portB3 = arbiter.users[3]; // was 18 Vector#(1,Tuple3#(Bit#(2), Bit#(32),Bit#(PcieDataBusWidth))) initCtlValues = vec( // tuple3(0, 32'h00000004, 'h00000147) // ,tuple3(0, 32'h00000018, 'h00070100) // ,tuple3(0, 32'h00000010, 'h00000000) // Bridge BAR0 // ,tuple3(0, 32'h00000014, 'h00000000) // Bridge BAR1 // ,tuple3(0, 32'h00100004, 'h00000147) // enable card I/O, Memory, bus master, parity and SERR // ,tuple3(0, 32'h00100010, 'h00000000) // Card BAR0 // ,tuple3(0, 32'h00100014, 'h00000000) // Card BAR1 // ,tuple3(0, 32'h00100018, 'h02200000) // Card BAR2 // ,tuple3(0, 32'h0010001c, 'h00000000) // Card BAR3 // ,tuple3(0, 32'h00000148, 'h00000001) // enable bridge // ,tuple3(0, 32'h00000140, 'h00010000) // enable bridge // ,tuple3(1, 32'h00000014, 'h00460000) // ,tuple3(1, 0, 0) // skip the rest for now // ,tuple3(1, 32'h00000028, 'h00000000) // admin submission queue in BRAM // ,tuple3(1, 32'h00000030, 'h00000000) // admin response queue in BRAM // ,tuple3(1, 32'h00000024, 'h003f003f) // queue sizes? // ,tuple3(1, 32'h00000014, 'h00460001) // enable the admin queues //, tuple3(1, 0, 0)); let index <- mkReg(0); let kindReg <- mkReg(0); let addrReg <- mkReg(0); let dataReg <- mkReg(0); let setupFsm <- mkFSMWithPred(seq index <= 0; while (tpl_2(initCtlValues[index]) != 32'h0) seq action match { .kind, .addr, .data } = initCtlValues[index]; kindReg <= kind; addrReg <= addr; dataReg <= data; endaction action let kind = kindReg; let addr = addrReg; let data = dataReg; if (kind == 0) awaddrFifoCtl.enq(PhysMemRequest {addr: addr, burstLen: 4, tag: index }); if (kind == 1) awaddrFifo.enq(PhysMemRequest {addr: addr, burstLen: 4, tag: index }); if (kind == 2) portB3.request.put(BRAMRequest { address: addr, write: True, responseOnWrite: True, datain: data }); endaction action //match { .kind, .addr, .data } = initCtlValues[index]; let kind = kindReg; let addr = addrReg; let data = dataReg; if (kind == 0) wdataFifoCtl.enq(MemData {data: truncate(data), tag: index, last: True }); if (kind == 1) wdataFifo.enq(MemData {data: data, tag: index, last: True }); endaction action //match { .kind, .addr, .data } = initCtlValues[index]; let kind = kindReg; let addr = addrReg; let data = dataReg; let tag = 0; if (kind == 0) doneFifoCtl.deq(); if (kind == 1) doneFifo.deq(); if (kind == 2) tag <- portB3.response.get(); index <= index + 1; endaction endseq driverInd.setupDone(); inSetup <= False; endseq, inSetup); Axi4MasterBits#(32,PcieDataBusWidth,MemTagSize,Empty) m_axi_mm = toAxi4MasterBits(axiRootPort.m_axi); let getObjId = (interface GetObjId; method SGLId objId(Bit#(32) addr); return extend(addr[31:24]); endmethod method Bit#(MemOffsetSize) addr(Bit#(32) axiAddr); return extend(axiAddr[23:0]); endmethod endinterface); let memReadClient <- mkMemReadClient(getObjId, m_axi_mm); let memWriteClient <- mkMemWriteClient(getObjId, m_axi_mm); Reg#(Bool) traceEnabled <- mkReg(False); FIFOF#(Tuple4#(DmaChannel,Bool,MemRequest,Bit#(32))) traceFifo <- mkSizedBRAMFIFOF(128); PipeIn#(Tuple4#(DmaChannel,Bool,MemRequest,Bit#(32))) tracePipe = traceEnabled ? toPipeIn(traceFifo) : sinkPipe(); FIFOF#(Tuple4#(DmaChannel,Bool,MemData#(PcieDataBusWidth),Bit#(32))) traceDataFifo <- mkSizedBRAMFIFOF(128); PipeIn#(Tuple4#(DmaChannel,Bool,MemData#(PcieDataBusWidth),Bit#(32))) traceDataPipe = traceEnabled ? toPipeIn(traceDataFifo) : sinkPipe(); FIFOF#(Tuple2#(DmaChannel,Bit#(32))) traceDoneFifo <- mkSizedBRAMFIFOF(128); PipeIn#(Tuple2#(DmaChannel,Bit#(32))) traceDonePipe = traceEnabled ? toPipeIn(traceDoneFifo) : sinkPipe(); rule rl_trace1; match { .chan, .write, .req, .timestamp } <- toGet(traceFifo).get(); trace.traceDmaRequest(chan, write, truncate(req.sglId), truncate(req.offset), extend(req.burstLen), extend(req.tag), timestamp); endrule rule rl_trace_data; match { .chan, .write, .md, .timestamp } <- toGet(traceDataFifo).get(); trace.traceDmaData(chan, write, unpack(md.data), md.last, extend(md.tag), timestamp); endrule rule rl_trace_done; match { .chan, .timestamp } <- toGet(traceDoneFifo).get(); trace.traceDmaDone(chan, 0, timestamp); endrule let traceReadClient <- mkTraceReadClient(tracePipe,traceDataPipe,DMA_TX,memReadClient); let traceWriteClient <- mkTraceWriteClient(tracePipe,traceDataPipe,traceDonePipe,DMA_RX,memWriteClient); let traceClient = (interface MemClient#(PcieDataBusWidth); interface readClient = traceReadClient; interface writeClient = traceWriteClient; endinterface); SplitMemServer#(PcieDataBusWidth) splitter <- mkSplitMemServer(); MemServerGearbox#(PcieDataBusWidth,DataBusWidth) axiGearbox <- mk1toNMemServerGearbox(); let gearboxCnx <- mkConnection(splitter.busClient, axiGearbox.server); Reg#(Bit#(16)) requestId <- mkReg(0); Reg#(Bit#(16)) responseId <- mkReg(0); Reg#(Bit#(16)) requestQueueEntryCount <- mkReg(8); Reg#(Bool) requestSlotAvailable <- mkReg(True); Reg#(Bool) requestInProgress <- mkReg(True); Reg#(Vector#(16,Bit#(32))) ioCommand <- mkReg(unpack(0)); Reg#(Bit#(32)) requestStartTimestamp <- mkReg(0); FIFOF#(NvmeIoCommand) ioCommandFifo <- mkFIFOF(); FIFOF#(NvmeIoCommand) ioSegmentFifo <- mkFIFOF(); // max request size 32 `ifdef NVME_ACCELERATOR_INTERFACE FIFOF#(NvmeIoCommand) ioCommandFifoAccel <- mkFIFOF(); FIFOF#(NvmeIoResponse) ioResponseFifoAccel <- mkFIFOF(); `endif FIFOF#(Bit#(1)) ioCommandSourceFifo <- mkFIFOF(); FIFOF#(Bit#(1)) ioSegmentSourceFifo <- mkFIFOF(); FIFOF#(Bit#(1)) ioResponseSourceFifo <- mkSizedFIFOF(8); Reg#(Bit#(32)) cycles <- mkReg(0); rule rl_cycles; cycles <= cycles + 1; endrule IteratorWithContext#(Bit#(32),NvmeIoCommand) ioIterator <- mkIteratorWithContext(); let segmenterFsm <- mkAutoFSM(seq while (True) seq action NvmeIoCommand command = unpack(0); Bit#(1) commandSource = 0; Bool commandValid = False; if (ioCommandFifo.notEmpty) begin command <- toGet(ioCommandFifo).get(); commandValid = True; commandSource = 0; end `ifdef NVME_ACCELERATOR_INTERFACE else if (ioCommandFifoAccel.notEmpty) begin command <- toGet(ioCommandFifoAccel).get(); commandValid = True; commandSource = 1; end `endif if (commandValid) begin ioIterator.start(IteratorConfig {xbase: 0, xlimit: command.numBlocks, xstep: `BlocksPerRequest}, command); ioCommandSourceFifo.enq(commandSource); end endaction while (ioIterator.ivpipe.notEmpty()) seq action let v <- toGet(ioIterator.ivpipe).get(); let command = v.ctxt; if (v.last) begin command.numBlocks = command.numBlocks - v.value; //fixme ioCommandSourceFifo.deq(); end else begin command.numBlocks = `BlocksPerRequest; end command.startBlock = command.startBlock + extend(v.value); ioSegmentFifo.enq(command); ioSegmentSourceFifo.enq(ioCommandSourceFifo.first); endaction endseq endseq // while True endseq); Reg#(Bit#(32)) i <- mkReg(0); let requestFsm <- mkAutoFSM(seq while (True) seq action let req <- toGet(ioSegmentFifo).get(); let source <- toGet(ioSegmentSourceFifo).get(); Vector#(16,Bit#(32)) command = unpack(0); command[0] = { requestId, req.flags, req.opcode }; command[1] = 1; // nsid // prp1: send data to fifo command[6] = 32'h30000000; // p2p2: read PRP list from BRAM at offset 0x2000 command[8] = 32'h20002000; command[10] = req.startBlock[31:0]; command[11] = 0; //req.startBlock[63:32]; command[12] = req.numBlocks-1; command[13] = req.dsm; //requestId <= req.requestId; ioCommand <= command; requestSlotAvailable <= False; ioResponseSourceFifo.enq(source); endaction while (!requestSlotAvailable) seq // wait for open request slot portB1.request.put(BRAMRequest {address: (extend(requestId[2:0]) * fromInteger(responseSize/bytesPerEntry)) + fromInteger(12/bytesPerEntry), write: False, responseOnWrite: False, datain: 0}); action let response <- portB1.response.get(); let phase = ~requestId[3]; if (response[16+(3*32 % valueOf(PcieDataBusWidth))] == ~phase) begin requestSlotAvailable <= True; end endaction endseq // wait for open request slot // write a IO read request to BRAM for (i <= 0; i < fromInteger(requestSize/bytesPerEntry); i <= i + 1) seq portB1.request.put(BRAMRequest {address: 'h1000/fromInteger(bytesPerEntry) + (extend(requestId[2:0]) * fromInteger(requestSize/bytesPerEntry)) + i, write: True, responseOnWrite: False, datain: truncate(pack(ioCommand) >> (i*fromInteger(valueOf(PcieDataBusWidth)))) }); endseq // tell the NVME the new submission queue tail pointer action awaddrFifo.enq(PhysMemRequest { addr: 'h1000 + (2*2+0)*(4<<0), burstLen: 4, tag: 1 }); wdataFifo.enq(MemData{data: zeroExtend((requestId+1)[2:0]), tag: 1, last: True}); requestInProgress <= True; requestStartTimestamp <= cycles; trace.traceData(unpack(0), False, truncate(requestId), cycles); requestId <= requestId + 1; endaction endseq // while True endseq); let responseFsm <- mkAutoFSM(seq // wait for response queue to be updated while (True) seq requestInProgress <= True; while (requestInProgress) seq portB2.request.put(BRAMRequest {address: (extend(responseId[2:0]) * fromInteger(responseSize/bytesPerEntry)) + fromInteger(12/bytesPerEntry), write: False, responseOnWrite: False, datain: 0}); action let response <- portB2.response.get(); let phase = ~responseId[3]; if (response[16+(3*32 % valueOf(PcieDataBusWidth))] == phase) begin // if status field written by NVME let source <- toGet(ioResponseSourceFifo).get(); `ifdef NVME_ACCELERATOR_INTERFACE if (source == 1) ioResponseFifoAccel.enq(NvmeIoResponse {requestId: responseId, statusCode: 'h5a5a, statusCodeType: 'h5a5a }); else `endif nvmeInd.transferCompleted(responseId, truncate(response), cycles - requestStartTimestamp); requestInProgress <= False; end endaction endseq // while requestInProgress // tell the NVME the new response queue head pointer action let nextRequestId = (responseId + 1); responseId <= nextRequestId; awaddrFifo.enq(PhysMemRequest { addr: 'h1000 + (2*2+1)*(4<<0), burstLen: 4, tag: 1 }); wdataFifo.enq(MemData{data: zeroExtend((nextRequestId)[2:0]), tag: 1, last: True}); endaction endseq // while True endseq); let traceMemCnx <- mkConnection(traceClient, splitter.server); let bramMemCnx <- mkConnection(splitter.bramClient, bramMemA); `ifdef NVME_ACCELERATOR_INTERFACE FIFOF#(MemData#(32)) msgToSoftwareFifo <- mkSizedFIFOF(128); FIFOF#(MemData#(32)) msgFromSoftwareFifo <- mkSizedFIFOF(16); AxiStreamSlave#(32) msgToSoftwareStream <- mkAxiStream(msgToSoftwareFifo); AxiStreamMaster#(32) msgFromSoftwareStream <- mkAxiStream(msgFromSoftwareFifo); AxiStreamMaster#(PcieDataBusWidth) dataFromNvmeStream <- mkAxiStream(splitter.dataFromNvme); AxiStreamSlave#(PcieDataBusWidth) dataToNvmeStream <- mkAxiStream(splitter.dataToNvme); AxiStreamSlave#(SizeOf#(NvmeIoCommand)) requestStream <- mkAxiStream(mapPipeIn(unpack,toPipeIn(ioCommandFifoAccel))); AxiStreamMaster#(SizeOf#(NvmeIoResponse)) responseStream <- mkAxiStream(mapPipe(pack,toPipeOut(ioResponseFifoAccel))); rule rl_msgToSoftware; let msg <- toGet(msgToSoftwareFifo).get(); nvmeInd.msgToSoftware(msg.data, pack(msg.last)); endrule `endif let ltssm <- mkProbe(); let userLinkUp <- mkProbe(); rule rl_probe; ltssm <= axiRootPort.cfg.ltssm_state(); userLinkUp <= axiRootPort.user.link_up(); endrule //let pcie_sys_reset_n <- mkResetInverter(axiRootPort.axi.aresetn, clocked_by axiClock); let pcie_sys_reset_n <- mkResetInverter(nvme_rst_n.new_rst, clocked_by axiClock); interface MemServerPortalRequest bramRequest = bramMemServerPortal.request; interface NvmeDriverRequest driverRequest; method Action reset(Bit#(8) count) if (sysResetCount == 0); sysResetCount <= count; endmethod method Action nvmeReset(Bit#(8) count) if (nvmeResetCount == 0); nvmeResetCount <= count; endmethod method Action setup(); inSetup <= True; setupFsm.start(); endmethod method Action status(); `ifndef PCIE3 let mmcmLock = axiRootPort.mmcm.lock(); let ltssm_state = 1'd0; `else let mmcmLock = axiRootPort.user.link_up(); let ltssm_state = axiRootPort.cfg.ltssm_state(); `endif driverInd.status(mmcmLock, extend(ltssm_state)); endmethod method Action trace(Bool enabled); traceEnabled <= enabled; endmethod method Action read32(Bit#(32) addr) if (!inSetup); araddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); endmethod method Action write32(Bit#(32) addr, Bit#(32) value) if (!inSetup); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); wdataFifo.enq(MemData {data: extend(value), tag: 0, last: True}); endmethod method Action read64(Bit#(32) addr) if (!inSetup); araddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 8, tag: 0 }); endmethod method Action write64(Bit#(32) addr, Bit#(64) value) if (!inSetup); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 8, tag: 0 }); wdataFifo.enq(MemData {data: extend(value), tag: 0, last: True}); endmethod method Action write128(Bit#(32) addr, Bit#(64) uvalue, Bit#(64) lvalue) if (!inSetup); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 16, tag: 0 }); wdataFifo.enq(MemData {data: {uvalue,lvalue}, tag: 0, last: True}); endmethod method Action read(Bit#(32) addr) if (!inSetup); araddrFifo.enq(PhysMemRequest { addr: addr, burstLen: fromInteger(valueOf(TDiv#(DataBusWidth,8))), tag: 0 }); endmethod method Action write(Bit#(32) addr, Bit#(DataBusWidth) value) if (!inSetup); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: fromInteger(valueOf(TDiv#(DataBusWidth,8))), tag: 0 }); wdataFifo.enq(MemData {data: extend(value), tag: 0, last: True}); endmethod method Action readCtl(Bit#(32) addr) if (!inSetup); araddrFifoCtl.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); endmethod method Action writeCtl(Bit#(32) addr, Bit#(DataBusWidth) value) if (!inSetup); awaddrFifoCtl.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); wdataFifoCtl.enq(MemData {data: truncate(value), tag: 0, last: True}); endmethod endinterface interface NvmeRequest request; method Action startTransfer(Bit#(8) opcode, Bit#(8) flags, Bit#(16) requestId, Bit#(32) startBlock, Bit#(32) numBlocks, Bit#(32) dsm); ioCommandFifo.enq(NvmeIoCommand{opcode: opcode, flags: flags, requestId: requestId, startBlock: startBlock, numBlocks: numBlocks, dsm: dsm }); endmethod method Action msgFromSoftware(Bit#(32) value, Bit#(1) last); `ifdef NVME_ACCELERATOR_INTERFACE msgFromSoftwareFifo.enq(MemData { data:value, last: unpack(last), tag: 0 }); `endif endmethod endinterface `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource = axiRootPort.axi.aclk_out; `endif `ifndef NVME_ACCELERATOR_INTERFACE interface PipeOut dataFromNvme = splitter.dataFromNvme; interface PipeOut dataToNvme = splitter.dataToNvme; `endif interface NvmePins pins; interface deleteme_unused_clock = clock; interface pcie_sys_reset_n = pcie_sys_reset_n; interface pcie = axiRootPort.pci; method Action pcie_refclk(Bit#(1) p, Bit#(1) n); refclk_p.inputclock(p); refclk_n.inputclock(n); endmethod `ifdef NVME_ACCELERATOR_INTERFACE interface NvmeAccelerator accel; interface msgToSoftware = msgToSoftwareStream; interface msgFromSoftware = msgFromSoftwareStream; interface dataFromNvme = dataFromNvmeStream; interface dataToNvme = dataToNvmeStream; interface request = requestStream; interface response = responseStream; interface clock = clock; interface reset = reset; endinterface `endif endinterface interface Vector dmaReadClient = vec(axiGearbox.client.readClient); interface Vector dmaWriteClient = vec(axiGearbox.client.writeClient); endmodule interface NvmeAcceleratorModule; interface NvmeAccelerator accelerator; interface NvmePins pins; endinterface instance ToAxi4SlaveBits#(Axi4SlaveBits#(32,PcieDataBusWidth,4,Empty), AprpS_axi); function Axi4SlaveBits#(32,PcieDataBusWidth,4,Empty) toAxi4SlaveBits(AprpS_axi s); return (interface Axi4SlaveBits#(32,PcieDataBusWidth,4,Empty); method araddr = compose(s.araddr, extend); method arburst = s.arburst; //method arcache = s.arcache; method arid = s.arid; method arlen = s.arlen; //method arlock = s.arlock; //method arprot = s.arprot; //method arqos = s.arqos; method arready = s.arready; method arsize = s.arsize; method arvalid = s.arvalid; method awaddr = compose(s.awaddr, extend); method awburst = s.awburst; //method awcache = s.awcache; method awid = s.awid; method awlen = s.awlen; //method awlock = s.awlock; //method awprot = s.awprot; //method awqos = s.awqos; method awready = s.awready; method awsize = s.awsize; method awvalid = s.awvalid; method bid = s.bid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rid = s.rid; method rlast = s.rlast; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wlast = s.wlast; method wready = s.wready; method wvalid = s.wvalid; method wstrb = s.wstrb; endinterface); endfunction endinstance instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(32,32), AprpS_axi_ctl); function Axi4SlaveLiteBits#(32,32) toAxi4SlaveBits(AprpS_axi_ctl s); return (interface Axi4SlaveLiteBits#(32,32); method araddr = compose(s.araddr, truncate); method arready = s.arready; method arvalid = s.arvalid; method awaddr = compose(s.awaddr, truncate); method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance instance ToAxi4MasterBits#(Axi4MasterBits#(32,PcieDataBusWidth,tagWidth,Empty), AprpM_axi); function Axi4MasterBits#(32,PcieDataBusWidth,tagWidth,Empty) toAxi4MasterBits(AprpM_axi m); return (interface Axi4MasterBits#(32,PcieDataBusWidth,tagWidth,Empty); method araddr = m.araddr; method arburst = m.arburst; method arcache = m.arcache; method arlen = m.arlen; method arlock = extend(m.arlock); method arready = m.arready; method arsize = m.arsize; method arvalid = m.arvalid; method Bit#(1) aresetn(); return 1; endmethod method Bit#(tagWidth) arid(); return 0; endmethod method arprot = m.arprot; method arqos = 0; method awaddr = m.awaddr; method awburst = m.awburst; method awcache = m.awcache; method Bit#(tagWidth) awid(); return 0; endmethod method awlen = m.awlen; method awlock = extend(m.awlock); method awprot = m.awprot; method awready = m.awready; method Bit#(4) awqos(); return 0; endmethod method awsize = m.awsize; method awvalid = m.awvalid; method Action bid(Bit#(tagWidth) v); endmethod method bready = m.bready; method bresp = m.bresp; method bvalid = m.bvalid; method rdata = m.rdata; method Action rid(Bit#(tagWidth) v); endmethod method rlast = m.rlast; method rready = m.rready; method rresp = m.rresp; method rvalid = m.rvalid; method wdata = m.wdata; method Bit#(tagWidth) wid(); return 0; endmethod method wlast = m.wlast; method wready = m.wready; method wstrb = m.wstrb; method wvalid = m.wvalid; interface extra = ?; endinterface); endfunction endinstance interface SplitMemServer#(numeric type dataBusWidth); interface MemServer#(dataBusWidth) server; interface MemClient#(dataBusWidth) busClient; interface MemClient#(dataBusWidth) bramClient; interface PipeOut#(MemData#(dataBusWidth)) dataFromNvme; interface PipeIn#(MemData#(dataBusWidth)) dataToNvme; endinterface `ifndef DATA_FIFO_DEPTH typedef 16 DataFifoDepth; `else typedef `DATA_FIFO_DEPTH DataFifoDepth; `endif module mkSplitMemServer(SplitMemServer#(dataBusWidth)); let readReqFifo <- mkFIFOF(); let readDataFifo <- mkFIFOF(); let writeReqFifo <- mkFIFOF(); let writeDataFifo <- mkFIFOF(); let writeDoneFifo <- mkFIFOF(); let busReadReqFifo <- mkFIFOF(); let busReadDataFifo <- mkSizedBRAMFIFOF(16); let busWriteReqFifo <- mkFIFOF(); let busWriteDataFifo <- mkSizedBRAMFIFOF(16); let busWriteDoneFifo <- mkFIFOF(); let bramReadReqFifo <- mkFIFOF(); let bramReadDataFifo <- mkSizedBRAMFIFOF(16); let bramWriteReqFifo <- mkFIFOF(); let bramWriteDataFifo <- mkSizedBRAMFIFOF(16); let bramWriteDoneFifo <- mkFIFOF(); let doneFifo <- mkFIFOF(); let dataFromNvmeFifo <- mkSizedBRAMFIFOF(valueOf(DataFifoDepth)); let dataToNvmeFifo <- mkSizedBRAMFIFOF(valueOf(DataFifoDepth)); let readDestFifo <- mkFIFOF(); let writeDestFifo <- mkFIFOF(); rule rl_rd_req; MemRequest req <- toGet(readReqFifo).get(); let dest = req.sglId[5:4]; if (dest == 2) bramReadReqFifo.enq(req); else if (dest == 3) begin // reading from dataToNvmeFifo end else busReadReqFifo.enq(req); readDestFifo.enq(dest); endrule rule rl_rd_data; let dest = readDestFifo.first(); MemData#(dataBusWidth) md; if (dest == 2) md <- toGet(bramReadDataFifo).get(); else if (dest == 3) md <- toGet(dataToNvmeFifo).get(); else md <- toGet(busReadDataFifo).get(); if (md.last) readDestFifo.deq(); readDataFifo.enq(md); endrule rule rl_wr_req; MemRequest req <- toGet(writeReqFifo).get(); Bit#(2) dest = req.sglId[5:4]; if (dest == 2) bramWriteReqFifo.enq(req); else if (dest == 3) begin // no need to send the request end else busWriteReqFifo.enq(req); writeDestFifo.enq(dest); endrule rule rl_wr_data; let dest = writeDestFifo.first(); MemData#(dataBusWidth) md <- toGet(writeDataFifo).get(); if (dest == 2) bramWriteDataFifo.enq(md); else if (dest == 3) dataFromNvmeFifo.enq(md); else busWriteDataFifo.enq(md); if (md.last) begin writeDestFifo.deq(); doneFifo.enq(tuple2(dest, md.tag)); end endrule rule rl_wr_done; match { .dest, .tag } <- toGet(doneFifo).get(); Bit#(MemTagSize) doneTag; if (dest == 2) doneTag <- toGet(bramWriteDoneFifo).get(); else if (dest == 3) doneTag = 0; else doneTag <- toGet(busWriteDoneFifo).get(); writeDoneFifo.enq(doneTag); endrule interface MemServer server; interface MemReadServer readServer; interface readReq = toPut(readReqFifo); interface readData = toGet(readDataFifo); endinterface interface MemWriteServer writeServer; interface writeReq = toPut(writeReqFifo); interface writeData = toPut(writeDataFifo); interface writeDone = toGet(writeDoneFifo); endinterface endinterface interface MemClient busClient; interface MemReadClient readClient; interface readReq = toGet(busReadReqFifo); interface Put readData; method Action put(MemData#(dataBusWidth) md); busReadDataFifo.enq(md); endmethod endinterface endinterface interface MemWriteClient writeClient; interface writeReq = toGet(busWriteReqFifo); interface writeData = toGet(busWriteDataFifo); interface writeDone = toPut(busWriteDoneFifo); endinterface endinterface interface MemClient bramClient; interface MemReadClient readClient; interface readReq = toGet(bramReadReqFifo); interface readData = toPut(bramReadDataFifo); endinterface interface MemWriteClient writeClient; interface writeReq = toGet(bramWriteReqFifo); interface writeData = toGet(bramWriteDataFifo); interface writeDone = toPut(bramWriteDoneFifo); endinterface endinterface interface PipeOut dataFromNvme = toPipeOut(dataFromNvmeFifo); interface PipeOut dataToNvme = toPipeIn(dataToNvmeFifo); endmodule interface MemServerGearbox#(numeric type serverDataBusWidth, numeric type clientDataBusWidth); interface MemServer#(serverDataBusWidth) server; interface MemClient#(clientDataBusWidth) client; endinterface module mk1toNMemServerGearbox(MemServerGearbox#(serverDataBusWidth, clientDataBusWidth)) provisos (Div#(serverDataBusWidth,clientDataBusWidth,k) ,Mul#(clientDataBusWidth,k,serverDataBusWidth) ,Add#(1, a__, TMul#(2, k)) ,Add#(k, b__, TMul#(2, k)) ,Add#(1, c__, k) ); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); let readReqFifo <- mkFIFOF(); let writeReqFifo <- mkFIFOF(); let writeDoneFifo <- mkFIFOF(); Gearbox#(1,k,MemData#(clientDataBusWidth)) readDataGearbox <- mk1toNGearbox(clock, reset, clock, reset); Gearbox#(k,1,MemData#(clientDataBusWidth)) writeDataGearbox <- mkNto1Gearbox(clock, reset, clock, reset); FIFOF#(MemData#(clientDataBusWidth)) busReadDataFifo <- mkSizedBRAMFIFOF(16); FIFOF#(MemData#(clientDataBusWidth)) busWriteDataFifo <- mkSizedBRAMFIFOF(16); rule readDataCnx; let md <- toGet(busReadDataFifo).get(); readDataGearbox.enq(vec(md)); endrule rule writeDataCnx; let md = writeDataGearbox.first[0]; writeDataGearbox.deq(); busWriteDataFifo.enq(md); endrule interface MemServer server; interface MemReadServer readServer; interface readReq = toPut(readReqFifo); interface Get readData; method ActionValue#(MemData#(serverDataBusWidth)) get(); let mds = readDataGearbox.first(); readDataGearbox.deq(); let md = MemData { data: pack(map(memDataData, mds)), tag: mds[0].tag, last: mds[valueOf(k)-1].last }; return md; endmethod endinterface endinterface interface MemWriteServer writeServer; interface writeReq = toPut(writeReqFifo); interface Put writeData; method Action put(MemData#(serverDataBusWidth) md); Vector#(k, Bit#(clientDataBusWidth)) datavec = unpack(md.data); Vector#(k, MemData#(clientDataBusWidth)) mds = newVector; for (Integer i = 0; i < valueOf(k); i = i + 1) mds[i] = MemData { data: datavec[i], tag: md.tag, last: (i == valueOf(k)-1) && md.last }; writeDataGearbox.enq(mds); endmethod endinterface interface writeDone = toGet(writeDoneFifo); endinterface endinterface interface MemClient client; interface MemReadClient readClient; interface readReq = toGet(readReqFifo); interface Put readData; method Action put(MemData#(clientDataBusWidth) md); busReadDataFifo.enq(md); //busReadDataData <= md.data; //busReadDataLast <= md.last; endmethod endinterface endinterface interface MemWriteClient writeClient; interface writeReq = toGet(writeReqFifo); interface writeData = toGet(busWriteDataFifo); interface writeDone = toPut(writeDoneFifo); endinterface endinterface endmodule interface MemServerPortal; interface MemServerPortalRequest request; endinterface module mkPhysMemSlavePortal#(PhysMemSlave#(32,dataBusWidth) ms, MemServerPortalIndication ind)(MemServerPortal) provisos (Add#(dataBusWidth,7,a__) ,Add#(b__,64,dataBusWidth) ,Bits#(ConnectalMemTypes::MemData#(dataBusWidth), a__)); FIFOF#(PhysMemRequest#(32,dataBusWidth)) araddrFifo <- mkFIFOF(); FIFOF#(PhysMemRequest#(32,dataBusWidth)) awaddrFifo <- mkFIFOF(); FIFOF#(MemData#(dataBusWidth)) rdataFifo <- mkFIFOF(); FIFOF#(MemData#(dataBusWidth)) wdataFifo <- mkFIFOF(); FIFOF#(Bit#(6)) doneFifo <- mkFIFOF(); let araddrCnx <- mkConnection(toGet(araddrFifo), ms.read_server.readReq); let awaddrCnx <- mkConnection(toGet(awaddrFifo), ms.write_server.writeReq); let rdataCnx <- mkConnection(ms.read_server.readData, toPut(rdataFifo)); let wdataCnx <- mkConnection(toGet(wdataFifo), ms.write_server.writeData); let doneCnx <- mkConnection(ms.write_server.writeDone, toPut(doneFifo)); rule rl_rdata; let rdata <- toGet(rdataFifo).get(); ind.readDone(truncate(rdata.data)); endrule rule rl_writeDone; let tag <- toGet(doneFifo).get(); ind.writeDone(); endrule interface MemServerPortalRequest request; method Action read(Bit#(32) addr); araddrFifo.enq(PhysMemRequest { addr: addr, burstLen: fromInteger(valueOf(TDiv#(dataBusWidth,8))), tag: 0 }); endmethod method Action write(Bit#(32) addr, Bit#(DataBusWidth) value); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: fromInteger(valueOf(TDiv#(dataBusWidth,8))), tag: 0 }); wdataFifo.enq(MemData {data: extend(value), tag: 0, last: True}); endmethod endinterface endmodule ================================================ FILE: lib/nvme/bsv/NvmeIfc.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import AxiStream::*; import Vector::*; import ConnectalConfig::*; `include "ConnectalProjectConfig.bsv" typedef `PcieDataBusWidth PcieDataBusWidth; typedef enum { DMA_RX, DMA_TX, DMA_SG } DmaChannel deriving (Bits,Eq); interface MemServerPortalRequest; method Action read(Bit#(32) addr); method Action write(Bit#(32) addr, Bit#(DataBusWidth) data); endinterface interface MemServerPortalIndication; method Action readDone(Bit#(DataBusWidth) data); method Action writeDone(); endinterface typedef enum { NvmeFlush = 0, NvmeWrite = 1, NvmeRead = 2, NvmeWriteUncorrectable = 4, NvmeCompare = 5, NvmeWriteZeros = 8, NvmeManageDataset = 9, NvmeRegisterReservation = 13, NvmeReportReservation = 14, NvmeAcquireReservation = 17, NvmeReleaseReservation = 21 } NvmeOpcode deriving (Bits,Eq,FShow); interface NvmeRequest; method Action startTransfer(Bit#(8) opcode, Bit#(8) flags, Bit#(16) requestId, Bit#(32) startBlock, Bit#(32) numBlocks, Bit#(32) dsm); method Action msgFromSoftware(Bit#(32) value, Bit#(1) last); endinterface interface NvmeIndication; method Action transferCompleted(Bit#(16) requestId, Bit#(64) sc, Bit#(32) cycles); method Action msgToSoftware(Bit#(32) value, Bit#(1) last); endinterface // internal interfaces interface NvmeDriverRequest; method Action reset(Bit#(8) count); method Action nvmeReset(Bit#(8) count); method Action setup(); method Action read32(Bit#(32) addr); method Action write32(Bit#(32) addr, Bit#(32) data); method Action read64(Bit#(32) addr); method Action write64(Bit#(32) addr, Bit#(64) data); method Action read128(Bit#(32) addr); method Action write128(Bit#(32) addr, Bit#(64) udata, Bit#(64) ldata); method Action read(Bit#(32) addr); method Action write(Bit#(32) addr, Bit#(DataBusWidth) data); method Action readCtl(Bit#(32) addr); method Action writeCtl(Bit#(32) addr, Bit#(DataBusWidth) data); method Action status(); method Action trace(Bool enabled); endinterface interface NvmeDriverIndication; method Action setupDone(); method Action readDone(Bit#(DataBusWidth) data); method Action writeDone(); method Action status(Bit#(1) mmcm_lock, Bit#(32) dataCounter); method Action setupComplete(); endinterface interface NvmeTrace; method Action traceDmaRequest(DmaChannel channel, Bool write, Bit#(16) objId, Bit#(32) offset, Bit#(16) burstLen, Bit#(8) tag, Bit#(32) timestamp); method Action traceDmaData(DmaChannel channel, Bool write, Vector#(TDiv#(PcieDataBusWidth,32),Bit#(32)) data, Bool last, Bit#(8) tag, Bit#(32) timestamp); method Action traceDmaDone(DmaChannel channel, Bit#(8) tag, Bit#(32) timestamp); method Action traceData(Vector#(TDiv#(PcieDataBusWidth,32),Bit#(32)) data, Bool last, Bit#(8) tag, Bit#(32) timestamp); endinterface typedef struct { Bit#(8) opcode; Bit#(8) flags; Bit#(16) requestId; Bit#(32) startBlock; Bit#(32) numBlocks; Bit#(32) dsm; } NvmeIoCommand deriving (Bits); typedef struct { Bit#(16) requestId; Bit#(16) statusCode; Bit#(16) statusCodeType; } NvmeIoResponse deriving (Bits); // these ports exposed to a verilog wrapper module interface NvmeAccelerator; interface AxiStreamMaster#(32) msgFromSoftware; interface AxiStreamSlave#(32) msgToSoftware; interface AxiStreamMaster#(PcieDataBusWidth) dataFromNvme; interface AxiStreamSlave#(PcieDataBusWidth) dataToNvme; interface AxiStreamSlave#(SizeOf#(NvmeIoCommand)) request; interface AxiStreamMaster#(SizeOf#(NvmeIoResponse)) response; interface Clock clock; interface Reset reset; endinterface interface NvmeAcceleratorClient; interface AxiStreamSlave#(32) msgFromSoftware; interface AxiStreamMaster#(32) msgToSoftware; interface AxiStreamSlave#(PcieDataBusWidth) dataFromNvme; interface AxiStreamMaster#(PcieDataBusWidth) dataToNvme; interface AxiStreamMaster#(SizeOf#(NvmeIoCommand)) request; interface AxiStreamSlave#(SizeOf#(NvmeIoResponse)) response; endinterface ================================================ FILE: lib/nvme/bsv/NvmePins.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" `ifndef PCIE3 import AxiPcieRootPort::*; `else import AxiPcie3RootPort::*; `endif import NvmeIfc::*; interface NvmePins; interface AprpPci pcie; (* always_ready, always_enabled *) method Action pcie_refclk(Bit#(1) p, Bit#(1) n); interface Clock deleteme_unused_clock; interface Reset pcie_sys_reset_n; `ifdef NVME_ACCELERATOR_INTERFACE interface NvmeAccelerator accel; `endif endinterface export NvmePins(..); ================================================ FILE: lib/nvme/cpp/nvme.cpp ================================================ #include #include #include "nvme.h" #include // PcieDataBusWidth // queue size in create I/O completion/submission queue is specified as a 0 based value static const int queueSizeDelta = 1; class NvmeTrace : public NvmeTraceWrapper { std::multimap traceValues; public: void traceDmaRequest(const DmaChannel chan, const int write, const uint16_t objId, const uint32_t offset, const uint16_t burstLen, const uint8_t tag, const uint32_t timestamp) { char msg[128]; snprintf(msg, sizeof(msg), "%08x: traceDmaRequest chan=%d write=%d objId=%d offset=%08lx burstLen=%d tag=%x\n", timestamp, chan, write, objId, (long)offset, burstLen, tag); traceValues.insert(std::pair(timestamp, std::string(msg))); } void traceDmaData ( const DmaChannel chan, const int write, const bsvvector_Luint32_t_L4 data, const int last, const uint8_t tag, const uint32_t timestamp ) { char msg[128]; char datastr[128]; int offset = 0; for (int i = 0; i < PcieDataBusWidth/32; i++) offset += snprintf(datastr+offset, sizeof(datastr)-offset-1, " %08x", data[i]); snprintf(msg, sizeof(msg), "%08x: traceDmaData chan=%d write=%d data=%s last=%d tag=%x\n", timestamp, chan, write, datastr, last, tag); traceValues.insert(std::pair(timestamp, std::string(msg))); } virtual void traceDmaDone ( const DmaChannel chan, const uint8_t tag, const uint32_t timestamp ) { char msg[128]; snprintf(msg, sizeof(msg), "%08x: traceDmaDone chan=%d tag=%x\n", timestamp, chan, tag); traceValues.insert(std::pair(timestamp, std::string(msg))); } void traceData ( const bsvvector_Luint32_t_L4 data, const int last, const uint8_t tag, const uint32_t timestamp ) { char datastr[128]; int offset = 0; for (int i = 0; i < PcieDataBusWidth/32; i++) offset += snprintf(datastr+offset, sizeof(datastr)-offset-1, " %08x", data[i]); char msg[128]; snprintf(msg, sizeof(msg), "traceData data=%s last=%d tag=%x\n", datastr, last, tag); traceValues.insert(std::pair(timestamp, std::string(msg))); } void dumpTrace() { int prev = 0; fprintf(stderr, "%ld traceValues\n", traceValues.size()); for (auto it=traceValues.begin(); it!=traceValues.end(); ++it) { fprintf(stderr, "%08d %4d %s", it->first, it->first - prev, it->second.c_str()); prev = it->first; } traceValues.clear(); } NvmeTrace(int id, PortalPoller *poller = 0) : NvmeTraceWrapper(id, poller) { } }; class NvmeIndication : public NvmeIndicationWrapper { sem_t sem; pthread_cond_t cond; pthread_mutex_t mutex; std::queue msgs; std::queue lastmsgs; int waiters; public: uint64_t value; uint32_t requests; uint32_t cycles; virtual void msgIn ( const uint32_t value ) { } virtual void transferCompleted ( const uint16_t requestId, const uint64_t status, const uint32_t cycles ) { fprintf(stderr, "%s:%d requestId=%08x status=%08llx cycles=%d\n", __FUNCTION__, __LINE__, requestId, (long long)status, cycles); value = status; this->requests++; this->cycles += cycles; sem_post(&sem); } virtual void msgToSoftware ( const uint32_t msg, uint8_t last ) { fprintf(stderr, "%s:%d msg=%x\n", __FUNCTION__, __LINE__, msg); pthread_mutex_lock(&mutex); msgs.push(msg); lastmsgs.push(last); if (waiters) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } bool messageToSoftware(uint32_t *msg, bool *last, bool nonBlocking=true) { bool hasMsg = false; pthread_mutex_lock(&mutex); do { hasMsg = !msgs.empty(); if (msgs.size()) { if (*msg) *msg = msgs.front(); if (last) *last = lastmsgs.front(); msgs.pop(); lastmsgs.pop(); } else if (!nonBlocking) { waiters++; pthread_cond_wait(&cond, &mutex); waiters--; } } while (!hasMsg); pthread_mutex_unlock(&mutex); return hasMsg; } void wait() { sem_wait(&sem); } NvmeIndication(int id, PortalPoller *poller = 0) : NvmeIndicationWrapper(id, poller), waiters(0), value(0), requests(0), cycles(0) { sem_init(&sem, 0, 0); pthread_mutex_init(&mutex, 0); pthread_cond_init(&cond, 0); } }; class NvmeDriverIndication : public NvmeDriverIndicationWrapper { sem_t sem, wsem; public: uint64_t value; uint32_t requests; uint32_t cycles; virtual void setupDone ( ) { fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__); sem_post(&sem); } virtual void readDone ( const uint64_t data ) { //fprintf(stderr, "%s:%d data=%08llx\n", __FUNCTION__, __LINE__, (long long)data); value = data; sem_post(&sem); } virtual void writeDone ( ) { //fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__); sem_post(&wsem); } virtual void status ( const uint8_t mmcm_lock, const uint32_t counter ) { fprintf(stderr, "%s:%d mmcm_lock=%d counter=%d\n", __FUNCTION__, __LINE__, mmcm_lock, counter); sem_post(&sem); } virtual void setupComplete() { fprintf(stderr, "%s\n", __FUNCTION__); sem_post(&sem); } virtual void strstrLoc ( const uint32_t loc ) { fprintf(stderr, "strstr loc loc=%d\n", loc); } virtual void transferCompleted ( const uint16_t requestId, const uint64_t status, const uint32_t cycles ) { fprintf(stderr, "%s:%d requestId=%08x status=%08llx cycles=%d\n", __FUNCTION__, __LINE__, requestId, (long long)status, cycles); value = status; this->requests++; this->cycles += cycles; sem_post(&sem); } void wait() { sem_wait(&sem); } void waitwrite() { sem_wait(&wsem); } NvmeDriverIndication(int id, PortalPoller *poller = 0) : NvmeDriverIndicationWrapper(id, poller), value(0), requests(0), cycles(0) { sem_init(&sem, 0, 0); sem_init(&wsem, 0, 0); } }; class MemServerPortalIndication : public MemServerPortalIndicationWrapper { sem_t sem; sem_t wsem; public: uint64_t value; MemServerPortalIndication(int id, PortalPoller *poller = 0) : MemServerPortalIndicationWrapper(id, poller) { sem_init(&sem, 0, 0); sem_init(&wsem, 0, 0); } virtual void readDone ( const uint64_t data ) { value = data; sem_post(&sem); } virtual void writeDone ( ) { sem_post(&wsem); } void wait() { sem_wait(&sem); } void waitw() { sem_wait(&sem); } }; uint32_t Nvme::readCtl(uint32_t addr) { // if (verbose) fprintf(stderr, "readCtl %x\n", addr); driverRequest.readCtl(addr); driverIndication->wait(); return (uint32_t)driverIndication->value; } void Nvme::writeCtl(uint32_t addr, uint32_t data) { //if (verbose) fprintf(stderr, "writeCtl %x\n", addr); driverRequest.writeCtl(addr, data); driverIndication->waitwrite(); } uint64_t Nvme::read(uint32_t addr) { driverRequest.read64(addr); driverIndication->wait(); return driverIndication->value; } void Nvme::write(uint32_t addr, uint64_t data) { driverRequest.write64(addr, data); driverIndication->waitwrite(); } uint32_t Nvme::read32(uint32_t addr) { driverRequest.read32(addr); driverIndication->wait(); uint64_t v = driverIndication->value; return (uint32_t)(v >> ((addr & 4) ? 32 : 0)); //return v; } void Nvme::write32(uint32_t addr, uint32_t data) { uint64_t v = data; //fixme byte enables //driverRequest.write(addr & ~7, v << ((addr & 4) ? 32 : 0)); driverRequest.write32(addr, v); driverIndication->waitwrite(); } uint64_t Nvme::read64(uint32_t addr) { driverRequest.read64(addr); driverIndication->wait(); uint64_t v = driverIndication->value; return v; } void Nvme::write64(uint32_t addr, uint64_t data) { uint64_t v = data; //fixme byte enables driverRequest.write64(addr, v); driverIndication->waitwrite(); } void Nvme::write128(uint32_t addr, uint64_t udata, uint64_t ldata) { driverRequest.write128(addr, udata, ldata); driverIndication->waitwrite(); } uint64_t Nvme::bramRead(uint32_t addr) { bram.read(addr); bramIndication->wait(); return bramIndication->value; } void Nvme::bramWrite(uint32_t addr, uint64_t data) { bram.write(addr, data); //bramIndication->wait(); } Nvme::Nvme(bool verbose) : Nvme(BlocksPerRequest*512, verbose) { fprintf(stderr, "Nvme verbose=%d\n", verbose); } Nvme::Nvme(int transferBufferSize, bool verbose) : verbose(verbose) , requestProxy(IfcNames_NvmeRequestS2H) , indication(new NvmeIndication(IfcNames_NvmeIndicationH2S)) , driverRequest(IfcNames_NvmeDriverRequestS2H) , driverIndication(new NvmeDriverIndication(IfcNames_NvmeDriverIndicationH2S)) , trace(new NvmeTrace(IfcNames_NvmeTraceH2S)) , bram(IfcNames_MemServerPortalRequestS2H) , bramIndication(new MemServerPortalIndication(IfcNames_MemServerPortalIndicationH2S)) , adminRequestNumber(0) , adminBuffer(4096) , transferBuffer(transferBufferSize) , adminSubmissionQueue(4096) , adminCompletionQueue(4096) , ioSubmissionQueue(ioQueueSize) , ioCompletionQueue(ioQueueSize) , needleBuffer(8192) , mpNextBuffer(8192) { memset(ioRequestNumber, 0, sizeof(ioRequestNumber)); adminBufferRef = adminBuffer.reference(); transferBufferRef = transferBuffer.reference(); adminSubmissionQueueRef = adminSubmissionQueue.reference(); adminCompletionQueueRef = adminCompletionQueue.reference(); if (verbose) fprintf(stderr, "adminSubmissionQueue %d\n", adminSubmissionQueue.reference()); if (verbose) fprintf(stderr, "adminCompletionQueue %d\n", adminCompletionQueue.reference()); ioSubmissionQueueRef = ioSubmissionQueue.reference(); ioCompletionQueueRef = ioCompletionQueue.reference(); needleRef = needleBuffer.reference(); mpNextRef = mpNextBuffer.reference(); if (verbose) fprintf(stderr, "ioSubmissionQueue %d\n", ioSubmissionQueue.reference()); if (verbose) fprintf(stderr, "ioCompletionQueue %d\n", ioCompletionQueue.reference()); driverRequest.status(); driverIndication->wait(); driverRequest.trace(0); } void Nvme::setup() { driverRequest.reset(16); sleep(1); driverRequest.nvmeReset(16); sleep(1); driverRequest.setup(); driverIndication->wait(); if (1) { if (verbose) fprintf(stderr, "Enabling I/O and Memory, bus master, parity and SERR\n"); writeCtl(0x004, 0x147); if (verbose) fprintf(stderr, "bridge control %08x\n", readCtl(0x004)); // required writeCtl(0x18, 0x00070100); writeCtl(0x10, 0xFFFFFFFF); writeCtl(0x14, 0xFFFFFFFF); fprintf(stderr, "Root Port BAR0: %08x\n", readCtl((0 << 20) + 0x10)); fprintf(stderr, "Root Port BAR1: %08x\n", readCtl((0 << 20) + 0x14)); writeCtl(0x10, 0x0); writeCtl(0x14, 0x0); if (verbose) fprintf(stderr, "Enabling card I/O and Memory, bus master, parity and SERR\n"); writeCtl((1 << 20) + 4, 0x147); if (verbose) fprintf(stderr, "card bridge control %08x\n", readCtl((1 << 20) + 4)); if (verbose) for (int i = 0; i < 6; i++) fprintf(stderr, "Card BAR%d: %08x\n", i, readCtl((1 << 20) + 0x10 + i*4)); if (verbose) fprintf(stderr, "probing card BAR\n"); for (int i = 0; i < 6; i++) { writeCtl((1 << 20) + 0x10 + 4*i, 0xffffffff); if (verbose) fprintf(stderr, "Card BAR%d: %08x\n", i, readCtl((1 << 20) + 0x10 + 4*i)); } writeCtl((1 << 20) + 0x10, 0x00000000); // initialize to offset 0 writeCtl((1 << 20) + 0x14, 0x00000000); writeCtl((1 << 20) + 0x18, 0x02200000); // BAR2 unused writeCtl((1 << 20) + 0x1c, 0x00000000); writeCtl((1 << 20) + 0x10+5*4, 0); // sata card if (verbose) { fprintf(stderr, "reading card BARs\n"); for (int i = 0; i < 6; i++) { fprintf(stderr, "Card BAR%d: %08x\n", i, readCtl((1 << 20) + 0x10 + 4*i)); } } fprintf(stderr, "PHY Status/Control: %08x\n", readCtl(0x144)); fprintf(stderr, "Configuration Control (should be zero): %08x\n", readCtl(0x168)); for (int i = 0; i < 6; i++) fprintf(stderr, "AXI Bar%d %08x.%08x\n", i, readCtl(0x208 + i*8), readCtl(0x208 + i*8+4)); if (verbose) fprintf(stderr, "Enabling bridge\n"); fprintf(stderr, "0x148: %08x\n", readCtl(0x148)); writeCtl(0x140, 0x00000100); fprintf(stderr, "Bus Location Register: %08x\n", readCtl(0x140)); writeCtl(0x148, 1); fprintf(stderr, "0x148: %08x\n", readCtl(0x148)); fprintf(stderr, "before: contents of 0x30 %08lx.%08lx\n", read64(0x38), read64(0x30)); write128(0x30, 0x11ffeeddccbbaa99l, 0x8877665544332211); fprintf(stderr, "after: contents of 0x30 %08lx.%08lx\n", read64(0x38), read64(0x30)); write64(0x30, 0x8877665544332211); write64(0x38, 0x11ffeeddccbbaa99l); fprintf(stderr, "after2: contents of 0x30 %08lx.%08lx\n", read64(0x38), read64(0x30)); write64(0x20, 0x8877665544332211); write64(0x28, 0x11ffeeddccbbaa99l); fprintf(stderr, "after3: contents of 0x20 %08lx.%08lx\n", read64(0x28), read64(0x20)); if (verbose) { fprintf(stderr, "Reading card memory space\n"); for (int i = 0; i < 16; i++) fprintf(stderr, "CARDMEM[%02x]=%08x\n", i*4, read32(0x00000000 + i*4)); for (int i = 0; i < 16; i += 2) fprintf(stderr, "CARDMEM[%02x]=%08lx\n", i*4, read64(0x00000000 + i*8)); } } uint64_t cardcap = read64(0); fprintf(stderr, "cardcap=%08lx\n", cardcap); int mpsmax = (cardcap >> 52)&0xF; int mpsmin = (cardcap >> 48)&0xF; if (verbose) fprintf(stderr, "MPSMAX=%0x %#x bytes\n", mpsmax, 1 << (12+mpsmax)); if (verbose) fprintf(stderr, "MPSMIN=%0x %#x bytes\n", mpsmin, 1 << (12+mpsmin)); write32(0x1c, 0x10); // clear reset bit if (verbose) fprintf(stderr, "0x1c reset %08x\n", read32(0x1c)); if (verbose) fprintf(stderr, "0x14 %08llx\n", (long long)read(0x14)); if (verbose) fprintf(stderr, "0x18 %08llx\n", (long long)read(0x18)); // initialize CC.IOCQES and CC.IOSQES write32(0x14, 0x00460000); // completion queue entry size 2^4, submission queue entry size 2^6 if (verbose) { fprintf(stderr, "CMB size %08x\n", read32(0x38)); fprintf(stderr, "CMB location %08x\n", read32(0x3c)); } uint64_t adminCompletionBaseAddress = adminCompletionQueueRef << 24; uint64_t adminSubmissionBaseAddress = adminSubmissionQueueRef << 24; if (verbose) fprintf(stderr, "Setting up Admin submission and completion queues %llx %llx\n", (long long)adminCompletionBaseAddress, (long long)adminSubmissionBaseAddress); write64(0x28, adminSubmissionBaseAddress); if (verbose) fprintf(stderr, "AdminSubmissionBaseAddress %08llx\n", (long long)read(0x28)); write64(0x30, adminCompletionBaseAddress); if (verbose) fprintf(stderr, "AdminCompletionBaseAddress %08llx\n", (long long)read(0x30)); write32(0x24, 0x003f003f); // CC.enable if (verbose) fprintf(stderr, "****************************************\n"); if (verbose) fprintf(stderr, "CSTS %08x \n", read32(0x1c)); if (verbose) fprintf(stderr, "read64 0x18 %08lx\n", read64(0x18)); write32(0x14, 0x00460000); if (verbose) fprintf(stderr, "CC.enable %08x (expected 0x00460001)\n", read32(0x14)); write32(0x14, 0x00460001); if (verbose) fprintf(stderr, "read64 0x010 %08llx\n", (long long)read64(0x10)); if (verbose) fprintf(stderr, "read32 0x014 %08llx\n", (long long)read32(0x14)); if (verbose) fprintf(stderr, "****************************************\n"); for (int i = 0; i < 10; i++) fprintf(stderr, "CARDMEM[%02x]=%08x\n", i*4, read32(0x00000000 + i*4)); } void Nvme::memserverWrite() { Nvme *nvme = this; // identify portals int numTiles = nvme->read32(0x02200000 + 0x08); int numPortals = nvme->read32(0x02200000 + 0x14); fprintf(stderr, "numTiles=%x numPortals=%x\n", numTiles, numPortals); for (int p = 0; p < numPortals; p++) { fprintf(stderr, "Platform Portal[%d].id=%x\n", p, nvme->read32(0x02200000 + p*0x1000 + 0x10)); } numTiles = nvme->read32(0x02200000 + 0x40000 + 0x08); numPortals = nvme->read32(0x02200000 + 0x40000 + 0x14); fprintf(stderr, "numTiles=%x numPortals=%x\n", numTiles, numPortals); for (int p = 0; p < numPortals; p++) { fprintf(stderr, "Portal[%d].id=%x\n", p, nvme->read32(0x02200000 + 0x40000 + p*0x1000 + 0x10)); } if (1) { // pause for vivado to connect fprintf(stderr, "type enter to continue:\n"); char line[100]; char *str = fgets(line, sizeof(line), stdin); if (str == 0) fprintf(stderr, "Failed to read continuation line\n"); } // start write test int pointer = 1; int numWords = 0x1000; int burstLen = 64; int numReqs = numWords / burstLen; int byteEnable = 0xff; nvme->write32(0x02200000 + 0x41000 + 0x20, (pointer>>24)); nvme->write32(0x02200000 + 0x41000 + 0x20, (numWords>>24)|(((unsigned long)pointer)<<8)); nvme->write32(0x02200000 + 0x41000 + 0x20, (numReqs>>24)|(((unsigned long)numWords)<<8)); nvme->write32(0x02200000 + 0x41000 + 0x20, (burstLen>>24)|(((unsigned long)numReqs)<<8)); nvme->write32(0x02200000 + 0x41000 + 0x20, byteEnable|(((unsigned long)burstLen)<<8)); } void Nvme::status() { driverRequest.status(); driverIndication->wait(); } void Nvme::transferStats() { uint32_t cycles = driverIndication->cycles; uint32_t requests = driverIndication->requests; fprintf(stderr, "transfer stats: requests=%d cycles=%d average cycles/request=%5.2f\n", requests, cycles, (double)cycles/(double)requests); } void Nvme::dumpTrace() { trace->dumpTrace(); } int Nvme::adminCommand(nvme_admin_cmd *cmd, nvme_completion *completion) { nvme_admin_cmd *requests = (nvme_admin_cmd *)adminSubmissionQueue.buffer(); int requestNumber = adminRequestNumber % (4096 / sizeof(nvme_admin_cmd)); nvme_admin_cmd *request = &requests[requestNumber]; int *responses = (int *)adminCompletionQueue.buffer(); int responseNumber = adminRequestNumber % (4096 / 16); int *response = &responses[responseNumber * 4]; driverRequest.trace(1); if (verbose) fprintf(stderr, "%s:%d requestNumber=%d responseNumber = %d\n", __FUNCTION__, __LINE__, requestNumber, responseNumber); cmd->cid = adminRequestNumber++; *request = *cmd; write32(0x1000 + ((2*0 + 0) * (4 << 0)), requestNumber+1); fprintf(stderr, "doorbell value: %08x\n", read32(0x1000 + ((2*0 + 0) * (4 << 0)))); adminSubmissionQueue.cacheInvalidate(4096, 1); adminCompletionQueue.cacheInvalidate(4096, 0); // update submission queue tail write32(0x1000 + ((2*0 + 0) * (4 << 0)), requestNumber+1); sleep(1); dumpTrace(); if (verbose) { for (int i = 0; i < 4; i++) fprintf(stderr, " response[%02x]=%08x\n", i*4, response[i]); } int status = response[3]; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; write32(0x1000 + ((2*0 + 1) * (4 << 0)), responseNumber+1); fprintf(stderr, "doorbell value: %08x\n", read32(0x1000 + ((2*0 + 1) * (4 << 0)))); if (verbose) fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); return sc; } int Nvme::ioCommand(nvme_io_cmd *cmd, nvme_completion *completion, int queue, int dotrace) { nvme_io_cmd *requests = (nvme_io_cmd *)ioSubmissionQueue.buffer(); int requestNumber = ioRequestNumber[queue] % (Nvme::ioQueueSize / sizeof(nvme_io_cmd)); nvme_io_cmd *request = &requests[requestNumber]; int *responses = (int *)ioCompletionQueue.buffer(); int responseNumber = ioRequestNumber[queue] % (Nvme::ioQueueSize / 16); int *response = &responses[responseNumber * 4]; int responseBuffer[4]; fprintf(stderr, "%s:%d requestNumber=%d responseNumber = %d requestOffset=%lx io request objid=%d\n", __FUNCTION__, __LINE__, requestNumber, responseNumber, (long)(requestNumber*sizeof(nvme_io_cmd)), ioSubmissionQueueRef); cmd->cid = ioRequestNumber[queue]++; driverRequest.trace(dotrace); if (queue == 2) { fprintf(stderr, "%s:%d starting transfer opcode=%d\n", __FUNCTION__, __LINE__, cmd->opcode); int numBlocks = cmd->cdw12+1; requestProxy.startTransfer(/* read */ cmd->opcode, /* flags */ 0, cmd->cid, cmd->cdw10, numBlocks, /* dsm */0x71); //sleep(1); if (0) { for (int i = 0; i < 16; i++) { fprintf(stderr, "requestbuffer[%02x]=%016llx\n", i, (long long)bramRead(0x1000 + i*8)); } for (int i = 0; i < 4; i++) { fprintf(stderr, "responsebuffer[%02x]=%016llx\n", i, (long long)bramRead(i*8)); } } for (int i = 0; i < numBlocks/BlocksPerRequest; i++) { fprintf(stderr, "%s:%d waiting for completion numBlocks=%d\n", __FUNCTION__, __LINE__, numBlocks); indication->wait(); } dumpTrace(); int status = driverIndication->value >> 32; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); return sc; } if (queue == 1) { ioSubmissionQueue.cacheInvalidate(Nvme::ioQueueSize, 0); *request = *cmd; ioSubmissionQueue.cacheInvalidate(Nvme::ioQueueSize, 1); ioCompletionQueue.cacheInvalidate(Nvme::ioQueueSize, 0); } else { requestNumber = cmd->cid % 8; uint32_t bramRequestBase = 0x1000 + requestNumber*sizeof(nvme_io_cmd); for (uint32_t i = 0; i < sizeof(nvme_io_cmd); i += DataBusBytes) { bramWrite(bramRequestBase+i, ((uint64_t *)cmd)[i/8]); uint64_t val = bramRead(bramRequestBase+i); fprintf(stderr, "bramRequest[%02x]=%08x.%08x\n", bramRequestBase+i, (uint32_t)(val >> 32), (uint32_t)val); } } if (0 && requestNumber==7) { fprintf(stderr, "enabling DMA trace\n"); driverRequest.trace(1); sleep(1); } // update submission queue tail write32(0x1000+(2*queue*(4<<0)), requestNumber+1); sleep(1); if (queue != 1) { // read response from BRAM response = responseBuffer; responseNumber = cmd->cid % 8; fprintf(stderr, "cmd->cid=%x\n", cmd->cid); for (uint32_t i = 0; i < sizeof(nvme_completion); i += DataBusBytes) { uint64_t val = bramRead(responseNumber*sizeof(nvme_completion) + i); fprintf(stderr, "i=%02x val=%016llx\n", i, (long long)val); ((uint64_t *)responseBuffer)[i/DataBusBytes] = val; } } for (int i = 0; i < 4; i++) { fprintf(stderr, " response[%02x]=%08x\n", i*4, response[i]); } int status = response[3]; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; // clear status field so we can detect when NVME updates it if (queue == 1) { response[3] = 0; } else { // clear status field bramWrite(responseNumber*sizeof(nvme_completion) + 1, 0); } // notify NVME that we processed this response write32(0x1000 + ((2*queue + 1) * (4 << 0)), responseNumber+1); fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); return status ? sc : -1; } void Nvme::identify() { Nvme *nvme = this; fprintf(stderr, "sizeof(nvmd_id_cmd)=%ld\n", (long)sizeof(nvme_admin_cmd)); // write an identify command nvme_completion completion; nvme_admin_cmd buffer; nvme_admin_cmd *cmd = &buffer; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = nvme_identify; cmd->nsid = 0; cmd->prp1 = (nvme->transferBufferRef << 24) + 0; cmd->prp2 = (nvme->transferBufferRef << 24) + 4096; cmd->cdw10 = 1; nvme->adminCommand(cmd, &completion); { char *cbuffer = (char *)(nvme->transferBuffer.buffer() + 0); //int *buffer = (int *)(nvme->transferBuffer.buffer() + 0); char str[128]; fprintf(stderr, "PCI vendorid %02x\n", *(unsigned short *)&cbuffer[0]); fprintf(stderr, "PCI deviceid %02x\n", *(unsigned short *)&cbuffer[2]); snprintf(str, 20, "%s", &cbuffer[4]); fprintf(stderr, "serial number '%s'\n", str); snprintf(str, 40, "%s", &cbuffer[24]); fprintf(stderr, "model number '%s'\n", str); snprintf(str, 8, "%s", &cbuffer[64]); fprintf(stderr, "firmware rev '%s'\n", str); fprintf(stderr, "host buffer preferred size %x\n", *(int *)&cbuffer[272]); fprintf(stderr, "host buffer min size %x\n", *(int *)&cbuffer[276]); fprintf(stderr, "nvm submission queue entry size %d\n", cbuffer[512]); fprintf(stderr, "nvm completion queue entry size %d\n", cbuffer[513]); fprintf(stderr, "maximum data transfer size: %d pages\n", cbuffer[77] ? (1 << cbuffer[77]) : -1); fprintf(stderr, "controller id: %d\n", *(unsigned short *)&cbuffer[78]); fprintf(stderr, "OACS: %x\n", *(unsigned short *)&cbuffer[256]); fprintf(stderr, "log page attributes: %x\n", cbuffer[261]); fprintf(stderr, "error log page entries %d\n", cbuffer[262]); fprintf(stderr, "host memory buffer preferred size: %x\n", *(unsigned int *)&cbuffer[272]); fprintf(stderr, "host memory buffer minimum size: %x\n", *(unsigned int *)&cbuffer[272]); fprintf(stderr, "nvm capacity: %08llx %08llx\n", *(long long *)&cbuffer[288], *(long long *)&cbuffer[280]); fprintf(stderr, "unallocated capacity: %08llx %08llx\n", *(long long *)&cbuffer[304], *(long long *)&cbuffer[296]); fprintf(stderr, "number of namespaces: %x\n", *(unsigned int *)&cbuffer[516]); fprintf(stderr, "ONCS: %x\n", *(unsigned short *)&cbuffer[520]); fprintf(stderr, "supports SGL: %x\n", *(int *)&cbuffer[536]); } } void Nvme::getFeatures(FeatureId featureId) { Nvme *nvme = this; fprintf(stderr, "sizeof(nvmd_id_cmd)=%ld\n", (long)sizeof(nvme_admin_cmd)); nvme_completion completion; nvme_admin_cmd buffer; nvme_admin_cmd *cmd = &buffer; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = 0xa; cmd->nsid = 0; //cmd->prp1 = (nvme->transferBufferRef << 24) + 0; //cmd->prp2 = (nvme->transferBufferRef << 24) + 4096; cmd->cdw10 = featureId; nvme->adminCommand(cmd, &completion); { char *cbuffer = (char *)(nvme->transferBuffer.buffer() + 0); //int *buffer = (int *)(nvme->transferBuffer.buffer() + 0); //char str[128]; fprintf(stderr, "foo %x\n", *(unsigned short *)&cbuffer[0]); } } void Nvme::allocIOQueues(int entry) { Nvme *nvme = this; nvme_completion completion; nvme_admin_cmd buffer; nvme_admin_cmd *cmd = &buffer; fprintf(stderr, "%s:%d allocating completion queue with %d entries\n", __FUNCTION__, __LINE__, (Nvme::ioQueueSize / 16)); // create I/O completion queue memset(cmd, 0, sizeof(*cmd)); cmd->opcode = nvme_create_completion_queue; //5; cmd->nsid = 0; cmd->prp1 = (nvme->ioCompletionQueueRef << 24) + 0; cmd->cdw10 = ((Nvme::ioQueueSize / 16 - queueSizeDelta) << 16) | 1; // size, completion queue 1 cmd->cdw11 = 1; // physically contiguous nvme->adminCommand(cmd, &completion); fprintf(stderr, "%s:%d allocating request queue with %d entries\n", __FUNCTION__, __LINE__, (Nvme::ioQueueSize / 64)); // create I/O submission queue memset(cmd, 0, sizeof(*cmd)); cmd->opcode = nvme_create_submission_queue; //1; cmd->nsid = 0; cmd->prp1 = (nvme->ioSubmissionQueueRef << 24) + 0; cmd->cdw10 = ((Nvme::ioQueueSize / 64 - queueSizeDelta) << 16) | 1; // size, submission queue 1 cmd->cdw11 = (1 << 16) | 1; // completion queue 1, physically contiguous nvme->adminCommand(cmd, &completion); int numBramEntries = 8; //int responseQueueOffset = 0; //int submissionQueueOffset = numBramEntries * 16; fprintf(stderr, "%s:%d allocating completion queue with %d entries\n", __FUNCTION__, __LINE__, numBramEntries); // create I/O completion queue memset(cmd, 0, sizeof(*cmd)); cmd->opcode = nvme_create_completion_queue; cmd->nsid = 0; cmd->prp1 = (0x20 << 24) + 0; cmd->cdw10 = ((numBramEntries-queueSizeDelta)<<16) | 2; // size, completion queue 2 cmd->cdw11 = 1; // physically contiguous nvme->adminCommand(cmd, &completion); fprintf(stderr, "%s:%d allocating request queue with %d entries\n", __FUNCTION__, __LINE__, numBramEntries); // create I/O submission queue memset(cmd, 0, sizeof(*cmd)); cmd->opcode = nvme_create_submission_queue; cmd->nsid = 0; cmd->prp1 = (0x20 << 24) + 0x1000; cmd->cdw10 = ((numBramEntries-queueSizeDelta)<<16) | 2; // size, submission queue 2 cmd->cdw11 = (2 << 16) | 1; // completion queue 2, physically contiguous nvme->adminCommand(cmd, &completion); } int Nvme::doIO(nvme_io_opcode opcode, int startBlock, int numBlocks, int queue, int dotrace) { Nvme *nvme = this; int blocksPerPage = 4096 / 512; int transferBufferId = (queue == 1) ? nvme->transferBufferRef : 2; uint32_t bramBuffer = (2 << 24) + 0x2000; // clear transfer buffer { int *buffer = (int *)nvme->ioCompletionQueue.buffer(); memset(buffer, 0, numBlocks*512); } // let's do a read nvme_io_cmd cmd; nvme_completion completion; memset(&cmd, 0, sizeof(cmd)); cmd.opcode = opcode; cmd.nsid = 1; cmd.flags = 0x00; // PRP used for this transfer if (queue == 2) cmd.prp1 = 0x30000000ul; // send data to the FIFO else cmd.prp1 = (transferBufferId << 24); fprintf(stderr, "cmd.prp1=%llx\n", (long long)cmd.prp1); cmd.prp2 = (transferBufferId << 24) + 0; if (queue == 1) { uint64_t *prplist = (uint64_t *)nvme->adminBuffer.buffer(); for (int i = 0; i < numBlocks/blocksPerPage; i++) { if (opcode == nvme_read) prplist[i] = (uint64_t)(0x30000000ul + 0x1000*i + 0x1000); // enqueue/dequeue FIFO data else prplist[i] = (uint64_t)((transferBufferId << 24) + 0x1000*i + 0x1000); // read/write DRAM data } nvme->transferBuffer.cacheInvalidate(8*512, 1); } else { for (int i = 0; i < numBlocks/blocksPerPage; i++) { nvme->bramWrite(bramBuffer+i, (uint64_t)(0x30000000ul + 0x1000*i + 0x1000)); // send data to the FIFO fprintf(stderr, "bramRead[%02x]=%08llx\n", i, (long long)nvme->bramRead(bramBuffer+i)); } } cmd.cdw10 = startBlock; // starting LBA.lower cmd.cdw11 = 0; // starting LBA.upper cmd.cdw12 = numBlocks-1; // read N blocks fprintf(stderr, "IO cmd opcode=%02x flags=%02x cid=%04x %08x\n", cmd.opcode, cmd.flags, cmd.cid, *(int *)&cmd); int sc = nvme->ioCommand(&cmd, &completion, queue, dotrace); if (sc) { int *buffer = (int *)nvme->transferBuffer.buffer(); for (int i = 0; i < numBlocks*512/4; i++) { if (buffer[i]) fprintf(stderr, "data read [%02x]=%08x\n", i*4, buffer[i]); } } return sc; } void Nvme::messageFromSoftware(uint32_t msg, bool last) { requestProxy.msgFromSoftware(msg, last); } bool Nvme::messageToSoftware(uint32_t *msgp, bool *lastp, bool nonBlocking) { return indication->messageToSoftware(msgp, lastp, nonBlocking); } ================================================ FILE: lib/nvme/cpp/nvme.h ================================================ #pragma once #include #include #include "DmaBuffer.h" #include "portal.h" #include "dmaManager.h" #include "NvmeDriverIndication.h" #include "NvmeDriverRequest.h" #include "NvmeIndication.h" #include "NvmeRequest.h" #include "NvmeTrace.h" #include "MemServerPortalRequest.h" #include "MemServerPortalIndication.h" //#include "ConnectalProjectConfig.h" const int DataBusWidth = 64; const int DataBusBytes = DataBusWidth/8; enum nvme_admin_opcode { nvme_create_submission_queue = 1, nvme_create_completion_queue = 5, nvme_identify = 6, nvme_get_features = 10, }; enum nvme_io_opcode { nvme_flush = 0, nvme_write = 1, nvme_read = 2, nvme_write_uncorrectable = 4, nvme_compare = 5, nvme_write_zeroes = 8, nvme_manage_dataset = 9, nvme_register_reservation = 13, nvme_report_reservation = 14, nvme_acquire_reservation = 17, nvme_release_reservation = 21 }; struct nvme_admin_cmd { uint8_t opcode; uint8_t flags; uint16_t cid; uint32_t nsid; uint32_t reserved0; uint32_t reserved1; uint64_t mptr; uint64_t prp1; uint64_t prp2; uint32_t cdw10; uint32_t cdw11; uint32_t cdw12; uint32_t cdw13; uint32_t cdw14; uint32_t cdw15; }; struct nvme_io_cmd { uint8_t opcode; // offset: 00 uint8_t flags; uint16_t cid; uint32_t nsid; // offset 04 uint64_t reserved0; // offset 08 uint64_t mptr; // offset 16 uint64_t prp1; // offset 24 uint64_t prp2; // offset 32 uint32_t cdw10; // offset 40 uint32_t cdw11; // offset 44 uint32_t cdw12; uint32_t cdw13; uint32_t cdw14; uint32_t cdw15; }; struct nvme_completion { int cdw0; int cdw1; int cdw2; int cdw3; }; struct sgl_data_block_descriptor { uint64_t address; uint32_t length; uint8_t reserved[3]; uint8_t sglid; }; enum FeatureId { FID_NumberOfQueues = 7 }; class NvmeTrace; class NvmeIndication; class NvmeDriverIndication; class MemServerPortalIndication; class Nvme { bool verbose; NvmeRequestProxy requestProxy; NvmeIndication *indication; NvmeDriverRequestProxy driverRequest; NvmeDriverIndication *driverIndication; NvmeTrace *trace; MemServerPortalRequestProxy bram; MemServerPortalIndication *bramIndication; int adminRequestNumber; int ioRequestNumber[3]; // per queue, io queue 0 unused public: DmaBuffer adminBuffer; DmaBuffer transferBuffer; DmaBuffer adminSubmissionQueue; DmaBuffer adminCompletionQueue; DmaBuffer ioSubmissionQueue; DmaBuffer ioCompletionQueue; DmaBuffer needleBuffer; DmaBuffer mpNextBuffer; int adminBufferRef; int transferBufferRef; int adminSubmissionQueueRef; int adminCompletionQueueRef; int ioSubmissionQueueRef; int ioCompletionQueueRef; int needleRef; int mpNextRef; static const int ioQueueSize = 4096; Nvme(int transferBuffeSize = BlocksPerRequest*512, bool verbose=false); Nvme(bool verbose); void setup(); int adminCommand(nvme_admin_cmd *cmd, nvme_completion *completion); int ioCommand(nvme_io_cmd *cmd, nvme_completion *completion, int queue=1, int dotrace=0); void status(); void transferStats(); void dumpTrace(); void identify(); void getFeatures(FeatureId featureId=FID_NumberOfQueues); void allocIOQueues(int entry=0); int doIO(nvme_io_opcode opcode, int startBlock, int numBlocks, int queue=1, int dotrace=0); void messageFromSoftware(uint32_t msg, bool last=false); bool messageToSoftware(uint32_t *msg, bool *last, bool nonBlocking=false); // private: uint32_t readCtl(uint32_t addr); void writeCtl(uint32_t addr, uint32_t data); uint64_t read(uint32_t addr); void write(uint32_t addr, uint64_t data); uint32_t read32(uint32_t addr); void write32(uint32_t addr, uint32_t data); uint64_t read64(uint32_t addr); void write64(uint32_t addr, uint64_t data); void write128(uint32_t addr, uint64_t udata, uint64_t ldata); uint64_t bramRead(uint32_t addr); void bramWrite(uint32_t addr, uint64_t data); void memserverWrite(); }; ================================================ FILE: lib/nvme/tcl/package.tcl ================================================ #----------------------------------------------------------- # Vivado v2016.2 (64-bit) # SW Build 1577090 on Thu Jun 2 16:32:35 MDT 2016 # IP Build 1577682 on Fri Jun 3 12:00:54 MDT 2016 # Start of session at: Tue Aug 2 13:39:27 2016 # Process ID: 17294 # Current directory: /home/jamey/connectal/tests/nvme_strstr # Command line: vivado # Log file: /home/jamey/connectal/tests/nvme_strstr/vivado.log # Journal file: /home/jamey/connectal/tests/nvme_strstr/vivado.jou #----------------------------------------------------------- start_gui create_project accel /home/jamey/connectal/tests/nvme_strstr/accel -part xc7vx485tffg1157-1 add_files -norecurse /home/jamey/connectal/tests/nvme_strstr/miniitx100/verilog/mkNvmeAccelerator.v update_compile_order -fileset sources_1 update_compile_order -fileset sim_1 ipx::package_project -root_dir /home/jamey/connectal/tests/nvme_strstr/miniitx100 -vendor user.org -library user -taxonomy /UserIP ipx::add_port_map TREADY [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]] ipx::add_port_map TVALID [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]] ipx::add_port_map TLAST [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]] ipx::add_port_map TDATA [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]] ipx::add_port_map TKEEP [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]] set_property physical_name dataOut_tready_v [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]]] set_property physical_name dataOut_tvalid [ipx::get_port_maps TVALID -of_objects [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]]] set_property physical_name dataOut_tlast [ipx::get_port_maps TLAST -of_objects [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]]] set_property physical_name dataOut_tdata [ipx::get_port_maps TDATA -of_objects [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]]] set_property physical_name dataOut_tkeep [ipx::get_port_maps TKEEP -of_objects [ipx::get_bus_interfaces dataOut -of_objects [ipx::current_core]]] ipx::associate_bus_interfaces -busif dataOut -clock CLK [ipx::current_core] ipx::add_port_map TREADY [ipx::get_bus_interfaces msgOut -of_objects [ipx::current_core]] set_property physical_name msgOut_tready_v [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces msgOut -of_objects [ipx::current_core]]] ipx::add_bus_interface msgIn [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:axis_rtl:1.0 [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:axis:1.0 [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] ipx::add_port_map TVALID [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] set_property physical_name msgIn_tvalid_v [ipx::get_port_maps TVALID -of_objects [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]]] ipx::add_port_map TLAST [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] set_property physical_name msgIn_tlast_v [ipx::get_port_maps TLAST -of_objects [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]]] ipx::add_port_map TDATA [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] set_property physical_name msgIn_tdata_v [ipx::get_port_maps TDATA -of_objects [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]]] ipx::add_port_map TKEEP [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] set_property physical_name msgIn_tkeep_v [ipx::get_port_maps TKEEP -of_objects [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]]] ipx::add_port_map TREADY [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]] set_property physical_name msgIn_tready [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces msgIn -of_objects [ipx::current_core]]] ipx::associate_bus_interfaces -busif msgIn -clock CLK [ipx::current_core] ipx::associate_bus_interfaces -busif msgOut -clock CLK [ipx::current_core] ipx::associate_bus_interfaces -busif dataOut -clock CLK [ipx::current_core] ipx::infer_bus_interface RST_N xilinx.com:signal:reset_rtl:1.0 [ipx::current_core] ipx::add_bus_interface nvme_pcie_mgt [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:pcie_7x_mgt_rtl:1.0 [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:pcie_7x_mgt:1.0 [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] ipx::add_port_map rxn [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pins_pcie_exp_rxn_v [ipx::get_port_maps rxn -of_objects [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]]] ipx::add_port_map txn [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pins_pcie_exp_txn [ipx::get_port_maps txn -of_objects [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]]] ipx::add_port_map rxp [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pins_pcie_exp_rxp_v [ipx::get_port_maps rxp -of_objects [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]]] ipx::add_port_map txp [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pins_pcie_exp_txp [ipx::get_port_maps txp -of_objects [ipx::get_bus_interfaces nvme_pcie_mgt -of_objects [ipx::current_core]]] ipx::add_bus_interface pcie_ref_clk [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:diff_clock_rtl:1.0 [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:diff_clock:1.0 [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]] set_property interface_mode slave [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]] ipx::add_port_map CLK_P [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]] set_property physical_name pins_pcie_refclk_p [ipx::get_port_maps CLK_P -of_objects [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]]] ipx::add_port_map CLK_N [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]] set_property physical_name pins_pcie_refclk_n [ipx::get_port_maps CLK_N -of_objects [ipx::get_bus_interfaces pcie_ref_clk -of_objects [ipx::current_core]]] ipx::add_bus_interface pcie_sys_reset_n [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:signal:reset_rtl:1.0 [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:signal:reset:1.0 [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] ipx::add_port_map RST [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property physical_name RST_N_pins_pcie_sys_reset_n [ipx::get_port_maps RST -of_objects [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]]] set_property core_revision 2 [ipx::current_core] ipx::create_xgui_files [ipx::current_core] ipx::update_checksums [ipx::current_core] ipx::save_core [ipx::current_core] set_property ip_repo_paths /home/jamey/connectal/tests/nvme_strstr/miniitx100 [current_project] update_ip_catalog ipx::check_integrity -quiet [ipx::current_core] #ipx::archive_core /home/jamey/connectal/tests/nvme_strstr/miniitx100/user.org_user_mkNvmeAccelerator_1.0.zip [ipx::current_core] ================================================ FILE: lib/qemu/fpgadev.cpp ================================================ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "fpgadev.h" #ifdef REGISTER_SPIKE_DEVICES #include #include #include #endif int verbose = 0; std::mutex mutex; void sem_wait_with_timeout(sem_t *sem) { struct timespec timeout; for (int tries = 0; tries < 10; tries++) { clock_gettime(CLOCK_REALTIME, &timeout); timeout.tv_sec += 1; int status = sem_timedwait(sem, &timeout); if (status == 0) { return; } else if (errno == ETIMEDOUT) { if (tries > 5) fprintf(stderr, "%s:%d: try %d timed out waiting for response status=%d errno=%d:%s\n", __FILE__, __LINE__, tries, status, errno, strerror(errno)); } else { fprintf(stderr, "%s:%d errno=%d:%s\n", __FUNCTION__, __LINE__, errno, strerror(errno)); return; } } fprintf(stderr, "%s:%d timed out waiting for semaphore\n", __FUNCTION__, __LINE__); } int readReq; int readCount; class MemServerPortalResponse : public MemServerPortalResponseWrapper { sem_t sem; public: int irq; uint32_t buf[16]; IrqCallback irqCallback; void wait() { sem_wait_with_timeout(&sem); } void read32Done ( const uint32_t value ) { buf[0] = value; if (0 || verbose) fprintf(stderr, "readDone value=%08x count=%d\n", value, readCount++); sem_post(&sem); } void read64Done ( const uint64_t value ) { *(uint64_t *)buf = value; if (0 || verbose) fprintf(stderr, "readDone value=%08llx count=%d\n", (long long)value, readCount++); sem_post(&sem); } void writeDone ( ) { if (verbose) fprintf(stderr, "writeDone\n"); sem_post(&sem); } MemServerPortalResponse(unsigned int id, IrqCallback callback=0) : MemServerPortalResponseWrapper(id), irq(0), irqCallback(callback) { sem_init(&sem, 0, 0); } }; class QemuAccelIndication : public QemuAccelIndicationWrapper { private: sem_t sem; public: QemuAccelIndication(int id, PortalPoller *poller = 0) : QemuAccelIndicationWrapper(id, poller) { sem_init(&sem, 0, 0); } virtual ~QemuAccelIndication() {} virtual void started ( ) { } virtual void wait() { sem_wait_with_timeout(&sem); } }; class SerialIndication : public SerialIndicationWrapper { private: public: SerialIndication(int id, PortalPoller *poller = 0) : SerialIndicationWrapper(id, poller) { } virtual ~SerialIndication() {} virtual void rx (const uint8_t ch) { fprintf(stderr, "%c", ch); } }; class BlockDevRequest; class BlockDevRequest : public BlockDevRequestWrapper { private: FpgaDev *fpgaDev; BlockDevResponseProxy *response; int driveFd; std::queue responseQueue; sem_t worker_sem; std::mutex rqmutex; std::thread rqthread; static void blockDevWorker(BlockDevRequest *blockdev); public: BlockDevRequest(FpgaDev *fpgaDev, BlockDevResponseProxy *response, int id, PortalPoller *poller = 0) : BlockDevRequestWrapper(id, poller), fpgaDev(fpgaDev), response(response) { const char *driveName = getenv("FPGADEV_BLOCKDEV_FILE"); if (driveName) { driveFd = open(driveName, O_RDWR); fprintf(stderr, "Opened blockdev %s fd %d\n", driveName, driveFd); } sem_init(&worker_sem, 0, 0); rqthread = std::thread(blockDevWorker, this); } virtual ~BlockDevRequest() {} virtual void transfer ( const BlockDevOp op, const uint32_t dramaddr, const uint32_t offset, const uint32_t size, const uint32_t tag ); }; void BlockDevRequest::blockDevWorker(BlockDevRequest *blockdev) { fprintf(stderr, "%s:%d started\n", __FUNCTION__, __LINE__); while (1) { int tag = -1; sem_wait(&blockdev->worker_sem); { std::lock_guard lock(blockdev->rqmutex); tag = blockdev->responseQueue.front(); blockdev->responseQueue.pop(); } if (tag != -1) { //std::lock_guard lock(mutex); blockdev->response->transferDone(tag); } } } void BlockDevRequest::transfer ( const BlockDevOp op, const uint32_t dramaddr, const uint32_t offset, const uint32_t size, const uint32_t tag ) { if (0) fprintf(stderr, "BlockDevRequest::transfer op=%x dramaddr=%x offset=%x size=%x tag=%x\n", op, dramaddr, offset, size, tag); if (fpgaDev->mainMemBuf) { if (op == BlockDevRead) { int numBytes = pread(driveFd, fpgaDev->mainMemBuf + dramaddr, size, offset); if (numBytes != (long)size) fprintf(stderr, "Read error size=%d numBytes=%d errno=%d:%s\n", size, numBytes, errno, strerror(errno)); } else { int numBytes = pwrite(driveFd, fpgaDev->mainMemBuf + dramaddr, size, offset); if (numBytes != (long)size) fprintf(stderr, "Read error size=%d numBytes=%d errno=%d:%s\n", size, numBytes, errno, strerror(errno)); } } { std::lock_guard lock(rqmutex); responseQueue.push(tag); sem_post(&worker_sem); } } MemServerPortalRequestProxy *request; MemServerPortalResponse *indication; FpgaDev::FpgaDev(IrqCallback callback) : request(0), indication(0), dmaManager(0), didReset(false), mainMemFd(0) { request = new MemServerPortalRequestProxy(IfcNames_MemServerPortalRequestS2H); indication = new MemServerPortalResponse(IfcNames_MemServerPortalResponseH2S, callback); qemuAccelRequest = new QemuAccelRequestProxy(IfcNames_QemuAccelRequestS2H); qemuAccelIndication = new QemuAccelIndication(IfcNames_QemuAccelIndicationH2S); serialRequest = new SerialRequestProxy(IfcNames_SerialRequestS2H); serialIndication = new SerialIndication(IfcNames_SerialIndicationH2S); blockDevResponse = new BlockDevResponseProxy(IfcNames_BlockDevResponseS2H); // responses to the risc-v blockDevRequest = new BlockDevRequest(this, blockDevResponse, IfcNames_BlockDevRequestH2S); // requests from the risc-v dmaManager = platformInit(); //std::lock_guard lock(mutex); qemuAccelRequest->reset(); fprintf(stderr, "FpgaDev::FpgaDev\n"); for (int i = 0; i < 20; i++) { request->write32(0xc0003020, '*'); indication->wait(); } } FpgaDev::~FpgaDev() { //delete request; //delete indication; request = 0; indication = 0; } void FpgaDev::maybeReset() { if (0) if (!didReset) { //std::lock_guard lock(mutex); qemuAccelRequest->reset(); qemuAccelIndication->wait(); //request->setParameters(50, 0); didReset = true; } } void FpgaDev::status() { //std::lock_guard lock(mutex); qemuAccelRequest->status(); qemuAccelIndication->wait(); } void FpgaDev::setupDma(uint32_t memfd) { //std::lock_guard lock(mutex); int memref = dmaManager->reference(memfd); fprintf(stderr, "FpgaDev::setupDma memfd=%d memref=%d\n", memfd, memref); qemuAccelRequest->setupDma(memref); } void FpgaDev::read(unsigned long offset, uint8_t *buf) { maybeReset(); //std::lock_guard lock(mutex); int count = readReq++; if (0 || verbose) fprintf(stderr, "FpgaDev::read offset=%lx count=%d\n", offset, count); request->read32(offset); indication->wait(); if (0 || verbose) fprintf(stderr, "FpgaDev::read offset=%lx value=%x count=%d\n", offset, *(uint32_t *)indication->buf, count); memcpy(buf, indication->buf, 4); } void FpgaDev::write(unsigned long offset, const uint8_t *buf) { maybeReset(); //std::lock_guard lock(mutex); if (verbose) fprintf(stderr, "FpgaDev::write offset=%lx value=%x\n", offset, *(uint32_t *)buf); request->write32(offset, *(uint32_t *)buf); indication->wait(); //request->status(); //indication->wait(); } uint32_t FpgaDev::read(unsigned long offset) { maybeReset(); //std::lock_guard lock(mutex); int count = readReq++; if (0 || verbose) fprintf(stderr, "FpgaDev::read offset=%08lx count=%d\n", offset, count); request->read32(offset); indication->wait(); if (0 || verbose) fprintf(stderr, "FpgaDev::read done value=%x count=%d\n", *(uint32_t *)indication->buf, count); return *(uint32_t *)indication->buf; } void FpgaDev::write(unsigned long offset, const uint32_t value) { maybeReset(); //std::lock_guard lock(mutex); if (verbose) fprintf(stderr, "FpgaDev::write offset=%08lx value=%x\n", offset, value); request->write32(offset, value); indication->wait(); if (verbose) fprintf(stderr, "FpgaDev::write done\n"); } bool FpgaDev::hasInterrupt() { return indication->irq; } void FpgaDev::clearInterrupt() { indication->irq = 0; } char *FpgaDev::allocate_mem(size_t memsz) { int memfd = portalAlloc(memsz, 1); if (memfd < 0) return 0; char *buf = (char *)portalMmap(memfd, memsz); if (buf == MAP_FAILED) { close(memfd); return 0; } fprintf(stderr, "FpgaDev::allocate_mem memsz=%lx memfd=%d buf=%p\n", memsz, memfd, buf); if (!mainMemFd) { setupDma(memfd); mainMemFd = memfd; mainMemBuf = buf; fprintf(stderr, "FpgaDev::allocate_mem mainMemFd=%d\n", memfd); } return buf; } FpgaDev *fpgaDev; #ifdef REGISTER_SPIKE_DEVICES class spikehw_device_t : public abstract_device_t { public: spikehw_device_t(); bool has_interrupt(); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); static abstract_device_t *make_device(); }; spikehw_device_t::spikehw_device_t() { if (!fpgaDev) fpgaDev = new FpgaDev(); } bool spikehw_device_t::has_interrupt() { if (fpgaDev->hasInterrupt()) { fpgaDev->clearInterrupt(); return true; } return false; } bool spikehw_device_t::load(reg_t addr, size_t len, uint8_t* bytes) { int count=readReq++; fprintf(stderr, "%s:%d addr=%x count=%d\n", __FUNCTION__, __LINE__, addr, count); fpgaDev->read32(addr, bytes); // always reads 4 bytes fprintf(stderr, "%s:%d addr=%x -> value %x count=%d\n", __FUNCTION__, __LINE__, addr, *(int *)bytes, count); return true; } bool spikehw_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) { fpgaDev->write32(addr, bytes); return true; } abstract_device_t *spikehw_device_t::make_device() { std::cerr << "make_device called" << std::endl; return new spikehw_device_t(); } class spikeflash_device_t : public abstract_device_t { public: spikeflash_device_t(); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); static abstract_device_t *make_device(); }; spikeflash_device_t::spikeflash_device_t() { if (!fpgaDev) fpgaDev = new FpgaDev(); } bool spikeflash_device_t::load(reg_t addr, size_t len, uint8_t* bytes) { if (addr & 1 && len != 1) fprintf(stderr, "spikeflash::load addr=%08lx len=%ld\n", addr, len); if (addr & 1) { uint8_t data[2]; fpgaDev->readFlash(addr, data); // always reads 4 bytes bytes[0] = data[1]; if (len > 1) return false; else return true; } while (len) { fpgaDev->readFlash(addr, bytes); // always reads 4 bytes if (len < 2) break; addr += 2; bytes += 2; len -= 2; } return true; } bool spikeflash_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) { //fprintf(stderr, "spikeflash::store addr=%08lx len=%ld bytes=%02x\n", addr, len, *(uint16_t *)bytes); if (len != 2) return false; fpgaDev->writeFlash(addr, bytes); return true; } abstract_device_t *spikeflash_device_t::make_device() { std::cerr << "spikeflash_device_t::make_device called" << std::endl; return new spikeflash_device_t(); } class devicetree_device_t : public abstract_device_t { public: devicetree_device_t(); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); static abstract_device_t *make_device(); private: const char *dtb; size_t dtbsz; }; devicetree_device_t::devicetree_device_t() { int fd = open("devicetree.dtb", O_RDONLY); if (fd > 0) { struct stat statbuf; int status = fstat(fd, &statbuf); fprintf(stderr, "fstat status %d size %ld\n", status, statbuf.st_size); if (status == 0) { dtb = (const char *)mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); dtbsz = statbuf.st_size; fprintf(stderr, "mapped dtb at %p (%ld bytes)\n", dtb, dtbsz); } close(fd); } else { fprintf(stderr, "Could not open devicetree.dtb\n"); } } bool devicetree_device_t::load(reg_t addr, size_t len, uint8_t* bytes) { if (dtb && dtb != MAP_FAILED) { if ((addr < dtbsz) && (bytes != 0)) { memcpy(bytes, dtb + addr, len); return true; } } return false; } bool devicetree_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) { return true; } abstract_device_t *devicetree_device_t::make_device() { std::cerr << "devicetree_device_t::make_device called" << std::endl; return new devicetree_device_t(); } //REGISTER_MEM_ALLOCATOR(FpgaDev::allocate_mem); REGISTER_DEVICE(devicetree, 0x04080000, devicetree_device_t::make_device); REGISTER_DEVICE(spikehw, 0x04100000, spikehw_device_t::make_device); REGISTER_DEVICE(spikeflash, 0x08000000, spikeflash_device_t::make_device); #endif #ifndef REGISTER_SPIKE_DEVICES extern "C" { struct FpgaOps { uint64_t (*read)(uint64_t addr); void (*write)(uint64_t addr, uint64_t value); void (*close)(); void *(*alloc_mem)(size_t size); }; uint64_t fpga_read(uint64_t addr) { uint64_t val = fpgaDev->read(0x100000 + addr); return val; } void fpga_write(uint64_t addr, uint64_t value) { fpgaDev->write(0x100000 + addr, value); } void fpga_close() { } void *fpga_alloc_mem(size_t size) { return (void *)fpgaDev->allocate_mem(size);; } void *fpgadev_init(void (*irqCallback)(int irq)) { fprintf(stderr, "connectal.so init called\n"); if (!fpgaDev) fpgaDev = new FpgaDev(irqCallback); struct FpgaOps *ops = (struct FpgaOps *)malloc(sizeof(struct FpgaOps)); ops->read = fpga_read; ops->write = fpga_write; ops->close = fpga_close; ops->alloc_mem = fpga_alloc_mem; return ops; } } #endif ================================================ FILE: lib/qemu/fpgadev.h ================================================ #ifndef SPIKEHW_H #define SPIKEHW_H #include class BlockDevResponseProxy; // responses sent to the risc-v class BlockDevRequest; // requests received from the risc-v class MemServerPortalRequestProxy; class MemServerPortalResponse; class DmaManager; class QemuAccelRequestProxy; class QemuAccelIndication; class SerialIndication; class SerialRequest; typedef void (*IrqCallback)(int irq); class FpgaDev { public: FpgaDev(IrqCallback callback=0); ~FpgaDev(); int irq ( const uint8_t newLevel ); void status(); void read(unsigned long offset, uint8_t *buf); void write(unsigned long offset, const uint8_t *buf); uint32_t read(unsigned long offset); void write(unsigned long offset, const uint32_t value); void setFlashParameters(unsigned long cycles); void readFlash(unsigned long offset, uint8_t *buf); void writeFlash(unsigned long offset, const uint8_t *buf); bool hasInterrupt(); void clearInterrupt(); char *allocate_mem(size_t memsz); private: void setupDma( uint32_t memfd ); BlockDevResponseProxy *blockDevResponse; BlockDevRequest *blockDevRequest; MemServerPortalRequestProxy *request; MemServerPortalResponse *indication; QemuAccelRequestProxy *qemuAccelRequest; QemuAccelIndication *qemuAccelIndication; SerialRequestProxy *serialRequest; SerialIndication *serialIndication; DmaManager *dmaManager; bool didReset; int mainMemFd; char *mainMemBuf; void maybeReset(); friend class BlockDevRequest; }; #endif ================================================ FILE: lib/rbm/bsv/DmaVector.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; import GetPut::*; import ClientServer::*; import FIFOF::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Adapter::*; import BRAM::*; import Pipe::*; import RbmTypes::*; import ConnectalMemTypes::*; typedef 8 BurstLen; interface VectorSource#(numeric type dsz, type a); interface PipeOut#(a) pipe; method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); method ActionValue#(Bool) finish(); endinterface module mkMemReadVectorSource#(MemReadEngineServer#(asz) memreadServer)(VectorSource#(asz, a)) provisos (Bits#(a,asz), Div#(asz,8,abytes), Log#(abytes,ashift), Mul#(abytes, 8, asz) ); Bool verbose = False; let asz = valueOf(asz); let ashift = valueOf(ashift); function Bit#(dataWidth) memData_data(MemDataF#(dataWidth) d); return d.data; endfunction method Action start(SGLId p, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); if (verbose) $display("mkMemReadVectorSource: start h=%d a=%h l=%h ashift=%d", p, a, l, ashift); memreadServer.request.put(MemengineCmd { sglId: p, base: a << ashift, len: truncate(l << ashift), burstLen: (fromInteger(valueOf(BurstLen)) << ashift), tag: 0}); endmethod method ActionValue#(Bool) finish(); return memreadServer.data.first().last; endmethod interface PipeOut pipe = mapPipe(unpack, mapPipe(memData_data, memreadServer.data)); endmodule interface VectorSink#(numeric type dsz, type a); interface PipeIn#(a) pipe; method Action start(SGLId h, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); method ActionValue#(Bool) finish(); endinterface module mkMemWriteVectorSink#(MemWriteEngineServer#(asz) memwriteServer)(VectorSink#(asz, a)) provisos (Bits#(a,asz), Div#(asz,8,abytes), Log#(abytes,ashift), Mul#(abytes, 8, asz) ); Bool verbose = False; let asz = valueOf(asz); let ashift = valueOf(ashift); method Action start(SGLId p, Bit#(MemOffsetSize) a, Bit#(MemOffsetSize) l); if (verbose) $display("mkMemWriteVectorSink: start h=%d a=%h l=%h ashift=%d", p, a, l, ashift); // I set burstLen==1 so that testmm works for all J,K,N. If we want burst writes we will need to rethink this (mdk) let cmd = MemengineCmd { sglId: p, base: a << ashift, len: truncate(l << ashift), burstLen: fromInteger(valueOf(abytes)), tag: 0}; memwriteServer.request.put(cmd); //$display("mkMemWriteVectorSink: %d %d %d %d", cmd.sglId, cmd.base, cmd.len, cmd.burstLen); endmethod method finish = memwriteServer.done.get; interface PipeIn pipe = mapPipeIn(pack, memwriteServer.data); endmodule ================================================ FILE: lib/rbm/bsv/Rbm.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFO::*; import FIFOF::*; import DefaultValue::*; import GetPut::*; import ClientServer::*; import Connectable::*; import FloatingPoint::*; import BRAM::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import DmaVector::*; import HostInterface::*; import MemReadEngine::*; import MemWriteEngine::*; import MatrixTN::*; import Timer::*; import Sigmoid::*; import FloatOps::*; import Pipe::*; import RbmTypes::*; import DotProdServer::*; function Float tokenValue(MmToken v) = v.v; interface StatesPipe#(numeric type n, numeric type dmasz); method Action start(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) readPointer2, Bit#(32) readOffset2, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numElts); method ActionValue#(Bool) finish(); endinterface module mkComputeStatesPipe#(PipeOut#(Vector#(n, Float)) pipe_in, PipeOut#(Vector#(n, Float)) randomPipe, PipeIn#(Vector#(n,Float)) writePipe)(PipeOut#(Vector#(n, Float))) provisos(Add#(a__, 1, n)); function Float greater(Float a, Float b); if (compareFP(a, b) == GT) return 1.0; else return 0.0; endfunction function Vector#(n, Float) vgreater(Vector#(n, Float) x, Vector#(n, Float) y); return map(uncurry(greater), zip(x, y)); endfunction rule foo; let vs <- toGet(pipe_in).get; let rs <- toGet(randomPipe).get; let gs = vgreater(vs, rs); //$display($format(fshow("vs=")+fshow(pack(vs)) + fshow(" rs=") + fshow(pack(rs)) + fshow(" states=") + fshow(gs))); writePipe.enq(gs); endrule endmodule module mkStatesPipe#(Vector#(2,MemReadEngineServer#(TMul#(N,32))) readSrvrs, Vector#(1,MemWriteEngineServer#(TMul#(N,32))) writeSrvrs)(StatesPipe#(N, DmaSz)) provisos ( Bits#(Vector#(N, Float), DmaSz) ,Log#(N,nshift)); let verbose = True; let nshift = valueOf(nshift); Vector#(2, VectorSource#(DmaSz, Vector#(N,Float))) statesources <- mapM(mkMemReadVectorSource, readSrvrs); VectorSink#(DmaSz, Vector#(N, Float)) dmaStatesSink <- mkMemWriteVectorSink(writeSrvrs[0]); PipeOut#(Vector#(N, Float)) dmaStatesPipe <- mkComputeStatesPipe(statesources[0].pipe, statesources[1].pipe, dmaStatesSink.pipe); method Action start(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) readPointer2, Bit#(32) readOffset2, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numElts); statesources[0].start(readPointer, extend(readOffset), extend(unpack(numElts)>>nshift)); statesources[1].start(readPointer2, extend(readOffset2), extend(unpack(numElts)>>nshift)); dmaStatesSink.start(writePointer, extend(writeOffset), extend(unpack(numElts)>>nshift)); if (verbose) $display("mkStatesPipe::start(%d %d %d %d %d %d)", readPointer, readOffset, readPointer2, readOffset2, writePointer, writeOffset, numElts); endmethod method ActionValue#(Bool) finish(); let x0 <- statesources[0].finish; let x1 <- statesources[1].finish; let b <- dmaStatesSink.finish; return b; endmethod endmodule interface UpdateWeights#(numeric type n, numeric type dmasz); method Action start(Bit#(32) posAssociationsPointer, Bit#(32) negAssociationsPointer, Bit#(32) weightsPointer, Bit#(32) numElts, Float learningRateOverNumExamples); method ActionValue#(Bool) finish(); endinterface module mkUpdateWeights#(Vector#(3,MemReadEngineServer#(TMul#(N,32))) readSrvrs, Vector#(1,MemWriteEngineServer#(TMul#(N,32))) writeSrvrs)(UpdateWeights#(N, DmaSz)) provisos ( Bits#(Vector#(N, Float), DmaSz) ,Log#(N,nshift)); Vector#(3, VectorSource#(DmaSz, Vector#(N,Float))) sources <- mapM(mkMemReadVectorSource, readSrvrs); let n = valueOf(N); let nshift = valueOf(nshift); Reg#(Float) learningRateOverNumExamples <- mkReg(defaultValue); Vector#(N, FloatAlu) adders <- replicateM(mkFloatAdder(defaultValue)); Vector#(N, FloatAlu) adders2 <- replicateM(mkFloatAdder(defaultValue)); Vector#(N, FloatAlu) multipliers <- replicateM(mkFloatMultiplier(defaultValue)); VectorSink#(DmaSz, Vector#(N, Float)) sink <- mkMemWriteVectorSink(writeSrvrs[0]); // weights += learningRate * (pos_associations - neg_associations) / num_examples; rule sub; let pa = sources[0].pipe.first(); sources[0].pipe.deq(); let na = sources[1].pipe.first(); sources[1].pipe.deq(); for (Integer i = 0; i < n; i = i+1) begin adders[i].request.put(tuple2(pa[i], -na[i])); end endrule rule mul; for (Integer i = 0; i < n; i = i+1) begin let sumexc <- adders[i].response.get(); multipliers[i].request.put(tuple2(learningRateOverNumExamples, tpl_1(sumexc))); end endrule rule add; let weights = sources[2].pipe.first(); sources[2].pipe.deq(); for (Integer i = 0; i < n; i = i+1) begin let resultexc <- multipliers[i].response.get(); adders2[i].request.put(tuple2(weights[i], tpl_1(resultexc))); end endrule rule result; Vector#(N, Float) r; for (Integer i = 0; i < n; i = i+1) begin let resultexc <- adders2[i].response.get(); r[i] = tpl_1(resultexc); end sink.pipe.enq(r); endrule for (Integer i = 0; i < 3; i = i + 1) rule finishSources; let b <- sources[i].finish(); endrule method Action start(Bit#(32) posAssociationsPointer, Bit#(32) negAssociationsPointer, Bit#(32) weightsPointer, Bit#(32) numElts, Float lrone); learningRateOverNumExamples <= lrone; sources[0].start(posAssociationsPointer, 0, extend(numElts)>>nshift); sources[1].start(negAssociationsPointer, 0, extend(numElts)>>nshift); sources[2].start(weightsPointer, 0, extend(numElts)>>nshift); sink.start(weightsPointer, 0, extend(numElts)>>nshift); endmethod method ActionValue#(Bool) finish(); let b <- sink.finish(); return b; endmethod endmodule interface SumOfErrorSquaredDebug; interface PipeOut#(Bit#(32)) macCount; endinterface interface SumOfErrorSquared#(numeric type n, numeric type dmasz); interface PipeOut#(Float) pipe; method Action start(Bit#(32) dataPointer, Bit#(32) predPointer, Bit#(32) numElts); interface SumOfErrorSquaredDebug debug; endinterface module mkSumOfErrorSquared#(Vector#(2,MemReadEngineServer#(TMul#(N,32))) readSrvrs)(SumOfErrorSquared#(N, DmaSz)) provisos ( Bits#(Vector#(N, Float), DmaSz) ,Log#(N,nshift)); Vector#(2, VectorSource#(DmaSz, Vector#(N,Float))) sources <- mapM(mkMemReadVectorSource, readSrvrs); let n = valueOf(N); let nshift = valueOf(nshift); SharedDotProdServer#(1) dotprod <- mkSharedInterleavedDotProdServerConfig(0); FirstLastPipe#(Bit#(MemOffsetSize)) firstlastPipe <- mkFirstLastPipe(); PipeOut#(Float) aPipe <- mkFunnel1(sources[0].pipe); PipeOut#(Float) bPipe <- mkFunnel1(sources[1].pipe); let joinPipe <- mkJoin(tuple2, aPipe, bPipe); let subPipe <- mkFloatSubPipe(joinPipe); rule fromsub; match {.first, .last} <- toGet(firstlastPipe.pipe).get(); let diff <- toGet(subPipe).get(); MmToken t = MmToken { v: diff, first: first, last: last }; dotprod.aInput.put(t); dotprod.bInput.put(t); //$display("%d %d", first, last); endrule for (Integer i = 0; i < 2; i = i + 1) rule finishSources; let b <- sources[i].finish(); endrule interface PipeOut pipe = mapPipe(tokenValue, dotprod.pipes[0]); method Action start(Bit#(32) dataPointer, Bit#(32) predPointer, Bit#(32) numElts); sources[0].start(dataPointer, 0, extend(numElts)>>nshift); sources[1].start(predPointer, 0, extend(numElts)>>nshift); firstlastPipe.start(extend(numElts)); endmethod interface SumOfErrorSquaredDebug debug; interface PipeOut macCount = dotprod.debug.macCount; endinterface endmodule: mkSumOfErrorSquared interface Rbm#(numeric type n); interface RbmRequest rbmRequest; interface SigmoidRequest sigmoidRequest; interface MmRequestTN mmRequest; interface TimerRequest timerRequest; interface Vector#(3,MemReadClient#(TMul#(32,n))) readClients; interface Vector#(3,MemWriteClient#(TMul#(32,n))) writeClients; endinterface module mkRbm#(HostInterface host, RbmIndication rbmInd, SigmoidIndication sigmoidInd, MmIndication mmInd, TimerIndication timerInd)(Rbm#(N)) provisos (Add#(1,a__,N), Add#(N,0,n), Mul#(N,32,DmaSz)); let n = valueOf(n); // TODO: figure out the correct amount of buffering required MemReadEngine#(TMul#(n,32),TMul#(n,32),2, 9) readEngine <- mkMemReadEngine; MemWriteEngine#(TMul#(n,32),TMul#(n,32),2, 3) writeEngine <- mkMemWriteEngine; let res = readEngine.readServers; let wes = writeEngine.writeServers; SigmoidIfc#(TMul#(32,n)) sigmoid <- mkSigmoid(takeAt(0,res), takeAt(0,wes)); // 2 read, 1 write StatesPipe#(N, DmaSz) states <- mkStatesPipe(takeAt(2,res), takeAt(1,wes)); // 2 read, 1 write UpdateWeights#(N, DmaSz) updateWeights <- mkUpdateWeights(takeAt(4,res), takeAt(2,wes)); // 3 read, 1 write SumOfErrorSquared#(N, DmaSz) sumOfErrorSquared <- mkSumOfErrorSquared(takeAt(7,res)); // 2 read, 0 write MmTNInternal#(N) mm <- mkMmTNInternal(host); /////////////////////////////////////////////// // timing cruft FIFOF#(Bool) busyFifo <- mkFIFOF(); FIFOF#(Bool) timerRunning <- mkFIFOF(); Reg#(Bit#(64)) cycleCount <- mkReg(0); Reg#(Bit#(64)) idleCount <- mkReg(0); rule countCycles if (timerRunning.notEmpty()); cycleCount <= cycleCount + 1; if (!busyFifo.notEmpty()) idleCount <= idleCount + 1; endrule /////////////////////////////////////////////// /////////////////////////////////////////////// // sigmoid indication rule sigmoidDone; sigmoid.sigmoidDone(); sigmoidInd.sigmoidDone(); busyFifo.deq; endrule rule sigmoidTableUpdateDone; let b <- sigmoid.updateDone(); sigmoidInd.tableUpdated(0); busyFifo.deq; endrule /////////////////////////////////////////////// /////////////////////////////////////////////// // mm indication rule mmfDone; let d <- mm.mmfDone; busyFifo.deq(); mmInd.mmfDone(d); endrule rule mmDebugDone; let d <- mm.debugDone; mmInd.debug(d); endrule FIFO#(Bit#(32)) sumOfErrorSquaredDebugFifo <- mkFIFO(); rule sumOfErrorSquaredDebugRule; let unused <- toGet(sumOfErrorSquaredDebugFifo).get(); let macCount <- toGet(sumOfErrorSquared.debug.macCount).get(); rbmInd.sumOfErrorSquaredDebug(macCount); endrule /////////////////////////////////////////////// /////////////////////////////////////////////// // rbm indication rule statesDone; $display("statesDone"); let b <- states.finish(); rbmInd.statesDone(); busyFifo.deq; endrule rule updateWeightsDone; $display("updateWeightsDone"); let b <- updateWeights.finish(); rbmInd.updateWeightsDone(); busyFifo.deq; endrule rule sumOfErrorSquaredDone; $display("sumOfErrorSquaredDone"); sumOfErrorSquared.pipe.deq(); rbmInd.sumOfErrorSquared(pack(sumOfErrorSquared.pipe.first())); busyFifo.deq; endrule /////////////////////////////////////////////// interface TimerRequest timerRequest; method Action startTimer() if (!timerRunning.notEmpty()); cycleCount <= 0; idleCount <= 0; timerRunning.enq(True); endmethod method Action stopTimer(); timerRunning.deq(); timerInd.elapsedCycles(cycleCount, idleCount); endmethod endinterface interface MmRequestTN mmRequest; method Action mmf(Bit#(32) h1, Bit#(32) r1, Bit#(32) c1, Bit#(32) h2, Bit#(32) r2, Bit#(32) c2, Bit#(32) h3, Bit#(32) r1_x_c1, Bit#(32) c1_x_j, Bit#(32) r1_x_c2, Bit#(32) c2_x_j, Bit#(32) c1_x_c2, Bit#(32) r2_x_c2); mm.mmRequest.mmf(h1,r1,c1, h2,r2,c2, h3, r1_x_c1, c1_x_j, r1_x_c2, c2_x_j, c1_x_c2, r2_x_c2); busyFifo.enq(True); endmethod method Action debug = mm.mmRequest.debug; endinterface interface RbmRequest rbmRequest; method Action finish(); $finish(0); endmethod method Action computeStates(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) readPointer2, Bit#(32) readOffset2, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numElts); states.start(readPointer, readOffset, readPointer2, readOffset2, writePointer,writeOffset, numElts); busyFifo.enq(True); endmethod method Action updateWeights(Bit#(32) posAssociationsPointer, Bit#(32) negAssociationsPointer, Bit#(32) weightsPointer, Bit#(32) numElts, Bit#(32) learningRateOverNumExamples); updateWeights.start(posAssociationsPointer, negAssociationsPointer, weightsPointer, numElts, unpack(learningRateOverNumExamples)); busyFifo.enq(True); endmethod method Action sumOfErrorSquared(Bit#(32) dataPointer, Bit#(32) predPointer, Bit#(32) numElts); sumOfErrorSquared.start(dataPointer, predPointer, numElts); busyFifo.enq(True); endmethod method Action sumOfErrorSquaredDebug(); sumOfErrorSquaredDebugFifo.enq(0); endmethod endinterface interface SigmoidRequest sigmoidRequest; method Action sigmoid(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numvalues); sigmoid.sigmoidRequest.sigmoid(readPointer, readOffset, writePointer, writeOffset, numvalues); busyFifo.enq(True); endmethod method Action setLimits(Bit#(32) rscale, Bit#(32) llimit, Bit#(32) ulimit); sigmoid.sigmoidRequest.setLimits(rscale, llimit, ulimit); endmethod method Action updateTable(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) numvalues); sigmoid.sigmoidRequest.updateTable(readPointer, readOffset, numvalues); busyFifo.enq(True); endmethod method Action tableSize(); sigmoidInd.tableSize(sigmoid.tableSize); endmethod endinterface interface Vector readClients = cons(readEngine.dmaClient,mm.readClients); interface Vector writeClients = cons(writeEngine.dmaClient,mm.writeClients); endmodule ================================================ FILE: lib/rbm/bsv/RbmTypes.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FloatingPoint::*; typedef 20 MMSize; `ifdef DataBusWidth typedef TDiv#(`DataBusWidth,32) N; `else `ifndef N_VALUE typedef 1 N; `else typedef `N_VALUE N; `endif `endif `ifndef J_VALUE typedef 1 J; `else typedef `J_VALUE J; `endif `ifndef K_VALUE typedef 1 K; `else typedef `K_VALUE K; `endif typedef `NumberOfMasters NumberOfMasters; typedef TMin#(4,J) RowsPerTile; typedef TDiv#(J,RowsPerTile) T; typedef TMul#(32,N) DmaSz; interface MmIndication; method Action started(); method Action startSourceAndSink(UInt#(32) startA, UInt#(32) startC, Int#(32) jint); method Action debug(Bit#(32) macCount); method Action mmfDone(Bit#(64) cycles); endinterface interface MmRequestNT; method Action debug(); method Action mmf(Bit#(32) inPointer1, Bit#(32) r1, Bit#(32) c1, Bit#(32) inPointer2, Bit#(32) r2, Bit#(32) c2, Bit#(32) outPointer, Bit#(32) r1_x_c1, Bit#(32) c1_x_j, Bit#(32) r2_x_c2, Bit#(32) c2_x_k, Bit#(32) r1_x_r1, Bit#(32) r2_x_j); endinterface interface MmRequestTN; method Action debug(); method Action mmf(Bit#(32) inPointer1, Bit#(32) r1, Bit#(32) c1, Bit#(32) inPointer2, Bit#(32) r2, Bit#(32) c2, Bit#(32) outPointer, Bit#(32) r1_x_c1, Bit#(32) c1_x_j, Bit#(32) r1_x_c2, Bit#(32) c2_x_j, Bit#(32) c1_x_c2, Bit#(32) r2_x_c2); endinterface interface SigmoidIndication; method Action sigmoidDone(); method Action tableSize(Bit#(32) size); method Action tableUpdated(Bit#(32) addr); endinterface interface SigmoidRequest; method Action sigmoid(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numElts); method Action setLimits(Bit#(32) rscale, Bit#(32) llimit, Bit#(32) ulimit); method Action tableSize(); method Action updateTable(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) numElts); endinterface interface RbmIndication; method Action statesDone(); method Action updateWeightsDone(); method Action sumOfErrorSquared(Bit#(32) error); method Action sumOfErrorSquaredDebug(Bit#(32) macCount); method Action dbg(Bit#(32) a, Bit#(32) b, Bit#(32) c, Bit#(32) d); endinterface interface RbmRequest; //method Action sglist(Bit#(32) off, Bit#(40) addr, Bit#(32) len); method Action paref(Bit#(32) addr, Bit#(32) len); method Action computeStates(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) readPointer2, Bit#(32) readOffset2, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numElts); method Action updateWeights(Bit#(32) posAssociationsPointer, Bit#(32) negAssociationsPointer, Bit#(32) weightsPointer, Bit#(32) numElts, Bit#(32) learningRateOverNumExamples); method Action sumOfErrorSquared(Bit#(32) dataPointer, Bit#(32) predPointer, Bit#(32) numElts); method Action sumOfErrorSquaredDebug(); method Action finish(); // for bsim only endinterface function Action check_dimension(Bit#(32) d); return (action Bit#(32) x = d/fromInteger(valueOf(N)); Bit#(32) y = x*fromInteger(valueOf(N)); if (y != d) begin $display("matrix dimension %d is not a multiple of %d", d, valueOf(N)); $finish(1); end endaction); endfunction ================================================ FILE: lib/rbm/bsv/Sigmoid.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import RegFile::*; import FIFO::*; import FIFOF::*; import Vector::*; import Connectable::*; import ClientServer::*; import Memory::*; import BRAM::*; import DefaultValue::*; import FloatingPoint::*; import Real::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import DmaVector::*; import Pipe::*; import FloatOps::*; import RbmTypes::*; import BUtils::*; interface SigmoidTable#(numeric type tsz); interface Vector#(2, BRAMServer#(Bit#(tsz), Vector#(3,Float))) ports; interface ReadOnly#(Float) rscale; interface ReadOnly#(Float) llimit; interface ReadOnly#(Float) ulimit; method Action setSigmoidLimits(Float rscale, Float llimit, Float ulimit); method Action updateSigmoidTable(Bit#(tsz) addr, Vector#(3,Float) v); method Bit#(32) tableSize(); endinterface module mkSigmoidTable(SigmoidTable#(tsz)); let tsz = valueOf(tsz); BRAM_Configure bramCfg = defaultValue; let memorySize = 2**tsz; bramCfg.memorySize = memorySize; BRAM2Port#(Bit#(tsz), Vector#(3, Float)) sigmoidTable <- mkBRAM2Server(bramCfg); Reg#(Float) rscaleReg <- mkReg(fromReal(0.0)); Reg#(Float) llimitReg <- mkReg(fromReal(0.0)); Reg#(Float) ulimitReg <- mkReg(fromReal(0.0)); Vector#(2, BRAMServer#(Bit#(tsz), Vector#(3,Float))) bramPorts; bramPorts[0] = sigmoidTable.portA; bramPorts[1] = sigmoidTable.portB; interface ReadOnly rscale = regToReadOnly(rscaleReg); interface ReadOnly llimit = regToReadOnly(llimitReg); interface ReadOnly ulimit = regToReadOnly(ulimitReg); interface Vector ports = bramPorts; method Action setSigmoidLimits(Float _rscale, Float _llimit, Float _ulimit); $display("setSigmoidLimits memorySize=%d\n", memorySize); rscaleReg <= _rscale; llimitReg <= _llimit; ulimitReg <= _ulimit; $display($format("rscale=", fshow(_rscale), "pack(rscale)=", fshow(pack(_rscale)), " llimit=", fshow(_llimit), " ulimit=", fshow(_ulimit))); endmethod method Action updateSigmoidTable(Bit#(tsz) addr, Vector#(3,Float) v); sigmoidTable.portB.request.put(BRAMRequest{ write: True, responseOnWrite: False, address: addr, datain: v}); endmethod method Bit#(32) tableSize(); return (1 << tsz); endmethod endmodule // Why was this not picked up from FloatingPoint.bsv??? function Integer bias( FloatingPoint#(e,m) din ); return (2 ** (valueof(e)-1)) - 1; endfunction function Int#(32) toInt32(FloatingPoint#(e,m) din); Int#(32) res = 0; if (isNaN(din)) res = 0; else if (isInfinity(din)) res = (din.sign) ? unpack('h80000000) : unpack('h7FFFFFFF); else begin // if the quantity is less than +/-1, it is zero. if (din.exp >= fromInteger(bias(din))) begin // be sure to re-add the hidden bit when converting. Bit#(TAdd#(m,1)) y = { 1, din.sfd }; y = y >> (fromInteger(bias(din)) + fromInteger(valueOf(m)) - din.exp); Bit#(32) r = cExtend(y); if (din.sign) res = unpack(~r + 1); else res = unpack(r); end end return res; endfunction module mkSigmoidServer#(Integer id, SigmoidTable#(tsz) sigmoidTable)(Server#(Float,Float)) provisos (Add#(tsz,2,usz), Add#(a__, usz, 32) ); let tsz = valueOf(tsz); Int#(usz) numEntries = 1< (numEntries/2-1)) index = truncate(pack(numEntries-1)); if (i < -numEntries/2) index = 0; if (verbose) $display("sigmoid lookupEntry i=%d index=%d numEntries=%d", i, index, numEntries); sigmoidTable.ports[0].request.put(BRAMRequest{ write: False, responseOnWrite: False, address: index, datain: ?}); endrule FIFOF#(Vector#(3, Float)) vFifo <- mkFIFOF(); rule computeDelta; let vs <- sigmoidTable.ports[0].response.get(); let angle <- toGet(angleFifo).get; if (verbose) $display("computeDelta angle=%h vs[0]=%h", pack(angle), pack(vs[0])); adder[1].request.put(tuple2(angle, vs[0])); vFifo.enq(vs); endrule rule interpolate; let vs <- toGet(vFifo).get; let result <- adder[1].response.get(); let delta = tpl_1(result); Exception e = tpl_2(result); if (verbose && pack(e) != 0) $display("interpolate.exception e=%h delta=%h", e, pack(delta)); if (verbose) $display("sigmoid interpolate delta=%h vs[1]=%h vs[2]", pack(delta), pack(vs[1]), pack(vs[2])); mul[0].request.put(tuple2(vs[2],delta)); adder_fifo.enq(vs[1]); endrule rule accumulate; match {.p, .*} <- mul[0].response.get; let v <- toGet(adder_fifo).get; adder[0].request.put(tuple2(v,p)); endrule interface Put request; method Action put(Float angle); let c = compareFP(angle, sigmoidTable.llimit); let d = compareFP(angle, sigmoidTable.ulimit); if (c == LT) angle = sigmoidTable.llimit; if (d == GT) angle = sigmoidTable.ulimit; angleFifo.enq(angle); mul[1].request.put(tuple2(angle, sigmoidTable.rscale)); if (verbose) $display("sigmoid request.put"); endmethod endinterface interface Get response; method ActionValue#(Float) get(); match {.v,.e} <- adder[0].response.get(); if (verbose && pack(e) != 0) $display("adder[0].exception e=%h v=%h", e, pack(v)); if (verbose) $display("sigmoid response.get"); return v; endmethod endinterface endmodule interface SigmoidIfc#(numeric type dsz); interface SigmoidRequest sigmoidRequest; method Action sigmoidDone; method Action updateDone; method Bit#(32) tableSize; endinterface module mkSigmoid#(Vector#(2,MemReadEngineServer#(TMul#(N,32))) readSrvrs, Vector#(1,MemWriteEngineServer#(TMul#(N,32))) writeSrvrs) (SigmoidIfc#(dsz)) provisos (Bits#(Float, fsz) , Add#(N,0,n) , Mul#(fsz,N,dmasz) , Bits#(Vector#(N,Float), dsz) , Mul#(dbytes, 8, dsz) , Div#(dsz, 8, dbytes) , Log#(n,nshift) ); let nshift = valueOf(nshift); Bool verbose = False; VectorSource#(dmasz, Vector#(n,Float)) source <- mkMemReadVectorSource(readSrvrs[0]); VectorSource#(dmasz, Vector#(n,Float)) tabsrc <- mkMemReadVectorSource(readSrvrs[1]); Vector#(n, SigmoidTable#(6)) sigmoidTables <- replicateM(mkSigmoidTable); Vector#(n, Server#(Float,Float)) sigmoidServers <- mapM(uncurry(mkSigmoidServer), zip(genVector,sigmoidTables)); Reg#(Bool) updatingSigmoidTable <- mkReg(False); Reg#(Bit#(6)) entryNumber <- mkReg(0); PipeOut#(Vector#(4, Float)) tabsrcs <- mkUnfunnel(tabsrc.pipe); Reg#(Bit#(32)) count <- mkReg(0); VectorSink#(TMul#(N,32),Vector#(N,Float)) sinkC <- mkMemWriteVectorSink(writeSrvrs[0]); rule updateSigmoidTableRule if (updatingSigmoidTable); let vs <- toGet(tabsrcs).get; if (verbose) $display("updateSigmaTableRule vs[0]=%h entryNumber=%d", vs[0], entryNumber); Vector#(3,Float) vs3 = take(vs); for (Integer i = 0; i < valueOf(n); i = i + 1) begin sigmoidTables[i].updateSigmoidTable(entryNumber, vs3); end entryNumber <= entryNumber + 1; endrule Reg#(Bit#(32)) countInput <- mkReg(0); rule consumeInput if (!updatingSigmoidTable); let vs <- toGet(source.pipe).get; for (Integer i = 0; i < valueOf(n); i = i + 1) begin sigmoidServers[i].request.put(vs[i]); end if (verbose) $display("consumeInput countInput=%d vs[0]=%h", countInput+1, vs[0]); countInput <= countInput + 1; endrule rule enqResult; Vector#(n, Float) vs; for (Integer i = 0; i < valueOf(n); i = i + 1) begin let v <- sigmoidServers[i].response.get(); vs[i] = v; end if (verbose) $display("sigmoid count=%d value=%h", count+1, vs); count <= count + 1; sinkC.pipe.enq(vs); endrule method Action sigmoidDone; let b <- sinkC.finish(); endmethod method Action updateDone; let b <- tabsrc.finish(); updatingSigmoidTable <= False; endmethod method Bit#(32) tableSize; return sigmoidTables[0].tableSize; endmethod interface SigmoidRequest sigmoidRequest; method Action sigmoid(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) writePointer, Bit#(32) writeOffset, Bit#(32) numvalues); source.start(readPointer, 0, unpack(extend(numvalues))>>nshift); sinkC.start(writePointer, 0, unpack(extend(numvalues))>>nshift); if (verbose) $display("sigmoid.start numvalues=%d", numvalues); endmethod method Action setLimits(Bit#(32) rscale, Bit#(32) llimit, Bit#(32) ulimit); for (Integer i = 0; i < valueOf(n); i = i + 1) begin sigmoidTables[i].setSigmoidLimits(unpack(rscale), unpack(llimit), unpack(ulimit)); end endmethod method Action updateTable(Bit#(32) readPointer, Bit#(32) readOffset, Bit#(32) numvalues); entryNumber <= 0; updatingSigmoidTable <= True; tabsrc.start(readPointer, extend(readOffset), (4*extend(numvalues))>>nshift); if (verbose) $display("sigmoid.updateSigmoidTable %d %d %d", readPointer, readOffset, numvalues); endmethod method Action tableSize(); noAction; endmethod endinterface endmodule ================================================ FILE: lib/rbm/bsv/Timer.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface TimerRequest; method Action startTimer(); method Action stopTimer(); endinterface interface TimerIndication; method Action elapsedCycles(Bit#(64) cycles, Bit#(64) idleCycles); endinterface ================================================ FILE: lib/rbm/cpp/mnist.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef _MNIST_H_ #define _MNIST_H_ #include #include #include #include #include #include #include #include #include #include class MnistImageFile { public: MnistImageFile(const char *name) : name(name), fd(0), mapping(0), len(0) {} ~MnistImageFile() { if (mapping) munmap((void*)mapping, len); if (fd) close(fd); } void open() { fd = ::open(name, O_RDONLY); if (fd < 0) { fprintf(stderr, "Failed to open %s errno=%d:%s\n", name, errno, strerror(errno)); } mapping = (const char *)mmap(0, 4096, PROT_READ, MAP_SHARED, fd, 0); if (mapping == MAP_FAILED) { fprintf(stderr, "mmap failed on file %s errno=%d:%s\n", name, errno, strerror(errno)); } int magic = *(int *)mapping; int dtype = mapping[2]; int dims = mapping[3]; int *nosizes = (int *)(mapping + 4); int size = 0; switch (dtype) { case 8: case 9: size = 1; break; case 0xb: size = 2; break; case 0xc: size = 4; break; case 0xe: size = 8; break; default: fprintf(stderr, "Unknown data type %x\n", dtype); } for (int i = 0; i < dims; i++) { sizes[i] = ntohl(nosizes[i]); size = size * sizes[i]; } dataOffset = 4+dims*4; elementSize = size / sizes[0]; len = cv::alignSize(size + dataOffset, 4096); fprintf(stderr, "magic=%x dtype=%x dims=%d size=%d elementSize=%d len=%d\n", ntohl(magic), dtype, dims, size, elementSize, len); munmap((void*)mapping, 4096); mapping = (const char *)mmap(0, len, PROT_READ, MAP_SHARED, fd, 0); if (mapping == MAP_FAILED) { fprintf(stderr, "mmap failed on file %s errno=%d:%s\n", name, errno, strerror(errno)); } } int numEntries() const { return sizes[0]; } int rows() const { return sizes[1]; } int cols() const { return sizes[2]; } cv::Mat mat(int i) const { const char *data = mapping + dataOffset + elementSize*i; int rows = sizes[1]; int cols = sizes[2]; //fprintf(stderr, "image %d rows=%d cols=%d offset=%d\n", i, rows, cols, dataOffset + elementSize*i); cv::Mat m(rows, cols, CV_8U); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { m.at(i,j) = (unsigned char)data[i*cols + j]; } } return m; } private: const char *name; int fd; const char *mapping; int sizes[3]; int len; int dataOffset; int elementSize; }; #endif ================================================ FILE: lib/rbm/cpp/rbm.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #undef NDEBUG #include "portalmat.h" #include "rbm.h" #include "mnist.h" float sigmoid(float x) { if (x < -8.0) x = -8.0; if (x > 8.0) x = 8.0; return 1 / (1 + expf(-x)); } void configureSigmoidTable() { sigmoiddevice->tableSize(); sem_wait(&mul_sem); int num_entries = sigmoidindication->tableSize(); int addrsize = log((double)num_entries) / log(2.0); float range = 16.0; float lowest_angle = - range/2.0; double fincr = (float)num_entries / range; double fscale = num_entries / range; fprintf(stderr, "configureSigmoidTable: num_entries=%d addrsize=%d fscale=%f fincr=%f\n", num_entries, addrsize, fscale, fincr); RbmMat sigmoidTable; // each entry consists of [-angle, sigmoid(angle), derivative, 0] sigmoidTable.create(1, 4*num_entries, CV_32F); // v = (index-num_entries/2) / fscale // index = v * fscale + num_entries/2 float fxscale = fscale; float fxllimit = (float)lowest_angle; float fxulimit = (float)-lowest_angle; fprintf(stderr, "configureSigmoidTable num_entries=%d rscale=%f %x llimit=%f %x rlimit=%f %x\n", num_entries, fxscale, *(int*)&fxscale, fxllimit, *(int*)&fxllimit, fxulimit, *(int*)&fxulimit); sigmoiddevice->setLimits(*(int*)&fxscale, *(int*)&fxllimit, *(int*)&fxulimit); int incr = 1; fprintf(stderr, "filling sigmoid table pointer=%x\n", sigmoidTable.reference()); for (int ai = 0; ai < num_entries; ai += incr) { float angle = (ai - num_entries / 2) / fscale; //int index = (int)(angle*fscale); float s = sigmoid(angle); //fprintf(stderr, "ai=%d angle=%f entry_angle=%f sigmoid=%f\n", ai, angle, angle * fscale + num_entries/2, s); sigmoidTable.at(0, 4*ai+0) = -angle; sigmoidTable.at(0, 4*ai+1) = s; if (ai == num_entries-1) { sigmoidTable.at(0, 4*ai+2) = 0; } else if (ai > 0) { float angle_prev = (ai - 1 - num_entries/2) / fscale; float s_prev = sigmoidTable.at(0,4*(ai-1)+1); float dangle = angle - angle_prev; float ds = s - s_prev; float slope = ds / dangle; //fprintf(stderr, "angle=%f angle_prev=%f s=%f s_prev=%f ds=%f dangle=%f slope=%f\n", angle, angle_prev, s, s_prev, ds, dangle, slope); sigmoidTable.at(0, 4*ai+2) = slope; } sigmoidTable.at(0, 4*ai+3) = 0; } fprintf(stderr, "updating sigmoid table pointer=%x\n", sigmoidTable.reference()); sigmoiddevice->updateTable(sigmoidTable.reference(), 0, num_entries); sem_wait(&mul_sem); fprintf(stderr, "sigmoid table updated\n"); } void RbmMat::sigmoid(RbmMat &a) { create(a.rows, a.cols, CV_32F); fprintf(stderr, "RbmMat::sigmoid() %d %d\n", a.rows, a.cols); reference(); cacheFlushInvalidate(); //fprintf(stderr, "sigmoid: a.ref=%d a.rows=%d a.cols=%d\n", a.reference(), a.rows, a.cols); //fprintf(stderr, "sigmoiddevice->sigmoid\n"); sigmoiddevice->sigmoid(a.reference(), 0, reference(), 0, a.rows*a.cols); sem_wait(&mul_sem); } void RbmMat::hiddenStates(RbmMat &a, RbmMat &rand) { create(a.rows, a.cols, CV_32F); fprintf(stderr, "hiddenStates: a.ref=%d a.rows=%d a.cols=%d\n", a.reference(), a.rows, a.cols); rand.reference(); reference(); cacheFlushInvalidate(); fprintf(stderr, "rbmdevice->computeStates ptr=%d randPtr=%d\n", a.reference(), rand.reference()); rbmdevice->computeStates(a.reference(), 0, rand.reference(), 0, reference(), 0, a.rows*a.cols); sem_wait(&mul_sem); } // weights += learningRate * (pos_associations - neg_associations) / num_examples; void RbmMat::updateWeights(RbmMat &posAssociations, RbmMat &negAssociations, float learningRateOverNumExamples) { fprintf(stderr, "rbmdevice->updateWeights pa.ref=%d na.ref=%d\n", posAssociations.reference(), negAssociations.reference()); cacheFlushInvalidate(); rbmdevice->updateWeights(posAssociations.reference(), negAssociations.reference(), reference(), rows*cols, *(int*)&learningRateOverNumExamples); sem_wait(&mul_sem); } void RbmMat::sumOfErrorSquared(RbmMat &pred) { if (rows != pred.rows || cols != pred.cols) { fprintf(stderr, "Mismatched data and pred: data.rows=%d data.cols=%d pred.rows=%d pred.cols=%d\n", rows, cols, pred.rows, pred.cols); exit(-1); } fprintf(stderr, "sumOfErrorSquared called numElts=%d\n", rows*cols); cacheFlushInvalidate(); rbmdevice->sumOfErrorSquared(reference(), pred.reference(), rows*cols); sem_wait(&mul_sem); } void printDynamicRange(const char *label, cv::Mat m) { int min_exp = 0; int max_exp = 0; float min_val = 0.0; float max_val = 0.0; dynamicRange(m, &min_exp, &max_exp, &min_val, &max_val); printf("dynamic range: max_exp=%d min_exp=%d max_val=%f min_val=%f %s\n", max_exp, min_exp, max_val, min_val, label); } float sumOfErrorSquared(cv::Mat &a, cv::Mat &b) { cv::Mat diff = a - b; float error = diff.dot(diff); return error; } void RBM::train(int numVisible, int numHidden, const cv::Mat &trainingData) { bool verify = false; #ifdef SIMULATION int numEpochs = 10; #else int numEpochs = 100; #endif if (verify) numEpochs = 1; float sum_of_errors_squareds[numEpochs]; bool verbose = false; bool dynamicRange = true; //int numExamples = trainingData.rows; if (verbose) dumpMat("trainingData", "%5.6f", trainingData); if (dynamicRange) printDynamicRange("trainingData", trainingData); cv::Mat weights; weights.create(numVisible+1, numHidden+1, CV_32F); for (int i = 0; i < numVisible+1; i++) { for (int j = 0; j < numHidden+1; j++) { float w = 0.1 * drand48(); if (w < 0 || w > 1.0) printf("w out of range %f\n", w); weights.at(i,j) = w; } } if (dynamicRange) printDynamicRange("weights", weights); // insert bias units of 1 into first column of data cv::Mat data; data.create(trainingData.rows, trainingData.cols+1, CV_32F); trainingData.copyTo(data.colRange(1, data.cols)); for (int i = 0; i < data.rows; i++) data.at(i, 0) = 1.0; RbmMat pmData(data); RbmMat pmDataT(pmData.t()); RbmMat pmWeights(weights); RbmMat pmWeightsT; RbmMat pm_pos_hidden_activations; RbmMat pm_pos_hidden_probs; RbmMat pm_rand_mat; RbmMat pm_pos_hidden_states; RbmMat pm_pos_hidden_probsT; RbmMat pm_pos_associations; RbmMat pm_neg_visible_activations; RbmMat pm_neg_visible_probs; RbmMat pm_neg_hidden_activations; RbmMat pm_neg_hidden_probs; RbmMat pm_neg_visible_probsT; RbmMat pm_neg_hidden_probsT; RbmMat pm_neg_associations; RbmMat pm_pos_hidden_statesT; if (verbose) dumpMat("data", "%5.6f", data); if (verbose) dumpMat("weights", "%5.6f", weights); portalTimerStart(0); for (int epoch = 0; epoch < numEpochs; epoch++) { timerdevice->startTimer(); cv::Mat pos_hidden_activations = data * pmWeights; if (dynamicRange) printDynamicRange("pos_hidden_activations", pos_hidden_activations); // fixme transpose pmWeightsT.transpose(pmWeights); if (verbose) dumpMat("pmWeightsT", "%5.1f", pmWeightsT); //RbmMat pm_pos_hidden_activations; pm_pos_hidden_activations.multf(pmDataT, pmWeights); if (verbose) dumpMat("pm_pos_hidden_activations", "%5.1f", pm_pos_hidden_activations); if (verbose) dumpMat(" pos_hidden_activations", "%5.1f", pos_hidden_activations); if (verify) assert(pm_pos_hidden_activations.compare(pos_hidden_activations, __FILE__, __LINE__)); // RbmMat pm_pos_hidden_probs; pm_pos_hidden_probs.sigmoid(pm_pos_hidden_activations); if (dynamicRange) printDynamicRange("pm_pos_hidden_probs", pm_pos_hidden_probs); cv::Mat pos_hidden_probs(pm_pos_hidden_activations); for (int i = 0; i < pm_pos_hidden_activations.rows; i++) { for (int j = 0; j < pm_pos_hidden_activations.cols; j++) { pos_hidden_probs.at(i,j) = sigmoid(pm_pos_hidden_activations.at(i,j)); } } if (verbose) dumpMat("pm_pos_hidden_probs", "%5.1f", pm_pos_hidden_probs); if (verbose) dumpMat(" pos_hidden_probs", "%5.1f", pos_hidden_probs); if (verify) assert(pm_pos_hidden_probs.compare(pos_hidden_probs, __FILE__, __LINE__)); // RbmMat pm_rand_mat; pm_rand_mat.create(pm_pos_hidden_probs.rows, pm_pos_hidden_probs.cols, CV_32F); for (int i = 0; i < pm_pos_hidden_probs.rows; i++) { for (int j = 0; j < pm_pos_hidden_probs.cols; j++) { pm_rand_mat.at(i,j) = (float)drand48(); } } if (verbose) dumpMat("pm_rand_mat", "%5.1f", pm_rand_mat); if (dynamicRange) printDynamicRange("pm_rand_mat", pm_rand_mat); cv::Mat pos_hidden_states; pos_hidden_states.create(pm_pos_hidden_probs.rows, pm_pos_hidden_probs.cols, CV_32F); for (int i = 0; i < pm_pos_hidden_probs.rows; i++) { for (int j = 0; j < pm_pos_hidden_probs.cols; j++) { float val = 0.0; if (pm_pos_hidden_probs.at(i,j) > pm_rand_mat.at(i,j)) val = 1.0; pos_hidden_states.at(i,j) = val; } } if (dynamicRange) printDynamicRange("pos_hidden_states", pos_hidden_states); // RbmMat pm_pos_hidden_states; pm_pos_hidden_states.hiddenStates(pm_pos_hidden_probs, pm_rand_mat); if (verbose) dumpMat("pm_pos_hidden_states", "%5.1f", pm_pos_hidden_states); if (verbose) dumpMat(" pos_hidden_states", "%5.1f", pos_hidden_states); if (verify) assert(pm_pos_hidden_states.compare(pos_hidden_states, __FILE__, __LINE__)); if (verbose) dumpMat("pmDataT", "%5.1f", pmDataT); //RbmMat pmWeights(weights); // back to non-transposed //pmWeights.copy(weights); if (verbose) dumpMat("pmWeights", "%5.1f", pmWeights); pm_pos_hidden_probsT.transpose(pm_pos_hidden_probs); if (verbose) dumpMat("pos_hidden_probsT", "%5.1f", pm_pos_hidden_probsT); cv::Mat pos_associations = pmDataT * pm_pos_hidden_probs; //RbmMat pm_pos_associations; pm_pos_associations.multf(pmData, pm_pos_hidden_probs); if (verbose) dumpMat("pos_associations", "%5.1f", pm_pos_associations); if (dynamicRange) printDynamicRange("pm_pos_associations", pm_pos_associations); // check results if (verify) assert(pm_pos_associations.compare(pos_associations, __FILE__, __LINE__)); // RbmMat pm_neg_visible_activations; pm_pos_hidden_statesT.transpose(pm_pos_hidden_states); pm_neg_visible_activations.multf(pm_pos_hidden_statesT, pmWeightsT); if (verbose) dumpMat("neg_visible_activations", "%5.1f", pm_neg_visible_activations); if (dynamicRange) printDynamicRange("pm_neg_visible_activations", pm_neg_visible_activations); cv::Mat neg_visible_probs; neg_visible_probs.create(pm_neg_visible_activations.rows, pm_neg_visible_activations.cols, CV_32F); for (int i = 0; i < pm_neg_visible_activations.rows; i++) { for (int j = 0; j < pm_neg_visible_activations.cols; j++) { neg_visible_probs.at(i,j) = sigmoid(pm_neg_visible_activations.at(i,j)); } } // RbmMat pm_neg_visible_probs; pm_neg_visible_probs.sigmoid(pm_neg_visible_activations); pm_neg_visible_probsT.transpose(pm_neg_visible_probs); if (verbose) dumpMat("neg_visible_probs", "%5.1f", pm_neg_visible_probs); // pm_neg_visible_probs[:0] = 1; for (int i = 0; i < pm_neg_visible_probs.rows; i++) { pm_neg_visible_probs.at(i,0) = 1.0; neg_visible_probs.at(i,0) = 1.0; } if (dynamicRange) printDynamicRange("pm_neg_visible_probs", pm_neg_visible_probs); if (verify) assert(pm_neg_visible_probs.compare(neg_visible_probs, __FILE__, __LINE__)); // RbmMat pm_neg_hidden_activations; pm_neg_hidden_activations.multf(pm_neg_visible_probsT, pmWeights); if (verbose) dumpMat("pm_neg_hidden_activations", "%5.1f", pm_neg_hidden_activations); if (dynamicRange) printDynamicRange("pm_neg_hidden_activations", pm_neg_hidden_activations); cv::Mat neg_hidden_activations = pm_neg_visible_probs * pmWeights; if (verbose) dumpMat(" neg_hidden_activations", "%5.1f", neg_hidden_activations); if (verify) assert(pm_neg_hidden_activations.compare(neg_hidden_activations, __FILE__, __LINE__, 0.05)); // RbmMat pm_neg_hidden_probs; pm_neg_hidden_probs.sigmoid(pm_neg_hidden_activations); if (verbose) dumpMat("pm_neg_hidden_probs", "%5.1f", pm_neg_hidden_probs); if (dynamicRange) printDynamicRange("pm_neg_hidden_probs", pm_neg_hidden_probs); pm_neg_visible_probsT.transpose(pm_neg_visible_probs); if (verbose) dumpMat("pm_neg_visible_probsT", "%5.1f", pm_neg_visible_probsT); if (dynamicRange) printDynamicRange("pm_neg_visible_probs", pm_neg_visible_probs); pm_neg_hidden_probsT.transpose(pm_neg_hidden_probs); //RbmMat pm_neg_associations; pm_neg_associations.multf(pm_neg_visible_probs, pm_neg_hidden_probs); if (verbose) dumpMat("pm_neg_associations", "%5.1f", pm_neg_associations); cv::Mat neg_associations = pm_neg_visible_probsT * pm_neg_hidden_probs; if (verbose) dumpMat(" neg_associations", "%5.1f", neg_associations); if (dynamicRange) printDynamicRange("pm_neg_associations", pm_neg_associations); if (verbose) dumpMat("pmWeights.before", "%5.1f", pmWeights); // weights += learningRate * (pos_associations - neg_associations) / num_examples; float learningRate = 1.0; float num_examples = data.rows; pmWeights.updateWeights(pm_pos_associations, pm_neg_associations, learningRate / num_examples); if (verbose) dumpMat("pmWeights.after ", "%5.1f", pmWeights); if (dynamicRange) printDynamicRange("weights", weights); fprintf(stderr, "========== %s:%d\n", __FILE__, __LINE__); // error = np.sum((data - neg_visible_probs) ** 2) pmData.sumOfErrorSquared(pm_neg_visible_probs); float error = sumOfErrorSquared(data, pm_neg_visible_probs); fprintf(stderr, "========== %s:%d\n", __FILE__, __LINE__); fprintf(stderr, "completed epoch %d sumOfErrorSquared=%f\n", epoch, error); sum_of_errors_squareds[epoch] = rbmDeviceIndication->sum_of_errors_squared; timerdevice->stopTimer(); } //uint64_t total_cycles = portalTimerLap(0); //uint64_t beats = hostMemServerIndication->getMemoryTraffic(ChannelType_Read); //fprintf(stderr, "total_cycles=%ld beats=%ld utilization=%f\n", (long)total_cycles, (long)beats, (float)beats / (float)total_cycles); for(int i = 0; i < numEpochs; i++) fprintf(stderr, "(%d) %f\n", i, sum_of_errors_squareds[i]); } void RBM::run() { cv::Mat trainingData = (cv::Mat_(6,6) << 1,1,1,0,0,0, 1,0,1,0,0,0, 1,1,1,0,0,0, 0,0,1,1,1,0, 0,0,1,1,0,0, 0,0,1,1,1,0); char name_buff[256]; snprintf(name_buff, 256, "../train-images-idx3-ubyte"); fprintf(stderr, "reading image data from %s\n", name_buff); MnistImageFile imagefile(name_buff); imagefile.open(); int numImages = imagefile.numEntries(); int numPixels = imagefile.rows()*imagefile.cols(); numImages = 200; int cols = 783; // one more column is added below to make the total 784. #ifdef SIMULATION numImages = 32; cols = 31; // one more column is added to make the total 32 #endif if (!cols || numPixels < cols) cols = numPixels; fprintf(stderr, "numImages=%d numPixels=%d imagefile.rows=%d imagefile.cols=%d\n", numImages, numPixels, imagefile.rows(), imagefile.cols()); //numVisible = imagefile.rows()*imagefile.cols(); int numVisible = cols; int numHidden = numVisible / 2; trainingData.create(numImages, cols, CV_32F); for (int i = 0; i < numImages; i++) { //fprintf(stderr, "Reading mat %d\n", i); cv::Mat m = imagefile.mat(i); //dumpMat("foo", "%02x", m); for (int j = 0; j < imagefile.rows(); j++) { for (int k = 0; k < imagefile.cols(); k++) { int offset = j*imagefile.cols() + k; if (offset < cols) { float f = (float)m.at(k,j); trainingData.at(i, offset) = f; } } } } fprintf(stderr, "RBM::run() invoking train\n"); train(numVisible, numHidden, trainingData); fprintf(stderr, "trainingData.rows=%d trainingData.cols=%d\n", trainingData.rows, trainingData.cols); } ================================================ FILE: lib/rbm/cpp/rbm.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef _RBM_H_ #define _RBM_H_ #include "RbmRequest.h" #include "RbmIndication.h" #include "SigmoidRequest.h" #include "SigmoidIndication.h" #include "dmaManager.h" class SigmoidIndication; class RbmIndication; extern RbmRequestProxy *rbmdevice; extern SigmoidRequestProxy *sigmoiddevice; extern SigmoidIndication *sigmoidindication; extern RbmIndication *rbmDeviceIndication; class RbmIndication : public RbmIndicationWrapper { public: RbmIndication(int id) : RbmIndicationWrapper(id) { } virtual ~RbmIndication() {} virtual void bramMmfDone() { //fprintf(stderr, "bramMmfDone\n"); sem_post(&mul_sem); } virtual void toBramDone() { //fprintf(stderr, "toBramDone\n"); sem_post(&mul_sem); } virtual void fromBramDone() { //fprintf(stderr, "fromBramDone\n"); sem_post(&mul_sem); } virtual void statesDone() { //fprintf(stderr, "statesDone\n"); sem_post(&mul_sem); } virtual void updateWeightsDone() { //fprintf(stderr, "updateWeightsDone\n"); sem_post(&mul_sem); } virtual void sumOfErrorSquared(uint32_t x) { sum_of_errors_squared = *(float *)&x; fprintf(stderr, "sumOfErrorSquared error=%f\n", sum_of_errors_squared); sem_post(&mul_sem); } virtual void sumOfErrorSquaredDebug(uint32_t macCount) { fprintf(stderr, "sumOfErrorSquared debug macCount=%d\n", macCount); } virtual void dbg(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { fprintf(stderr, "rbm dbg a=%x b=%x c=%x d=%x\n", a, b, c, d); } float sum_of_errors_squared; }; class SigmoidIndication : public SigmoidIndicationWrapper { public: SigmoidIndication(int id) : SigmoidIndicationWrapper(id) { } virtual ~SigmoidIndication() {} virtual void sigmoidDone() { //fprintf(stderr, "sigmoidDone\n"); sem_post(&mul_sem); } virtual void tableUpdated(uint32_t addr) { sem_post(&mul_sem); } uint32_t tableSize() { return tableSize_; } virtual void tableSize(uint32_t size) { fprintf(stderr, "sigmoidTableSize %d\n", size); tableSize_ = size; sem_post(&mul_sem); } private: uint32_t tableSize_; }; void sigmoid(PortalMat &a); float sigmoid(float x); void configureSigmoidTable(); class RBM { public: RBM(DmaManager *dma) : dma(dma) {} void train(int numVisible, int numHidden, const cv::Mat &trainingData); void run(); private: DmaManager *dma; }; class RbmMat : public PortalMat { public: RbmMat() : PortalMat() {}; RbmMat(const RbmMat &m) : PortalMat(m) {}; RbmMat(const cv::Mat &m) : PortalMat(m) {}; void sigmoid(RbmMat &a); void hiddenStates(RbmMat &a, RbmMat &rand); // weights += learningRate * (pos_associations - neg_associations) / num_examples; void updateWeights(RbmMat &posAssociations, RbmMat &negAssociations, float learningRateOverNumExamples); void sumOfErrorSquared(RbmMat &pred); }; #endif // _RBM_H_ ================================================ FILE: lib/regexp/bsv/Regexp.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import Vector::*; import BRAM::*; import Gearbox::*; import StmtFSM::*; import ClientServer::*; import GetPut::*; import Connectable::*; import ConnectalMemTypes::*; import MemReadEngine::*; import Pipe::*; import Dma2BRAM::*; import RegexpEngine::*; `include "ConnectalProjectConfig.bsv" interface RegexpRequest; method Action setup(Bit#(32) mapSGLId, Bit#(32) mapLen); method Action search(Bit#(32) token, Bit#(32) haystackSGLId, Bit#(32) haystackLen); method Action retire(Bit#(32) token); endinterface interface RegexpIndication; method Action setupComplete(Bit#(32) token); method Action searchResult(Bit#(32) token, Int#(32) v); endinterface interface Regexp#(numeric type busWidth); interface RegexpRequest request; interface Vector#(1, MemReadClient#(busWidth)) config_read_client; interface Vector#(1, MemReadClient#(busWidth)) haystack_read_client; endinterface typedef `DEGPAR DegPar; typedef enum {Config_charMap, Config_stateMap, Config_stateTransitions} RegexpState deriving (Eq,Bits); module mkRegexp#(RegexpIndication indication)(Regexp#(64)) provisos( Log#(`MAX_NUM_STATES,5) ,Log#(`MAX_NUM_CHARS,5) ,Div#(64,8,nc) ,Mul#(nc,8,64) ,Add#(0,DegPar,p) ,Log#(p,lp) ); MemReadEngine#(64,64,1,p) config_re <- mkMemReadEngine; MemReadEngine#(64,64,2,p) haystack_re <- mkMemReadEngine; let read_servers = zip(config_re.readServers,haystack_re.readServers); Vector#(p, RegexpEngine#(lp)) rees <- mapM(uncurry(mkRegexpEngine), zip(read_servers,genVector)); Reg#(RegexpState) state <- mkReg(Config_charMap); let readyFIFO <- mkSizedFIFOF(valueOf(p)); Vector#(p, PipeOut#(LDR#(lp))) ldrPipes; FIFOF#(Tuple2#(Bit#(lp), SSV#(lp))) setsearchFIFO <- mkFIFOF; UnFunnelPipe#(1,p,SSV#(lp),1) setsearchPipeUnFunnel <- mkUnFunnelPipesPipelined(cons(toPipeOut(setsearchFIFO),nil)); for(Integer i = 0; i < valueOf(p); i=i+1) begin ldrPipes[i] = rees[i].ldr; mkConnection(setsearchPipeUnFunnel[i],rees[i].setsearch); end FunnelPipe#(1,p,LDR#(lp),1) ldr <- mkFunnelPipesPipelined(ldrPipes); rule ldrr; let rv <- toGet(ldr[0]).get; case (rv) matches tagged Ready .r : readyFIFO.enq(r); tagged Done .d : indication.searchResult(extend(d), -1); tagged Loc .l : indication.searchResult(extend(tpl_1(l)), tpl_2(l)); tagged Config .c : indication.setupComplete(extend(c)); endcase endrule let setupFIFO <- mkSizedFIFO(4); rule setup_r; match {.sglId, .len} <- toGet(setupFIFO).get; $display("mkRegexp::setup(%d) %d %d %d", readyFIFO.first,sglId, len, state); case (state) matches Config_charMap: begin state <= Config_stateMap; setsearchFIFO.enq(tuple2(readyFIFO.first,tagged CharMap tuple2(sglId,len))); end Config_stateMap: begin state <= Config_stateTransitions; setsearchFIFO.enq(tuple2(readyFIFO.first,tagged StateMap tuple2(sglId,len))); end Config_stateTransitions: begin readyFIFO.deq; state <= Config_charMap; setsearchFIFO.enq(tuple2(readyFIFO.first,tagged StateTransitions tuple2(sglId,len))); end endcase endrule interface config_read_client = cons(config_re.dmaClient, nil); interface haystack_read_client = cons(haystack_re.dmaClient, nil); interface RegexpRequest request; method Action setup(Bit#(32) sglId, Bit#(32) len); setupFIFO.enq(tuple2(sglId,len)); endmethod method Action search(Bit#(32) token, Bit#(32) sglId, Bit#(32) len); $display("mkRegexp::search %d %d %d", token, sglId, len); setsearchFIFO.enq(tuple2(truncate(token),tagged Search tuple2(sglId,len))); endmethod method Action retire(Bit#(32) token); Bit#(lp) tok = truncate(token); $display("mkRegexp::retire(%d)", tok); setsearchFIFO.enq(tuple2(tok,tagged Retire tok)); endmethod endinterface endmodule ================================================ FILE: lib/regexp/bsv/RegexpEngine.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import Vector::*; import BRAM::*; import Gearbox::*; import StmtFSM::*; import ClientServer::*; import GetPut::*; import Probe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import Pipe::*; import Dma2BRAM::*; `include "ConnectalProjectConfig.bsv" typedef union tagged { Tuple2#(Bit#(t),Int#(32)) Loc; Bit#(t) Done; Bit#(t) Ready; Bit#(t) Config; } LDR#(numeric type t) deriving (Eq,Bits); typedef union tagged{ Pair#(Bit#(32)) CharMap; Pair#(Bit#(32)) StateMap; Pair#(Bit#(32)) StateTransitions; Pair#(Bit#(32)) Search; Bit#(t) Retire; } SSV#(numeric type t) deriving (Eq,Bits); interface RegexpEngine#(numeric type tw); interface PipeIn#(SSV#(tw)) setsearch; interface PipeOut#(LDR#(tw)) ldr; endinterface typedef Bit#(8) Char; typedef Bit#(64) DWord; typedef Bit#(32) Word; module mkRegexpEngine#(Pair#(MemReadEngineServer#(64)) readers, Integer iid)(RegexpEngine#(tw)) provisos(Log#(`MAX_NUM_STATES,5), Log#(`MAX_NUM_CHARS,5), Div#(64,8,nc), Mul#(nc,8,64) ); let debug = False; let verbose = True; let timing = False; let config_re = tpl_1(readers); let haystack_re = tpl_2(readers); FIFO#(Bool) conff <- mkSizedFIFO(1); Reg#(Bool) readyr <- mkReg(True); FIFOF#(SSV#(tw)) setsearchFIFO <- mkSizedFIFOF(4); Probe#(Bool) ssfp <- mkProbe(); FIFOF#(LDR#(tw)) ldrFIFO <- mkFIFOF; BRAM1Port#(Bit#(8), Bit#(8)) charMap <- mkBRAM1Server(defaultValue); BRAM1Port#(Bit#(5), Bit#(8)) stateMap <- mkBRAM1Server(defaultValue); BRAM1Port#(Bit#(10),Bit#(8)) stateTransitions <- mkBRAM1Server(defaultValue); BRAMWriter#(8,64) charMapWriter <- mkBRAMWriter(0, charMap.portA, config_re); BRAMWriter#(5,64) stateMapWriter <- mkBRAMWriter(1, stateMap.portA, config_re); BRAMWriter#(10,64) stateTransitionsWriter <- mkBRAMWriter(2, stateTransitions.portA, config_re); let clk <- exposeCurrentClock; let rst <- exposeCurrentReset; Gearbox#(nc,1,Char) haystack <- mkNto1Gearbox(clk,rst,clk,rst); Reg#(Bit#(32)) cycleCnt <- mkReg(0); Reg#(Bit#(32)) lastHD <- mkReg(0); FIFO#(Bit#(5)) fsmState <- mkBypassFIFO; Reg#(Bit#(64)) charCnt <- mkReg(0); Reg#(Bit#(64)) resCnt <- mkReg(0); Reg#(Bool) accepted <- mkReg(False); FIFO#(void) doneFifo <- mkFIFO; rule countCycles; if (timing) $display("******************************************** %d", cycleCnt); cycleCnt <= cycleCnt+1; //$dumpvars(); endrule rule set_ssfp; ssfp <= setsearchFIFO.notEmpty; endrule rule haystackResp; let rv <- toGet(haystack_re.data).get; haystack.enq(unpack(rv.data)); if (rv.last) doneFifo.enq(?); endrule rule haystackFinish if (!haystack.notEmpty); doneFifo.deq; ldrFIFO.enq(tagged Done fromInteger(iid)); conff.deq; fsmState.deq; if (verbose) $display("haystackFinish"); endrule rule finishCharMapWriter; conff.deq; let rv <- charMapWriter.finish; if (verbose) $display("finishCharMapWriter"); endrule rule finishStateMapWriter; conff.deq; let rv <- stateMapWriter.finish; if (verbose) $display("finishStateMapWriter"); endrule rule finishStateTransitionsWriter; conff.deq; let rv <- stateTransitionsWriter.finish; if (verbose) $display("finishStateTransitionsWriter"); ldrFIFO.enq(tagged Config fromInteger(iid)); endrule rule lookup_state; lastHD <= cycleCnt; if (debug) $display("deq haystack(%d)", cycleCnt-lastHD); haystack.deq; charCnt <= charCnt+1; let fsm_addr <- toGet(fsmState).get; charMap.portA.request.put(BRAMRequest{write:False, responseOnWrite:False, address:haystack.first[0], datain:?}); stateMap.portA.request.put(BRAMRequest{write:False, responseOnWrite:False, address:fsm_addr, datain:?}); endrule rule resolve_state; let mapped_char <- charMap.portA.response.get; let mapped_state <- stateMap.portA.response.get; Bit#(10) ns_addr = {mapped_state[4:0],mapped_char[4:0]}; let accept = mapped_state[7]==1; resCnt <= resCnt+1; if (accept) begin if (debug) $display("accept %d", resCnt); ldrFIFO.enq(tagged Loc tuple2(fromInteger(iid),unpack(truncate(resCnt)))); accepted <= accept; fsmState.enq(0); end else begin stateTransitions.portA.request.put(BRAMRequest{write:False, responseOnWrite:False, address:ns_addr, datain:?}); end endrule rule next_state; let new_state <- stateTransitions.portA.response.get; fsmState.enq(truncate(new_state)); endrule // the following case statement is much cleaner, but bsc doesn't compiler it // correctly. As a result, I broke it up into four rules, which seems to work (mdk) // // rule setsearch_r; // let ssv <- toGet(setsearchFIFO).get; // conff.enq(True); // case (ssv) matches // tagged CharMap .p: // begin // match {.pointer, .len} = p; // if (verbose) $display("setupCharMap %d %h", pointer, len); // charMapWriter.start(pointer, 0, minBound, maxBound); // end // tagged StateMap .p: // begin // match {.pointer, .len} = p; // if (verbose) $display("setupStateMap %d %h", pointer, len); // stateMapWriter.start(pointer, 0, minBound, maxBound); // end // tagged StateTransitions .p: // begin // match {.pointer, .len} = p; // if (verbose) $display("setupStateTransitions %d %h", pointer, len); // stateTransitionsWriter.start(pointer, 0, minBound, maxBound); // end // tagged Search .p: // begin // match {.pointer, .len} = p; // if (verbose) $display("setupSearch %d %d", pointer, len); // haystack_re.request.put(MemengineCmd{sglId:pointer, base:0, len:len, burstLen:16*fromInteger(valueOf(nc))}); // charCnt <= 0; // resCnt <= 0; // fsmState.enq(0); // end // tagged Retire .r: // begin // readyr <= True; // if (verbose) $display("Retire %d", r); // end // endcase // endrule rule setsearch_r_0 if (setsearchFIFO.first matches tagged CharMap .p); setsearchFIFO.deq; conff.enq(True); match {.pointer, .len} = p; if (verbose) $display("setupCharMap %d %h", pointer, len); charMapWriter.start(pointer, 0, minBound, maxBound); endrule rule setsearch_r_1 if (setsearchFIFO.first matches tagged StateMap .p); setsearchFIFO.deq; conff.enq(True); match {.pointer, .len} = p; if (verbose) $display("setupStateMap %d %h", pointer, len); stateMapWriter.start(pointer, 0, minBound, maxBound); endrule rule setsearch_r_2 if (setsearchFIFO.first matches tagged StateTransitions .p); setsearchFIFO.deq; conff.enq(True); match {.pointer, .len} = p; if (verbose) $display("setupStateTransitions %d %h", pointer, len); stateTransitionsWriter.start(pointer, 0, minBound, maxBound); endrule rule setsearch_r_3 if (setsearchFIFO.first matches tagged Search .p); setsearchFIFO.deq; conff.enq(True); match {.pointer, .len} = p; if (verbose) $display("setupSearch %d %d", pointer, len); haystack_re.request.put(MemengineCmd{sglId:pointer, base:0, len:len, burstLen:16*fromInteger(valueOf(nc)), tag: 0}); charCnt <= 0; resCnt <= 0; fsmState.enq(0); endrule rule setsearch_r_4 if (setsearchFIFO.first matches tagged Retire .r); setsearchFIFO.deq; readyr <= True; if (verbose) $display("Retire %d", r); endrule rule ready_r if (readyr); ldrFIFO.enq(tagged Ready fromInteger(iid)); readyr <= False; endrule interface PipeIn setsearch = toPipeIn(setsearchFIFO); interface PipeOut ldr = toPipeOut(ldrFIFO); endmodule ================================================ FILE: lib/regexp/cpp/regexp_utils.h ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include sem_t test_sem; int sw_match_cnt = 0; int hw_match_cnt = 0; #define num_tests (DEGPAR*2) #define max_num_tokens (DEGPAR) int token_map[max_num_tokens]; typedef struct P { unsigned int ref; int alloc; int length; char *mem; }P; P haystackP[num_tests]; DmaManager *haystack_dma; //MMURequestProxy *haystack_mmu; RegexpRequestProxy *regexp; using namespace std; class RegexpIndication : public RegexpIndicationWrapper { public: RegexpIndication(unsigned int id) : RegexpIndicationWrapper(id),done_cnt(0){}; virtual void setupComplete(uint32_t t){ fprintf(stderr, "setupComplete = %d\n", t); sem_post(&test_sem); token = t; } virtual void searchResult (uint32_t t, int v){ if (v == -1 ){ fprintf(stderr, "searchComplete = (%d, %d)\n", t, v); #ifndef ALGO_NANDSIM // in ALGO_NANDSIM we are just re-usng the same haystack which // has been written to the nandsim backing store by nandsim_exe munmap(haystackP[token_map[t]].mem, haystackP[token_map[t]].length); close(haystackP[token_map[t]].alloc); //haystack_mmu->idReturn(haystackP[token_map[t]].ref); #endif regexp->retire(t); if(++done_cnt == num_tests){ fprintf(stderr, "donzo\n"); sem_post(&test_sem); } }else if (v >= 0){ fprintf(stderr, "searchResult = (%d, %d)\n", t, v); hw_match_cnt++; } } int token; int done_cnt; }; int readfile(const char *fname, P* pP) { int rc = 0; ifstream binFile(fname, ios::in|ios::binary|ios::ate); if (!binFile.good()) { fprintf(stderr, "%s: error opening %s\n", __FUNCTION__, fname); } pP->length = binFile.tellg(); pP->alloc = portalAlloc(pP->length, 0); pP->mem = (char *)portalMmap(pP->alloc, pP->length); pP->ref = haystack_dma->reference(pP->alloc); binFile.seekg (0, ios::beg); if(!binFile.read(pP->mem, pP->length)){ fprintf(stderr, "error reading %s\n", fname); rc = -1; } binFile.close(); return rc; } int sw_ref(P *haystack, P *charMap, P *stateMap, P *stateTransitions) { int matches = 0; int state = 0; for(int i = 0; i < haystack->length; i++){ unsigned int c = haystack->mem[i]; unsigned int mapped_c = charMap->mem[c]; unsigned int mapped_state = stateMap->mem[state]; if (mapped_state & (1<<7)){ matches++; mapped_state = 0; } state = stateTransitions->mem[(mapped_state<<5) | mapped_c]; } return matches; } ================================================ FILE: lib/strstr/bsv/MPEngine.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. /* * Implementation of: * MP algorithm on pages 7-11 from "Pattern Matching Algorithms" by * Alberto Apostolico, Zvi Galil, 1997 */ `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import Vector::*; import BRAM::*; import Gearbox::*; import Connectable::*; import ConfigReg::*; import StmtFSM::*; import Probe::*; import ConnectalMemUtils::*; import ConnectalMemTypes::*; import Dma2BRAM::*; import Pipe::*; import OldEHR::*; interface MPEngine#(numeric type haystackBusWidth, numeric type configBusWidth); interface PipeIn#(Triplet#(Bit#(32))) setsearch; interface PipeOut#(Int#(32)) locdone; endinterface interface MPStreamEngine#(numeric type haystackBusWidth, numeric type configBusWidth); interface PipeIn#(MemDataF#(configBusWidth)) needle; interface PipeIn#(MemDataF#(configBusWidth)) mpNext; interface PipeIn#(MemDataF#(haystackBusWidth)) haystack; interface PipeOut#(Int#(32)) locdone; method Action clear(); method Action start(Bit#(32) needleLen); endinterface typedef Bit#(8) Char; typedef Bit#(64) DWord; typedef Bit#(32) Word; typedef 1024 MaxNeedleLen; typedef TLog#(MaxNeedleLen) NeedleIdxWidth; typedef Bit#(NeedleIdxWidth) NeedleIdx; typedef enum {Config_needle, Config_mpNext, Initialized, Search} Stage deriving (Eq, Bits); module mkMPEngine#(MemReadEngineServer#(haystackBusWidth) haystackReader, MemReadEngineServer#(configBusWidth) configReader) (MPEngine#(haystackBusWidth,configBusWidth)) provisos(Add#(a__, 8, haystackBusWidth), Div#(haystackBusWidth,8,haystackBusBytes), Mul#(haystackBusBytes,8,haystackBusWidth), Add#(1, b__, haystackBusBytes), Add#(c__, 32, haystackBusWidth), Add#(1, d__, TDiv#(haystackBusWidth, 32)), Mul#(TDiv#(haystackBusWidth, 32), 32, haystackBusWidth), Add#(e__, TLog#(haystackBusBytes), 32), Add#(f__, TLog#(TDiv#(haystackBusWidth, 32)), 32) ,Mul#(TDiv#(configBusWidth, 8), 8, configBusWidth) ,Add#(1, g__, TDiv#(configBusWidth, 8)) ,Add#(h__, TLog#(TDiv#(configBusWidth, 8)), 32) ,Add#(i__, TLog#(TDiv#(configBusWidth, 32)), 32) ,Add#(1, j__, TDiv#(configBusWidth, 32)) ,Mul#(TDiv#(configBusWidth, 32), 32, configBusWidth) ); FIFOF#(Int#(32)) locf <- mkFIFOF; FIFO#(Bool) conff <- mkSizedFIFO(1); let verbose = True; let debug = False; Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; BRAM2Port#(NeedleIdx, Char) needle <- mkBRAM2Server(defaultValue); BRAM2Port#(NeedleIdx, Bit#(32)) mpNext <- mkBRAM2Server(defaultValue); Gearbox#(haystackBusBytes,1,Char) haystack <- mkNto1Gearbox(clk,rst,clk,rst); Reg#(Bit#(32)) cycleCnt <- mkReg(0); Reg#(Bit#(32)) lastHD <- mkReg(0); Reg#(Stage) stage <- mkReg(Config_needle); Reg#(Bit#(32)) needleLenReg <- mkReg(0); Reg#(Bit#(32)) haystackLenReg <- mkReg(0); Reg#(Bit#(32)) haystackBase <- mkReg(0); Reg#(Bit#(32)) jReg <- mkReg(0); // offset in haystack Reg#(Bit#(32)) iReg <- mkReg(0); // offset in needle Reg#(Bit#(2)) epochReg <- mkReg(0); BRAMWriter#(NeedleIdxWidth,configBusWidth) n2b <- mkBRAMWriter(0, needle.portB, configReader); BRAMWriter#(NeedleIdxWidth,configBusWidth) mp2b <- mkBRAMWriter(1, mpNext.portB, configReader); FIFOF#(Tuple2#(Bit#(2),Bit#(32))) efifo <- mkSizedFIFOF(2); FIFOF#(Triplet#(Bit#(32))) ssfifo <- mkFIFOF; FIFO#(void) doneFifo <- mkFIFO; rule countCycles; if (debug) $display("******************************************** %d", cycleCnt); cycleCnt <= cycleCnt+1; endrule rule haystackResp; if (debug) $display("mkMPEngine::haystackResp"); let rv <- toGet(haystackReader.data).get; haystack.enq(unpack(rv.data)); if (rv.last) conff.deq; endrule rule haystackDrain(stage != Search); if (debug) $display("mkMPEngine::haystackDrain"); haystack.deq; endrule rule bramDrain(stage != Search); if (debug) $display("mkMPEngine::mpNextDrain"); let x <- mpNext.portA.response.get; let y <- needle.portA.response.get; efifo.deq; endrule `define OPTIMIZE_MISMATCH `ifdef OPTIMIZE_MISMATCH rule matchNeedleReq(stage == Search); if (debug) $display("mkMPEngine::matchNeedleReq %d %d", epochReg, iReg); needle.portA.request.put(BRAMRequest{write:False, address: truncate(iReg-1), datain:?, responseOnWrite:?}); mpNext.portA.request.put(BRAMRequest{write:False, address: truncate(iReg), datain:?, responseOnWrite:?}); efifo.enq(tuple2(epochReg,iReg)); iReg <= 1; endrule rule matchNeedleResp(stage == Search); let nv <- needle.portA.response.get; let mp <- mpNext.portA.response.get; let epoch = tpl_1(efifo.first); efifo.deq; if (debug) $display("mkMPEngine::matchNeedleResp %d %d", epochReg, epoch); if (epoch == epochReg) begin Bool deq_haystack = False; let n = haystackLenReg; let m = needleLenReg; let hv = haystack.first; let i = tpl_2(efifo.first); let j = jReg; if (debug) $display("mkMPEngine::feck %d %d %d %d %x %x", n, m, i, j, hv[0], nv); if (j > n) begin // jReg points to the end of the haystack; we are done stage <= Config_needle; if (debug) $display("mkMPEngine::end of search %d", j); locf.enq(-1); end else if (i==m+1) begin // iReg points to the end of the needle; we have a match if (debug) $display("mkMPEngine::string match %d", j); locf.enq(unpack(haystackBase+j-i)); end else if (nv != hv[0]) begin // mismatch betwen head of haystack and head of needle; rewind iReg if (debug) $display("mkMPEngine::char mismatch %d %d MP_Next[i]=%d", i, j, mp); if (mp == 0) begin iReg <= 1; jReg <= j+1; deq_haystack = True; end else begin epochReg <= epochReg + 1; iReg <= mp; end end else begin // match between head of needle and head of haystack; increment haystack if (debug) $display("mkMPEngine::char match(%d) %d %d", (nv == hv[0]), i, j); deq_haystack = True; jReg <= j+1; epochReg <= epochReg + 1; iReg <= i+1; end if (deq_haystack) begin haystack.deq; lastHD <= cycleCnt; if (debug) $display("mkMPEngine:: deq haystack(%d)", cycleCnt-lastHD); end end else begin if (debug) $display("mkMPEngine::discard"); noAction; end endrule `else rule matchNeedleReq(stage == Search); if (debug) $display("mkMPEngine::matchNeedleReq %d %d", epochReg, iReg); needle.portA.request.put(BRAMRequest{write:False, address: truncate(iReg-1), datain:?, responseOnWrite:?}); mpNext.portA.request.put(BRAMRequest{write:False, address: truncate(iReg), datain:?, responseOnWrite:?}); efifo.enq(tuple2(epochReg,iReg)); iReg <= iReg+1; endrule rule matchNeedleResp(stage == Search); let nv <- needle.portA.response.get; let mp <- mpNext.portA.response.get; let epoch = tpl_1(efifo.first); efifo.deq; if (debug) $display("mkMPEngine::matchNeedleResp %d %d", epochReg, epoch); if (epoch == epochReg) begin Bool deq_haystack = False; let n = haystackLenReg; let m = needleLenReg; let hv = haystack.first; let i = tpl_2(efifo.first); let j = jReg; if (debug) $display("mkMPEngine::feck %d %d %d %d %x %x", n, m, i, j, hv[0], nv); if (j > n) begin // jReg points to the end of the haystack; we are done stage <= Config_needle; if (debug) $display("mkMPEngine::end of search %d", j); end else if (i==m+1) begin // iReg points to the end of the needle; we have a match if (debug) $display("mkMPEngine::string match %d", j); locf.enq(unpack(haystackBase+j-i)); epochReg <= epochReg + 1; iReg <= 1; end else if (nv != hv[0]) begin // mismatch betwen head of haystack and head of needle; rewind iReg if (debug) $display("mkMPEngine::char mismatch %d %d MP_Next[i]=%d", i, j, mp); epochReg <= epochReg + 1; if (mp == 0) begin iReg <= 1; jReg <= j+1; deq_haystack = True; end else begin iReg <= mp; end end else begin // match between head of needle and head of haystack; increment haystack if (debug) $display("mkMPEngine::char match(%d) %d %d", (nv == hv[0]), i, j); deq_haystack = True; jReg <= j+1; end if (deq_haystack) begin haystack.deq; lastHD <= cycleCnt; if (debug) $display("mkMPEngine:: deq haystack(%d)", cycleCnt-lastHD); end end else begin if (debug) $display("mkMPEngine::discard"); noAction; end endrule `endif rule finish_setup_n2b; if (verbose) $display("mkMPEngine::finish_setup_n2b"); let x <- n2b.finish; conff.deq; stage <= Config_mpNext; endrule rule finish_setup_mp2b; if (verbose) $display("mkMPEngine::finish_setup_mp2b"); let y <- mp2b.finish; conff.deq; stage <= Initialized; endrule rule setup_needle (stage == Config_needle); conff.enq(True); match {.needle_sglId, .mpNext_sglId, .needle_len} = ssfifo.first; needleLenReg <= extend(needle_len); if (verbose) $display("mkMPEngine::setup_needle %d %d", needle_sglId, needle_len); n2b.start(needle_sglId, 0, 0, pack(truncate(needle_len))); endrule rule setup_mpNext (stage == Config_mpNext); conff.enq(True); match {.needle_sglId, .mpNext_sglId, .needle_len} = ssfifo.first; needleLenReg <= extend(needle_len); if (verbose) $display("mkMPEngine::setup_mpNext %d %d", mpNext_sglId, needle_len); mp2b.start(mpNext_sglId, 0, 0, pack(truncate(needle_len))); ssfifo.deq; endrule rule search (stage == Initialized && !efifo.notEmpty && !haystack.notEmpty); stage <= Search; conff.enq(True); match {.haystack_sglId, .haystack_len, .haystack_base} <- toGet(ssfifo).get; haystackLenReg <= extend(haystack_len); haystackBase <= extend(haystack_base); iReg <= 1; jReg <= 1; epochReg <= 0; Bit#(32) haystack_len_ds = haystack_len+fromInteger(valueOf(haystackBusBytes)-1); Bit#(TLog#(haystackBusBytes)) zeros = 0; Bit#(32) haystack_len_bytes = {zeros,haystack_len_ds[31:valueOf(TLog#(haystackBusBytes))]} * fromInteger(valueOf(haystackBusBytes)); $display("haystack read offset=%d burstLen=%d", haystack_base, fromInteger(8*valueOf(haystackBusBytes))); haystackReader.request.put(MemengineCmd{sglId:haystack_sglId, base:extend(haystack_base), len:haystack_len_bytes, burstLen:fromInteger(8*valueOf(haystackBusBytes)), tag: 0}); if (verbose) $display("mkMPEngine::search %d %d %d", haystack_sglId, haystack_base, haystack_len_bytes); endrule interface PipeIn setsearch = toPipeIn(ssfifo); interface PipeOut locdone = toPipeOut(locf); endmodule module mkMPStreamEngine(MPStreamEngine#(haystackBusWidth,configBusWidth)) provisos(Add#(a__, 8, haystackBusWidth), Div#(haystackBusWidth,8,haystackBusBytes), Mul#(haystackBusBytes,8,haystackBusWidth), Add#(1, b__, haystackBusBytes), Add#(c__, 32, haystackBusWidth), Add#(1, d__, TDiv#(haystackBusWidth, 32)), Mul#(TDiv#(haystackBusWidth, 32), 32, haystackBusWidth), Add#(e__, TLog#(haystackBusBytes), 32), Add#(f__, TLog#(TDiv#(haystackBusWidth, 32)), 32) ,Mul#(TDiv#(configBusWidth, 8), 8, configBusWidth) ,Add#(1, g__, TDiv#(configBusWidth, 8)) ,Add#(h__, TLog#(TDiv#(configBusWidth, 8)), 32) ,Add#(i__, TLog#(TDiv#(configBusWidth, 32)), 32) ,Add#(1, j__, TDiv#(configBusWidth, 32)) ,Mul#(TDiv#(configBusWidth, 32), 32, configBusWidth) ); FIFOF#(Int#(32)) locf <- mkFIFOF; let verbose = True; let debug = True; Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; BRAM2Port#(NeedleIdx, Char) needleBram <- mkBRAM2Server(defaultValue); BRAM2Port#(NeedleIdx, Bit#(32)) mpNextBram <- mkBRAM2Server(defaultValue); FIFOF#(MemDataF#(haystackBusWidth)) haystackFifo <- mkFIFOF(); Gearbox#(haystackBusBytes,1,Char) haystackGb <- mkNto1Gearbox(clk,rst,clk,rst); Reg#(Bit#(32)) cycleCnt <- mkReg(0); Reg#(Bit#(32)) lastHD <- mkReg(0); Reg#(Stage) stage <- mkReg(Initialized); Reg#(Bit#(32)) needleLenReg <- mkReg(0); Reg#(Bit#(32)) jReg <- mkReg(1); // offset in haystack Reg#(Bit#(32)) iReg <- mkReg(1); // offset in needle BRAMPipeIn#(NeedleIdxWidth,configBusWidth) n2b <- mkBRAMPipeIn(0, needleBram.portB); BRAMPipeIn#(NeedleIdxWidth,configBusWidth) mp2b <- mkBRAMPipeIn(1, mpNextBram.portB); FIFOF#(Tuple2#(Bit#(2),Bit#(32))) efifo <- mkSizedFIFOF(2); FIFO#(void) doneFifo <- mkFIFO; rule countCycles; //if (debug) $display("******************************************** %d", cycleCnt); cycleCnt <= cycleCnt+1; endrule rule haystackResp; let rv <- toGet(haystackFifo).get; if (debug) $display("mkMPEngine::haystackResp rv=%h", rv.data); haystackGb.enq(unpack(rv.data)); endrule let x_i <- mkReg(0); let t_j <- mkReg(0); let m = needleLenReg; let i = iReg; let iReg_minus_1 <- mkReg(0); let matchFsm <- mkAutoFSM(seq while (stage != Search) seq iReg <= 1; endseq action iReg <= 1; jReg <= 1; let t = haystackGb.first[0]; haystackGb.deq(); t_j <= t; iReg_minus_1 <= iReg-1; endaction action needleBram.portA.request.put(BRAMRequest{write:False, address: truncate(iReg_minus_1), datain:?, responseOnWrite:?}); endaction action let xNext <- needleBram.portA.response.get(); x_i <= xNext; endaction while (stage == Search) seq $display("initial i=%d j=%d x_i=%h t_j=%h", iReg, jReg, x_i, t_j); while ((i == m + 1) || (i > 0 && x_i != t_j)) seq action mpNextBram.portA.request.put(BRAMRequest{write:False, address: truncate(iReg), datain:?, responseOnWrite:?}); endaction action Bit#(32) mpNext <- mpNextBram.portA.response.get(); let iNext = mpNext[15:0]; let xNext = mpNext[31:16]; iReg <= extend(iNext); x_i <= truncate(xNext); $display("i=%d iNext=%d m+1=%d x_i=%h t_j=%h mpNext=%h", i, iNext, m+1, xNext, t_j, mpNext); endaction endseq action iReg <= iReg + 1; jReg <= jReg + 1; needleBram.portA.request.put(BRAMRequest{write:False, address: truncate(iReg+1-1), datain:?, responseOnWrite:?}); let t = haystackGb.first[0]; haystackGb.deq(); t_j <= t; endaction action if (t_j == 0) begin $display("iReg=%d jReg=%d t==0 locf.enq(-1)", iReg-1, jReg-1, t_j); locf.enq(-1); // this seems to be needed for the strstr example to terminate end endaction action let xNext <- needleBram.portA.response.get(); x_i <= xNext; $display("step i=%d j=%d x_i=%h t_j=%h", iReg, jReg, xNext, t_j); if (iReg == m + 1) begin $display("match at j=%d", jReg - iReg); locf.enq(unpack(jReg - iReg)); end endaction endseq // stage == Search endseq); interface PipeIn needle = n2b.pipe; interface PipeIn mpNext = mp2b.pipe; interface PipeIn haystack = toPipeIn(haystackFifo); interface PipeOut locdone = toPipeOut(locf); method Action clear(); stage <= Initialized; endmethod method Action start(Bit#(32) needleLen); stage <= Search; jReg <= 1; iReg <= 1; needleLenReg <= needleLen; endmethod endmodule ================================================ FILE: lib/strstr/bsv/Strstr.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import SpecialFIFOs::*; import Vector::*; import BuildVector::*; import BRAM::*; import Gearbox::*; import Connectable::*; import StmtFSM::*; import ConnectalMemTypes::*; import MPEngine::*; import MemReadEngine::*; import Pipe::*; interface StrstrRequest; method Action setup(Bit#(32) needleSGLId, Bit#(32) mpNextSGLId, Bit#(32) needle_len); method Action search(Bit#(32) haystackSGLId, Bit#(32) haystack_len); endinterface interface StrstrIndication; method Action searchResult(Int#(32) v); endinterface interface Strstr#(numeric type haystackBusWidth, numeric type configBusWidth); interface StrstrRequest request; interface Vector#(1, MemReadClient#(haystackBusWidth)) haystack_read_client; interface Vector#(1, MemReadClient#(configBusWidth)) config_read_client; endinterface // I can't belive we still have to do this shit function Bool my_or(Bool a, Bool b) = a || b; module mkStrstr#(StrstrIndication indication)(Strstr#(haystackBusWidth, configBusWidth)) provisos ( Mul#(TDiv#(configBusWidth, 8), 8, configBusWidth) ,Mul#(TDiv#(haystackBusWidth, 8), 8, haystackBusWidth) ,Add#(1, a__, TDiv#(haystackBusWidth, 8)) ,Add#(b__, TLog#(TDiv#(haystackBusWidth, 8)), 32) ,Mul#(TDiv#(configBusWidth, 32), 32, configBusWidth) ,Add#(1, c__, TDiv#(configBusWidth, 32)) ,Add#(d__, TLog#(TDiv#(configBusWidth, 32)), 32) ,Add#(e__, TLog#(TDiv#(configBusWidth, 8)), 32) ,Add#(1, f__, TDiv#(configBusWidth, 8)) ,Add#(g__, TLog#(TDiv#(haystackBusWidth, 32)), 32) ,Mul#(TDiv#(haystackBusWidth, 32), 32, haystackBusWidth) ,Add#(1, h__, TDiv#(haystackBusWidth, 32)) ,Add#(i__, 32, haystackBusWidth) ,Add#(j__, 8, haystackBusWidth) ); let verbose = True; Reg#(Bit#(32)) needleLen <- mkReg(0); MemReadEngine#(haystackBusWidth,haystackBusWidth,1,1) haystack_re <- mkMemReadEngineBuff(1024); MemReadEngine#(configBusWidth,configBusWidth,1,2) config_re <- mkMemReadEngineBuff(1024); Reg#(Bit#(32)) needleSGLId <- mkReg(0); Reg#(Bit#(32)) mpNextSGLId <- mkReg(0); Reg#(Bit#(32)) haystackSGLId <- mkReg(0); Reg#(Bit#(32)) haystackLen <- mkReg(0); Reg#(Bit#(32)) startCnt <- mkReg(0); Reg#(Bit#(32)) startBase <- mkReg(0); Reg#(Bit#(32)) setupCnt <- mkReg(0); Reg#(Bit#(32)) doneCnt <- mkReg(0); MPStreamEngine#(haystackBusWidth,configBusWidth) engine <- mkMPStreamEngine; mkConnection(config_re.readServers[0].data, engine.needle); mkConnection(config_re.readServers[1].data, engine.mpNext); mkConnection(haystack_re.readServers[0].data, engine.haystack); rule resr; let rv <- toGet(engine.locdone).get; // send results back to SW indication.searchResult(rv); if (verbose) $display("strstr search result %d", rv); endrule interface StrstrRequest request; method Action setup(Bit#(32) needle_sglId, Bit#(32) mpNext_sglId, Bit#(32) needle_len); if (verbose) $display("mkStrstr::setup %d %d %d", needle_sglId, mpNext_sglId, needle_len); needleLen <= needle_len; needleSGLId <= needle_sglId; mpNextSGLId <= mpNext_sglId; let burstLen = fromInteger(valueOf(configBusWidth)/8); let mask = burstLen - 1; needle_len = (needle_len + mask) & ~mask; $display("needle_len %d", needle_len); config_re.readServers[0].request.put(MemengineCmd {sglId: needle_sglId, base: 0, burstLen: burstLen, len: needle_len, tag: 0}); config_re.readServers[1].request.put(MemengineCmd {sglId: mpNext_sglId, base: 0, burstLen: burstLen, len: needle_len*4, tag: 0}); engine.clear(); endmethod method Action search(Bit#(32) haystack_sglId, Bit#(32) haystack_len); if (verbose) $display("mkStrstr::search %d %d", haystack_sglId, haystack_len); haystackLen <= haystack_len; haystackSGLId <= haystack_sglId; let burstLen = fromInteger(valueOf(haystackBusWidth)/8); let mask = burstLen - 1; haystack_len = (haystack_len + mask) & ~mask; haystack_re.readServers[0].request.put(MemengineCmd {sglId: haystack_sglId, base: 0, burstLen: burstLen, len: haystack_len, tag: 0}); engine.start(needleLen); endmethod endinterface interface config_read_client = vec(config_re.dmaClient); interface haystack_read_client = vec(haystack_re.dmaClient); endmodule ================================================ FILE: lib/strstr/cpp/mp.h ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Implementation of: * MP algorithm on pages 7-11 from "Pattern Matching Algorithms" by * Alberto Apostolico, Zvi Galil, 1997 * * pattern x of length m * text t of length n * * procedure MP(x, t: string; m, n: integer); * begin * i := 1; j := 1; * while j <= n do begin * while (i = m + 1) or (i > 0 and x[i] != t[j]) do i := MP_next[i]; * i := i + 1; j := j + 1; * if i = m + 1 then writeln('x occurs in t at position ', j - i + 1); * end; * end; * * procedure Compute_borders(x: string; m: integer); * begin * Border[0] := -1; * for i := 1 to m do begin * j := Border[i - 1]; * while j >= 0 and x[i] != x[j + 1] do j := Border[j]; * Border[i] := j + 1; * end; * end; * * procedure Compute_MP_next(x: string; m: integer); * begin * MP_next[i] := 0; j := 0; * for i := 1 to m do begin * { at this point, we have j = MP_next[i] } * while j > 0 and x[i] != x[j] do j := MP_next[j]; * j := j + 1; * MP_next[i + 1] := j; * end; * end; * */ #ifndef _MP_H_ #define _MP_H_ void compute_borders(const char *x, int *border, int m) { border[0] = -1; for(int i = 1; i <=m; i++){ int j = border[i-1]; while ((j>=0) && (x[i] != x[j+1])) j = border[j]; border[i] = j+1; } } struct MP { MP(uint16_t x, uint16_t index) : index(index), x(x) {} uint16_t index; uint16_t x; }; void compute_MP_next(const char *x, struct MP *MP_next, int m) { MP_next[1] = MP(0, 0); int j = 0; for(int i = 1; i <= m; i++){ while ((j>0) && (x[i] != x[j])) j = MP_next[j].index; j = j+1; MP_next[i+1] = MP(x[j-1], j); } } void MP(const char *x, const char *t, struct MP *MP_next, int m, int n, int *match_cnt) { int i = 1; int j = 1; fprintf(stderr, "MP starting\n"); while (j <= n) { while ((i==m+1) || ((i>0) && (x[i-1] != t[j-1]))){ //fprintf(stderr, "char mismatch %d %d MP_next[i]=%d\n", i,j,MP_next[i]); i = MP_next[i].index; } //fprintf(stderr, " char match %d %d\n", i, j); i = i+1; j = j+1; if (i==m+1){ fprintf(stderr, "%s occurs in t at position %d\n", x, j-i); i = 1; (*match_cnt)++; } } fprintf(stderr, "MP exiting\n"); } #endif // _MP_H_ ================================================ FILE: lib/strstr/cpp/strstr.h ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ class StrstrIndication : public StrstrIndicationWrapper { public: StrstrIndication(unsigned int id) : StrstrIndicationWrapper(id){ sem_init(&sem, 0, 0); match_cnt = 0; }; virtual void setupComplete() { fprintf(stderr, "Strstr::setupComplete\n"); sem_post(&sem); } virtual void searchResult (int v){ fprintf(stderr, "searchResult = %d\n", v); if (v == -1) sem_post(&sem); else match_cnt++; } void wait() { fprintf(stderr, "Strstr::wait for semaphore\n"); sem_wait(&sem); } int match_cnt; private: sem_t sem; }; ================================================ FILE: lib/zedboard_robot/bsv/GyroController.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import GetPut::*; import Vector::*; import StmtFSM::*; import FIFO::*; import SpecialFIFOs::*; import Gearbox::*; import ClientServer::*; import ConnectalMemTypes::*; import Leds::*; import ConnectalSpi::*; import MemWriteEngine::*; import Pipe::*; interface GyroCtrlRequest; method Action write_reg_req(Bit#(8) addr, Bit#(8) val); method Action read_reg_req(Bit#(8) addr); method Action sample(Bit#(32) sgl_id, Bit#(32) alloc_sz, Bit#(32) sample_freq); method Action set_en(Bit#(32) en); endinterface interface GyroCtrlIndication; method Action read_reg_resp(Bit#(8) val); method Action write_reg_resp(Bit#(8) addr); method Action memwrite_status(Bit#(32) addr, Bit#(32) wrap_cnt); endinterface interface GyroSampleStream; method Action sample(Int#(16) x, Int#(16) y, Int#(16) z); endinterface interface GyroSimplePins; interface SpiMasterPins#(1) spi; interface LEDS leds; endinterface interface GyroController; interface GyroCtrlRequest req; interface GyroSimplePins pins; interface MemWriteClient#(64) dmaClient; endinterface module mkGyroController#(GyroCtrlIndication ind)(GyroController); SPIMaster#(Bit#(16), 1) spiCtrl <- mkSPIMaster(1000, True); FIFO#(Bool) spi_aux <- mkPipelineFIFO; Reg#(Bit#(32)) sampleFreq <- mkReg(0); Reg#(Bit#(32)) sampleCnt <- mkReg(0); FIFO#(Bool) rc_fifo <- mkFIFO1; `ifdef SIMULATION Reg#(Bit#(8)) bsim_cnt <- mkReg(0); `endif let clk <- exposeCurrentClock; let rst <- exposeCurrentReset; Gearbox#(1,8,Bit#(8)) gb <- mk1toNGearbox(clk,rst,clk,rst); MemWriteEngine#(64,64,1,1) we <- mkMemWriteEngine; Reg#(Bit#(32)) en_memwr <- mkReg(maxBound); Reg#(Bit#(32)) cWrapCnt <- mkReg(0); Reg#(Bit#(32)) sglId <- mkReg(0); Reg#(Bit#(32)) allocSz <- mkReg(0); Reg#(Bit#(32)) writePtr <- mkReg(0); Reg#(Bit#(32)) cWritePtr <- mkReg(0); let out_X_L = 'h28; let out_X_H = 'h29; let out_Y_L = 'h2A; let out_Y_H = 'h2B; let out_Z_L = 'h2C; let out_Z_H = 'h2D; let verbose = False; rule read_reg_resp; let rv <- spiCtrl.response[0].get; if (rc_fifo.first) ind.read_reg_resp(truncate(rv)); rc_fifo.deq; endrule rule sample_req(sampleFreq > 0); let new_sampleCnt = sampleCnt+1; let sampling = True; if (new_sampleCnt == sampleFreq-5) begin spiCtrl.request[0].put({1'b1,1'b0,out_X_L,8'h00}); if(verbose) $display("sample_x_l"); end else if (new_sampleCnt == sampleFreq-4) begin spiCtrl.request[0].put({1'b1,1'b0,out_X_H,8'h00}); if(verbose) $display("sample_x_h"); end else if (new_sampleCnt == sampleFreq-3) begin spiCtrl.request[0].put({1'b1,1'b0,out_Y_L,8'h00}); if(verbose) $display("sample_y_l"); end else if (new_sampleCnt == sampleFreq-2) begin spiCtrl.request[0].put({1'b1,1'b0,out_Y_H,8'h00}); if(verbose) $display("sample_y_h"); end else if (new_sampleCnt == sampleFreq-1) begin spiCtrl.request[0].put({1'b1,1'b0,out_Z_L,8'h00}); if(verbose) $display("sample_z_l"); end else if (new_sampleCnt >= sampleFreq-0) begin spiCtrl.request[0].put({1'b1,1'b0,out_Z_H,8'h00}); if(verbose) $display("sample_z_h"); new_sampleCnt = 0; end else begin sampling = False; end if(sampling) spi_aux.enq(True); sampleCnt <= new_sampleCnt; endrule rule sample_resp(sampleFreq > 0); spi_aux.deq; if(verbose) $display("sample_resp"); let rv <- spiCtrl.response[0].get; `ifdef SIMULATION bsim_cnt <= (bsim_cnt == 5) ? 0 : bsim_cnt+1; let bsim_val = bsim_cnt[0]==1'b0 ? bsim_cnt+1 : 0; gb.enq(cons(bsim_val,nil)); `else gb.enq(cons(truncate(rv),nil)); `endif endrule rule we_cmd_enq if (en_memwr != 0 && allocSz > 0); Bit#(32) new_writePtr = writePtr + 8; if (new_writePtr >= allocSz) begin new_writePtr = 0; en_memwr <= en_memwr-1; end writePtr <= new_writePtr; we.writeServers[0].request.put(MemengineCmd{sglId:sglId, base:extend(writePtr), burstLen:8, len:8, tag:0}); endrule rule we_cmd_deq; let rv <- we.writeServers[0].done.get; Bit#(32) new_cWritePtr = cWritePtr + 8; if(new_cWritePtr >= allocSz) begin new_cWritePtr = 0; cWrapCnt <= cWrapCnt+1; end cWritePtr <= new_cWritePtr; endrule rule we_data_enq; gb.deq; we.writeServers[0].data.enq(pack(gb.first)); endrule interface GyroCtrlRequest req; method Action write_reg_req(Bit#(8) addr, Bit#(8) val); spiCtrl.request[0].put({1'b0,1'b0,addr[5:0],val}); ind.write_reg_resp(addr); rc_fifo.enq(False); endmethod method Action read_reg_req(Bit#(8) addr); spiCtrl.request[0].put({1'b1,1'b0,addr[5:0],8'h00}); rc_fifo.enq(True); endmethod method Action sample(Bit#(32) sgl_id, Bit#(32) alloc_sz, Bit#(32) sample_freq); $display("sample %d %d %d", sgl_id, alloc_sz, sample_freq); sampleFreq <= sample_freq; sampleCnt <= 0; allocSz <= alloc_sz; sglId <= sgl_id; endmethod method Action set_en(Bit#(32) en); en_memwr <= en; if(en == 0) ind.memwrite_status(cWritePtr, cWrapCnt); endmethod endinterface interface GyroSimplePins pins; interface SpiMasterPins spi = spiCtrl.pins; interface LEDS leds; method Bit#(LedsWidth) leds() = truncate(pack(cWrapCnt)); endinterface endinterface interface dmaClient = we.dmaClient; endmodule ================================================ FILE: lib/zedboard_robot/bsv/HBridgeController.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Leds::*; import Vector::*; import FIFOF::*; import Arith::*; interface HBridgeCtrlRequest; method Action ctrl(Vector#(2,Bit#(11)) power, Vector#(2,Bit#(1)) direction); endinterface interface HBridgeCtrlIndication; method Action hbc_event(Bit#(32) e); endinterface interface HBridgePins; method Bit#(1) direction(); method Bit#(1) enabled(); endinterface interface HBridge2Pins; interface HBridgePins hbridge0; interface HBridgePins hbridge1; endinterface interface HBridgeSimplePins; interface HBridge2Pins hbridge; interface LEDS leds; endinterface interface HBridgeController; interface HBridgeCtrlRequest req; interface HBridgeSimplePins pins; endinterface typedef enum {HBridgeCtrlEvent_Stopped, HBridgeCtrlEvent_Started} HBridgeCtrlEvent deriving (Eq,Bits); module mkHBridgeController#(HBridgeCtrlIndication ind)(HBridgeController); Vector#(2, Reg#(Bit#(1))) direction <- replicateM(mkReg(0)); Vector#(2, Reg#(Bit#(1))) enabled <- replicateM(mkReg(0)); Vector#(2, Reg#(Bit#(11))) power <- replicateM(mkReg(0)); Vector#(2, Reg#(Bool)) pz <- replicateM(mkReg(True)); FIFOF#(Bit#(32)) event_fifo <- mkSizedFIFOF(4); Bit#(8) leds_val = {enabled[0],enabled[1],1'b0,1'b0,1'b0,1'b0,direction[0],direction[1]}; // more information on the Digilent PmodHB5: // https://digilentinc.com/Data/Products/PMOD-HB5/PmodHB5_RevD_rm.pdf // frequency of design: 100 mHz // frequency of PWM System: 2 kHz // 2k design cycles == 1 PWM cycle Reg#(Bit#(11)) fcnt <- mkReg(0); rule detect_event; Vector#(2,Bool) npz; for(int i = 0; i < 2; i=i+1) npz[i] = power[i]==0; Bool started = fold(booland, readVReg(pz)) && !fold(booland, npz); Bool stopped = !fold(booland, readVReg(pz)) && fold(booland, npz); Bit#(32) e = 0; e = e | (extend(pack(stopped)) << pack(HBridgeCtrlEvent_Stopped)); e = e | (extend(pack(started)) << pack(HBridgeCtrlEvent_Started)); if (e != 0 && event_fifo.notFull) event_fifo.enq(e); writeVReg(pz,npz); endrule rule report_event; ind.hbc_event(event_fifo.first); event_fifo.deq; endrule rule pwm; for(Integer i = 0; i < 2; i=i+1) enabled[i] <= ((power[i] > 0) && (fcnt <= power[i])) ? 1 : 0; fcnt <= fcnt+1; endrule interface HBridgeCtrlRequest req; method Action ctrl(Vector#(2,Bit#(11)) p, Vector#(2,Bit#(1)) d); for(Integer i = 0; i < 2; i=i+1) begin direction[i] <= d[i]; power[i] <= p[i]; end endmethod endinterface interface HBridgeSimplePins pins; interface HBridge2Pins hbridge; interface HBridgePins hbridge0; method Bit#(1) enabled(); return enabled[0]; endmethod method Bit#(1) direction(); return direction[0]; endmethod endinterface interface HBridgePins hbridge1; method Bit#(1) enabled(); return enabled[1]; endmethod method Bit#(1) direction(); return direction[1]; endmethod endinterface endinterface interface LEDS leds; method Bit#(LedsWidth) leds() = leds_val; endinterface endinterface endmodule ================================================ FILE: lib/zedboard_robot/bsv/MaxSonarController.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Leds::*; import Vector::*; import ConnectalMemTypes::*; import GetPut::*; import Gearbox::*; import FIFO::*; interface MaxSonarPins; method Bit#(1) range_ctrl(); method Action pulse(Bit#(1) v); endinterface interface MaxSonarCtrlRequest; method Action pulse_width(); method Action range_ctrl(Bit#(1) v); endinterface interface MaxSonarCtrlIndication; method Action range_ctrl(Bit#(1) v); method Action pulse_width(Bit#(32) v); endinterface interface MaxSonarSampleStream; method Action sample(Bit#(32) v); endinterface interface MaxSonarSimplePins; interface MaxSonarPins maxsonar; interface LEDS leds; endinterface interface MaxSonarController; interface MaxSonarCtrlRequest req; interface MaxSonarSimplePins pins; endinterface module mkMaxSonarController#(MaxSonarCtrlIndication ind)(MaxSonarController); Reg#(Bit#(1)) range_ctrl_reg <- mkReg(0); Vector#(2,Reg#(Bit#(32))) high_cnt <- replicateM(mkReg(0)); Reg#(Bit#(1)) last_pulse <- mkReg(0); Reg#(Bool) end_pulse <- mkReg(False); FIFO#(Bool) pw_fifo <- mkSizedFIFO(1); `ifdef SIMULATION Reg#(Bit#(32)) bsim_cnt <- mkReg(0); Reg#(Bit#(32)) bsim_pulse <- mkReg(0); `endif let clk <- exposeCurrentClock; let rst <- exposeCurrentReset; Gearbox#(1,2,Bit#(32)) gb <- mk1toNGearbox(clk,rst,clk,rst); let verbose = True; `ifdef SIMULATION rule bsim_pulse_rule if (!end_pulse); if (bsim_pulse[10] == 1) begin bsim_cnt <= bsim_cnt+1; high_cnt[1] <= bsim_cnt+1; end_pulse <= True; bsim_pulse <= 0; end else begin bsim_pulse <= bsim_pulse+1; end endrule `endif rule fill_gb if (end_pulse); end_pulse <= False; gb.enq(cons(high_cnt[1],nil)); endrule interface MaxSonarCtrlRequest req; method Action range_ctrl(Bit#(1) v); range_ctrl_reg <= v; ind.range_ctrl(v); endmethod method Action pulse_width(); ind.pulse_width(high_cnt[1]); endmethod endinterface interface MaxSonarSimplePins pins; // pulse width modulation interface MaxSonarPins maxsonar; method Bit#(1) range_ctrl(); return range_ctrl_reg; endmethod method Action pulse(Bit#(1) v); last_pulse <= v; if (last_pulse == 1 && v == 0) begin // end of pulse high_cnt[1] <= high_cnt[0]; high_cnt[0] <= 0; end_pulse <= True; end else if (v == 1) begin high_cnt[0] <= high_cnt[0]+1; end endmethod endinterface interface LEDS leds; method Bit#(LedsWidth) leds() = extend(range_ctrl_reg); endinterface endinterface endmodule ================================================ FILE: lib/zedboard_robot/cpp/read_buffer.cpp ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "read_buffer.h" int reader::read_circ_buff(int buff_len, unsigned int ref_dstAlloc, int dstAlloc, char* dstBuffer, char *snapshot, int write_addr, int write_wrap_cnt) { int dwc = write_wrap_cnt - wrap_cnt; int two,top,bottom,datalen=0; if(dwc == 0){ assert(addr <= write_addr); two = false; top = write_addr; bottom = addr; datalen = write_addr - addr; } else if (dwc == 1 && addr > write_addr) { two = true; top = addr; bottom = write_addr; datalen = (buff_len-top)+bottom; } else if (write_addr == 0) { two = false; top = buff_len; bottom = 0; datalen = buff_len; } else { two = true; top = write_addr; bottom = write_addr; datalen = buff_len; fprintf(stderr, "WARNING: sock_server::read_circ_buffer dwc>1\n"); } portalCacheFlush(dstAlloc, dstBuffer, buff_len, 1); if (verbose) fprintf(stderr, "bottom:%4x, top:%4x, two:%d, datalen:%4x, dwc:%d\n", bottom,top,two,datalen,dwc); if (datalen){ if (two) { memcpy(snapshot, dstBuffer+top, datalen-bottom); memcpy(snapshot+(datalen-bottom), dstBuffer, bottom ); } else { memcpy(snapshot, dstBuffer+bottom, datalen ); } } addr = write_addr; wrap_cnt = write_wrap_cnt; return datalen; } ================================================ FILE: lib/zedboard_robot/cpp/read_buffer.h ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. class reader { private: int wrap_cnt; int addr; public: int verbose; reader(): wrap_cnt(0), addr(0){} int read_circ_buff(int buff_len, unsigned int ref_dstAlloc, int dstAlloc, char* dstBuffer,char *snapshot, int write_addr, int write_wrap_cnt); }; ================================================ FILE: pcie/Makefile ================================================ # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # ifeq ("$(DESTDIR)","") PREFIX?=/usr/local else PREFIX?=/usr endif all: install: install -D -m755 pcieflat $(DESTDIR)$(PREFIX)/bin/pcieflat clean: ================================================ FILE: pcie/pcieflat ================================================ #!/usr/bin/env python3 # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # from __future__ import print_function import fcntl, glob, json, struct, subprocess, sys from gmpy import mpz BNOC_TRACE = 0xc008b508 Trace_len = 144 struct_traceData = '@ L I I 16I 16I' BNOC_GET_TLP = 0x8008b507 Tlp_len = 24 BNOC_ENABLE_TRACE = 0x8008b508 Enable_len = 4 PCIE_CHANGE_ENTRY = 0x8008b50f struct_changeEntry = '@ I I' ChangeEntry_len = 8 # 64-bit BAR tlpdatalog = [ '000000011184ffff4a000001020000040018001068470000', '000000020984fff0000000010018000fdf508000e775b7be', '000000031184ffff4a0000010200000400180000bad0dada', '000000040984fff0000000010018000fdf5040002c7bdba8', '000000051184ffff4a0000010200000400180000005a05a0', '000000060984fff0000000010018000fdf5000001ce1d27f', '000000071184ffff4a0000010200000400180000005b05b0', '000000080984fff0000000010018000fdf5040009c773d52', '000000091184ffff4a0000010200000400180000005a05a0', '0000000a0984fff0000000010018000fdf50c0107d93c3c9', '0000000b1184ffff4a000001020000040018001068470000', '0000000c0984fff0000000010018000fdf50800099159bf9', '0000000d1184ffff4a0000010200000400180000bad0dada', '0000000e0984fff0000000010018000fdf5040008fc4124f', '0000000f1184ffff4a0000010200000400180000005a05a0', '000000100984fff0000000010018000fdf5000000f52fd62', ] TlpPacketType = [ 'MRW', # 'MEMORY_READ_WRITE' 'MEMORY_READ_LOCKED', 'IO_REQUEST', 'UNKNOWN_TYPE_3', 'CONFIG_0_READ_WRITE', 'CONFIG_1_READ_WRITE', 'UNKNOWN_TYPE_6', 'UNKNOWN_TYPE_7', 'UNKNOWN_TYPE_8', 'UNKNOWN_TYPE_9', 'COMP', 'COMPLETION_LOCKED', 'UNKNOWN_TYPE_12', 'UNKNOWN_TYPE_13', 'UNKNOWN_TYPE_14', 'UNKNOWN_TYPE_15', 'MSG_ROUTED_TO_ROOT', 'MSG_ROUTED_BY_ADDR', 'MSG_ROUTED_BY_ID', 'MSG_ROOT_BROADCAST', 'MSG_LOCAL', 'MSG_GATHER', 'UNKNOWN_TYPE_22', 'UNKNOWN_TYPE_23', 'UNKNOWN_TYPE_24', 'UNKNOWN_TYPE_25', 'UNKNOWN_TYPE_26', 'UNKNOWN_TYPE_27', 'UNKNOWN_TYPE_28', 'UNKNOWN_TYPE_29', 'UNKNOWN_TYPE_30', 'UNKNOWN_TYPE_31' ] TlpPacketFormat = [ 'MEM_READ__3DW ', 'MEM_READ__4DW ', 'MEM_WRITE_3DW_DATA', 'MEM_WRITE_4DW_DATA', 'TLP Prefix', 'UNKNOWN_FMT_5', 'UNKNOWN_FMT_6', 'UNKNOWN_FMT_7', ] Pcie3ChangeSrc = [ 'none', 'current_speed', 'dpa_substate_change', 'err_cor_out', 'err_fatal_out', 'err_nonfatal_out', 'flr_in_process', 'function_power_state', 'function_status', 'hot_reset_out', 'link_power_state', 'ltr_enable', 'ltssm_state', 'max_payload', 'max_read_req', 'negotiated_width', 'obff_enable', 'phy_link_down', 'phy_link_status', 'pl_status_change', 'power_state_change_interrupt', 'rcb_status', 'backpressure_count' ] first_vcd_timestamp = mpz(0) last_vcd_timestamp = mpz(0) last_vcd_pktclass_code = None def byteswap(be): return '%s%s%s%s' % (be[6:8],be[4:6],be[2:4],be[0:2]) pktclassCodes = { 'CpuRReq': 'S', 'CpuWReq': 'T', 'CpuRResp': 's', '(to) slave continuation': 'c', 'DmaWReq': 'W', 'DmaRReq': 'M', 'DmaRResp': 'm', '(to) master continuation': 'C', 'trace': 't', } vcd_header_template=''' $version tlp.py $end $comment $end $timescale 8ns $end $scope module logic $end %(vars)s $upscope $end $enddefinitions $end ''' unused=''' $dumpvars %(dumpvars)s $end ''' def emit_vcd_header(f): f.write(vcd_header_template % { 'vars': '\n'.join(['$var wire 1 %s %s $end' % (pktclassCodes[k], k.lower().replace(' ', '_')) for k in pktclassCodes]), 'dumpvars': '\n'.join(['0%s' % pktclassCodes[k] for k in pktclassCodes]) }) def emit_vcd_entry(f, timestamp, pktclass): global first_vcd_timestamp, last_vcd_timestamp, last_vcd_pktclass_code if not timestamp: return if not first_vcd_timestamp: first_vcd_timestamp = timestamp #print last_vcd_timestamp, timestamp, (timestamp < last_vcd_timestamp) if last_vcd_timestamp and (timestamp < last_vcd_timestamp): f.write('$comment %s %s %s $end\n' % (hex(last_vcd_timestamp), hex(timestamp), hex(timestamp + mpz('100000000', 16)))) timestamp = timestamp + mpz('100000000', 16) f.write('$comment %s %s $end\n' % (hex(timestamp), hex(timestamp - first_vcd_timestamp))) #timestamp = timestamp - first_vcd_timestamp if last_vcd_timestamp and timestamp > (last_vcd_timestamp+1): f.write('#%s\n0%s\n' % ((last_vcd_timestamp+mpz(1)), last_vcd_pktclass_code)) if pktclass in pktclassCodes: pktclass_code = pktclassCodes[pktclass] f.write('#%s\n' % timestamp) f.write('1%s\n' % pktclass_code) if last_vcd_pktclass_code and last_vcd_pktclass_code != pktclass_code: f.write('0%s\n' % last_vcd_pktclass_code) last_vcd_pktclass_code = pktclass_code last_vcd_timestamp = timestamp else: f.write('$comment %s $end\n' % pktclass) def pktClassification(tlpsof, tlpeof, tlpbe, pktformat, pkttype, portnum, address): ## altera does not fill in the BE bits #if tlpbe == '0000': #return 'trace' if tlpsof == 0: if portnum == 4: return 'DmaRCon' else: return 'CpuRCon' if portnum == 4: if pkttype == 10: # COMPLETION return 'DmaRRsp' else: if pktformat == 2 or pktformat == 3: return 'CpuWReq' else: return 'CpuRReq' elif portnum == 8: if pkttype == 10: # COMPLETION return 'CpuRRsp' else: if pktformat == 2 or pktformat == 3: if (address[0:3] == 'fee'): return 'Interru' else: return 'DmaWReq' else: return 'DmaRReq' else: return ' Misc' classCounts = {} last_seqno = mpz(-1) def interfaceId(interfaceNumber): if (interfaceNumber >= 0 and interfaceNumber < len(fooMap)): return fooMap[interfaceNumber] else: return '%x' % interfaceNumber def interfaceName(interfaceNumber): if (interfaceNumber >= 0 and interfaceNumber < len(fooMap)): return interfaceMap[fooMap[interfaceNumber]] else: return '%x' % interfaceNumber def print_tlp(tlpdata, f=None): global last_seqno def segment(i): return tlpdata[i*8:i*8+8] def byteswap(w): def byte(i): return w[i*2:i*2+2] return ''.join(map(byte, [3,2,1,0])) words = map(segment, [0,1,2,3,4,5]) seqno = mpz(tlpdata[0:8],16) if last_seqno >= 0: delta = seqno - last_seqno else: delta = 0 tlpsof = int(tlpdata[9:10],16) & 1 tlpeof = int(tlpdata[10:12],16) >> 7 tlpbe = tlpdata[12:16] tlphit = int(tlpdata[10:12],16) & 0x7f pktformat = (int(tlpdata[16:17],16) >> 1) & 7 pkttype = (int(tlpdata[16:18],16) & 0x1f) address=0 if TlpPacketFormat[pktformat] == 'MEM_READ__4DW ' or TlpPacketFormat[pktformat] == 'MEM_WRITE_4DW_DATA': address = tlpdata[32:] elif TlpPacketFormat[pktformat] == 'MEM_READ__3DW ' or TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA': address = tlpdata[32:40] portnum = int(tlpdata[8:10],16) >> 1 pktclass = pktClassification(tlpsof, tlpeof, tlpbe, pktformat, pkttype, portnum, address) if pktclass in classCounts: classCounts[pktclass] += 1 else: classCounts[pktclass] = 1 if f: emit_vcd_entry(f, seqno, pktclass) headerstr = tlpdata headerstr = '' headerstr = headerstr + '%6s' % (pktclass) if tlpsof: headerstr = headerstr + ':%4s:%18s' % (TlpPacketType[pkttype], TlpPacketFormat[pktformat]) else: headerstr = headerstr + ' ' headerstr = headerstr + ' ' + tlpdata[8:10] + ' ' + hex(int(tlpdata[8:10],16) >> 1) headerstr = headerstr + ' tlp(%s %d %d %d)' % (tlpbe, tlphit, tlpeof, tlpsof) address = -1 if tlpsof == 0: headerstr = headerstr + ' data:' + tlpdata[16:] elif TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA' and TlpPacketType[pkttype] == 'COMP': headerstr = headerstr + ' tag:' + tlpdata[36:38] headerstr = headerstr + ' ' + tlpdata[32:36] headerstr = headerstr + ' ' + tlpdata[24:28] headerstr = headerstr + ' ' + tlpdata[28:29] headerstr = headerstr + ' ' + tlpdata[20:21] + str(int(tlpdata[20:21],16) >> 3) headerstr = headerstr + ' ' + tlpdata[29:32] headerstr = headerstr + ' ' + tlpdata[38:40] headerstr = headerstr + ' %3d' % (int(tlpdata[21:24],16) & 0x3ff) headerstr = headerstr + ' ' + byteswap(tlpdata[40:]) elif TlpPacketFormat[pktformat] == 'MEM_READ__3DW ' or TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA': address = tlpdata[32:40] headerstr = headerstr + ' ' + address address = int(address,16) headerstr = headerstr + ' %4x'% ((address >> 2) % 8192) headerstr = headerstr + ' be(' + tlpdata[31:32] + ' ' + tlpdata[30:31] + ')' headerstr = headerstr + ' tag:' + tlpdata[28:30] headerstr = headerstr + ' ' + tlpdata[24:28] headerstr = headerstr + ' %3d' % (int(tlpdata[21:24],16) & 0x3ff) if TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA': headerstr = headerstr + ' ' + byteswap(tlpdata[40:]) elif TlpPacketFormat[pktformat] == 'MEM_READ__4DW ' or TlpPacketFormat[pktformat] == 'MEM_WRITE_4DW_DATA': address = tlpdata[32:] headerstr = headerstr + ' address: ' + address address = int(address,16) headerstr = headerstr + ' be(1st: ' + tlpdata[31:32] + ' last:' + tlpdata[30:31] + ')' headerstr = headerstr + ' tag:' + tlpdata[28:30] headerstr = headerstr + ' reqid:' + tlpdata[24:28] headerstr = headerstr + ' length:' + str(int(tlpdata[21:24],16) & 0x3ff) elif TlpPacketFormat[pktformat] == 'TLP Prefix': headerstr = headerstr + tlpdata else: headerstr = headerstr + ' tlp data:' + tlpdata[40:] headerstr = headerstr + 'lower addr:' + tlpdata[38:40] headerstr = headerstr + ' tag:' + tlpdata[36:38] headerstr = headerstr + ' reqid:' + tlpdata[34:36] headerstr = headerstr + ' bytecount:' + '0x' + tlpdata[33:34] headerstr = headerstr + ' bcm:' + str(int(tlpdata[32:33], 16) & 1) headerstr = headerstr + ' cstatus:' + str((int(tlpdata[32:33], 16) >> 1) & 7) headerstr = headerstr + ' cmplid:' + tlpdata[30:32] headerstr = headerstr + ' cmplen:' + tlpdata[27:30] headerstr = headerstr + ' nosnoop:' + str(int(tlpdata[26:27],16) & 1) headerstr = headerstr + ' relaxed:' + str(int(tlpdata[26:27],16) & 2) headerstr = headerstr + ' poison:' + str(int(tlpdata[26:27],16) & 4) headerstr = headerstr + ' digest:' + str(int(tlpdata[26:27],16) & 8) headerstr = headerstr + ' zero:' + tlpdata[25:26] headerstr = headerstr + ' tclass:' + tlpdata[24:25] headerstr = headerstr + ' pkttype:' + str(int(tlpdata[22:24],16) & 0x1f) + ' ' + TlpPacketType[int(tlpdata[22:24],16) & 0x1f] headerstr = headerstr + ' format:' + str((int(tlpdata[22:24],16) >> 1) & 3) + ' ' + TlpPacketFormat[(int(tlpdata[22:24],16) >> 1) & 3] if portnum == 4: dir = 'RX' elif portnum == 8: dir = 'TX' else: dir = '__' if tlpsof == 0: dir = dir + 'cc' # continuation elif pkttype == 10: dir = dir + 'pp' # response else: dir = dir + 'qq' # request smeth = '' if address != -1 and address < baseLimit and interfaceMap != {}: address = address - base interfaceNumber = address / 0x10000 offset = address - interfaceNumber * 0x10000 methodNumber = offset / 0x100 #print 'AA', "%6x" % address, "%2x" % interfaceNumber, "%2x" % methodNumber t = interfaceName(interfaceNumber) if methodNumber == 0: smeth = '/dir' elif methodNumber <= len(t): offset = offset - methodNumber * 0x100 smeth = '/'+t[methodNumber-1] smeth = ('%02d' % interfaceNumber) + '/' + interfaceId(interfaceNumber) + smeth + '/' + "%x" % (offset/4) print(dir, '%10d %10d %s' % (seqno, delta, headerstr), smeth) #print ' ' + tlpdata[0:8] + ' ' + tlpdata[8:] if len(tlpdata) != 48: print('bogus len', len(tlpdata)) sys.exit(1) last_seqno = seqno def print_tlp_log(tlplog, f=None, lf=None): if f: emit_vcd_header(f) #ts delta response foo XXX tlp(be hit eof sof) pkttype format address off be(1st last) tag req clid stat nosnoop bcnt laddr length data print(' ts delta response XXX tlp address off be tag clid nosnp laddr data') print(' pkttype format foo (be hit eof sof) (1st last) req stat bcnt length') for tlpdata in tlplog: if tlpdata.startswith('00000000') or tlpdata == '': continue if lf: lf.write(tlpdata+'\n') print_tlp(tlpdata, f) if __name__ == '__main__': argindex = 1 argcount = len(sys.argv) jsondata = {} interfaceMap = {} if argcount >= 2 and sys.argv[argindex] == '-j': fooMap = sys.argv[argindex+1].split(':') print('FFF', fooMap) j2file = open(sys.argv[argindex + 2]).read() jsondata = json.loads(j2file) argindex = argindex + 3 argcount = argcount - 3 for item in jsondata['interfaces']: interfaceMap[item['name']] = [mitem['name'] for mitem in item['decls']] devfilenames = glob.glob('/dev/portal_*') print('pcieflat: devices are', devfilenames) if argcount == 2: tlplog = open(sys.argv[argindex]).read().split('\n') base = 0 elif False: tlplog = subprocess.check_output(['connectalutil', devfilenames[0]]).split('\n') tlpfirst = tlplog.pop(0) base = int(tlpfirst[0:16],16) base = int(tlpfirst[0:8],16) else: fd = open(devfilenames[0], 'rw') try: while 1: buf = fcntl.ioctl(fd, PCIE_CHANGE_ENTRY, ' ' * ChangeEntry_len) (ts,v) = struct.unpack_from(struct_changeEntry, buf) if (v == 0 or v == 0xbad0add0 or ts == 0xbad0add0): break src = v & 0xff value = v >> 8 print('pcie status change: %12d src=%20s:%02d value=%#06x' % (ts, Pcie3ChangeSrc[src], src, value)) pass except: pass buf = fcntl.ioctl(fd, BNOC_TRACE, ' ' * Trace_len) traceData = struct.unpack_from(struct_traceData, buf) #print 'SSS', traceData base = traceData[0] #print ('base %x' % base), 'trace', traceData[1], 'len', traceData[2], 'intval', ['%x' % p for p in traceData[3:3+16]], 'name', traceData[19:19+16] tlplog = [] tlplog.append('%016x' % traceData[0]) counter = traceData[2] while counter > 0: counter = counter - 1 buf = fcntl.ioctl(fd, BNOC_GET_TLP, ' ' * Tlp_len) foo = '' for x in buf: foo = "%02x" % ord( x ) + foo tlplog.append(foo) fcntl.ioctl(fd, BNOC_ENABLE_TRACE, 1) #for foo in tlplog: # print foo #sys.exit(1) tlplog.sort() lf = open('tlp.log', 'w') f = open('tlp.vcd', 'w') baseLimit = base + 16 * 0x10000 print_tlp_log(tlplog, f, lf) print(classCounts) print(sum([ classCounts[k] for k in classCounts])) f.close() lf.close() ================================================ FILE: pcie/tlp.py ================================================ #!/usr/bin/env python3 from __future__ import print_function import os import re import sys import subprocess from gmpy import mpz # 64-bit BAR tlpdatalog = [ '000000011184ffff4a000001020000040018001068470000', '000000020984fff0000000010018000fdf508000e775b7be', '000000031184ffff4a0000010200000400180000bad0dada', '000000040984fff0000000010018000fdf5040002c7bdba8', '000000051184ffff4a0000010200000400180000005a05a0', '000000060984fff0000000010018000fdf5000001ce1d27f', '000000071184ffff4a0000010200000400180000005b05b0', '000000080984fff0000000010018000fdf5040009c773d52', '000000091184ffff4a0000010200000400180000005a05a0', '0000000a0984fff0000000010018000fdf50c0107d93c3c9', '0000000b1184ffff4a000001020000040018001068470000', '0000000c0984fff0000000010018000fdf50800099159bf9', '0000000d1184ffff4a0000010200000400180000bad0dada', '0000000e0984fff0000000010018000fdf5040008fc4124f', '0000000f1184ffff4a0000010200000400180000005a05a0', '000000100984fff0000000010018000fdf5000000f52fd62', ] TlpPacketType = [ 'MEMORY_READ_WRITE', 'MEMORY_READ_LOCKED', 'IO_REQUEST', 'UNKNOWN_TYPE_3', 'CONFIG_0_READ_WRITE', 'CONFIG_1_READ_WRITE', 'UNKNOWN_TYPE_6', 'UNKNOWN_TYPE_7', 'UNKNOWN_TYPE_8', 'UNKNOWN_TYPE_9', 'COMPLETION', 'COMPLETION_LOCKED', 'UNKNOWN_TYPE_12', 'UNKNOWN_TYPE_13', 'UNKNOWN_TYPE_14', 'UNKNOWN_TYPE_15', 'MSG_ROUTED_TO_ROOT', 'MSG_ROUTED_BY_ADDR', 'MSG_ROUTED_BY_ID', 'MSG_ROOT_BROADCAST', 'MSG_LOCAL', 'MSG_GATHER', 'UNKNOWN_TYPE_22', 'UNKNOWN_TYPE_23', 'UNKNOWN_TYPE_24', 'UNKNOWN_TYPE_25', 'UNKNOWN_TYPE_26', 'UNKNOWN_TYPE_27', 'UNKNOWN_TYPE_28', 'UNKNOWN_TYPE_29', 'UNKNOWN_TYPE_30', 'UNKNOWN_TYPE_31' ] TlpPacketFormat = [ 'MEM_READ_3DW_NO_DATA', 'MEM_READ_4DW_NO_DATA', 'MEM_WRITE_3DW_DATA', 'MEM_WRITE_4DW_DATA' ] first_vcd_timestamp = mpz(0) last_vcd_timestamp = mpz(0) last_vcd_pktclass_code = None pktclassCodes = { 'Slave Request': 'S', 'Slave Write Request': 'T', 'Slave Response': 's', 'slave continuation': 'c', 'Master Write Request': 'W', 'Master Request': 'M', 'Master Response': 'm', 'master continuation': 'C', 'trace': 't', } vcd_header_template=''' $version tlp.py $end $comment $end $timescale 8ns $end $scope module logic $end %(vars)s $upscope $end $enddefinitions $end ''' unused=''' $dumpvars %(dumpvars)s $end ''' def emit_vcd_header(f): f.write(vcd_header_template % { 'vars': '\n'.join(['$var wire 1 %s %s $end' % (pktclassCodes[k], k.lower().replace(' ', '_')) for k in pktclassCodes]), 'dumpvars': '\n'.join(['0%s' % pktclassCodes[k] for k in pktclassCodes]) }) def emit_vcd_entry(f, timestamp, pktclass): global first_vcd_timestamp, last_vcd_timestamp, last_vcd_pktclass_code if not timestamp: return if not first_vcd_timestamp: first_vcd_timestamp = timestamp print(last_vcd_timestamp, timestamp, (timestamp < last_vcd_timestamp)) if last_vcd_timestamp and (timestamp < last_vcd_timestamp): f.write('$comment %s %s %s $end\n' % (hex(last_vcd_timestamp), hex(timestamp), hex(timestamp + mpz('100000000', 16)))) timestamp = timestamp + mpz('100000000', 16) f.write('$comment %s %s $end\n' % (hex(timestamp), hex(timestamp - first_vcd_timestamp))) #timestamp = timestamp - first_vcd_timestamp if last_vcd_timestamp and timestamp > (last_vcd_timestamp+1): f.write('#%s\n0%s\n' % ((last_vcd_timestamp+mpz(1)), last_vcd_pktclass_code)) if pktclass in pktclassCodes: pktclass_code = pktclassCodes[pktclass] f.write('#%s\n' % timestamp) f.write('1%s\n' % pktclass_code) if last_vcd_pktclass_code and last_vcd_pktclass_code != pktclass_code: f.write('0%s\n' % last_vcd_pktclass_code) last_vcd_pktclass_code = pktclass_code last_vcd_timestamp = timestamp else: f.write('$comment %s $end\n' % pktclass) def pktClassification(tlpsof, tlpeof, tlpbe, pktformat, pkttype, portnum): if tlpbe == '0000': return 'trace' if tlpsof == 0: if portnum == 4: return 'master continuation' else: return 'slave continuation' if portnum == 4: if pkttype == 10: # COMPLETION return 'Master Response' else: if pktformat == 2 or pktformat == 3: return 'Slave Write Request' else: return 'Slave Request' elif portnum == 8: if pkttype == 10: # COMPLETION return 'Slave Response' else: if pktformat == 2 or pktformat == 3: return 'Master Write Request' else: return 'Master Request' else: return 'Misc' classCounts = {} last_seqno = mpz(-1) def print_tlp(tlpdata, f=None): global last_seqno def segment(i): return tlpdata[i*8:i*8+8] def byteswap(w): def byte(i): return w[i*2:i*2+2] return ''.join(map(byte, [3,2,1,0])) words = map(segment, [0,1,2,3,4,5]) seqno = mpz(tlpdata[-48:-40],16) if last_seqno >= 0: delta = seqno - last_seqno else: delta = 0 tlpsof = int(tlpdata[-39:-38],16) & 1 tlpeof = int(tlpdata[-38:-36],16) >> 7 tlpbe = tlpdata[-36:-32] tlphit = int(tlpdata[-38:-36],16) & 0x7f pktformat = (int(tlpdata[-32:-31],16) >> 1) & 3 pkttype = (int(tlpdata[-32:-30],16) & 0x1f) portnum = int(tlpdata[-40:-38],16) >> 1 pktclass = pktClassification(tlpsof, tlpeof, tlpbe, pktformat, pkttype, portnum) if pktclass in classCounts: classCounts[pktclass] += 1 else: classCounts[pktclass] = 1 if f: emit_vcd_entry(f, seqno, pktclass) print(tlpdata) print('timestamp:', seqno) print(' delta:', delta) last_seqno = seqno print(' ', pktclass) print(' foo:', tlpdata[-40:-38], hex(int(tlpdata[-40:-38],16) >> 1)) print(' tlpbe:', tlpbe) print(' tlphit:', tlphit) print(' tlpeof:', tlpeof) print(' tlpsof:', tlpsof) if tlpsof: print(' format:', tlpdata[-32:-31], pktformat, TlpPacketFormat[pktformat]) print(' pkttype:', tlpdata[-32:-30], pkttype, TlpPacketType[pkttype]) if tlpsof == 0: print(' data:', tlpdata[-32:]) elif TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA' and TlpPacketType[pkttype] == 'COMPLETION': print(' tag:', tlpdata[-12:-10]) print(' reqid:', tlpdata[-16:-12]) print(' cmplid:', tlpdata[-24:-20]) print(' status:', tlpdata[-20:-19]) print(' nosnoop:', tlpdata[-28:-27], int(tlpdata[-28:-27],16) >> 3) print('bytecount:', tlpdata[-19:-16]) print('loweraddr:', tlpdata[-10:-8]) print(' length:', int(tlpdata[-27:-24],16) & 0x3ff) print(' data:', tlpdata[-8:]) elif TlpPacketFormat[pktformat] == 'MEM_READ_3DW_NO_DATA' or TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA': print(' address:', tlpdata[-16:-8], (int(tlpdata[-16:-8],16) >> 2) % 8192) print(' 1st be:', tlpdata[-17:-16]) print(' last be:', tlpdata[-18:-17]) print(' tag:', tlpdata[-20:-18]) print(' reqid:', tlpdata[-24:-20]) print(' length:', int(tlpdata[-27:-24],16) & 0x3ff) if TlpPacketFormat[pktformat] == 'MEM_WRITE_3DW_DATA': print(' data:', tlpdata[-8:]) elif TlpPacketFormat[pktformat] == 'MEM_READ_4DW_NO_DATA' or TlpPacketFormat[pktformat] == 'MEM_WRITE_4DW_DATA': print(' address:', tlpdata[-16:]) print(' 1st be:', tlpdata[-17:-16]) print(' last be:', tlpdata[-18:-17]) print(' tag:', tlpdata[-20:-18]) print(' reqid:', tlpdata[-24:-20]) print(' length:', int(tlpdata[-27:-24],16) & 0x3ff) else: print(' tlp data:', tlpdata[-8:]) print('lower addr:', tlpdata[-10:-8]) print(' tag:', tlpdata[-12:-10]) print(' reqid:', tlpdata[-14:-12]) print(' bytecount:', '0x' + tlpdata[-15:-14]) print(' bcm:', int(tlpdata[-16:-15], 16) & 1) print(' cstatus:', (int(tlpdata[-16:-15], 16) >> 1) & 7) print(' cmplid:', tlpdata[-18:-16]) print(' cmplen:', tlpdata[-21:-18]) print(' nosnoop:', int(tlpdata[-22:-21],16) & 1) print(' relaxed:', int(tlpdata[-22:-21],16) & 2) print(' poison:', int(tlpdata[-22:-21],16) & 4) print(' digest:', int(tlpdata[-22:-21],16) & 8) print(' zero:', tlpdata[-23:-22]) print(' tclass:', tlpdata[-24:-23]) print(' pkttype:', int(tlpdata[-26:-24],16) & 0x1f, TlpPacketType[int(tlpdata[-26:-24],16) & 0x1f]) print(' format:', (int(tlpdata[-26:-24],16) >> 1) & 3, TlpPacketFormat[(int(tlpdata[-26:-24],16) >> 1) & 3]) print() def print_tlp_log(tlplog, f=None): if f: emit_vcd_header(f) for tlpdata in tlplog: if tlpdata == '000000000000000000000000000000000000000000000000': continue m = re.match('^([0-9A-Fa-f]+)$', tlpdata) if m: print_tlp(tlpdata, f) if __name__ == '__main__': f = open('tlp.vcd', 'w') if len(sys.argv) > 1 and sys.argv[1] == 'openocd': os.chdir('/scratch/jamey/connectal/jtag') tlplog = subprocess.check_output(['openocd', '-f', 'pcietrace.cfg'], stderr=subprocess.STDOUT).split('\n') elif len(sys.argv) > 1: tlplog = open(sys.argv[1]).read().split('\n') else: tlplog = subprocess.check_output(['connectalutil', 'tlp', '/dev/portal0']).split('\n') print_tlp_log(tlplog[0:-1], f) print(classCounts) print(sum([ classCounts[k] for k in classCounts])) ================================================ FILE: scripts/AST.py ================================================ # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # from __future__ import print_function import math import re import functools import json import os import sys import traceback import AST import globalv import util verbose = False tempFilename = 'generatedDesignInterfaceFile.json' lookupTable = {} class InterfaceMixin: def getSubinterface(self, name): subinterfaceName = name if not subinterfaceName in globalv.globalvars: return None subinterface = globalv.globalvars[subinterfaceName] #print('subinterface', subinterface, subinterface) return subinterface def parentClass(self, default): rv = default if (len(self.typeClassInstances)==0) else (self.typeClassInstances[0]) return rv def dtInfo(arg): rc = {} if hasattr(arg, 'name'): rc['name'] = arg.name if lookupTable.get(arg.name): rc['name'] = lookupTable[arg.name] if hasattr(arg, 'type') and arg.type != 'Type': rc['type'] = arg.type if lookupTable.get(arg.type): rc['type'] = lookupTable[arg.type] if hasattr(arg, 'params'): if arg.params is not None and arg.params != []: rc['params'] = [dtInfo(p) for p in arg.params] if hasattr(arg, 'elements'): if arg.type == 'Enum': rc['elements'] = arg.elements else: rc['elements'] = [piInfo(p) for p in arg.elements] return rc def piInfo(pitem): rc = {} rc['pname'] = pitem.name rc['ptype'] = dtInfo(pitem.type) if hasattr(pitem, 'oldtype'): rc['oldtype'] = dtInfo(pitem.oldtype) return rc def declInfo(mitem): rc = {} rc['dname'] = mitem.name rc['dparams'] = [] for pitem in mitem.params: rc['dparams'].append(piInfo(pitem)) return rc def classInfo(item): rc = { 'Package': os.path.splitext(os.path.basename(item.package))[0], 'cname': item.name, 'cdecls': [], } for mitem in item.decls: rc['cdecls'].append(declInfo(mitem)) return rc def serialize_json(interfaces, globalimports, bsvdefines): global verbose itemlist = [] for item in interfaces: itemlist.append(classInfo(item)) jfile = open(tempFilename, 'w') toplevel = {} toplevel['interfaces'] = itemlist gdlist = [] for item in globalv.globaldecls: if item.type == 'TypeDef': newitem = {'dtype': item.type} newitem['tname'] = item.name newitem['tdtype'] = dtInfo(item.tdtype) if item.params: newitem['tparams'] = item.params if verbose: print('TYPEDEF globaldecl:', item, newitem) gdlist.append(newitem) elif verbose: print('Unprocessed globaldecl:', item) toplevel['globaldecls'] = gdlist toplevel['globalimports'] = globalimports toplevel['bsvdefines'] = bsvdefines if True: try: json.dump(toplevel, jfile, sort_keys = True, indent = 4) jfile.close() j2file = open(tempFilename).read() toplevelnew = json.loads(j2file) except: print('Unable to encode json file', tempFilename) #print('WWWW', toplevel) sys.exit(-1) return toplevel class Method: def __init__(self, name, return_type, params): self.type = 'Method' self.name = name self.return_type = return_type self.params = params def __repr__(self): sparams = [p.__repr__() for p in self.params] return '' % (self.name, self.return_type, sparams) def instantiate(self, paramBindings): #print('instantiate method', self.name, self.params) return Method(self.name, self.return_type.instantiate(paramBindings), [ p.instantiate(paramBindings) for p in self.params]) class Function: def __init__(self, name, return_type, params): self.type = 'Function' self.name = name self.return_type = return_type self.params = params def __repr__(self): if not self.params: return '' % (self.name, self.return_type) sparams = list(map(str, self.params)) return '' % (self.name, self.return_type, sparams) class Variable: def __init__(self, name, t, value): self.type = 'Variable' self.name = name self.type = t self.value = value if t and t.type == 'Type' and t.name == 'Integer' and value and value.type == 'Type': lookupTable[name] = value.name def __repr__(self): return '' % (self.name, self.type) class Interface(InterfaceMixin): def __init__(self, name, params, decls, subinterfacename, packagename): self.type = 'Interface' self.name = name self.params = params self.decls = decls self.subinterfacename = subinterfacename self.typeClassInstances = [] self.package = packagename def interfaceType(self): return Type(self.name,self.params) def __repr__(self): return '{interface: %s (%s) : %s}' % (self.name, self.params, self.typeClassInstances) def instantiate(self, paramBindings): newInterface = Interface(self.name, [], [d.instantiate(paramBindings) for d in self.decls], self.subinterfacename, self.package) newInterface.typeClassInstances = self.typeClassInstances return newInterface class Typeclass: def __init__(self, name): self.name = name self.type = 'TypeClass' def __repr__(self): return '{typeclass %s}' % (self.name) class TypeclassInstance: def __init__(self, name, params, provisos, decl): self.name = name self.params = params self.provisos = provisos self.decl = decl self.type = 'TypeclassInstance' def __repr__(self): return '{typeclassinstance %s %s}' % (self.name, self.params) class Module: def __init__(self, moduleContext, name, params, interface, provisos, decls): self.type = 'Module' self.name = name self.moduleContext = moduleContext self.interface = interface self.params = params self.provisos = provisos self.decls = decls def __repr__(self): return '{module: %s %s}' % (self.name, self.decls) class EnumElement: def __init__(self, name, qualifiers, value): self.qualifiers = qualifiers self.value = value def __repr__(self): return '{enumelt: %s}' % (self.name) class Enum: def __init__(self, elements): self.type = 'Enum' self.elements = elements def __repr__(self): return '{enum: %s}' % (self.elements) def instantiate(self, paramBindings): return self class StructMember: def __init__(self, t, name): self.type = t self.name = name def __repr__(self): return '{field: %s %s}' % (self.type, self.name) def instantiate(self, paramBindings): return StructMember(self.type.instantiate(paramBindings), self.name) class Struct: def __init__(self, elements): self.type = 'Struct' self.elements = elements def __repr__(self): return '{struct: %s}' % (self.elements) def instantiate(self, paramBindings): return Struct([e.instantiate(paramBindings) for e in self.elements]) class TypeDef: def __init__(self, tdtype, name, params): self.name = name self.params = params self.type = 'TypeDef' self.tdtype = tdtype if tdtype and tdtype.type != 'Type': tdtype.name = name self.type = 'TypeDef' def __repr__(self): return '{typedef: %s %s}' % (self.tdtype, self.name) class Param: def __init__(self, name, t): self.name = name self.type = t def __repr__(self): return '{param %s: %s}' % (self.name, self.type) def instantiate(self, paramBindings): return Param(self.name, self.type.instantiate(paramBindings)) class Type: def __init__(self, name, params): self.type = 'Type' self.name = name if params: self.params = params else: self.params = [] def __repr__(self): sparams = list(map(str, self.params)) return '{type: %s %s}' % (self.name, sparams) def instantiate(self, paramBindings): #print('Type.instantiate', self.name, paramBindings) if self.name in paramBindings: return paramBindings[self.name] else: return Type(self.name, [p.instantiate(paramBindings) for p in self.params]) ================================================ FILE: scripts/Doxyfile ================================================ # Doxyfile 1.7.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = "CONNECTAL" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = YES # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = bsv # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.bsv # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = scripts/bsv.filter # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # style sheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ================================================ FILE: scripts/Makefile.connectal.application ================================================ # Copyright (c) 2015 The Connectal Project # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # export V=0 ifeq ($(V),0) Q=@ else Q= endif include $(DTOP)/jni/Makefile.generated_files PORTAL_INFRA := portal.c transportHardware.c transportSocket.c transportShared.c transportSerial.c portalJson.c portalPrintf.c poller.cpp sock_utils.c timer.c PORTAL_SRC_FILES := $(addprefix $(CONNECTALDIR)/cpp/, $(PORTAL_INFRA)) \ $(addprefix $(DTOP)/jni/, $(GENERATED_CPP)) BSIM_EXE_CXX_FILES := TlpReplay.cpp BSIM_EXE_CXX := $(addprefix $(CONNECTALDIR)/cpp/, $(BSIM_EXE_CXX_FILES)) ================================================ FILE: scripts/Makefile.connectal.build ================================================ # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # # # File: Makefile.build # V?=0 ifeq ($(V),0) Q=@ BSC_QUIET=-no-show-compiles CONNECTAL_NDK_PARAM="NDK_HOST_ECHO=true" FPGAMAKE_VERBOSE= else Q= BSC_QUIET= CONNECTAL_NDK_PARAM= FPGAMAKE_VERBOSE=-v endif NDK_OBJCOPY=$(shell $(NDKPATH)ndk-which objcopy) ifneq ($(XILINX),) ifeq ($(OS),android) OBJCOPY?=$(NDK_OBJCOPY) BINFILE?=bin/mkTop.xdevcfg.bin.gz else #!android OBJCOPY?=$(TOOLCHAIN)objcopy BINFILE?=bin/mkTop.bin.gz endif #!android else #!XILINX OBJCOPY?= objcopy BINFILE?=bin/mkTop.sof.gz endif #!XILINX CONNECTAL_EXENAME?=ubuntu.exe CONNECTAL_EXENAME2?=ubuntu.exe2 ifneq ($(CONNECTAL_SHARED),) EXENAME=connectal.so else EXENAME=$(CONNECTAL_EXENAME) endif EXENAME2=$(CONNECTAL_EXENAME2) ifeq ($(CONNECTAL_DEBUG),1) GDB=gdb GDB2=gdb else GDB= LD_PRELOAD=libSegFault.so SEGFAULT_USE_ALTSTACK=1 SEGFAULT_OUTPUT_NAME=bin/bsimexe-segv-output.txt GDB2= LD_PRELOAD=libSegFault.so SEGFAULT_USE_ALTSTACK=1 SEGFAULT_OUTPUT_NAME=bin/bsimexe2-segv-output.txt endif GDB_BSIM= LD_PRELOAD=libSegFault.so SEGFAULT_USE_ALTSTACK=1 SEGFAULT_OUTPUT_NAME=bin/bsim-segv-output.txt BLUESPECDIR?=$(shell bsc --help | grep 'Bluespec directory:' | sed 's/Bluespec directory: //') BSCVERSION=$(shell bsc -v |grep version | sed -e "s/.*version //" -e "s/ .*//") BSCMAJOR=$(shell bsc -v |grep version | sed -e "s/.*version //" -e "s/\..*//") ifeq ($(BSCVERSION),) BSIM_LIBRARY_DIR = $(BLUESPECDIR)/Bluesim else ifeq ($(shell test $(BSCMAJOR) -le 2019 &>/dev/null && echo obsolete),obsolete) BSIM_LIBRARY_DIR = $(BLUESPECDIR)/Bluesim/g++4_64 CXXFLAGS_BSIM += -DBSC_OBSOLETE else BSIM_LIBRARY_DIR = $(BLUESPECDIR)/Bluesim endif ifneq ($(BSCMAJOR), 2013) # S0015: The use of a mkSyncReset may not always result in a reset # signal being seen on the destination side. Recommend # replacement with mkAsyncReset. BSCWARNFLAGS += -demote-errors G0066:G0045 -suppress-warnings G0046:G0020:S0015:S0080:S0039:T0127 else #BSCFLAGS_COMMON += -D ExportUnusedClocksAndResets endif ifneq ($(BSCMAJOR), 2013) BSCFLAGS_COMMON += -D ClockDefaultParam endif ifeq ($(BOARD),bluesim) BSCFLAGS_COMMON += -sim else BSCFLAGS_COMMON += -verilog -remove-dollar endif # Add -wait-for-license if bsc supports it BSCFLAGS_COMMON += $(shell bsc -help | grep -q wait-for-license && echo -wait-for-license) BSCOPTFLAGS= -show-schedule -aggressive-conditions -show-method-bvi BSCPATHFLAGS= -bdir $(DTOP)/obj -vdir $(DTOP)/verilog -simdir $(DTOP)/obj -info-dir $(DTOP)/obj BSCFLAGS_COMMON += $(BSCWARNFLAGS) $(BSCOPTFLAGS) $(BSCPATHFLAGS) PROF_FLAGS= #-pg export SIM_CFLAGS= $(CFLAGS_PROJECT) -fPIC -Ijni -I $(CONNECTALDIR)/cpp -I $(CONNECTALDIR) -I $(CONNECTALDIR)/lib/json -O $(PROF_FLAGS) export SIM_CXXFLAGS= $(CXXFLAGS_PROJECT) -fPIC -Ijni -I $(CONNECTALDIR)/cpp -I $(CONNECTALDIR) -O $(PROF_FLAGS) SIM_CXX_COMMON = $(addprefix $(CONNECTALDIR)/cpp/, TlpReplay.cpp BsimDma.cpp sock_utils.c portalPrintf.c XsimTop.cpp poller.cpp transportSocket.c transportHardware.c transportXsim.c portal.c) SIM_CXX_LOCAL = $(SIM_CXX_COMMON) $(DTOP)/jni/XsimMsgRequest.c $(DTOP)/jni/XsimMsgIndication.c $(DTOP)/jni/GeneratedCppCallbacks.cpp ifneq ($(ALTERA),) BLUESPEC_VERILOG+=$(BLUESPECDIR)/Verilog.Quartus endif ifneq ($(XILINX),) BLUESPEC_VERILOG+=$(BLUESPECDIR)/Verilog.Vivado endif #XILINX BLUESPEC_VERILOG+=$(BLUESPECDIR)/Verilog VIVADO=$(shell which vivado) ifneq ($(VIVADO), ) export VIVADODIR=$(shell dirname $(shell dirname $(VIVADO)))) VIVADOFLAGS= -notrace XVLOGFLAGS = endif MODELSIM=$(shell which vsim) ifneq ($(MODELSIM), ) endif QUARTUS=$(shell which quartus_sh) ifneq ($(QUARTUS), ) export QUARTUSDIR=$(shell dirname $(shell dirname $(QUARTUS))) endif ifeq ($(USE_BUILDCACHE),1) BUILDCACHE=$(shell cd $(CONNECTALDIR)/..; /bin/pwd)/buildcache/buildcache ifeq ("$(BUILDCACHE_CACHEDIR)", "") BUILDCACHE_CACHEDIR=$(shell cd $(CONNECTALDIR)/..; /bin/pwd)/fpgamake-cache endif endif EXTRABSVPATH = $(shell test -d $(BLUESPECDIR)/Libraries/FPGA && echo -p +:$(BLUESPECDIR)/Libraries/FPGA/Xilinx:$(BLUESPECDIR)/Libraries/FPGA/Altera:$(BLUESPECDIR)/Libraries/FPGA/Misc) ifneq ($(BSC_LM_LICENSE_FILE),) RUN_BSC_LM_LICENSE_FILE=LM_LICENSE_FILE=$(BSC_LM_LICENSE_FILE) endif RUN_BSC = $(RUN_BSC_LM_LICENSE_FILE) BUILDCACHE_CACHEDIR=$(BUILDCACHE_CACHEDIR) $(BUILDCACHE) bsc $(BSC_QUIET) $(BSVDEFINES) $(BSCFLAGS_COMMON) $(BSCFLAGS_PROJECT) $(BSCFLAGS_EXTRA) -p +:$(BSVPATH) $(EXTRABSVPATH) VFILE=verilog/$(MKTOP).v all: exe bits extratarget extratarget:: # placeholder for variant targets ifeq ($(RUNSOURCE2),) exe: $(EXENAME) else exe: $(EXENAME) $(EXENAME2) endif ubuntu.exe: prepare_bin_target @echo "ubuntu.exe" $(Q)cd jni; $(MAKE) --no-print-directory -f Ubuntu.mk ubuntu.exe @cp -v jni/ubuntu.exe bin @echo "ubuntu.exe done" ubuntu.exe2: prepare_bin_target $(Q)cd jni; $(MAKE) --no-print-directory -f Ubuntu.mk ubuntu.exe2 @cp -v jni/ubuntu.exe2 bin connectal.so: prepare_bin_target ifneq ($(OS),android) $(Q)cd jni; $(MAKE) --no-print-directory -f Ubuntu.mk connectal.so @cp -v jni/connectal.so bin else +ndk-build $(CONNECTAL_NDK_PARAM) @cp -v libs/armeabi/libconnectal.so bin/connectal.so endif $(Q)if [ -f $(BINFILE) ] ; then $(OBJCOPY) --remove-section fpgadata bin/connectal.so; fi $(Q)if [ -f $(BINFILE) ] ; then $(OBJCOPY) --add-section fpgadata=$(BINFILE) bin/connectal.so; fi ifneq ($(BOARD),bluesim) ifneq ($(OS),android) program: fpgajtag bin/mkTop.bin.gz sleep 1 programflash: vivado -mode batch -source $(dir $(FPGAMAKE))/tcl/program_bpi_flash.tcl endif endif ifneq ($(CONNECTAL_NOHARDWARE),1) BITS_DEPENDENCES ?= $(CONNECTAL_BITS_DEPENDENCES) endif #hw/mkTop.bit prepare_bin_target bits: $(BITS_DEPENDENCES) prepare_bin_target ifneq ($(XILINX),) ifeq ($(OS),android) @echo "zipping android" $(CONNECTALDIR)/scripts/reorderbytes.py hw/mkTop.bin bin/mkTop.xdevcfg.bin gzip -f bin/mkTop.xdevcfg.bin else ifneq ($(SIMULATION),) @echo "not zipping xilinx" else ifneq ($(AWSF1),) @echo "not zipping awsf1" else @echo "zipping xilinx" gzip -c hw/mkTop.bin > bin/mkTop.bin.gz endif # AWSF1 endif #xsim endif #android else #!xilinx ifneq ($(ALTERA),) gzip -c $(MKTOP).sof > bin/$(MKTOP).sof.gz endif # endif #!xilinx $(Q)if [ -f bin/$(EXENAME) -a -f "$(BINFILE)" ]; then $(OBJCOPY) --remove-section fpgadata bin/$(EXENAME); fi $(Q)if [ -f bin/$(EXENAME) -a -f "$(BINFILE)" ]; then $(OBJCOPY) --add-section fpgadata=$(BINFILE) bin/$(EXENAME); fi $(Q)if [ -f Impl/TopDown/top-post-route.dcp ]; then cp -f Impl/TopDown/top-post-route.dcp bin; fi $(Q)if [ -f Impl/TopDown/top-post-route-timing-summary.rpt ]; then $(CONNECTALDIR)/scripts/check-timing.py Impl/TopDown/top-post-route-timing-summary.rpt; fi $(Q)if [ -f Impl/TopDown/top-post-route-timing-summary.txt ]; then $(CONNECTALDIR)/scripts/check-timing.py Impl/TopDown/top-post-route-timing-summary.txt; fi android.exe: prepare_bin_target +ndk-build $(CONNECTAL_NDK_PARAM) @cp -fv libs/armeabi/android.exe bin $(Q)if [ -f bin/mkTop.xdevcfg.bin.gz ]; then $(NDK_OBJCOPY) --remove-section fpgadata bin/android.exe; fi $(Q)if [ -f bin/mkTop.xdevcfg.bin.gz ]; then $(NDK_OBJCOPY) --add-section fpgadata=bin/mkTop.xdevcfg.bin.gz bin/android.exe; fi android.debug.exe: prepare_bin_target +ndk-build $(CONNECTAL_NDK_PARAM) -B V=1 NDK_DEBUG=1 @cp -v libs/armeabi/android.exe bin $(Q)if [ -f bin/mkTop.xdevcfg.bin.gz ]; then $(NDK_OBJCOPY) --remove-section fpgadata bin/android.exe; fi $(Q)if [ -f bin/mkTop.xdevcfg.bin.gz ]; then $(NDK_OBJCOPY) --add-section fpgadata=bin/mkTop.xdevcfg.bin.gz bin/android.exe; fi android.exe2: prepare_bin_target +ndk-build $(CONNECTAL_NDK_PARAM) @cp -fv libs/armeabi/android.exe2 bin RUN_SCRIPT?=$(CONNECTAL_RUN_SCRIPT) run: ifeq ($(CONNECTAL_SHARED),1) $(RUN_BSC_LM_LICENSE_FILE) $(GDB) $(RUN_SCRIPT) ./bin/$(EXENAME2) $(RUN_ARGS); retcode=$$?; exit $$retcode else ifeq ($(RUNSOURCE2),) $(RUN_BSC_LM_LICENSE_FILE) $(GDB) $(RUN_SCRIPT) ./bin/$(EXENAME) $(RUN_ARGS); retcode=$$?; exit $$retcode else $(RUN_BSC_LM_LICENSE_FILE) $(GDB2) $(RUN_SCRIPT) ./bin/$(EXENAME2)& bsim2pid=$$!; $(RUN_SCRIPT) $(GDB) ./bin/$(EXENAME) $(RUN_ARGS); retcode=$$?; kill $$bsim2pid; exit $$retcode endif endif # CONNECTAL_SHARED define SIM_C_RULE $1/$(notdir $(basename $3)).o: $3 mkdir -p $1 $(CC) -c $2 -o $1/$(notdir $(basename $3)).o $3 endef define SIM_CXX_RULE $1/$(notdir $(basename $3)).o: $3 mkdir -p $1 $(CXX) -c $2 -o $1/$(notdir $(basename $3)).o $3 endef $(foreach src, $(filter %.c, $(SIM_CXX_LOCAL) $(SIM_CXX_PROJECT)), $(eval $(call SIM_C_RULE, $(DTOP)/lib, $(SIM_CFLAGS), $(src)))) $(foreach src, $(filter %.cpp, $(SIM_CXX_LOCAL) $(SIM_CXX_PROJECT)), $(eval $(call SIM_CXX_RULE, $(DTOP)/lib, $(SIM_CXXFLAGS), $(src)))) SIM_OBJECTS = $(addprefix $(DTOP)/lib/, $(addsuffix .o, $(basename $(notdir $(SIM_CXX_LOCAL) $(SIM_CXX_PROJECT))))) VIVADODIR=$(realpath $(shell dirname $(VIVADO))/..) XSC_CFLAGS= -Wa,-W -fPIC -m64 -I"$(VIVADODIR)/data/xsim/include" -DSYSTEM_VERILOG -DBOARD_xsim -I$(CONNECTALDIR)/cpp -I$(CONNECTALDIR) -Ijni XVLOGDEFINES = $(subst -D,-d,$(BSVDEFINES)) SVLOG = $(addprefix -svlog $(CONNECTALDIR)/verilog/, xsimtop.sv XsimDmaReadWrite.sv XsimLink.sv XsimSink.sv XsimSource.sv) XCIDIRS = $(basename $(XCIFILES)) VLOG_PRJ_FILE = $(wildcard $(addsuffix /xsim/vlog.prj, $(XCIDIRS))) VHDL_PRJ_FILE = $(wildcard $(addsuffix /xsim/vhdl.prj, $(XCIDIRS))) # phony targets to trigger calls to xvlog and xvhdl VLOG_PRJ_BLD = $(addsuffix .bld, $(VLOG_PRJ_FILE)) VHDL_PRJ_BLD = $(addsuffix .bld, $(VHDL_PRJ_FILE)) %/vlog.prj.bld: %/vlog.prj sed -i s/xil_defaultlib/work/ $(*)/vlog.prj xvlog $(XVLOGFLAGS) -prj $(*)/vlog.prj %/vhdl.prj.bld: %/vhdl.prj sed -i s/xil_defaultlib/work/ $(*)/vhdl.prj xvhdl $(XVLOGFLAGS) -prj $(*)/vhdl.prj xsim: verilog $(SIM_OBJECTS) $(VLOG_PRJ_BLD) $(VHDL_PRJ_BLD) xvlog $(XVLOGFLAGS) $(XVLOGDEFINES) $(VERILOG_PATH:%=--sourcelibdir %) --sourcelibext .v verilog/*.v $(VERILOG_FILES) ifneq ($(VHDL_FILES),) xvhdl $(XVHDLFLAGS) $(VHDL_FILES) endif xvlog $(XVLOGDEFINES) --sv $(CONNECTALDIR)/verilog/*.sv ## not needed because these all get passed to xelab because they use DPI ls -l $(SIM_OBJECTS) xsc -v -cc gcc -link $(SIM_OBJECTS) -o xsimtop || echo xsc failed xelab -timescale 1ns/1ps --stats $(XVLOGDEFINES) -cc gcc $(SVLOG) --dpiheader XsimTop.h --debug wave -L unisim -L unifast -L unimacro work.xsimtop -sv_lib xsimtop || echo xelab failed true CVC64 ?= cvc64 CVC_DEFINES = $(addprefix +define+, $(BSVDEFINES_LIST)) CVC_TRACE_ARGS = +printstats +fstvars CVC_ARGS ?= CVC_SOURCES = $(addprefix -v , $(wildcard $(BLUESPECDIR)/Verilog/*.v $(DTOP)/verilog/*.v)) cvcsim: bin/cvcsim bin/cvcsim: $(DTOP)/bin/libconnectal-sim.so verilog bin/cvcsim $(CVC64) $(CVC_DEFINES) $(CVC_ARGS) -y $(CONNECTALDIR)/verilog $(CVC_SOURCES) -sv $(CONNECTALDIR)/verilog/XsimSink.sv $(CONNECTALDIR)/verilog/XsimSource.sv $(CONNECTALDIR)/verilog/XsimDmaReadWrite.sv -sv $(CONNECTALDIR)/verilog/xsimtop.sv -sv_lib $(DTOP)/bin/libconnectal-sim.so -o bin/cvcsim vlsim: $(DTOP)/obj_dir/vlsim VERILATOR_ARGS?= -O3 -CFLAGS "-I$(CONNECTALDIR)/cpp -I$(DTOP)/jni -O $(PROF_FLAGS)" -LDFLAGS "-O $(PROF_FLAGS)" --profile-cfuncs --output-split 20000 VERILATOR_ARGS += $(VERILATOR_PROJECT_ARGS) $(DTOP)/obj_dir/vlsim.mk: $(DTOP)/bin/libconnectal-sim.so verilog rm -fr $(DTOP)/obj_dir verilator -o vlsim --prefix vlsim $(VERILATOR_ARGS) -cc -exe $(DTOP)/verilog/mkXsimTop.v -DMainClockPeriod=4 -DDerivedClockPeriod=4 --top-module mkXsimTop $(VERILOG_PATH:%=-y %) -Wno-fatal $(CONNECTALDIR)/cpp/verilatortop.cpp -LDFLAGS -L$(DTOP)/bin $(DTOP)/obj_dir/vlsim: $(DTOP)/obj_dir/vlsim.mk +$(MAKE) USER_LDLIBS="-lconnectal-sim -lpthread" VM_PARALLEL_BUILDS=1 -C obj_dir -f vlsim.mk cp obj_dir/vlsim bin/vlsim vcssim: bin/simv VCS_DEFINES = $(addprefix +define+, $(BSVDEFINES_LIST)) VCS_ARGS?= -CFLAGS "-I$(CONNECTALDIR)/cpp -I$(CONNECTALDIR) -I$(DTOP)/jni" VCS_ARGS += +define+SVA_ON -assert svaext+enable_diag VCS_ARGS += -debug_acc+all VCS_ARGS += -kdb -fsdb VCS_ARGS += $(VCS_PROJECT_ARGS) bin/simv: $(DTOP)/bin/libconnectal-sim.so verilog vcs -full64 -sverilog $(VCS_DEFINES) $(VCS_ARGS) -o $(DTOP)/bin/simv \ $(CONNECTALDIR)/verilog/xsimtop.sv $(SIM_CXX_LOCAL) \ +libext+.v+.sv $(VERILOG_PATH:%=-y %) MODELSIMDIR=$(realpath $(dir $(MODELSIM))/..) VSIM_CFLAGS= $(CFLAGS_PROJECT) -Wa,-W -fPIC -m64 -I"$(MODELSIMDIR)/include" -DSYSTEM_VERILOG -DBOARD_vsim -I$(CONNECTALDIR)/cpp -I$(CONNECTALDIR) -Ijni VSIM_CXXFLAGS= $(CXXFLAGS_PROJECT) -Wa,-W -fPIC -m64 -I"$(MODELSIMDIR)/include" -DSYSTEM_VERILOG -DBOARD_vsim -I$(CONNECTALDIR)/cpp -I$(CONNECTALDIR) -Ijni $(foreach src, $(filter %.c, $(SIM_CXX_LOCAL) $(SIM_CXX_PROJECT)), $(eval $(call SIM_C_RULE, vsim.dir/xsc, $(VSIM_CFLAGS), $(src)))) $(foreach src, $(filter %.cpp, $(SIM_CXX_LOCAL) $(SIM_CXX_PROJECT)), $(eval $(call SIM_CXX_RULE, vsim.dir/xsc, $(VSIM_CXXFLAGS), $(src)))) VSIM_OBJECTS = $(addprefix vsim.dir/xsc/, $(addsuffix .o, $(basename $(notdir $(SIM_CXX_LOCAL) $(SIM_CXX_PROJECT))))) VSIM_DEFINES = $(subst -D ,+define+,$(BSVDEFINES)) VSIM_SV = $(addprefix -sv $(CONNECTALDIR)/verilog/, xsimtop.sv XsimDmaReadWrite.sv XsimLink.sv XsimSink.sv XsimSource.sv) SV_SEARCH_PATH = $(addprefix -y , $(VERILOG_PATH)) SV_SEARCH_PATH += $(addprefix -y , $(addsuffix /submodules, $(VERILOG_PATH))) SV_SEARCH_PATH += $(addprefix -y , $(addsuffix /submodules/mentor, $(VERILOG_PATH))) VSIM_LIBRARY_FILES += $(addprefix -sv $(QUARTUSDIR)/eda/sim_lib/, altera_lnsim.sv) VSIM_LIBRARY_FILES += $(addprefix -v $(QUARTUSDIR)/eda/sim_lib/, altera_mf.v 220model.v sgate.v altera_primitives.v mentor/stratixv_atoms_ncrypt.v stratixv_atoms.v mentor/stratixv_hssi_atoms_ncrypt.v stratixv_hssi_atoms.v) VSIM_MISC_FILES = $(addprefix -sv , $(MODELSIM_FILES)) vsim: verilog $(VSIM_OBJECTS) rm -rf work vlib work vlog -timescale 1ns/1ps -dpiheader XsimTop.h $(VSIM_DEFINES) $(VSIM_SV) $(VSIM_LIBRARY_FILES) $(VSIM_MISC_FILES) +libext+.sv+.v $(SV_SEARCH_PATH) $(VERILOG_PATH:%=-y %) -sv verilog/*.v $(CXX) $(CXXFLAGS_PROJECT) -O -g -I$(DTOP)/jni -shared -fPIC -g -o xsimtop.so $(VSIM_OBJECTS) obj/%.bvi: verilog/%.v $(CONNECTALDIR)/scripts/extract-bvi-schedule.py -d obj verilog/$(*).v define BSV_BO_RULE $(1): $(2) $(3) $(4) $(Q)mkdir -p $(DTOP)/obj verilog @echo BSV_BO [$(2)] $(Q)MAKEFLAGS="" $(RUN_BSC) $(2) endef define BSV_V_RULE $(2): $(3) $(4) $(5) $(Q)mkdir -p $(DTOP)/obj verilog @echo BSCVERILOG [$(1)] cd generatedbsv; MAKEFLAGS="" $(RUN_BSC) -g $(1) $(3) $(Q)sed -i 's|// On .*|// timestamp removed|' verilog/*.v $(Q)sed -i 's|Prelude_inst_changeSpecialWires|csw|g' verilog/*.v $(Q)sed -i 's| reg.*PROBE[,;]|(* mark_debug="true" *)&|' verilog/*.v $(Q)sed -i 's| wire.*PROBE[,;]|(* mark_debug="true" *)&|' verilog/*.v $(Q)sed -i 's| wire.*PROBE_VALID[,;]|(* mark_debug="true" *)&|' verilog/*.v endef include obj/Makefile obj/mkXsimTop.ba: $(addprefix obj/, $(patsubst %.bsv, %.bo, $(notdir $(TOPBSVFILE)))) $(Q)mkdir -p $(DTOP)/obj @echo BSCSIM [mkXsimTop.ba] $(Q)cd generatedbsv; MAKEFLAGS="" $(RUN_BSC) -g $(MKTOP) $(TOPBSVFILE) $(VFILE): $(addprefix obj/, $(patsubst %.bsv, %.bo, $(notdir $(TOPBSVFILE)))) $(Q)mkdir -p verilog $(DTOP)/obj @echo BSCVERILOG [$(VFILE)] $(Q)cd generatedbsv; MAKEFLAGS="" $(RUN_BSC) -g $(MKTOP) $(TOPBSVFILE) $(Q)sed -i 's|// On .*|// timestamp removed|' verilog/*.v $(Q)sed -i 's|Prelude_inst_changeSpecialWires|csw|g' verilog/*.v $(Q)sed -i 's| reg.*PROBE[,;]|(* mark_debug="true" *)&|' verilog/*.v $(Q)sed -i 's| wire.*PROBE[,;]|(* mark_debug="true" *)&|' verilog/*.v $(Q)sed -i 's| wire.*PROBE_VALID[,;]|(* mark_debug="true" *)&|' verilog/*.v $(Q)sed -i '/assign/{N; s|^\s*assign\s\+CLK_.*_deleteme_unused_clock =.*;|\/\/deleteme CLK ports disconnected from nets|}' verilog/$(MKTOP).v obj/Makefile: $(OBJMAKEFILE_DEP) syntax.timestamp @mkdir -p obj $(CONNECTALDIR)/scripts/bsvdepend.py -o obj/Makefile $(BSVDEFINES) --bsvpath=$(BSVPATH) --bluespecdir=$(BLUESPECDIR) --all $(TOPBSVFILE) $(DTOP)/bin/libconnectal-sim.so: $(SIM_OBJECTS) prepare_bin_target $(Q)mkdir -p $(DTOP)/bin $(CXX) -O -g -I$(DTOP)/jni -shared -fpic $(SIM_CXXFLAGS) -g -o $(DTOP)/bin/libconnectal-sim.so $(SIM_OBJECTS) bsim: prepare_bin_target $(DTOP)/bin/libconnectal-sim.so obj/mkXsimTop.ba $(Q)mkdir -p $(DTOP)/obj verilog @echo BSCBSIM [$(DTOP)] $(Q)cd generatedbsv; MAKEFLAGS="" $(RUN_BSC) -O -L $(DTOP)/bin -l connectal-sim -sim -e $(MKTOP) -o bsim $(DTOP)/obj/*.ba g++ -O -g $(CXXFLAGS_BSIM) -o bin/bsim -Iobj -I$(BLUESPECDIR)/Bluesim obj/*.o $(CONNECTALDIR)/cpp/bluesim_main.cxx -L$(BSIM_LIBRARY_DIR) -lbskernel -lbsprim -lpthread -L bin -lconnectal-sim build/checkpoints/to_aws/mkTop.SH_CL_routed.dcp: verilog CONNECTALDIR=$(CONNECTALDIR) $(CONNECTALDIR)/scripts/aws/build.sh $(AWSFLAGS) syntax.timestamp: $(BSVFILES) @#$syntax.py uses environment variables: V INTERFACES BSVDEFINES_LIST DTOP DUT_NAME $(Q)BSVPATH=$(BSVPATH) $(CONNECTALDIR)/scripts/syntax.py $(BSVFILES) $(Q)touch syntax.timestamp verilog: $(VFILE) syntax.timestamp @echo "verilog" lint: $(VFILE) verilator --error-limit 200 --lint-only -Igeneratedbsv -Igeneratedbsv/source $(VFILE) prepare_bin_target: syntax.timestamp @echo "prepare_bin_target" @mkdir -p bin jni @(git rev-parse HEAD 2> /dev/null || echo not a git repo) > bin/githash @(git diff 2>/dev/null || echo not a git repo) | gzip -c > bin/gitdiff.patch.gz hwclean: rm -fr obj hw vivado*.jou vivado*.log fsm_encoding.os .Xil clean: hwclean rm -fr verilog ================================================ FILE: scripts/adb/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: scripts/adb/README.rst ================================================ python-adb ========== This repository contains a pure-python implementation of the ADB and Fastboot protocols, using libusb1 for USB communications. This is a complete replacement and rearchitecture of the Android project's ADB and fastboot code available at https://github.com/android/platform_system_core/tree/master/adb This code is mainly targeted to users that need to communicate with Android devices in an automated fashion, such as in automated testing. It does not have a daemon between the client and the device, and therefore does not support multiple simultaneous commands to the same device. It does support any number of devices and never communicates with a device that it wasn't intended to, unlike the Android project's ADB. Pros: * Simpler code due to use of libusb1 and Python. * API can be used by other Python code easily. * Errors are propagated with tracebacks, helping debug connectivity issues. Cons: * Technically slower due to Python, mitigated by no daemon. * Only one command per device at a time. * More dependencies than Android's ADB. Dependencies: * libusb1 (1.0.16+) * python-libusb1 (1.2.0+) * python-progressbar (for fastboot_debug, 2.3+) * python-m2crypto (0.21.1+) ================================================ FILE: scripts/adb/__init__.py ================================================ ================================================ FILE: scripts/adb/adb_commands.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A libusb1-based ADB reimplementation. ADB was giving us trouble with its client/server architecture, which is great for users and developers, but not so great for reliable scripting. This will allow us to more easily catch errors as Python exceptions instead of checking random exit codes, and all the other great benefits from not going through subprocess and a network socket. All timeouts are in milliseconds. """ try: import cStringIO except ImportError: import io as cStringIO # Python 3 compatibility import os import socket from . import adb_protocol from . import common from . import filesync_protocol try: basestring except NameError: basestring = str # Python 3 compatibility try: import libusb1 # From adb.h CLASS = 0xFF SUBCLASS = 0x42 PROTOCOL = 0x01 # pylint: disable=invalid-name DeviceIsAvailable = common.InterfaceMatcher(CLASS, SUBCLASS, PROTOCOL) except: # no libusb1 support pass try: from M2Crypto import RSA class M2CryptoSigner(adb_protocol.AuthSigner): """AuthSigner using M2Crypto.""" def __init__(self, rsa_key_path): with open(rsa_key_path + '.pub') as rsa_pub_file: self.public_key = rsa_pub_file.read() self.rsa_key = RSA.load_key(rsa_key_path) def Sign(self, data): return self.rsa_key.sign(data, 'sha1') def GetPublicKey(self): return self.public_key except: #print 'Install M2Crypto in order to use adb debug' pass class AdbCommands(object): """Exposes adb-like methods for use. Some methods are more-pythonic and/or have more options. """ protocol_handler = adb_protocol.AdbMessage filesync_handler = filesync_protocol.FilesyncProtocol @classmethod def ConnectDevice( cls, port_path=None, serial=None, default_timeout_ms=None, **kwargs): """Convenience function to get an adb device from usb path or serial. Args: port_path: The filename of usb port to use. serial: The serial number of the device to use. default_timeout_ms: The default timeout in milliseconds to use. If serial specifies a TCP address:port, then a TCP connection is used instead of a USB connection. """ if serial and ':' in serial: handle = common.TcpHandle(serial) else: handle = common.UsbHandle.FindAndOpen( DeviceIsAvailable, port_path=port_path, serial=serial, timeout_ms=default_timeout_ms) return cls.Connect(handle, **kwargs) def __init__(self, handle, device_state): self._handle = handle self._device_state = device_state @property def usb_handle(self): return self._handle def Close(self): self._handle.Close() @classmethod def Connect(cls, usb, banner=None, **kwargs): """Connect to the device. Args: usb: UsbHandle or TcpHandle instance to use. banner: See protocol_handler.Connect. **kwargs: See protocol_handler.Connect for kwargs. Includes rsa_keys, and auth_timeout_ms. Returns: An instance of this class if the device connected successfully. """ if not banner: banner = socket.gethostname() device_state = cls.protocol_handler.Connect(usb, banner=banner, **kwargs) # Remove banner and colons after device state (state::banner) device_state = device_state.split(':')[0] return cls(usb, device_state) @classmethod def Devices(cls): """Get a generator of UsbHandle for devices available.""" return common.UsbHandle.FindDevices(DeviceIsAvailable) def GetState(self): return self._device_state def Install(self, apk_path, destination_dir=None, timeout_ms=None): """Install apk to device. Doesn't support verifier file, instead allows destination directory to be overridden. Arguments: apk_path: Local path to apk to install. destination_dir: Optional destination directory. Use /system/app/ for persistent applications. timeout_ms: Expected timeout for pushing and installing. Returns: The pm install output. """ if not destination_dir: destination_dir = '/data/local/tmp/' basename = os.path.basename(apk_path) destination_path = destination_dir + basename self.Push(apk_path, destination_path, timeout_ms=timeout_ms) return self.Shell('pm install -r "%s"' % destination_path, timeout_ms=timeout_ms) def Push(self, source_file, device_filename, mtime='0', timeout_ms=None): """Push source_file to file on device. Arguments: source_file: Either a filename or file-like object to push to the device. device_filename: The filename on the device to write to. mtime: Optional, modification time to set on the file. timeout_ms: Expected timeout for any part of the push. """ connection = self.protocol_handler.Open( self._handle, destination='sync:', timeout_ms=timeout_ms) if isinstance(source_file, basestring): source_file = open(source_file) self.filesync_handler.Push(connection, source_file, device_filename, mtime=int(mtime)) connection.Close() def Pull(self, device_filename, dest_file=None, timeout_ms=None): """Pull file from device. Arguments: device_filename: The filename on the device to pull. dest_file: If set, a filename or writable file-like object. timeout_ms: Expected timeout for any part of the pull. Returns: The file data if dest_file is not set. """ if isinstance(dest_file, basestring): dest_file = open(dest_file, 'w') elif not dest_file: dest_file = cStringIO.StringIO() connection = self.protocol_handler.Open( self._handle, destination='sync:', timeout_ms=timeout_ms) self.filesync_handler.Pull(connection, device_filename, dest_file) connection.Close() try: # An empty call to cStringIO.StringIO returns an instance of # cStringIO.OutputType on Python 2. StringIOType = cStringIO.OutputType except AttributeError: # On Python 3, this object just an instance of StringIO. StringIOType = cStringIO.StringIO if isinstance(dest_file, StringIOType): return dest_file.getvalue() def Stat(self, device_filename): """Get a file's stat() information.""" connection = self.protocol_handler.Open(self._handle, destination='sync:') mode, size, mtime = self.filesync_handler.Stat( connection, device_filename) connection.Close() return mode, size, mtime def List(self, device_path): """Return a directory listing of the given path.""" connection = self.protocol_handler.Open(self._handle, destination='sync:') listing = self.filesync_handler.List(connection, device_path) connection.Close() return listing def Reboot(self, destination=''): """Reboot device, specify 'bootloader' for fastboot.""" self.protocol_handler.Open(self._handle, 'reboot:%s' % destination) def RebootBootloader(self): """Reboot device into fastboot.""" self.Reboot('bootloader') def Remount(self): """Remount / as read-write.""" return self.protocol_handler.Command(self._handle, service='remount') def Root(self): """Restart adbd as root on device.""" return self.protocol_handler.Command(self._handle, service='root') def Shell(self, command, timeout_ms=None): """Run command on the device, returning the output.""" return self.protocol_handler.Command( self._handle, service='shell', command=command, timeout_ms=timeout_ms) def StreamingShell(self, command, timeout_ms=None): """Run command on the device, returning the output. Args: command: the command to run on the target. timeout_ms: Maximum time to allow the command to run. Yields: The responses from the shell command. """ return self.protocol_handler.StreamingCommand( self._handle, service='shell', command=command, timeout_ms=timeout_ms) def Logcat(self, options, timeout_ms=None): """Run 'shell logcat' and stream the output to stdout.""" return self.protocol_handler.StreamingCommand( self._handle, service='shell', command='logcat %s' % options, timeout_ms=timeout_ms) ================================================ FILE: scripts/adb/adb_debug.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ADB debugging binary. Call it similar to how you call android's adb. Takes either --serial or --port_path to connect to a device. """ from __future__ import print_function import os import sys import gflags from . import adb_commands from . import common_cli gflags.ADOPT_module_key_flags(common_cli) gflags.DEFINE_multistring('rsa_key_path', '~/.android/adbkey', 'RSA key(s) to use') gflags.DEFINE_integer('auth_timeout_s', 60, 'Seconds to wait for the dialog to be accepted when using ' 'authenticated ADB.') FLAGS = gflags.FLAGS def GetRSAKwargs(): if FLAGS.rsa_key_path: try: return { 'rsa_keys': [adb_commands.M2CryptoSigner(os.path.expanduser(path)) for path in FLAGS.rsa_key_path], 'auth_timeout_ms': int(FLAGS.auth_timeout_s * 1000.0), } except: print('Install M2Crypto in order to use adb debug') return {} def main(argv): common_cli.StartCli( argv, adb_commands.AdbCommands.ConnectDevice, list_callback=adb_commands.AdbCommands.Devices, **GetRSAKwargs()) if __name__ == '__main__': main(FLAGS(sys.argv)) ================================================ FILE: scripts/adb/adb_protocol.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ADB protocol implementation. Implements the ADB protocol as seen in android's adb/adbd binaries, but only the host side. """ import struct import time from . import usb_exceptions # Maximum amount of data in an ADB packet. MAX_ADB_DATA = 4096 # ADB protocol version. VERSION = 0x01000000 # AUTH constants for arg0. AUTH_TOKEN = 1 AUTH_SIGNATURE = 2 AUTH_RSAPUBLICKEY = 3 class InvalidCommandError(Exception): """Got an invalid command over USB.""" def __init__(self, message, response_header, response_data): if response_header == 'FAIL': message = 'Command failed, device said so. (%s)' % message super(InvalidCommandError, self).__init__( message, response_header, response_data) class InvalidResponseError(Exception): """Got an invalid response to our command.""" class InvalidChecksumError(Exception): """Checksum of data didn't match expected checksum.""" class InterleavedDataError(Exception): """We only support command sent serially.""" def MakeWireIDs(ids): id_to_wire = { cmd_id: sum(ord(c) << (i * 8) for i, c in enumerate(cmd_id)) for cmd_id in ids } wire_to_id = {wire: cmd_id for cmd_id, wire in id_to_wire.items()} return id_to_wire, wire_to_id class AuthSigner(object): """Signer for use with authenticated ADB, introduced in 4.4.x/KitKat.""" def Sign(self, data): """Signs given data using a private key.""" raise NotImplementedError() def GetPublicKey(self): """Returns the public key in PEM format without headers or newlines.""" raise NotImplementedError() class _AdbConnection(object): """ADB Connection.""" def __init__(self, usb, local_id, remote_id, timeout_ms): self.usb = usb self.local_id = local_id self.remote_id = remote_id self.timeout_ms = timeout_ms def _Send(self, command, arg0, arg1, data=''): message = AdbMessage(command, arg0, arg1, data) message.Send(self.usb, self.timeout_ms) def Write(self, data): """Write a packet and expect an Ack.""" self._Send('WRTE', arg0=self.local_id, arg1=self.remote_id, data=data) # Expect an ack in response. cmd, okay_data = self.ReadUntil('OKAY') if cmd != 'OKAY': if cmd == 'FAIL': raise usb_exceptions.AdbCommandFailureException( 'Command failed.', okay_data) raise InvalidCommandError( 'Expected an OKAY in response to a WRITE, got %s (%s)', cmd, okay_data) return len(data) def Okay(self): self._Send('OKAY', arg0=self.local_id, arg1=self.remote_id) def ReadUntil(self, *expected_cmds): """Read a packet, Ack any write packets.""" cmd, remote_id, local_id, data = AdbMessage.Read( self.usb, expected_cmds, self.timeout_ms) if local_id != 0 and self.local_id != local_id: raise InterleavedDataError("We don't support multiple streams...") if remote_id != 0 and self.remote_id != remote_id: raise InvalidResponseError( 'Incorrect remote id, expected %s got %s' % ( self.remote_id, remote_id)) # Ack write packets. if cmd == 'WRTE': self.Okay() return cmd, data def ReadUntilClose(self): """Yield packets until a Close packet is received.""" while True: cmd, data = self.ReadUntil('CLSE', 'WRTE') if cmd == 'CLSE': self._Send('CLSE', arg0=self.local_id, arg1=self.remote_id) break if cmd != 'WRTE': if cmd == 'FAIL': raise usb_exceptions.AdbCommandFailureException( 'Command failed.', data) raise InvalidCommandError('Expected a WRITE or a CLOSE, got %s (%s)', cmd, data) yield data def Close(self): self._Send('CLSE', arg0=self.local_id, arg1=self.remote_id) cmd, data = self.ReadUntil('CLSE') if cmd != 'CLSE': if cmd == 'FAIL': raise usb_exceptions.AdbCommandFailureException('Command failed.', data) raise InvalidCommandError('Expected a CLSE response, got %s (%s)', cmd, data) class AdbMessage(object): """ADB Protocol and message class. Protocol Notes local_id/remote_id: Turns out the documentation is host/device ambidextrous, so local_id is the id for 'the sender' and remote_id is for 'the recipient'. So since we're only on the host, we'll re-document with host_id and device_id: OPEN(host_id, 0, 'shell:XXX') READY/OKAY(device_id, host_id, '') WRITE(0, host_id, 'data') CLOSE(device_id, host_id, '') """ ids = ['SYNC', 'CNXN', 'AUTH', 'OPEN', 'OKAY', 'CLSE', 'WRTE'] commands, constants = MakeWireIDs(ids) # An ADB message is 6 words in little-endian. format = '<6I' connections = 0 def __init__(self, command=None, arg0=None, arg1=None, data=''): self.command = self.commands[command] self.magic = self.command ^ 0xFFFFFFFF self.arg0 = arg0 self.arg1 = arg1 self.data = data @property def checksum(self): return self.CalculateChecksum(self.data) @staticmethod def CalculateChecksum(data): # The checksum is just a sum of all the bytes. I swear. return sum(map(ord, data)) & 0xFFFFFFFF def Pack(self): """Returns this message in an over-the-wire format.""" return struct.pack(self.format, self.command, self.arg0, self.arg1, len(self.data), self.checksum, self.magic) @classmethod def Unpack(cls, message): try: cmd, arg0, arg1, data_length, data_checksum, unused_magic = struct.unpack( cls.format, message) except struct.error as e: raise ValueError('Unable to unpack ADB command.', cls.format, message, e) return cmd, arg0, arg1, data_length, data_checksum def Send(self, usb, timeout_ms=None): """Send this message over USB.""" usb.BulkWrite(self.Pack(), timeout_ms) usb.BulkWrite(self.data, timeout_ms) @classmethod def Read(cls, usb, expected_cmds, timeout_ms=None, total_timeout_ms=None): """Receive a response from the device.""" total_timeout_ms = usb.Timeout(total_timeout_ms) start = time.time() while True: msg = usb.BulkRead(24, timeout_ms) cmd, arg0, arg1, data_length, data_checksum = cls.Unpack(msg) command = cls.constants.get(cmd) if not command: raise InvalidCommandError( 'Unknown command: %x' % cmd, cmd, (arg0, arg1)) if command in expected_cmds: break if time.time() - start > total_timeout_ms: raise InvalidCommandError( 'Never got one of the expected responses (%s)' % expected_cmds, cmd, (timeout_ms, total_timeout_ms)) if data_length > 0: data = '' while data_length > 0: temp = usb.BulkRead(data_length, timeout_ms) data += temp data_length -= len(temp) actual_checksum = cls.CalculateChecksum(data) if actual_checksum != data_checksum: raise InvalidChecksumError( 'Received checksum %s != %s', (actual_checksum, data_checksum)) else: data = '' return command, arg0, arg1, data @classmethod def Connect(cls, usb, banner='notadb', rsa_keys=None, auth_timeout_ms=100): """Establish a new connection to the device. Args: usb: A USBHandle with BulkRead and BulkWrite methods. banner: A string to send as a host identifier. rsa_keys: List of AuthSigner subclass instances to be used for authentication. The device can either accept one of these via the Sign method, or we will send the result of GetPublicKey from the first one if the device doesn't accept any of them. auth_timeout_ms: Timeout to wait for when sending a new public key. This is only relevant when we send a new public key. The device shows a dialog and this timeout is how long to wait for that dialog. If used in automation, this should be low to catch such a case as a failure quickly; while in interactive settings it should be high to allow users to accept the dialog. We default to automation here, so it's low by default. Returns: The device's reported banner. Always starts with the state (device, recovery, or sideload), sometimes includes information after a : with various product information. Raises: usb_exceptions.DeviceAuthError: When the device expects authentication, but we weren't given any valid keys. InvalidResponseError: When the device does authentication in an unexpected way. """ msg = cls( command='CNXN', arg0=VERSION, arg1=MAX_ADB_DATA, data='host::%s\0' % banner) msg.Send(usb) cmd, arg0, arg1, banner = cls.Read(usb, ['CNXN', 'AUTH']) if cmd == 'AUTH': if not rsa_keys: raise usb_exceptions.DeviceAuthError( 'Device authentication required, no keys available.') # Loop through our keys, signing the last 'banner' or token. for rsa_key in rsa_keys: if arg0 != AUTH_TOKEN: raise InvalidResponseError( 'Unknown AUTH response: %s %s %s' % (arg0, arg1, banner)) signed_token = rsa_key.Sign(banner) msg = cls( command='AUTH', arg0=AUTH_SIGNATURE, arg1=0, data=signed_token) msg.Send(usb) cmd, arg0, unused_arg1, banner = cls.Read(usb, ['CNXN', 'AUTH']) if cmd == 'CNXN': return banner # None of the keys worked, so send a public key. msg = cls( command='AUTH', arg0=AUTH_RSAPUBLICKEY, arg1=0, data=rsa_keys[0].GetPublicKey() + '\0') msg.Send(usb) try: cmd, arg0, unused_arg1, banner = cls.Read( usb, ['CNXN'], timeout_ms=auth_timeout_ms) except usb_exceptions.BulkReadFailedError as e: if e.usb_error.value == -7: # Timeout. raise usb_exceptions.DeviceAuthError( 'Accept auth key on device, then retry.') raise # This didn't time-out, so we got a CNXN response. return banner return banner @classmethod def Open(cls, usb, destination, timeout_ms=None): """Opens a new connection to the device via an OPEN message. Not the same as the posix 'open' or any other google3 Open methods. Args: usb: USB device handle with BulkRead and BulkWrite methods. destination: The service:command string. timeout_ms: Timeout in milliseconds for USB packets. Raises: InvalidResponseError: Wrong local_id sent to us. InvalidCommandError: Didn't get a ready response. Returns: The local connection id. """ local_id = 1 msg = cls( command='OPEN', arg0=local_id, arg1=0, data=destination + '\0') msg.Send(usb, timeout_ms) cmd, remote_id, their_local_id, _ = cls.Read(usb, ['CLSE', 'OKAY'], timeout_ms=timeout_ms) if local_id != their_local_id: raise InvalidResponseError( 'Expected the local_id to be %s, got %s' % (local_id, their_local_id)) if cmd == 'CLSE': # Device doesn't support this service. return None if cmd != 'OKAY': raise InvalidCommandError('Expected a ready response, got %s' % cmd, cmd, (remote_id, their_local_id)) return _AdbConnection(usb, local_id, remote_id, timeout_ms) @classmethod def Command(cls, usb, service, command='', timeout_ms=None): """One complete set of USB packets for a single command. Sends service:command in a new connection, reading the data for the response. All the data is held in memory, large responses will be slow and can fill up memory. Args: usb: USB device handle with BulkRead and BulkWrite methods. service: The service on the device to talk to. command: The command to send to the service. timeout_ms: Timeout for USB packets, in milliseconds. Raises: InterleavedDataError: Multiple streams running over usb. InvalidCommandError: Got an unexpected response command. Returns: The response from the service. """ return ''.join(cls.StreamingCommand(usb, service, command, timeout_ms)) @classmethod def StreamingCommand(cls, usb, service, command='', timeout_ms=None): """One complete set of USB packets for a single command. Sends service:command in a new connection, reading the data for the response. All the data is held in memory, large responses will be slow and can fill up memory. Args: usb: USB device handle with BulkRead and BulkWrite methods. service: The service on the device to talk to. command: The command to send to the service. timeout_ms: Timeout for USB packets, in milliseconds. Raises: InterleavedDataError: Multiple streams running over usb. InvalidCommandError: Got an unexpected response command. Yields: The responses from the service. """ connection = cls.Open(usb, destination='%s:%s' % (service, command), timeout_ms=timeout_ms) for data in connection.ReadUntilClose(): yield data ================================================ FILE: scripts/adb/adb_test.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for adb.""" try: import cStringIO except ImportError: import io as cStringIO # Python 3 compatibility import struct import unittest from . import adb_commands from . import adb_protocol from . import common_stub BANNER = 'blazetest' LOCAL_ID = 1 REMOTE_ID = 2 class BaseAdbTest(unittest.TestCase): @classmethod def _ExpectWrite(cls, usb, command, arg0, arg1, data): usb.ExpectWrite(cls._MakeHeader(command, arg0, arg1, data)) usb.ExpectWrite(data) if command == 'WRTE': cls._ExpectRead(usb, 'OKAY', 0, 0) @classmethod def _ExpectRead(cls, usb, command, arg0, arg1, data=''): usb.ExpectRead(cls._MakeHeader(command, arg0, arg1, data)) if data: usb.ExpectRead(data) if command == 'WRTE': cls._ExpectWrite(usb, 'OKAY', LOCAL_ID, REMOTE_ID, '') @classmethod def _ConvertCommand(cls, command): return sum(ord(c) << (i * 8) for i, c in enumerate(command)) @classmethod def _MakeHeader(cls, command, arg0, arg1, data): command = cls._ConvertCommand(command) magic = command ^ 0xFFFFFFFF checksum = adb_protocol.AdbMessage.CalculateChecksum(data) return struct.pack('<6I', command, arg0, arg1, len(data), checksum, magic) @classmethod def _ExpectConnection(cls, usb): cls._ExpectWrite(usb, 'CNXN', 0x01000000, 4096, 'host::%s\0' % BANNER) cls._ExpectRead(usb, 'CNXN', 0, 0, 'device::\0') @classmethod def _ExpectOpen(cls, usb, service): cls._ExpectWrite(usb, 'OPEN', LOCAL_ID, 0, service) cls._ExpectRead(usb, 'OKAY', REMOTE_ID, LOCAL_ID) @classmethod def _ExpectClose(cls, usb): cls._ExpectRead(usb, 'CLSE', REMOTE_ID, 0) cls._ExpectWrite(usb, 'CLSE', LOCAL_ID, REMOTE_ID, '') @classmethod def _Connect(cls, usb): return adb_commands.AdbCommands.Connect(usb, BANNER) class AdbTest(BaseAdbTest): @classmethod def _ExpectCommand(cls, service, command, *responses): usb = common_stub.StubUsb() cls._ExpectConnection(usb) cls._ExpectOpen(usb, '%s:%s\0' % (service, command)) for response in responses: cls._ExpectRead(usb, 'WRTE', REMOTE_ID, 0, response) cls._ExpectClose(usb) return usb def testConnect(self): usb = common_stub.StubUsb() self._ExpectConnection(usb) adb_commands.AdbCommands.Connect(usb, BANNER) def testSmallResponseShell(self): command = 'keepin it real' response = 'word.' usb = self._ExpectCommand('shell', command, response) adb_commands = self._Connect(usb) self.assertEqual(response, adb_commands.Shell(command)) def testBigResponseShell(self): command = 'keepin it real big' # The data doesn't have to be big, the point is that it just concatenates # the data from different WRTEs together. responses = ['other stuff, ', 'and some words.'] usb = self._ExpectCommand('shell', command, *responses) adb_commands = self._Connect(usb) self.assertEqual(''.join(responses), adb_commands.Shell(command)) def testReboot(self): usb = self._ExpectCommand('reboot', '', '') adb_commands = self._Connect(usb) adb_commands.Reboot() def testRebootBootloader(self): usb = self._ExpectCommand('reboot', 'bootloader', '') adb_commands = self._Connect(usb) adb_commands.RebootBootloader() def testRemount(self): usb = self._ExpectCommand('remount', '', '') adb_commands = self._Connect(usb) adb_commands.Remount() def testRoot(self): usb = self._ExpectCommand('root', '', '') adb_commands = self._Connect(usb) adb_commands.Root() class FilesyncAdbTest(BaseAdbTest): @classmethod def _MakeSyncHeader(cls, command, *int_parts): command = cls._ConvertCommand(command) return struct.pack('<%dI' % (len(int_parts) + 1), command, *int_parts) @classmethod def _MakeWriteSyncPacket(cls, command, data='', size=None): return cls._MakeSyncHeader(command, size or len(data)) + data @classmethod def _ExpectSyncCommand(cls, write_commands, read_commands): usb = common_stub.StubUsb() cls._ExpectConnection(usb) cls._ExpectOpen(usb, 'sync:\0') while write_commands or read_commands: if write_commands: command = write_commands.pop(0) cls._ExpectWrite(usb, 'WRTE', LOCAL_ID, REMOTE_ID, command) if read_commands: command = read_commands.pop(0) cls._ExpectRead(usb, 'WRTE', REMOTE_ID, LOCAL_ID, command) cls._ExpectClose(usb) return usb def testPush(self): filedata = 'alo there, govnah' mtime = 100 send = [ self._MakeWriteSyncPacket('SEND', '/data,33272'), self._MakeWriteSyncPacket('DATA', filedata), self._MakeWriteSyncPacket('DONE', size=mtime), ] data = 'OKAY\0\0\0\0' usb = self._ExpectSyncCommand([''.join(send)], [data]) adb_commands = self._Connect(usb) adb_commands.Push(cStringIO.StringIO(filedata), '/data', mtime=mtime) def testPull(self): filedata = "g'ddayta, govnah" recv = self._MakeWriteSyncPacket('RECV', '/data') data = [ self._MakeWriteSyncPacket('DATA', filedata), self._MakeWriteSyncPacket('DONE'), ] usb = self._ExpectSyncCommand([recv], [''.join(data)]) adb_commands = self._Connect(usb) self.assertEqual(filedata, adb_commands.Pull('/data')) if __name__ == '__main__': unittest.main() ================================================ FILE: scripts/adb/common.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Common code for ADB and Fastboot. Common usb browsing, and usb communication. """ import logging import socket import threading import weakref try: basestring except NameError: basestring = str # Python 3 compatibility try: import libusb1 import usb1 from . import usb_exceptions DEFAULT_TIMEOUT_MS = 1000 _LOG = logging.getLogger('android_usb') def GetInterface(setting): """Get the class, subclass, and protocol for the given USB setting.""" return (setting.getClass(), setting.getSubClass(), setting.getProtocol()) def InterfaceMatcher(clazz, subclass, protocol): """Returns a matcher that returns the setting with the given interface.""" interface = (clazz, subclass, protocol) def Matcher(device): for setting in device.iterSettings(): if GetInterface(setting) == interface: return setting return Matcher class UsbHandle(object): """USB communication object. Not thread-safe. Handles reading and writing over USB with the proper endpoints, exceptions, and interface claiming. Important methods: FlushBuffers() BulkRead(int length) BulkWrite(bytes data) """ _HANDLE_CACHE = weakref.WeakValueDictionary() _HANDLE_CACHE_LOCK = threading.Lock() def __init__(self, device, setting, usb_info=None, timeout_ms=None): """Initialize USB Handle. Arguments: device: libusb_device to connect to. setting: libusb setting with the correct endpoints to communicate with. usb_info: String describing the usb path/serial/device, for debugging. timeout_ms: Timeout in milliseconds for all I/O. """ self._setting = setting self._device = device self._handle = None self._usb_info = usb_info or '' self._timeout_ms = timeout_ms or DEFAULT_TIMEOUT_MS @property def usb_info(self): try: sn = self.serial_number except libusb1.USBError: sn = '' if sn and sn != self._usb_info: return '%s %s' % (self._usb_info, sn) return self._usb_info def Open(self): """Opens the USB device for this setting, and claims the interface.""" # Make sure we close any previous handle open to this usb device. port_path = tuple(self.port_path) with self._HANDLE_CACHE_LOCK: old_handle = self._HANDLE_CACHE.get(port_path) if old_handle is not None: old_handle.Close() self._read_endpoint = None self._write_endpoint = None for endpoint in self._setting.iterEndpoints(): address = endpoint.getAddress() if address & libusb1.USB_ENDPOINT_DIR_MASK: self._read_endpoint = address self._max_read_packet_len = endpoint.getMaxPacketSize() else: self._write_endpoint = address assert self._read_endpoint is not None assert self._write_endpoint is not None handle = self._device.open() iface_number = self._setting.getNumber() try: if handle.kernelDriverActive(iface_number): handle.detachKernelDriver(iface_number) except libusb1.USBError as e: if e.value == libusb1.LIBUSB_ERROR_NOT_FOUND: _LOG.warning('Kernel driver not found for interface: %s.', iface_number) else: raise handle.claimInterface(iface_number) self._handle = handle self._interface_number = iface_number with self._HANDLE_CACHE_LOCK: self._HANDLE_CACHE[port_path] = self # When this object is deleted, make sure it's closed. weakref.ref(self, self.Close) @property def serial_number(self): return self._device.getSerialNumber() @property def port_path(self): return [self._device.getBusNumber()] + self._device.getPortNumberList() def Close(self): if self._handle is None: return try: self._handle.releaseInterface(self._interface_number) self._handle.close() except libusb1.USBError: _LOG.info('USBError while closing handle %s: ', self.usb_info, exc_info=True) finally: self._handle = None def Timeout(self, timeout_ms): return timeout_ms if timeout_ms is not None else self._timeout_ms def FlushBuffers(self): while True: try: self.BulkRead(self._max_read_packet_len, timeout_ms=10) except usb_exceptions.ReadFailedError as e: if e.usb_error.value == libusb1.LIBUSB_ERROR_TIMEOUT: break raise def BulkWrite(self, data, timeout_ms=None): if self._handle is None: raise usb_exceptions.WriteFailedError( 'This handle has been closed, probably due to another being opened.', None) try: return self._handle.bulkWrite( self._write_endpoint, data, timeout=self.Timeout(timeout_ms)) except libusb1.USBError as e: raise usb_exceptions.WriteFailedError( 'Could not send data to %s (timeout %sms)' % ( self.usb_info, self.Timeout(timeout_ms)), e) def BulkRead(self, length, timeout_ms=None): if self._handle is None: raise usb_exceptions.ReadFailedError( 'This handle has been closed, probably due to another being opened.', None) try: return self._handle.bulkRead( self._read_endpoint, length, timeout=self.Timeout(timeout_ms)) except libusb1.USBError as e: raise usb_exceptions.ReadFailedError( 'Could not receive data from %s (timeout %sms)' % ( self.usb_info, self.Timeout(timeout_ms)), e) def PortPathMatcher(cls, port_path): """Returns a device matcher for the given port path.""" if isinstance(port_path, basestring): # Convert from sysfs path to port_path. port_path = [int(part) for part in SYSFS_PORT_SPLIT_RE.split(port_path)] return lambda device: device.port_path == port_path @classmethod def SerialMatcher(cls, serial): """Returns a device matcher for the given serial.""" return lambda device: device.serial_number == serial @classmethod def FindAndOpen(cls, setting_matcher, port_path=None, serial=None, timeout_ms=None): dev = cls.Find( setting_matcher, port_path=port_path, serial=serial, timeout_ms=timeout_ms) dev.Open() dev.FlushBuffers() return dev @classmethod def Find(cls, setting_matcher, port_path=None, serial=None, timeout_ms=None): """Gets the first device that matches according to the keyword args.""" if port_path: device_matcher = cls.PortPathMatcher(port_path) usb_info = port_path elif serial: device_matcher = cls.SerialMatcher(serial) usb_info = serial else: device_matcher = None usb_info = 'first' return cls.FindFirst(setting_matcher, device_matcher, usb_info=usb_info, timeout_ms=timeout_ms) @classmethod def FindFirst(cls, setting_matcher, device_matcher=None, **kwargs): """Find and return the first matching device. Args: setting_matcher: See cls.FindDevices. device_matcher: See cls.FindDevices. **kwargs: See cls.FindDevices. Returns: An instance of UsbHandle. Raises: DeviceNotFoundError: Raised if the device is not available. """ try: return next(cls.FindDevices( setting_matcher, device_matcher=device_matcher, **kwargs)) except StopIteration: raise usb_exceptions.DeviceNotFoundError( 'No device available, or it is in the wrong configuration.') @classmethod def FindDevices(cls, setting_matcher, device_matcher=None, usb_info='', timeout_ms=None): """Find and yield the devices that match. Args: setting_matcher: Function that returns the setting to use given a usb1.USBDevice, or None if the device doesn't have a valid setting. device_matcher: Function that returns True if the given UsbHandle is valid. None to match any device. usb_info: Info string describing device(s). timeout_ms: Default timeout of commands in milliseconds. Yields: UsbHandle instances """ ctx = usb1.USBContext() for device in ctx.getDeviceList(skip_on_error=True): setting = setting_matcher(device) if setting is None: continue handle = cls(device, setting, usb_info=usb_info, timeout_ms=timeout_ms) if device_matcher is None or device_matcher(handle): yield handle except: pass class TcpHandle(object): """TCP connection object. Provides same interface as UsbHandle but ignores timeout.""" def __init__(self, serial): """Initialize the TCP Handle. Arguments: serial: Android device serial of the form host or host:port. Host may be an IP address or a host name. """ if ':' in serial: (host, port) = serial.split(':') else: host = serial port = 5555 self._connection = socket.create_connection((host, port)) def BulkWrite(self, data, timeout=None): return self._connection.sendall(data) def BulkRead(self, numbytes, timeout=None): return self._connection.recv(numbytes) def Timeout(self, timeout_ms): return timeout_ms def Close(self): return self._connection.close() ================================================ FILE: scripts/adb/common_cli.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Common code for ADB and Fastboot CLI. Usage introspects the given class for methods, args, and docs to show the user. StartCli handles connecting to a device, calling the expected method, and outputting the results. """ from __future__ import print_function try: import cStringIO except ImportError: import io as cStringIO # Python 3 compatibility import inspect import re import sys import types import gflags from . import usb_exceptions gflags.DEFINE_integer('timeout_ms', 10000, 'Timeout in milliseconds.') gflags.DEFINE_list('port_path', [], 'USB port path integers (eg 1,2 or 2,1,1)') gflags.DEFINE_string('serial', None, 'Device serial to look for (host:port or USB serial)', short_name='s') gflags.DEFINE_bool('output_port_path', False, 'Affects the devices command only, outputs the port_path ' 'alongside the serial if true.') FLAGS = gflags.FLAGS _BLACKLIST = { 'Connect', 'Close', 'ConnectDevice', 'DeviceIsAvailable', } def Uncamelcase(name): parts = re.split(r'([A-Z][a-z]+)', name)[1:-1:2] return ('-'.join(parts)).lower() def Camelcase(name): return name.replace('-', ' ').title().replace(' ', '') def Usage(adb_dev): methods = inspect.getmembers(adb_dev, inspect.ismethod) print('Methods:') for name, method in methods: if name.startswith('_'): continue if not method.__doc__: continue if name in _BLACKLIST: continue argspec = inspect.getargspec(method) args = argspec.args[1:] or '' # Surround default'd arguments with [] defaults = argspec.defaults or [] if args: args = (args[:-len(defaults)] + ['[%s]' % arg for arg in args[-len(defaults):]]) args = ' ' + ' '.join(args) print(' %s%s:' % (Uncamelcase(name), args)) print(' %s' % method.__doc__) def StartCli(argv, device_callback, kwarg_callback=None, list_callback=None, **device_kwargs): """Starts a common CLI interface for this usb path and protocol.""" argv = argv[1:] if len(argv) == 1 and argv[0] == 'devices' and list_callback is not None: # To mimic 'adb devices' output like: # ------------------------------ # List of devices attached # 015DB7591102001A device # Or with --output_port_path: # 015DB7591102001A device 1,2 # ------------------------------ for device in list_callback(): if FLAGS.output_port_path: print('%s\tdevice\t%s' % ( device.serial_number, ','.join(str(port) for port in device.port_path))) else: print('%s\tdevice' % device.serial_number) return port_path = [int(part) for part in FLAGS.port_path] serial = FLAGS.serial device_kwargs.setdefault('default_timeout_ms', FLAGS.timeout_ms) try: dev = device_callback( port_path=port_path, serial=serial, **device_kwargs) except usb_exceptions.DeviceNotFoundError as e: print('No device found: %s' % e, file=sys.stderr) return except usb_exceptions.CommonUsbError as e: print('Could not connect to device: %s' % e, file=sys.stderr) raise if not argv: Usage(dev) return kwargs = {} # CamelCase method names, eg reboot-bootloader -> RebootBootloader method_name = Camelcase(argv[0]) method = getattr(dev, method_name) argspec = inspect.getargspec(method) num_args = len(argspec.args) - 1 # self is the first one. num_args -= len(argspec.defaults or []) # Handle putting the remaining command line args into the last normal arg. argv.pop(0) # Flags -> Keyword args if kwarg_callback: kwarg_callback(kwargs, argspec) try: if num_args == 1: # Only one argument, so join them all with spaces result = method(' '.join(argv), **kwargs) else: result = method(*argv, **kwargs) if result is not None: try: # An empty call to cStringIO.StringIO returns an instance of # cStringIO.OutputType on Python 2. StringIOType = cStringIO.OutputType except AttributeError: # On Python 3, this object is just an instance of StringIO. StringIOType = cStringIO.StringIO if isinstance(result, StringIOType): sys.stdout.write(result.getvalue()) elif isinstance(result, (list, types.GeneratorType)): for r in result: r = str(r) sys.stdout.write(r) if not r.endswith('\n'): sys.stdout.write('\n') else: sys.stdout.write(result) sys.stdout.write('\n') except Exception as e: # pylint: disable=broad-except sys.stdout.write(str(e)) return finally: dev.Close() ================================================ FILE: scripts/adb/common_stub.py ================================================ """Stubs for tests using common's usb handling.""" import binascii import string PRINTABLE_DATA = set(string.printable) - set(string.whitespace) def _Dotify(data): return ''.join(char if char in PRINTABLE_DATA else '.' for char in data) class StubUsb(object): """UsbHandle stub.""" def __init__(self): self.written_data = [] self.read_data = [] self.timeout_ms = 0 def BulkWrite(self, data, unused_timeout_ms=None): expected_data = self.written_data.pop(0) if expected_data != data: raise ValueError('Expected %s, got %s (%s)' % ( _Dotify(expected_data), binascii.hexlify(data), _Dotify(data))) def BulkRead(self, length, timeout_ms=None): # pylint: disable=unused-argument data = self.read_data.pop(0) if length < len(data): raise ValueError( 'Overflow packet length. Read %d bytes, got %d bytes: %s', length, len(data)) return data def ExpectWrite(self, data): self.written_data.append(data) def ExpectRead(self, data): self.read_data.append(data) def Timeout(self, timeout_ms): return timeout_ms if timeout_ms is not None else self.timeout_ms ================================================ FILE: scripts/adb/fastboot.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A libusb1-based fastboot implementation.""" import binascii import collections try: import cStringIO except ImportError: import io as cStringIO # Python 3 compatibility import logging import os import struct import gflags from . import common from . import usb_exceptions try: basestring except NameError: basestring = str # Python 3 compatibility FLAGS = gflags.FLAGS gflags.DEFINE_integer('fastboot_write_chunk_size_kb', 4, 'The size of packets to write to usb, this is set to 4 ' "for legacy reasons. We've had success with 1MB " 'DRASTICALLY increasing flashing times.') _LOG = logging.getLogger('fastboot') DEFAULT_MESSAGE_CALLBACK = lambda m: logging.info('Got %s from device', m) FastbootMessage = collections.namedtuple( # pylint: disable=invalid-name 'FastbootMessage', ['message', 'header']) # From fastboot.c VENDORS = {0x18D1, 0x0451, 0x0502, 0x0FCE, 0x05C6, 0x22B8, 0x0955, 0x413C, 0x2314, 0x0BB4, 0x8087} CLASS = 0xFF SUBCLASS = 0x42 PROTOCOL = 0x03 # pylint: disable=invalid-name DeviceIsAvailable = common.InterfaceMatcher(CLASS, SUBCLASS, PROTOCOL) # pylint doesn't understand cross-module exception baseclasses. # pylint: disable=nonstandard-exception class FastbootTransferError(usb_exceptions.FormatMessageWithArgumentsException): """Transfer error.""" class FastbootRemoteFailure(usb_exceptions.FormatMessageWithArgumentsException): """Remote error.""" class FastbootStateMismatch(usb_exceptions.FormatMessageWithArgumentsException): """Fastboot and uboot's state machines are arguing. You Lose.""" class FastbootInvalidResponse( usb_exceptions.FormatMessageWithArgumentsException): """Fastboot responded with a header we didn't expect.""" class FastbootProtocol(object): """Encapsulates the fastboot protocol.""" FINAL_HEADERS = {'OKAY', 'DATA'} def __init__(self, usb): """Constructs a FastbootProtocol instance. Arguments: usb: UsbHandle instance. """ self.usb = usb @property def usb_handle(self): return self.usb def SendCommand(self, command, arg=None): """Sends a command to the device. Args: command: The command to send. arg: Optional argument to the command. """ if arg is not None: command = '%s:%s' % (command, arg) self._Write(cStringIO.StringIO(command), len(command)) def HandleSimpleResponses( self, timeout_ms=None, info_cb=DEFAULT_MESSAGE_CALLBACK): """Accepts normal responses from the device. Args: timeout_ms: Timeout in milliseconds to wait for each response. info_cb: Optional callback for text sent from the bootloader. Returns: OKAY packet's message. """ return self._AcceptResponses('OKAY', info_cb, timeout_ms=timeout_ms) def HandleDataSending(self, source_file, source_len, info_cb=DEFAULT_MESSAGE_CALLBACK, progress_callback=None, timeout_ms=None): """Handles the protocol for sending data to the device. Arguments: source_file: File-object to read from for the device. source_len: Amount of data, in bytes, to send to the device. info_cb: Optional callback for text sent from the bootloader. progress_callback: Callback that takes the current and the total progress of the current file. timeout_ms: Timeout in milliseconds to wait for each response. Raises: FastbootTransferError: When fastboot can't handle this amount of data. FastbootStateMismatch: Fastboot responded with the wrong packet type. FastbootRemoteFailure: Fastboot reported failure. FastbootInvalidResponse: Fastboot responded with an unknown packet type. Returns: OKAY packet's message. """ accepted_size = self._AcceptResponses( 'DATA', info_cb, timeout_ms=timeout_ms) accepted_size = binascii.unhexlify(accepted_size[:8]) accepted_size, = struct.unpack('>I', accepted_size) if accepted_size != source_len: raise FastbootTransferError( 'Device refused to download %s bytes of data (accepts %s bytes)', source_len, accepted_size) self._Write(source_file, accepted_size, progress_callback) return self._AcceptResponses('OKAY', info_cb, timeout_ms=timeout_ms) def _AcceptResponses(self, expected_header, info_cb, timeout_ms=None): """Accepts responses until the expected header or a FAIL. Arguments: expected_header: OKAY or DATA info_cb: Optional callback for text sent from the bootloader. timeout_ms: Timeout in milliseconds to wait for each response. Raises: FastbootStateMismatch: Fastboot responded with the wrong packet type. FastbootRemoteFailure: Fastboot reported failure. FastbootInvalidResponse: Fastboot responded with an unknown packet type. Returns: OKAY packet's message. """ while True: response = self.usb.BulkRead(64, timeout_ms=timeout_ms) header = response[:4] remaining = response[4:] if header == 'INFO': info_cb(FastbootMessage(remaining, header)) elif header in self.FINAL_HEADERS: if header != expected_header: raise FastbootStateMismatch( 'Expected %s, got %s', expected_header, header) if header == 'OKAY': info_cb(FastbootMessage(remaining, header)) return remaining elif header == 'FAIL': info_cb(FastbootMessage(remaining, header)) raise FastbootRemoteFailure('FAIL: %s', remaining) else: raise FastbootInvalidResponse( 'Got unknown header %s and response %s', header, remaining) def _HandleProgress(self, total, progress_callback): """Calls the callback with the current progress and total .""" current = 0 while True: current += yield try: progress_callback(current, total) except Exception: # pylint: disable=broad-except _LOG.exception('Progress callback raised an exception. %s', progress_callback) continue def _Write(self, data, length, progress_callback=None): """Sends the data to the device, tracking progress with the callback.""" if progress_callback: progress = self._HandleProgress(length, progress_callback) next(progress) while length: tmp = data.read(FLAGS.fastboot_write_chunk_size_kb * 1024) length -= len(tmp) self.usb.BulkWrite(tmp) if progress_callback: progress.send(len(tmp)) class FastbootCommands(object): """Encapsulates the fastboot commands.""" protocol_handler = FastbootProtocol def __init__(self, usb): """Constructs a FastbootCommands instance. Arguments: usb: UsbHandle instance. """ self._usb = usb self._protocol = self.protocol_handler(usb) @property def usb_handle(self): return self._usb def Close(self): self._usb.Close() @classmethod def ConnectDevice( cls, port_path=None, serial=None, default_timeout_ms=None): """Convenience function to get an adb device from usb path or serial.""" usb = common.UsbHandle.FindAndOpen( DeviceIsAvailable, port_path=port_path, serial=serial, timeout_ms=default_timeout_ms) return cls(usb) @classmethod def Devices(cls): """Get a generator of UsbHandle for devices available.""" return common.UsbHandle.FindDevices(DeviceIsAvailable) def _SimpleCommand(self, command, arg=None, **kwargs): self._protocol.SendCommand(command, arg) return self._protocol.HandleSimpleResponses(**kwargs) def FlashFromFile(self, partition, source_file, source_len=0, info_cb=DEFAULT_MESSAGE_CALLBACK, progress_callback=None): """Flashes a partition from the file on disk. Args: partition: Partition name to flash to. source_file: Filename to download to the device. source_len: Optional length of source_file, uses os.stat if not provided. info_cb: See Download. progress_callback: See Download. Returns: Download and flash responses, normally nothing. """ if source_len == 0: # Fall back to stat. source_len = os.stat(source_file).st_size download_response = self.Download( source_file, source_len=source_len, info_cb=info_cb, progress_callback=progress_callback) flash_response = self.Flash(partition, info_cb=info_cb) return download_response + flash_response def Download(self, source_file, source_len=0, info_cb=DEFAULT_MESSAGE_CALLBACK, progress_callback=None): """Downloads a file to the device. Args: source_file: A filename or file-like object to download to the device. source_len: Optional length of source_file. If source_file is a file-like object and source_len is not provided, source_file is read into memory. info_cb: Optional callback accepting FastbootMessage for text sent from the bootloader. progress_callback: Optional callback called with the percent of the source_file downloaded. Note, this doesn't include progress of the actual flashing. Returns: Response to a download request, normally nothing. """ if isinstance(source_file, basestring): source_len = os.stat(source_file).st_size source_file = open(source_file) if source_len == 0: # Fall back to storing it all in memory :( data = source_file.read() source_file = cStringIO.StringIO(data) source_len = len(data) self._protocol.SendCommand('download', '%08x' % source_len) return self._protocol.HandleDataSending( source_file, source_len, info_cb, progress_callback=progress_callback) def Flash(self, partition, timeout_ms=0, info_cb=DEFAULT_MESSAGE_CALLBACK): """Flashes the last downloaded file to the given partition. Args: partition: Partition to flash. timeout_ms: Optional timeout in milliseconds to wait for it to finish. info_cb: See Download. Usually no messages. Returns: Response to a download request, normally nothing. """ return self._SimpleCommand('flash', arg=partition, info_cb=info_cb, timeout_ms=timeout_ms) def Erase(self, partition, timeout_ms=None): """Erases the given partition.""" self._SimpleCommand('erase', arg=partition, timeout_ms=timeout_ms) def Getvar(self, var, info_cb=DEFAULT_MESSAGE_CALLBACK): """Returns the given variable's definition. Args: var: A variable the bootloader tracks, such as version. info_cb: See Download. Usually no messages. Returns: Value of var according to the current bootloader. """ return self._SimpleCommand('getvar', arg=var, info_cb=info_cb) def Oem(self, command, timeout_ms=None, info_cb=DEFAULT_MESSAGE_CALLBACK): """Executes an OEM command on the device. Args: command: The command to execute, such as 'poweroff' or 'bootconfig read'. timeout_ms: Optional timeout in milliseconds to wait for a response. info_cb: See Download. Messages vary based on command. Returns: The final response from the device. """ return self._SimpleCommand( 'oem %s' % command, timeout_ms=timeout_ms, info_cb=info_cb) def Continue(self): """Continues execution past fastboot into the system.""" return self._SimpleCommand('continue') def Reboot(self, target_mode=None, timeout_ms=None): """Reboots the device. Args: target_mode: Normal reboot when unspecified (or None). Can specify other target modes, such as 'recovery' or 'bootloader'. timeout_ms: Optional timeout in milliseconds to wait for a response. Returns: Usually the empty string. Depends on the bootloader and the target_mode. """ return self._SimpleCommand('reboot', arg=target_mode, timeout_ms=timeout_ms) def RebootBootloader(self, timeout_ms=None): """Reboots into the bootloader, usually equiv to Reboot('bootloader').""" return self._SimpleCommand('reboot-bootloader', timeout_ms=timeout_ms) ================================================ FILE: scripts/adb/fastboot_debug.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Fastboot debugging binary. Call it similar to how you call android's fastboot. Call it similar to how you call android's fastboot, but this only accepts usb paths and no serials. """ import sys import gflags import progressbar from . import common_cli from . import fastboot gflags.ADOPT_module_key_flags(common_cli) FLAGS = gflags.FLAGS def KwargHandler(kwargs, argspec): if 'info_cb' in argspec.args: # Use an unbuffered version of stdout. def InfoCb(message): if not message.message: return sys.stdout.write('%s: %s\n' % (message.header, message.message)) sys.stdout.flush() kwargs['info_cb'] = InfoCb if 'progress_callback' in argspec.args: bar = progressbar.ProgessBar( widgets=[progressbar.Bar(), progressbar.Percentage()]) bar.start() def SetProgress(current, total): bar.update(current / total * 100.0) if current == total: bar.finish() kwargs['progress_callback'] = SetProgress def main(argv): common_cli.StartCli( argv, fastboot.FastbootCommands.ConnectDevice, list_callback=fastboot.FastbootCommands.Devices, kwarg_callback=KwargHandler) if __name__ == '__main__': main(FLAGS(sys.argv)) ================================================ FILE: scripts/adb/fastboot_protocol.txt ================================================ Fastboot Protocol Documentation Fastboot's protocol is similar to ADB in only a few ways. However, to make the code simpler to be inside a bootloader, it basically was completely altered. Commands: getvar:%(variable)s download:%08x verify:%08x flash:%(partition)s erase:%(partition)s oem %(stuff)s boot continue reboot reboot-bootloader Responses: These are 4-64 bytes long. The first 4 bytes is the header, the rest is header-specific but only up to 60 bytes. INFO + data[0-60] Arbitrary data returned from the bootloader. OKAY + reason[0-60] Last response, says the command succeeded. FAIL + reason[0-60] Last response, says the command failed. DATA + size[8] Only in response to a download command, says the bootloader is ready to accept `size` amount of data. ================================================ FILE: scripts/adb/fastboot_test.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for adb.fastboot.""" try: import cStringIO except ImportError: import io as cStringIO # Python 3 compatibility import os import tempfile import unittest import gflags from . import common_stub from . import fastboot FLAGS = gflags.FLAGS class FastbootTest(unittest.TestCase): def setUp(self): self.usb = common_stub.StubUsb() @staticmethod def _SumLengths(items): return sum(len(item) for item in items) def ExpectDownload(self, writes, succeed=True, accept_data=True): self.usb.ExpectWrite('download:%08x' % self._SumLengths(writes)) if accept_data: self.usb.ExpectRead('DATA%08x' % self._SumLengths(writes)) else: self.usb.ExpectRead('DATA%08x' % (self._SumLengths(writes) - 2)) for data in writes: self.usb.ExpectWrite(data) if succeed: self.usb.ExpectRead('OKAYResult') else: self.usb.ExpectRead('FAILResult') def ExpectFlash(self, partition, succeed=True): self.usb.ExpectWrite('flash:%s' % partition) self.usb.ExpectRead('INFORandom info from the bootloader') if succeed: self.usb.ExpectRead('OKAYDone') else: self.usb.ExpectRead('FAILDone') def testDownload(self): raw = 'aoeuidhtnsqjkxbmwpyfgcrl' data = cStringIO.StringIO(raw) self.ExpectDownload([raw]) commands = fastboot.FastbootCommands(self.usb) response = commands.Download(data) self.assertEqual('Result', response) def testDownloadFail(self): raw = 'aoeuidhtnsqjkxbmwpyfgcrl' data = cStringIO.StringIO(raw) self.ExpectDownload([raw], succeed=False) commands = fastboot.FastbootCommands(self.usb) with self.assertRaises(fastboot.FastbootRemoteFailure): commands.Download(data) data = cStringIO.StringIO(raw) self.ExpectDownload([raw], accept_data=False) with self.assertRaises(fastboot.FastbootTransferError): commands.Download(data) def testFlash(self): partition = 'yarr' self.ExpectFlash(partition) commands = fastboot.FastbootCommands(self.usb) output = cStringIO.StringIO() def InfoCb(message): if message.header == 'INFO': output.write(message.message) response = commands.Flash(partition, info_cb=InfoCb) self.assertEqual('Done', response) self.assertEqual('Random info from the bootloader', output.getvalue()) def testFlashFail(self): partition = 'matey' self.ExpectFlash(partition, succeed=False) commands = fastboot.FastbootCommands(self.usb) with self.assertRaises(fastboot.FastbootRemoteFailure): commands.Flash(partition) def testFlashFromFile(self): partition = 'somewhere' # More than one packet, ends somewhere into the 3rd packet. raw = 'SOMETHING' * 1086 tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(raw) tmp.close() progresses = [] pieces = [] chunk_size = FLAGS.fastboot_write_chunk_size_kb * 1024 while raw: pieces.append(raw[:chunk_size]) raw = raw[chunk_size:] self.ExpectDownload(pieces) self.ExpectFlash(partition) cb = lambda progress, total: progresses.append((progress, total)) commands = fastboot.FastbootCommands(self.usb) commands.FlashFromFile( partition, tmp.name, progress_callback=cb) self.assertEqual(len(pieces), len(progresses)) os.remove(tmp.name) def testSimplerCommands(self): commands = fastboot.FastbootCommands(self.usb) self.usb.ExpectWrite('erase:vector') self.usb.ExpectRead('OKAY') commands.Erase('vector') self.usb.ExpectWrite('getvar:variable') self.usb.ExpectRead('OKAYstuff') self.assertEqual('stuff', commands.Getvar('variable')) self.usb.ExpectWrite('continue') self.usb.ExpectRead('OKAY') commands.Continue() self.usb.ExpectWrite('reboot') self.usb.ExpectRead('OKAY') commands.Reboot() self.usb.ExpectWrite('reboot-bootloader') self.usb.ExpectRead('OKAY') commands.RebootBootloader() self.usb.ExpectWrite('oem a little somethin') self.usb.ExpectRead('OKAYsomethin') self.assertEqual('somethin', commands.Oem('a little somethin')) def testVariousFailures(self): commands = fastboot.FastbootCommands(self.usb) self.usb.ExpectWrite('continue') self.usb.ExpectRead('BLEH') with self.assertRaises(fastboot.FastbootInvalidResponse): commands.Continue() self.usb.ExpectWrite('continue') self.usb.ExpectRead('DATA000000') with self.assertRaises(fastboot.FastbootStateMismatch): commands.Continue() if __name__ == '__main__': unittest.main() ================================================ FILE: scripts/adb/filesync_protocol.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ADB protocol implementation. Implements the ADB protocol as seen in android's adb/adbd binaries, but only the host side. """ import collections import stat import struct import time from . import adb_protocol from . import usb_exceptions # Default mode for pushed files. DEFAULT_PUSH_MODE = stat.S_IFREG | stat.S_IRWXU | stat.S_IRWXG # Maximum size of a filesync DATA packet. MAX_PUSH_DATA = 2*1024 class InvalidChecksumError(Exception): """Checksum of data didn't match expected checksum.""" class InterleavedDataError(Exception): """We only support command sent serially.""" class PushFailedError(Exception): """Pushing a file failed for some reason.""" DeviceFile = collections.namedtuple('DeviceFile', [ 'filename', 'mode', 'size', 'mtime']) class FilesyncProtocol(object): """Implements the FileSync protocol as described in sync.txt.""" @staticmethod def Stat(connection, filename): cnxn = FileSyncConnection(connection, '<4I') cnxn.Send('STAT', filename) command, (mode, size, mtime) = cnxn.Read(('STAT',), read_data=False) if command != 'STAT': raise adb_protocol.InvalidResponseError( 'Expected STAT response to STAT, got %s' % command) return mode, size, mtime @classmethod def List(cls, connection, path): cnxn = FileSyncConnection(connection, '<5I') cnxn.Send('LIST', path) files = [] for cmd_id, header, filename in cnxn.ReadUntil(('DENT',), 'DONE'): if cmd_id == 'DONE': break mode, size, mtime = header files.append(DeviceFile(filename, mode, size, mtime)) return files @classmethod def Pull(cls, connection, filename, dest_file): """Pull a file from the device into the file-like dest_file.""" cnxn = FileSyncConnection(connection, '<2I') cnxn.Send('RECV', filename) for cmd_id, _, data in cnxn.ReadUntil(('DATA',), 'DONE'): if cmd_id == 'DONE': break dest_file.write(data) @classmethod def Push(cls, connection, datafile, filename, st_mode=DEFAULT_PUSH_MODE, mtime=0): """Push a file-like object to the device. Args: connection: ADB connection datafile: File-like object for reading from filename: Filename to push to st_mode: stat mode for filename mtime: modification time Raises: PushFailedError: Raised on push failure. """ fileinfo = '%s,%s' % (filename, st_mode) cnxn = FileSyncConnection(connection, '<2I') cnxn.Send('SEND', fileinfo) while True: data = datafile.read(MAX_PUSH_DATA) if not data: break cnxn.Send('DATA', data) if mtime == 0: mtime = int(time.time()) # DONE doesn't send data, but it hides the last bit of data in the size # field. cnxn.Send('DONE', size=mtime) for cmd_id, _, data in cnxn.ReadUntil((), 'OKAY', 'FAIL'): if cmd_id == 'OKAY': return raise PushFailedError(data) class FileSyncConnection(object): """Encapsulate a FileSync service connection.""" ids = [ 'STAT', 'LIST', 'SEND', 'RECV', 'DENT', 'DONE', 'DATA', 'OKAY', 'FAIL', 'QUIT', ] id_to_wire, wire_to_id = adb_protocol.MakeWireIDs(ids) def __init__(self, adb_connection, recv_header_format): self.adb = adb_connection # Sending self.send_buffer = '' self.send_header_len = struct.calcsize('<2I') # Receiving self.recv_buffer = '' self.recv_header_format = recv_header_format self.recv_header_len = struct.calcsize(recv_header_format) def Send(self, command_id, data='', size=0): """Send/buffer FileSync packets. Packets are buffered and only flushed when this connection is read from. All messages have a response from the device, so this will always get flushed. Args: command_id: Command to send. data: Optional data to send, must set data or size. size: Optionally override size from len(data). """ if data: size = len(data) if not self._CanAddToSendBuffer(len(data)): self._Flush() header = struct.pack('<2I', self.id_to_wire[command_id], size) self.send_buffer += header + data def Read(self, expected_ids, read_data=True): """Read ADB messages and return FileSync packets.""" if self.send_buffer: self._Flush() # Read one filesync packet off the recv buffer. header_data = self._ReadBuffered(self.recv_header_len) header = struct.unpack(self.recv_header_format, header_data) # Header is (ID, ...). command_id = self.wire_to_id[header[0]] if command_id not in expected_ids: if command_id == 'FAIL': raise usb_exceptions.AdbCommandFailureException('Command failed.') raise adb_protocol.InvalidResponseError( 'Expected one of %s, got %s' % (expected_ids, command_id)) if not read_data: return command_id, header[1:] # Header is (ID, ..., size). size = header[-1] data = self._ReadBuffered(size) return command_id, header[1:-1], data def ReadUntil(self, expected_ids, *finish_ids): """Useful wrapper around Read.""" while True: cmd_id, header, data = self.Read(expected_ids + finish_ids) yield cmd_id, header, data if cmd_id in finish_ids: break def _CanAddToSendBuffer(self, data_len): added_len = self.send_header_len + data_len return len(self.send_buffer) + added_len < adb_protocol.MAX_ADB_DATA def _Flush(self): self.adb.Write(self.send_buffer) self.send_buffer = '' def _ReadBuffered(self, size): # Ensure recv buffer has enough data. while len(self.recv_buffer) < size: _, data = self.adb.ReadUntil('WRTE') self.recv_buffer += data result = self.recv_buffer[:size] self.recv_buffer = self.recv_buffer[size:] return result ================================================ FILE: scripts/adb/filesync_protocol.txt ================================================ The missing sync.txt from android's ADB. Message Format: Every message starts with a single 32-bit word. (Everything is little-endian). Depending on that first word, the rest of the data can have various meanings. Messages from the host/desktop to the device always start with a 'request' message of a u32 command, u32 size, and size more bytes that's a filename, directory or symlink. The command here is referred to as 'id' in the code and the 4-letter codes are prefixed by ID_, eg ID_STAT. STAT: request: u32 command = 'STAT' == 0x53544154 u32 size = len(filename) < 1024 u8 data[size] = filename (no null) response: struct stat st = lstat(filename) u32 command = 'STAT' u32 mode = st.st_mode u32 size = st.st_size u32 time = st.st_mtime LIST: request: u32 command = 'LIST' == 0x4C495354 u32 size = len(path) < 1024 u8 data[size] = path (no null) response: for each filename in listing of path: struct stat st = lstat(filename) u32 command = 'DENT' == 0x44454E54 u32 mode = st.st_mode u32 size = st.st_size u32 time = st.st_mtime u32 namelen = len(filename) u8 data[namelen] = filename done (device -> host): u32 command = 'DONE' == 0x444F4E45 u32[4] = 0 SEND: struct stat st = lstat(filename) request: fileinfo = sprintf(',%d', st.st_mode) u32 command = 'SEND' == 0x53454E44 u32 size = len(filename) + len(fileinfo) < 1024 u8 data[size] = filename + fileinfo repeated data command (host -> device): u32 command = 'DATA' == 0x44415441 u32 size < (64 * 1024) u8 data[size] = file contents finish command (host -> device): u32 command = 'DONE' == 0x444F4E45 u32 timestamp = st.st_mtime response (device -> host): u32 command = 'OKAY' == 0x4F4B4159 or 'FAIL' == 0x4641494C u32 size = 0 if 'OKAY' else len(fail_message) u8 data[] = fail_message RECV: request: u32 command = 'RECV' == 0x52454356 u32 size = len(filename) u8 data[size] = filename repeated data response (device -> host): u32 command = 'DATA' == 0x44415441 u32 size < (64 * 1024) u8 data[size] = file contents finish response (device -> host): u32 command = 'DONE' == 0x444F4E45 u32 size = 0 ================================================ FILE: scripts/adb/usb_exceptions.py ================================================ # Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Common exceptions for ADB and Fastboot.""" class CommonUsbError(Exception): """Base class for usb communication errors.""" class FormatMessageWithArgumentsException(CommonUsbError): """Exception that both looks good and is functional. Okay, not that kind of functional, it's still a class. This interpolates the message with the given arguments to make it human-readable, but keeps the arguments in case other code try-excepts it. """ def __init__(self, message, *args): message %= args super(FormatMessageWithArgumentsException, self).__init__(message, *args) class DeviceNotFoundError(FormatMessageWithArgumentsException): """Device isn't on USB.""" class DeviceAuthError(FormatMessageWithArgumentsException): """Device authentication failed.""" class LibusbWrappingError(CommonUsbError): """Wraps libusb1 errors while keeping its original usefulness. Attributes: usb_error: Instance of libusb1.USBError """ def __init__(self, msg, usb_error): super(LibusbWrappingError, self).__init__(msg) self.usb_error = usb_error def __str__(self): return '%s: %s' % ( super(LibusbWrappingError, self).__str__(), str(self.usb_error)) class WriteFailedError(LibusbWrappingError): """Raised when the device doesn't accept our command.""" class ReadFailedError(LibusbWrappingError): """Raised when the device doesn't respond to our commands.""" class AdbCommandFailureException(Exception): """ADB Command returned a FAIL.""" class AdbOperationException(Exception): """Failed to communicate over adb with device after multiple retries.""" ================================================ FILE: scripts/aws/build.sh ================================================ #!/bin/bash scriptname=`which $0` scriptdir=`dirname $scriptname` scriptdir=`dirname $scriptdir` export CONNECTALDIR=`dirname $scriptdir` echo "CONNECTALDIR=$CONNECTALDIR" if [ "$AWS_FPGA_BUCKET" == "" ]; then AWS_FPGA_BUCKET=aws-fpga fi if [ "$AWS_FPGA_REPO_DIR" == "" ]; then if [ -d `dirname $CONNECTALDIR`/aws-fpga ]; then pushd `dirname $CONNECTALDIR`/aws-fpga . hdk_setup.sh popd fi if [ -d ~/aws-fpga ]; then pushd ~/aws-fpga . hdk_setup.sh popd fi fi BUILD_DIR=`pwd` echo BUILD_DIR=$BUILD_DIR if [ `basename $BUILD_DIR` = 'scripts' ]; then cd ../.. else mkdir -p design mkdir -p build/checkpoints/to_aws mkdir -p build/constraints mkdir -p build/reports mkdir -p build/scripts mkdir -p build/src_post_encryption BUILD_DIR=`pwd`/build/scripts echo BUILD_DIR=$BUILD_DIR fi ## copy the scripts into the build directory so we don't have to worry about paths rsync -v $CONNECTALDIR/scripts/aws/* $BUILD_DIR if [ ! -f $CONNECTALDIR/out/awsf1/ila_connectal_1/ila_connectal_1.xci ]; then echo echo 'Generating Integrated Logic Analyzer core' echo vivado -mode batch -source $CONNECTALDIR/scripts/connectal-synth-ila.tcl echo echo 'Finished generating Integrated Logic Analyzer core' echo fi if [ ! -f $CONNECTALDIR/out/awsf1/axi_protocol_checker_0/axi_protocol_checker_0.xci ]; then echo echo 'Generating AXI Protocol Checker core' echo vivado -mode batch -source $CONNECTALDIR/scripts/connectal-synth-axichecker.tcl echo echo 'Finished generating AXI Protocol Checker core' echo fi export CL_DIR=`pwd` cd $BUILD_DIR echo CL_DIR=$CL_DIR echo BUILD_DIR=$BUILD_DIR cp -fv $CONNECTALDIR/verilog/cl_id_defines.vh $BUILD_DIR/../../design echo '#placeholder' > ../constraints/cl_pnr_user.xdc echo '#placeholder' > ../constraints/cl_synth_user.xdc ## run Vivado to build the FPGA image $AWS_FPGA_REPO_DIR/hdk/common/shell_stable/build/scripts/aws_build_dcp_from_cl.sh -ignore_memory_requirement -notify -foreground "$@" PROJECT_DIR=`dirname $CL_DIR` PROJECT_NAME=`basename $PROJECT_DIR` echo PROJECT_NAME=${PROJECT_NAME} ## return to $CL_DIR cd $CL_DIR ## and now should be in awsf1 subdirectory of $PROJECT_DIR pwd last_log=`realpath build/scripts/last_log` echo last_log=${last_log} build_timestamp=`basename ${last_log} .vivado.log` echo build_timestamp=${build_timestamp} ## ## if build completed successfully, request AWS to create an FPGA image ## if [ -f build/checkpoints/to_aws/${build_timestamp}.Developer_CL.tar ]; then ## request AWS to create an AWS FPGA image $CONNECTALDIR/scripts/aws/create-fpga-image.sh $PROJECT_NAME $build_timestamp $AWS_FPGA_BUCKET \ && ( sleep 1; ## query AWS to make sure the FPGA image is building $CONNECTALDIR/scripts/aws/describe-latest-fpga-image.sh ) fi if [ "$EMAIL" != "" ]; then echo "Connectal AWS FPGA: - Calling notification script to send e-mail to $EMAIL"; ${CONNECTALDIR}/scripts/aws/notify_via_sns.py --build-project ${PROJECT_NAME} --filename ${filename} --timestamp ${build_timestamp} --fpga-image-ids `cat latest-fpga-image.json` fi ================================================ FILE: scripts/aws/create-fpga-image.sh ================================================ #!/bin/bash name=$1 timestamp=$2 bucket="aws-fpga" if [ "$AWS_FPGA_BUCKET" != "" ]; then bucket="$AWS_FPGA_BUCKET" fi if [ "$name" == "" -o "$timestamp" == "" ]; then echo "usage: $0 [s3 bucket]" >&2 exit -1 fi if [ "$3" != "" ]; then bucket="$3" fi if [ -d "build/checkpoints" ]; then CHECKPOINTS_DIR="build/checkpoints" fi if [ -d "awsf1/build/checkpoints" ]; then CHECKPOINTS_DIR="awsf1/build/checkpoints" fi aws s3 cp $CHECKPOINTS_DIR/to_aws/$timestamp.Developer_CL.tar s3://$bucket/$name/ aws s3 cp $CHECKPOINTS_DIR/$timestamp.debug_probes.ltx s3://$bucket/$name/ aws ec2 create-fpga-image --name $name --description $timestamp --input-storage-location Bucket=$bucket,Key=$name/$timestamp.Developer_CL.tar --logs-storage-location Bucket=$bucket,Key=logs-folder | tee latest-fpga-image.json ================================================ FILE: scripts/aws/create_dcp_from_cl.tcl ================================================ # Amazon FPGA Hardware Development Kit # # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Amazon Software License (the "License"). You may not use # this file except in compliance with the License. A copy of the License is # located at # # http://aws.amazon.com/asl/ # # or in the "license" file accompanying this file. This file is distributed on # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or # implied. See the License for the specific language governing permissions and # limitations under the License. package require tar ## Do not edit $TOP set TOP top_sp ## Replace with the name of your module set CL_MODULE awsf1 ################################################# ## Command-line Arguments ################################################# set timestamp [lindex $argv 0] set strategy [lindex $argv 1] set hdk_version [lindex $argv 2] set shell_version [lindex $argv 3] set device_id [lindex $argv 4] set vendor_id [lindex $argv 5] set subsystem_id [lindex $argv 6] set subsystem_vendor_id [lindex $argv 7] set clock_recipe_a [lindex $argv 8] set clock_recipe_b [lindex $argv 9] set clock_recipe_c [lindex $argv 10] set uram_option [lindex $argv 11] set notify_via_sns [lindex $argv 12] ################################################## ## Flow control variables ################################################## set cl.synth 1 set implement 1 ################################################# ## Generate CL_routed.dcp (Done by User) ################################################# puts "AWS FPGA Scripts"; puts "Creating Design Checkpoint from Custom Logic source code"; puts "HDK Version: $hdk_version"; puts "Shell Version: $shell_version"; puts "Vivado Script Name: $argv0"; puts "Strategy: $strategy"; puts "PCI Device ID $device_id"; puts "PCI Vendor ID $vendor_id"; puts "PCI Subsystem ID $subsystem_id"; puts "PCI Subsystem Vendor ID $subsystem_vendor_id"; puts "Clock Recipe A: $clock_recipe_a"; puts "Clock Recipe B: $clock_recipe_b"; puts "Clock Recipe C: $clock_recipe_c"; puts "URAM option: $uram_option"; puts "Notify when done: $notify_via_sns"; #checking if CL_DIR env variable exists if { [info exists ::env(CL_DIR)] } { set CL_DIR $::env(CL_DIR) puts "Using CL directory $CL_DIR"; } else { puts "Error: CL_DIR environment variable not defined ! "; puts "Use export CL_DIR=Your_Design_Root_Directory" exit 2 } #checking if HDK_SHELL_DIR env variable exists if { [info exists ::env(HDK_SHELL_DIR)] } { set HDK_SHELL_DIR $::env(HDK_SHELL_DIR) puts "Using Shell directory $HDK_SHELL_DIR"; } else { puts "Error: HDK_SHELL_DIR environment variable not defined ! "; puts "Run the hdk_setup.sh script from the root directory of aws-fpga"; exit 2 } #checking if HDK_SHELL_DESIGN_DIR env variable exists if { [info exists ::env(HDK_SHELL_DESIGN_DIR)] } { set HDK_SHELL_DESIGN_DIR $::env(HDK_SHELL_DESIGN_DIR) puts "Using Shell design directory $HDK_SHELL_DESIGN_DIR"; } else { puts "Error: HDK_SHELL_DESIGN_DIR environment variable not defined ! "; puts "Run the hdk_setup.sh script from the root directory of aws-fpga"; exit 2 } if [info exists ::env(BUILD_PROJECT)] { set projname $::env(BUILD_PROJECT) } else { set projname [file tail [file dirname $CL_DIR]] } if [info exists ::env(BUILD_USER)] { set build_user $::env(BUILD_USER) set imagename "${build_user} ${projname}" } elseif [info exists ::env(USER)] { set build_user $::env(USER) set imagename "${build_user} ${projname}" } else { set build_user "default" set imagename "${projname}" } set s3_key "${build_user}/${projname}" set s3_folder "s3://aws-fpga/${s3_key}" puts "BUILD_USER ${build_user} BUILD_PROJECT ${projname} S3_FOLDER ${s3_folder}" ################################################## ### Output Directories used by step_user.tcl ################################################## set implDir $CL_DIR/build/checkpoints set rptDir $CL_DIR/build/reports set cacheDir $HDK_SHELL_DESIGN_DIR/cache/ddr4_phy puts "All reports and intermediate results will be time stamped with $timestamp"; set_msg_config -id {Chipscope 16-3} -suppress set_msg_config -string {AXI_QUAD_SPI} -suppress # Suppress Warnings # These are to avoid warning messages that may not be real issues. A developer # may comment them out if they wish to see more information from warning # messages. set_msg_config -id {Common 17-55} -suppress set_msg_config -id {Vivado 12-4739} -suppress set_msg_config -id {Constraints 18-4866} -suppress set_msg_config -id {IP_Flow 19-2162} -suppress set_msg_config -id {Route 35-328} -suppress set_msg_config -id {Vivado 12-1008} -suppress set_msg_config -id {Vivado 12-508} -suppress set_msg_config -id {filemgmt 56-12} -suppress set_msg_config -id {DRC CKLD-1} -suppress set_msg_config -id {DRC CKLD-2} -suppress set_msg_config -id {IP_Flow 19-2248} -suppress set_msg_config -id {Vivado 12-1580} -suppress set_msg_config -id {Constraints 18-550} -suppress set_msg_config -id {Synth 8-3295} -suppress set_msg_config -id {Synth 8-3321} -suppress set_msg_config -id {Synth 8-3331} -suppress set_msg_config -id {Synth 8-3332} -suppress set_msg_config -id {Synth 8-6014} -suppress set_msg_config -id {Timing 38-436} -suppress set_msg_config -id {DRC REQP-1853} -suppress set_msg_config -id {Synth 8-350} -suppress set_msg_config -id {Synth 8-3848} -suppress set_msg_config -id {Synth 8-3917} -suppress puts "AWS FPGA: ([clock format [clock seconds] -format %T]) Calling the encrypt.tcl."; # Check that an email address has been set, else unset notify_via_sns if {[string compare $notify_via_sns "1"] == 0} { if {![info exists env(EMAIL)]} { puts "AWS FPGA: ([clock format [clock seconds] -format %T]) EMAIL variable empty! Completition notification will *not* be sent!"; set notify_via_sns 0; } else { puts "AWS FPGA: ([clock format [clock seconds] -format %T]) EMAIL address for completion notification set to $env(EMAIL)."; } } ################################################## ### Strategy options ################################################## switch $strategy { "BASIC" { puts "BASIC strategy." source $HDK_SHELL_DIR/build/scripts/strategy_BASIC.tcl } "EXPLORE" { puts "EXPLORE strategy." source $HDK_SHELL_DIR/build/scripts/strategy_EXPLORE.tcl } "TIMING" { puts "TIMING strategy." source $HDK_SHELL_DIR/build/scripts/strategy_TIMING.tcl } "CONGESTION" { puts "CONGESTION strategy." source $HDK_SHELL_DIR/build/scripts/strategy_CONGESTION.tcl } "DEFAULT" { puts "DEFAULT strategy." source $HDK_SHELL_DIR/build/scripts/strategy_DEFAULT.tcl } default { puts "$strategy is NOT a valid strategy. Defaulting to strategy DEFAULT." source $HDK_SHELL_DIR/build/scripts/strategy_DEFAULT.tcl } } if { [file exists $CL_DIR/strategy_OVERRIDES.tcl] } { puts "Custom OVERRIDES for strategy." source $CL_DIR/strategy_OVERRIDES.tcl } #Encrypt source code source encrypt.tcl #Set the Device Type source $HDK_SHELL_DIR/build/scripts/device_type.tcl #Procedure for running various implementation steps (impl_step) source $HDK_SHELL_DIR/build/scripts/step_user.tcl -notrace ######################################## ## Generate clocks based on Recipe ######################################## puts "AWS FPGA: ([clock format [clock seconds] -format %T]) Calling aws_gen_clk_constraints.tcl to generate clock constraints from developer's specified recipe."; source $HDK_SHELL_DIR/build/scripts/aws_gen_clk_constraints.tcl ################################################## ### CL XPR OOC Synthesis ################################################## if {${cl.synth}} { source -notrace ./synth_${CL_MODULE}.tcl } ################################################## ### Implementation ################################################## if {$implement} { ######################## # Link Design ######################## if {$link} { ####Create in-memory prjoect and setup IP cache location create_project -part [DEVICE_TYPE] -in_memory set_property IP_REPO_PATHS $cacheDir [current_project] puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Combining Shell and CL design checkpoints"; add_files $HDK_SHELL_DIR/build/checkpoints/from_aws/SH_CL_BB_routed.dcp add_files $CL_DIR/build/checkpoints/${timestamp}.CL.post_synth.dcp set_property SCOPED_TO_CELLS {WRAPPER_INST/CL} [get_files $CL_DIR/build/checkpoints/${timestamp}.CL.post_synth.dcp] #Read the constraints, note *DO NOT* read cl_clocks_aws (clocks originating from AWS shell) read_xdc [ list \ $CL_DIR/build/constraints/cl_pnr_user.xdc ] set_property PROCESSING_ORDER late [get_files cl_pnr_user.xdc] puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Running link_design"; link_design -top $TOP -part [DEVICE_TYPE] -reconfig_partitions {WRAPPER_INST/SH WRAPPER_INST/CL} report_timing -cell WRAPPER_INST/CL -delay_type max -max_paths 10 -sort_by group -input_pins -file $rptDir/${timestamp}.postlinkdesign_timing_max.rpt report_timing -cell WRAPPER_INST/CL -delay_type min -max_paths 10 -sort_by group -input_pins -file $rptDir/${timestamp}.postlinkdesign_timing_min.rpt puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - PLATFORM.IMPL==[get_property PLATFORM.IMPL [current_design]]"; ################################################## # Apply Clock Properties for Clock Table Recipes ################################################## puts "AWS FPGA: ([clock format [clock seconds] -format %T]) - Sourcing aws_clock_properties.tcl to apply properties to clocks. "; # Apply properties to clocks source $HDK_SHELL_DIR/build/scripts/aws_clock_properties.tcl # Write post-link checkpoint puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Writing post-link_design checkpoint ${timestamp}.post_link.dcp"; write_checkpoint -force $CL_DIR/build/checkpoints/${timestamp}.post_link.dcp } ######################## # CL Optimize ######################## if {$opt} { puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Running optimization"; impl_step opt_design $TOP $opt_options $opt_directive $opt_preHookTcl $opt_postHookTcl if {$psip} { impl_step opt_design $TOP "-merge_equivalent_drivers -sweep" } } # Constraints for TCK<->Main Clock #set_clock_groups -name tck_clk_main_a0 -asynchronous -group [get_clocks -of_objects [get_pins static_sh/SH_DEBUG_BRIDGE/inst/bsip/inst/USE_SOFTBSCAN.U_TAP_TCKBUFG/O]] -group [get_clocks -of_objects [get_pins SH/kernel_clks_i/clkwiz_sys_clk/inst/CLK_CORE_DRP_I/clk_inst/mmcme3_adv_inst/CLKOUT0]] #set_clock_groups -name tck_drck -asynchronous -group [get_clocks -of_objects [get_pins static_sh/SH_DEBUG_BRIDGE/inst/bsip/inst/USE_SOFTBSCAN.U_TAP_TCKBUFG/O]] -group [get_clocks drck] #set_clock_groups -name tck_userclk -asynchronous -group [get_clocks -of_objects [get_pins static_sh/SH_DEBUG_BRIDGE/inst/bsip/inst/USE_SOFTBSCAN.U_TAP_TCKBUFG/O]] -group [get_clocks -of_objects [get_pins static_sh/pcie_inst/inst/gt_top_i/diablo_gt.diablo_gt_phy_wrapper/phy_clk_i/bufg_gt_userclk/O]] ######################## # CL Place ######################## if {$place} { puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Running placement"; if {$psip} { append place_options " -fanout_opt" } impl_step place_design $TOP $place_options $place_directive $place_preHookTcl $place_postHookTcl } ############################## # CL Post-Place Optimization ############################## if {$phys_opt} { puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Running post-place optimization"; impl_step phys_opt_design $TOP $phys_options $phys_directive $phys_preHookTcl $phys_postHookTcl } ######################## # CL Route ######################## if {$route} { puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Routing design"; impl_step route_design $TOP $route_options $route_directive $route_preHookTcl $route_postHookTcl } ############################## # CL Post-Route Optimization ############################## set SLACK [get_property SLACK [get_timing_paths]] #Post-route phys_opt will not be run if slack is positive or greater than -200ps. if {$route_phys_opt && $SLACK > -0.400 && $SLACK < 0} { puts "\nAWS FPGA: ([clock format [clock seconds] -format %T]) - Running post-route optimization"; impl_step route_phys_opt_design $TOP $post_phys_options $post_phys_directive $post_phys_preHookTcl $post_phys_postHookTcl } ############################## # Final Implmentation Steps ############################## # Report final timing report_timing_summary -file $CL_DIR/build/reports/${timestamp}.SH_CL_final_timing_summary.rpt # This is what will deliver to AWS puts "AWS FPGA: ([clock format [clock seconds] -format %T]) - Writing final DCP to to_aws directory."; write_checkpoint -force $CL_DIR/build/checkpoints/to_aws/${timestamp}.SH_CL_routed.dcp # Generate debug probes file write_debug_probes -force -no_partial_ltxfile -file $CL_DIR/build/checkpoints/${timestamp}.debug_probes.ltx close_project } # ################################################ # Create Manifest and Tarball for delivery # ################################################ # Create a zipped tar file, that would be used for createFpgaImage EC2 API puts "AWS FPGA: ([clock format [clock seconds] -format %T]) - Compress files for sending to AWS. " # Create manifest file set manifest_file [open "$CL_DIR/build/checkpoints/to_aws/${timestamp}.manifest.txt" w] set hash [lindex [split [exec sha256sum $CL_DIR/build/checkpoints/to_aws/${timestamp}.SH_CL_routed.dcp] ] 0] set vivado_version [string range [version -short] 0 5] puts "vivado_version is $vivado_version\n" puts $manifest_file "manifest_format_version=2\n" puts $manifest_file "pci_vendor_id=$vendor_id\n" puts $manifest_file "pci_device_id=$device_id\n" puts $manifest_file "pci_subsystem_id=$subsystem_id\n" puts $manifest_file "pci_subsystem_vendor_id=$subsystem_vendor_id\n" puts $manifest_file "dcp_hash=$hash\n" puts $manifest_file "shell_version=$shell_version\n" puts $manifest_file "tool_version=v$vivado_version\n" puts $manifest_file "dcp_file_name=${timestamp}.SH_CL_routed.dcp\n" puts $manifest_file "hdk_version=$hdk_version\n" puts $manifest_file "date=$timestamp\n" puts $manifest_file "clock_recipe_a=$clock_recipe_a\n" puts $manifest_file "clock_recipe_b=$clock_recipe_b\n" puts $manifest_file "clock_recipe_c=$clock_recipe_c\n" close $manifest_file # Delete old tar file with same name if { [file exists $CL_DIR/build/checkpoints/to_aws/${timestamp}.Developer_CL.tar] } { puts "Deleting old tar file with same name."; file delete -force $CL_DIR/build/checkpoints/to_aws/${timestamp}.Developer_CL.tar } # Tar checkpoint to aws cd $CL_DIR/build/checkpoints tar::create to_aws/${timestamp}.Developer_CL.tar [glob to_aws/${timestamp}*] puts "AWS FPGA: ([clock format [clock seconds] -format %T]) - Finished creating final tar file in to_aws directory."; puts "AWS FPGA: ([clock format [clock seconds] -format %T]) - Build complete."; ================================================ FILE: scripts/aws/describe-latest-fpga-image.sh ================================================ #!/bin/bash if [ -f awsf1/latest-fpga-image.json ]; then aws ec2 describe-fpga-images --fpga-image-ids `jq -r .FpgaImageId < awsf1/latest-fpga-image.json` fi if [ -f latest-fpga-image.json ]; then aws ec2 describe-fpga-images --fpga-image-ids `jq -r .FpgaImageId < latest-fpga-image.json` fi ================================================ FILE: scripts/aws/encrypt.tcl ================================================ # Amazon FPGA Hardware Development Kit # # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Amazon Software License (the "License"). You may not use # this file except in compliance with the License. A copy of the License is # located at # # http://aws.amazon.com/asl/ # # or in the "license" file accompanying this file. This file is distributed on # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or # implied. See the License for the specific language governing permissions and # limitations under the License. # TODO: # Add check if CL_DIR and HDK_SHELL_DIR directories exist # Add check if /build and /build/src_port_encryption directories exist # Add check if the vivado_keyfile exist set HDK_SHELL_DIR $::env(HDK_SHELL_DIR) set HDK_SHELL_DESIGN_DIR $::env(HDK_SHELL_DESIGN_DIR) set CL_DIR $::env(CL_DIR) set TARGET_DIR $CL_DIR/build/src_post_encryption set UNUSED_TEMPLATES_DIR $HDK_SHELL_DESIGN_DIR/interfaces set BLUESPECDIR $::env(BLUESPECDIR) set CONNECTALDIR $::env(CONNECTALDIR) # Remove any previously encrypted files, that may no longer be used exec rm -f $TARGET_DIR/* #---- Developr would replace this section with design files ---- ## Change file names and paths below to reflect your CL area. DO NOT include AWS RTL files. foreach {file} [glob -nocomplain -- $CL_DIR/verilog/*.v $CL_DIR/verilog/*.sv $CL_DIR/verilog/*.vh $CL_DIR/generatedbsv/ConnectalProjectConfig.bsv] { file copy -force $file $TARGET_DIR } foreach {dir} "$BLUESPECDIR/Verilog $BLUESPECDIR/Verilog.Vivado $CONNECTALDIR/verilog $HDK_SHELL_DIR/design/interfaces" { puts "Looking in directory $dir" foreach {pat} {FIFO BRAM Reg Counter Reset Sync cl_ unused aws} { foreach {file} [glob -nocomplain -- $dir/*$pat*.v $dir/*$pat*.vh $dir/*$pat*.inc $dir/*$pat*.sv] { puts "Copying file $file" file copy -force $file $TARGET_DIR } } } #---- End of section replaced by Developr --- # Make sure files have write permissions for the encryption exec chmod +w {*}[glob $TARGET_DIR/*] # encrypt .v/.sv/.vh/inc as verilog files # encrypt -k $HDK_SHELL_DIR/build/scripts/vivado_keyfile.txt -lang verilog [glob -nocomplain -- $TARGET_DIR/*.{v,sv}] ## [glob -nocomplain -- $TARGET_DIR/*.vh] [glob -nocomplain -- $TARGET_DIR/*.inc] # encrypt *vhdl files # encrypt -k $HDK_SHELL_DIR/build/scripts/vivado_vhdl_keyfile.txt -lang vhdl -quiet [ glob -nocomplain -- $TARGET_DIR/*.vhd? ] ================================================ FILE: scripts/aws/notify_via_sns.py ================================================ #!/usr/bin/env python33 # Amazon FPGA Hardware Development Kit # # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Amazon Software License (the "License"). You may not use # this file except in compliance with the License. A copy of the License is # located at # # http://aws.amazon.com/asl/ # # or in the "license" file accompanying this file. This file is distributed on # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or # implied. See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import argparse import base64 import boto3 import json import os import sys import requests import hmac argparser = argparse.ArgumentParser(description="Notify via email or HTTP that FPGA CL build is complete") argparser.add_argument('--email', help='Email to notify', default=os.environ.get('SNS_NOTIFY_EMAIL', None)) argparser.add_argument('--sns-notify-url', help='url to notify via SNS', default=os.environ.get('SNS_NOTIFY_URL', None)) argparser.add_argument('--notify-url', help='url to notify via POST', default=os.environ.get('NOTIFY_URL', None)) argparser.add_argument('--secret-key-file', help='File containing base64 encoded secret key for signing message sent to notify_url', default=os.environ.get('NOTIFY_SECRET_KEY_FILE', None)) argparser.add_argument('--build-user', help='User performing build', default=os.environ.get('BUILD_USER', 'default')) argparser.add_argument('--build-project', help='Name of project built', default=os.environ.get('BUILD_PROJECT', None)) argparser.add_argument('--filename', help='Name of checkpoint archive', default=None) argparser.add_argument('--timestamp', help='Timestamp of build', default=None) argparser.add_argument('--sourcehash', help='md5sum of the RTL', default=None) argparser.add_argument('--fpga-image-ids', help='JSON output from aws ec2 create-fpga-image', default=None) options = argparser.parse_args() sns = boto3.client('sns') topic_resp = sns.create_topic(Name="FPGA_CL_BUILD_%s" % options.build_user) print(topic_resp['TopicArn']) if options.sns_notify_url: topic_resp_json = sns.create_topic(Name="FPGA_CL_BUILD_JSON") list_resp_json = sns.list_subscriptions_by_topic(TopicArn=topic_resp_json['TopicArn']) if not any(i['Endpoint'] == options.sns_notify_url for i in list_resp_json.get('Subscriptions')): print("Subscribing to the FPGA_CL_BUILD topic") sub_resp_json = sns.subscribe(TopicArn=topic_resp_json['TopicArn'], Protocol='http', Endpoint=options.sns_notify_url) print(sub_resp_json) list_resp = sns.list_subscriptions_by_topic(TopicArn=topic_resp['TopicArn']) if list_resp.get('Subscriptions'): print(list_resp.get('Subscriptions')) if options.email is None: print('Please set your EMAIL environment variable to your email address.') sys.exit(1) print("Using email address: %s" % options.email) # subscribe if email is not in list if not any(i['Endpoint'] == options.email for i in list_resp.get('Subscriptions')): print("Subscribing to the FPGA_CL_BUILD topic") sub_resp = sns.subscribe(TopicArn=topic_resp['TopicArn'], Protocol='email', Endpoint=options.email) print(sub_resp) message_dict = { 'subject': 'Your FPGA CL build is complete.', 'user': options.build_user, 'email': options.email, 'project': options.build_project, 'filename': options.filename, 'timestamp': options.timestamp, 'sourceHash': options.sourcehash, 'fpgaImageId': '', 'fpgaImageGlobalId': '', } if options.fpga_image_ids: fpga_image_ids = json.loads(options.fpga_image_ids) message_dict['fpgaImageId'] = fpga_image_ids.get('FpgaImageId', '') message_dict['fpgaImageGlobalId'] = fpga_image_ids.get('FpgaImageGlobalId', '') email_message_template = ''' Your FPGA CL build is complete: Project: %(project)s Timestamp: %(timestamp)s FPGA Image Id: %(fpgaImageId)s FPGA Image Global Id: %(fpgaImageGlobalId)s ''' pub_resp = sns.publish(TopicArn=topic_resp['TopicArn'], Message=email_message_template % message_dict, Subject='Your FPGA CL build is complete.') if options.sns_notify_url: print('notifying %s' % options.sns_notify_url); imageIds = json.loads(options.fpga_image_ids) if options.fpga_image_ids else None pub_resp = sns.publish(TopicArn=topic_resp_json['TopicArn'], Message=json.dumps(message_dict), Subject='Your FPGA CL build is complete.') if options.notify_url: message = bytes(json.dumps(message_dict), 'utf8') signature = None if options.secret_key_file: secret_key_b64 = open(options.secret_key_file, 'r').read() secret_key = base64.b64decode(secret_key_b64) signature = hmac.new(secret_key, message).hexdigest() data = {'message': message, 'signature': signature } resp = requests.post(options.notify_url, data=data) print('Posting to url %s \n data %s' % (options.notify_url, data)) print('Posted to url %s got response %s' % (options.notify_url, resp)) print(json.dumps({'message': message.decode('utf8'), 'signature': signature })) sys.exit(0) ================================================ FILE: scripts/aws/run.awsf1 ================================================ #!/bin/bash #set -x set -e export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" echo "run.awsf1 parameters are:" $* SSHPARAM=" -o StrictHostKeyChecking=no" if [ "$1" == "" ]; then echo "usage: $0 ubuntu.exe" >&2 exit -1 fi if [ "$RUNTIMELIMIT" != "" ]; then TIMELIMIT=$RUNTIMELIMIT else TIMELIMIT=3m fi ENV="" if [ "$RUNENV" != "" ]; then for e in `env | grep $RUNENV | grep -v RUNENV | sed 's/=(.*)/=\"$1\"/'`; do ENV="$ENV $e" done fi if [ "$RUNPARAM" != "" ]; then if [ "$ENV" != "" ]; then echo "sending environment variables $ENV" fi RUNPARAMTEMP=$RUNPARAM:22 array=(${RUNPARAMTEMP//:/ }) RUNIP=${array[0]} RUNPORT=${array[1]} TEMPDIR=/tmp/`uname -n`-$PPID-pcie if [ "$INSTANCE_ID" != "" ]; then aws ec2 start-instances --instance-ids $INSTANCE_ID while true; do ssh -o ConnectTimeout=10 -p $RUNPORT $RUNIP uptime && break done fi ssh $SSHPARAM -p $RUNPORT $RUNIP "rm -rf $TEMPDIR; mkdir -p $TEMPDIR" || exit 1 EXE=$1 EXENAME=`basename $1` ARGS="" shift scp -P $RUNPORT $EXE $RUNIP:$TEMPDIR || exit 2 for arg in $*; do if [ -f "$arg" ]; then scp -P $RUNPORT $arg $RUNIP:$TEMPDIR || exit 2 arg_basename=`basename "$arg"` ARGS="$ARGS $TEMPDIR/$arg_basename" else ARGS="$ARGS $arg" fi done for f in $RUNFILES; do scp -P $RUNPORT $f $RUNIP:$TEMPDIR || exit 2 done echo "ARGS=$*" ssh $SSHPARAM -p $RUNPORT $RUNIP "$ENV timeout $TIMELIMIT sudo fpga-load-local-image -S 0 -I $AGFI"; status=$? ssh $SSHPARAM -p $RUNPORT $RUNIP "$ENV timeout $TIMELIMIT pciescanportal"; status=$? ssh $SSHPARAM -p $RUNPORT $RUNIP "$ENV timeout $TIMELIMIT sudo modprobe portalmem"; status=$? ssh $SSHPARAM -p $RUNPORT $RUNIP "$ENV timeout $TIMELIMIT sudo modprobe pcieportal"; status=$? #ssh $SSHPARAM -p $RUNPORT $RUNIP "$ENV timeout $TIMELIMIT dmesg | tail -40"; status=$? ssh $SSHPARAM -p $RUNPORT $RUNIP "cd $TEMPDIR; LD_LIBRARY_PATH=$TEMPDIR $ENV timeout $TIMELIMIT catchsegv $TEMPDIR/$EXENAME $ARGS"; status=$? ssh $SSHPARAM -p $RUNPORT $RUNIP "rm -rf $TEMPDIR" if [ "$INSTANCE_ID" != "" ]; then echo "" echo "Stopping instance $INSTANCE_ID" aws ec2 stop-instances --instance-ids $INSTANCE_ID fi exit $status else ## FIXME timeout 3m catchsegv $1; status=$? exit $status fi ================================================ FILE: scripts/aws/synth_awsf1.tcl ================================================ #Param needed to avoid clock name collisions set_param sta.enableAutoGenClkNamePersistence 0 set CL_MODULE $CL_MODULE create_project -in_memory -part [DEVICE_TYPE] -force source {../../board.tcl} if [info exists AWSF1_DDR_A] { if {$AWSF1_DDR_A == ""} { set AWSF1_DDR_A 1 } puts "AWSF1_DDR_A=$AWSF1_DDR_A" } else { set AWSF1_DDR_A 0 } if [info exists AWSF1_CL_DEBUG_BRIDGE] { if {$AWSF1_CL_DEBUG_BRIDGE == ""} { set AWSF1_CL_DEBUG_BRIDGE 1 } puts "AWSF1_CL_DEBUG_BRIDGE=$AWSF1_CL_DEBUG_BRIDGE" } else { set AWSF1_CL_DEBUG_BRIDGE 0 } ######################################## ## Generate clocks based on Recipe ######################################## puts "AWS FPGA: ([clock format [clock seconds] -format %T]) Calling aws_gen_clk_constraints.tcl to generate clock constraints from developer's specified recipe."; source $HDK_SHELL_DIR/build/scripts/aws_gen_clk_constraints.tcl ############################# ## Read design files ############################# #Convenience to set the root of the RTL directory set ENC_SRC_DIR $CL_DIR/build/src_post_encryption puts "AWS FPGA: ([clock format [clock seconds] -format %T]) Reading developer's Custom Logic files post encryption."; #---- User would replace this section ----- # Reading the .sv and .v files, as proper designs would not require # reading .v, .vh, nor .inc files read_verilog -sv [glob $ENC_SRC_DIR/*.sv] [glob $ENC_SRC_DIR/*.v] if {$AWSF1_CL_DEBUG_BRIDGE} { puts "Reading connectal ILA IP" read_ip [list \ "$CONNECTALDIR/out/awsf1/ila_connectal_1/ila_connectal_1.xci" \ "$CONNECTALDIR/out/awsf1/ila_connectal_2/ila_connectal_2.xci" \ "$CONNECTALDIR/out/awsf1/ila_connectal_3/ila_connectal_3.xci" \ "$CONNECTALDIR/out/awsf1/axi_protocol_checker_0/axi_protocol_checker_0.xci" \ ] } #---- End of section replaced by User ---- puts "AWS FPGA: Reading AWS Shell design"; #Read AWS Design files read_verilog [list \ $HDK_SHELL_DESIGN_DIR/lib/lib_pipe.sv \ $HDK_SHELL_DESIGN_DIR/lib/bram_2rw.sv \ $HDK_SHELL_DESIGN_DIR/lib/flop_fifo.sv \ $HDK_SHELL_DESIGN_DIR/interfaces/cl_ports.vh \ $HDK_SHELL_DESIGN_DIR/sh_ddr/synth/sync.v \ $HDK_SHELL_DESIGN_DIR/sh_ddr/synth/flop_ccf.sv \ $HDK_SHELL_DESIGN_DIR/sh_ddr/synth/ccf_ctl.v \ $HDK_SHELL_DESIGN_DIR/sh_ddr/synth/mgt_acc_axl.sv \ $HDK_SHELL_DESIGN_DIR/sh_ddr/synth/mgt_gen_axl.sv \ $HDK_SHELL_DESIGN_DIR/sh_ddr/synth/sh_ddr.sv \ ] puts "AWS FPGA: Reading IP blocks"; #Read DDR IP if {$AWSF1_DDR_A} { read_ip [ list \ $HDK_SHELL_DESIGN_DIR/ip/ddr4_core/ddr4_core.xci \ ] # Additional IP's that might be needed if using the DDR read_bd [list \ $HDK_SHELL_DESIGN_DIR/ip/cl_axi_interconnect/cl_axi_interconnect.bd \ ] } #Read IP for axi register slices read_ip [ list \ $HDK_SHELL_DESIGN_DIR/ip/src_register_slice/src_register_slice.xci \ $HDK_SHELL_DESIGN_DIR/ip/dest_register_slice/dest_register_slice.xci \ $HDK_SHELL_DESIGN_DIR/ip/axi_clock_converter_0/axi_clock_converter_0.xci \ $HDK_SHELL_DESIGN_DIR/ip/axi_register_slice/axi_register_slice.xci \ $HDK_SHELL_DESIGN_DIR/ip/axi_register_slice_light/axi_register_slice_light.xci ] #Read IP for virtual jtag / ILA/VIO read_ip [ list \ $HDK_SHELL_DESIGN_DIR/ip/cl_debug_bridge/cl_debug_bridge.xci \ $HDK_SHELL_DESIGN_DIR/ip/ila_1/ila_1.xci \ $HDK_SHELL_DESIGN_DIR/ip/ila_0/ila_0.xci \ $HDK_SHELL_DESIGN_DIR/ip/ila_vio_counter/ila_vio_counter.xci \ $HDK_SHELL_DESIGN_DIR/ip/vio_0/vio_0.xci ] puts "AWS FPGA: Reading AWS constraints"; #Read all the constraints # # cl_clocks_aws.xdc - AWS auto-generated clock constraint. ***DO NOT MODIFY*** # cl_ddr.xdc - AWS provided DDR pin constraints. ***DO NOT MODIFY*** # cl_synth_user.xdc - Developer synthesis constraints. read_xdc [ list \ $CL_DIR/build/constraints/cl_clocks_aws.xdc \ $HDK_SHELL_DIR/build/constraints/cl_ddr.xdc \ $HDK_SHELL_DIR/build/constraints/cl_synth_aws.xdc \ $CL_DIR/build/constraints/cl_synth_user.xdc ] #Do not propagate local clock constraints for clocks generated in the SH set_property USED_IN {synthesis implementation OUT_OF_CONTEXT} [get_files cl_clocks_aws.xdc] set_property PROCESSING_ORDER EARLY [get_files cl_clocks_aws.xdc] ######################## # CL Synthesis ######################## puts "AWS FPGA: ([clock format [clock seconds] -format %T]) Start design synthesis."; update_compile_order -fileset sources_1 puts "\nRunning synth_design for $CL_MODULE $CL_DIR/build/scripts \[[clock format [clock seconds] -format {%a %b %d %H:%M:%S %Y}]\]" eval [concat synth_design -top $CL_MODULE -verilog_define XSDB_SLV_DIS -part [DEVICE_TYPE] -mode out_of_context $synth_options -directive $synth_directive] set failval [catch {exec grep "FAIL" failfast.csv}] if { $failval==0 } { puts "AWS FPGA: FATAL ERROR--Resource utilization error; check failfast.csv for details" exit 1 } puts "AWS FPGA: ([clock format [clock seconds] -format %T]) writing post synth checkpoint."; write_checkpoint -force $CL_DIR/build/checkpoints/${timestamp}.CL.post_synth.dcp close_project #Set param back to default value set_param sta.enableAutoGenClkNamePersistence 1 ================================================ FILE: scripts/aws/upload.sh ================================================ #!/bin/bash filename=$1 if [ "$filename" = "" ]; then echo Usage: $0 filename exit 1 fi basename=`basename $filename .Developer_CL.tar` echo "basename=$basename" aws s3 cp ../checkpoints/to_aws/$filename s3://aws-fpga/simple/$filename aws s3 cp ../checkpoints.$basename.debug_probes.ltx s3://aws-fpga/simple/$filename aws ec2 create-fpga-image --name simple --description "$filename" --input-storage-location Bucket=aws-fpga,Key=simple/$filename --logs-storage-location Bucket=aws-fpga,Key=logs-folder ================================================ FILE: scripts/aws/wait_for_afi.py ================================================ #!/usr/bin/env python3 # Amazon FPGA Hardware Development Kit # # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Amazon Software License (the "License"). You may not use # this file except in compliance with the License. A copy of the License is # located at # # http://aws.amazon.com/asl/ # # or in the "license" file accompanying this file. This file is distributed on # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or # implied. See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import argparse import boto3 import datetime from datetime import datetime, timedelta import logging import json import os import re import sys import time import traceback try: import aws_fpga_utils logger = aws_fpga_utils.get_logger(__file__) except ImportError as e: traceback.print_tb(sys.exc_info()[2]) print("warning: {}\nMake sure to source hdk_setup.sh".format(sys.exc_info()[1])) logging.basicConfig(stream=sys.stderr, level=logging.INFO) logger = logging.getLogger('aws-fpga') aws_fpga_utils = None SLEEP_SECONDS = 60 DEFAULT_MAX_DURATION_HOURS = 6 description = ''' Waits for AFI generation to complete. Optionally notifies an email address subscribed to an SNS topic. If --notify is used then --email is required. ''' if __name__ == '__main__': parser = argparse.ArgumentParser(description=description) parser.add_argument('--afi', action='store', required=True, help="AFI ID (not Global AFI ID)") parser.add_argument('--max-minutes', action='store', required=False, default=(DEFAULT_MAX_DURATION_HOURS * 60), help="Maximum minutes to wait. Default={}".format(DEFAULT_MAX_DURATION_HOURS * 60)) parser.add_argument('--notify', action='store_true', default=False, required=False, help="Notify SNS topic when AFI generation completes.") parser.add_argument('--sns-topic', action='store', required=False, default='CREATE_AFI', help="SNS topic name to create/use for notification. Defaults to CREATE_AFI)") parser.add_argument('--email', action='store', required=False, default=None, help="Email address to subscribe to the SNS topic.") parser.add_argument('--debug', action='store_true', default=False, help="Enable debug messages") args = parser.parse_args() if args.debug: logger.setLevel(logging.DEBUG) if args.afi.endswith('.json'): with open(args.afi) as f: ids = json.loads(f.read()) args.afi = ids.get('FpgaImageId').decode('utf8') start_time = datetime.utcnow() max_duration = timedelta(minutes=args.max_minutes) logger.info("Waiting for {} generation to complete.".format(args.afi)) if args.notify: if not args.email: logger.error("--email required with --notify.") sys.exit(1) email = args.email topic_name = args.sns_topic logger.info("Will subscribe {} to SNS topic {} and notify the topic when complete".format(email, topic_name)) if aws_fpga_utils: topic_arn = aws_fpga_utils.create_sns_subscription(topic_name, email) # Wait for create-fpga-image to complete ec2_client = boto3.client('ec2') create_fpga_image_complete = False while not create_fpga_image_complete: afi_info = ec2_client.describe_fpga_images(FpgaImageIds=[args.afi])['FpgaImages'][0] afi_state = afi_info['State']['Code'] logger.debug("State={}".format(afi_state)) if afi_state != 'pending': if afi_state == 'available': logger.info('AFI generation passed and AFI is available') else: afi_message = afi_info['State']['Message'] logger.error("AFI generation failed. State={} Message={}".format(afi_state, afi_message)) create_fpga_image_complete = True else: current_time = datetime.utcnow() if (current_time - start_time) > max_duration: logger.error("Timed out waiting for AFI generation to complete.") sys.exit(1) time.sleep(SLEEP_SECONDS) passed = afi_state == 'available' if args.notify: if passed: subject = "create-fpga-image of {} passed".format(args.afi) message = "State={}".format(afi_state) else: subject = "create-fpga-image of {} failed".format(args.afi) message = "State={} Messsage={}".format(afi_state, afi_message) sns_client = boto3.client('sns') pub_resp = sns_client.publish(TopicArn=topic_arn, Subject=subject, Message=message) if passed: sys.exit(0) sys.exit(1) ================================================ FILE: scripts/boardinfo.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2014 Quanta Research Cambridge, Inc. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import json, os, sys scripthome = os.path.dirname(os.path.abspath(__file__)) def attribute(boardname, name): filename = scripthome + '/../boardinfo/' + boardname + '.json' if not os.path.exists(filename): print('boardinfo: The boardinfo file for the specified architecture does not exist \'' + boardname + '\'') sys.exit(-1) boardInfo = json.loads(open(filename).read()) return boardInfo[name] if __name__=='__main__': print(attribute(sys.argv[1], 'options')) ================================================ FILE: scripts/bsv.filter ================================================ #!/usr/bin/env python3 # Usage doxyfilter_bsv.psv < infile.bsv > outfile.java import fileinput import os import sys import re import argparse argparser = argparse.ArgumentParser("Generate doxygen-ready Java from BSV.") argparser.add_argument('bsvfile', help='BSV files to process', nargs='*') argparser.add_argument('-d', '--outdir', default=None, help='Directory for output files') def filter_bsv(bsvin, out): processing_module = 0 module_start = "" prev_line = "" continue_template = 0 important_comment = 0 in_interface = 0 in_module = 0 in_instance = 0 in_license = 0 in_section_break = 0 in_enum = 0 in_struct = 0 documented_construct = 0 # define groups to bundle interfaces and modules out.write("/** @defgroup BSVInterface Interfaces */ \n") out.write("/** @defgroup BSVModule Modules */ \n") for line in bsvin: # Skip the license section if "Copyright" in line: # Print the line without modification out.write(line) in_license = 1 continue if in_license: # All comments in the license section should be printed without modification if "//" in line: out.write(line) continue # if in license and the current line is not a comment then # end the license section in_license = 0 important_comment = 0 documented_construct = 0 # Skip the section break marked by // ============= comment_re = re.compile(r"""[\s]* # white space at the start of the line // # start of the comment [\s]* # one or more white spaces === # section break marked by a line of = """, re.X) if comment_re.match(line): # if a section break found then print the line without modification out.write(line) # if beginning of section break comment then set in_section_break to 1 # if end of section break comment then set in_section_break to 0 in_section_break = in_section_break ^ 1 continue if in_section_break: # All comments in section break comment should be printed without modification if "//" in line: out.write(line) continue # Check if it is the beginning of an important comment # // comment_re = re.compile(r"""[\s]* # white space before the comment // # start of comment [\s]* # immediately followed by 0 or more white space \n # end of line """, re.X) if comment_re.search(line): # if this is the beginning of an important comment then change double slashes to # triple slashes and set important_comment line = re.sub(r'//', r'///', line) important_comment = 1 documented_construct = 1 out.write(line) continue if important_comment: # If inside an important comment then change double slashes to # triple slashes comment_re = re.compile(r"""[\s]* # white space before the comment // # start of a comment """, re.X) if comment_re.search(line): line = re.sub(r'//', r'///', line) out.write(line) continue important_comment = 0 #FIXME # Check to see if it is the second highest priority comment # // #comment_re = re.compile(r"""[\s]* # white space before the comment # // # start of comment # [\s]* # white space before the start of the text # (.+) # comment text # """, re.X) #if comment_re.search(line): # line = re.sub(r'//', r'///', line) # All comments with or without space/newline in the first line # are important within a module or interface if in_module or in_interface or in_instance: comment_re = re.compile(r"""[\s]+ # white space before the comment // # start of comment (?!/) # should not be followed by a 3rd slash """, re.X) if comment_re.search(line): line = re.sub(r'//', r'/// ', line) # Replace #() with <> comment_re = re.compile("""#\( # start of the template parameter ([\w\s,<>]+?) # non greedy search for template parameters \) # End of the template parameter """, re.X) # If the template parameter did not find a closing parantheses in the last line # then process the last line along with this line if continue_template: line = prev_line + line prev_line = "" if re.search(r'#\(', line): prev_line = line continue_template = 1 while re.search(r'#\(([\w\s,<>]+?)\)', line): line = re.sub(r'#\(([\w\s,<>]+?)\)', r'<\1>', line) if not re.search(r'#\(', line): prev_line = "" continue_template = 0 if continue_template: continue # handle interface definitions comment_re = re.compile("""interface\s # interface keyword followed by white space [\w]+ # interface name [\s]* # 0 or more white spaces after the name (< # Start of template [\w\s,<>]+ # Template parameters - may be nested >)* # End of template - may not be present and hence the * ; # end of interface declaration statement """, re.X) if comment_re.search(line): line = re.sub(r'\binterface\b', r'class', line) if documented_construct: line = "/** @ingroup BSVInterface */ " + line line = line.replace(';', ' {'); in_interface = 1 if re.search(r'endinterface', line): line = line.replace('endinterface', '};', re.DOTALL) in_interface = 0 documented_construct = 0 # handle module definitions comment_re = re.compile("""^(\s)* # start of string followed by white space module(\s)+ # module keyword followed by white spaces (\[[\w]+\])* # [module type] may or may not be present [\s]* # white space ([\w]+) # module name (< # Start of template [\w\s,<>]+ # Template parameters - may be nested >)* # End of template may not be present and hence the * (\(.*\))* # interface name may or may not be present on the same line """, re.X) if comment_re.search(line): line = re.sub(r'\bmodule\b', r'class', line) line = re.sub(r'\[[\w]+\]', r'', line) line = re.sub(r'\n$', ' {\n', line) # the $ sign denotes the end of line. In case module declaration span multiple lines if documented_construct: line = "/** @ingroup BSVModule */ " + line line = line.replace(';', ''); # remove interface name from the definition line = re.sub(r'\(.*\)', r' ', line) in_module = 1 # substitute the end module statement with a closing curly brace if re.search(r'endmodule', line): line = line.replace('endmodule', '};', re.DOTALL) in_module = 0 documented_construct = 0 # handle methods comment_re = re.compile("""^(\s)* # start of the string followed by white space method(\s)+ # method keyword followed by white space ([\w<>,]+)(\s)+ # method type followed by white space ([\w]+) # method name """, re.X) if in_module: if comment_re.search(line): line = re.sub(r'\bmethod\b', r'', line) line = line.replace(';', ''); line = re.sub(r'\n', ' {\n', line) line = line.replace('endmethod', '}') #FIXME # handle functions #comment_re = re.compile("""^(\s)* # start of a string followed by white space # function(\s)+ # function keyword followed by white space # ([\w<>,]+)(\s)+ # function return type followed by white space # ([\w]+) # function name # """, re.X) #if comment_re.search(line): # if documented_construct: # line = "/** @ingroup BSVFunctions */ " + line # line = re.sub(r'\bfunction\b', r'', line) # line = line.replace(';', '') # line = re.sub(r'\n', ' {\n', line) #line = line.replace('endfunction', '}') # handle the special "deriving" enum case comment_re = re.compile("""^(\s)* # start of a string followed by white space typedef(\s)+ # typedef keyword followed by white space enum(\s)+ # enum keyword followed by white space """, re.X) if comment_re.search(line): in_enum = 1 comment_re = re.compile("""(\s)+ # white space deriving(\s)+ # keyword derving followed by white space \([\w,\s]+\) # Parameters inside parantheses """, re.X) if in_enum: if comment_re.search(line): line = re.sub(r'deriving(.)*', ';', line) in_enum = 0; documented_construct = 0 # handle the special "deriving" struct case comment_re = re.compile("""^(\s)* # start of a string followed by white space typedef(\s)+ # typedef keyword followed by white space struct(\s)+ # struct keyword followed by white space """, re.X) if comment_re.search(line): in_struct = 1 comment_re = re.compile("""(\s)+ # white space deriving(\s)+ # keyword derving followed by white space \([\w,\s]+\) # Parameters inside parantheses """, re.X) if in_struct: if comment_re.search(line): line = re.sub(r'deriving(.)*', ';', line) in_struct = 0; documented_construct = 0 import_re = re.compile("""(\s)* # white space import(\s)+ # keyword import followed by white space .* # Parameters inside parantheses """, re.X) if import_re.search(line): continue out.write(line) out.close() if __name__=='__main__': exename = os.path.abspath(sys.argv[0]) connectaldir = os.path.dirname(exename) namespace = argparser.parse_args() if namespace.outdir and not os.path.exists(namespace.outdir): os.makedirs(namespace.outdir) if not namespace.outdir: filter_bsv(open(namespace.bsvfile[0], 'r'), sys.stdout) else: for bsvfile in namespace.bsvfile: if not namespace.outdir: ofile = bsvfile.replace('.bsv', '.java') else: basename = os.path.basename(bsvfile).replace('.bsv', '.java') ofile = os.path.join(namespace.outdir, basename) bsvin = open(bsvfile, 'r') out = open(ofile, 'w') filter_bsv(bsvin, out) ================================================ FILE: scripts/bsvdepend.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2015 Connectal Project # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # import os, sys import glob import argparse import re import bsvpreprocess import bsvdependencies default_bluespecdir=None if 'BLUESPECDIR' in os.environ: default_bluespecdir = os.environ['BLUESPECDIR'] argparser = argparse.ArgumentParser("Writes a makefile for a dependence build of the BSV files.") argparser.add_argument('bsvfile', help='BSV files to process', nargs='*') argparser.add_argument('-D', '--bsvdefine', default=[], help='BSV define', action='append') argparser.add_argument('--bsvpath', default=[], help='directories to add to bsc search path', action='append') argparser.add_argument('--bluespecdir', default=default_bluespecdir, help='BSC bluespec dir') argparser.add_argument('-o', '--output', help='Output Makefile', default='Makefile.bsv') argparser.add_argument('--all', help='Generate entries for all BSV files on path.', default=False, action='store_true') makefiletemplate=''' %(name)s_BO = obj/%(name)s.bo %(name)s_DEP = %(dependences)s %(name)s_INC = %(includes)s %(name)s_BSV = %(bsvfilename)s $(eval $(call BSV_BO_RULE, $(%(name)s_BO), $(%(name)s_BSV), $(%(name)s_DEP), $(%(name)s_INC))) ''' synthmoduletemplate = ''' %(name)s_MOD = %(module)s %(name)s_V = verilog/%(module)s.v %(name)s_BO = obj/%(name)s.bo %(name)s_BSV = %(bsvfilename)s %(name)s_DEP = %(dependences)s %(name)s_INC = %(includes)s $(eval $(call BSV_V_RULE, $(%(name)s_MOD), $(%(name)s_V), $(%(name)s_BSV), $(%(name)s_DEP), $(%(name)s_INC))) ''' if __name__=='__main__': options = argparser.parse_args() (bsvdep,bsvpath) = bsvdependencies.bsvDependencies(options.bsvfile, options.all, options.bluespecdir, options.bsvpath, options.bsvdefine) makef = open(options.output, 'w') makef.write('# BSV dependences\n') for bsvdef in options.bsvdefine: makef.write('# -D%s\n' % bsvdef) makef.write('OBJMAKEFILE_DEP = %s\n' % ' '.join(['$(wildcard %s/*.bsv)' % path for path in bsvpath])) makef.write('\n') for bsvfilename,packages,includes,synthesizedModules in bsvdep: basename = os.path.basename(bsvfilename) (name, ext) = os.path.splitext(basename) makef.write(makefiletemplate % { 'name': name, 'bsvfilename': bsvfilename, 'dependences': ' '.join(['obj/%s.bo' % pkg for pkg in packages]), 'includes': ' '.join(includes) }) for mod in synthesizedModules: makef.write(synthmoduletemplate % { 'module': mod, 'name': name, 'bsvfilename': bsvfilename, 'dependences': ' '.join(['obj/%s.bo' % pkg for pkg in packages]), 'includes': ' '.join(includes) }) pass makef.close() ================================================ FILE: scripts/bsvdependencies.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2015 Connectal Project # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # import os, sys import glob import argparse import re import bsvpreprocess import subprocess def getBsvPackages(bluespecdir): """BLUESPECDIR is expected to be the path to the bluespec distribution. The function GETBSVPACKAGES returns a list of all the packages in the prelude library of this distribution. """ pkgs = [] for f in glob.glob('%s/Prelude/*.bo' % bluespecdir) + glob.glob('%s/Libraries/*.bo' % bluespecdir) + glob.glob('%s/Libraries/*/*.bo' % bluespecdir) + glob.glob('%s/Libraries/*/*/*.bo' % bluespecdir): pkgs.append(os.path.splitext(os.path.basename(f))[0]) return pkgs def bsvDependencies(bsvfile, allBsv=False, bluespecdir=None, argbsvpath=[], bsvdefine=[]): """Return the list of dependencies [(NAME,BSVFILENAME,PACKAGES,INCLUDES,SYNTHESIZEDMODULES)] of BSVFILE, adding the list BSVPATH to the directories to explore for dependencies. The boolean ALLBSV will generate entries for all BSV files on path. The string BLUESPECDIR will add the Prelude of Bsv in packages. The BSVDEFINE argument is passed to the preprocessor. """ bsvpath = [] for p in argbsvpath: ps = p.split(':') bsvpath.extend(ps) bsvpackages = getBsvPackages(bluespecdir) project_packages = {} if allBsv: for d in bsvpath: for bsvfilename in glob.glob('%s/*.bsv' % d): package_name = os.path.basename(bsvfilename) if bsvfilename not in bsvfile and package_name not in project_packages: bsvfile.append(bsvfilename) project_packages[package_name] = bsvfilename abspaths = {} for f in bsvfile: abspaths[os.path.basename(f)] = f for d in bsvpath: for f in glob.glob('%s/*' % d): abspaths[os.path.basename(f)] = f generated = [] for bsvfilename in bsvfile: vf = open(bsvfilename, 'r') basename = os.path.basename(bsvfilename) (name, ext) = os.path.splitext(basename) source = vf.read() ##preprocessed = bsvpreprocess.preprocess(bsvfilename, source, bsvdefine, bsvpath) bsc_search_path = '+:' + ':'.join(bsvpath) bsc_define_args = [] for var in bsvdefine: bsc_define_args.append('-D') bsc_define_args.append(var) cp = subprocess.check_output(['bsc', '-E', '-p', bsc_search_path] + bsc_define_args + [bsvfilename]) preprocessed = cp.decode('utf8') packages = [] includes = [] synthesizedModules = [] synthesize = False for line in preprocessed.split('\n'): m = re.match('//`include "([^\"]+)"', line) m1 = re.match('//`include(.*)', line) if m: iname = m.group(1) if iname in abspaths: iname = abspaths[iname] else: iname = 'obj/%s' % iname includes.append(iname) elif m1: sys.stderr.write('bsvdepend %s: unhandled `include %s\n' % (bsvfilename, m1.group(1))) if re.match('^//', line): continue m = re.match('import\s+([A-Za-z0-9_]+)\w*', re.sub("`line\(.*\)", " ", line)) if m: pkg = m.group(1) if pkg not in packages and pkg not in bsvpackages: packages.append(pkg) if synthesize: m = re.match('\s*module\s+([A-Za-z0-9_]+)', line) if m: synthesizedModules.append(m.group(1)) else: sys.stderr.write('bsvdepend: in %s expecting module: %s\n' % (bsvfilename, line)) synth = line.find('(* synthesize *)') attr = line.find('(* ') if synth >= 0: synthesize = True elif attr >= 0: pass # no change to synthesize else: synthesize = False pass generated.append((bsvfilename,packages,includes,synthesizedModules)) vf.close() return (generated,bsvpath) ================================================ FILE: scripts/bsvgen.py ================================================ ## ## Copyright (C) 2012-2013 Nokia, Inc ## Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, copy, ## modify, merge, publish, distribute, sublicense, and/or sell copies ## of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## The above copyright notice and this permission notice shall be ## included in all copies or substantial portions of the Software. ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ## BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ## ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ## SOFTWARE. ## from __future__ import print_function import os import math import re import hashlib import AST import string import util try: xrange except NameError: xrange = range # Python 3 compatibility preambleTemplate=''' import FIFO::*; import FIFOF::*; import GetPut::*; import Connectable::*; import Clocks::*; import FloatingPoint::*; import Adapter::*; import Leds::*; import Vector::*; import SpecialFIFOs::*; import ConnectalConfig::*; import ConnectalMemory::*; import Portal::*; import CtrlMux::*; import ConnectalMemTypes::*; import Pipe::*; import HostInterface::*; import LinkerLib::*; %(extraImports)s ''' requestStructTemplate=''' typedef struct { %(paramStructDeclarations)s } %(MethodName)s_Message deriving (Bits); ''' requestOutputPipeInterfaceTemplate='''\ interface PipeOut#(%(MethodName)s_Message) %(methodName)s_PipeOut; ''' exposedProxyInterfaceTemplate=''' // exposed proxy interface typedef PipePortal#(0, %(channelCount)s, SlaveDataBusWidth) %(Ifc)sPortalOutput; interface %(Ifc)sOutput; interface %(Ifc)sPortalOutput portalIfc; interface %(Package)s%(Ifc)s ifc; endinterface interface %(Dut)s; interface StdPortal portalIfc; interface %(Package)s%(Ifc)s ifc; endinterface interface %(Ifc)sOutputPipeMethods; %(indicationMethodDecls)s endinterface interface %(Ifc)sOutputPipes; interface %(Ifc)sOutputPipeMethods methods; interface %(Ifc)sPortalOutput portalIfc; endinterface function Bit#(16) get%(Ifc)sMessageSize(Bit#(16) methodNumber); case (methodNumber)%(messageSizes)s endcase endfunction (* synthesize *) module mk%(Ifc)sOutputPipes(%(Ifc)sOutputPipes); Vector#(%(channelCount)s, PipeOut#(Bit#(SlaveDataBusWidth))) indicationPipes; %(indicationMethodRules)s PortalInterrupt#(SlaveDataBusWidth) intrInst <- mkPortalInterrupt(indicationPipes); interface %(Ifc)sOutputPipeMethods methods; %(indicationMethodAssigns)s endinterface interface PipePortal portalIfc; interface PortalSize messageSize; method size = get%(Ifc)sMessageSize; endinterface interface Vector requests = nil; interface Vector indications = indicationPipes; interface PortalInterrupt intr = intrInst; endinterface endmodule (* synthesize *) module mk%(Ifc)sOutput(%(Ifc)sOutput); let indicationPipes <- mk%(Ifc)sOutputPipes; interface %(Package)s%(Ifc)s ifc; %(indicationMethods)s endinterface interface PipePortal portalIfc = indicationPipes.portalIfc; endmodule instance PortalMessageSize#(%(Ifc)sOutput); function Bit#(16) portalMessageSize(%(Ifc)sOutput p, Bit#(16) methodNumber); return get%(Ifc)sMessageSize(methodNumber); endfunction endinstance interface %(Ifc)sInverse; %(indicationInverseMethodDecls)s endinterface interface %(Ifc)sInverter; interface %(Package)s%(Ifc)s ifc; interface %(Ifc)sInverse inverseIfc; endinterface instance Connectable#(%(Ifc)sInverse, %(Ifc)sOutputPipeMethods); module mkConnection#(%(Ifc)sInverse in, %(Ifc)sOutputPipeMethods out)(Empty); %(indicationInverseConnect)s endmodule endinstance (* synthesize *) module mk%(Ifc)sInverter(%(Ifc)sInverter); %(inverseIndicationMethodRules)s interface %(Package)s%(Ifc)s ifc; %(inverseIndicationMethods)s endinterface interface %(Ifc)sInverse inverseIfc; %(inverseIndicationInverseMethods)s endinterface endmodule (* synthesize *) module mk%(Ifc)sInverterV(%(Ifc)sInverter); %(wInverseIndicationMethodRules)s interface %(Package)s%(Ifc)s ifc; %(wInverseIndicationMethods)s endinterface interface %(Ifc)sInverse inverseIfc; %(wInverseIndicationInverseMethods)s endinterface endmodule // synthesizeable proxy MemPortal (* synthesize *) module mk%(Dut)sSynth#(Bit#(SlaveDataBusWidth) id)(%(Dut)s); let dut <- mk%(Ifc)sOutput(); PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort <- mkPortalCtrlMemSlave(id, dut.portalIfc.intr); let memslave <- mkMemMethodMuxOut(ctrlPort.memSlave,dut.portalIfc.indications); interface MemPortal portalIfc = (interface MemPortal; interface PhysMemSlave slave = memslave; interface ReadOnly interrupt = ctrlPort.interrupt; interface WriteOnly num_portals = ctrlPort.num_portals; endinterface); interface %(Package)s%(Ifc)s ifc = dut.ifc; endmodule // exposed proxy MemPortal module mk%(Dut)s#(idType id)(%(Dut)s) provisos (Bits#(idType, a__), Add#(b__, a__, SlaveDataBusWidth)); let rv <- mk%(Dut)sSynth(extend(pack(id))); return rv; endmodule ''' exposedWrapperInterfaceTemplate=''' %(requestElements)s // exposed wrapper portal interface interface %(Ifc)sInputPipes; %(requestOutputPipeInterfaces)s endinterface typedef PipePortal#(%(channelCount)s, 0, SlaveDataBusWidth) %(Ifc)sPortalInput; interface %(Ifc)sInput; interface %(Ifc)sPortalInput portalIfc; interface %(Ifc)sInputPipes pipes; endinterface interface %(Dut)sPortal; interface %(Ifc)sPortalInput portalIfc; endinterface // exposed wrapper MemPortal interface interface %(Dut)s; interface StdPortal portalIfc; endinterface instance Connectable#(%(Ifc)sInputPipes,%(Ifc)s); module mkConnection#(%(Ifc)sInputPipes pipes, %(Ifc)s ifc)(Empty); %(mkConnectionMethodRules)s endmodule endinstance // exposed wrapper Portal implementation (* synthesize *) module mk%(Ifc)sInput(%(Ifc)sInput); Vector#(%(channelCount)s, PipeIn#(Bit#(SlaveDataBusWidth))) requestPipeIn; %(methodRules)s interface PipePortal portalIfc; interface PortalSize messageSize; method Bit#(16) size(Bit#(16) methodNumber); case (methodNumber)%(messageSizes)s endcase endmethod endinterface interface Vector requests = requestPipeIn; interface Vector indications = nil; interface PortalInterrupt intr; method Bool status(); return False; endmethod method Bit#(dataWidth) channel(); return -1; endmethod endinterface endinterface interface %(Ifc)sInputPipes pipes; %(outputPipes)s endinterface endmodule module mk%(Dut)sPortal#(%(Ifc)s ifc)(%(Dut)sPortal); let dut <- mk%(Ifc)sInput; mkConnection(dut.pipes, ifc); interface PipePortal portalIfc = dut.portalIfc; endmodule interface %(Dut)sMemPortalPipes; interface %(Ifc)sInputPipes pipes; interface MemPortal#(12,32) portalIfc; endinterface (* synthesize *) module mk%(Dut)sMemPortalPipes#(Bit#(SlaveDataBusWidth) id)(%(Dut)sMemPortalPipes); let dut <- mk%(Ifc)sInput; PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort <- mkPortalCtrlMemSlave(id, dut.portalIfc.intr); let memslave <- mkMemMethodMuxIn(ctrlPort.memSlave,dut.portalIfc.requests); interface %(Ifc)sInputPipes pipes = dut.pipes; interface MemPortal portalIfc = (interface MemPortal; interface PhysMemSlave slave = memslave; interface ReadOnly interrupt = ctrlPort.interrupt; interface WriteOnly num_portals = ctrlPort.num_portals; endinterface); endmodule // exposed wrapper MemPortal implementation module mk%(Dut)s#(idType id, %(Ifc)s ifc)(%(Dut)s) provisos (Bits#(idType, a__), Add#(b__, a__, SlaveDataBusWidth)); let dut <- mk%(Dut)sMemPortalPipes(zeroExtend(pack(id))); mkConnection(dut.pipes, ifc); interface MemPortal portalIfc = dut.portalIfc; endmodule ''' requestRuleTemplate=''' AdapterFromBus#(SlaveDataBusWidth,%(MethodName)s_Message) %(methodName)s_requestAdapter <- mkAdapterFromBus(); requestPipeIn[%(channelNumber)s] = %(methodName)s_requestAdapter.in; ''' methodDefTemplate=''' method Action %(methodName)s(%(formals)s);''' interfaceDefTemplate = ''' interface %(Ifc)s;%(methodDef)s endinterface ''' messageSizeTemplate=''' %(channelNumber)s: return fromInteger(valueOf(SizeOf#(%(MethodName)s_Message)));''' mkConnectionMethodTemplate=''' rule handle_%(methodName)s_request; let request <- toGet(pipes.%(methodName)s_PipeOut).get(); ifc.%(methodName)s(%(paramsForCall)s); endrule ''' indicationRuleTemplate=''' AdapterToBus#(SlaveDataBusWidth,%(MethodName)s_Message) %(methodName)s_responseAdapter <- mkAdapterToBus(); indicationPipes[%(channelNumber)s] = %(methodName)s_responseAdapter.out; ''' indicationDeclTemplate=''' interface PipeIn#(%(MethodName)s_Message) %(methodName)s; ''' indicationAssignTemplate=''' interface %(methodName)s = %(methodName)s_responseAdapter.in; ''' indicationMethodTemplate=''' method Action %(methodName)s(%(formals)s); indicationPipes.methods.%(methodName)s.enq(%(MethodName)s_Message {%(structElements)s}); //$display(\"indicationMethod \'%(methodName)s\' invoked\"); endmethod''' indicationInverseDeclTemplate=''' method ActionValue#(%(MethodName)s_Message) %(methodName)s; ''' inverseIndicationRuleTemplate=''' FIFOF#(%(MethodName)s_Message) fifo_%(methodName)s <- mkFIFOF(); ''' inverseIndicationMethodTemplate=''' method Action %(methodName)s(%(formals)s); fifo_%(methodName)s.enq(%(MethodName)s_Message {%(structElements)s}); endmethod''' inverseIndicationInverseMethodTemplate=''' method ActionValue#(%(MethodName)s_Message) %(methodName)s; fifo_%(methodName)s.deq; return fifo_%(methodName)s.first; endmethod''' indicationInverseConnectTemplate=''' mkConnection(in.%(methodName)s, out.%(methodName)s); ''' wInverseIndicationRuleTemplate=''' PutInverter#(%(MethodName)s_Message) inv_%(methodName)s <- mkPutInverter(); ''' wInverseIndicationMethodTemplate=''' method Action %(methodName)s(%(formals)s); inv_%(methodName)s.mod.put(%(MethodName)s_Message {%(structElements)s}); endmethod''' wInverseIndicationInverseMethodTemplate=''' method ActionValue#(%(MethodName)s_Message) %(methodName)s; let v <- inv_%(methodName)s.inverse.get; return v; endmethod''' def toBsvType(titem, oitem): if oitem and oitem['name'].startswith('Tuple'): titem = oitem if titem.get('params') and len(titem['params']): return '%s#(%s)' % (titem['name'], ','.join([str(toBsvType(p, None)) for p in titem['params']])) elif titem['name'] == 'fixed32': return 'Bit#(32)' else: return titem['name'] def collectElements(mlist, workerfn, name): methods = [] mindex = 0 for item in mlist: if verbose: print('collectEl', item) for p in item['dparams']: print('collectEl/param', p) break sub = { 'dut': util.decapitalize(name), 'Dut': util.capitalize(name), 'methodName': item['dname'], 'MethodName': util.capitalize(item['dname']), 'channelNumber': mindex} paramStructDeclarations = [' %s %s;' % (toBsvType(p['ptype'], p.get('oldtype')), p['pname']) for p in item['dparams']] sub['paramType'] = ', '.join(['%s' % toBsvType(p['ptype'], p.get('oldtype')) for p in item['dparams']]) sub['formals'] = ', '.join(['%s %s' % (toBsvType(p['ptype'], p.get('oldtype')), p['pname']) for p in item['dparams']]) structElements = ['%s: %s' % (p['pname'], p['pname']) for p in item['dparams']] if not item['dparams']: paramStructDeclarations = [' %s %s;' % ('Bit#(32)', 'padding')] structElements = ['padding: 0'] sub['paramStructDeclarations'] = '\n'.join(paramStructDeclarations) sub['structElements'] = ', '.join(structElements) methods.append(workerfn % sub) mindex = mindex + 1 return ''.join(methods) def fixupSubsts(item, suffix): name = item['cname']+suffix dlist = item['cdecls'] mkConnectionMethodRules = [] outputPipes = [] for m in dlist: if verbose: print('fixupSubsts', m) paramsForCall = ['request.%s' % p['pname'] for p in m['dparams']] msubs = {'methodName': m['dname'], 'paramsForCall': ', '.join(paramsForCall)} mkConnectionMethodRules.append(mkConnectionMethodTemplate % msubs) outputPipes.append(' interface %(methodName)s_PipeOut = %(methodName)s_requestAdapter.out;' % msubs) substs = { 'Package': '', 'channelCount': len(dlist), 'Ifc': item['cname'], 'dut': util.decapitalize(name), 'Dut': util.capitalize(name), } if not generateInterfaceDefs: substs['Package'] = item['Package'] + '::' substs['requestOutputPipeInterfaces'] = ''.join( [requestOutputPipeInterfaceTemplate % {'methodName': m['dname'], 'MethodName': util.capitalize(m['dname'])} for m in dlist]) substs['outputPipes'] = '\n'.join(outputPipes) substs['mkConnectionMethodRules'] = ''.join(mkConnectionMethodRules) substs['indicationMethodRules'] = collectElements(dlist, indicationRuleTemplate, name) substs['indicationMethodDecls'] = collectElements(dlist, indicationDeclTemplate, name) substs['indicationMethodAssigns'] = collectElements(dlist, indicationAssignTemplate, name) substs['indicationMethods'] = collectElements(dlist, indicationMethodTemplate, name) substs['indicationInverseMethodDecls'] = collectElements(dlist, indicationInverseDeclTemplate, name) substs['inverseIndicationMethodRules'] = collectElements(dlist, inverseIndicationRuleTemplate, name) substs['inverseIndicationMethods'] = collectElements(dlist, inverseIndicationMethodTemplate, name) substs['inverseIndicationInverseMethods'] = collectElements(dlist, inverseIndicationInverseMethodTemplate, name) substs['indicationInverseConnect'] = collectElements(dlist, indicationInverseConnectTemplate, name) substs['wInverseIndicationMethodRules'] = collectElements(dlist, wInverseIndicationRuleTemplate, name) substs['wInverseIndicationMethods'] = collectElements(dlist, wInverseIndicationMethodTemplate, name) substs['wInverseIndicationInverseMethods'] = collectElements(dlist, wInverseIndicationInverseMethodTemplate, name) substs['requestElements'] = collectElements(dlist, requestStructTemplate, name) substs['methodRules'] = collectElements(dlist, requestRuleTemplate, name) substs['methodDef'] = collectElements(dlist, methodDefTemplate, name) substs['messageSizes'] = collectElements(dlist, messageSizeTemplate, name) return substs def indent(f, indentation): for i in xrange(indentation): f.write(' ') def bemitStructMember(item, f, indentation): if verbose: print('emitSM', item) indent(f, indentation) f.write('%s %s' % (toBsvType(item['ptype'], item.get('oldtype')), item['pname'])) #if hasBitWidth(item['ptype']): # f.write(' : %d' % typeBitWidth(item['ptype'])) f.write(';\n') def bemitStruct(item, name, f, indentation): indent(f, indentation) if (indentation == 0): f.write('typedef ') f.write('struct {\n') for e in item['elements']: bemitStructMember(e, f, indentation+4) indent(f, indentation) f.write('}') if (indentation == 0): f.write(' %s deriving (Bits);' % name) f.write('\n') def bemitType(item, name, f, indentation): indent(f, indentation) tmp = toBsvType(item, None) if re.match('[0-9]+', tmp): if True or verbose: print('bsvgen/bemitType: INFO ignore numeric typedef for', tmp) return if not tmp or tmp[0] == '`' or tmp == 'Empty' or tmp[-2:] == '_P': if True or verbose: print('bsvgen/bemitType: INFO ignore typedef for', tmp) return if (indentation == 0): f.write('typedef ') f.write(tmp) if (indentation == 0): f.write(' %s deriving (Bits);' % name) f.write('\n') def bemitEnum(item, name, f, indentation): indent(f, indentation) if (indentation == 0): f.write('typedef ') f.write('enum %s { ' % name) indent(f, indentation) f.write(', '.join(['%s_%s' % (name, e) for e in item['elements']])) indent(f, indentation) f.write(' }') if (indentation == 0): f.write(' %s deriving (Bits);' % name) f.write('\n') def emitBDef(item, generated_hpp, indentation): if verbose: print('bsvgen/emitBDef:', item) n = item['tname'] td = item['tdtype'] t = td.get('type') if t == 'Enum': bemitEnum(td, n, generated_hpp, indentation) elif t == 'Struct': bemitStruct(td, n, generated_hpp, indentation) elif t == 'Type' or t == None: bemitType(td, n, generated_hpp, indentation) else: print('EMITCD', n, t, td) def generate_bsv(project_dir, noisyFlag, aGenDef, jsondata): global generateInterfaceDefs,verbose verbose = noisyFlag generateInterfaceDefs = aGenDef generatedPackageNames = [] if generateInterfaceDefs: fname = os.path.join(project_dir, 'generatedbsv', 'GeneratedTypes.bsv') if_file = util.createDirAndOpen(fname, 'w') for v in jsondata['globaldecls']: if v['dtype'] == 'TypeDef': if v.get('tparams'): print('Skipping BSV declaration for parameterized type', v['tname']) continue emitBDef(v, if_file, 0) if_file.write('\n') for item in jsondata['interfaces']: if verbose: print('genbsv', item) pname = item['cname'] if pname in generatedPackageNames: continue generatedPackageNames.append(pname) fname = os.path.join(project_dir, 'generatedbsv', '%s.bsv' % pname) bsv_file = util.createDirAndOpen(fname, 'w') bsv_file.write('package %s;\n' % pname) if generateInterfaceDefs: extraImports = ['HostInterface', 'GeneratedTypes'] else: extraImports = [item['Package']] extraImports += [i for i in jsondata['globalimports'] if not i in generatedPackageNames] bsv_file.write(preambleTemplate % {'extraImports' : ''.join(['import %s::*;\n' % pn for pn in extraImports])}) if verbose: print('Writing file ', fname) if generateInterfaceDefs: if_file.write(interfaceDefTemplate % fixupSubsts(item, '')) bsv_file.write(exposedWrapperInterfaceTemplate % fixupSubsts(item, 'Wrapper')) bsv_file.write(exposedProxyInterfaceTemplate % fixupSubsts(item, 'Proxy')) bsv_file.write('endpackage: %s\n' % pname) bsv_file.close() if generateInterfaceDefs: if_file.close() ================================================ FILE: scripts/bsvpreprocess.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2014-2015 Quanta Research Cambridge, Inc # Copyright (c) 2015 Connectal Project # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # from __future__ import print_function import os, sys, re, string import argparse argparser = argparse.ArgumentParser("Preprocess BSV files.") argparser.add_argument('bsvfile', help='BSV files to parse', nargs='+') argparser.add_argument('-D', '--bsvdefine', default=[], help='BSV define', action='append') argparser.add_argument('-I', '--include', help='Specify import/include directories', default=[], action='append') argparser.add_argument('--bsvpath', default=[], help='directories to add to bsc search path', action='append') argparser.add_argument('-v', '--verbose', help='Display verbose information messages', action='store_true') def preprocess(sourcefilename, source, defs, bsvpath): # convert defs to a dict # defs could be a list of symbol or symbol=value if type(defs) == list: d = {} for sym in defs: if '=' in sym: (s, val) = sym.split('=') d[s] = val else: d[sym] = '' defs = d stack = [(True,True)] def nexttok(s): k = re.search('[^A-Za-z0-9~_]', s) if k: sym = s[:k.start()] s = s[k.end():] return (sym, s) else: return (s, '') lines = source.splitlines() outlines = [] noncomment = '' # true if a previous line started a block comment and didn't finish it multilinecomment = False while lines: line = lines[0] lines = lines[1:] cond = stack[-1][0] valid = stack[-1][1] # FIXME if (line.endswith('\\')): noncomment += line[:-1] continue remaining = line comment = '' noncomment = '' if multilinecomment: commentEnd = remaining.find('*/') if commentEnd >= 0: comment += remaining[0:commentEnd+2] remaining = remaining[commentEnd+2:] multilinecomment = False else: comment += remaining remaining = '' while len(remaining): commentStart = remaining.find('/') if commentStart >= 0: noncomment += remaining[0:commentStart] restofline = remaining[commentStart:] if restofline.startswith('/*'): commentEnd = restofline.find('*/') if commentEnd >= 0: comment += restofline[0:commentEnd+2] remaining = restofline[commentEnd+2:] else: comment += restofline remaining = '' multilinecomment = True elif restofline.startswith('//'): comment += remaining remaining = '' else: noncomment += restofline[0] remaining = remaining[1:] else: noncomment += remaining remaining = '' i = noncomment.find('`') if i < 0: if valid: outlines.append(line) else: outlines.append('//SKIPPED %s' % line) continue s = noncomment[i+1:] (tok, s) = nexttok(s) if tok == 'ifdef': (sym, s) = nexttok(s) new_cond = sym in defs new_valid = new_cond and valid #sys.stderr.write('ifdef %s new_cond=%d new_valid=%d cond=%d valid=%d\n' % (sym, new_cond, new_valid, cond, valid)) stack.append((new_cond,new_valid)) elif tok == 'ifndef': (sym, s) = nexttok(s) new_cond = not sym in defs new_valid = valid and new_cond #sys.stderr.write('ifndef %s new_cond=%d new_valid=%d cond=%d valid=%d\n' % (sym, new_cond, new_valid, cond, valid)) stack.append((new_cond,new_valid)) elif tok == 'else': stack.pop() try: valid = stack[-1][1] except: sys.stderr.write('Failed to preprocess %s\n' % sourcefilename) sys.exit(1) new_cond = not cond new_valid = new_cond and valid #sys.stderr.write('else %s new_cond=%d new_valid=%d cond=%d valid=%d\n' % (sym, new_cond, new_valid, cond, valid)) stack.append((new_cond,new_valid)) elif tok == 'elsif': stack.pop() valid = stack[-1][1] (sym, s) = nexttok(s) new_cond = sym in defs new_valid = new_cond and valid stack.append((new_cond,new_valid)) elif tok == 'endif': stack.pop() try: valid = stack[-1][1] except: sys.stderr.write('Failed to preprocess %s\n' % sourcefilename) sys.exit(1) elif tok == 'define': (sym, s) = nexttok(s) if s: defs[sym] = s else: defs[sym] = '' elif tok == 'include': m = re.search('"?([-_A-Za-z0-9.]+)"?', s) if not m: sys.stderr.write('syntax.preprocess %s: could not find file in line {%s}\n' % (sourcefilename, s)) break filename = m.group(1) inc = '' for d in bsvpath: fn = os.path.join(d, filename) if os.path.exists(fn): inc = open(fn).read() break if not inc: sys.stderr.write('syntax.preprocess %s: did not find included file %s in path\n' % (sourcefilename, filename)) outlines.append('//`include "%s"' % filename) lines = inc.splitlines() + lines continue elif tok: while '`' in noncomment: ## must be an undefined variable i = noncomment.find('`') (tok, s) = nexttok(noncomment[i+1:]) #sys.stderr.write('syntax.preprocess %s: preprocessor variable `%s\n' % (sourcefilename, tok)) if tok in defs: val = defs[tok] else: val = '' #sys.stderr.write('sym=%s val=%s\n' % (tok, val)) noncomment = noncomment.replace('`%s' % tok, val) prefix='//SKIPPED ' if not valid else '' outlines.append('//PREPROCESSED: %s' % line) outlines.append(prefix + noncomment + comment) continue else: sys.stderr.write('syntax.preprocess %s: unhandled preprocessor token %s\n' % (sourcefilename, tok)) sys.stderr.write('line: %s\n' % line) assert(tok in ['ifdef', 'ifndef', 'else', 'endif', 'define', '']) outlines.append('//PREPROCESSED: %s' % line) return '%s\n' % '\n'.join(outlines) if __name__=='__main__': options = argparser.parse_args() for bsvfile in options.bsvfile: preprocessed = preprocess(bsvfile, open(bsvfile).read(), options.bsvdefine, options.include + options.bsvpath) print(preprocessed) ================================================ FILE: scripts/cadb ================================================ #!/usr/bin/env python3 # Copyright (c) 2015 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import os, sys, time from adb import adb_commands from adb import common timebound = 5 #scriptdir=os.path.dirname(sys.argv[0]) #sys.path.append(scriptdir) command_list = ['shell', 'push', 'pull', 'root', 'reboot'] if __name__ == '__main__': if len(sys.argv) < 2: print('cadb ') sys.exit(-1) ipaddr = '' args = sys.argv[1:] if args[0] not in command_list: ipaddr = args[0] args = args[1:] if 'RUNPARAM' in os.environ: ipaddr=os.environ['RUNPARAM'] if ipaddr == '': print('cadb: missing address') sys.exit(-1) print('connecting to %s' % ipaddr) starttime = time.clock() count = 0 while True: try: connection = adb_commands.AdbCommands.ConnectDevice(serial=ipaddr) print('connect ok', count, time.clock() - starttime) break except: pass if time.clock() - starttime > timebound: print('cadb: connection attempt timed out') sys.exit(-1) count += 1 try: if args[0] == 'shell': for line in connection.StreamingShell(' '.join(args[1:])): sys.stdout.write(line) elif args[0] == 'push': for filename in args[1:-1]: connection.Push(filename, args[-1]) elif args[0] == 'pull': connection.Pull(args[1], args[2]) elif args[0] == 'root': try: connection.Root() except: pass # connection always fails as adbd reboots... elif args[0] == 'reboot': connection.Reboot() connection.Close() except: print('cadb: operation failed', args[0]) sys.exit(-1) sys.exit(0) ================================================ FILE: scripts/check-timing.py ================================================ #!/usr/bin/env python3 from __future__ import print_function import sys, re failed = 0 for timingreport in sys.argv[1:]: print_lines = 0 for line in open(timingreport): re_no_clock = re.compile('\s*There are (\d+) register/latch pins with no clock(.*)') re_constant_clock = re.compile('\s*There are (\d+) .*constant_clock(.*)') re_violated = re.compile('.*VIOLATED.*-([.0-9]+)') m = re_no_clock.match(line) if m and int(m.group(1)): print('*** no clock pins ***') print(line) failed = 1 m = re_constant_clock.match(line) if m and int(m.group(1)): print('*** constant clock pins ***') print(line) failed = 1 m = re_violated.match(line) if m and float(m.group(1)) >= 0.1: print('*** timing violation ***') print(line[0:-1]) failed = 1 print_lines = 4 continue if print_lines: print(line[0:-1]) print_lines -= 1 if not print_lines: print() if failed: sys.exit(-11) ================================================ FILE: scripts/connectal-make ================================================ #!/bin/sh make CONNECTALDIR=/usr/share/connectal $* ================================================ FILE: scripts/connectal-synth-avalonddr3.tcl ================================================ # Copyright (c) 2015 Connectal Project # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" proc create_altera_de5_ddr3 {} { set core_name {altera_mem_if_ddr3_emif} set core_version {14.0} set ip_name {altera_mem_if_ddr3_emif_wrapper} set params [ dict create ] dict set params MEM_VENDOR "JEDEC" dict set params MEM_FORMAT "UNBUFFERED" dict set params RDIMM_CONFIG 0 dict set params LRDIMM_EXTENDED_CONFIG "0x000000000000000000" dict set params DISCRETE_FLY_BY "true" dict set params DEVICE_DEPTH 1 dict set params MEM_MIRROR_ADDRESSING 0 dict set params MEM_CLK_FREQ_MAX "800.0" dict set params MEM_ROW_ADDR_WIDTH 15 dict set params MEM_COL_ADDR_WIDTH 10 dict set params MEM_DQ_WIDTH 64 dict set params MEM_DQ_PER_DQS 8 dict set params MEM_BANKADDR_WIDTH 3 dict set params MEM_IF_DM_PINS_EN "true" dict set params MEM_IF_DQSN_EN "true" dict set params MEM_NUMBER_OF_DIMMS 1 dict set params MEM_NUMBER_OF_RANKS_PER_DIMM 1 dict set params MEM_NUMBER_OF_RANKS_PER_DEVICE 1 dict set params MEM_RANK_MULTIPLICATION_FACTOR 1 dict set params MEM_CK_WIDTH 1 dict set params MEM_CS_WIDTH 1 dict set params MEM_CLK_EN_WIDTH 1 dict set params ALTMEMPHY_COMPATIBLE_MODE "false" dict set params NEXTGEN "true" dict set params MEM_IF_BOARD_BASE_DELAY 10 dict set params MEM_IF_SIM_VALID_WINDOW 0 dict set params MEM_GUARANTEED_WRITE_INIT "false" dict set params MEM_VERBOSE "true" dict set params PINGPONGPHY_EN "false" dict set params REFRESH_BURST_VALIDATION "false" dict set params MEM_BL "OTF" dict set params MEM_BT "Sequential" dict set params MEM_ASR "Manual" dict set params MEM_SRT "Normal" dict set params MEM_PD "DLL off" dict set params MEM_DRV_STR "RZQ/7" dict set params MEM_DLL_EN "true" dict set params MEM_RTT_NOM "RZQ/6" dict set params MEM_RTT_WR "RZQ/4" dict set params MEM_WTCL 8 dict set params MEM_ATCL "Disabled" dict set params MEM_TCL 11 dict set params MEM_AUTO_LEVELING_MODE "true" dict set params MEM_USER_LEVELING_MODE "Leveling" dict set params MEM_INIT_EN "false" dict set params DAT_DATA_WIDTH 32 dict set params TIMING_TIS 170 dict set params TIMING_TIH 120 dict set params TIMING_TDS 10 dict set params TIMING_TDH 45 dict set params TIMING_TDQSQ 100 dict set params TIMING_TQH "0.38" dict set params TIMING_TDQSCK 225 dict set params TIMING_TDQSCKDS 450 dict set params TIMING_TDQSCKDM 900 dict set params TIMING_TDQSCKDL 1200 dict set params TIMING_TDQSS "0.25" dict set params TIMING_TQSH "0.4" dict set params TIMING_TDSH "0.18" dict set params TIMING_TDSS "0.18" dict set params MEM_TINIT_US 500 dict set params MEM_TMRD_CK 4 dict set params MEM_TRAS_NS "35.0" dict set params MEM_TRCD_NS "13.75" dict set params MEM_TRP_NS "13.75" dict set params MEM_TREFI_US "7.8" dict set params MEM_TRFC_NS "160.0" dict set params CFG_TCCD_NS "2.5" dict set params MEM_TWR_NS "15.0" dict set params MEM_TWTR "6" dict set params MEM_TFAW_NS "30.0" dict set params MEM_TRRD_NS "6.0" dict set params MEM_TRTP_NS "7.5" dict set params RATE "Quarter" dict set params MEM_CLK_FREQ "800.0" dict set params USE_MEM_CLK_FREQ "false" dict set params SYS_INFO_DEVICE_FAMILY "Stratix V" dict set params SPEED_GRADE 2 dict set params PACKAGE_DESKEW "true" dict set params AC_PACKAGE_DESKEW "true" dict set params TIMING_BOARD_MAX_CK_DELAY "1.33" dict set params TIMING_BOARD_MAX_DQS_DELAY "0.61" dict set params TIMING_BOARD_SKEW_CKDQS_DIMM_MIN "0.0" dict set params TIMING_BOARD_SKEW_CKDQS_DIMM_MAX "0.0" dict set params TIMING_BOARD_SKEW_BETWEEN_DIMMS "0.05" dict set params TIMING_BOARD_SKEW_WITHIN_DQS "0.0070" dict set params TIMING_BOARD_SKEW_BETWEEN_DQS "0.09" dict set params TIMING_BOARD_DQ_TO_DQS_SKEW "0.0020" dict set params TIMING_BOARD_AC_SKEW "0.05" dict set params TIMING_BOARD_AC_TO_CK_SKEW "0.012" dict set params REF_CLK_FREQ "50.0" dict set params REF_CLK_FREQ_PARAM_VALID "false" dict set params REF_CLK_FREQ_MIN_PARAM "0.0" dict set params REF_CLK_FREQ_MAX_PARAM "0.0" dict set params PHY_ONLY "false" # dict set params PLL_SHARING_MODE "Master" # dict set params NUM_PLL_SHARING_INTERFACES "1" # dict set params DLL_SHARING_MODE "Master" # dict set params NUM_DLL_SHARING_INTERFACES "1" # dict set params OCT_SHARING_MODE "Master" # dict set params NUM_OCT_SHARING_INTERFACES "1" set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } create_altera_de5_ddr3 ================================================ FILE: scripts/connectal-synth-axichecker.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" puts $boardname set prj_boardname $boardname if [string match "*g2" $boardname] {set prj_boardname [string trimright $boardname "g2"]} connectal_synth_ip axi_protocol_checker 2.0 axi_protocol_checker_0 [list \ CONFIG.ADDR_WIDTH 64 \ CONFIG.DATA_WIDTH 512 \ CONFIG.HAS_WSTRB 1 \ CONFIG.ID_WIDTH 6 \ CONFIG.ARUSER_WIDTH 0 \ CONFIG.AWUSER_WIDTH 0 \ CONFIG.BUSER_WIDTH 0 \ CONFIG.RUSER_WIDTH 0 \ CONFIG.WUSER_WIDTH 0 \ CONFIG.MAX_AR_WAITS 500 \ CONFIG.MAX_AW_WAITS 500 \ CONFIG.MAX_B_WAITS 500 \ CONFIG.MAX_R_WAITS 500 \ CONFIG.MAX_W_WAITS 500 \ ] # create_project -name local_synthesized_ip -in_memory # set_property PART {xcvu9p-flgb2104-2-i} [current_project] # create_ip -name axi_protocol_checker -version 2.0 -vendor xilinx.com -library ip -module_name axi_protocol_checker_0 -dir /home/ubuntu/connectal/out/awsf1/axi_protocol_checker_0 # report_property -file /home/ubuntu/connectal/out/awsf1/axi_protocol_checker_0.properties.log [get_ips axi_protocol_checker_0] ================================================ FILE: scripts/connectal-synth-axiddr3.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" set prj_boardname $boardname if [string match "*g2" $boardname] {set prj_boardname [string trimright $boardname "g2"]} connectal_synth_ip mig_7series 4.0 axiddr3 [list CONFIG.XML_INPUT_FILE "$connectaldir/constraints/xilinx/$prj_boardname-axiddr3.prj" CONFIG.RESET_BOARD_INTERFACE {Custom} CONFIG.MIG_DONT_TOUCH_PARAM {Custom} CONFIG.BOARD_MIG_PARAM {Custom}] ================================================ FILE: scripts/connectal-synth-axidma.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" set prj_boardname $boardname if [string match "*g2" $boardname] {set prj_boardname [string trimright $boardname "g2"]} connectal_synth_ip axi_dma 7.1 axi_dma_0 [list CONFIG.c_sg_include_stscntrl_strm {1} CONFIG.c_m_axi_mm2s_data_width {32} CONFIG.c_m_axi_s2mm_data_width {32} CONFIG.c_mm2s_burst_size {8} CONFIG.c_s2mm_burst_size {8}] ================================================ FILE: scripts/connectal-synth-axieth.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" set prj_boardname $boardname if [string match "*g2" $boardname] {set prj_boardname [string trimright $boardname "g2"]} connectal_synth_ip axi_ethernet 7.0 axi_ethernet_0 [list CONFIG.ETHERNET_BOARD_INTERFACE {sfp_sfp1} CONFIG.DIFFCLK_BOARD_INTERFACE {sfp_mgt_clk} CONFIG.axiliteclkrate {250.0} CONFIG.axisclkrate {250.0} CONFIG.PHY_TYPE {1000BaseX}] ================================================ FILE: scripts/connectal-synth-axiintc.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" puts $boardname set prj_boardname $boardname if [string match "*g2" $boardname] {set prj_boardname [string trimright $boardname "g2"]} connectal_synth_ip axi_intc 4.1 axi_intc_0 [list CONFIG.C_NUM_INTR_INPUTS {16} CONFIG.C_S_AXI_ACLK_FREQ_MHZ {250.0} CONFIG.C_NUM_SW_INTR {0}] ================================================ FILE: scripts/connectal-synth-eth.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" # PMA-Direct Transceiver, No PCS proc create_altera_10gbe_pma {channels} { set core_name {altera_xcvr_native_sv} set core_version {14.0} set ip_name {altera_xcvr_native_sv_wrapper} set params [ dict create ] dict set params tx_enable 1 dict set params rx_enable 1 dict set params enable_std 0 dict set params enable_teng 0 dict set params data_path_select "pma_direct" dict set params channels 4 dict set params bonded_mode "non_bonded" dict set params enable_simple_interface 1 dict set params set_data_rate "10312.5" dict set params pma_direct_width 40 dict set params tx_pma_clk_div 1 dict set params pll_reconfig_enable 0 dict set params pll_external_enable 0 dict set params plls 1 dict set params pll_select 0 dict set params pll_refclk_cnt 1 dict set params gui_pll_reconfig_pll0_pll_type "CMU" dict set params gui_pll_reconfig_pll1_pll_type "CMU" dict set params gui_pll_reconfig_pll2_pll_type "CMU" dict set params gui_pll_reconfig_pll3_pll_type "CMU" dict set params gui_pll_reconfig_pll0_data_rate "1250" dict set params gui_pll_reconfig_pll1_data_rate "1250" dict set params gui_pll_reconfig_pll2_data_rate "1250" dict set params gui_pll_reconfig_pll3_data_rate "1250" dict set params gui_pll_reconfig_pll0_refclk_freq "644.53125 MHz" dict set params gui_pll_reconfig_pll1_refclk_freq "125.0" dict set params gui_pll_reconfig_pll2_refclk_freq "125.0" dict set params gui_pll_reconfig_pll3_refclk_freq "125.0" dict set params gui_pll_reconfig_pll0_refclk_sel 0 dict set params gui_pll_reconfig_pll1_refclk_sel 0 dict set params gui_pll_reconfig_pll2_refclk_sel 0 dict set params gui_pll_reconfig_pll3_refclk_sel 0 dict set params gui_pll_reconfig_pll0_clk_network "x1" dict set params gui_pll_reconfig_pll1_clk_network "x1" dict set params gui_pll_reconfig_pll2_clk_network "x1" dict set params gui_pll_reconfig_pll3_clk_network "x1" dict set params cdr_reconfig_enable 0 dict set params cdr_refclk_cnt 1 dict set params cdr_refclk_select 0 dict set params set_cdr_refclk_freq "644.53125 MHz" dict set params rx_ppm_detect_threshold 100 dict set params enable_port_tx_pma_qpipullup 0 dict set params enable_port_tx_pma_qpipulldn 0 dict set params enable_port_tx_pma_txdetectrx 0 dict set params enable_port_tx_pma_rxfound 0 dict set params enable_port_tx_pma_pclk 0 dict set params enable_port_rx_pma_qpipulldn 0 dict set params enable_port_rx_pma_clkout 1 dict set params enable_port_rx_pma_pclk 0 dict set params enable_port_rx_is_lockedtodata 1 dict set params enable_port_rx_is_lockedtoref 1 dict set params enable_ports_rx_manual_cdr_mode 0 dict set params rx_clkslip_enable 0 dict set params enable_port_rx_signaldetect 0 dict set params enable_port_rx_seriallpbken 1 dict set params std_protocol_hint "basic" dict set params std_pcs_pma_width 10 dict set params std_low_latency_bypass_enable 0 dict set params std_tx_pcfifo_mode "low_latency" dict set params std_rx_pcfifo_mode "low_latency" dict set params enable_port_tx_std_pcfifo_full 0 dict set params enable_port_tx_std_pcfifo_empty 0 dict set params enable_port_rx_std_pcfifo_full 0 dict set params enable_port_rx_std_pcfifo_empty 0 dict set params std_rx_byte_order_enable 0 dict set params std_rx_byte_order_mode "manual" dict set params std_rx_byte_order_symbol_count 1 dict set params std_rx_byte_order_pattern 0 dict set params std_rx_byte_order_pad 0 dict set params enable_port_rx_std_byteorder_ena 0 dict set params enable_port_rx_std_byteorder_flag 0 dict set params std_tx_byte_ser_enable 0 dict set params std_rx_byte_deser_enable 0 dict set params std_tx_8b10b_enable 0 dict set params std_tx_8b10b_disp_ctrl_enable 0 dict set params std_rx_8b10b_enable 0 dict set params std_rx_rmfifo_enable 0 dict set params std_rx_rmfifo_pattern_p 00000 dict set params std_rx_rmfifo_pattern_n 00000 dict set params enable_port_rx_std_rmfifo_full 0 dict set params enable_port_rx_std_rmfifo_empty 0 dict set params std_tx_bitslip_enable 0 dict set params enable_port_tx_std_bitslipboundarysel 0 dict set params std_rx_word_aligner_mode "bit_slip" dict set params std_rx_word_aligner_pattern_len 7 dict set params std_rx_word_aligner_pattern 0000000000 dict set params std_rx_word_aligner_rknumber 3 dict set params std_rx_word_aligner_renumber 3 dict set params std_rx_word_aligner_rgnumber 3 dict set params std_rx_run_length_val 0 dict set params enable_port_rx_std_wa_patternalign 0 dict set params enable_port_rx_std_wa_a1a2size 0 dict set params enable_port_rx_std_bitslipboundarysel 0 dict set params enable_port_rx_std_bitslip 0 dict set params enable_port_rx_std_runlength_err 0 dict set params std_tx_bitrev_enable 0 dict set params std_rx_bitrev_enable 0 dict set params std_tx_byterev_enable 0 dict set params std_rx_byterev_enable 0 dict set params std_tx_polinv_enable 0 dict set params std_rx_polinv_enable 0 dict set params enable_port_rx_std_bitrev_ena 0 dict set params enable_port_rx_std_byterev_ena 0 dict set params enable_port_tx_std_polinv 0 dict set params enable_port_rx_std_polinv 0 dict set params enable_port_tx_std_elecidle 0 dict set params enable_port_rx_std_signaldetect 0 dict set params enable_port_rx_std_prbs_status 0 dict set params teng_protocol_hint "basic" dict set params teng_pcs_pma_width 40 dict set params teng_pld_pcs_width 40 dict set params teng_txfifo_mode "phase_comp" dict set params teng_txfifo_full 31 dict set params teng_txfifo_empty 0 dict set params teng_txfifo_pfull 23 dict set params teng_txfifo_pempty 2 dict set params enable_port_tx_10g_fifo_full 0 dict set params enable_port_tx_10g_fifo_pfull 0 dict set params enable_port_tx_10g_fifo_empty 0 dict set params enable_port_tx_10g_fifo_pempty 0 dict set params enable_port_tx_10g_fifo_del 0 dict set params enable_port_tx_10g_fifo_insert 0 dict set params teng_rxfifo_mode "phase_comp" dict set params teng_rxfifo_full 31 dict set params teng_rxfifo_empty 0 dict set params teng_rxfifo_pfull 23 dict set params teng_rxfifo_pempty 7 dict set params teng_rxfifo_align_del 0 dict set params teng_rxfifo_control_del 0 dict set params enable_port_rx_10g_data_valid 0 dict set params enable_port_rx_10g_fifo_full 0 dict set params enable_port_rx_10g_fifo_pfull 0 dict set params enable_port_rx_10g_fifo_empty 0 dict set params enable_port_rx_10g_fifo_pempty 0 dict set params enable_port_rx_10g_fifo_del 0 dict set params enable_port_rx_10g_fifo_insert 0 dict set params enable_port_rx_10g_fifo_rd_en 0 dict set params enable_port_rx_10g_fifo_align_val 0 dict set params enable_port_rx_10g_fifo_align_clr 0 dict set params enable_port_rx_10g_fifo_align_en 0 dict set params enable_port_rx_10g_clk33out 0 dict set params teng_tx_frmgen_user_length 2048 dict set params teng_tx_frmgen_burst_enable 0 dict set params enable_port_tx_10g_frame 0 dict set params enable_port_tx_10g_frame_diag_status 0 dict set params enable_port_tx_10g_frame_burst_en 0 dict set params teng_rx_frmsync_user_length 2048 dict set params enable_port_rx_10g_frame 0 dict set params enable_port_rx_10g_frame_lock 0 dict set params enable_port_rx_10g_frame_mfrm_err 0 dict set params enable_port_rx_10g_frame_sync_err 0 dict set params enable_port_rx_10g_frame_pyld_ins 0 dict set params enable_port_rx_10g_frame_skip_ins 0 dict set params enable_port_rx_10g_frame_skip_err 0 dict set params enable_port_rx_10g_frame_diag_err 0 dict set params enable_port_rx_10g_frame_diag_status 0 dict set params teng_tx_sh_err 0 dict set params enable_port_rx_10g_crc32_err 0 dict set params enable_port_rx_10g_highber 0 dict set params enable_port_rx_10g_highber_clr_cnt 0 dict set params enable_port_rx_10g_clr_errblk_count 0 dict set params teng_tx_scram_user_seed 000000000000000 dict set params enable_port_rx_10g_descram_err 0 dict set params enable_port_rx_10g_blk_lock 0 dict set params enable_port_rx_10g_blk_sh_err 0 dict set params teng_tx_polinv_enable 0 dict set params teng_tx_bitslip_enable 0 dict set params teng_rx_polinv_enable 0 dict set params teng_rx_bitslip_enable 0 dict set params enable_port_tx_10g_bitslip 0 dict set params enable_port_rx_10g_bitslip 0 dict set params enable_port_rx_teng_prbs_status 0 set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } proc create_xcvr_reset {channels} { set core_name {altera_xcvr_reset_control} set core_version {14.0} set ip_name {altera_xcvr_reset_control_wrapper} dict set params CHANNELS $channels dict set params PLLS 4 dict set params SYS_CLK_IN_MHZ 125 dict set params SYNCHRONIZE_RESET 1 dict set params REDUCED_SIM_TIME 1 dict set params TX_PLL_ENABLE 1 dict set params T_PLL_POWERDOWN 1000 dict set params SYNCHRONIZE_PLL_RESET 0 dict set params TX_ENABLE 1 dict set params TX_PER_CHANNEL 0 dict set params T_TX_DIGITALRESET 20 dict set params T_PLL_LOCK_HYST 0 dict set params RX_ENABLE 1 dict set params RX_PER_CHANNEL 0 dict set params T_RX_ANALOGRESET 40 dict set params T_RX_DIGITALRESET 4000 set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } if {$NUMBER_OF_10G_PORTS != ""} { set v [expr "$NUMBER_OF_10G_PORTS * 2"] create_altera_10gbe_pma $NUMBER_OF_10G_PORTS create_xcvr_reconfig alt_xcvr_reconfig 14.0 altera_xgbe_pma_reconfig_wrapper $v create_xcvr_reset $NUMBER_OF_10G_PORTS } ================================================ FILE: scripts/connectal-synth-ila.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" # for monitoring the slave connection to the portal connectal_synth_ip ila 6.2 ila_connectal_1 [list CONFIG.C_PROBE12_WIDTH {16} CONFIG.C_PROBE11_WIDTH {16} CONFIG.C_PROBE10_WIDTH {32} CONFIG.C_PROBE7_WIDTH {32} CONFIG.C_PROBE4_WIDTH {32} CONFIG.C_PROBE1_WIDTH {32} CONFIG.C_DATA_DEPTH {4096} CONFIG.C_NUM_OF_PROBES {14} CONFIG.C_EN_STRG_QUAL {1} CONFIG.C_PROBE7_MU_CNT {2} CONFIG.C_PROBE6_MU_CNT {2} CONFIG.C_PROBE5_MU_CNT {2} CONFIG.C_PROBE4_MU_CNT {2} CONFIG.C_PROBE3_MU_CNT {2} CONFIG.C_PROBE2_MU_CNT {2} CONFIG.C_PROBE1_MU_CNT {2} CONFIG.C_PROBE0_MU_CNT {2} CONFIG.ALL_PROBE_SAME_MU_CNT {2}] # for monitoring the memory master connection from the portal, including 19 bit aruser and awuser for AwsF1 connectal_synth_ip ila 6.2 ila_connectal_2 [list \ CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ CONFIG.C_DATA_DEPTH {4096} \ CONFIG.C_EN_STRG_QUAL {1} \ CONFIG.C_NUM_OF_PROBES {25} \ CONFIG.C_PROBE0_MU_CNT {2} \ CONFIG.C_PROBE1_MU_CNT {2} \ CONFIG.C_PROBE1_WIDTH {64} \ CONFIG.C_PROBE2_MU_CNT {2} \ CONFIG.C_PROBE3_MU_CNT {2} \ CONFIG.C_PROBE4_MU_CNT {2} \ CONFIG.C_PROBE4_WIDTH {64} \ CONFIG.C_PROBE5_MU_CNT {2} \ CONFIG.C_PROBE6_MU_CNT {2} \ CONFIG.C_PROBE7_MU_CNT {2} \ CONFIG.C_PROBE7_WIDTH {512} \ CONFIG.C_PROBE10_WIDTH {512} \ CONFIG.C_PROBE12_WIDTH {64} \ CONFIG.C_PROBE13_WIDTH {19} \ CONFIG.C_PROBE14_WIDTH {19} \ CONFIG.C_PROBE15_WIDTH {8} \ CONFIG.C_PROBE16_WIDTH {8} \ CONFIG.C_PROBE17_WIDTH {3} \ CONFIG.C_PROBE18_WIDTH {3} \ CONFIG.C_PROBE19_WIDTH {16} \ CONFIG.C_PROBE20_WIDTH {16} \ CONFIG.C_PROBE21_WIDTH {16} \ CONFIG.C_PROBE22_WIDTH {2} \ CONFIG.C_PROBE23_WIDTH {1} \ CONFIG.C_PROBE24_WIDTH {1} \ ] connectal_synth_ip ila 6.2 ila_connectal_3 [list \ CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ CONFIG.C_DATA_DEPTH {4096} \ CONFIG.C_EN_STRG_QUAL {1} \ CONFIG.C_NUM_OF_PROBES {26} \ CONFIG.C_PROBE0_MU_CNT {2} \ CONFIG.C_PROBE1_MU_CNT {2} \ CONFIG.C_PROBE1_WIDTH {64} \ CONFIG.C_PROBE2_MU_CNT {2} \ CONFIG.C_PROBE3_MU_CNT {2} \ CONFIG.C_PROBE4_MU_CNT {2} \ CONFIG.C_PROBE4_WIDTH {64} \ CONFIG.C_PROBE5_MU_CNT {2} \ CONFIG.C_PROBE6_MU_CNT {2} \ CONFIG.C_PROBE7_MU_CNT {2} \ CONFIG.C_PROBE7_WIDTH {512} \ CONFIG.C_PROBE10_WIDTH {512} \ CONFIG.C_PROBE12_WIDTH {64} \ CONFIG.C_PROBE13_WIDTH {19} \ CONFIG.C_PROBE14_WIDTH {19} \ CONFIG.C_PROBE15_WIDTH {8} \ CONFIG.C_PROBE16_WIDTH {8} \ CONFIG.C_PROBE17_WIDTH {3} \ CONFIG.C_PROBE18_WIDTH {3} \ CONFIG.C_PROBE19_WIDTH {16} \ CONFIG.C_PROBE20_WIDTH {16} \ CONFIG.C_PROBE21_WIDTH {16} \ CONFIG.C_PROBE22_WIDTH {2} \ CONFIG.C_PROBE23_WIDTH {1} \ CONFIG.C_PROBE24_WIDTH {1} \ CONFIG.C_PROBE25_WIDTH {160} \ ] ================================================ FILE: scripts/connectal-synth-ip.tcl ================================================ # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. set scriptsdir [file dirname [info script] ] source "$scriptsdir/../../fpgamake/tcl/ipcore.tcl" # Altera Specific proc create_xcvr_reconfig {core_name core_version ip_name n_interface} { set params [ dict create ] dict set params number_of_reconfig_interfaces $n_interface set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } fpgamake_altera_ipcore $core_name $core_version $ip_name QUARTUS_SYNTH $component_parameters } proc connectal_synth_ip {core_name core_version ip_name params} { fpgamake_ipcore $core_name $core_version $ip_name $params } proc connectal_altera_synth_ip {core_name core_version ip_name params} { fpgamake_altera_ipcore $core_name $core_version $ip_name QUARTUS_SYNTH $params } proc connectal_altera_simu_ip {core_name core_version ip_name params} { fpgamake_altera_ipcore $core_name $core_version $ip_name SIM_VERILOG $params } ================================================ FILE: scripts/connectal-synth-pcie-rp.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" source "$scriptsdir/../../fpgamake/tcl/ipcore.tcl" if {$need_pcie == "x7_gen2x8"} { connectal_synth_ip pcie_7x 3.0 pcie_7x_rp [list CONFIG.Device_Port_Type {Root_Port_of_PCI_Express_Root_Complex} CONFIG.Maximum_Link_Width {X8} CONFIG.Link_Speed {5.0_GT/s} CONFIG.PCIe_Cap_Slot_Implemented {true} CONFIG.Xlnx_Ref_Board {VC707} CONFIG.en_ext_pipe_interface {true}] } if {$need_pcie == "x7_gen3x8"} { if {[version -short] >= "2015.3"} { set pcieversion {4.1} } elseif {[version -short] >= "2015.2"} { set pcieversion {4.0} } else { set pcieversion {3.0} } set maxlinkwidth {X8} connectal_synth_ip pcie3_7x $pcieversion pcie3_7x_rp [list CONFIG.device_port_type {Root_Port_of_PCI_Express_Root_Complex} CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} CONFIG.axisten_if_enable_client_tag {false} CONFIG.AXISTEN_IF_RC_STRADDLE {false} CONFIG.pf0_bar0_size {8} CONFIG.PF0_DEV_CAP2_TPH_COMPLETER_SUPPORT {true} CONFIG.pf0_dsn_enabled {true} CONFIG.mode_selection {Advanced} CONFIG.pipe_mode_sim {Enable_External_PIPE_Interface} CONFIG.en_ext_clk {false} CONFIG.shared_logic_in_core {true} CONFIG.pcie_blk_locn {X0Y0} CONFIG.tandem_mode {None} CONFIG.axisten_if_width {256_bit} CONFIG.PF0_DEVICE_ID {7138} CONFIG.pf0_class_code_base {06} CONFIG.PF0_CLASS_CODE {068000} CONFIG.pf0_base_class_menu {Bridge_device} CONFIG.pf0_sub_class_interface_menu {InfiniBand_to_PCI_host_bridge} CONFIG.PF1_DEVICE_ID {7011} CONFIG.pf1_class_code_base {06} CONFIG.PF1_CLASS_CODE {068000} CONFIG.pf1_base_class_menu {Bridge_device} CONFIG.pf1_sub_class_interface_menu {InfiniBand_to_PCI_host_bridge} CONFIG.pf0_bar0_type {Memory} CONFIG.pf0_bar1_type {N/A} CONFIG.pf0_bar2_type {N/A} CONFIG.pf0_bar3_type {N/A} CONFIG.pf0_bar4_type {N/A} CONFIG.pf0_bar5_type {N/A} CONFIG.pf1_bar0_type {N/A} CONFIG.pf1_bar1_type {N/A} CONFIG.pf1_bar2_type {N/A} CONFIG.pf1_bar3_type {N/A} CONFIG.pf1_bar4_type {N/A} CONFIG.pf1_bar5_type {N/A} CONFIG.pf0_sriov_bar0_type {Memory} CONFIG.pf0_sriov_bar1_type {N/A} CONFIG.pf0_sriov_bar2_type {N/A} CONFIG.pf0_sriov_bar3_type {N/A} CONFIG.pf0_sriov_bar4_type {N/A} CONFIG.pf0_sriov_bar5_type {N/A} CONFIG.pf1_sriov_bar0_type {Memory} CONFIG.pf1_sriov_bar1_type {N/A} CONFIG.pf1_sriov_bar2_type {N/A} CONFIG.pf1_sriov_bar3_type {N/A} CONFIG.pf1_sriov_bar4_type {N/A} CONFIG.pf1_sriov_bar5_type {N/A} CONFIG.silicon_rev {Production} CONFIG.pipe_sim {false} CONFIG.axisten_freq {250} CONFIG.aspm_support {No_ASPM} CONFIG.en_ext_pipe_interface {true}] } ================================================ FILE: scripts/connectal-synth-pcie.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" source "$scriptsdir/../../fpgamake/tcl/ipcore.tcl" if {"$XILINX" == "1"} { set x7_pcie_version 2.1 if {[version -short] == "2013.2"} { set x7_pcieversion {2.1} } if {[version -short] >= "2015.1"} { set x7_pcieversion {3.1} } if {[version -short] >= "2015.3"} { set x7_pcieversion {3.2} } if {[version -short] >= "2016.1"} { set x7_pcieversion {3.3} } } if {$need_pcie == "x7_gen1x8"} { set maxlinkwidth {X8} if {$boardname == {zc706}} { set maxlinkwidth {X4} } if {$boardname == {ac701}} { set maxlinkwidth {X4} } ## ## MSIX Table and PBA offset here is multiplied by 8, so 0x200 -> 4096 connectal_synth_ip pcie_7x $x7_pcieversion pcie_7x_0 [list CONFIG.mode_selection {Advanced} CONFIG.ASPM_Optionality {true} CONFIG.Disable_Tx_ASPM_L0s {true} CONFIG.Buf_Opt_BMA {true} CONFIG.Bar0_64bit {true} CONFIG.Bar0_Size {16} CONFIG.Bar0_Scale {Kilobytes} CONFIG.Bar2_64bit {true} CONFIG.Bar2_Enabled {true} CONFIG.Bar2_Scale {Megabytes} CONFIG.Bar2_Size {1} CONFIG.Base_Class_Menu {Memory_controller} CONFIG.Device_ID {c100} CONFIG.IntX_Generation {false} CONFIG.MSI_Enabled {false} CONFIG.MSIx_Enabled {true} CONFIG.MSIx_PBA_Offset {1f0} CONFIG.MSIx_Table_Offset {200} CONFIG.MSIx_Table_Size {10} CONFIG.Maximum_Link_Width $maxlinkwidth CONFIG.Subsystem_ID {a705} CONFIG.Subsystem_Vendor_ID {1be7} CONFIG.Use_Class_Code_Lookup_Assistant {false} CONFIG.Vendor_ID {1be7} ] } if {$need_pcie == "x7_gen2x8"} { set maxlinkwidth "X$PcieLanes" set maxinterfacebits [expr 16 * $PcieLanes] set maxinterfacewidth "${maxinterfacebits}_bit" set linkspeed {5.0_GT/s} ## MSIX Table and PBA offset here is multiplied by 8, so 0x200 -> 4096 connectal_synth_ip pcie_7x $x7_pcieversion pcie2_7x_0 [list CONFIG.mode_selection {Advanced} CONFIG.ASPM_Optionality {true} CONFIG.Disable_Tx_ASPM_L0s {true} CONFIG.Buf_Opt_BMA {true} CONFIG.Bar0_64bit {true} CONFIG.Bar0_Size {16} CONFIG.Bar0_Scale {Kilobytes} CONFIG.Bar2_64bit {true} CONFIG.Bar2_Enabled {true} CONFIG.Bar2_Scale {Megabytes} CONFIG.Bar2_Size {1} CONFIG.Base_Class_Menu {Memory_controller} CONFIG.Device_ID {c100} CONFIG.IntX_Generation {false} CONFIG.MSI_Enabled {false} CONFIG.MSIx_Enabled {true} CONFIG.MSIx_PBA_Offset {1f0} CONFIG.MSIx_Table_Offset {200} CONFIG.MSIx_Table_Size {10} CONFIG.Maximum_Link_Width $maxlinkwidth CONFIG.Subsystem_ID {a705} CONFIG.Subsystem_Vendor_ID {1be7} CONFIG.Use_Class_Code_Lookup_Assistant {false} CONFIG.Vendor_ID {1be7} CONFIG.Link_Speed $linkspeed CONFIG.Interface_Width $maxinterfacewidth CONFIG.en_ext_clk {false} CONFIG.PCIe_Debug_Ports {false} CONFIG.shared_logic_in_core {true} \ CONFIG.VC_Cap_Enabled {true} \ CONFIG.AER_Enabled {true} CONFIG.AER_Multiheader {true} CONFIG.AER_Permit_Root_Error_Update {true} CONFIG.AER_Completion_Timeout {true} CONFIG.AER_Uncorrectable_Internal_Error {true} CONFIG.AER_MC_Blocked_TLP {true} CONFIG.AER_Receiver_Overflow {true} CONFIG.AER_TLP_Prefix_Blocked {true} CONFIG.Optional_Error_Support {059400}] } if {$need_pcie == "x7_gen3x8"} { if {[version -short] >= "2017.1"} { set x7_pcieversion {4.3} } set maxlinkwidth {X8} connectal_synth_ip pcie3_7x $x7_pcieversion pcie3_7x_0 [list \ CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \ CONFIG.TL_PF_ENABLE_REG {false} CONFIG.vendor_id {1be7} CONFIG.PF0_DEVICE_ID {c100} \ CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1be7} CONFIG.PF0_SUBSYSTEM_ID {a705} \ CONFIG.PF0_Use_Class_Code_Lookup_Assistant {false} CONFIG.pf0_base_class_menu \ {Memory_controller} CONFIG.pf0_bar0_64bit {true} CONFIG.pf0_bar0_size {16} \ CONFIG.pf0_bar2_enabled {true} CONFIG.pf0_bar2_64bit {true} CONFIG.pf0_bar2_scale \ {Megabytes} CONFIG.pf0_bar2_size {1} CONFIG.PF0_INTERRUPT_PIN {NONE} \ CONFIG.pf0_msi_enabled {false} CONFIG.pf0_msix_enabled {true} \ CONFIG.PF0_MSIX_CAP_TABLE_SIZE {010} CONFIG.PF0_MSIX_CAP_TABLE_OFFSET {00001000} \ CONFIG.PF0_MSIX_CAP_PBA_OFFSET {00000f80} CONFIG.axisten_if_width {256_bit} \ CONFIG.AXISTEN_IF_RC_STRADDLE {false} CONFIG.AXISTEN_IF_ENABLE_CLIENT_TAG {false} \ CONFIG.cfg_ctl_if {true} CONFIG.cfg_ext_if {false} CONFIG.cfg_fc_if {false} \ CONFIG.cfg_mgmt_if {false} CONFIG.cfg_status_if {true} CONFIG.cfg_tx_msg_if \ {false} CONFIG.en_ext_clk {false} CONFIG.axisten_freq {250} \ CONFIG.PF0_PM_CAP_SUPP_D1_STATE {false} CONFIG.pf0_dsn_enabled {true} \ CONFIG.mode_selection {Advanced} CONFIG.pcie_blk_locn {X0Y1} \ CONFIG.per_func_status_if {false} CONFIG.en_ext_clk {false} CONFIG.rcv_msg_if \ {false} CONFIG.tx_fc_if {false} CONFIG.shared_logic_in_core {true} \ CONFIG.en_msi_per_vec_masking {false} \ CONFIG.pf0_vc_cap_enabled {true} ] # add the following to enable PF1: # CONFIG.TL_PF_ENABLE_REG {true} CONFIG.PF1_DEVICE_ID {c100} \ # CONFIG.pf1_bar0_64bit {true} CONFIG.pf1_bar0_size {16} \ # CONFIG.pf1_bar2_enabled {true} CONFIG.pf1_bar2_64bit {true} \ # CONFIG.pf1_bar2_scale {Megabytes} CONFIG.pf1_bar2_size {1} \ # CONFIG.pf1_msix_enabled {true} CONFIG.PF1_MSIX_CAP_TABLE_OFFSET \ # {00000400} CONFIG.PF1_MSIX_CAP_PBA_OFFSET {00000500} \ # CONFIG.pf1_dsn_enabled {true} CONFIG.pf1_bar0_enabled {true} \ # CONFIG.pf1_bar0_type {Memory} CONFIG.pf1_bar0_scale {Kilobytes} \ # CONFIG.pf1_bar2_type {Memory} CONFIG.pf1_bar2_size {1} \ # CONFIG.PF1_MSIX_CAP_TABLE_SIZE {010} \ # CONFIG.PF1_MSIX_CAP_TABLE_OFFSET {00000200} \ # CONFIG.PF1_MSIX_CAP_PBA_OFFSET {000001f0} \ } if {$need_pcie == "xu_gen3x8"} { if {[version -short] >= "2017.1"} { set ultrascale_pcieversion {4.4} } elseif {[version -short] >= "2016.2"} { set ultrascale_pcieversion {4.2} } set maxlinkwidth {X8} connectal_synth_ip pcie3_ultrascale $ultrascale_pcieversion pcie3_ultrascale_0 [list \ CONFIG.PF0_DEVICE_ID {c100} \ CONFIG.PF0_MSIX_CAP_PBA_BIR {BAR_1:0} \ CONFIG.PF0_MSIX_CAP_PBA_OFFSET {00000f80} \ CONFIG.PF0_MSIX_CAP_TABLE_BIR {BAR_1:0} \ CONFIG.PF0_MSIX_CAP_TABLE_OFFSET {00001000} \ CONFIG.PF0_MSIX_CAP_TABLE_SIZE {16} \ CONFIG.PF0_SUBSYSTEM_ID {a705} \ CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1be7} \ CONFIG.PF1_DEVICE_ID {8011} \ CONFIG.PF1_MSIX_CAP_PBA_BIR {BAR_0} \ CONFIG.PF1_MSIX_CAP_TABLE_BIR {BAR_0} \ CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \ CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \ CONFIG.aspm_support {No_ASPM} \ CONFIG.axisten_freq {250} \ CONFIG.axisten_if_width {256_bit} \ CONFIG.coreclk_freq {250} \ CONFIG.mode_selection {Advanced} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_scale {Kilobytes} \ CONFIG.pf0_bar0_size {16} \ CONFIG.pf0_bar2_enabled {true} \ CONFIG.pf0_bar2_scale {Megabytes} \ CONFIG.pf0_bar2_size {1} \ CONFIG.pf0_bar2_type {Memory} \ CONFIG.pf0_dev_cap_max_payload {1024_bytes} \ CONFIG.pf0_dsn_enabled {true} \ CONFIG.pf0_msix_enabled {true} \ CONFIG.plltype {QPLL1} \ CONFIG.vendor_id {1be7} \ CONFIG.xlnx_ref_board {VCU108} \ CONFIG.AXISTEN_IF_RC_STRADDLE {false} ] # add the following to enable PF1: # CONFIG.TL_PF_ENABLE_REG {true} CONFIG.PF1_DEVICE_ID {c100} \ # CONFIG.pf1_bar0_64bit {true} CONFIG.pf1_bar0_size {16} \ # CONFIG.pf1_bar2_enabled {true} CONFIG.pf1_bar2_64bit {true} \ # CONFIG.pf1_bar2_scale {Megabytes} CONFIG.pf1_bar2_size {1} \ # CONFIG.pf1_msix_enabled {true} CONFIG.PF1_MSIX_CAP_TABLE_OFFSET \ # {00000400} CONFIG.PF1_MSIX_CAP_PBA_OFFSET {00000500} \ # CONFIG.pf1_dsn_enabled {true} CONFIG.pf1_bar0_enabled {true} \ # CONFIG.pf1_bar0_type {Memory} CONFIG.pf1_bar0_scale {Kilobytes} \ # CONFIG.pf1_bar2_type {Memory} CONFIG.pf1_bar2_size {1} \ # CONFIG.PF1_MSIX_CAP_TABLE_SIZE {010} \ # CONFIG.PF1_MSIX_CAP_TABLE_OFFSET {00000200} \ # CONFIG.PF1_MSIX_CAP_PBA_OFFSET {000001f0} \ } if {$need_pcie == "xuplus_gen3x8"} { if {[version -short] >= "2017.4"} { set ultrascale_pcieversion {1.3} } set maxlinkwidth $PcieLanes connectal_synth_ip pcie4_uscale_plus $ultrascale_pcieversion pcie_uscale_plus_0 \ [list \ CONFIG.PF0_DEVICE_ID {c100} \ CONFIG.PF0_MSIX_CAP_PBA_BIR {BAR_1:0} \ CONFIG.PF0_MSIX_CAP_PBA_OFFSET {00000f80} \ CONFIG.PF0_MSIX_CAP_TABLE_BIR {BAR_1:0} \ CONFIG.PF0_MSIX_CAP_TABLE_OFFSET {00001000} \ CONFIG.PF0_MSIX_CAP_TABLE_SIZE {16} \ CONFIG.PF0_SUBSYSTEM_ID {a705} \ CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1be7} \ CONFIG.PF1_DEVICE_ID {8011} \ CONFIG.MSI_X_OPTIONS {MSI-X_External} \ CONFIG.PF1_MSIX_CAP_PBA_BIR {BAR_0} \ CONFIG.PF1_MSIX_CAP_TABLE_BIR {BAR_0} \ CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \ CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \ CONFIG.aspm_support {No_ASPM} \ CONFIG.axisten_freq {250} \ CONFIG.axisten_if_width {256_bit} \ CONFIG.coreclk_freq {250} \ CONFIG.mode_selection {Advanced} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_scale {Kilobytes} \ CONFIG.pf0_bar0_size {16} \ CONFIG.pf0_bar2_enabled {true} \ CONFIG.pf0_bar2_scale {Megabytes} \ CONFIG.pf0_bar2_size {1} \ CONFIG.pf0_bar2_type {Memory} \ CONFIG.pf0_dev_cap_max_payload {1024_bytes} \ CONFIG.pf0_dsn_enabled {true} \ CONFIG.pf0_msix_enabled {true} \ CONFIG.plltype {QPLL1} \ CONFIG.vendor_id {1be7} \ CONFIG.xlnx_ref_board {VCU118} \ CONFIG.AXISTEN_IF_RC_STRADDLE {false} \ CONFIG.extended_tag_field {false} \ CONFIG.axisten_if_enable_client_tag {true} ] } proc create_pcie_sv_hip_ast {mode} { global boardname set pcieversion {2.1} set maxlinkwidth {x8} set core_name {altera_pcie_sv_hip_ast} set core_version {14.0} set ip_name {altera_pcie_sv_hip_ast_wrapper} set vendor_id {0x1be7} set device_id {0xc100} set class_code {0xde5000} set params [ dict create ] dict set params lane_mask_hwtcl $maxlinkwidth dict set params gen123_lane_rate_mode_hwtcl "Gen2 (5.0 Gbps)" dict set params port_type_hwtcl "Native endpoint" dict set params pcie_spec_version_hwtcl $pcieversion dict set params ast_width_hwtcl "Avalon-ST 128-bit" dict set params rxbuffer_rxreq_hwtcl "Low" dict set params pll_refclk_freq_hwtcl "100 MHz" dict set params set_pld_clk_x1_625MHz_hwtcl 0 # use_rx_be_hwtcl is a deprecated signal dict set params use_rx_st_be_hwtcl 1 dict set params use_ast_parity 0 dict set params multiple_packets_per_cycle_hwtcl 0 dict set params in_cvp_mode_hwtcl 0 dict set params use_tx_cons_cred_sel_hwtcl 0 dict set params use_config_bypass_hwtcl 0 dict set params hip_reconfig_hwtcl 0 dict set params hip_tag_checking_hwtcl 1 dict set params enable_power_on_rst_pulse_hwtcl 0 dict set params bar0_type_hwtcl 1 dict set params bar0_size_mask_hwtcl 14 dict set params bar0_io_space_hwtcl "Disabled" dict set params bar0_64bit_mem_space_hwtcl "Enabled" dict set params bar0_prefetchable_hwtcl "Disabled" dict set params bar1_type_hwtcl 0 dict set params bar1_size_mask_hwtcl 0 dict set params bar1_io_space_hwtcl "Disabled" dict set params bar1_prefetchable_hwtcl "Disabled" dict set params bar2_type_hwtcl 1 dict set params bar2_size_mask_hwtcl 20 dict set params bar2_io_space_hwtcl "Disabled" dict set params bar2_64bit_mem_space_hwtcl "Enabled" dict set params bar2_prefetchable_hwtcl "Disabled" dict set params bar3_type_hwtcl 0 dict set params bar3_size_mask_hwtcl 0 dict set params bar3_io_space_hwtcl "Disabled" dict set params bar3_prefetchable_hwtcl "Disabled" dict set params bar4_size_mask_hwtcl 0 dict set params bar4_io_space_hwtcl "Disabled" dict set params bar4_64bit_mem_space_hwtcl "Disabled" dict set params bar4_prefetchable_hwtcl "Disabled" dict set params bar5_size_mask_hwtcl 0 dict set params bar5_io_space_hwtcl "Disabled" dict set params bar5_prefetchable_hwtcl "Disabled" dict set params expansion_base_address_register_hwtcl 0 dict set params io_window_addr_width_hwtcl 0 dict set params prefetchable_mem_window_addr_width_hwtcl 0 dict set params vendor_id_hwtcl $vendor_id dict set params device_id_hwtcl $device_id dict set params revision_id_hwtcl 1 dict set params class_code_hwtcl $class_code dict set params subsystem_vendor_id_hwtcl $vendor_id dict set params subsystem_device_id_hwtcl $device_id dict set params max_payload_size_hwtcl 512 dict set params extend_tag_field_hwtcl "64" dict set params completion_timeout_hwtcl "ABCD" dict set params enable_completion_timeout_disable_hwtcl 1 dict set params use_aer_hwtcl 0 dict set params ecrc_check_capable_hwtcl 0 dict set params ecrc_gen_capable_hwtcl 0 dict set params use_crc_forwarding_hwtcl 0 dict set params port_link_number_hwtcl 1 dict set params dll_active_report_support_hwtcl 0 dict set params surprise_down_error_support_hwtcl 0 dict set params slotclkcfg_hwtcl 1 dict set params msi_multi_message_capable_hwtcl "1" dict set params msi_64bit_addressing_capable_hwtcl "true" dict set params msi_masking_capable_hwtcl "false" dict set params msi_support_hwtcl "true" dict set params enable_function_msix_support_hwtcl 1 dict set params msix_table_size_hwtcl 16 dict set params msix_table_offset_hwtcl "4096" dict set params msix_table_bir_hwtcl 0 dict set params msix_pba_offset_hwtcl "3968" dict set params msix_pba_bir_hwtcl 0 set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } if { [string match "SIMULATION" $mode]} { connectal_altera_simu_ip $core_name $core_version $ip_name $component_parameters } else { connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } } proc create_pcie_reconfig {mode} { set core_name {altera_pcie_reconfig_driver} set core_version {14.0} set ip_name {altera_pcie_reconfig_driver_wrapper} set params [ dict create ] dict set params INTENDED_DEVICE_FAMILY "Stratix V" dict set params gen123_lane_rate_mode_hwtcl "Gen2 (5.0 Gbps)" dict set params number_of_reconfig_interfaces 10 set component_parameters {} foreach item [dict keys $params ] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } if {[string match "SIMULATION" $mode]} { connectal_altera_simu_ip $core_name $core_version $ip_name $component_parameters } else { connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } } proc create_pcie_hip_ast_ed {} { set core_name {altera_pcie_hip_ast_ed} set core_version {14.0} set ip_name {altera_pcie_hip_ast_ed} set params [ dict create ] dict set params device_family_hwtcl "Stratix V" dict set params lane_mask_hwtcl "x8" dict set params gen123_lane_rate_mode_hwtcl "Gen2 (5.0 Gbps)" dict set params pld_clockrate_hwtcl 250000000 dict set params port_type_hwtcl "Native endpoint" dict set params ast_width_hwtcl "Avalon-ST 128-bit" dict set params extend_tag_field_hwtcl 32 dict set params max_payload_size_hwtcl 256 dict set params num_of_func_hwtcl 1 dict set params multiple_packets_per_cycle_hwtcl 0 dict set params port_width_be_hwtcl 16 dict set params port_width_data_hwtcl 128 dict set params avalon_waddr_hwltcl 12 dict set params check_bus_master_ena_hwtcl 1 dict set params check_rx_buffer_cpl_hwtcl 1 dict set params use_crc_forwarding_hwtcl 0 set component_parameters {} foreach item [dict keys $params ] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } proc create_pcie_xcvr_reconfig {mode core_name core_version ip_name n_interface} { set params [ dict create ] dict set params number_of_reconfig_interfaces $n_interface dict set params device_family "Stratix V" dict set params enable_offset 1 dict set params enable_lc 1 dict set params enable_dcd 0 dict set params enable_dcd_power_up 1 dict set params enable_analog 1 dict set params enable_eyemon 0 dict set params enable_ber 0 dict set params enable_dfe 0 dict set params enable_adce 1 dict set params enable_mif 0 dict set params enable_pll 0 set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-parameter=$item=$val } if {[string match "SIMULATION" $mode]} { connectal_altera_simu_ip $core_name $core_version $ip_name $component_parameters } else { connectal_altera_synth_ip $core_name $core_version $ip_name $component_parameters } } if {$need_pcie == "s5_gen2x8"} { create_pcie_sv_hip_ast SYNTHESIS create_pcie_xcvr_reconfig SYNTHESIS alt_xcvr_reconfig 14.0 alt_xcvr_reconfig_wrapper 10 create_pcie_reconfig SYNTHESIS create_pcie_hip_ast_ed } # Stratix IV PCIe requires use of Megawizard if {$need_pcie == "s4_gen2x8"} { fpgamake_altera_qmegawiz $connectaldir/verilog/altera/siv_gen2x8 siv_gen2x8 } ================================================ FILE: scripts/connectal-synth-pll.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" proc create_custom_pll {name refclk args} { global ipdir boardname partname set num [llength $args] if {$num == 0} { set error {wrong # args: should be at least "create_custom_pll [refclk] [genclk0] ..."} error $error } puts "Generating PLL with ref clock $refclk and output clock $args..." set params [ dict create ] dict set params gui_reference_clock_frequency $refclk dict set params gui_operation_mode "normal" dict set params gui_number_of_clocks $num dict set params gui_use_locked "false" set m 0 while {$m < 18} { set key0 gui_output_clock_frequency$m set key1 gui_phase_shift$m set key2 gui_duty_cycle$m if {$m < $num} { dict set params $key0 [lindex $args $m] dict set params $key1 0 dict set params $key2 50 } else { dict set params $key0 0 dict set params $key1 0 dict set params $key2 50 } incr m } set component_parameters {} foreach item [dict keys $params] { set val [dict get $params $item] lappend component_parameters --component-param=$item=$val } set core_name {altera_pll} set core_version {14.0} set ip_name $name exec -ignorestderr -- ip-generate \ --project-directory=$ipdir/$boardname \ --output-directory=$ipdir/$boardname/synthesis/$ip_name \ --file-set=QUARTUS_SYNTH \ --report-file=html:$ipdir/$boardname/$ip_name.html \ --report-file=sopcinfo:$ipdir/$boardname/$ip_name.sopcinfo \ --report-file=cmp:$ipdir/$boardname/$ip_name.cmp \ --report-file=svd:$ipdir/$boardname/synthesis/$ip_name/$ip_name.svd \ --report-file=qip:$ipdir/$boardname/synthesis/$ip_name/altera_$ip_name.qip \ --report-file=regmap:$ipdir/$boardname/synthesis/$ip_name/$ip_name.regmap \ --report-file=xml:$ipdir/$boardname/$ip_name.xml \ --system-info=DEVICE_FAMILY=StratixV \ --system-info=DEVICE=$partname \ --system-info=DEVICE_SPEEDGRADE=2_H2 \ --language=VERILOG \ {*}$component_parameters\ --component-name=$core_name \ --output-name=$ip_name } create_custom_pll pll_156 644.53125 156.25 ================================================ FILE: scripts/connectal-synth-zynq-mpsoc.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" set prj_boardname $boardname if {"$XILINX" == "1"} { set zynq_ultra_ps_version 2.0 if {[version -short] == "2022.2"} { set zynq_ultra_ps_version {3.4} } if {[version -short] == "2022.1"} { set zynq_ultra_ps_version {3.4} } if {[version -short] == "2019.1"} { set zynq_ultra_ps_version {3.3} } } connectal_synth_ip zynq_ultra_ps_e ${zynq_ultra_ps_version} zynq_ultra_ps_e_0 [list \ CONFIG.PSU__FPGA_PL1_ENABLE {1} \ CONFIG.PSU__USE__M_AXI_GP0 {1} \ CONFIG.PSU__USE__IRQ0 {1} \ CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ {200} \ CONFIG.PSU__CRL_APB__PL1_REF_CTRL__FREQMHZ {200} \ CONFIG.PSU__USE__S_AXI_GP0 {1} \ CONFIG.PSU__USE__S_AXI_GP1 {1} \ CONFIG.PSU__USE__S_AXI_GP2 {1} \ CONFIG.PSU__USE__S_AXI_GP3 {1} \ CONFIG.PSU__USE__S_AXI_GP4 {1} \ CONFIG.PSU__USE__S_AXI_GP5 {1} \ CONFIG.PSU__USE__S_AXI_GP6 {1} \ CONFIG.PSU__USE__S_AXI_ACP {1} \ CONFIG.PSU__USE__S_AXI_ACE {1} \ ] ================================================ FILE: scripts/cppgen.py ================================================ ## ## Copyright (C) 2013 Nokia, Inc ## Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, copy, ## modify, merge, publish, distribute, sublicense, and/or sell copies ## of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## The above copyright notice and this permission notice shall be ## included in all copies or substantial portions of the Software. ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ## BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ## ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ## SOFTWARE. from __future__ import print_function import functools, json, math, os, re, sys, util try: basestring except NameError: basestring = str # Python 3 compatibility generatedSubdirectory = 'jni' verbose = False generateJson = True generatePacketOnly = False suppressGeneratedMakefile = False synchronousInvoke = False sizeofUint32_t = 4 generatedVectors = [] itypeNames = ['int', 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'uint64_t', 'SpecialTypeForSendingFd', 'ChannelType', 'DmaDbgRec'] proxyClassPrefixTemplate=''' class %(className)sProxy : public Portal { %(classNameOrig)sCb *cb; public: %(className)sProxy(int id, int tile = DEFAULT_TILE, %(classNameOrig)sCb *cbarg = &%(className)sProxyReq, int bufsize = %(classNameOrig)s_reqinfo, PortalPoller *poller = 0) : Portal(id, tile, bufsize, %(handlerName)s, NULL, this, poller), cb(cbarg) {%(initName)s}; %(className)sProxy(int id, PortalTransportFunctions *transport, void *param, %(classNameOrig)sCb *cbarg = &%(className)sProxyReq, int bufsize = %(classNameOrig)s_reqinfo, PortalPoller *poller = 0) : Portal(id, DEFAULT_TILE, bufsize, %(handlerName)s, NULL, transport, param, this, poller), cb(cbarg) {%(initName)s}; %(className)sProxy(int id, PortalPoller *poller) : Portal(id, DEFAULT_TILE, %(classNameOrig)s_reqinfo, %(handlerName)s, NULL, NULL, NULL, this, poller), cb(&%(className)sProxyReq) {%(initName)s}; ''' syncProxyTemplate=''' private: static int __internalHandleMessage(struct PortalInternal *p, unsigned int channel, int messageFd) { return ((%(className)sProxy *)p->parent)->__internalResponse(p, channel); } sem_t *__internalWaitSemaphore; sem_t __internalWaitSemaphoreBody; uint64_t __internalWaitResult; unsigned int __internalWaitMethod; int __internalWaitSize; void __internalInit() { if ((__internalWaitSemaphore = sem_open("/semaphore", O_CREAT, 0644, 0)) == SEM_FAILED) { __internalWaitSemaphore = &__internalWaitSemaphoreBody; if (sem_init(__internalWaitSemaphore, 1, 0) == 0) return; perror("sem_open failed"); exit(-1); } } int __internalResponse(struct PortalInternal *p, unsigned int channel) { int tmpfd __attribute__ ((unused)); volatile unsigned int* temp_working_addr = p->transport->mapchannelInd(p, channel); int offset = 0, remain = 1; p->transport->recv(p, temp_working_addr, 1, &tmpfd); uint32_t temp = p->transport->read(p, &temp_working_addr); offset++; int messageSize = temp & 0xffff; temp = temp >> 16; if (channel != __internalWaitMethod || __internalWaitSize != messageSize) printf("%(className)sProxy: channel %%d/%%d waitSize %%d messageSize %%d\\n", channel, __internalWaitMethod, __internalWaitSize, messageSize); __internalWaitResult = 0; uint16_t *dest = (uint16_t *)&__internalWaitResult; while (messageSize > 0) { if (remain == 0) { p->transport->recv(p, temp_working_addr, 1, &tmpfd); temp = p->transport->read(p, &temp_working_addr); offset++; remain = 2; } *dest++ = temp & 0xffff; temp = temp >> 16; messageSize -= 16; --remain; } sem_post(__internalWaitSemaphore); return 0; } uint64_t __internalWaitReturn(int method, int size) { __internalWaitMethod = method; __internalWaitSize = size; sem_wait(__internalWaitSemaphore); return __internalWaitResult; } ''' wrapperClassPrefixTemplate=''' extern %(classNameOrig)sCb %(className)s_cbTable; class %(className)sWrapper : public Portal { public: %(className)sWrapper(int id, int tile = DEFAULT_TILE, PORTAL_INDFUNC cba = %(className)s_handleMessage, int bufsize = %(classNameOrig)s_reqinfo, PortalPoller *poller = 0) : Portal(id, tile, bufsize, cba, (void *)&%(className)s_cbTable, this, poller) { }; %(className)sWrapper(int id, PortalTransportFunctions *transport, void *param, PORTAL_INDFUNC cba = %(className)s_handleMessage, int bufsize = %(classNameOrig)s_reqinfo, PortalPoller *poller=0): Portal(id, DEFAULT_TILE, bufsize, cba, (void *)&%(className)s_cbTable, transport, param, this, poller) { }; %(className)sWrapper(int id, PortalPoller *poller) : Portal(id, DEFAULT_TILE, %(classNameOrig)s_reqinfo, %(className)s_handleMessage, (void *)&%(className)s_cbTable, this, poller) { }; %(className)sWrapper(int id, PortalTransportFunctions *transport, void *param, PortalPoller *poller): Portal(id, DEFAULT_TILE, %(classNameOrig)s_reqinfo, %(className)s_handleMessage, (void *)&%(className)s_cbTable, transport, param, this, poller) { }; virtual void disconnect(void) { printf("%(className)sWrapper.disconnect called %%d\\n", pint.client_fd_number); }; ''' handleMessageTemplateDecl=''' int %(className)s_handleMessage(struct PortalInternal *p, unsigned int channel, int messageFd)''' messageStructTemplate=''' typedef struct { %(paramStructDeclarations)s } %(channelName)sData;''' portalStructTemplate=''' typedef union { %(messageStructDeclarations)s } %(className)sData;''' handleMessageTemplateTmpDecl=''' int tmp __attribute__ ((unused));''' handleMessageTemplate1=''' { static int runaway = 0;%(tmpDecl)s int tmpfd __attribute__ ((unused)); %(classNameOrig)sData tempdata __attribute__ ((unused)); memset(&tempdata, 0, sizeof(tempdata)); %(handleStartup)s switch (channel) {''' handleMessagePrepRecv=''' p->transport->recv(p, temp_working_addr, %(wordLen)s, &tmpfd);''' handleMessagePrep=''' %(paramStructDemarshall)s''' handleMessageCase=''' case %(channelNumber)s: {%(responseCase)s } break;''' handleMessageTemplate2=''' default: PORTAL_PRINTF("%(className)s_handleMessage: unknown channel 0x%%x\\n", channel); if (runaway++ > 10) { PORTAL_PRINTF("%(className)s_handleMessage: too many bogus indications, exiting\\n"); #ifndef __KERNEL__ exit(-1); #endif } return 0; } return 0; } ''' proxyMethodTableDecl=''' %(classNameOrig)sCb %(className)sProxyReq = { %(methodTable)s }; %(classNameOrig)sCb *p%(className)sProxyReq = &%(className)sProxyReq; ''' proxyMethodTemplateDecl=''' int %(className)s_%(methodName)s (%(paramProxyDeclarations)s )''' proxyMethodTemplateProlog=''' volatile unsigned int* temp_working_addr_start = p->transport->mapchannelReq(p, %(channelNumber)s, %(wordLenP1)s); volatile unsigned int* temp_working_addr = temp_working_addr_start; if (p->transport->busywait(p, %(channelNumber)s, "%(className)s_%(methodName)s")) return 1;''' proxyMethodTemplatePrologPacket=''' unsigned int temp_working_addr_start[%(wordLenP1)s + 1] = {0, (%(channelNumber)s << 16) | %(wordLenP1)s,''' proxyMethodTemplate=''' {%(prolog)s %(paramStructMarshall)s p->transport->send(p, %(temp)s, (%(channelNumber)s << 16) | %(wordLenP1)s, %(fdName)s); return 0; }; ''' proxyJMethodTemplate=''' { Json::Value request; request.append(Json::Value("%(methodName)s")); %(paramStructMarshall)s std::string requestjson = Json::FastWriter().write(request);; connectalJsonSend(p, requestjson.c_str(), (int)%(channelNumber)s); return 0; }; ''' def indent(f, indentation): for i in range(indentation): f.write(' ') def cName(x): if isinstance(x, basestring): x = x.replace(' ', '') x = x.replace('.', '$') return x else: return x.cName() class paramInfo: def __init__(self, name, width, shifted, datatype, assignOp): self.name = name self.width = width self.shifted = shifted self.datatype = datatype self.assignOp = assignOp # resurse interface types and flattening all structs into a list of types def collectMembers(scope, pitem): if verbose: print('collectM', pitem) membtype = pitem['ptype'] while 1: if membtype['name'] == 'Bit' or membtype['name'] == 'Int' or membtype['name'] == 'UInt' \ or membtype['name'] == 'Float' or membtype['name'] == 'Bool' or membtype['name'] == 'fixed32': return [('%s%s'%(scope,pitem['pname']),membtype)] elif membtype['name'] == 'SpecialTypeForSendingFd': return [('%s%s'%(scope,pitem['pname']),membtype)] elif membtype['name'] == 'Vector': nElt = typeNumeric(membtype['params'][0]) retitem = [] ind = 0; while ind < nElt: retitem.append([('%s%s'%(scope,pitem['pname']+'['+str(ind)+']'),membtype['params'][1])]) ind = ind + 1 return sum(retitem, []) else: td = globalv_globalvars[membtype['name']] #print('instantiate', membtype['params']) tdtype = td['tdtype'] #print(' ', membtype) if tdtype.get('type') == 'Struct': ns = '%s%s.' % (scope,pitem['pname']) rv = map(functools.partial(collectMembers, ns), tdtype['elements']) return sum(rv,[]) membtype = tdtype if tdtype.get('type') == 'Enum': return [('%s%s'%(scope,pitem['pname']),membtype)] #print('resolved to type', membtype.get('type'), membtype['name'], membtype) def typeNumeric(item): global bsvdefines tstr = item.get('name') if tstr in globalv_globalvars: decl = globalv_globalvars[tstr] if decl.get('dtype') == 'TypeDef': return typeNumeric(decl['tdtype']) elif tstr in ['TAdd', 'TSub', 'TMul', 'TDiv', 'TLog', 'TExp', 'TMax', 'TMin']: values = [typeNumeric(p) for p in item['params']] if tstr == 'TAdd': return values[0] + values[1] elif tstr == 'TSub': return values[0] - values[1] elif tstr == 'TMul': return values[0] * values[1] elif tstr == 'TDiv': return int(math.ceil(values[0] / float(values[1]))) elif tstr == 'TLog': return int(math.ceil(math.log(values[0], 2))) elif tstr == 'TExp': return math.pow(2, values[0]) elif tstr == 'TMax': return max(values[0], values[1]) elif tstr == 'TMax': return min(values[0], values[1]) if tstr[0] == '`': var = tstr[1:] if var in bsvdefines: return int(bsvdefines[var]) if tstr[0] >= 'A' and tstr[0] <= 'Z': return tstr return int(tstr) def typeCName(item): global generatedVectors if item.get('type') == None: cid = item['name'].replace(' ', '') if cid == 'Bit': numbits = typeNumeric(item['params'][0]) if numbits <= 8: return 'uint8_t' elif numbits <= 16: return 'uint16_t' elif numbits <= 32: return 'uint32_t' elif numbits <= 64: return 'uint64_t' else: return 'char * /* %d bytes */' % ((numbits+7) / 8) elif cid == 'bit': return 'int' elif cid == 'Bool': return 'int' elif cid == 'Int': numbits = typeNumeric(item['params'][0]) if numbits <= 8: return 'int8_t' elif numbits <= 16: return 'int16_t' elif numbits <= 32: return 'int32_t' elif numbits <= 64: return 'int64_t' else: assert(False) elif cid == 'UInt': numbits = typeNumeric(item['params'][0]) if numbits <= 8: return 'uint8_t' if numbits <= 16: return 'uint16_t' elif numbits <= 32: return 'uint32_t' elif numbits <= 64: return 'uint64_t' else: assert(False) elif cid == 'Float': return 'float' elif cid == 'Vector': t = [typeNumeric(item['params'][0]), typeCName(item['params'][1])] if t not in generatedVectors: generatedVectors.append(t) return 'bsvvector_L%s_L%d' % (t[1], t[0]) elif cid == 'Action': return 'int' elif cid == 'ActionValue': assert(False) if item.get('params'): name = '%sL_%s_P' % (cid, '_'.join([typeCName(t) for t in item['params'] if t])) else: name = cid return name return item['name'] def signCName(item): global generatedVectors if item.get('type') == None: cid = item['name'].replace(' ', '') if cid == 'Bool': return '1L' elif cid == 'Int': numbits = typeNumeric(item['params'][0]) if numbits <= 16: return '0xffffL' elif numbits <= 32: return '0xffffffffL' return None def typeJson(item): tname = typeCName(item) if tname not in itypeNames: #print('typeJson.other', tname, tname in itypeNames) return 'other' return tname def hasBitWidth(item): return item['name'] in ['Bit', 'Int', 'UInt', 'fixed32', 'bit'] def getNumeric(item): if item['name'] in globalv_globalvars: decl = globalv_globalvars[item['name']] if decl.get('dtype') == 'TypeDef': return getNumeric(decl['tdtype']) elif item['name'] in ['TAdd', 'TSub', 'TMul', 'TDiv', 'TLog', 'TExp', 'TMax', 'TMin']: values = [getNumeric(p) for p in item['params']] if item['name'] == 'TAdd': return values[0] + values[1] elif item['name'] == 'TSub': return values[0] - values[1] elif item['name'] == 'TMul': return values[0] * values[1] elif item['name'] == 'TDiv': return math.ceil(values[0] / float(values[1])) elif item['name'] == 'TLog': return math.ceil(math.log(values[0], 2)) elif item['name'] == 'TExp': return math.pow(2, values[0]) elif item['name'] == 'TMax': return max(values[0], values[1]) elif item['name'] == 'TMax': return min(values[0], values[1]) elif item['name'].startswith('`'): return int(bsvdefines[item['name'][1:]]) return int(item['name']) def typeBitWidth(item): if item['name'] == 'Bool': return 1 if item['name'] == 'bit': return 1 if item['name'] == 'Float': return 32 if item['name'] == 'fixed32': return 32 if item['name'] == 'SpecialTypeForSendingFd': return 32 if item.get('type') == 'Enum': enum_width = int(math.ceil(math.log(len(item['elements']), 2))) # determines that the element is a scoped enum if any([element[1] is not None for element in item['elements']]): # calculate the maximum bit width among all enum items enum_width = max([int(math.ceil(math.log(int(element[1] or i) + 1, 2))) for i, element in enumerate(item['elements'])]) return enum_width if hasBitWidth(item): width = item['params'][0]['name'] while width in globalv_globalvars: decl = globalv_globalvars[width] if decl.get('type') != 'TypeDef': break print('Resolving width', width, decl['tdtype']) width = decl['tdtype']['name'] if re.match('[0-9]+', width): return int(width) return getNumeric(decl['tdtype']) return 0 # pack flattened struct-member list into 32-bit wide bins. If a type is wider than 32-bits or # crosses a 32-bit boundary, it will appear in more than one bin (though with different ranges). # This is intended to mimick exactly Bluespec struct packing. The padding must match the code # in Adapter.bsv. the argument s is a list of bins, atoms is the flattened list, and pro represents # the number of bits already consumed from atoms[0]. def accumWords(s, pro, memberList): if len(memberList) == 0: if len(s) == 0: return [] else: return [s] w = sum([x.width-x.shifted for x in s]) mitem = memberList[0] name = mitem[0] thisType = mitem[1] aw = typeBitWidth(thisType) #print('%d %d %d' %(aw, pro, w)) if (aw-pro+w == 32): s.append(paramInfo(name,aw,pro,thisType,'=')) #print('%s (0)'% (name)) return [s]+accumWords([],0,memberList[1:]) if (aw-pro+w < 32): s.append(paramInfo(name,aw,pro,thisType,'=')) #print('%s (1)'% (name)) return accumWords(s,0,memberList[1:]) else: s.append(paramInfo(name,pro+(32-w),pro,thisType,'|=')) #print('%s (2)'% (name)) return [s]+accumWords([],pro+(32-w), memberList) def generate_marshall(pfmt, argWords): global fdName retList = [] for w in argWords: off = 0 fields = [] fmt = pfmt outstr = '' for e in w: field = e.name if typeCName(e.datatype) == 'float': return pfmt % ('*(int*)&' + e.name) mask = signCName(e.datatype) if mask: field = '(%s & %s)' % (field, mask) if e.shifted: field = '(%s>>%s)' % (field, e.shifted) if off: field = '(((unsigned long)%s)<<%s)' % (field, off) if typeBitWidth(e.datatype) > 64: field = '(const %s & std::bitset<%d>(0xFFFFFFFF)).to_ulong()' % (field, typeBitWidth(e.datatype)) fields.append(field) off = off+e.width-e.shifted if typeCName(e.datatype) == 'SpecialTypeForSendingFd': fdName = field fmt = 'p->transport->writefd(p, &temp_working_addr, %s);' if generatePacketOnly: print('generate_marshall: when using "generatePacketOnly", fd items cannot be sent') sys.exit(-1) retList.append(fmt % (''.join(util.intersperse('|', fields)))) return retList def generate_demarshall(fmt, methodName, argWords): retList = [] itemIndex = 0 for w in argWords: off = 0 statements = [] if (fmt != ''): statements.append(fmt) for e in w: # print(e.name+' (d)') if generatePacketOnly: field = 'temp_working_addr[%d]' % itemIndex else: field = 'tmp' if typeCName(e.datatype) == 'float': statements.append('tempdata.%s.%s %s *(float *)&(%s);'%(methodName, e.name, e.assignOp, field)) continue if off: field = '%s>>%s' % (field, off) #print('JJJ', e.name, '{{'+field+'}}', typeBitWidth(e.datatype), e.shifted, e.assignOp, off) fieldWidth = 32 - off # number of valid data bits in source fieldWidth += e.shifted # number of valid data bits after shifting if fieldWidth > typeBitWidth(e.datatype): # if num bits in type < num of valid bits fieldWidth = typeBitWidth(e.datatype) field = '((%s)&0x%xul)' % (field, ((1 << (fieldWidth - e.shifted))-1)) if e.shifted: field = '((%s)(%s)<<%s)' % (typeCName(e.datatype),field, e.shifted) if typeCName(e.datatype) == 'SpecialTypeForSendingFd': if generatePacketOnly: print('generate_demarshall: when using "generatePacketOnly", fd items cannot be sent') sys.exit(-1) statements.append('tempdata.%s.%s %s messageFd;'%(methodName, e.name, e.assignOp)) elif e.datatype.get('type') == 'Enum' and e.assignOp == '|=': statements.append('tempdata.%s.%s = (%s)((int)tempdata.%s.%s | %s);'%(methodName, e.name, typeCName(e.datatype), methodName, e.name, field)) else: statements.append('tempdata.%s.%s %s (%s)(%s);'%(methodName, e.name, e.assignOp, typeCName(e.datatype), field)) off = off+e.width-e.shifted retList.append('\n '.join(statements)) itemIndex += 1 return retList def formalParameters(params, insertPortal): rc = [ 'const %s %s' % (typeCName(pitem['ptype']), pitem['pname']) for pitem in params] if insertPortal: rc.insert(0, ' struct PortalInternal *p') return ', '.join(rc) toJsonVerbose = False def genToJson(var, name, prefix, ptype, appendto=False): typename = ptype['name'] if toJsonVerbose: print('genToJson', name, typename, ptype, appendto) if typename in ['Bit', 'Int', 'UInt', 'Bool']: if typename == 'Int': cast = 'Json::Int64' else: cast = 'Json::UInt64' if appendto: return ['%s.append((%s)%s);' % (var, cast, prefix)] else: return ['%s["%s"] = (%s)%s;' % (var, name, cast, prefix)] if 'type' not in ptype and typename != 'Vector': typedef = globalv_globalvars[typename] if toJsonVerbose: print(' dereferencing typedef', typedef) if typedef['dtype'] == 'TypeDef': tdtype = typedef['tdtype'] return genToJson(var, name, prefix, tdtype, appendto) result = [] if typename == 'Vector': ptype_type = 'Vector' else: ptype_type = ptype['type'] if ptype_type == 'Struct': if toJsonVerbose: print('elements', ptype['elements']) structvar = '_%sValue' % name result.append('Json::Value %s;' % structvar) result.append('%s["__type__"]="%s";' % (structvar, typename)) for elt in ptype['elements']: result.extend(genToJson(structvar, elt['pname'], '%s.%s' % (name, elt['pname']), elt['ptype'])) expr = structvar elif ptype_type == 'Enum': expr = '(int)%s' % prefix elif ptype_type == 'Vector': vectorSize = typeNumeric(ptype['params'][0]) vectorType = ptype['params'][1] vectorName = '%sVector' % cName(prefix) result.append('Json::Value %s;' % vectorName) for i in range(0,vectorSize): result.extend(genToJson(vectorName,None,('%s[%d]' % (prefix,i)),vectorType,True)) expr = vectorName else: print('genToJson cannot handle', name, prefix, ptype) expr = prefix if appendto: result.append('%s.append(%s);' % (var, expr)) else: result.append('%s["%s"] = %s;' % (var, name, expr)) if toJsonVerbose: print('result', result) return result def gatherMethodInfo(mname, params, itemname, classNameOrig, classVariant): global fdName className = cName(itemname) methodName = cName(mname) argAtoms = sum(map(functools.partial(collectMembers, ''), params), []) argAtoms.reverse() argWords = accumWords([], 0, argAtoms) argWords.reverse() fdName = '-1' if generatePacketOnly: paramStructMarshallStr = ' (unsigned int)(%s),' paramStructDemarshallStr = '' else: paramStructMarshallStr = 'p->transport->write(p, &temp_working_addr, %s);' paramStructDemarshallStr = 'tmp = p->transport->read(p, &temp_working_addr);' if argWords == []: if generatePacketOnly: paramStructMarshall = [] else: paramStructMarshall = [paramStructMarshallStr % '0'] paramStructDemarshall = [paramStructDemarshallStr] else: paramStructMarshall = generate_marshall(paramStructMarshallStr, argWords) paramStructDemarshall = generate_demarshall(paramStructDemarshallStr, methodName, argWords) chname = '%s_%s' % (classNameOrig, methodName) if verbose: for pitem in params: print('gatherMI', pitem) break if classVariant: paramStructMarshall = [] itemNumber = 0 for pitem in params: pname = pitem['pname'] ptype = pitem['ptype'] titems = genToJson('request', pname, pname, pitem['ptype'], True) paramStructMarshall.extend(titems) itemNumber = itemNumber + 1 paramStructDeclarations = [ '%s %s;' % (typeCName(pitem['ptype']), pitem['pname']) for pitem in params] paramJsonDeclarations = [ '{"%s", Connectaloffsetof(%sData,%s), ITYPE_%s},' % \ (pitem['pname'], chname, pitem['pname'], typeJson(pitem['ptype'])) for pitem in params] if not params: paramStructDeclarations = [' int padding;\n'] paramJsonDeclarations = [''] respParams = ['tempdata.%s.%s' % (methodName, pitem['pname']) for pitem in params] respParams.insert(0, 'p') substs = { 'methodName': methodName, 'paramDeclarations': formalParameters(params, False), 'paramProxyDeclarations': formalParameters(params, True), 'paramStructDeclarations': '\n '.join(paramStructDeclarations), 'paramStructMarshall': '\n '.join(paramStructMarshall), 'paramJsonDeclarations': '\n '.join(paramJsonDeclarations), 'paramStructDemarshall': '\n '.join(paramStructDemarshall), 'paramNames': ', '.join(['msg->%s' % pitem['pname'] for pitem in params]), 'wordLen': len(argWords), 'wordLenP1': len(argWords) + 1, 'fdName': fdName, 'className': className, 'classNameOrig': classNameOrig, 'channelName': chname, 'channelNumber': 'CHAN_NUM_%s' % chname, 'name': mname, 'params': ', '.join(respParams), } # 'className' : classNameOrig, respCase = '\n ((%(classNameOrig)sCb *)p->cb)->%(name)s(%(params)s);' if not classVariant: respCase = handleMessagePrep + respCase if not generatePacketOnly: respCase = handleMessagePrepRecv + respCase substs['responseCase'] = respCase % substs return substs, len(argWords) def emitMethodDeclaration(mname, params, f, className, methodIndex, returnType): paramValues = [pitem['pname'] for pitem in params] paramValues.insert(0, '&pint') methodName = cName(mname) indent(f, 4) if className == '': f.write('virtual void') elif synchronousInvoke: if returnType is not None: f.write(typeCName(returnType)) else: f.write('void') else: f.write('int') f.write((' %s ( ' % methodName) + formalParameters(params, False) + ' ) ') if className == '': f.write('= 0;\n') elif synchronousInvoke: f.write('{ cb->%s (' % methodName) f.write(', '.join(paramValues) + ');') if returnType is not None: f.write(' return __internalWaitReturn(%d, %d);' % (methodIndex, typeBitWidth(returnType))) f.write(' };\n') else: f.write('{ return cb->%s (' % methodName) f.write(', '.join(paramValues) + '); };\n') wrapperStartTemplate = ''' /************** Start of %(className)sWrapper CPP ***********/ #include "%(classNameOrig)s.h" int %(classNameOrig)sdisconnect_cb (struct PortalInternal *p) { (static_cast<%(classNameOrig)sWrapper *>(p->parent))->disconnect(); return 0; }; ''' def generate_class(classNameOrig, classVariant, declList, generatedCFiles, create_cpp_file, generated_hpp, generated_cpp, direction): global generatedVectors className = classNameOrig + classVariant classCName = cName(className) generateProxy = True generateWrapper = True if direction == '0': generateWrapper = False print('JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ Proxy ', className) if direction == '1': generateProxy = False print('JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ Wrapper ', className) if classVariant == 'Json': cppname = '%s.cpp' % className else: cppname = '%s.c' % className hppname = '%s.h' % className if cppname in generatedCFiles: return generatedCFiles.append(cppname) cpp = create_cpp_file(cppname) if classVariant: cpp.write('#ifdef PORTAL_JSON\n') cpp.write('#include "jsoncpp/json/json.h"\n') maxSize = 0 reqChanNums = [] methodList = [] cnSubst = {'className': className, 'classNameOrig': classNameOrig} if not classVariant: hpp = create_cpp_file(hppname) hpp.write('#ifndef _%(name)s_H_\n#define _%(name)s_H_\n' % {'name': className.upper()}) hpp.write('#include "portal.h"\n') if (not classVariant) and generateWrapper: generated_cpp.write(wrapperStartTemplate % cnSubst) for mitem in declList: if verbose: print('gcl/mitem', mitem) substs, t = gatherMethodInfo(mitem['dname'], mitem['dparams'], className, classNameOrig, classVariant) if t > maxSize: maxSize = t methodList.append(substs['methodName']) reqChanNums.append(substs['channelNumber']) methodJsonDeclarations = ['{"%(methodName)s", %(classNameOrig)s_%(methodName)sInfo},' % {'methodName': p, 'classNameOrig': classNameOrig} for p in methodList] if generateProxy: for mitem in declList: substs, t = gatherMethodInfo(mitem['dname'], mitem['dparams'], className, classNameOrig, classVariant) if generatePacketOnly: substs['temp'] = 'temp_working_addr_start + 2' substs['prolog'] = proxyMethodTemplatePrologPacket % substs substs['paramStructMarshall'] = substs['paramStructMarshall'][0: len(substs['paramStructMarshall']) - 1] + "};" else: substs['temp'] = 'temp_working_addr_start' substs['prolog'] = proxyMethodTemplateProlog % substs if classVariant: cpp.write((proxyMethodTemplateDecl + proxyJMethodTemplate) % substs) else: cpp.write((proxyMethodTemplateDecl + proxyMethodTemplate) % substs) for t in generatedVectors: #'Vector' generated_hpp.write('\ntypedef %s bsvvector_L%s_L%d[%d];' % (t[1], t[1], t[0], t[0])) generatedVectors = [] for mitem in declList: substs, t = gatherMethodInfo(mitem['dname'], mitem['dparams'], className, classNameOrig, classVariant) generated_hpp.write((proxyMethodTemplateDecl % substs) + ';') methodTable = ['%(className)s_%(methodName)s,' % {'methodName': p, 'className': className} for p in methodList] cpp.write(proxyMethodTableDecl % {'className': className, 'classNameOrig': classNameOrig, 'methodTable': '\n '.join(['portal_disconnect,'] + methodTable)}) subs = {'className': classCName, 'maxSize': (maxSize+1) * sizeofUint32_t, 'reqInfo': '0x%x' % ((len(declList) << 16) + (maxSize+1) * sizeofUint32_t), 'classNameOrig': classNameOrig, 'tmpDecl': handleMessageTemplateTmpDecl} if classVariant: subs['handleStartup'] = 'Json::Value msg = Json::Value(connectalJsonReceive(p));' % subs else: if generatePacketOnly: subs['handleStartup'] = 'volatile unsigned int* temp_working_addr = &p->map_base[1];' subs['tmpDecl'] = '' else: subs['handleStartup'] = 'volatile unsigned int* temp_working_addr = p->transport->mapchannelInd(p, channel);' generated_hpp.write('\nenum { ' + ','.join(reqChanNums) + '};\n' % subs) generated_hpp.write('extern const uint32_t %(className)s_reqinfo;\n' % subs) cpp.write('\nconst uint32_t %(className)s_reqinfo = %(reqInfo)s;\n' % subs) if generateProxy: generateHandler = False for mitem in declList: if mitem.get('rtype') is not None: generateHandler = True if generateHandler: hpp.write('#include \n') hpp.write('#include \n') subs['handlerName'] = '__internalHandleMessage' subs['initName'] = '__internalInit();' else: subs['handlerName'] = 'NULL' subs['initName'] = '' hpp.write(proxyClassPrefixTemplate % subs) dindex = 0 for mitem in declList: emitMethodDeclaration(mitem['dname'], mitem['dparams'], hpp, classCName, dindex, mitem.get('rtype')) dindex = dindex + 1 if generateHandler: hpp.write(syncProxyTemplate % subs) hpp.write('};\n') if generateWrapper: cpp.write('const char * %(className)s_methodSignatures()\n{\n' % subs) signatures = dict([(mitem['dname'], ['long' for param in mitem['dparams']]) for mitem in declList]) cpp.write(' return %s;\n}\n' % json.dumps(json.dumps(signatures))) cpp.write((handleMessageTemplateDecl % subs)) cpp.write(handleMessageTemplate1 % subs) for mitem in declList: substs, t = gatherMethodInfo(mitem['dname'], mitem['dparams'], className, classNameOrig, classVariant) if not classVariant: generated_hpp.write(messageStructTemplate % substs) cpp.write(handleMessageCase % substs) if not classVariant: elemList = [] for mitem in declList: substs, t = gatherMethodInfo(mitem['dname'], mitem['dparams'], className, className, classVariant) elemList.append('%(channelName)sData %(methodName)s;' % substs) generated_hpp.write(portalStructTemplate % {'className': classCName, 'messageStructDeclarations': '\n '.join(elemList)}) cpp.write(handleMessageTemplate2 % subs) generated_hpp.write((handleMessageTemplateDecl % subs)+ ';\n') if (not classVariant) and generateWrapper: hpp.write(wrapperClassPrefixTemplate % subs) dindex = 0 for mitem in declList: emitMethodDeclaration(mitem['dname'], mitem['dparams'], hpp, '', dindex, mitem.get('rtype')) dindex = dindex + 1 hpp.write('};\n') cCNSubst = { 'classCName': classCName} if not classVariant: generated_hpp.write('typedef struct {\n PORTAL_DISCONNECT disconnect;\n') for mitem in declList: if verbose: for pitem in mitem['dparams']: print('generatecl/dparam', pitem) break paramValues = ', '.join([pitem['pname'] for pitem in mitem['dparams']]) formalParamStr = formalParameters(mitem['dparams'], True) methodName = cName(mitem['dname']) generated_hpp.write((' int (*%s) ( ' % methodName) + formalParamStr + ' );\n') if generateWrapper: generated_cpp.write(('int %s%s_cb ( ' % (classCName, methodName)) + formalParamStr + ' ) {\n') indent(generated_cpp, 4) generated_cpp.write(('(static_cast<%sWrapper *>(p->parent))->%s ( ' % (classCName, methodName)) + paramValues + ');\n') indent(generated_cpp, 4) generated_cpp.write('return 0;\n};\n') generated_hpp.write('} %(classCName)sCb;\n' % cCNSubst) if (not classVariant) and generateWrapper: generated_cpp.write('%(classCName)sCb %(classCName)s_cbTable = {\n %(classCName)sdisconnect_cb,\n' % cCNSubst) for mitem in declList: generated_cpp.write(' %s%s_cb,\n' % (classCName, mitem['dname'])) generated_cpp.write('};\n') if not classVariant: hpp.write('#endif // _%(name)s_H_\n' % {'name': className.upper()}) hpp.close() if generateProxy: generated_hpp.write('extern %(classNameOrig)sCb %(className)sProxyReq;\n' % subs) if classVariant: cpp.write('#endif /* PORTAL_JSON */\n') cpp.close() def emitStructMember(item, f, indentation): if verbose: print('emitSM', item) indent(f, indentation) f.write('%s %s' % (typeCName(item['ptype']), item['pname'])) if hasBitWidth(item['ptype']): f.write(' : %d' % typeBitWidth(item['ptype'])) f.write(';\n') def emitStruct(item, name, f, indentation): indent(f, indentation) if (indentation == 0): f.write('typedef ') f.write('struct %s {\n' % name) for e in item['elements']: emitStructMember(e, f, indentation+4) indent(f, indentation) f.write('}') if (indentation == 0): f.write(' %s;' % name) f.write('\n') def emitType(item, name, f, indentation): indent(f, indentation) tmp = typeCName(item) if re.match('[0-9]+', tmp): if True or verbose: print('cppgen/emitType: INFO ignore numeric typedef for', tmp) return if not tmp or tmp[0] == '`' or tmp == 'Empty' or tmp[-2:] == '_P': if True or verbose: print('cppgen/emitType: INFO ignore typedef for', tmp) return if (indentation == 0): f.write('typedef ') f.write(tmp) if (indentation == 0): f.write(' %s;' % name) f.write('\n') def convertVerilogNumber(n): if "'" in n: width, n = n.split("'") base = 10 if n[0] in ['h', 'd', 'o', 'b']: if n[0] == 'h': base = 16 if n[0] == 'd': base = 10 if n[0] == 'o': base = 8 if n[0] == 'b': base = 2 n = n[1:] n = hex(int(n, base)) return n def emitEnum(item, name, f, indentation): indent(f, indentation) if (indentation == 0): f.write('typedef ') f.write('enum %s { ' % name) indent(f, indentation) for val in item['elements']: temp = val[0] if val[1] != None: temp += '=' + convertVerilogNumber(val[1]) f.write(temp + ', ') indent(f, indentation) f.write(' }') if (indentation == 0): f.write(' %s;' % name) f.write('\n') def emitCD(item, generated_hpp, indentation): if verbose: print('cppgen/emitCD:', item) n = item['tname'] td = item['tdtype'] t = td.get('type') if t == 'Enum': emitEnum(td, n, generated_hpp, indentation) elif t == 'Struct': emitStruct(td, n, generated_hpp, indentation) elif t == 'Type' or t == None: emitType(td, n, generated_hpp, indentation) else: print('EMITCD', n, t, td) def generate_cpp(project_dir, noisyFlag, jsondata): global globalv_globalvars, verbose, bsvdefines def create_cpp_file(name): fname = os.path.join(project_dir, generatedSubdirectory, name) f = util.createDirAndOpen(fname, 'w') if verbose: print("Writing file ",fname) f.write('#include "GeneratedTypes.h"\n') return f verbose = noisyFlag bsvdefines = {} for binding in jsondata['bsvdefines']: if '=' in binding: print('split', binding.split('=')) var,val = binding.split('=') bsvdefines[var] = val else: bsvdefines[binding] = binding generatedCFiles = [] globalv_globalvars = {} hname = os.path.join(project_dir, generatedSubdirectory, 'GeneratedTypes.h') generated_hpp = util.createDirAndOpen(hname, 'w') generated_hpp.write('#ifndef __GENERATED_TYPES__\n') generated_hpp.write('#define __GENERATED_TYPES__\n') generated_hpp.write('#include "portal.h"\n') generated_hpp.write('#ifdef __cplusplus\n') generated_hpp.write('extern "C" {\n') generated_hpp.write('#endif\n') # global type declarations used by interface mthods for v in jsondata['globaldecls']: if v['dtype'] == 'TypeDef': globalv_globalvars[v['tname']] = v if v.get('tparams'): print('Skipping C++ declaration for parameterized type', v['tname']) continue emitCD(v, generated_hpp, 0) generated_hpp.write('\n') cppname = 'GeneratedCppCallbacks.cpp' generated_cpp = create_cpp_file(cppname) generatedCFiles.append(cppname) generated_cpp.write('\n#ifndef NO_CPP_PORTAL_CODE\n') for decl in jsondata['globaldecls']: if decl['tname'] == 'IfcNames': ifcnames = decl['tdtype']['elements'] for (ifcname,ifcvalue) in ifcnames: generated_cpp.write('extern const uint32_t %s = %s;\n' % (util.decapitalize(ifcname), ifcname)) for item in jsondata['interfaces']: if verbose: print('generateclass', item) generate_class(item['cname'], '', item['cdecls'], generatedCFiles, create_cpp_file, generated_hpp, generated_cpp, item.get('direction')) if generateJson: generate_class(item['cname'], 'Json', item['cdecls'], generatedCFiles, create_cpp_file, generated_hpp, generated_cpp, item.get('direction')) generated_cpp.write('#endif //NO_CPP_PORTAL_CODE\n') generated_cpp.close() generated_hpp.write('#ifdef __cplusplus\n') generated_hpp.write('}\n') generated_hpp.write('#endif\n') generated_hpp.write('#endif //__GENERATED_TYPES__\n') generated_hpp.close() if not suppressGeneratedMakefile: gen_makefile = util.createDirAndOpen(os.path.join(project_dir, generatedSubdirectory, 'Makefile.generated_files'), 'w') gen_makefile.write('\nGENERATED_CPP=' + ' '.join(generatedCFiles)+'\n') gen_makefile.close() return generatedCFiles ================================================ FILE: scripts/deprecated/mkpcietop-partial-reconfiguration.tcl ================================================ # NOTE: typical usage would be "vivado -mode tcl -source create_mkPcieTop_batch.tcl" # # STEP#0: define output directory area. # set outputDir ./hw file mkdir $outputDir if [file exists {board.tcl}] { source {board.tcl} } else { set boardname vc707 set partname {xc7vx485tffg1761-2} } if [file exists $outputDir/mkpcietop_static_routed.dcp] { read_checkpoint $outputDir/mkpcietop_static_routed.dcp lock_design -level routing } else { read_checkpoint $outputDir/mkpcietop_post_synth.dcp read_xdc constraints/$boardname.xdc } #start_gui # # STEP#3: run placement and logic optimization, report utilization and timing estimates, write checkpoint design # read_checkpoint -cell top_portalTop hw/portaltop_post_synth.dcp if [file exists $outputDir/mkpcietop_static_routed.dcp] { } else { read_xdc $connectaldir/xilinx/constraints/$boardname-portal-pblock.xdc set_property HD.RECONFIGURABLE TRUE [get_cells top_portalTop] ## if the pblock is aligned to a reconfigurable frame, can use the following #set_property RESET_AFTER_RECONFIG true [get_pblocks top_portalTop] } opt_design # power_opt_design place_design #phys_opt_design write_checkpoint -force $outputDir/mkpcietop_post_place.dcp report_timing_summary -file $outputDir/mkpcietop_post_place_timing_summary.rpt # # STEP#4: run router, report actual utilization and timing, write checkpoint design, run drc, write verilog and xdc out # route_design write_checkpoint -force $outputDir/mkpcietop_post_route.dcp report_timing_summary -file $outputDir/mkpcietop_post_route_timing_summary.rpt report_timing -sort_by group -max_paths 100 -path_type summary -file $outputDir/mkpcietop_post_route_timing.rpt report_clock_utilization -file $outputDir/mkpcietop_clock_util.rpt report_utilization -file $outputDir/mkpcietop_post_route_util.rpt #report_power -file $outputDir/mkpcietop_post_route_power.rpt report_drc -file $outputDir/mkpcietop_post_imp_drc.rpt #write_verilog -force $outputDir/mkpcietop_impl_netlist.v write_xdc -no_fixed_only -force $outputDir/mkpcietop_post_route.xdc # # STEP#5: generate a bitstream # write_bitstream -force -bin_file $outputDir/mkPcieTop.bit if [file exists $outputDir/mkpcietop_static_routed.dcp] { pr_verify $outputDir/mkpcietop_static_routed.dcp $outputDir/mkpcietop_post_route.dcp } else { update_design -cells [get_cells top_portalTop] -black_box write_checkpoint -force $outputDir/mkpcietop_static_routed.dcp } ================================================ FILE: scripts/deprecated/mkpcietop-synth.tcl ================================================ # NOTE: typical usage would be "vivado -mode tcl -source create_mkPcieTop_batch.tcl" # # STEP#0: define output directory area. # if [file exists {board.tcl}] { source {board.tcl} } else { set boardname vc707 set partname {xc7vx485tffg1761-2} } set outputDir ./hw file mkdir $outputDir # # STEP#1: setup design sources and constraints # read_verilog [ glob {verilog/top/*.v} ] read_verilog [ glob $connectaldir/xilinx/pcie_7x_v2_1/pcie_7x_0/source/*.v ] read_verilog [ glob $connectaldir/xilinx/7x/pcie/source/*.v ] read_xdc constraints/$boardname.xdc # STEP#2: run synthesis, report utilization and timing estimates, write checkpoint design # synth_design -name mkPcieTop -top mkPcieTop -part $partname -flatten rebuilt write_checkpoint -force $outputDir/mkpcietop_post_synth ================================================ FILE: scripts/deprecated/portaltop-impl.tcl ================================================ # NOTE: typical usage would be "vivado -mode tcl -source create_mkPcieTop_batch.tcl" # # STEP#0: define output directory area. # if [file exists {board.tcl}] { source {board.tcl} } else { set boardname vc707 set partname {xc7vx485tffg1761-2} } set outputDir ./hw file mkdir $outputDir # # STEP#1: setup design sources and constraints # read_verilog [ glob {verilog/lib/*.v} ] read_verilog [ glob {verilog/portal/*.v} ] # STEP#2: run synthesis, report utilization and timing estimates, write checkpoint design # synth_design -mode out_of_context -name mkConnectalTopForPcie -top mkConnectalTopForPcie -part $partname -flatten rebuilt write_checkpoint -force $outputDir/portaltop_post_synth read_xdc $connectaldir/constraints/$boardname-portal-pblock.xdc place_design route_design write_checkpoint -force $outputDir/portaltop_post_route ================================================ FILE: scripts/deprecated/portaltop-synth.tcl ================================================ # NOTE: typical usage would be "vivado -mode tcl -source create_mkPcieTop_batch.tcl" # # STEP#0: define output directory area. # if [file exists {board.tcl}] { source {board.tcl} } else { set boardname vc707 set partname {xc7vx485tffg1761-2} } set outputDir ./hw file mkdir $outputDir # # STEP#1: setup design sources and constraints # read_verilog [ glob {verilog/top/*.v} ] read_verilog [ glob {verilog/portal/*.v} ] # STEP#2: run synthesis, report utilization and timing estimates, write checkpoint design # synth_design -mode out_of_context -name mkSynthesizeableConnectalTop -top mkSynthesizeableConnectalTop -part $partname -flatten rebuilt write_checkpoint -force $outputDir/portaltop_post_synth ================================================ FILE: scripts/discover_icmp.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import sys import os import socket import struct import select import time import threading import argparse import netifaces from adb import adb_commands from adb import common def connect_with_adb(ipaddr): connected = False device_serial = '%s:5555' % (ipaddr) print('connecting to android device %s' % device_serial) while not connected: try: connection = adb_commands.AdbCommands.ConnectDevice(serial=device_serial) connected = True except socket.error: pass if 'hostname' in connection.Shell('ls /mnt/sdcard/'): name = connection.Shell('cat /mnt/sdcard/hostname') print(name) return (ipaddr, name) else: print("/mnt/sdcard/hostname not found") def calcsum(source_string): sum = 0 for i in range(0,len(source_string),2): sum = sum + ord(source_string[i+1])*256 + ord(source_string[i]) sum = (sum >> 16) + (sum & 0xFFFF) sum += (sum >> 16) sum = (~sum) & 0xFFFF return sum >> 8 | (sum << 8 & 0xFF00) def receive_ping(timeout): global recv_cnt rem = timeout while True: a = time.time() b = select.select([icmp_socket], [], [], rem) c = (time.time() - a) if b[0] == []: return rp, addr = icmp_socket.recvfrom(1024) icmpHeader = rp[20:28] type, code, checksum, packetID, sequence = struct.unpack( "bbHHh", icmpHeader ) if packetID == icmp_id: recv_cnt = recv_cnt+1 # print "recv_cnt: %x" % recv_cnt return addr rem = rem - c if rem <= 0: return def send_ping(dest_addr): global send_cnt send_cnt = send_cnt+1 dest_addr = socket.gethostbyname(dest_addr) header = struct.pack("bbHHh", 8, 0, 0, icmp_id, 1) header = struct.pack("bbHHh", 8, 0, socket.htons(calcsum(header)), icmp_id, 1) try: # print header.encode('hex') # if (send_cnt > 1024): # time.sleep(0.1) icmp_socket.sendto(header, (dest_addr, 1)) except socket.error as e: print((dest_addr,e)) raise def check_adb_port(dest_addr): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(0.1) result = sock.connect_ex((dest_addr,5555)) return result == 0 def ping_request(dest_addr): try: send_ping(dest_addr) except socket.gaierror as e: print("%s failed. (socket error: '%s')" % (dest_addr, e[1])) def ping_response(timeout = 0.1): try: addr = receive_ping(timeout) except socket.gaierror as e: print("failed. (socket error: '%s')" % e[1]) if (addr != None): responders.append(addr[0]) def ip2int(addr): return struct.unpack("!I", socket.inet_aton(addr))[0] def int2ip(addr): return socket.inet_ntoa(struct.pack("!I", addr)) def send_pings(): for i in range(low_addr,high_addr+1): ping_request(int2ip(i)) def get_pings(): while (not stop): ping_response(0) def do_work(start, end): global responders global stop global low_addr global high_addr global icmp_socket global icmp_id global zedboards global send_cnt global recv_cnt send_cnt = 0 recv_cnt = 0 responders = [] stop = False low_addr = start high_addr = end print("pinging "+int2ip(low_addr)+" to "+int2ip(high_addr)) icmp = socket.getprotobyname("icmp") icmp_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) icmp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, (start-end)*64) icmp_id = os.getpid() & 0xFFFF t0 = threading.Thread(target=send_pings) t1 = threading.Thread(target=get_pings) t0.start() t1.start() t0.join() time.sleep(3) stop = True t1.join() open = [] for r in responders: if check_adb_port(r): open.append(r) for o in open: zedboards.append(connect_with_adb(o)) icmp_socket.close() argparser = argparse.ArgumentParser("Discover Zedboards on a network") argparser.add_argument('-n', '--network', help='xxx.xxx.xxx.xxx/N') def detect_network(): global zedboards zedboards = [] for ifc in netifaces.interfaces(): ifaddrs = netifaces.ifaddresses(ifc) if netifaces.AF_INET in ifaddrs.keys(): af_inet = ifaddrs[netifaces.AF_INET] for i in af_inet: if i.get('addr') == '127.0.0.1': print('skipping localhost') else: addr = ip2int(i.get('addr')) netmask = ip2int(i.get('netmask')) start = addr & netmask end = start + (netmask ^ 0xffffffff) print((int2ip(start), int2ip(end))) do_work(start, end) if __name__ == '__main__': zedboards = [] options = argparser.parse_args() if options.network == None: detect_network() else: nw = options.network.split("/") start = ip2int(nw[0]) end = start+(1< ...') print('Where is:') print(' pset n v Sets outlet #n to v(value 1-on,0-off)') print(' mac Displays Ethernet port Mac address') print(' nwshow Displays network Status') print(' pshow Displays outlet status') print(' sysshow Displays system information') print(' time Displays current time') print(' ver Displays hardware and software versions') sys.exit(1) lines = [] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((sys.argv[1], 23)) inline = '' for item in sys.argv[2:]: inline = inline + item + ' ' s.send(inline + '\r\nlogout\r\n') inline = '' while True: data = s.recv(1000) if not data: break for c in data: if c == '\r' or c == '\n': if inline != '': print(inline) inline = '' else: inline = inline + c s.close() if inline != '': print(inline) print('connection ended') ================================================ FILE: scripts/preprocess_trace.py ================================================ #! /usr/bin/env python3 # Copyright (c) 2014 Quanta Research Cambridge, Inc # Original author John Ankcorn # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. from __future__ import print_function import sys print('preprocess_trace.py:', sys.argv) cppind = [] bsvind = [] for filename in sys.argv[2:]: data = open(filename).readlines() hasdisplay = False hasdispind = False for line in data: if line.find('$display') >= 0: hasdisplay = True if line.find('printfInd') >= 0: hasdispind = True if hasdisplay and hasdispind: fname = sys.argv[1] + '/generatedbsv/' + filename fh = open(fname, 'w') for line in data: ind = line.find('$display') if ind >= 0: param = line[ind+8:].strip()[1:][:-2].strip() formatstr = '' pitem = '' level = 0 informat = True pactual = [] for ch in param[1:]: if informat: if ch == '"': if level == 0: informat = False else: formatstr = formatstr + ch elif ch == ',': if pitem != '': pactual.append(pitem.strip()) pitem = '' else: pitem = pitem + ch pactual.append(pitem.strip()) freplace = 'printfind_' lastch = '' plist = [] for ch in formatstr: if lastch == '%': if ch == 'x': plist.append('Bit#(32)') else: print('unknown format char', ch) if ch == '-': freplace = freplace + '__' elif (ch >= 'A' and ch <= 'Z') or (ch >= 'a' and ch <= 'z') or (ch >= '0' and ch <= '9'): freplace = freplace + ch else: freplace = freplace + '_' + '{:02x}'.format(ord(ch)) lastch = ch line = line[:ind] + 'printfInd.' + freplace + '(' + ','.join(pactual) + ');\n' pformal = '' pactual = '' pbsv = '' pcount = 1 for item in plist: if pcount > 1: pformal = pformal + ', ' pactual = pactual + ', ' pbsv = pbsv + ', ' pvar = 'v%d' % pcount pcount = pcount + 1 if item == 'Bit#(32)': pformal = pformal + 'uint32_t ' + pvar pactual = pactual + pvar pbsv = pbsv + item + ' ' + pvar cppind.append(' void ' + freplace + '(' + pformal + ') { printf("' + formatstr + '\\n", ' + pactual + '); }\n') bsvind.append(' method Action ' + freplace + '(' + pbsv + ');\n') fh.write(line) fh.close() if cppind != []: fname = sys.argv[1] + '/jni/printfInd.h' fh = open(fname, 'w') fh.write('class DisplayInd : public DisplayIndWrapper\n') fh.write('{\n') fh.write('public:\n') fh.write(' DisplayInd(unsigned int id, PortalPoller *poller) : DisplayIndWrapper(id, poller) {}\n') for item in cppind: fh.write(item) fh.write('};\n') fh.close() if bsvind != []: fname = sys.argv[1] + '/generatedbsv/DisplayInd.bsv' fh = open(fname, 'w') fh.write('interface DisplayInd;\n') for item in bsvind: fh.write(item) fh.write('endinterface\n') fh.close() sys.exit(0) ================================================ FILE: scripts/reorderbytes.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2014 Quanta Research Cambridge, Inc. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import sys, array if __name__=='__main__': if len(sys.argv) != 3: print('reorderbytes ') sys.exit(1) filename = sys.argv[1] if filename == '-': infile = sys.stdin else: infile = open(filename, 'rb') readarr = array.array('I', infile.read()) readarr.byteswap() open(sys.argv[2], 'wb').write(readarr.tostring()) ================================================ FILE: scripts/run.android ================================================ #!/usr/bin/env python3 # Copyright (c) 2013 Quanta Research Cambridge, Inc. # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function import argparse import os import socket import subprocess import sys import discover_tcp scriptdir=os.path.dirname(sys.argv[0]) sys.path.append(scriptdir) from adb import adb_commands from adb import common from argparse import RawTextHelpFormatter timelimit=600 if 'RUNTIMELIMIT' in os.environ: timelimit = int(os.environ['RUNTIMELIMIT']) buildbot_build=None if 'BUILDBOT_BUILD_NUMBER' in os.environ: buildbot_build = os.environ['BUILDBOT_BUILD_NUMBER'] if 'RUNPARAM' in os.environ: ipaddr = os.environ['RUNPARAM'] else: ipaddr = None buildbot_url='http://connectalbuild.qrclab.com/archive/' if 'BUILDBOT_URL' in os.environ: buildbot_url=os.environ['BUILDBOT_URL'] epilog = ''' Will download the bit file and executable from buildbot if buildbot-url, project, and build-number are specified. The buildbot-url defaults to %(buildbot_url)s. Will download the bit file and executable from an arbitrary location using rsync if rsync-path is specified. If you require a non-default identity file for rsync, add the following lines to ~/.ssh/config: Host HostName User Port 22 IdentityFile --- ''' % { 'buildbot_url': buildbot_url } argparser = argparse.ArgumentParser("Run Connectal apps on Android Zynq boards.", epilog=epilog, formatter_class=RawTextHelpFormatter) argparser.add_argument('androidexe', help='Android executable for the Zynq', nargs='?') argparser.add_argument('push', help='Additional files to push to the target before execution', nargs='*', default=[]) argparser.add_argument('--pull', help='Additional files to pull from the target after execution', nargs='*', default=[]) argparser.add_argument('-t', '--timelimit', type=int, default=timelimit, help='Time limit for jobs running on the zedboard. Defaults to value of environment variable RUNTIMELIMIT or 600 seconds.') argparser.add_argument('-a', '--ipaddr', default=ipaddr, help='IP address of target board') argparser.add_argument('-u', '--buildbot-url', default=buildbot_url, help='Base URL of buildbot.') argparser.add_argument('-p', '--project', help='Name of project on buildbot.') argparser.add_argument('-b', '--build-number', help='Build number on buildbot.') argparser.add_argument('-n', '--board-name', help='String in \'hostname\' on the SDCard') argparser.add_argument('-r', '--rsync-path', help='rsync path to android.exe (hostname:/home/.../zedboard/bin/)') def run_android(androidexe, pushFiles, pullFiles=[]): ipaddr = options.ipaddr if ipaddr: if ipaddr.find(':') == -1: ipaddr = ipaddr + ':5555' else: if (options.board_name): found = False discover_tcp.detect_network() for ip,name in discover_tcp.zedboards: if options.board_name == name: ipaddr = ip found = True print("found %s at %s" %(name,ip)) if not found: print("unable to find %s on your subnet" % name) else: p = subprocess.Popen('checkip') ipaddr = p.stdout.read() ipaddr = ipaddr.replace('\n', '') ipaddr = ipaddr.replace('\r', '') ipaddr = ipaddr + ':5555' device_serial = ipaddr print('connecting to %s' % device_serial) connected = False while not connected: try: connection = adb_commands.AdbCommands.ConnectDevice(serial=device_serial) connected = True except socket.error: #print('socket.error', sys.exc_info()) pass print('Reconnecting') connected = False while not connected: try: connection = adb_commands.AdbCommands.ConnectDevice(serial=device_serial) connected = True except socket.error: #print('socket.error', sys.exc_info()) pass params = { 'time': options.timelimit, 'env': '', 'exe': os.path.basename(androidexe), 'args': ' '.join([os.path.basename(f) for f in pushFiles]), } nofpgajtag = os.environ.get('NOFPGAJTAG') if nofpgajtag != None: params['env'] += 'NOFPGAJTAG= ' print('Sending files to the zedboard') connection.Push(androidexe, '/mnt/sdcard/tmp/%(exe)s' % params) connection.Shell('chmod agu+rx /mnt/sdcard/tmp/%(exe)s' % params) for f in pushFiles: print('Pushing file %s' % f) connection.Push(f, '/mnt/sdcard/tmp/%s' % os.path.basename(f)) connection.Shell("touch /mnt/sdcard/tmp/perf.monkit") print('Running %(exe)s with timelimit %(time)d' % params) cmd = ("cd /mnt/sdcard/tmp/; rm -f /mnt/sdcard/tmp/exit.status; %(env)s /mnt/sdcard/timelimit -t %(time)d ./%(exe)s %(args)s; echo $? > /mnt/sdcard/tmp/exit.status" % params) for line in connection.StreamingShell(cmd): sys.stdout.write(line) connection.Pull('/mnt/sdcard/tmp/exit.status', 'exit.status') connection.Pull('/mnt/sdcard/tmp/perf.monkit', 'perf.monkit') for f in pullFiles: print('pulling %s' % f) connection.Pull('/mnt/sdcard/tmp/%s' % f, f) connection.Shell('rm -vf %s' % ' '.join([os.path.basename(f) for f in [androidexe] + pushFiles])) status = int(open('exit.status').read()) print('status=%d' % status) sys.exit(status) if __name__ == '__main__': options = argparser.parse_args() if options.buildbot_url and options.project and options.build_number: # download android.exe options.androidexe = 'android.exe' url = '%s/%s/%s/bin/android.exe' % (options.buildbot_url, options.project, options.build_number) print('downloading', url) status = subprocess.call(['curl', '-f', '-O', url]) if status != 0: #print 'curl returned error', status sys.exit(status) elif options.rsync_path: options.androidexe = 'android.exe' status = subprocess.call(['rsync', '-av', '%s/android.exe' % (options.rsync_path), '.']) if status != 0: sys.exit(status) if not options.androidexe: argparser.print_help() sys.exit(1) run_android(options.androidexe, options.push, options.pull) ================================================ FILE: scripts/run.android.sh ================================================ # set -x set -e export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" echo "run.android parameters are:" $* androidexe=$1 if [ "$BUILDBOT_URL" == "" ]; then BUILDBOT_URL="http://sj9.qrclab.com/archive" fi if [ "$BUILDBOT_BUILD" != "" ]; then mkdir -p zedboard/bin (cd zedboard/bin; \ curl -v -O $BUILDBOT_URL/$BUILDBOT_BUILD/bin/android.exe ; \ curl -v -O $BUILDBOT_URL/$BUILDBOT_BUILD/bin/mkTop.xdevcfg.bin.gz) chmod agu+rx zedboard/bin/android.exe androidexe=zedboard/bin/android.exe fi if [ "$RUNPARAM" != "" ]; then ZEDBOARD_IPADDR=$RUNPARAM else ZEDBOARD_IPADDR=`checkip` fi if [ "$RUNTIMELIMIT" != "" ]; then TIMELIMIT=$RUNTIMELIMIT else TIMELIMIT=180 fi ANDROID_SERIAL=$ZEDBOARD_IPADDR:5555 exename=`basename $androidexe` adb -s $ANDROID_SERIAL disconnect $ZEDBOARD_IPADDR sleep 2 adb connect $ZEDBOARD_IPADDR adb -s $ANDROID_SERIAL root sleep 2 adb connect $ZEDBOARD_IPADDR ## sometimes /mnt/sdcard is readonly: adb -s $ANDROID_SERIAL shell mount -o remount,rw /mnt/sdcard adb -s $ANDROID_SERIAL shell mkdir -p /mnt/sdcard/tmp adb -s $ANDROID_SERIAL shell mount -t tmpfs tmpfs /mnt/sdcard/tmp adb -s $ANDROID_SERIAL push $androidexe /mnt/sdcard/tmp for f in $RUNFILES; do adb -s $ANDROID_SERIAL push $f /mnt/sdcard/tmp done adb -s $ANDROID_SERIAL shell rmmod portalmem adb -s $ANDROID_SERIAL shell rmmod zynqportal adb -s $ANDROID_SERIAL shell insmod /mnt/sdcard/portalmem.ko adb -s $ANDROID_SERIAL shell insmod /mnt/sdcard/zynqportal.ko adb -s $ANDROID_SERIAL shell "pwd" adb -s $ANDROID_SERIAL shell touch /mnt/sdcard/tmp/perf.monkit if [ "$CONNECTAL_DEBUG" != "" ]; then adb -s $ANDROID_SERIAL forward tcp:5039 tcp:5039 adb -s $ANDROID_SERIAL shell gdbserver :5039 /mnt/sdcard/tmp/android.exe & TEMP=`dirname $androidexe`/../.. TEMPDIR=$TEMP/obj/local/armeabi TEMPSCRIPT=$TEMP/xxfoo echo set solib-search-path $TEMPDIR >$TEMPSCRIPT echo target remote :5039 >>$TEMPSCRIPT `ndk-which gdb` --command=$TEMPSCRIPT $TEMPDIR/android.exe else adb -s $ANDROID_SERIAL shell "cd /mnt/sdcard/tmp/; rm -f /mnt/sdcard/tmp/exit.status; /mnt/sdcard/timelimit -t $TIMELIMIT ./$exename $3; echo \$? > /mnt/sdcard/tmp/exit.status" adb -s $ANDROID_SERIAL pull /mnt/sdcard/tmp/exit.status ./ adb -s $ANDROID_SERIAL pull /mnt/sdcard/tmp/perf.monkit `dirname $androidexe` fi adb -s $ANDROID_SERIAL shell rm -f /mnt/sdcard/tmp/`basename $androidexe` /mnt/sdcard/tmp/perf.monkit pwd status=`cat exit.status` if [ "$status" != "0" ]; then status=1 fi exit $status ================================================ FILE: scripts/run.parallella.sh ================================================ # # push programs to a parallella board # running linux, and execute set -x set -e export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" echo "run.parallella.sh parameters are:" $* bitfile=$1 ubuntuexe=$2 parallellahost=$3 if [ "$RUNTIMELIMIT" != "" ]; then TIMELIMIT=$RUNTIMELIMIT else TIMELIMIT=180 fi exename=`basename $ubuntuexe` for f in $RUNFILES; do scp $f $parallellahost:/mnt/sdcard/tmp done scp $bitfile $parallellahost:/tmp scp $ubuntuexe $parallellahost:/tmp scp $CONNECTALDIR/drivers/portalmem/portalmem.ko $parallellahost:/tmp scp $CONNECTALDIR/drivers/zynqportal/zynqportal.ko $parallellahost:/tmp set +e ssh $parallellahost sudo rmmod portalmem ssh $parallellahost sudo rmmod zynqportal set -e ssh $parallellahost sudo insmod /tmp/portalmem.ko ssh $parallellahost sudo insmod /tmp/zynqportal.ko ssh $parallellahost sudo "gzip -dc /tmp/`basename $bitfile` >/dev/xdevcfg" ssh $parallellahost sudo cat /dev/connectal ssh $parallellahost sudo /tmp/$exename status=0 if [ "$status" != "0" ]; then status=1 fi exit $status ================================================ FILE: scripts/run.pcietest ================================================ #!/bin/bash #set -x set -e export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" echo "run.pcie parameters are:" $* SSHPARAM=" -o StrictHostKeyChecking=no" if [ "$1" == "" ]; then echo "usage: $0 ubuntu.exe" >&2 exit -1 fi if [ "$SERIALNO" != "" ]; then BOARD_SERIAL="SERIALNO=$SERIALNO" else BOARD_SERIAL="" fi if [ "$RUNTIMELIMIT" != "" ]; then TIMELIMIT=$RUNTIMELIMIT else TIMELIMIT=3m fi ENV="" if [ "$RUNENV" != "" ]; then for e in `env | grep $RUNENV | grep -v RUNENV | sed 's/=(.*)/=\"$1\"/'`; do ENV="$ENV $e" done fi if [ "$RUNPARAM" != "" ]; then if [ "$ENV" != "" ]; then echo "sending environment variables $ENV" fi RUNPARAMTEMP=$RUNPARAM:22 array=(${RUNPARAMTEMP//:/ }) RUNIP=${array[0]} RUNPORT=${array[1]} TEMPDIR=/tmp/`uname -n`-$PPID-pcie ssh $SSHPARAM -p $RUNPORT $RUNIP "rm -rf $TEMPDIR; mkdir -p $TEMPDIR" || exit 1 scp -P $RUNPORT $* $RUNIP:$TEMPDIR || exit 2 EXE=$1 EXENAME=`basename $1` ARGS="" shift echo "ARGS=$*" for arg in $*; do arg_basename=`basename $arg`; ARGS="$ARGS $TEMPDIR/$arg_basename"; done ssh $SSHPARAM -p $RUNPORT $RUNIP "$BOARD_SERIAL $ENV timeout $TIMELIMIT catchsegv $TEMPDIR/$EXENAME $ARGS"; status=$? ssh $SSHPARAM -p $RUNPORT $RUNIP "pcieflat > $TEMPDIR/pcieflat.txt" scp -P $RUNPORT $RUNIP:$TEMPDIR/pcieflat.txt `dirname $EXE` ssh $SSHPARAM -p $RUNPORT $RUNIP "rm -rf $TEMPDIR" exit $status else timeout 3m catchsegv $1; status=$? if [ "$PORTAL_DUMP_MAP" != "" ]; then pcieflat -j $PORTAL_DUMP_MAP generatedDesignInterfaceFile.json > bin/pcieflat.txt else pcieflat > bin/pcieflat.txt fi exit $status fi ================================================ FILE: scripts/run.pcietest.altera ================================================ # set -x set -e export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" echo "run.de5test parameters are:" $* SSHPARAM=" -o StrictHostKeyChecking=no" if [ "$SERIALNO" != "" ]; then BOARD_USB="-c $SERIALNO" else BOARD_USB="-c 1" fi if [ "$RUNTIMELIMIT" != "" ]; then TIMELIMIT=$RUNTIMELIMIT else TIMELIMIT=3m fi if [ "$RUNPARAM" != "" ]; then TEMPDIR=/tmp/`uname -n`-$PPID-pcie ssh $SSHPARAM $RUNPARAM "rm -rf $TEMPDIR; mkdir -p $TEMPDIR" scp $1 $2 $RUNPARAM:$TEMPDIR BINNAME=`basename $1` EXENAME=`basename $2` if [ "$NOPROGRAM" != "1" ]; then ssh $SSHPARAM $RUNPARAM "fpgajtag $BOARD_USB $TEMPDIR/$BINNAME" else echo "not programming $BOARD" fi else if [ "$NOPROGRAM" != "1" ]; then echo $1 quartus_pgm $BOARD_USB -m jtag -o p\;$1 sleep 1 fi fi ================================================ FILE: scripts/run_on_daffodil ================================================ #! /bin/bash ./run.android --buildbot-url=http://connectalbuild.qrclab.com/archive --project=connectal-simple/zedboard --build-number=10 --board-name=daffodil_zedboard ================================================ FILE: scripts/syntax.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2014 Quanta Research Cambridge, Inc # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # from __future__ import print_function import ply.lex as lex import AST import json, os, re, sys import bsvpreprocess import globalv import cppgen, bsvgen scripthome = os.path.dirname(os.path.abspath(__file__)) noisyFlag=True parseDebugFlag=False parseTrace=False tokens = ( 'AMPER', 'AMPERAMPER', 'AMPERAMPERAMPER', 'APOSTROPHE', 'BANG', 'BAR', 'BARBAR', 'BUILTINVAR', 'CARET', 'COLON', 'COLONCOLON', 'COMMA', 'DOT', 'EQEQ', 'EQUAL', 'GEQ', 'GREATER', 'GREATERGREATER', 'HASH', 'LARROW', 'LBRACE', 'LBRACKET', 'LEQ', 'LESS', 'LESSLESS', 'LPAREN', 'LPARENSTAR', 'MINUS', 'NEQ', 'NUM', 'PERCENT', 'PLUS', 'QUESTION', 'RBRACE', 'RBRACKET', 'RPAREN', 'RPARENSTAR', 'SEMICOLON', 'SLASH', 'STAR', 'STARSTAR', 'STR', 'TILDE', 'TILDEAMPER', 'TILDEBAR', 'TILDECARET', 'VAR' ) reserved = { 'action': 'TOKACTION', 'Action': 'TOKUACTION', 'actionvalue': 'TOKACTIONVALUE', 'BDPI': 'TOKBDPI', 'begin': 'TOKBEGIN', 'BVI': 'TOKBVI', 'C': 'TOKC', 'case': 'TOKCASE', 'CF': 'TOKCF', 'clocked_by': 'TOKCLOCKED_BY', 'default': 'TOKDEFAULT', 'default_clock': 'TOKDEFAULT_CLOCK', 'default_reset': 'TOKDEFAULT_RESET', '`define': 'TOKTICKDEFINE', 'dependencies': 'TOKDEPENDENCIES', 'deriving': 'TOKDERIVING', 'determines': 'TOKDETERMINES', 'else': 'TOKELSE', 'enable': 'TOKENABLE', 'end': 'TOKEND', 'endaction': 'TOKENDACTION', 'endactionvalue': 'TOKENDACTIONVALUE', 'endcase': 'TOKENDCASE', 'endfunction': 'TOKENDFUNCTION', 'endinstance': 'TOKENDINSTANCE', 'endinterface': 'TOKENDINTERFACE', 'endmethod': 'TOKENDMETHOD', 'endmodule': 'TOKENDMODULE', 'endpackage': 'TOKENDPACKAGE', 'endpar': 'TOKENDPAR', 'endrule': 'TOKENDRULE', 'endrules': 'TOKENDRULES', 'endseq': 'TOKENDSEQ', 'endtypeclass': 'TOKENDTYPECLASS', 'enum': 'TOKENUM', 'export': 'TOKEXPORT', 'for': 'TOKFOR', 'function': 'TOKFUNCTION', 'if': 'TOKIF', 'import': 'TOKIMPORT', # 'in': 'TOKIN', 'input_clock': 'TOKINPUT_CLOCK', 'input_reset': 'TOKINPUT_RESET', 'instance': 'TOKINSTANCE', 'interface': 'TOKINTERFACE', 'let': 'TOKLET', 'match': 'TOKMATCH', 'matches': 'TOKMATCHES', 'method': 'TOKMETHOD', 'module': 'TOKMODULE', 'no_reset': 'TOKNO_RESET', 'numeric': 'TOKNUMERIC', 'output_clock': 'TOKOUTPUT_CLOCK', 'output_reset': 'TOKOUTPUT_RESET', 'package': 'TOKPACKAGE', 'par': 'TOKPAR', 'port': 'TOKPORT', 'parameter': 'TOKPARAMETER', 'port': 'TOKPORT', 'provisos': 'TOKPROVISOS', 'ready': 'TOKREADY', 'reset_by': 'TOKRESET_BY', 'return': 'TOKRETURN', 'rule': 'TOKRULE', 'rules': 'TOKRULES', 'SB': 'TOKSB', 'SBR': 'TOKSBR', 'schedule': 'TOKSCHEDULE', 'seq': 'TOKSEQ', '_when_': 'TOKWHEN', 'Stmt' : 'TOKSTMT', 'struct': 'TOKSTRUCT', 'tagged': 'TOKTAGGED', 'type': 'TOKTYPE', 'typeclass': 'TOKTYPECLASS', 'typedef': 'TOKTYPEDEF', 'union': 'TOKUNION', 'while': 'TOKWHILE', } for tok in reserved.values(): tokens = tokens + (tok,) t_AMPER = r'&' t_AMPERAMPER = r'&&' t_AMPERAMPERAMPER = r'&&&' t_APOSTROPHE = r'\'' t_BANG = r'!' t_BAR = r'\|' t_BARBAR = r'\|\|' t_CARET = r'\^' t_COLON = r':' t_COLONCOLON = r'::' t_COMMA = r',' t_DOT = r'[\.]' t_EQEQ = r'==' t_EQUAL = r'=' t_GEQ = r'>=' t_GREATER = r'>' t_GREATERGREATER = r'>>' t_HASH = r'\#' t_LARROW = r'<-' t_LBRACE = r'{' t_LBRACKET = r'\[' t_LEQ = r'<=' t_LESS = r'<' t_LESSLESS = r'<<' t_LPAREN = r'\(' t_LPARENSTAR = r'\(\*' t_MINUS = r'[-]' t_NEQ = r'!=' t_NUM = r'(([0-9]+\'?[bdh\.]?[0-9a-zA-Z?]*)|(\'[bdh\.]?[0-9a-zA-Z?]+))' t_PERCENT = r'%' t_PLUS = r'\+' t_QUESTION = r'\?' t_RBRACE = r'}' t_RBRACKET = r'\]' t_RPAREN = r'\)' t_RPARENSTAR = r'\*\)' t_SEMICOLON = r';' t_SLASH = r'/' t_STAR = r'\*' t_STARSTAR = r'\*\*' t_STR = r'"[^\"]*"' t_TILDE = r'~' t_TILDEAMPER = r'~\&' t_TILDEBAR = r'~\|' t_TILDECARET = r'~^' t_ignore = ' \t\f' def t_error(t): print("Illegal character '%s' in file '%s'" % (t.value[0], globalfilename)) t.lexer.skip(1) def p_error(errtoken): if hasattr(errtoken, 'lineno'): sys.stderr.write("%s:%d: Syntax error, token=%s\n" % (globalfilename, errtoken.lineno, errtoken.type)) else: sys.stderr.write("%s: Syntax error, token=%s\n" % (globalfilename, errtoken)) return None def t_VAR(t): r'`?([a-zA-Z_][$a-zA-Z0-9_]*)|(\\[-+*/|^&][*]?)' t.type = reserved.get(t.value,'VAR') return t t_BUILTINVAR = r'\$[a-zA-Z_][a-zA-Z0-9_]*' def t_newline(t): r'\n+' t.lexer.lineno += len(t.value) def t_COMMENT(t): r'//.*' pass def t_MCOMMENT(t): r'/\*(.|\n)*?\*/' #print(t.value, t.value.count('\n'), t.lineno) t.lineno += t.value.count('\n') import ply.yacc as yacc def p_goal(p): 'goal : package ' p[0] = p[1] def p_typeParams(p): '''typeParams : | type | typeParams COMMA type''' if len(p) == 2: p[0] = [p[1]] elif len(p) == 4: p[0] = p[1] + [p[3]] else: p[0] = [] def p_type(p): '''type : VAR | VAR COLONCOLON VAR | NUM | TOKUACTION | VAR HASH LPAREN typeParams RPAREN | VAR COLONCOLON VAR HASH LPAREN typeParams RPAREN''' if len(p) == 2: p[0] = AST.Type(p[1], []) elif len(p) == 4: p[0] = p[3] elif len(p) == 8: p[0] = AST.Type(p[3], p[6]) else: p[0] = AST.Type(p[1], p[4]) def p_expressions(p): '''expressions : expression | | expressions COMMA expression''' precedence = ( ('left', 'STAR', 'SLASH', 'PERCENT'), ('left', 'PLUS', 'MINUS'), ('left', 'GREATERGREATER', 'LESSLESS'), ('left', 'LEQ', 'GEQ', 'LESS', 'GREATER'), ('left', 'EQEQ', 'NEQ'), ('left', 'AMPER'), ('left', 'CARET'), ('left', 'TILDECARET'), ('left', 'BAR'), ('left', 'AMPERAMPER'), ('left', 'BARBAR'), ('left', 'AMPERAMPERAMPER') ) def p_colonVar(p): '''colonVar : | COLON VAR''' def p_expression(p): '''expression : caseExpr | binaryExpression''' p[0] = p[1] def p_caseExprItem(p): '''caseExprItem : pattern COLON expression SEMICOLON''' def p_caseExprItems(p): '''caseExprItems : | caseExprItems caseExprItem''' def p_defaultExprItem(p): '''defaultExprItem : | TOKDEFAULT expression SEMICOLON | TOKDEFAULT COLON expression SEMICOLON''' def p_caseExpr(p): '''caseExpr : TOKCASE LPAREN expression RPAREN caseExprItems defaultExprItem TOKENDCASE | TOKCASE LPAREN expression RPAREN TOKMATCHES caseExprItems defaultExprItem TOKENDCASE''' def p_binaryExpression(p): '''binaryExpression : unaryExpression | binaryExpression AMPERAMPERAMPER binaryExpression | binaryExpression MINUS binaryExpression | binaryExpression PLUS binaryExpression | binaryExpression STAR binaryExpression | binaryExpression STARSTAR binaryExpression | binaryExpression APOSTROPHE binaryExpression | binaryExpression SLASH binaryExpression | binaryExpression CARET binaryExpression | binaryExpression LESS binaryExpression | binaryExpression GREATER binaryExpression | binaryExpression GEQ binaryExpression | binaryExpression LESSLESS binaryExpression | binaryExpression LEQ binaryExpression | binaryExpression GREATERGREATER binaryExpression | binaryExpression EQEQ binaryExpression | binaryExpression NEQ binaryExpression | binaryExpression AMPER binaryExpression | binaryExpression AMPERAMPER binaryExpression | binaryExpression BAR binaryExpression | binaryExpression BARBAR binaryExpression | binaryExpression PERCENT binaryExpression''' p[0] = p[1] def p_unaryExpression(p): '''unaryExpression : term | PLUS term | MINUS term | BANG term | TILDE term | AMPER term | TILDEAMPER term | BAR term | TILDEBAR term | CARET term | TILDECARET term | TOKACTION colonVar expressionStmts TOKENDACTION colonVar | TOKACTIONVALUE colonVar expressionStmts TOKENDACTIONVALUE colonVar ''' p[0] = p[1] def p_term(p): '''term : type | type LBRACKET expression RBRACKET | type LBRACKET expression COLON expression RBRACKET | STR | QUESTION | term QUESTION expression | term QUESTION expression COLON expression | LPAREN expression RPAREN | TOKINTERFACE VAR interfaceHashParams SEMICOLON expressionStmts TOKENDINTERFACE colonVar | TOKINTERFACE VAR COLONCOLON VAR interfaceHashParams SEMICOLON expressionStmts TOKENDINTERFACE colonVar | TOKINTERFACE VAR expressionStmts TOKENDINTERFACE colonVar | TOKINTERFACE VAR COLONCOLON VAR expressionStmts TOKENDINTERFACE colonVar | BUILTINVAR | TOKCLOCKED_BY expression | TOKRESET_BY expression | TOKTAGGED VAR | TOKTAGGED VAR expression | TOKTAGGED VAR LBRACE structInits RBRACE | term LBRACE structInits RBRACE | term TOKMATCHES pattern | LBRACE expressions RBRACE | term DOT VAR | term LBRACKET expression RBRACKET DOT term | term LBRACKET expression RBRACKET | term LBRACKET expression COLON expression RBRACKET | term LPAREN params RPAREN DOT term | term LPAREN params RPAREN''' if len(p) > 2 and type(p[1]) == str: p[0] = p[2] else: p[0] = p[1] def p_structInits(p): '''structInits : | structInits COMMA VAR COLON expression | structInits COMMA VAR COLON DOT VAR | VAR COLON expression | VAR COLON DOT VAR''' def p_structPatternElements(p): '''structPatternElements : VAR COLON pattern | structPatternElements COMMA VAR COLON pattern ''' def p_pattern(p): '''pattern : TOKTAGGED VAR | TOKTAGGED VAR DOT VAR | TOKTAGGED VAR LBRACE structPatternElements RBRACE | LBRACE patterns RBRACE | DOT VAR | DOT STAR | NUM''' def p_patterns(p): '''patterns : pattern | patterns COMMA pattern''' def p_importDecl(p): 'importDecl : TOKIMPORT VAR COLONCOLON STAR SEMICOLON' if not p[2] in globalimports: globalimports.append(p[2]) p[0] = p[2] def p_importDecls(p): '''importDecls : | importDecls importDecl''' def p_exportDecl(p): '''exportDecl : TOKEXPORT VAR LPAREN DOT DOT RPAREN SEMICOLON | TOKEXPORT VAR SEMICOLON | TOKEXPORT VAR COLONCOLON STAR SEMICOLON''' p[0] = p[2] def p_exportDecls(p): '''exportDecls : | exportDecls exportDecl''' def p_interfaceFormalParam(p): '''interfaceFormalParam : TOKTYPE VAR | VAR interfaceHashParams | NUM | TOKNUMERIC TOKTYPE VAR''' if len(p) == 2: p[0] = p[1] elif len(p) == 3: p[0] = p[2] else: p[0] = p[3] def p_interfaceFormalParams(p): '''interfaceFormalParams : interfaceFormalParam | interfaceFormalParams COMMA interfaceFormalParam''' if len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] + [p[3]] def p_interfaceHashParams(p): '''interfaceHashParams : | HASH LPAREN interfaceFormalParams RPAREN''' if len(p) == 5: p[0] = p[3] else: p[0] = [] def p_instanceAttributes(p): '''instanceAttributes : | instanceAttributes LPARENSTAR attrSpecs RPARENSTAR''' def p_subinterfaceDecl(p): '''subinterfaceDecl : instanceAttributes TOKINTERFACE type VAR SEMICOLON | type VAR SEMICOLON''' if len(p) == 6: name = p[4] t = p[3] elif len(p) == 5: name = p[3] t = p[2] else: name = p[2] t = p[1] p[0] = AST.Interface(t.name, t.params, [], name, globalfilename) def p_parenthesizedFormalParams(p): '''parenthesizedFormalParams : | LPAREN RPAREN | LPAREN moduleFormalParams RPAREN''' if len(p) < 4: p[0] = [] else: p[0] = p[2] def p_methodDecl(p): '''methodDecl : TOKMETHOD type VAR parenthesizedFormalParams SEMICOLON''' p[0] = AST.Method(p[3], p[2], p[4]) def p_interfaceStmt(p): '''interfaceStmt : subinterfaceDecl | methodDecl ''' p[0] = p[1] def p_interfaceStmts(p): '''interfaceStmts : | interfaceStmts interfaceStmt''' if len(p) == 3: p[0] = p[1] + [p[2]] else: p[0] = [] def p_interfaceDecl(p): '''interfaceDecl : instanceAttributes TOKINTERFACE VAR interfaceHashParams SEMICOLON interfaceStmts TOKENDINTERFACE colonVar''' interface = AST.Interface(p[3], p[4], p[6], None, globalfilename) p[0] = interface # the token '[' signifies an array type def p_arrayDecl(p): '''arrayDecl : type VAR LBRACKET NUM RBRACKET''' arr_t = AST.Type(p[3],p[1]) p[0] = AST.Variable(p[2], arr_t, None) def p_varDecl(p): '''varDecl : arrayDecl | type VAR''' if len(p)==3: p[0] = AST.Variable(p[2], p[1], None) else: p[0] = p[1] def p_params(p): '''params : expressions | TOKSEQ fsmStmts TOKENDSEQ''' def p_lvalue(p): '''lvalue : VAR | LPAREN lvalue RPAREN | lvalue DOT VAR | TOKACTION fsmStmts TOKENDACTION | lvalue LBRACKET expression RBRACKET | lvalue LBRACKET expression COLON expression RBRACKET | TOKMATCH pattern''' def p_varAssign1(p): '''varAssign1 : TOKLET VAR EQUAL expression | TOKLET VAR LARROW expression''' p[0] = AST.Variable(p[2], None, p[4]) def p_varAssign2(p): '''varAssign2 : type VAR EQUAL expression | type VAR LBRACKET expression RBRACKET EQUAL expression | type VAR LBRACKET expression RBRACKET LBRACKET NUM RBRACKET EQUAL expression | type VAR LARROW expression''' p[0] = AST.Variable(p[2], p[1], p[4]) def p_varAssign3(p): '''varAssign3 : lvalue EQUAL expression | lvalue LEQ expression | lvalue LARROW expression''' p[0] = AST.Variable(p[2], p[1], None) def p_varAssign(p): '''varAssign : varAssign1 | varAssign2 | varAssign3''' def p_ruleCond(p): '''ruleCond : LPAREN expression RPAREN''' def p_implicitCond(p): '''implicitCond : | TOKIF LPAREN expression RPAREN''' def p_rule(p): '''rule : TOKRULE VAR implicitCond SEMICOLON expressionStmts TOKENDRULE colonVar | TOKRULE VAR ruleCond implicitCond SEMICOLON expressionStmts TOKENDRULE colonVar''' def p_ifStmt(p): '''ifStmt : TOKIF LPAREN expression RPAREN fsmStmt | TOKIF LPAREN expression RPAREN fsmStmt TOKELSE fsmStmt''' def p_caseItem(p): '''caseItem : expressions COLON expressionStmt''' def p_caseItems(p): '''caseItems : | caseItems caseItem''' def p_defaultItem(p): '''defaultItem : | TOKDEFAULT expressionStmt | TOKDEFAULT COLON expressionStmt''' def p_caseStmt(p): '''caseStmt : TOKCASE LPAREN expression RPAREN caseItems defaultItem TOKENDCASE | TOKCASE LPAREN expression RPAREN TOKMATCHES caseItems defaultItem TOKENDCASE''' def p_forStmt(p): '''forStmt : TOKFOR LPAREN varAssign SEMICOLON expression SEMICOLON varAssign RPAREN fsmStmt''' def p_whenStmt(p): '''whenStmt : TOKWHEN LPAREN expression RPAREN LPAREN expression RPAREN SEMICOLON''' def p_beginStmt(p): '''beginStmt : TOKBEGIN expressionStmts TOKEND''' def p_expressionStmt(p): '''expressionStmt : TOKRETURN expression SEMICOLON | fsmStmtDef | whenStmt | lvalue SEMICOLON | lvalue LPAREN params RPAREN DOT expression SEMICOLON | lvalue LPAREN params RPAREN SEMICOLON | BUILTINVAR LPAREN expressions RPAREN SEMICOLON | varAssign SEMICOLON | varDecl SEMICOLON | beginStmt | ifStmt | caseStmt | forStmt | interfaceDef | functionDef | methodDef | moduleDef | TOKACTION colonVar expressionStmts TOKENDACTION colonVar | TOKACTIONVALUE colonVar expressionStmts TOKENDACTIONVALUE colonVar | typeDef | instanceAttributes rule | TOKACTION fsmStmts TOKENDACTION ''' if parseTrace: print('ENDSTATEMENT', [pitem for pitem in p]) def p_expressionStmts(p): '''expressionStmts : expressionStmts expressionStmt | ''' def p_provisos(p): '''provisos : | TOKPROVISOS LPAREN typeParams RPAREN''' if len(p) == 5: p[0] = p[3] else: p[0] = [] def p_endFunction(p): '''endFunction : TOKENDFUNCTION colonVar''' def p_functionBody(p): '''functionBody : SEMICOLON expressionStmts endFunction''' def p_functionValue(p): '''functionValue : EQUAL expression SEMICOLON''' def p_functionFormal(p): '''functionFormal : type VAR | VAR''' def p_functionFormals(p): '''functionFormals : | functionFormal | functionFormals COMMA functionFormal ''' def p_fsmStmt(p): '''fsmStmt : TOKSEQ fsmStmts TOKENDSEQ | TOKPAR fsmStmts TOKENDPAR | TOKWHILE ruleCond fsmStmt | expressionStmt''' def p_fsmStmts(p): '''fsmStmts : fsmStmt fsmStmts | fsmStmt''' def p_fsmStmtDef(p): '''fsmStmtDef : TOKSTMT VAR EQUAL fsmStmts SEMICOLON''' def p_functionDef(p): '''functionDef : instanceAttributes TOKFUNCTION type VAR LPAREN functionFormals RPAREN provisos functionBody | instanceAttributes TOKFUNCTION VAR LPAREN functionFormals RPAREN provisos functionBody | instanceAttributes TOKFUNCTION type VAR LPAREN functionFormals RPAREN provisos functionValue | instanceAttributes TOKFUNCTION VAR LPAREN functionFormals RPAREN provisos functionValue ''' if len(p) == 9: # no type p[0] = AST.Function(p[3], None, p[5]) else: p[0] = AST.Function(p[4], p[3], p[6]) def p_methodDef(p): '''methodDef : TOKMETHOD type VAR LPAREN functionFormals RPAREN implicitCond SEMICOLON methodBody | TOKMETHOD type VAR implicitCond SEMICOLON methodBody | TOKMETHOD type VAR EQUAL expression SEMICOLON | TOKMETHOD type VAR LPAREN functionFormals RPAREN EQUAL expression SEMICOLON | TOKMETHOD VAR LPAREN functionFormals RPAREN EQUAL expression SEMICOLON | TOKMETHOD VAR EQUAL expression SEMICOLON''' returnType = p[2] name = p[3] params = [] p[0] = AST.Method(name, returnType, params) def p_methodBody(p): '''methodBody : expressionStmts endMethod | endMethod''' def p_endMethod(p): '''endMethod : TOKENDMETHOD colonVar''' def p_unionMember(p): '''unionMember : type VAR SEMICOLON | subStruct VAR SEMICOLON | subUnion VAR SEMICOLON''' def p_subStruct(p): '''subStruct : TOKSTRUCT LBRACE structMembers RBRACE''' def p_structMembers(p): '''structMembers : | structMember | structMembers structMember''' if len(p) == 1: p[0] = [] elif len(p) == 2: p[0] = [p[1]] elif len(p) == 3: p[0] = p[1] + [p[2]] def p_structMember(p): '''structMember : type VAR SEMICOLON | subUnion VAR SEMICOLON''' p[0] = AST.StructMember(p[1], p[2]) def p_subUnion(p): '''subUnion : TOKUNION TOKTAGGED LBRACE unionMembers RBRACE''' def p_unionMembers(p): '''unionMembers : unionMember | unionMembers unionMember''' def p_taggedUnionDef(p): '''taggedUnionDef : TOKUNION TOKTAGGED LBRACE unionMembers RBRACE''' def p_structDef(p): '''structDef : TOKSTRUCT LBRACE structMembers RBRACE''' p[0] = AST.Struct(p[3]) def p_enumRange(p): '''enumRange : | LBRACKET NUM RBRACKET | LBRACKET NUM COLON NUM RBRACKET''' def p_enumElement(p): '''enumElement : VAR enumRange | VAR enumRange EQUAL NUM''' if len(p) == 3: p[0] = [p[1], None] else: p[0] = [p[1], p[4]] def p_enumElements(p): '''enumElements : enumElement | enumElements COMMA enumElement''' if len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] + [p[3]] def p_enumDef(p): '''enumDef : TOKENUM LBRACE enumElements RBRACE''' p[0] = AST.Enum(p[3]) def p_vardot(p): '''vardot : VAR | vardot DOT VAR''' if len(p) == 2: p[0] = p[1] else: p[0] = p[3] def p_vars(p): '''vars : vardot | vars COMMA vardot''' if len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] + [p[3]] def p_deriving(p): '''deriving : | TOKDERIVING LPAREN vars RPAREN''' if len(p) == 5: p[0] = p[3] else: p[0] = [] def p_macroDef(p): '''macroDef : TOKTICKDEFINE VAR expression''' def p_typeDefBody(p): '''typeDefBody : taggedUnionDef | structDef | enumDef | type''' p[0] = p[1] def p_typeDef(p): '''typeDef : TOKTYPEDEF typeDefBody VAR deriving SEMICOLON | TOKTYPEDEF typeDefBody VAR interfaceHashParams deriving SEMICOLON''' if len(p) == 6: p[0] = AST.TypeDef(p[2], p[3], []) else: p[0] = AST.TypeDef(p[2], p[3], p[4]) def p_interfaceDef(p): '''interfaceDef : TOKINTERFACE type VAR SEMICOLON expressionStmts TOKENDINTERFACE colonVar | TOKINTERFACE type VAR EQUAL expression SEMICOLON | TOKINTERFACE VAR EQUAL expression SEMICOLON''' if parseTrace: print('ENDINTERFACE', [pitem for pitem in p]) def p_formalParam(p): '''formalParam : type VAR''' param = AST.Param(p[2], p[1]) p[0] = param def p_moduleFormalParams(p): '''moduleFormalParams : formalParam | TOKFUNCTION type VAR parenthesizedFormalParams | moduleFormalParams COMMA formalParam |''' if len(p) == 1: p[0] = [] elif len(p) == 2: p[0] = [p[1]] elif len(p) == 5: p[0] = p[2] elif len(p) == 4: p[0] = p[1] + [p[3]] def p_moduleFormalArg(p): '''moduleFormalArg : instanceAttributes type | instanceAttributes type VAR''' def p_moduleFormalArgs(p): '''moduleFormalArgs : | moduleFormalArg | moduleFormalArgs COMMA moduleFormalArg''' if len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] + [p[3]] def p_moduleParamsArgs(p): '''moduleParamsArgs : | HASH LPAREN moduleFormalParams RPAREN | HASH LPAREN moduleFormalParams RPAREN LPAREN moduleFormalArgs RPAREN | LPAREN moduleFormalArgs RPAREN''' if len(p) == 8: p[0] = [ p[3], p[6] ] elif len(p) == 5: p[0] = [ p[3], None ] else: p[0] = [ None, p[2] ] def p_attrSpec(p): '''attrSpec : VAR | VAR EQUAL expression''' def p_attrSpecs(p): '''attrSpecs : attrSpec | attrSpecs COMMA attrSpec''' def p_moduleContext(p): '''moduleContext : | LBRACKET VAR RBRACKET''' if len(p) > 2: p[0] = p[2] def p_moduleDefHeader(p): '''moduleDefHeader : instanceAttributes TOKMODULE moduleContext VAR moduleParamsArgs provisos SEMICOLON''' p[0] = [p[3], p[4], p[5][0], p[5][1], p[6]] def p_moduleDef(p): '''moduleDef : moduleDefHeader expressionStmts TOKENDMODULE colonVar''' if parseTrace: print('ENDMODULE', [pitem for pitem in p]) p[0] = AST.Module(p[1][0], p[1][1], p[1][2], p[1][3], p[1][4], p[2]) def p_importBviDef(p): '''importBviDef : TOKIMPORT STR VAR EQUAL bviModuleDef | TOKIMPORT STR TOKFUNCTION TOKUACTION VAR LPAREN functionFormals RPAREN SEMICOLON''' p[0] = p[5] if len(p) > 6: p[0] = AST.Module(None, p[5], None, None, None, None) def p_bviModuleDef(p): '''bviModuleDef : instanceAttributes TOKMODULE moduleContext VAR moduleParamsArgs provisos SEMICOLON bviExpressionStmts TOKENDMODULE colonVar''' p[0] = AST.Module(p[3], p[4], p[5][0], p[5][1], p[6], p[8]) def p_bviExpressionStmts(p): '''bviExpressionStmts : bviExpressionStmts bviExpressionStmt | bviExpressionStmt ''' def p_bviExpressionStmt(p): '''bviExpressionStmt : TOKRETURN expression SEMICOLON | fsmStmtDef | whenStmt | lvalue SEMICOLON | lvalue LPAREN expressions RPAREN SEMICOLON | BUILTINVAR LPAREN expressions RPAREN SEMICOLON | varAssign SEMICOLON | varDecl SEMICOLON | beginStmt | ifStmt | caseStmt | forStmt | bviInterfaceDef | functionDef | bviMethodDef | moduleDef | TOKACTION colonVar expressionStmts TOKENDACTION colonVar | typeDef | instanceAttributes rule | TOKSEQ fsmStmts TOKENDSEQ | TOKPORT VAR EQUAL expression SEMICOLON | TOKPARAMETER VAR EQUAL expression SEMICOLON | TOKDEFAULT_CLOCK VAR LPAREN RPAREN SEMICOLON | TOKDEFAULT_CLOCK VAR LPAREN VAR RPAREN SEMICOLON | TOKDEFAULT_RESET VAR LPAREN RPAREN SEMICOLON | TOKDEFAULT_RESET TOKNO_RESET SEMICOLON | TOKDEFAULT_RESET VAR LPAREN VAR RPAREN SEMICOLON | TOKINPUT_CLOCK VAR LPAREN VAR RPAREN EQUAL expression SEMICOLON | TOKINPUT_RESET VAR LPAREN VAR RPAREN EQUAL expression SEMICOLON | TOKINPUT_RESET VAR LPAREN RPAREN EQUAL expression SEMICOLON | TOKOUTPUT_CLOCK VAR LPAREN VAR RPAREN SEMICOLON | TOKOUTPUT_RESET VAR LPAREN VAR RPAREN SEMICOLON | TOKSCHEDULE LPAREN vars RPAREN schedOp LPAREN vars RPAREN SEMICOLON''' def p_schedOp(p): '''schedOp : TOKCF | TOKC | TOKSB | TOKSBR''' def p_bviInterfaceDef(p): '''bviInterfaceDef : TOKINTERFACE type VAR SEMICOLON bviExpressionStmts TOKENDINTERFACE colonVar | TOKINTERFACE type VAR EQUAL expression SEMICOLON | TOKINTERFACE VAR EQUAL expression SEMICOLON''' def p_bviMethodAttributes(p): '''bviMethodAttributes : | bviMethodAttributes bviMethodAttribute''' def p_bviMethodAttribute(p): '''bviMethodAttribute : | TOKENABLE LPAREN instanceAttributes VAR RPAREN | TOKCLOCKED_BY LPAREN instanceAttributes VAR RPAREN | TOKRESET_BY LPAREN instanceAttributes VAR RPAREN''' def p_bviMethodDef(p): '''bviMethodDef : TOKMETHOD VAR LPAREN VAR RPAREN bviMethodAttributes SEMICOLON | TOKMETHOD VAR VAR LPAREN RPAREN bviMethodAttributes SEMICOLON''' def p_instanceDeclStmt(p): '''instanceDeclStmt : varAssign SEMICOLON | functionDef | moduleDef''' p[0] = p[1] def p_instanceDeclStmts(p): '''instanceDeclStmts : | instanceDeclStmt | instanceDeclStmts instanceDeclStmt''' def p_instanceDecl(p): '''instanceDecl : TOKINSTANCE VAR HASH LPAREN typeParams RPAREN provisos SEMICOLON instanceDeclStmts TOKENDINSTANCE''' p[0] = AST.TypeclassInstance(p[2], p[5], p[7], p[9]) def p_typeClassDeclStmts(p): '''typeClassDeclStmts : | moduleDefHeader''' def p_typeClassDecl(p): '''typeClassDecl : TOKTYPECLASS VAR HASH LPAREN interfaceFormalParams RPAREN provisos SEMICOLON typeClassDeclStmts TOKENDTYPECLASS''' p[0] = AST.Typeclass(p[2]) globalimports = [] globalfilename = None def p_packageStmt(p): '''packageStmt : interfaceDecl | typeClassDecl | functionDef | instanceDecl | varDecl SEMICOLON | varAssign SEMICOLON | moduleDef | macroDef | typeDef | importBviDef''' globalv.add_new(p[1]) def p_packageStmts(p): '''packageStmts : | packageStmts packageStmt exportDecls''' def p_beginPackage(p): '''beginPackage : | TOKPACKAGE VAR SEMICOLON''' def p_endPackage(p): '''endPackage : | TOKENDPACKAGE colonVar''' def p_package(p): '''package : beginPackage exportDecls importDecls packageStmts exportDecls endPackage''' p[0] = p[4] def syntax_parse(argdata, inputfilename, bsvdefines, bsvpath): global globalfilename globalfilename = inputfilename data = bsvpreprocess.preprocess(inputfilename, argdata + '\n', bsvdefines, bsvpath) lexer = lex.lex(errorlog=lex.NullLogger()) parserdir=scripthome+'/syntax' if not os.path.isdir(parserdir): os.makedirs(parserdir) if not (parserdir in sys.path): sys.path.append(parserdir) parser = yacc.yacc(optimize=1,errorlog=yacc.NullLogger(),outputdir=parserdir,debugfile=parserdir+'/parser.out') if noisyFlag: print('Parsing:', inputfilename) if parseDebugFlag: return parser.parse(data,debug=1) return parser.parse(data) def generate_bsvcpp(filelist, project_dir, bsvdefines, interfaces, bsvpath): for inputfile in filelist: syntax_parse(open(inputfile).read(), inputfile, bsvdefines, bsvpath) ## code generation pass ilist = [] for i in interfaces: ifc = globalv.globalvars.get(i) if not ifc: print('Connectal: Unable to locate the interface:', i) for keys in globalv.globalvars: print(' ', keys) sys.exit(1) ifc = ifc.instantiate(dict(zip(ifc.params, ifc.params))) ilist.append(ifc) for ditem in ifc.decls: for pitem in ditem.params: thisType = pitem.type p = globalv.globalvars.get(thisType.name) if p and thisType.params and p.params: myName = '%sL_%s_P' % (thisType.name, '_'.join([t.name for t in thisType.params if t])) pitem.oldtype = pitem.type pitem.type = AST.Type(myName, []) if not globalv.globalvars.get(myName): globalv.add_new(AST.TypeDef(p.tdtype.instantiate(dict(zip(p.params, thisType.params))), myName, [])) jsondata = AST.serialize_json(ilist, globalimports, bsvdefines) if project_dir: cppgen.generate_cpp(project_dir, noisyFlag, jsondata) bsvgen.generate_bsv(project_dir, noisyFlag, False, jsondata) if __name__=='__main__': if len(sys.argv) == 1: parserdir=scripthome+'/syntax' sys.path.append(parserdir) if not os.path.isdir(parserdir): os.makedirs(parserdir) parser = yacc.yacc(outputdir=parserdir,debugfile=parserdir+'/parser.out') import parsetab sys.exit(0) ifitems = [] t = os.environ.get('INTERFACES') if t: t = t.split() for item in t: if item not in ifitems: ifitems.append(item) deflist = [] t = os.environ.get('BSVDEFINES_LIST') if t: deflist = t.split() noisyFlag = os.environ.get('D') == '1' if os.environ.get('D'): parseDebugFlag=True if noisyFlag: parseTrace=True project_dir = os.environ.get('DTOP') tmp = os.environ.get('PROTODEBUG') if tmp: print('JSONNN', tmp) j2file = open(tmp).read() jsondata = json.loads(j2file) cppgen.generate_cpp(project_dir, noisyFlag, jsondata) bsvgen.generate_bsv(project_dir, noisyFlag, True, jsondata) else: bsvpath = os.environ.get('BSVPATH', []).split(':') generate_bsvcpp(sys.argv[1:], project_dir, deflist, ifitems, bsvpath) ================================================ FILE: scripts/topgen.py ================================================ #!/usr/bin/env python3 ## Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, copy, ## modify, merge, publish, distribute, sublicense, and/or sell copies ## of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## The above copyright notice and this permission notice shall be ## included in all copies or substantial portions of the Software. ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ## BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ## ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ## SOFTWARE. from __future__ import print_function import os, sys, shutil, string import argparse import util def newArgparser(): argparser = argparse.ArgumentParser("Generate Top.bsv for an project.") argparser.add_argument('--project-dir', help='project directory') argparser.add_argument('--filename', default='Top.bsv', help='name of generated file') argparser.add_argument('--topname', default='mkConnectalTop', help='name of generated module') argparser.add_argument('--ifcnames', default='IfcNames', help='name of interface names enum type and file') argparser.add_argument('--pintype', default=[], help='Type of pins interface', action='append') argparser.add_argument('--interface', default=[], help='exported interface declaration', action='append') argparser.add_argument('--portalclock', help='Portal clock source', default=None) argparser.add_argument('--importfiles', default=[], help='added imports', action='append') argparser.add_argument('--portname', default=[], help='added portal names to enum list', action='append') argparser.add_argument('--wrapper', default=[], help='exported wrapper interfaces', action='append') argparser.add_argument('--proxy', default=[], help='exported proxy interfaces', action='append') argparser.add_argument('--memread', default=[], help='memory read interfaces', action='append') argparser.add_argument('--memwrite', default=[], help='memory read interfaces', action='append') argparser.add_argument('--cnoc', help='generate mkCnocTop', action='store_true') argparser.add_argument('--integratedIndication', help='indication pipes instantiated in user module', action='store_true') return argparser argparser = newArgparser() topTemplate=''' import ConnectalConfig::*; import Vector::*; import BuildVector::*; import Portal::*; import CtrlMux::*; import HostInterface::*; import Connectable::*; import MemReadEngine::*; import MemWriteEngine::*; import ConnectalMemTypes::*; import MemServer::*; `include "ConnectalProjectConfig.bsv" import %(ifcnames)s::*; %(generatedImport)s %(pinsInterfaceDecl)s `ifndef IMPORT_HOSTIF (* synthesize *) `endif module %(topname)s `ifdef IMPORT_HOSTIF // no synthesis boundary #(HostInterface host) `else `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary #(Clock derivedClockIn, Reset derivedResetIn) `else // otherwise no params `endif `endif (%(moduleParam)s); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary HostInterface host = (interface HostInterface; interface Clock derivedClock = derivedClockIn; interface Reset derivedReset = derivedResetIn; endinterface); `endif %(pipeInstantiate)s %(portalInstantiate)s %(connectInstantiate)s Vector#(%(portalCount)s,StdPortal) portals; %(portalList)s let ctrl_mux <- mkSlaveMux(portals); Vector#(NumWriteClients,MemWriteClient#(DataBusWidth)) nullWriters = replicate(null_mem_write_client()); Vector#(NumReadClients,MemReadClient#(DataBusWidth)) nullReaders = replicate(null_mem_read_client()); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface readers = take(%(portalReaders)s); interface writers = take(%(portalWriters)s); `ifdef TOP_SOURCES_PORTAL_CLOCK interface portalClockSource = %(portalclock)s; `endif %(pinsInterface)s %(exportedInterfaces)s endmodule : %(topname)s %(exportedNames)s ''' ifcnamesTemplate=''' typedef enum {%(ifcnames)sNone=0, %(enumList)s } %(ifcnames)s deriving (Eq,Bits); ''' topNocTemplate=''' import ConnectalConfig::*; import Vector::*; import BuildVector::*; import Portal::*; import CnocPortal::*; import Connectable::*; import HostInterface::*; import ConnectalMemTypes::*; `include "ConnectalProjectConfig.bsv" import %(ifcnames)s::*; %(generatedImport)s %(generatedTypedefs)s `ifndef IMPORT_HOSTIF (* synthesize *) `endif module mkCnocTop `ifdef IMPORT_HOSTIF #(HostInterface host) `else `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary #(Clock derivedClockIn, Reset derivedResetIn) `else // otherwise no params `endif `endif (%(moduleParam)s); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary HostInterface host = (interface HostInterface; interface Clock derivedClock = derivedClockIn; interface Reset derivedReset = derivedResetIn; endinterface); `endif %(pipeInstantiate)s %(portalInstantiate)s %(connectInstantiate)s %(portalList)s Vector#(NumWriteClients,MemWriteClient#(DataBusWidth)) nullWriters = replicate(null_mem_write_client()); Vector#(NumReadClients,MemReadClient#(DataBusWidth)) nullReaders = replicate(null_mem_read_client()); interface requests = %(requestList)s; interface indications = %(indicationList)s; interface readers = take(%(portalReaders)s); interface writers = take(%(portalWriters)s); `ifdef TOP_SOURCES_PORTAL_CLOCK interface portalClockSource = %(portalclock)s; `endif %(pinsInterface)s %(exportedInterfaces)s endmodule : mkCnocTop %(exportedNames)s ''' topEnumTemplate=''' typedef enum {NoInterface, %(enumList)s} %(ifcnames)s; ''' portalTemplate = ''' PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_%(count)s <- mkPortalCtrlMemSlave(extend(pack(%(enumVal)s)), %(ifcName)s.intr); let memslave_%(count)s <- mkMemMethodMux%(slaveType)s(ctrlPort_%(count)s.memSlave,%(ifcName)s.%(itype)s); portals[%(count)s] = (interface MemPortal; interface PhysMemSlave slave = memslave_%(count)s; interface ReadOnly interrupt = ctrlPort_%(count)s.interrupt; interface WriteOnly num_portals = ctrlPort_%(count)s.num_portals; endinterface);''' portalNocTemplate = ''' let %(ifcNameNoc)s <- mkPortalMsg%(direction)s(extend(pack(%(enumVal)s)), %(ifcName)s.%(itype)s%(messageSize)s);''' def addPortal(outputPrefix, enumVal, ifcName, direction): global portalCount iName = ifcName + '.portalIfc' if outputPrefix != '': iName = outputPrefix + ifcName portParam = {'count': portalCount, 'enumVal': enumVal, 'ifcName': iName, 'ifcNameNoc': ifcName + 'Noc', 'direction': direction} if direction == 'Request': requestList.append('%(ifcNameNoc)s' % portParam) portParam['itype'] = 'requests' portParam['slaveType'] = 'In' portParam['intrParam'] = '' portParam['messageSize'] = '' else: indicationList.append('%(ifcNameNoc)s' % portParam) portParam['itype'] = 'indications' portParam['slaveType'] = 'Out' portParam['intrParam'] = ', %(ifcName)s.intr' % portParam portParam['messageSize'] = ', %(ifcName)s.messageSize' % portParam p = portalNocTemplate if options.cnoc else portalTemplate portalList.append(p % portParam) portalCount = portalCount + 1 class iReq: def __init__(self): self.inst = '' self.args = [] memShareInst = ''' SharedMemoryPortalConfigInput%(tparam)s l%(modname)sCW <- mkSharedMemoryPortalConfigInput;''' memEngineInst = ''' MemReadEngine#(64,64,2,%(clientCount)s) lSharereadEngine <- mkMemReadEngine(); MemWriteEngine#(64,64,2,%(clientCount)s) lSharewriteEngine <- mkMemWriteEngine();''' memModuleInstantiation = ''' SharedMemoryPortal#(64) l%(modname)sShare <- mkSharedMemory%(stype)sPortal(l%(modname)s%(number)s.portalIfc, get%(modnamebase)sMessageSize, takeAt(%(clientCount)s, lSharereadEngine.readServers), takeAt(%(clientCount)s, lSharewriteEngine.writeServers));''' memConnection = ''' mkConnection(l%(modname)sCW.pipes, l%(modname)sShare.cfg);''' connectUser = ''' mkConnection(lSimpleRequestInput.pipes, %(args)s);''' connectIndication = ''' mkConnection(l%(usermod)s.inverseIfc, l%(modname)s.methods);''' pipeInstantiation = ''' %(modname)s%(inverse)s%(tparam)s l%(modname)s%(number)s <- mk%(modname)s%(inverse)s;''' connectInstantiation = ''' mkConnection(l%(modname)s%(number)s.pipes, l%(userIf)s);''' def instMod(pmap, args, modname, modext, constructor, tparam, memFlag, inverseFlag): global clientCount if not modname: return map = pmap.copy() pmap['tparam'] = tparam pmap['modname'] = modname + modext pmap['modnamebase'] = modname tstr = 'S2H' if modext == 'Output': tstr = 'H2S' if modext: args = modname + tstr pmap['args'] = args % pmap if modext: options.portname.append('%s_%s%s%s' % (options.ifcnames, modname, tstr, pmap['number'])) pmap['argsConfig'] = modname + memFlag + tstr outputPrefix = '' if modext == 'Output': pmap['stype'] = 'Indication'; else: pmap['stype'] = 'Request'; if memFlag: if modext == 'Output': pmap['args'] = ''; else: pmap['args'] = 'l%(userIf)s' % pmap pmap['clientCount'] = clientCount; pipeInstantiate.append(pipeInstantiation % pmap) pipeInstantiate.append(memShareInst % pmap) portalInstantiate.append(memModuleInstantiation % pmap) connectInstantiate.append(memConnection % pmap) if modext != 'Output': connectInstantiate.append(connectUser % pmap) clientCount += 2 elif modext == 'Output': if options.integratedIndication: outputPrefix = 'l' + pmap['usermod'] + '.' else: pipeInstantiate.append(pipeInstantiation % pmap) if inverseFlag: connectInstantiate.append(connectIndication % pmap) else: pipeInstantiate.append(pipeInstantiation % pmap) connectInstantiate.append(connectInstantiation % pmap) if memFlag: options.portname.append('%s_%s%s%s%s' % (options.ifcnames, modname, memFlag, tstr, pmap['number'])) addPortal('', options.ifcnames + '_' + pmap['argsConfig'], 'l%(modname)sCW' % pmap, 'Request') else: addPortal(outputPrefix, options.ifcnames + '_' + pmap['args'] + pmap['number'], 'l%(modname)s%(number)s' % pmap, pmap['stype']) else: if not instantiateRequest.get(pmap['modname']): instantiateRequest[pmap['modname']] = iReq() pmap['hostif'] = '' instantiateRequest[pmap['modname']].inst = ' let l%(modname)s <- mk%(modname)s(%(hostif)s%%s);' % pmap instantiateRequest[pmap['modname']].args.append(pmap['args']) if pmap['modname'] not in instantiatedModules: instantiatedModules.append(pmap['modname']) options.importfiles.append(modname) def flushModules(key): temp = instantiateRequest.get(key) if temp: portalInstantiate.append(temp.inst % ','.join(temp.args)) del instantiateRequest[key] def toVectorLiteral(l): if l: return 'vec(%s)' % ', '.join(l) else: return 'nil' def appendVectors(l): if len(l) > 1: return 'append(%s,%s)' % (l[0], appendVectors(l[1:])) elif len(l) == 1: return l[0] else: return 'nil' def parseParam(pitem, proxy): p = pitem.split(':') pmap = {'tparam': '', 'xparam': '', 'uparam': '', 'memFlag': 'Pipes' if p[0][0] == '/' else '', 'inverse': 'Pipes' if p[0][0] == '!' else ''} pmap['usermod'] = p[0].replace('/','').replace('!','') pmap['name'] = p[1] ind = pmap['usermod'].find('#') if ind > 0: pmap['xparam'] = pmap['usermod'][ind:] pmap['usermod'] = pmap['usermod'][:ind] if len(p) > 2 and p[2]: pmap['uparam'] = p[2] + ', ' return pmap if __name__=='__main__': print('topgen', sys.argv) options = argparser.parse_args() if not options.project_dir: print("topgen: --project-dir option missing") sys.exit(1) project_dir = os.path.abspath(os.path.expanduser(options.project_dir)) clientCount = 0 userFiles = [] portalInstantiate = [] pipeInstantiate = [] connectInstantiate = [] instantiateRequest = {} for item in ['Platform%s_MemServerRequestS2H', 'Platform%s_MMURequestS2H', 'Platform%s_MemServerIndicationH2S', 'Platform%s_MMUIndicationH2S']: options.portname.append(item % options.ifcnames) requestList = [] indicationList = [] portalList = [] portalCount = 0 instantiatedModules = [] exportedNames = [] options.importfiles.append('`PinTypeInclude') if options.cnoc: exportedNames.extend(['export mkCnocTop;', 'export NumberOfRequests;', 'export NumberOfIndications;']) else: exportedNames.extend(['export %s;' % options.topname]) if options.importfiles: for item in options.importfiles: exportedNames.append('export %s::*;' % item) interfaceList = [] modcount = {} for pitem in options.proxy: print('options.proxy: %s' % options.proxy) pmap = parseParam(pitem, True) ptemp = pmap['name'].split(',') for pmap['name'] in ptemp: pmap['number'] = '' if (ptemp.count(pmap['name']) > 1): if pmap['name'] in modcount: pmap['number'] = str(modcount[pmap['name']]) modcount[pmap['name']] += 1 else: modcount[pmap['name']] = 1 pmap['number'] = str(0) instMod(pmap, '', pmap['name'], 'Output', '', '', pmap['memFlag'], pmap['inverse']) argstr = pmap['uparam'] if not options.integratedIndication: argstr += ('l%(name)sOutput%(number)s.ifc' if not pmap['inverse'] else '') if pmap['uparam'] and pmap['uparam'][0] == '/': argstr = 'l%(name)sOutput%(number)s.ifc, ' + pmap['uparam'][1:-2] instMod(pmap, argstr, pmap['usermod'], '', '', pmap['xparam'], False, pmap['inverse']) pmap['uparam'] = '' modcount = {} for pitem in options.wrapper: pmap = parseParam(pitem, False) print('options.wrapper: %s %s' % (pitem, pmap)) pmap['userIf'] = pmap['name'] pmap['name'] = pmap['usermod'] pmap['number'] = '' modintf_list = pmap['userIf'].split(',') number = 0 for pmap['userIf'] in modintf_list: if len(modintf_list) > 1: pmap['number'] = str(number) number += 1 pmap['usermod'] = pmap['userIf'].split('.')[0] if pmap['usermod'] not in instantiatedModules: instMod(pmap, pmap['uparam'], pmap['usermod'], '', '', pmap['xparam'], False, False) flushModules(pmap['usermod']) instMod(pmap, '', pmap['name'], 'Input', '', '', pmap['memFlag'], pmap['inverse']) portalInstantiate.append('') for key in instantiatedModules: flushModules(key) if len(options.pintype) > 1: interfaceList.append(' interface Pins pins;') for i,pitem in enumerate(options.interface): p = pitem.split(':') if len(options.pintype) > 1: interfaceList.append(' interface pins%d = l%s;' % (i, p[1])) else: interfaceList.append(' interface %s = l%s;' % (p[0], p[1])) if len(options.pintype) > 1: interfaceList.append(' endinterface ') memory_flag = 'MemServer' in instantiatedModules if clientCount: pipeInstantiate.append(memEngineInst % {'clientCount': clientCount}) pintype = '`PinType' pinsInterfaceDecl = '' if len(options.pintype) == 1: pintype = options.pintype[0] elif len(options.pintype) > 1: pintype = 'Pins' subifcs = [] for (i,ifc) in enumerate(options.pintype): subifcs.append(' interface %s pins%d;\n' % (ifc, i)) pinsInterfaceDecl = 'interface Pins;\n %s endinterface\n' % '\n'.join(subifcs) exportedNames.append('export Pins(..);') topsubsts = {'enumList': ',\n'.join(['%s=%d' % (name, i+1) for i,name in enumerate(options.portname)]), 'generatedImport': '\n'.join(['import %s::*;' % p for p in options.importfiles]), 'generatedTypedefs': '\n'.join(['typedef %d NumberOfRequests;' % len(requestList), 'typedef %d NumberOfIndications;' % len(indicationList)]), 'ifcnames': options.ifcnames, 'pipeInstantiate' : '\n'.join(sorted(pipeInstantiate)), 'connectInstantiate' : '\n'.join(sorted(connectInstantiate)), 'portalInstantiate' : '\n'.join(portalInstantiate), 'portalList': '\n'.join(portalList), 'portalCount': portalCount, 'requestList': toVectorLiteral(requestList), 'indicationList': toVectorLiteral(indicationList), 'exportedInterfaces' : '\n'.join(interfaceList), 'exportedNames' : '\n'.join(exportedNames), 'portalReaders' : appendVectors(options.memread + ['nullReaders']), 'portalWriters' : appendVectors(options.memwrite + ['nullWriters']), 'portalMaster' : 'lMemServer.masters' if memory_flag else 'nil', #Use e.g., --interface pins:Ddr3Test.ddr3 'pinsInterface' : ' interface pins = l%(usermod)s.pins;\n' % pmap if False else '', 'pinsInterfaceDecl' : pinsInterfaceDecl, 'moduleParam' : 'ConnectalTop#(%s)' % pintype if not options.cnoc \ else 'CnocTop#(NumberOfRequests,NumberOfIndications,PhysAddrWidth,DataBusWidth,%s,NumberOfMasters)' % pintype, 'portalclock': options.portalclock, 'topname': options.topname } topFilename = project_dir + '/' + options.filename print('Writing:', topFilename) top = util.createDirAndOpen(topFilename, 'w') if options.cnoc: top.write(topNocTemplate % topsubsts) else: top.write(topTemplate % topsubsts) top.close() topFilename = project_dir + '/' + options.ifcnames + '.bsv' print('Writing:', topFilename) top = util.createDirAndOpen(topFilename, 'w') top.write(ifcnamesTemplate % topsubsts) top.close() topFilename = project_dir + '/../jni/topEnum.h' print('Writing:', topFilename) top = util.createDirAndOpen(topFilename, 'w') top.write(topEnumTemplate % topsubsts) top.close() ================================================ FILE: scripts/util.py ================================================ ## ## Copyright (c) 2013 Quanta Research Cambridge, Inc. ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, copy, ## modify, merge, publish, distribute, sublicense, and/or sell copies ## of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## The above copyright notice and this permission notice shall be ## included in all copies or substantial portions of the Software. ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ## BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ## ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ## SOFTWARE. from __future__ import print_function import os import filecmp import string def createDirAndOpen(f, m): (d, name) = os.path.split(f) if not os.path.exists(d): os.makedirs(d) return open(f, m) def replaceIfChanged(name, replacement): if not os.path.isfile(name): print('os.rename(%s, %s)' % (replacement, name)) os.rename(replacement, name) return if filecmp.cmp(name, replacement): print('os.unlink(%s)' % replacement) os.unlink(replacement) else: print('os.rename(%s, %s)' % (replacement, name)) os.rename(replacement, name) ## for camelcase preservation def capitalize(s): return '%s%s' % (s[0].upper(), s[1:]) def decapitalize(s): return '%s%s' % (s[0].lower(), s[1:]) ## things I thought would have been in functools (mdk) intersperse = lambda e,l: sum([[x, e] for x in l],[])[:-1] def foldl(f, x, l): if len(l) == 0: return x return foldl(f, f(x, l[0]), l[1:]) ## Given a string V, V=, or V=VAL returns (V,VAL) def splitBinding(s): if '=' in s: return s.split('=') else: return (s,'') def escapequotes(s): s = s.replace('\"', '\\\"') return s ================================================ FILE: tests/adapter/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = TestRequest:Test.request H2S_INTERFACES = Test:TestIndication BSVFILES = Test.bsv CPPFILES=test.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/adapter/Test.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Adapter::*; interface TestIndication; method Action done(); endinterface interface TestRequest; method Action start(); endinterface interface Test; interface TestRequest request; endinterface module mkTest#(TestIndication indication)(Test); let dummy <- mkAdapterTb(interface AdapterIndication; method Action done = indication.done; endinterface); interface TestRequest request; method Action start(); dummy.start(); endmethod endinterface endmodule ================================================ FILE: tests/adapter/test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "TestRequest.h" #include "TestIndication.h" class TestIndication : public TestIndicationWrapper { public: void done() { printf("Test: all done\n"); exit(0); } TestIndication(unsigned int id) : TestIndicationWrapper(id) {} }; int main(int argc, const char **argv) { TestIndication *testIndication = new TestIndication(IfcNames_TestIndicationH2S); TestRequestProxy *testRequest = new TestRequestProxy(IfcNames_TestRequestS2H); printf("Test: start\n"); testRequest->start(); sleep(100); printf("Test: timed out\n"); return 0; } ================================================ FILE: tests/aecho/Echo.orig.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import EchoReq::*; import EchoIndication::*; import L_class_OC_Fifo1::*; interface Echo; interface EchoRequest request; interface EchoIndicationPortalOutput lEchoIndicationOutput; endinterface (*synthesize*) module mkEcho(Echo); EchoIndicationOutput myEchoIndicationOutput <- mkEchoIndicationOutput; EchoIndication indication = myEchoIndicationOutput.ifc; //FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); L_class_OC_Fifo1 delay <- mkL_class_OC_Fifo1; rule heard; delay.deq; indication.heard(delay.first); endrule interface EchoIndicationPortalOutput lEchoIndicationOutput = myEchoIndicationOutput.portalIfc; interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod endinterface endmodule ================================================ FILE: tests/aecho/EchoReq.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface EchoIndication; method Action heard(Bit#(32) v); endinterface interface EchoRequest; method Action say(Bit#(32) v); endinterface ================================================ FILE: tests/aecho/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication LTDIR = $(CONNECTALDIR)/../llvm-translate/ LLVMT = $(LTDIR)/Debug+Asserts/bin/llvm-translate ACCDIR = $(CONNECTALDIR)/../atomicc/examples/echo GENDIR = generated BSVFILES = EchoReq.bsv CPPFILES = testecho.cpp CONNECTALFLAGS += --verilog $(GENDIR) --bsvpath $(GENDIR) BSCFLAGS += -show-bvi AUTOTOP += --integratedIndication prebuild:: $(LLVMT) --odir=$(GENDIR) $(ACCDIR)/fifo.ll $(LLVMT) --odir=$(GENDIR) $(ACCDIR)/echo.ll $(ACCDIR)/atomicc.ll $(LTDIR)/linker.py --directory generated --output Echo l_class_OC_Echo include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/aecho/generated/Echo.bsv ================================================ import ConnectalConfig::*; import Portal::*; import Pipe::*; import Vector::*; import EchoReq::*; import EchoIndication::*; interface Echo; interface EchoRequest request; interface EchoIndicationPortalOutput lEchoIndicationOutput; endinterface interface EchoBVI; interface EchoRequest request; interface PortalSize messageSize; interface PipeOut#(Bit#(SlaveDataBusWidth)) indications; interface PortalInterrupt#(SlaveDataBusWidth) intr; endinterface import "BVI" EchoVerilog = module mkEchoBVI(EchoBVI); default_clock clk(); default_reset rst(); interface EchoRequest request; method say(request_say_v) ready(RDY_request_say) enable(EN_request_say); endinterface interface PortalSize messageSize; method messageSize_size size(messageSize_size_methodNumber) ready(RDY_messageSize_size); endinterface interface PipeOut indications; method deq() enable(EN_indications_0_deq) ready(RDY_indications_0_deq); method indications_0_notEmpty notEmpty() ready(RDY_indications_0_notEmpty); method indications_0_first first() ready(RDY_indications_0_first); endinterface interface PortalInterrupt intr; method intr_status status() ready(RDY_intr_status); method intr_channel channel() ready(RDY_intr_channel); endinterface endmodule (*synthesize*) module mkEcho(Echo); let bvi <- mkEchoBVI; Vector#(1, PipeOut#(Bit#(SlaveDataBusWidth))) tmpInd; tmpInd[0] = bvi.indications; interface EchoRequest request = bvi.request; interface EchoIndicationPortalOutput lEchoIndicationOutput; interface PortalSize messageSize = bvi.messageSize; interface Vector indications = tmpInd; interface PortalInterrupt intr = bvi.intr; endinterface endmodule ================================================ FILE: tests/aecho/generated/EchoVerilog.v ================================================ module EchoVerilog(input CLK, input RST_N, output RDY_indications_0_deq, input EN_indications_0_deq, input [31:0]request_say_v, output RDY_request_say, input EN_request_say, output RDY_indications_0_notEmpty, output indications_0_notEmpty, output RDY_indications_0_first, output [31:0]indications_0_first, output RDY_intr_status, output intr_status, output RDY_intr_channel, output [31:0]intr_channel, output RDY_messageSize_size, input[15:0] messageSize_size_methodNumber, output[15:0] messageSize_size ); wire [31:0]ifc_heard_v; wire RDY_ifc_heard, EN_ifc_heard; l_class_OC_Echo lEcho(.CLK(CLK), .nRST(RST_N), .say__RDY(RDY_request_say), .say__ENA(EN_request_say), .say_v(request_say_v), .ind$heard_heard_v(ifc_heard_v), .respond_rule__ENA(1)); mkEchoIndicationOutput myEchoIndicationOutput(.CLK(CLK), .RST_N(RST_N), .RDY_portalIfc_indications_0_deq(RDY_indications_0_deq), .EN_portalIfc_indications_0_deq(EN_indications_0_deq), .RDY_portalIfc_indications_0_notEmpty(RDY_indications_0_notEmpty), .portalIfc_indications_0_notEmpty(indications_0_notEmpty), .RDY_portalIfc_indications_0_first(RDY_indications_0_first), .portalIfc_indications_0_first(indications_0_first), .RDY_portalIfc_intr_status(RDY_intr_status), .portalIfc_intr_status(intr_status), .RDY_portalIfc_intr_channel(RDY_intr_channel), .portalIfc_intr_channel(intr_channel), .ifc_heard_v(ifc_heard_v), .RDY_ifc_heard(RDY_ifc_heard), .EN_ifc_heard(EN_ifc_heard), .RDY_portalIfc_messageSize_size(RDY_messageSize_size), .portalIfc_messageSize_size_methodNumber(messageSize_size_methodNumber), .portalIfc_messageSize_size(messageSize_size)); endmodule // mkEcho ================================================ FILE: tests/aecho/generated/L_class_OC_Echo.bsv ================================================ interface L_class_OC_Echo; method Action respond_rule(); method Action say(Bit#(32) say_v); endinterface import "BVI" l_class_OC_Echo = module mkL_class_OC_Echo(L_class_OC_Echo); default_reset rst(nRST); default_clock clk(CLK); method respond_rule() enable(respond_rule__ENA) ready(respond_rule__RDY); method say(say_v) enable(say__ENA) ready(say__RDY); schedule (respond_rule, say) CF (respond_rule, say); endmodule ================================================ FILE: tests/aecho/generated/L_class_OC_Fifo.bsv ================================================ interface L_class_OC_Fifo; method Action in_enq(Bit#(32) in_enq_v); method Action out_deq(); method Bit#(32) out_first(); endinterface import "BVI" l_class_OC_Fifo = module mkL_class_OC_Fifo(L_class_OC_Fifo); default_reset rst(nRST); default_clock clk(CLK); method in_enq(in_enq_v) enable(in_enq__ENA) ready(in_enq__RDY); method out_deq() enable(out_deq__ENA) ready(out_deq__RDY); method out_first out_first() ready(out_first__RDY); schedule (in_enq, out_deq, out_first) CF (in_enq, out_deq, out_first); endmodule ================================================ FILE: tests/aecho/generated/L_class_OC_Fifo1.bsv ================================================ interface L_class_OC_Fifo1; method Action in_enq(Bit#(32) in_enq_v); method Action out_deq(); method Bit#(32) out_first(); endinterface import "BVI" l_class_OC_Fifo1 = module mkL_class_OC_Fifo1(L_class_OC_Fifo1); default_reset rst(nRST); default_clock clk(CLK); method in_enq(in_enq_v) enable(in_enq__ENA) ready(in_enq__RDY); method out_deq() enable(out_deq__ENA) ready(out_deq__RDY); method out_first out_first() ready(out_first__RDY); schedule (in_enq, out_deq, out_first) CF (in_enq, out_deq, out_first); endmodule ================================================ FILE: tests/aecho/generated/l_class_OC_Echo.cpp ================================================ #include "l_class_OC_Echo.h" void l_class_OC_Echo::respond_rule(void) { unsigned int call = fifo.out_first(); fifo.out_deq(); ind->heard(call); } bool l_class_OC_Echo::respond_rule__RDY(void) { bool tmp__1 = fifo.out_first__RDY(); bool tmp__2 = fifo.out_deq__RDY(); bool tmp__3 = ind->heard__RDY(); return (tmp__1 & tmp__2) & tmp__3; } void l_class_OC_Echo::say(unsigned int say_v) { fifo.in_enq(say_v); } bool l_class_OC_Echo::say__RDY(void) { bool tmp__1 = fifo.in_enq__RDY(); return tmp__1; } void l_class_OC_Echo::run() { if (respond_rule__RDY()) respond_rule(); } ================================================ FILE: tests/aecho/generated/l_class_OC_Echo.h ================================================ #ifndef __l_class_OC_Echo_H__ #define __l_class_OC_Echo_H__ #include "l_class_OC_Fifo1.h" #include "l_class_OC_EchoIndication.h" class l_class_OC_Echo { class l_class_OC_Fifo1 fifo; class l_class_OC_EchoIndication *ind; unsigned int pipetemp; public: void respond_rule(void); bool respond_rule__RDY(void); void say(unsigned int say_v); bool say__RDY(void); void run(); void setind(class l_class_OC_EchoIndication *v) { ind = v; } }; #endif // __l_class_OC_Echo_H__ ================================================ FILE: tests/aecho/generated/l_class_OC_Echo.v ================================================ module l_class_OC_Echo ( input CLK, input nRST, input respond_rule__ENA, output respond_rule__RDY, input say__ENA, input [31:0]say_v, output say__RDY, output ind$heard__ENA, output [31:0]ind$heard_heard_v, input ind$heard__RDY); wire respond_rule__RDY_internal; wire respond_rule__ENA_internal = respond_rule__ENA && respond_rule__RDY_internal; assign respond_rule__RDY = respond_rule__RDY_internal; wire say__RDY_internal; wire say__ENA_internal = say__ENA && say__RDY_internal; assign say__RDY = say__RDY_internal; wire fifo$out_deq__RDY; wire fifo$out_first__RDY; l_class_OC_Fifo1 fifo ( CLK, nRST, say__ENA_internal, say_v, say__RDY, respond_rule__ENA_internal, fifo$out_deq__RDY, ind$heard_heard_v, fifo$out_first__RDY); reg[31:0] pipetemp; assign ind$heard__ENA = respond_rule__ENA_internal; assign respond_rule__RDY_internal = (fifo$out_first__RDY & fifo$out_deq__RDY) & ind$heard__RDY; always @( posedge CLK) begin if (!nRST) begin pipetemp <= 0; end // nRST end // always @ (posedge CLK) endmodule //METAGUARD; respond_rule__RDY; (fifo$out_first__RDY & fifo$out_deq__RDY) & ind$heard__RDY; //METAGUARD; say__RDY; fifo$in_enq__RDY; //METAINVOKE; respond_rule; :;fifo$out_deq:;ind$heard:;fifo$out_first; //METAINVOKE; say; :;fifo$in_enq; //METAINTERNAL; fifo; l_class_OC_Fifo1; //METAEXTERNAL; ind; l_class_OC_EchoIndication; ================================================ FILE: tests/aecho/generated/l_class_OC_EchoIndication.cpp ================================================ #include "l_class_OC_EchoIndication.h" void l_class_OC_EchoIndication::heard(unsigned int heard_v) { stop_main_program = 1; ("Heard an echo: %d\n")->(heard_v); } bool l_class_OC_EchoIndication::heard__RDY(void) { return 1; } ================================================ FILE: tests/aecho/generated/l_class_OC_EchoIndication.h ================================================ #ifndef __l_class_OC_EchoIndication_H__ #define __l_class_OC_EchoIndication_H__ class l_class_OC_EchoIndication { public: void heard(unsigned int heard_v); bool heard__RDY(void); }; #endif // __l_class_OC_EchoIndication_H__ ================================================ FILE: tests/aecho/generated/l_class_OC_EchoRequest.cpp ================================================ #include "l_class_OC_EchoRequest.h" void l_class_OC_EchoRequest::say(unsigned int say_v) { } bool l_class_OC_EchoRequest::say__RDY(void) { return 1; } ================================================ FILE: tests/aecho/generated/l_class_OC_EchoRequest.h ================================================ #ifndef __l_class_OC_EchoRequest_H__ #define __l_class_OC_EchoRequest_H__ class l_class_OC_EchoRequest { public: void say(unsigned int say_v); bool say__RDY(void); }; #endif // __l_class_OC_EchoRequest_H__ ================================================ FILE: tests/aecho/generated/l_class_OC_EchoTest.cpp ================================================ #include "l_class_OC_EchoTest.h" ================================================ FILE: tests/aecho/generated/l_class_OC_EchoTest.h ================================================ #ifndef __l_class_OC_EchoTest_H__ #define __l_class_OC_EchoTest_H__ #include "l_class_OC_Echo.h" class l_class_OC_EchoTest { class l_class_OC_Echo *echo; unsigned int x; public: void setecho(class l_class_OC_Echo *v) { echo = v; } }; #endif // __l_class_OC_EchoTest_H__ ================================================ FILE: tests/aecho/generated/l_class_OC_Fifo.cpp ================================================ #include "l_class_OC_Fifo.h" void l_class_OC_Fifo::in_enq(unsigned int in_enq_v) { } bool l_class_OC_Fifo::in_enq__RDY(void) { return 0; } void l_class_OC_Fifo::out_deq(void) { } bool l_class_OC_Fifo::out_deq__RDY(void) { return 0; } unsigned int l_class_OC_Fifo::out_first(void) { return 0; } bool l_class_OC_Fifo::out_first__RDY(void) { return 0; } ================================================ FILE: tests/aecho/generated/l_class_OC_Fifo.h ================================================ #ifndef __l_class_OC_Fifo_H__ #define __l_class_OC_Fifo_H__ class l_class_OC_Fifo { public: void in_enq(unsigned int in_enq_v); bool in_enq__RDY(void); void out_deq(void); bool out_deq__RDY(void); unsigned int out_first(void); bool out_first__RDY(void); }; #endif // __l_class_OC_Fifo_H__ ================================================ FILE: tests/aecho/generated/l_class_OC_Fifo.v ================================================ module l_class_OC_Fifo ( input CLK, input nRST, input in_enq__ENA, input [31:0]in_enq_v, output in_enq__RDY, input out_deq__ENA, output out_deq__RDY, output [31:0]out_first, output out_first__RDY); wire in_enq__RDY_internal; wire in_enq__ENA_internal = in_enq__ENA && in_enq__RDY_internal; assign in_enq__RDY = in_enq__RDY_internal; wire out_deq__RDY_internal; wire out_deq__ENA_internal = out_deq__ENA && out_deq__RDY_internal; assign out_deq__RDY = out_deq__RDY_internal; assign in_enq__RDY_internal = 0; assign out_deq__RDY_internal = 0; assign out_first = 0; assign out_first__RDY_internal = 0; endmodule //METAGUARD; in_enq__RDY; 0; //METAGUARD; out_deq__RDY; 0; //METAGUARD; out_first__RDY; 0; ================================================ FILE: tests/aecho/generated/l_class_OC_Fifo1.cpp ================================================ #include "l_class_OC_Fifo1.h" void l_class_OC_Fifo1::in_enq(unsigned int in_enq_v) { element = in_enq_v; full = 1; } bool l_class_OC_Fifo1::in_enq__RDY(void) { return full ^ 1; } void l_class_OC_Fifo1::out_deq(void) { full = 0; } bool l_class_OC_Fifo1::out_deq__RDY(void) { return full; } unsigned int l_class_OC_Fifo1::out_first(void) { return element; } bool l_class_OC_Fifo1::out_first__RDY(void) { return full; } ================================================ FILE: tests/aecho/generated/l_class_OC_Fifo1.h ================================================ #ifndef __l_class_OC_Fifo1_H__ #define __l_class_OC_Fifo1_H__ class l_class_OC_Fifo1 { unsigned int element; bool full; public: void in_enq(unsigned int in_enq_v); bool in_enq__RDY(void); void out_deq(void); bool out_deq__RDY(void); unsigned int out_first(void); bool out_first__RDY(void); }; #endif // __l_class_OC_Fifo1_H__ ================================================ FILE: tests/aecho/generated/l_class_OC_Fifo1.v ================================================ module l_class_OC_Fifo1 ( input CLK, input nRST, input in_enq__ENA, input [31:0]in_enq_v, output in_enq__RDY, input out_deq__ENA, output out_deq__RDY, output [31:0]out_first, output out_first__RDY); wire in_enq__RDY_internal; wire in_enq__ENA_internal = in_enq__ENA && in_enq__RDY_internal; assign in_enq__RDY = in_enq__RDY_internal; wire out_deq__RDY_internal; wire out_deq__ENA_internal = out_deq__ENA && out_deq__RDY_internal; assign out_deq__RDY = out_deq__RDY_internal; reg[31:0] element; reg full; assign in_enq__RDY_internal = full ^ 1; assign out_deq__RDY_internal = full; assign out_first = element; assign out_first__RDY_internal = full; always @( posedge CLK) begin if (!nRST) begin element <= 0; full <= 0; end // nRST else begin if (in_enq__ENA_internal) begin element <= in_enq_v; full <= 1; end; // End of in_enq if (out_deq__ENA_internal) begin full <= 0; end; // End of out_deq end end // always @ (posedge CLK) endmodule //METAGUARD; in_enq__RDY; full ^ 1; //METAGUARD; out_deq__RDY; full; //METAGUARD; out_first__RDY; full; //METAWRITE; in_enq; :;element:;full; //METAWRITE; out_deq; :;full; //METAREAD; out_first; :;element; ================================================ FILE: tests/aecho/generated/output.cpp ================================================ void l_class_OC_Echo::respond_rule(void) { unsigned int call = fifo.first(); fifo.deq(); ind->heard(call); } bool l_class_OC_Echo::respond_rule__RDY(void) { bool tmp__1 = fifo.first__RDY(); bool tmp__2 = fifo.deq__RDY(); bool tmp__3 = ind->heard__RDY(); return (tmp__1 & tmp__2) & tmp__3; } void l_class_OC_Echo::say(unsigned int say_v) { fifo.enq(say_v); } bool l_class_OC_Echo::say__RDY(void) { bool tmp__1 = fifo.enq__RDY(); return tmp__1; } void l_class_OC_Echo::run() { if (respond_rule__RDY()) respond_rule(); } ================================================ FILE: tests/aecho/generated/output.h ================================================ class l_class_OC_EchoRequest { private: public: void say(unsigned int say_v); bool say__RDY(void); }; class l_class_OC_EchoIndication { private: public: void heard(unsigned int heard_v); bool heard__RDY(void); }; class l_class_OC_Echo { private: class l_class_OC_Fifo1 fifo; class l_class_OC_EchoIndication *ind; unsigned int pipetemp; public: void respond_rule(void); bool respond_rule__RDY(void); void say(unsigned int say_v); bool say__RDY(void); void run(); void setind(class l_class_OC_EchoIndication *v) { ind = v; } }; class l_class_OC_EchoTest { private: class l_class_OC_Echo *echo; unsigned int x; public: void setecho(class l_class_OC_Echo *v) { echo = v; } }; ================================================ FILE: tests/aecho/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "EchoIndication.h" #include "EchoRequest.h" static EchoRequestProxy *echoRequestProxy = 0; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); } int main(int argc, const char **argv) { EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); printf("TEST TYPE: SEM\n"); return 0; } ================================================ FILE: tests/algo1_flashmodel/AuroraCommon.bsv ================================================ package AuroraCommon; `include "ConnectalProjectConfig.bsv" import FIFO::*; import Clocks :: *; import DefaultValue :: *; import Xilinx :: *; import XilinxCells :: *; import ConnectalXilinxCells::*; typedef 8 AuroraExtCount; (* always_enabled, always_ready *) interface Aurora_Clock_Pins; //(* prefix = "", result = "" *) method Action gtx_clk_p(Bit#(1) v); //(* prefix = "", result = "" *) method Action gtx_clk_n(Bit#(1) v); interface Clock gtx_clk_p_deleteme_unused_clock; interface Clock gtx_clk_n_deleteme_unused_clock; endinterface interface AuroraExtImportIfc#(numeric type lanes); interface Clock aurora_clk0; interface Clock aurora_clk1; interface Clock aurora_clk2; interface Clock aurora_clk3; interface Reset aurora_rst0; interface Reset aurora_rst1; interface Reset aurora_rst2; interface Reset aurora_rst3; (* prefix = "" *) interface Aurora_Pins#(1) aurora0; (* prefix = "" *) interface Aurora_Pins#(1) aurora1; (* prefix = "" *) interface Aurora_Pins#(1) aurora2; (* prefix = "" *) interface Aurora_Pins#(1) aurora3; (* prefix = "" *) interface AuroraControllerIfc#(64) user0; (* prefix = "" *) interface AuroraControllerIfc#(64) user1; (* prefix = "" *) interface AuroraControllerIfc#(64) user2; (* prefix = "" *) interface AuroraControllerIfc#(64) user3; endinterface interface AuroraImportIfc#(numeric type lanes); interface Clock aurora_clk; interface Reset aurora_rst; (* prefix = "" *) interface Aurora_Pins#(lanes) aurora; (* prefix = "" *) interface AuroraControllerIfc#(TMul#(lanes,32)) user; endinterface interface AuroraControllerIfc#(numeric type width); interface Reset aurora_rst_n; method Bit#(1) channel_up; method Bit#(1) lane_up; method Bit#(1) hard_err; method Bit#(1) soft_err; method Bit#(8) data_err_count; method Action send(Bit#(width) tx); method ActionValue#(Bit#(width)) receive(); endinterface (* always_enabled, always_ready *) interface Aurora_Pins#(numeric type lanes); (* prefix = "", result = "RXN" *) method Action rxn_in(Bit#(lanes) rxn_i); (* prefix = "", result = "RXP" *) method Action rxp_in(Bit#(lanes) rxp_i); (* prefix = "", result = "TXN" *) method Bit#(lanes) txn_out(); (* prefix = "", result = "TXP" *) method Bit#(lanes) txp_out(); endinterface interface GtxClockImportIfc; interface Aurora_Clock_Pins aurora_clk; interface Clock gtx_clk_p_ifc; interface Clock gtx_clk_n_ifc; endinterface (* synthesize *) module mkGtxClockImport (GtxClockImportIfc); `ifndef SIMULATION B2C i_gtx_clk_p <- mkB2C(); B2C i_gtx_clk_n <- mkB2C(); interface Aurora_Clock_Pins aurora_clk; method Action gtx_clk_p(Bit#(1) v); i_gtx_clk_p.inputclock(v); endmethod method Action gtx_clk_n(Bit#(1) v); i_gtx_clk_n.inputclock(v); endmethod interface Clock gtx_clk_p_deleteme_unused_clock = i_gtx_clk_p.c; // These clocks are deleted from the netlist by the synth.tcl script interface Clock gtx_clk_n_deleteme_unused_clock = i_gtx_clk_n.c; endinterface //interface Clock gtx_clk = gtx_clk_i; interface Clock gtx_clk_p_ifc = i_gtx_clk_p.c; interface Clock gtx_clk_n_ifc = i_gtx_clk_n.c; `else Clock clk <- exposeCurrentClock; interface Aurora_Clock_Pins aurora_clk; interface Clock gtx_clk_p_deleteme_unused_clock = clk; // These clocks are deleted from the netlist by the synth.tcl script interface Clock gtx_clk_n_deleteme_unused_clock = clk; endinterface //interface Clock gtx_clk = gtx_clk_i; interface Clock gtx_clk_p_ifc = clk; interface Clock gtx_clk_n_ifc = clk; `endif endmodule endpackage: AuroraCommon ================================================ FILE: tests/algo1_flashmodel/AuroraGearbox.bsv ================================================ import FIFO::*; import FIFOF::*; import Clocks :: *; typedef 8 HeaderSz; typedef TSub#(128,8) BodySz; typedef TMul#(2,TSub#(128,HeaderSz)) DataIfcSz; typedef Bit#(DataIfcSz) DataIfc; typedef Bit#(6) PacketType; typedef 128 AuroraWidth; interface AuroraGearboxIfc; method Action send(DataIfc data, PacketType ptype); method ActionValue#(Tuple2#(DataIfc, PacketType)) recv; method Action auroraRecv(Bit#(AuroraWidth) word); method ActionValue#(Bit#(AuroraWidth)) auroraSend; //method Action resetLink; endinterface module mkAuroraGearbox#(Clock aclk, Reset arst) (AuroraGearboxIfc); SyncFIFOIfc#(Tuple2#(DataIfc,PacketType)) sendQ <- mkSyncFIFOFromCC(4, aclk); Integer recvQDepth = 128; Integer windowSize = 64; SyncFIFOIfc#(Tuple2#(DataIfc,PacketType)) recvQ <- mkSyncFIFOToCC(4, aclk, arst); FIFO#(Tuple2#(DataIfc,PacketType)) recvBufferQ <- mkSizedFIFO(recvQDepth, clocked_by aclk, reset_by arst); Reg#(Bit#(16)) maxInFlightUp <- mkReg(0, clocked_by aclk, reset_by arst); Reg#(Bit#(16)) maxInFlightDown <- mkReg(0, clocked_by aclk, reset_by arst); Reg#(Bit#(16)) curInQUp <- mkReg(0, clocked_by aclk, reset_by arst); Reg#(Bit#(16)) curInQDown <- mkReg(0, clocked_by aclk, reset_by arst); FIFOF#(Bit#(8)) flowControlQ <- mkFIFOF(clocked_by aclk, reset_by arst); rule emitFlowControlPacket ((maxInFlightUp-maxInFlightDown) +(curInQUp-curInQDown) +fromInteger(windowSize) < fromInteger(recvQDepth)); flowControlQ.enq(fromInteger(windowSize)); maxInFlightUp <= maxInFlightUp + fromInteger(windowSize); endrule Reg#(Bit#(16)) curSendBudgetUp <- mkReg(0, clocked_by aclk, reset_by arst); Reg#(Bit#(16)) curSendBudgetDown <- mkReg(0, clocked_by aclk, reset_by arst); FIFO#(Bit#(AuroraWidth)) auroraOutQ <- mkFIFO(clocked_by aclk, reset_by arst); Reg#(Maybe#(Tuple2#(Bit#(BodySz), PacketType))) packetSendBuffer <- mkReg(tagged Invalid, clocked_by aclk, reset_by arst); rule sendPacketPart; let curSendBudget = curSendBudgetUp - curSendBudgetDown; if ( flowControlQ.notEmpty ) begin flowControlQ.deq; PacketType ptype = 0; auroraOutQ.enq({2'b01, ptype, zeroExtend(flowControlQ.first)}); $display("AuroraOutQ: flowControl packet: %d", flowControlQ.first); $display("send budget = %d", curSendBudget); end else if ( curSendBudget > 0 ) begin if ( isValid(packetSendBuffer) ) begin let btpl = fromMaybe(?, packetSendBuffer); //auroraIntraImport.user.send({2'b10, auroraOutQ.enq({2'b10, tpl_2(btpl), tpl_1(btpl) }); packetSendBuffer <= tagged Invalid; curSendBudgetDown <= curSendBudgetDown + 1; $display("AuroraOutQ: data packet VALID: data=%x, type=%x", tpl_1(btpl), tpl_2(btpl)); end else begin sendQ.deq; let data = sendQ.first; packetSendBuffer <= tagged Valid tuple2( truncate(tpl_1(data)>>valueOf(BodySz)), tpl_2(data) ); auroraOutQ.enq({2'b00, tpl_2(data),truncate(tpl_1(data))}); $display("AuroraOutQ: data packet INVALID: data=%x, type=%x", tpl_1(data), tpl_2(data)); end $display("send budget = %d", curSendBudget); end endrule FIFO#(Bit#(AuroraWidth)) auroraInQ <- mkFIFO(clocked_by aclk, reset_by arst); Reg#(Maybe#(Bit#(BodySz))) packetRecvBuffer <- mkReg(tagged Invalid, clocked_by aclk, reset_by arst); Reg#(Bit#(1)) curRecvOffset <- mkReg(0, clocked_by aclk, reset_by arst); rule recvPacketPart; let crdata = auroraInQ.first; auroraInQ.deq; Bit#(BodySz) cdata = truncate(crdata); Bit#(8) header = truncate(crdata>>valueOf(BodySz)); Bit#(1) idx = header[7]; Bit#(1) control = header[6]; PacketType ptype = truncate(header); if ( control == 1 ) begin curSendBudgetUp <= curSendBudgetUp + truncate(cdata); end else if ( isValid(packetRecvBuffer) ) begin let pdata = fromMaybe(0, packetRecvBuffer); if ( idx == 1 ) begin packetRecvBuffer <= tagged Invalid; recvBufferQ.enq( tuple2({cdata, pdata}, ptype) ); maxInFlightDown <= maxInFlightDown + 1; curInQUp <= curInQUp + 1; end else begin packetRecvBuffer <= tagged Valid cdata; end end else begin if ( idx == 0 ) packetRecvBuffer <= tagged Valid cdata; end endrule rule flushReadBuffer; curInQDown <= curInQDown + 1; recvBufferQ.deq; recvQ.enq(recvBufferQ.first); endrule method Action send(DataIfc data, PacketType ptype); sendQ.enq(tuple2(data, ptype)); endmethod method ActionValue#(Tuple2#(DataIfc, PacketType)) recv; recvQ.deq; return recvQ.first; endmethod method Action auroraRecv(Bit#(AuroraWidth) word); auroraInQ.enq(word); endmethod method ActionValue#(Bit#(AuroraWidth)) auroraSend; auroraOutQ.deq; return auroraOutQ.first; endmethod /* method Action resetLink; maxInFlightUp <= 0; maxInFlightDown <= 0; curInQUp <= 0; curInQDown <= 0; endmethod */ endmodule ================================================ FILE: tests/algo1_flashmodel/AuroraImportFmc1.bsv ================================================ package AuroraImportFmc1; `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import Clocks :: *; import DefaultValue :: *; import Xilinx :: *; import XilinxCells :: *; import ConnectalXilinxCells::*; import AuroraCommon::*; import AuroraGearbox::*; interface AuroraIfc; method Action send(DataIfc data, PacketType ptype); method ActionValue#(Tuple2#(DataIfc, PacketType)) receive; method Tuple4#(Bit#(32), Bit#(32), Bit#(32), Bit#(32)) getDebugCnts; interface Clock clk; interface Reset rst; method Bit#(1) channel_up; method Bit#(1) lane_up; method Bit#(1) hard_err; method Bit#(1) soft_err; method Bit#(8) data_err_count; (* prefix = "" *) interface Aurora_Pins#(4) aurora; endinterface (* synthesize *) module mkAuroraIntra#(Clock gtx_clk_p, Clock gtx_clk_n, Clock clk250) (AuroraIfc); Clock cur_clk <- exposeCurrentClock; // assuming 200MHz clock Reset cur_rst <- exposeCurrentReset; `ifndef SIMULATION ClockDividerIfc auroraIntraClockDiv4 <- mkDCMClockDivider(5, 4, clocked_by clk250); //ClockDividerIfc auroraIntraClockDiv4 <- mkDCMClockDivider(4, 5); Reset defaultReset <- exposeCurrentReset; Clock clk50 = auroraIntraClockDiv4.slowClock; //MakeResetIfc rst50ifc <- mkReset(8, True, clk50); MakeResetIfc rst50ifc2 <- mkReset(8, True, clk50); //Reset rst50 = rst50ifc.new_rst; Reset rst50 <- mkAsyncReset(2, defaultReset, clk50); Reset rst50_2 = rst50ifc2.new_rst; Reset rst50_2a <- mkAsyncReset(2, rst50_2, clk50); Clock fmc1_gtx_clk_i <- mkClockIBUFDS_GTE2(True, gtx_clk_p, gtx_clk_n); AuroraImportIfc#(4) auroraIntraImport <- mkAuroraImport_8b10b_fmc1(fmc1_gtx_clk_i, clk50, rst50, rst50);//rst50_2a); `else //Clock gtx_clk = cur_clk; AuroraImportIfc#(4) auroraIntraImport <- mkAuroraImport_8b10b_bsim; `endif Clock aclk = auroraIntraImport.aurora_clk; Reset arst = auroraIntraImport.aurora_rst; Reg#(Bit#(32)) gearboxSendCnt <- mkReg(0); Reg#(Bit#(32)) gearboxRecCnt <- mkReg(0); Reg#(Bit#(32)) auroraSendCnt <- mkReg(0, clocked_by aclk, reset_by arst); Reg#(Bit#(32)) auroraRecCnt <- mkReg(0, clocked_by aclk, reset_by arst); Reg#(Bit#(32)) auroraSendCntCC <- mkSyncRegToCC(0, aclk, arst); Reg#(Bit#(32)) auroraRecCntCC <- mkSyncRegToCC(0, aclk, arst); rule syncCnt; auroraSendCntCC <= auroraSendCnt; auroraRecCntCC <= auroraRecCnt; endrule AuroraGearboxIfc auroraGearbox <- mkAuroraGearbox(aclk, arst); rule auroraOut if (auroraIntraImport.user.channel_up==1); let d <- auroraGearbox.auroraSend; //if ( auroraIntraImport.user.channel_up == 1 ) begin $display("Gearbox send out: %x", d); auroraSendCnt <= auroraSendCnt + 1; auroraIntraImport.user.send(d); //end endrule /* rule resetDeadLink ( auroraIntraImport.user.channel_up == 0 ); auroraGearbox.resetLink; $display("Gearbox reset link"); endrule */ rule auroraIn; let d <- auroraIntraImport.user.receive; $display("Gearbox received: %x", d); auroraRecCnt <= auroraRecCnt + 1; auroraGearbox.auroraRecv(d); endrule method Tuple4#(Bit#(32), Bit#(32), Bit#(32), Bit#(32)) getDebugCnts; return tuple4(gearboxSendCnt, gearboxRecCnt, auroraSendCntCC, auroraRecCntCC); endmethod method Action send(DataIfc data, PacketType ptype); auroraGearbox.send(data, ptype); gearboxSendCnt <= gearboxSendCnt + 1; endmethod method ActionValue#(Tuple2#(DataIfc, PacketType)) receive; let d <- auroraGearbox.recv; gearboxRecCnt <= gearboxRecCnt + 1; return d; endmethod method channel_up = auroraIntraImport.user.channel_up; method lane_up = auroraIntraImport.user.lane_up; method hard_err = auroraIntraImport.user.hard_err; method soft_err = auroraIntraImport.user.soft_err; method data_err_count = auroraIntraImport.user.data_err_count; interface Clock clk = auroraIntraImport.aurora_clk; interface Reset rst = auroraIntraImport.aurora_rst; interface Aurora_Pins aurora = auroraIntraImport.aurora; endmodule module mkAuroraImport_8b10b_bsim (AuroraImportIfc#(4)); Clock clk <- exposeCurrentClock; Reset rst <- exposeCurrentReset; FIFOF#(Bit#(128)) mirrorQ <- mkSizedFIFOF(2); Reg#(Bit#(1)) laneUpR <- mkReg(0); Reg#(Bit#(32)) laneUpDelay <- mkReg(500); rule updateLaneUp; if (laneUpDelay ==0) begin laneUpR <= 1; end else begin laneUpDelay <= laneUpDelay - 1; end endrule rule detectFull if (!mirrorQ.notFull); $display("WARNING: mirrorQ is full!"); endrule interface aurora_clk = clk; interface aurora_rst = rst; interface AuroraControllerIfc user; interface Reset aurora_rst_n = rst; method Bit#(1) channel_up; return laneUpR; endmethod method Bit#(1) lane_up; return laneUpR; endmethod method Bit#(1) hard_err; return 0; endmethod method Bit#(1) soft_err; return 0; endmethod method Bit#(8) data_err_count; return 0; endmethod method Action send(Bit#(128) data); mirrorQ.enq(data); endmethod method ActionValue#(Bit#(128)) receive; mirrorQ.deq; return mirrorQ.first; endmethod endinterface endmodule import "BVI" aurora_8b10b_fmc1_exdes = module mkAuroraImport_8b10b_fmc1#(Clock gtx_clk_in, Clock init_clk, Reset init_rst_n, Reset gt_rst_n) (AuroraImportIfc#(4)); default_clock no_clock; default_reset no_reset; input_clock (INIT_CLK_IN) = init_clk; input_reset (RESET_N) = init_rst_n; input_reset (GT_RESET_N) = gt_rst_n; output_clock aurora_clk(USER_CLK); output_reset aurora_rst(USER_RST_N) clocked_by (aurora_clk); input_clock (GTX_CLK) = gtx_clk_in; interface Aurora_Pins aurora; method rxn_in(RXN) enable((*inhigh*) rx_n_en) reset_by(no_reset) clocked_by(gtx_clk_in); method rxp_in(RXP) enable((*inhigh*) rx_p_en) reset_by(no_reset) clocked_by(gtx_clk_in); method TXN txn_out() reset_by(no_reset) clocked_by(gtx_clk_in); method TXP txp_out() reset_by(no_reset) clocked_by(gtx_clk_in); endinterface interface AuroraControllerIfc user; output_reset aurora_rst_n(USER_RST) clocked_by (aurora_clk); method CHANNEL_UP channel_up; method LANE_UP lane_up; method HARD_ERR hard_err; method SOFT_ERR soft_err; method ERR_COUNT data_err_count; method send(TX_DATA) enable(tx_en) ready(tx_rdy) clocked_by(aurora_clk) reset_by(aurora_rst); method RX_DATA receive() enable((*inhigh*) rx_en) ready(rx_rdy) clocked_by(aurora_clk) reset_by(aurora_rst); endinterface schedule (aurora_rxn_in, aurora_rxp_in, aurora_txn_out, aurora_txp_out, user_channel_up, user_lane_up, user_hard_err, user_soft_err, user_data_err_count) CF (aurora_rxn_in, aurora_rxp_in, aurora_txn_out, aurora_txp_out, user_channel_up, user_lane_up, user_hard_err, user_soft_err, user_data_err_count); schedule (user_send) CF (aurora_rxn_in, aurora_rxp_in, aurora_txn_out, aurora_txp_out, user_channel_up, user_lane_up, user_hard_err, user_soft_err, user_data_err_count); schedule (user_receive) CF (aurora_rxn_in, aurora_rxp_in, aurora_txn_out, aurora_txp_out, user_channel_up, user_lane_up, user_hard_err, user_soft_err, user_data_err_count); schedule (user_receive) SB (user_send); schedule (user_send) C (user_send); schedule (user_receive) C (user_receive); endmodule endpackage: AuroraImportFmc1 ================================================ FILE: tests/algo1_flashmodel/ChipscopeWrapper.bsv ================================================ typedef 4 NumDbgIlas; interface DebugVIO; method Action setDebugVin (Bit#(64) i); method Bit#(64) getDebugVout(); endinterface interface DebugILA; method Action setDebug0 (Bit#(16) i); method Action setDebug1 (Bit#(16) i); method Action setDebug2 (Bit#(16) i); method Action setDebug3 (Bit#(16) i); method Action setDebug4 (Bit#(16) i); method Action setDebug5_64 (Bit#(64) i); method Action setDebug6_64 (Bit#(64) i); endinterface interface CSDebugIfc; interface DebugVIO vio; interface DebugILA ila0; interface DebugILA ila1; interface DebugILA ila2; interface DebugILA ila3; interface DebugILA ila4; interface DebugILA ila5; interface DebugILA ila6; interface DebugILA ila7; endinterface import "BVI" chipscope_debug_viv = //TODO change for Vivado or ISE IP module mkChipscopeDebug(CSDebugIfc); default_clock clk0; default_reset rst0; input_clock clk0(v_clk0) <- exposeCurrentClock; input_reset rst0(v_rst0) <- exposeCurrentReset; interface DebugVIO vio; method setDebugVin (v_debug_vin) enable((*inhigh*)en38); method v_debug_vout getDebugVout; endinterface interface DebugILA ila0; method setDebug0 (v_debug0_0) enable((*inhigh*)en0_0); method setDebug1 (v_debug0_1) enable((*inhigh*)en0_1); method setDebug2 (v_debug0_2) enable((*inhigh*)en0_2); method setDebug3 (v_debug0_3) enable((*inhigh*)en0_3); method setDebug4 (v_debug0_4) enable((*inhigh*)en0_4); method setDebug5_64 (v_debug0_5_64) enable((*inhigh*)en0_5); method setDebug6_64 (v_debug0_6_64) enable((*inhigh*)en0_6); endinterface interface DebugILA ila1; method setDebug0 (v_debug1_0) enable((*inhigh*)en1_0); method setDebug1 (v_debug1_1) enable((*inhigh*)en1_1); method setDebug2 (v_debug1_2) enable((*inhigh*)en1_2); method setDebug3 (v_debug1_3) enable((*inhigh*)en1_3); method setDebug4 (v_debug1_4) enable((*inhigh*)en1_4); method setDebug5_64 (v_debug1_5_64) enable((*inhigh*)en1_5); method setDebug6_64 (v_debug1_6_64) enable((*inhigh*)en1_6); endinterface interface DebugILA ila2; method setDebug0 (v_debug2_0) enable((*inhigh*)en2_0); method setDebug1 (v_debug2_1) enable((*inhigh*)en2_1); method setDebug2 (v_debug2_2) enable((*inhigh*)en2_2); method setDebug3 (v_debug2_3) enable((*inhigh*)en2_3); method setDebug4 (v_debug2_4) enable((*inhigh*)en2_4); method setDebug5_64 (v_debug2_5_64) enable((*inhigh*)en2_5); method setDebug6_64 (v_debug2_6_64) enable((*inhigh*)en2_6); endinterface interface DebugILA ila3; method setDebug0 (v_debug3_0) enable((*inhigh*)en3_0); method setDebug1 (v_debug3_1) enable((*inhigh*)en3_1); method setDebug2 (v_debug3_2) enable((*inhigh*)en3_2); method setDebug3 (v_debug3_3) enable((*inhigh*)en3_3); method setDebug4 (v_debug3_4) enable((*inhigh*)en3_4); method setDebug5_64 (v_debug3_5_64) enable((*inhigh*)en3_5); method setDebug6_64 (v_debug3_6_64) enable((*inhigh*)en3_6); endinterface interface DebugILA ila4; method setDebug0 (v_debug4_0) enable((*inhigh*)en4_0); method setDebug1 (v_debug4_1) enable((*inhigh*)en4_1); method setDebug2 (v_debug4_2) enable((*inhigh*)en4_2); method setDebug3 (v_debug4_3) enable((*inhigh*)en4_3); method setDebug4 (v_debug4_4) enable((*inhigh*)en4_4); method setDebug5_64 (v_debug4_5_64) enable((*inhigh*)en4_5); method setDebug6_64 (v_debug4_6_64) enable((*inhigh*)en4_6); endinterface interface DebugILA ila5; method setDebug0 (v_debug5_0) enable((*inhigh*)en5_0); method setDebug1 (v_debug5_1) enable((*inhigh*)en5_1); method setDebug2 (v_debug5_2) enable((*inhigh*)en5_2); method setDebug3 (v_debug5_3) enable((*inhigh*)en5_3); method setDebug4 (v_debug5_4) enable((*inhigh*)en5_4); method setDebug5_64 (v_debug5_5_64) enable((*inhigh*)en5_5); method setDebug6_64 (v_debug5_6_64) enable((*inhigh*)en5_6); endinterface interface DebugILA ila6; method setDebug0 (v_debug6_0) enable((*inhigh*)en6_0); method setDebug1 (v_debug6_1) enable((*inhigh*)en6_1); method setDebug2 (v_debug6_2) enable((*inhigh*)en6_2); method setDebug3 (v_debug6_3) enable((*inhigh*)en6_3); method setDebug4 (v_debug6_4) enable((*inhigh*)en6_4); method setDebug5_64 (v_debug6_5_64) enable((*inhigh*)en6_5); method setDebug6_64 (v_debug6_6_64) enable((*inhigh*)en6_6); endinterface interface DebugILA ila7; method setDebug0 (v_debug7_0) enable((*inhigh*)en7_0); method setDebug1 (v_debug7_1) enable((*inhigh*)en7_1); method setDebug2 (v_debug7_2) enable((*inhigh*)en7_2); method setDebug3 (v_debug7_3) enable((*inhigh*)en7_3); method setDebug4 (v_debug7_4) enable((*inhigh*)en7_4); method setDebug5_64 (v_debug7_5_64) enable((*inhigh*)en7_5); method setDebug6_64 (v_debug7_6_64) enable((*inhigh*)en7_6); endinterface schedule ( ila0_setDebug0, ila0_setDebug1, ila0_setDebug2, ila0_setDebug3, ila0_setDebug4, ila0_setDebug5_64, ila0_setDebug6_64, ila1_setDebug0, ila1_setDebug1, ila1_setDebug2, ila1_setDebug3, ila1_setDebug4, ila1_setDebug5_64, ila1_setDebug6_64, ila2_setDebug0, ila2_setDebug1, ila2_setDebug2, ila2_setDebug3, ila2_setDebug4, ila2_setDebug5_64, ila2_setDebug6_64, ila3_setDebug0, ila3_setDebug1, ila3_setDebug2, ila3_setDebug3, ila3_setDebug4, ila3_setDebug5_64, ila3_setDebug6_64, ila4_setDebug0, ila4_setDebug1, ila4_setDebug2, ila4_setDebug3, ila4_setDebug4, ila4_setDebug5_64, ila4_setDebug6_64, ila5_setDebug0, ila5_setDebug1, ila5_setDebug2, ila5_setDebug3, ila5_setDebug4, ila5_setDebug5_64, ila5_setDebug6_64, ila6_setDebug0, ila6_setDebug1, ila6_setDebug2, ila6_setDebug3, ila6_setDebug4, ila6_setDebug5_64, ila6_setDebug6_64, ila7_setDebug0, ila7_setDebug1, ila7_setDebug2, ila7_setDebug3, ila7_setDebug4, ila7_setDebug5_64, ila7_setDebug6_64, vio_setDebugVin, vio_getDebugVout ) CF ( ila0_setDebug0, ila0_setDebug1, ila0_setDebug2, ila0_setDebug3, ila0_setDebug4, ila0_setDebug5_64, ila0_setDebug6_64, ila1_setDebug0, ila1_setDebug1, ila1_setDebug2, ila1_setDebug3, ila1_setDebug4, ila1_setDebug5_64, ila1_setDebug6_64, ila2_setDebug0, ila2_setDebug1, ila2_setDebug2, ila2_setDebug3, ila2_setDebug4, ila2_setDebug5_64, ila2_setDebug6_64, ila3_setDebug0, ila3_setDebug1, ila3_setDebug2, ila3_setDebug3, ila3_setDebug4, ila3_setDebug5_64, ila3_setDebug6_64, ila4_setDebug0, ila4_setDebug1, ila4_setDebug2, ila4_setDebug3, ila4_setDebug4, ila4_setDebug5_64, ila4_setDebug6_64, ila5_setDebug0, ila5_setDebug1, ila5_setDebug2, ila5_setDebug3, ila5_setDebug4, ila5_setDebug5_64, ila5_setDebug6_64, ila6_setDebug0, ila6_setDebug1, ila6_setDebug2, ila6_setDebug3, ila6_setDebug4, ila6_setDebug5_64, ila6_setDebug6_64, ila7_setDebug0, ila7_setDebug1, ila7_setDebug2, ila7_setDebug3, ila7_setDebug4, ila7_setDebug5_64, ila7_setDebug6_64, vio_setDebugVin, vio_getDebugVout ); endmodule ================================================ FILE: tests/algo1_flashmodel/ControllerTypes.bsv ================================================ `include "ConnectalProjectConfig.bsv" import FShow::*; //********************************************************** // Type definitions of the flash controller and submodules //********************************************************** //NAND geometry //Actual page size is 8640B, but we don't need the last 40B for ECC //Valid Data: 2 x (243B x 16 + 208B) = 8192B; //With ECC: 2 x (255B x 16 + 220B) = 8600 typedef 8600 PageSize; typedef 8192 PageSizeUser; typedef 17 PageECCBlks; //16 blocks of k=243; 1 block of k=208 `ifdef SIMULATION typedef 16 PagesPerBlock; typedef 128 BlocksPerCE; typedef 8 ChipsPerBus; `elsif SLC typedef 128 PagesPerBlock; typedef 8192 BlocksPerCE; typedef 4 ChipsPerBus; `else //MLC typedef 256 PagesPerBlock; typedef 4096 BlocksPerCE; typedef 8 ChipsPerBus; `endif typedef 2 BusWordBytes; typedef TMul#(8, BusWordBytes) BusWordSz; typedef 16 WordBytes; typedef TLog#(WordBytes) WordBytesLog; typedef TMul#(8,WordBytes) WordSz; //Each burst is 128 bits via the controller interface typedef TDiv#(PageSizeUser, WordBytes) PageWords; typedef TMul#(TMul#(BlocksPerCE, PagesPerBlock), PageWords) WordsPerChip; typedef WordSz FlashDataWidth; typedef 44 FlashAddrWidth; Integer pageSize = valueOf(PageSize); //bytes Integer pageSizeUser = valueOf(PageSizeUser); //usable page size is 8k Integer pageECCBlks = valueOf(PageECCBlks); //16 blocks of k=243; 1 block of k=208 Integer pagesPerBlock = valueOf(PagesPerBlock); Integer blocksPerCE = valueOf(BlocksPerCE); Integer chipsPerBus = valueOf(ChipsPerBus); Integer wordBytes = valueOf(WordBytes); Integer pageWords = valueOf(PageWords); //Integer blocksPerPlane = 2048; //Integer planesPerLun = 2; //Integer lunsPerTarget = 1; //1 for SLC, 2 for MLC `ifdef NAND_SIM typedef 1 NUM_CHIPBUSES; `else typedef 4 NUM_CHIPBUSES; `endif typedef 2 BUSES_PER_CHIPBUS; typedef TMul#(NUM_CHIPBUSES, BUSES_PER_CHIPBUS) NUM_BUSES; typedef 8 NUM_DEBUG_ILAS; typedef TMul#(NUM_BUSES, ChipsPerBus) NUM_TOTAL_CHIPS; typedef 128 NumTags; //typedef Bit#(TLog#(TDiv#(NumTags, NUM_BUSES))) BusTagT; typedef Bit#(TLog#(NumTags)) TagT; typedef Bit#(TLog#(ChipsPerBus)) ChipT; typedef Bit#(TLog#(NUM_BUSES)) BusT; Integer num_tags = valueOf(NumTags); Integer num_buses = valueOf(NUM_BUSES); typedef enum { SRC_HOST, SRC_USER_HW } SourceT deriving (Bits, Eq, FShow); typedef enum { ERASE_ERROR, ERASE_DONE, WRITE_DONE } StatusT deriving (Bits, Eq); //---------------------- //Aurora related types //---------------------- typedef enum { F_CMD, F_DATA, F_ACK, F_WR_REQ } PacketClass deriving (Bits, Eq); //---------------------- //Phy related types //---------------------- typedef enum { PHY_CHIP_SEL, PHY_DESELECT_ALL, PHY_CMD, PHY_READ, PHY_WRITE, PHY_ADDR, PHY_SYNC_CALIB, PHY_ENABLE_NAND_CLK } PhyCycle deriving (Bits, Eq); typedef enum { N_RESET = 8'hFF, N_READ_STATUS = 8'h70, N_SET_FEATURES = 8'hEF, N_PROGRAM_PAGE = 8'h80, N_PROGRAM_PAGE_END = 8'h10, N_READ_MODE = 8'h00, N_READ_PAGE_END = 8'h30, N_ERASE_BLOCK = 8'h60, N_ERASE_BLOCK_END = 8'hD0, N_READ_ID = 8'h90 } ONFICmd deriving (Bits, Eq); //using tagged union typedef union tagged { ONFICmd OnfiCmd; ChipT ChipSel; } NandCmd deriving (Bits); typedef struct { Bool inSyncMode; PhyCycle phyCycle; NandCmd nandCmd; Bit#(16) numBurst; Bit#(32) postCmdWait; //number of cycles to wait after the command } PhyCmd deriving (Bits); //--------------------------------- // Bus controller related types //--------------------------------- typedef enum { //INIT_BUS, //EN_SYNC, //INIT_SYNC, //READ_DATA, READ_CMD, GET_STATUS_READ_DATA, WRITE_DATA_BUF_REQ, WRITE_CMD_DATA, WRITE_GET_STATUS, ERASE_CMD, ERASE_GET_STATUS, INVALID } BusOp deriving (Bits, Eq); typedef struct { TagT tag; BusOp busOp; ChipT chip; Bit#(16) block; Bit#(8) page; } BusCmd deriving (Bits, Eq); //--------------------------------- // Flash controller related types //--------------------------------- typedef enum { INIT_BUS, EN_SYNC, INIT_SYNC, READ_PAGE, WRITE_PAGE, ERASE_BLOCK, INVALID } FlashOp deriving (Bits, Eq); typedef struct { TagT tag; FlashOp op; BusT bus; //3 ChipT chip; //3 Bit#(16) block; Bit#(8) page; } FlashCmd deriving (Bits, Eq); typedef struct { Bit#(8) page; Bit#(16) block; ChipT chip; BusT bus; } FlashAddr deriving (Bits, Eq); // Flash Controller User Ifc interface FlashCtrlUser; method Action sendCmd (FlashCmd cmd); method Action writeWord (Tuple2#(Bit#(128), TagT) taggedData); method ActionValue#(Tuple2#(Bit#(128), TagT)) readWord (); method ActionValue#(TagT) writeDataReq(); method ActionValue#(Tuple2#(TagT, StatusT)) ackStatus (); endinterface instance FShow#(BusOp); function Fmt fshow (BusOp label); case(label) READ_CMD: return fshow("BUSOP READ_CMD"); GET_STATUS_READ_DATA: return fshow("BUSOP GET_STATUS_READ_DATA"); WRITE_CMD_DATA: return fshow("BUSOP WRITE_CMD_DATA"); ERASE_CMD: return fshow("BUSOP ERASE_CMD"); WRITE_GET_STATUS: return fshow("BUSOP WRITE_GET_STATUS"); WRITE_DATA_BUF_REQ: return fshow("BUSOP WRITE_DATA_BUF_REQ"); ERASE_GET_STATUS: return fshow("BUSOP ERASE_GET_STATUS"); INVALID: return fshow("BUSOP INVALID"); endcase endfunction endinstance ================================================ FILE: tests/algo1_flashmodel/FlashBusModel.bsv ================================================ import FIFOF::*; import FIFO::*; import BRAMFIFO::*; import BRAM::*; import GetPut::*; import ClientServer::*; import Vector::*; import RegFile::*; import ControllerTypes::*; //For SIMULATION: use hashed read data (so we don't have to write before read) typedef 1 SIMULATION_USE_HASHED_DATA; typedef enum { ST_CMD, ST_OP_DELAY, ST_BUS_RESERVE, ST_WRITE_BUS_RESERVE, ST_WRITE_REQ, ST_ERASE, ST_ERROR, ST_READ_TRANSFER, ST_WRITE_DATA, ST_WRITE_ACK, ST_READ_DATA } ChipState deriving (Bits, Eq); function Bit#(TLog#(WordsPerChip)) getRegAddr (Bit#(16) block, Bit#(8) page, Bit#(16) burstCnt); Bit#(64) blockExt = zeroExtend(block); Bit#(64) pageExt = zeroExtend(page); Bit#(64) burstCntExt = zeroExtend(burstCnt); Bit#(64) regAddr = (blockExt<<(log2(pageWords*pagesPerBlock))) + (pageExt<= 0; i=i-1) begin Bit#(8) dataHi = truncate(dataCntTrim + fromInteger(i) + 8'hA0 + (blockTrim<<4)+ (chipTrim<<2) + (busTrim<<6)); Bit#(8) dataLow = truncate( (~dataHi) + blockTrim ); dataAggr[i] = {dataHi, dataLow}; end return pack(dataAggr); */ //FIXME tmp hashing for debug Bit#(128) busEx = zeroExtend(bus); Bit#(128) chipEx = zeroExtend(chip); Bit#(128) blockEx = zeroExtend(block); Bit#(128) pageEx = zeroExtend(page); Bit#(128) dataCntEx = zeroExtend(dataCnt); Bit#(128) dataRet = zeroExtend( (busEx<<64) + (chipEx<<48) + (blockEx<<32) + (pageEx<<16) + dataCntEx ); return dataRet; endfunction interface FlashBusModelIfc; method Action sendCmd(FlashCmd cmd); method Action writeWord (Tuple2#(Bit#(128), TagT) taggedData); method ActionValue#(Tuple2#(Bit#(128), TagT)) readWord (); method ActionValue#(TagT) writeDataReq(); method ActionValue#(Tuple2#(TagT, StatusT)) ackStatus (); endinterface (* synthesize *) (* descending_urgency = "chipWriteAck, chipWriteAck_1, chipWriteAck_2, chipWriteAck_3, chipWriteAck_4, chipWriteAck_5, chipWriteAck_6, chipWriteAck_7" *) module mkFlashBusModel(FlashBusModelIfc); Integer t_Read = 750; //read delay Integer t_Write = 5000; //write delay Integer t_Erase = 15000; //erase delay Integer burstDelay = 7; //read bursts 128 bits every 8 cycles //TODO adjust this //Create a regfile per chip Vector#(ChipsPerBus, RegFile#(Bit#(TLog#(WordsPerChip)), Bit#(128))) flashArr <- replicateM(mkRegFileFull()); //enq commands to each chip (emulated sb) Vector#(ChipsPerBus, FIFO#(FlashCmd)) flashChipCmdQs <- replicateM(mkSizedFIFO(16)); FIFO#(Tuple2#(Bit#(WordSz), TagT)) busReadQ <- mkFIFO(); Reg#(Bool) busInUse <- mkReg(False); Reg#(ChipT) busReservedChipIdx <- mkReg(0); FIFO#(Tuple2#(TagT, StatusT)) ackQ <- mkSizedFIFO(valueOf(NumTags)); FIFOF#(TagT) writeReqQ <- mkSizedFIFOF(3); Reg#(Bit#(4)) writeDataReqIssued <- mkReg(0); Reg#(Bit#(4)) writeDataReqProcessed <- mkReg(0); //2 page buffer FIFOF#(Tuple2#(Bit#(WordSz), TagT)) writeBuffer <- mkSizedFIFOF(pageWords*2+1); //simulate the round robin sb using a counter Reg#(Bit#(16)) chipSel <- mkReg(0); Reg#(Bit#(64)) cycleCnt <- mkReg(0); rule incCycleCnt; cycleCnt <= cycleCnt + 1; endrule rule checkWriteReqFull if (!writeReqQ.notFull); $display("**ERROR: FlashBusModel: Write data request buffer should never be full"); endrule rule checkWriteBufferFull if (!writeBuffer.notFull); $display("**ERROR: FlashBusModel: Write buffer should never be full"); endrule rule chipSelIncr; if (chipSel == fromInteger(chipsPerBus-1)) begin chipSel <= 0; end else begin chipSel <= chipSel + 1; end //$display("chipSel=%d", chipSel); endrule for (Integer c=0; c fromInteger(pagesPerBlock-1)) begin $display("**ERROR: cmd page exceeds simulation pages available. Sim pages=%d", pagesPerBlock); chipSt <= ST_ERROR; end else if (cmd.block > fromInteger(blocksPerCE-1)) begin $display("**ERROR: cmd block exceeds simulation blocks available. Sim blocks=%d", blocksPerCE); chipSt <= ST_ERROR; end else begin case (cmd.op) READ_PAGE: begin delayCnt <= fromInteger(t_Read); chipSt <= ST_OP_DELAY; chipStReturn <= ST_BUS_RESERVE; $display("@%d %m FlashBus chip[%d] starting READ cmd...", cycleCnt, cmd.chip); end WRITE_PAGE: begin chipSt <= ST_WRITE_REQ; delayCnt <= fromInteger(t_Write); $display("@%d %m FlashBus chip[%d] starting WRITE cmd...", cycleCnt, cmd.chip); end ERASE_BLOCK: begin chipSt <= ST_OP_DELAY; chipStReturn <= ST_ERASE; delayCnt <= fromInteger(t_Erase); $display("@%d %m FlashBus chip[%d] starting ERASE cmd...", cycleCnt, cmd.chip); end default: begin chipSt <= ST_ERROR;//throw error TODO $display("**ERROR: FlashBusModel invalid op"); end endcase end endrule //wait rule (tRead, tWrite, tErase) rule chipOpDelay if (chipSt==ST_OP_DELAY); if (delayCnt==0) begin chipSt <= chipStReturn; $display("%m FlashBus chip[%d] op delay done", c); end else begin delayCnt <= delayCnt-1; end endrule //READ: take control of bus rule chipReadBusReserve if (chipSt==ST_BUS_RESERVE && !busInUse && chipSel==fromInteger(c)); busReservedChipIdx <= fromInteger(c); busInUse <= True; chipSt <= ST_READ_TRANSFER; $display("@%d %m FlashBus reserved bus for chip = %d", cycleCnt, c); endrule //READ: transfer read only if selected and bus is reserved rule chipReadTransfer if (chipSt==ST_READ_TRANSFER && busInUse && busReservedChipIdx==fromInteger(c)); let cmd = flashChipCmdQs[c].first; //transfer 128bits every 8 cycles (to emulate flash behavior) if (readDlyCnt > 0) begin readDlyCnt <= readDlyCnt - 1; end else begin readDlyCnt <= fromInteger(burstDelay); if (valueOf(BSIM_USE_HASHED_DATA)==1) begin let dataHashed = getDataHash (readBurstCnt, cmd.page, cmd.block, cmd.chip, cmd.bus); busReadQ.enq(tuple2(dataHashed, cmd.tag)); $display("@%d %m FlashBus chip[%d] read data tag=%d @ [%d][%d][%d] = %x", cycleCnt, c, cmd.tag, cmd.block, cmd.page, readBurstCnt, dataHashed); end else begin //compute addr in regfile let regAddr = getRegAddr(cmd.block, cmd.page, readBurstCnt); let rdata = flashArr[c].sub(regAddr); busReadQ.enq(tuple2(rdata, cmd.tag)); $display("@%d %m FlashBus chip[%d] read data tag=%d @ regAddr=%d [%d][%d][%d] = %x", cycleCnt, c, regAddr, cmd.tag, cmd.block, cmd.page, readBurstCnt, rdata); end if (readBurstCnt==fromInteger(pageWords-1)) begin flashChipCmdQs[c].deq; readBurstCnt <= 0; chipSt <= ST_CMD; busInUse <= False; $display("@%d %m FlashBus chip[%d] done read", cycleCnt, cmd.chip); end else begin readBurstCnt <= readBurstCnt + 1; end end endrule //write request for data; when selected and have enough page buffers rule chipWriteDataReq if (chipSt==ST_WRITE_REQ && chipSel==fromInteger(c) && (writeDataReqIssued - writeDataReqProcessed) < 2); let cmd = flashChipCmdQs[c].first; writeReqQ.enq(cmd.tag); chipSt <= ST_WRITE_BUS_RESERVE; writeDataReqIssued <= writeDataReqIssued + 1; $display("@%d %m FlashBus chip[%d] writeDataReq issued, tag=%d", cycleCnt, c, cmd.tag); endrule //write data reserve bus rule chipWriteBusReserve if (chipSt==ST_WRITE_BUS_RESERVE && !busInUse && flashChipCmdQs[c].first.tag==tpl_2(writeBuffer.first) && chipSel==fromInteger(c) ); busReservedChipIdx <= fromInteger(c); busInUse <= True; chipSt <= ST_WRITE_DATA; $display("@%d %m FlashBus chip[%d] write bus reserved", cycleCnt, c); endrule //write data every 8 cycles rule chipWriteData if (chipSt==ST_WRITE_DATA && busInUse && busReservedChipIdx==fromInteger(c)); let cmd = flashChipCmdQs[c].first; if (wrDlyCnt > 0) begin wrDlyCnt <= wrDlyCnt - 1; end else begin wrDlyCnt <= fromInteger(burstDelay); if (cmd.tag==tpl_2(writeBuffer.first)) begin let regAddr = getRegAddr(cmd.block, cmd.page, writeBurstCnt); flashArr[c].upd(regAddr, tpl_1(writeBuffer.first)); writeBuffer.deq; $display("@%d %m FlashBus chip[%d] wrote data @ regAddr=%d [%d][%d][%d] = %x", cycleCnt, c,regAddr, cmd.block, cmd.page, writeBurstCnt, tpl_1(writeBuffer.first)); end else begin $display("**ERROR: FlashBusModel incorrect burst received. Cmd tag=%d, burst tag=%d", flashChipCmdQs[c].first.tag, tpl_2(writeBuffer.first)); end if (writeBurstCnt==fromInteger(pageWords-1)) begin //done transfer $display("@%d %m FlashBus chip[%d] write done transfer", cycleCnt, c); //wait tWrite chipSt <= ST_OP_DELAY; chipStReturn <= ST_WRITE_ACK; writeDataReqProcessed <= writeDataReqProcessed + 1; busInUse <= False; writeBurstCnt <= 0; end else begin writeBurstCnt <= writeBurstCnt + 1; end end endrule //write ack rule chipWriteAck if (chipSt==ST_WRITE_ACK); let cmd = flashChipCmdQs[c].first; flashChipCmdQs[c].deq; ackQ.enq(tuple2(cmd.tag, WRITE_DONE)); chipSt <= ST_CMD; $display("%m FlashBus chip[%d] write ack tag=%d", c, cmd.tag); endrule //erase Reg#(Bit#(16)) eraseWordCnt <- mkReg(0); Reg#(Bit#(8)) erasePageCnt <- mkReg(0); rule chipErase if (chipSt==ST_ERASE); let cmd = flashChipCmdQs[c].first; //erase entire block let regAddr = getRegAddr(cmd.block, erasePageCnt, eraseWordCnt); flashArr[c].upd(regAddr, -1); $display("%m FlashBus chip[%d] erasing tag=%d, blk = %d, pageCnt = %d, wordCnt = %d", c, cmd.tag, cmd.block, erasePageCnt, eraseWordCnt); if (eraseWordCnt == fromInteger(pageWords-1)) begin //done page eraseWordCnt <= 0; if (erasePageCnt == fromInteger(pagesPerBlock-1)) begin //done block flashChipCmdQs[c].deq; erasePageCnt <= 0; ackQ.enq(tuple2(cmd.tag, ERASE_DONE)); chipSt <= ST_CMD; end else begin erasePageCnt <= erasePageCnt + 1; end end else begin eraseWordCnt <= eraseWordCnt + 1; end endrule rule errorState if (chipSt==ST_ERROR); $display("**ERROR: FlashBusModel chip[%d] in error state", c); endrule end //chipsPerBus method Action sendCmd(FlashCmd cmd); flashChipCmdQs[cmd.chip].enq(cmd); endmethod method Action writeWord (Tuple2#(Bit#(128), TagT) taggedData); writeBuffer.enq(taggedData); endmethod method ActionValue#(Tuple2#(Bit#(128), TagT)) readWord (); busReadQ.deq; return busReadQ.first; endmethod method ActionValue#(TagT) writeDataReq(); writeReqQ.deq; return writeReqQ.first; endmethod method ActionValue#(Tuple2#(TagT, StatusT)) ackStatus (); ackQ.deq; return ackQ.first; endmethod endmodule ================================================ FILE: tests/algo1_flashmodel/FlashCtrlModel.bsv ================================================ import FIFOF::*; import FIFO::*; import BRAMFIFO::*; import BRAM::*; import GetPut::*; import ClientServer::*; import Vector::*; import RegFile::*; import AuroraCommon::*; import AuroraGearbox::*; import AuroraImportFmc1::*; import ControllerTypes::*; //import FlashCtrlVirtex::*; import FlashBusModel::*; //simulator options //Integer SIMULATION_CHIPS_PER_BUS = 2; //Integer SIMULATION_BLOCKS_PER_CHIP = 2; //Integer SIMULATION_PAGES_PER_BLOCK = 2; //Integer SIMULATION_BUSES = 4; //use hashed read data (so we don't have to write before read) //Integer SIMULATION_USE_HASHED_DATA = 1; /* interface FlashCtrlUser; method Action sendCmd (FlashCmd cmd); method Action writeWord (Bit#(128) data, TagT tag); method ActionValue#(Tuple2#(Bit#(128), TagT)) readWord (); method ActionValue#(TagT) writeDataReq(); method ActionValue#(Tuple2#(TagT, StatusT)) ackStatus (); endinterface interface FlashCtrlVirtexIfc; interface FlashCtrlUser user; interface Aurora_Pins#(4) aurora; interface FCVirtexDebug debug; endinterface */ interface FCVirtexDebug; method Tuple2#(DataIfc, PacketType) debugRecPacket(); method Tuple4#(Bit#(32), Bit#(32), Bit#(32), Bit#(32)) getDebugCnts; endinterface interface FlashCtrlVirtexIfc; interface FlashCtrlUser user; interface Aurora_Pins#(4) aurora; interface FCVirtexDebug debug; endinterface (* synthesize *) (* descending_urgency = "forwardReads, forwardReads_1, forwardReads_2, forwardReads_3, forwardReads_4, forwardReads_5, forwardReads_6, forwardReads_7" *) (* descending_urgency = "forwardWrDataReq, forwardWrDataReq_1, forwardWrDataReq_2, forwardWrDataReq_3, forwardWrDataReq_4, forwardWrDataReq_5, forwardWrDataReq_6, forwardWrDataReq_7" *) (* descending_urgency = "forwardAck, forwardAck_1, forwardAck_2, forwardAck_3, forwardAck_4, forwardAck_5, forwardAck_6, forwardAck_7" *) module mkFlashCtrlModel#( Clock gtx_clk_p, Clock gtx_clk_n, Clock clk250) (FlashCtrlVirtexIfc); //Flash bus models Vector#(NUM_BUSES, FlashBusModelIfc) flashBuses <- replicateM(mkFlashBusModel()); RegFile#(TagT, FlashCmd) tagTable <- mkRegFileFull(); FIFO#(Tuple2#(Bit#(WordSz), TagT)) rdDataQ <- mkSizedFIFO(16); //TODO size? FIFO#(TagT) wrDataReqQ <- mkSizedFIFO(16); FIFO#(Tuple2#(TagT, StatusT)) ackQ <- mkSizedFIFO(16); //GTX-GTP Aurora. Unused in model AuroraIfc auroraIntra <- mkAuroraIntra(gtx_clk_p, gtx_clk_n, clk250); //handle reads, acks, writedataReq for (Integer b=0; b < valueOf(NUM_BUSES); b=b+1) begin rule forwardReads; let rd <- flashBuses[b].readWord(); rdDataQ.enq(rd); endrule rule forwardWrDataReq; let req <- flashBuses[b].writeDataReq(); wrDataReqQ.enq(req); endrule rule forwardAck; let ack <- flashBuses[b].ackStatus(); ackQ.enq(ack); endrule end interface FlashCtrlUser user; method Action sendCmd (FlashCmd cmd); tagTable.upd(cmd.tag, cmd); flashBuses[cmd.bus].sendCmd(cmd); $display("FlashEmu: received cmd: tag=%d, bus=%d, chip=%d, blk=%d, page=%d", cmd.tag, cmd.bus, cmd.chip, cmd.block, cmd.page); endmethod method Action writeWord (Tuple2#(Bit#(WordSz), TagT) taggedData); FlashCmd cmd = tagTable.sub(tpl_2(taggedData)); flashBuses[cmd.bus].writeWord(taggedData); endmethod method ActionValue#(Tuple2#(Bit#(WordSz), TagT)) readWord (); rdDataQ.deq(); return rdDataQ.first(); endmethod method ActionValue#(TagT) writeDataReq(); wrDataReqQ.deq(); return wrDataReqQ.first(); endmethod method ActionValue#(Tuple2#(TagT, StatusT)) ackStatus(); ackQ.deq(); return ackQ.first(); endmethod endinterface interface FCVirtexDebug debug = ?; interface Aurora_Pins aurora = auroraIntra.aurora; endmodule /* rule doHandleCmd if (state==SEND_DATA); FlashCmd cmd = flashCmdQ.first; Bit#(16) data0 = truncate(rdataCnt); Bit#(16) data1 = zeroExtend(cmd.tag); Bit#(16) data2 = zeroExtend(cmd.bus); Bit#(16) data3 = zeroExtend(cmd.chip); Bit#(16) data4 = zeroExtend(cmd.block); Bit#(16) data5 = zeroExtend(cmd.page); Bit#(128) rData = zeroExtend({data0, data1, data2, data3, data4, data5}); rdDataQ.enq(tuple2(rData, cmd.tag)); $display("@%t: Flash Emu enqueued cnt=%d, tag=%x, data=%x", $time, rdataCnt, cmd.tag, rData); if (rdataCnt == fromInteger(pageSizeUser/16)-1) begin state <= FINISHED_CMD; rdataCnt <= 0; end else begin state <= WAIT; rdataCnt <= rdataCnt + 1; end endrule rule doWait if (state==WAIT); if (waitCnt == 0) begin state <= SEND_DATA; waitCnt <= fromInteger(waitCycles); end else begin waitCnt <= waitCnt - 1; end endrule rule doFinish if (state==FINISHED_CMD); flashCmdQ.deq; let cmd = flashCmdQ.first; state <= SEND_DATA; $display("@%t: Flash Emu: finished command tag=%x, bus=%x, chip=%x, block=%x, page=%x", $time, cmd.tag, cmd.bus, cmd.chip, cmd.block, cmd.page); endrule */ ================================================ FILE: tests/algo1_flashmodel/FlashTop.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFOF::*; import FIFO::*; import FIFOLevel::*; import BRAMFIFO::*; import BRAM::*; import GetPut::*; import ClientServer::*; import Vector::*; import BuildVector::*; import List::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; import Clocks :: *; import Xilinx :: *; `ifndef SIMULATION import XilinxCells ::*; `endif import AuroraImportFmc1::*; import AuroraCommon::*; import ControllerTypes::*; import ControllerTypes::*; import FlashCtrlModel::*; import PageBuffers::*; interface FlashRequest; method Action readPage(Bit#(32) bus, Bit#(32) chip, Bit#(32) block, Bit#(32) page, Bit#(32) tag); method Action writePage(Bit#(32) bus, Bit#(32) chip, Bit#(32) block, Bit#(32) page, Bit#(32) tag); method Action eraseBlock(Bit#(32) bus, Bit#(32) chip, Bit#(32) block, Bit#(32) tag); method Action addDmaReadRefs(Bit#(32) sglId, Bit#(32) offset, Bit#(32) tag); method Action addDmaWriteRefs(Bit#(32) sglId, Bit#(32) offset, Bit#(32) tag); method Action start(Bit#(32) dummy); method Action debugDumpReq(Bit#(32) dummy); method Action setDebugVals (Bit#(32) flag, Bit#(32) debugDelay); endinterface interface FlashIndication; method Action readDone(Bit#(32) tag); method Action writeDone(Bit#(32) tag); method Action eraseDone(Bit#(32) tag, Bit#(32) status); method Action debugDumpResp(Bit#(32) debug0, Bit#(32) debug1, Bit#(32) debug2, Bit#(32) debug3); endinterface // NumDmaChannels each for flash i/o and emualted i/o //typedef TAdd#(NumDmaChannels, NumDmaChannels) NumObjectClients; //typedef NumDmaChannels NumObjectClients; typedef 128 DmaBurstBytes; Integer dmaBurstBytes = valueOf(DmaBurstBytes); Integer dmaBurstWords = dmaBurstBytes/wordBytes; //128/16 = 8 Integer dmaBurstsPerPage = pageSizeUser/dmaBurstBytes; interface FlashTop; interface FlashRequest request; interface Vector#(1, MemWriteClient#(WordSz)) hostMemWriteClient; interface Vector#(1, MemReadClient#(WordSz)) hostMemReadClient; interface PhysMemSlave#(FlashAddrWidth, 128) memSlave; interface Aurora_Pins#(4) aurora_fmc1; interface Aurora_Clock_Pins aurora_clk_fmc1; endinterface module mkFlashTop#(FlashIndication indication, Clock clk250, Reset rst250)(FlashTop); Clock curClk <- exposeCurrentClock; Reset curRst <- exposeCurrentReset; Reg#(Bool) started <- mkReg(False); Reg#(Bit#(64)) cycleCnt <- mkReg(0); FIFO#(Tuple2#(FlashCmd, SourceT)) flashCmdQ <- mkSizedFIFO(valueOf(NumTags)); Vector#(NumTags, Reg#(Tuple2#(BusT, SourceT))) tag2busNsrcTable <- replicateM(mkRegU()); Vector#(NumTags, Reg#(Tuple2#(Bit#(32),Bit#(32)))) dmaWriteRefs <- replicateM(mkRegU()); Vector#(NumTags, Reg#(Tuple2#(Bit#(32),Bit#(32)))) dmaReadRefs <- replicateM(mkRegU()); Vector#(NUM_BUSES, FIFO#(Tuple2#(Bit#(WordSz), TagT))) dmaWriteBuf <- replicateM(mkSizedBRAMFIFO(dmaBurstWords*2)); //FIFO#(Tuple3#(Bit#(WordSz), TagT, Bool)) memSlaveReadBuf <- mkSizedBRAMFIFO(128); //doesn't matter size? Vector#(NUM_BUSES, FIFO#(Tuple2#(Bit#(WordSz), TagT))) dmaWriteBufOut <- replicateM(mkFIFO()); GtxClockImportIfc gtx_clk_fmc1 <- mkGtxClockImport; `ifdef SIMULATION FlashCtrlVirtexIfc flashCtrl <- mkFlashCtrlModel(gtx_clk_fmc1.gtx_clk_p_ifc, gtx_clk_fmc1.gtx_clk_n_ifc, clk250); `else FlashCtrlVirtexIfc flashCtrl <- mkFlashCtrlVirtex(gtx_clk_fmc1.gtx_clk_p_ifc, gtx_clk_fmc1.gtx_clk_n_ifc, clk250); `endif //Page Buffers for MemSlave PageBuffers pageBufs <- mkPageBuffers(); //Create read/write engines with NUM_BUSES memservers MemReadEngine#(WordSz,WordSz,1, NUM_BUSES) re <- mkMemReadEngine; MemWriteEngine#(WordSz,WordSz,1, NUM_BUSES) we <- mkMemWriteEngine; Vector#(NUM_BUSES, Reg#(Bit#(16))) dmaWBurstCnts <- replicateM(mkReg(0)); Vector#(NUM_BUSES, Reg#(Bit#(16))) memSlaveCnts <- replicateM(mkReg(0)); Vector#(NUM_BUSES, FIFO#(TagT)) dmaReqQs <- replicateM(mkSizedFIFO(valueOf(NumTags)));//TODO make bigger? Vector#(NUM_BUSES, FIFO#(Tuple2#(TagT, Bit#(32)))) dmaReq2RespQ <- replicateM(mkSizedFIFO(valueOf(NumTags))); //TODO make bigger? Vector#(NUM_BUSES, Reg#(Bit#(32))) dmaWrReqCnts <- replicateM(mkReg(0)); Vector#(NUM_BUSES, Reg#(TagT)) currTags <- replicateM(mkReg(0)); FIFO#(Tuple2#(Bit#(WordSz), TagT)) dataFlash2DmaQ <- mkFIFO(); rule incCycle; cycleCnt <= cycleCnt + 1; endrule rule driveFlashCmd/* (started)*/; let cmdNsrc = flashCmdQ.first; flashCmdQ.deq; let cmd = tpl_1(cmdNsrc); let src = tpl_2(cmdNsrc); tag2busNsrcTable[cmd.tag] <= tuple2(cmd.bus, src); flashCtrl.user.sendCmd(cmd); //forward cmd to flash ctrl FIXME DEBUG $display("@%d: Main.bsv: received cmd tag=%d @%x %x %x %x", cycleCnt, cmd.tag, cmd.bus, cmd.chip, cmd.block, cmd.page); endrule Reg#(Bit#(32)) delayRegSet <- mkReg(0); Reg#(Bit#(32)) delayReg <- mkReg(0); Reg#(Bit#(32)) debugFlag <- mkReg(0); //-------------------------------------------- // Reads from Flash (DMA Write) //-------------------------------------------- rule doEnqReadFromFlash; if (delayReg==0) begin let taggedRdata <- flashCtrl.user.readWord(); if (debugFlag==0) begin dataFlash2DmaQ.enq(taggedRdata); end delayReg <= delayRegSet; end else begin delayReg <= delayReg - 1; end endrule rule doDistributeReadFromFlash; let taggedRdata = dataFlash2DmaQ.first; dataFlash2DmaQ.deq; let tag = tpl_2(taggedRdata); let data = tpl_1(taggedRdata); let busNsrc = tag2busNsrcTable[tag]; let bus = tpl_1(busNsrc); let src = tpl_2(busNsrc); if (src==SRC_HOST) begin dmaWriteBuf[bus].enq(taggedRdata); end else if (src==SRC_USER_HW) begin pageBufs.readResp.put(taggedRdata); /* Bool last = False; if (memSlaveCnts[bus]==fromInteger(pageWords-1)) begin memSlaveCnts[bus] <= 0; last = True; end else begin memSlaveCnts[bus] <= memSlaveCnts[bus] + 1; end memSlaveReadBuf.enq(tuple3(data, tag, last)); */ end else begin $display("ERROR: flashTop: incorrect source"); end $display("@%d Main.bsv: rdata tag=%d, bus=%d, data[%d]=%x", cycleCnt, tag, bus, dmaWBurstCnts[bus], data); endrule for (Integer b=0; b>(16+8)); BusT bus = truncate(req.addr>>(16+8+valueOf(TLog#(ChipsPerBus)))); TagT tag = zeroExtend(req.tag); FlashCmd fcmd = FlashCmd{ tag: tag, op: READ_PAGE, bus: bus, chip: chip, block: block, page: page }; flashCmdQ.enq(tuple2(fcmd, SRC_USER_HW)); endmethod endinterface interface Get readData; method ActionValue#(MemData#(128)) get(); let taggedRdataLast = memSlaveReadBuf.first; Bit#(WordSz) data = tpl_1(taggedRdataLast); TagT tag = tpl_2(taggedRdataLast); Bool last = tpl_3(taggedRdataLast); memSlaveReadBuf.deq; MemData#(128) memData = MemData { data: data, tag: truncate(tag), //FIXME DANGEROUS last: last }; return memData; endmethod endinterface endinterface interface PhysMemWriteServer write_server = ?; endinterface */ interface PhysMemSlave memSlave = pageBufs.memSlave; interface FlashRequest request; method Action readPage(Bit#(32) bus, Bit#(32) chip, Bit#(32) block, Bit#(32) page, Bit#(32) tag); FlashCmd fcmd = FlashCmd{ tag: truncate(tag), op: READ_PAGE, bus: truncate(bus), chip: truncate(chip), block: truncate(block), page: truncate(page) }; flashCmdQ.enq(tuple2(fcmd, SRC_HOST)); endmethod method Action writePage(Bit#(32) bus, Bit#(32) chip, Bit#(32) block, Bit#(32) page, Bit#(32) tag); FlashCmd fcmd = FlashCmd{ tag: truncate(tag), op: WRITE_PAGE, bus: truncate(bus), chip: truncate(chip), block: truncate(block), page: truncate(page) }; flashCmdQ.enq(tuple2(fcmd, SRC_HOST)); endmethod method Action eraseBlock(Bit#(32) bus, Bit#(32) chip, Bit#(32) block, Bit#(32) tag); FlashCmd fcmd = FlashCmd{ tag: truncate(tag), op: ERASE_BLOCK, bus: truncate(bus), chip: truncate(chip), block: truncate(block), page: 0 }; flashCmdQ.enq(tuple2(fcmd, SRC_HOST)); endmethod method Action addDmaReadRefs(Bit#(32) sglId, Bit#(32) offset, Bit#(32) tag); dmaReadRefs[tag] <= tuple2(sglId, offset); endmethod method Action addDmaWriteRefs(Bit#(32) sglId, Bit#(32) offset, Bit#(32) tag); dmaWriteRefs[tag] <= tuple2(sglId, offset); endmethod method Action start(Bit#(32) dummy); started <= True; endmethod method Action debugDumpReq(Bit#(32) dummy); debugReqQ.enq(1); endmethod method Action setDebugVals (Bit#(32) flag, Bit#(32) debugDelay); delayRegSet <= debugDelay; debugFlag <= flag; endmethod endinterface //FlashRequest interface MemWriteClient hostMemWriteClient = vec(we.dmaClient); interface MemReadClient hostMemReadClient = vec(re.dmaClient); interface Aurora_Pins aurora_fmc1 = flashCtrl.aurora; interface Aurora_Clock_Pins aurora_clk_fmc1 = gtx_clk_fmc1.aurora_clk; endmodule ================================================ FILE: tests/algo1_flashmodel/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = StrstrRequest StrstrIndication FlashRequest FlashIndication BSVFILES = $(CONNECTALDIR)/lib/strstr/bsv/Strstr.bsv $(CONNECTALDIR)/lib/nandsim/bsv/NandSimNames.bsv Top.bsv FlashTop.bsv #CPPFILES2=$(CONNECTALDIR)/examples/algo1_nandsim/test.cpp CPPFILES=test.cpp CONNECTALFLAGS += -D DEGPAR=2 CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/strstr/cpp CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/nandsim/cpp PIN_TYPE = Top_Pins PIN_TYPE_INCLUDE = TopPins CONNECTALFLAGS += -D IMPORT_HOSTIF --bscflags " -D DataBusWidth=128 " --clib rt include $(CONNECTALDIR)/Makefile.connectal # #Note: for some reason, xbsv can't parase ControllerTypes.bsv properly. So a soft link in current directory is created # BSVFILES = Main.bsv Top.bsv \ # ../../xilinx/aurora_8b10b_fmc1/AuroraImportFmc1.bsv \ # ../../src/lib/AuroraCommon.bsv \ # ../../controller/src/common/FlashBusModel.bsv \ # ../../controller/src/model_virtex/FlashCtrlModel.bsv \ # ../../controller/src/hw_virtex/FlashCtrlVirtex.bsv # CPPFILES=main.cpp # #CONNECTALFLAGS=--bscflags " -D TRACE_AXI" # ifeq ($(BOARD), vc707) # CONNECTALFLAGS += \ # --verilog ../../xilinx/aurora_8b10b_fmc1/ \ # --xci $(CONNECTALDIR)/out/$(BOARD)/aurora_8b10b_fmc1/aurora_8b10b_fmc1.xci \ # --constraint ../../xilinx/aurora_8b10b_fmc1/aurora_8b10b_fmc1_exdes.xdc # #--verilog ../../../xbsv/xilinx/ddr3_v1_7/ \ # --constraint ../../xilinx/ddr3_v2_0/vc707_ddr3_sx.xdc \ # --constraint $(CONNECTALDIR)/xilinx/constraints/vc707_ddr3.xdc \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/ \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/clocking \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/controller \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/ecc \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/ip_top \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/phy \ # --verilog $(BLUESPECDIR)/board_support/bluenoc/xilinx/VC707/verilog/ddr3_v2_0/ddr3_v2_0/user_design/rtl/ui \ # AURORA_INTRA = $(CONNECTALDIR)/out/$(BOARD)/aurora_8b10b_fmc1/aurora_8b10b_fmc1_stub.v # prebuild:: $(AURORA_INTRA) # $(AURORA_INTRA): core-scripts/synth-aurora-intra.tcl # (cd $(BOARD); vivado -mode batch -source ../core-scripts/synth-aurora-intra.tcl) # endif # include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/algo1_flashmodel/NandSimMod.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BRAMFIFO::*; import FIFO::*; import FIFOF::*; import GetPut::*; import Vector::*; import BRAM::*; import GetPut::*; import Connectable::*; import Pipe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import FlashCtrlModel::*; interface NandCfgRequest; method Action startRead(Bit#(32) drampointer, Bit#(32) dramOffset, Bit#(32) nandAddr, Bit#(32) numBytes, Bit#(32) burstLen); method Action startWrite(Bit#(32) drampointer, Bit#(32) dramOffset, Bit#(32) nandAddr, Bit#(32) numBytes, Bit#(32) burstLen); method Action startErase(Bit#(32) nandAddr, Bit#(32) numBytes); endinterface interface NandCfgIndication; method Action readDone(Bit#(32) tag); method Action writeDone(Bit#(32) tag); method Action eraseDone(Bit#(32) tag); endinterface interface NandSimMod#(numeric type numSlaves, numeric type memengineOuts); interface NandCfgRequest request; interface Vector#(numSlaves,PhysMemSlave#(PhysAddrWidth,64)) memSlaves; endinterface interface NandSimControl; interface NandCfgRequest request; endinterface module mkNandSimMod#(NandCfgIndication indication, MemReadServer#(64) nand_ctrl_host_rs, MemWriteServer#(64) nand_ctrl_host_ws) (NandSimMod#(numSlaves,memengineOuts)) provisos( Add#(a__, TLog#(TAdd#(numSlaves, 1)), 6) , Add#(b__, TLog#(TAdd#(numSlaves, 1)), TLog#(TMul#(4, TAdd#(numSlaves, 1)))) , Pipe::FunnelPipesPipelined#(1, TAdd#(numSlaves, 1), Tuple2#(Bit#(64), Bool), TMin#(2, TLog#(TAdd#(numSlaves, 1)))) , Pipe::FunnelPipesPipelined#(1, TAdd#(numSlaves, 1), Tuple2#(Bit#(TLog#(TAdd#(numSlaves, 1))), MemTypes::MemengineCmd), TMin#(2, TLog#(TAdd#(numSlaves, 1)))) , Add#(c__, TLog#(TAdd#(numSlaves, 1)), TAdd#(1, TLog#(TMul#(4, TAdd#(numSlaves, 1))))) , Add#(d__, TLog#(TAdd#(numSlaves, 2)), 6) , Pipe::FunnelPipesPipelined#(1, TAdd#(numSlaves, 2), Tuple3#(Bit#(TLog#(TAdd#(numSlaves, 2))), Bit#(64), Bool), TMin#(2, TLog#(TAdd#(numSlaves, 2)))) , Pipe::FunnelPipesPipelined#(1, TAdd#(numSlaves, 2), Tuple3#(Bit#(2), Bit#(64), Bool), TMin#(2, TLog#(TAdd#(numSlaves, 2)))) , Add#(e__, TLog#(TAdd#(numSlaves, 2)), TLog#(TMul#(4, TAdd#(numSlaves, 2)))) , Pipe::FunnelPipesPipelined#(1, TAdd#(numSlaves, 2), Tuple2#(Bit#(64), Bool), TMin#(2, TLog#(TAdd#(numSlaves, 2)))) , Pipe::FunnelPipesPipelined#(1, TAdd#(numSlaves, 2), Tuple2#(Bit#(TLog#(TAdd#(numSlaves, 2))), MemTypes::MemengineCmd), TMin#(2, TLog#(TAdd#(numSlaves, 2)))) , Add#(f__, TLog#(TAdd#(numSlaves, 2)), TAdd#(1, TLog#(TMul#(4, TAdd#(numSlaves, 2))))) , Add#(g__, TLog#(TAdd#(numSlaves, 1)), TLog#(TMul#(memengineOuts, TAdd#(numSlaves, 1)))) , Add#(h__, TLog#(TAdd#(numSlaves, 1)), TAdd#(1, TLog#(TMul#(memengineOuts, TAdd#(numSlaves, 1))))) , Add#(i__, TLog#(TAdd#(numSlaves, 2)), TLog#(TMul#(memengineOuts, TAdd#(numSlaves, 2)))) , Add#(j__, TLog#(TAdd#(numSlaves, 2)), TAdd#(1, TLog#(TMul#(memengineOuts, TAdd#(numSlaves, 2))))) ); let verbose = False; MemReadEngine#(64,64,memengineOuts, TAdd#(numSlaves,1)) re <- mkMemReadEngine(); MemWriteEngine#(64,64,memengineOuts, TAdd#(numSlaves,2)) we <- mkMemWriteEngine(); NandSimControl ns <- mkNandSimControl(nand_ctrl_host_rs, re.readServers[0], nand_ctrl_host_ws, we.writeServers[0], we.writeServers[1], indication); Vector#(numSlaves,MemReadServer#(64)) slave_read_servers = takeTail(re.readServers); Vector#(numSlaves,MemWriteServer#(MemengineCmd,Bool)) slave_write_servers = takeTail(we.writeServers); Vector#(numSlaves,FIFO#(Bit#(MemTagSize))) slaveWriteTags <- replicateM(mkSizedBRAMFIFO(valueOf(memengineOuts))); Vector#(numSlaves,FIFO#(Bit#(MemTagSize))) slaveReadTags <- replicateM(mkSizedBRAMFIFO(valueOf(memengineOuts))); Vector#(numSlaves,Reg#(Bit#(BurstLenSize))) slaveReadCnts <- replicateM(mkReg(0)); connectToFlashModel(re.dmaClient,we.dmaClient); function PhysMemSlave#(PhysAddrWidth,64) mms(Integer i); return ( interface PhysMemSlave; interface PhysMemWriteServer write_server; interface Put writeReq; method Action put(PhysMemRequest#(PhysAddrWidth) req); slave_write_servers[i].request.put(MemengineCmd{sglId:0, base:extend(req.addr), burstLen:req.burstLen, len:extend(req.burstLen), tag:req.tag}); slaveWriteTags[i].enq(req.tag); endmethod endinterface interface Put writeData; method Action put(MemData#(64) wdata); slave_write_servers[i].data.enq(wdata.data); endmethod endinterface interface Get writeDone; method ActionValue#(Bit#(MemTagSize)) get(); let rv <- slave_write_servers[i].done.get; slaveWriteTags[i].deq; return slaveWriteTags[i].first; endmethod endinterface endinterface interface PhysMemReadServer read_server; interface Put readReq; method Action put(PhysMemRequest#(PhysAddrWidth) req); if (verbose) $display("mkNandSim.memSlave::readReq %d %d %d (%d)", req.addr, req.burstLen, req.tag, i); slave_read_servers[i].request.put(MemengineCmd{sglId:0, base:extend(req.addr), burstLen:req.burstLen, len:extend(req.burstLen), tag:req.tag}); slaveReadTags[i].enq(req.tag); slaveReadCnts[i] <= req.burstLen; endmethod endinterface interface Get readData; method ActionValue#(MemData#(64)) get(); let rv <- toGet(slave_read_servers[i].data).get; let new_slaveReadCnt = slaveReadCnts[i]-8; let last = new_slaveReadCnt==0; slaveReadCnts[i] <= new_slaveReadCnt; if (verbose) $display("mkNandSim.memSlave::readData %d %d %d %d (%d)", slaveReadTags[i].first, last, rv.data, slaveReadCnts[i], i); if (rv.last) slaveReadTags[i].deq; return MemData{data:rv.data, tag:slaveReadTags[i].first,last:last}; endmethod endinterface endinterface endinterface ); endfunction interface memSlaves = map(mms,genVector); interface request = ns.request; endmodule module mkNandSimControl#(MemReadServer#(64) dram_read_server, MemReadServer#(64) nand_read_server, MemWriteServer#(64) dram_write_server, MemWriteServer#(64) nand_write_server, MemWriteServer#(64) nand_erase_server, NandCfgIndication indication) (NandSimControl); FIFOF#(Bit#(32)) readReqFifo <- mkFIFOF(); FIFOF#(Bit#(32)) writeReqFifo <- mkFIFOF(); Reg#(Bit#(32)) readCountReg <- mkReg(0); Reg#(Bit#(32)) writeCountReg <- mkReg(0); FIFOF#(Bool) readDoneFifo <- mkFIFOF(); FIFOF#(Bool) writeDoneFifo <- mkFIFOF(); FIFO#(void) dram_read_done <- mkFIFO; FIFO#(void) nand_read_done <- mkFIFO; rule countNandWrite; let v <- toGet(dram_read_server.data).get(); let count = writeCountReg; if (count == 0) count = writeReqFifo.first(); //$display("write v=%h count=%d", v.data, count); nand_write_server.data.enq(v.data); if (count == 8) begin writeReqFifo.deq(); writeDoneFifo.enq(True); end writeCountReg <= count-8; if (v.last) dram_read_done.enq(?); endrule rule countNandRead; let v <- toGet(nand_read_server.data).get(); let count = readCountReg; if (count == 0) count = readReqFifo.first(); //$display("read v=%h count=%d", v.data, count); dram_write_server.data.enq(v.data); if (count == 8) begin readReqFifo.deq(); readDoneFifo.enq(True); end readCountReg <= count-8; if (v.last) nand_read_done.enq(?); endrule PipeOut#(Bit#(64)) erasePipe = (interface PipeOut#(Bit#(64)); method Bit#(64) first(); return fromInteger(-1); endmethod method Action deq(); endmethod method Bool notEmpty(); return True; endmethod endinterface); rule eraseRule; let v <- toGet(nand_erase_server.data).get; toPut(erasePipe).put(v.data); endrule rule eraseDone; let done <- nand_erase_server.done.get(); $display("eraseDone"); indication.eraseDone(0); endrule rule writeDone; let nandWriteDone <- nand_write_server.done.get(); dram_read_done.deq; let v <- toGet(writeDoneFifo).get(); $display("writeDone"); indication.writeDone(0); endrule rule readDone; nand_read_done.deq; let dramWriteDone <- dram_write_server.done.get(); let v <- toGet(readDoneFifo).get(); $display("readDone"); indication.readDone(0); endrule interface NandCfgRequest request; /*! * Reads from NAND and writes to DRAM */ method Action startRead(Bit#(32) pointer, Bit#(32) dramOffset, Bit#(32) nandAddr,Bit#(32) numBytes, Bit#(32) burstLen); $display("startRead numBytes=%d burstLen=%d", numBytes, burstLen); readReqFifo.enq(numBytes); nand_read_server.request.put(MemengineCmd {sglId: 0, base: extend(nandAddr), burstLen: truncate(burstLen), len: extend(numBytes), tag:0}); dram_write_server.request.put(MemengineCmd {sglId: pointer, base: extend(dramOffset), burstLen: truncate(burstLen), len: extend(numBytes), tag:0}); endmethod /*! * Reads from DRAM and writes to NAND */ method Action startWrite(Bit#(32) pointer, Bit#(32) dramOffset, Bit#(32) nandAddr,Bit#(32) numBytes, Bit#(32) burstLen); $display("startWrite numBytes=%d burstLen=%d", numBytes, burstLen); writeReqFifo.enq(numBytes); nand_write_server.request.put(MemengineCmd {sglId: 0, base: extend(nandAddr), burstLen: truncate(burstLen), len: extend(numBytes), tag:0}); dram_read_server.request.put(MemengineCmd {sglId: pointer, base: extend(dramOffset), burstLen: truncate(burstLen), len: extend(numBytes), tag:0}); endmethod method Action startErase(Bit#(32) nandAddr, Bit#(32) numBytes); $display("startErase numBytes=%d burstLen=%d", numBytes, 16); nand_erase_server.request.put(MemengineCmd {sglId: 0, base: extend(nandAddr), burstLen: 16, len: extend(numBytes), tag:0}); endmethod endinterface endmodule ================================================ FILE: tests/algo1_flashmodel/NullResetN.bsv ================================================ package NullResetN; interface NullResetNIfc; interface Reset rst_n; endinterface import "BVI" null_reset_n = module mkNullResetN (NullResetNIfc); default_clock no_clock; default_reset no_reset; output_reset rst_n(RESET_N); endmodule endpackage: NullResetN ================================================ FILE: tests/algo1_flashmodel/PageBuffers.bsv ================================================ import FIFOF::*; import FIFO::*; import FIFOLevel::*; import BRAMFIFO::*; import BRAM::*; import GetPut::*; import ClientServer::*; import Arbiter::*; import Vector::*; import List::*; import ConnectalMemTypes::*; import ControllerTypes::*; interface PageBuffers; interface PhysMemSlave#(FlashAddrWidth, 128) memSlave; //to user hw interface Get#(FlashCmd) flashReq; interface Put#(Tuple2#(Bit#(WordSz), TagT)) readResp; endinterface typedef TLog#(PageWords) PageOffsetSz; typedef enum { ST_INIT, ST_CMD, ST_HIT, ST_MISS, ST_MISS_READDATA } BufOpState deriving (Bits, Eq); typedef struct { Bool valid; FlashAddr faddr; } PageBufferEntry deriving (Bits, Eq); typedef struct { FlashAddr faddr; Bit#(PageOffsetSz) offset; } PageAddrOff deriving (Bits, Eq); function PageAddrOff decodePhysMemAddr(Bit#(FlashAddrWidth) addr); //byte addressible Tuple2#(PageAddrOff, Bit#(TLog#(WordBytes))) decodedAddr = unpack(truncate(addr)); return tpl_1(decodedAddr); //PageAddrOff decodedAddr = unpack(truncate(addr)); //FIXME FIXME FIXME //return decodedAddr; endfunction function TagT splitTagsByBus(Integer id, Bit#(32) cnt); Bit#(32) group = fromInteger(id * (valueOf(NumTags)/valueOf(NUM_BUSES))); return truncate(group + cnt); endfunction function BusT tag2bus(TagT tag); return truncate( tag>>(log2(num_tags/num_buses)) ); endfunction //TODO: for now assumes that the request does not cross page boundaries (* synthesize *) module mkPageBuffers(PageBuffers); //Page Buffers Vector#(NUM_BUSES, PageBuffers) pageBuffers = newVector(); for (Integer bus=0; bus>fromInteger(valueOf(WordBytesLog)); respRemain <= currReq.burstLen>>fromInteger(valueOf(WordBytesLog)); end else begin //if miss, make request to flash controller $display("PageBuffers: miss"); state <= ST_MISS; pageBufEntry.valid <= False; end endrule rule handleHit (state==ST_HIT && reqRemain>0); Bit#(32) burstOffset = zeroExtend((currReq.burstLen>>fromInteger(valueOf(WordBytesLog))) - reqRemain); if (burstOffset >= fromInteger(pageWords)) begin $display("PageBuffer: **ERROR burstOffset exceeds number of pageWords"); end Bit#(PageOffsetSz) baddr = addrOff.offset + truncate(burstOffset); //safe truncation $display("PageBuffer: portB read req addrOff=%x, burstOffset=%x, baddr= %x", addrOff.offset, burstOffset, baddr); pageBuffer.portB.request.put( BRAMRequest{ write: False, responseOnWrite: ?, address: baddr, datain: ?} ); reqRemain <= reqRemain - 1; endrule rule handleHitData (state==ST_HIT); let data <- pageBuffer.portB.response.get(); Bool last = (respRemain==1); slaveRespQ.enq( MemData { data: data, tag: currReq.tag, last: last} ); $display("PageBuffer: hit data=%x, tag=%d, last=%d", data, currReq.tag, last); if (respRemain==1) begin state <= ST_CMD; slaveReqQ.deq; end else begin respRemain <= respRemain - 1; end endrule rule missFlashRequest (state==ST_MISS); //get free tag freeTagQ.deq; let ftag = freeTagQ.first; FlashCmd fcmd = FlashCmd { tag: ftag, op: READ_PAGE, bus: addrOff.faddr.bus, chip: addrOff.faddr.chip, block: addrOff.faddr.block, page: addrOff.faddr.page }; flashCmdQ.enq(fcmd); $display("PageBuffers: missFlashRequest issued for: ftag=%d, bus=%d, chip=%d, blk=%d, page=%d", ftag, addrOff.faddr.bus, addrOff.faddr.chip, addrOff.faddr.block, addrOff.faddr.page); state <= ST_MISS_READDATA; endrule rule missGetFlashRead (state==ST_MISS_READDATA); //TODO: only one buffer, so no reordering per bus flashReadQ.deq; let data = tpl_1(flashReadQ.first); let tag = tpl_2(flashReadQ.first); $display("PageBuffers: got read data from flash: tag=%d, data=%x", tag, data); pageBuffer.portA.request.put( BRAMRequest{ write:True, responseOnWrite:False, address:writePtr , datain: data } ); if (writePtr==fromInteger(pageWords-1)) begin //update metadata about what's in the buffer pageBufEntry <= PageBufferEntry { valid: True, faddr: addrOff.faddr}; freeTagQ.enq(tag); state <= ST_CMD; //reattempt command writePtr <= 0; end else begin writePtr <= writePtr + 1; end endrule interface PhysMemSlave memSlave; interface PhysMemReadServer read_server; interface Put readReq = toPut(slaveReqQ); interface Get readData = toGet(slaveRespQ); endinterface interface PhysMemWriteServer write_server = ?; endinterface interface Get flashReq = toGet(flashCmdQ); interface Put readResp = toPut(flashReadQ); endmodule ================================================ FILE: tests/algo1_flashmodel/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import ConnectalConfig::*; import SpecialFIFOs::*; import Vector::*; import BuildVector::*; import StmtFSM::*; import FIFO::*; import BRAM::*; import DefaultValue::*; import Connectable::*; import CtrlMux::*; import Portal::*; import HostInterface::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemServer::*; import MemServerInternal::*; import ConnectalMMU::*; import MemReadEngine::*; import MemWriteEngine::*; import MMURequest::*; import StrstrRequest::*; import MemServerIndication::*; import MMUIndication::*; import StrstrIndication::*; import NandSimNames::*; import Strstr::*; import AuroraCommon::*; import FlashTop::*; import ControllerTypes::*; import FlashRequest::*; import FlashIndication::*; import TopPins::*; module mkConnectalTop#(HostInterface host)(ConnectalTop); Clock clk250 = host.derivedClock; Reset rst250 = host.derivedReset; // strstr algo StrstrIndicationProxy strstrIndicationProxy <- mkStrstrIndicationProxy(IfcNames_AlgoIndicationH2S); Strstr#(128,128) strstr <- mkStrstr(strstrIndicationProxy.ifc); StrstrRequestWrapper strstrRequestWrapper <- mkStrstrRequestWrapper(IfcNames_AlgoRequestS2H,strstr.request); // algo mmu MMUIndicationProxy algoMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_AlgoMMUIndicationH2S); MMU#(PhysAddrWidth) algoMMU <- mkMMU(0, True, algoMMUIndicationProxy.ifc); MMURequestWrapper algoMMURequestWrapper <- mkMMURequestWrapper(IfcNames_AlgoMMURequestS2H, algoMMU.request); // backing store mmu MMUIndicationProxy backingMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_BackingStoreMMUIndicationH2S); MMU#(PhysAddrWidth) backingMMU <- mkMMU(1, True, backingMMUIndicationProxy.ifc); MMURequestWrapper backingMMURequestWrapper <- mkMMURequestWrapper(IfcNames_BackingStoreMMURequestS2H, backingMMU.request); // nand mmu MMUIndicationProxy nandMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_NandMMUIndicationH2S); MMU#(FlashAddrWidth) nandMMU <- mkMMU(0, False, nandMMUIndicationProxy.ifc); MMURequestWrapper nandMMURequestWrapper <- mkMMURequestWrapper(IfcNames_NandMMURequestS2H, nandMMU.request); // flash top FlashIndicationProxy flashIndicationProxy <- mkFlashIndicationProxy(IfcNames_NandCfgIndicationH2S); FlashTop flashtop <- mkFlashTop(flashIndicationProxy.ifc, clk250, rst250); FlashRequestWrapper flashRequestWrapper <- mkFlashRequestWrapper(IfcNames_NandCfgRequestS2H,flashtop.request); // host memory server MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_MemServerIndicationH2S); let rcs = append(strstr.config_read_client,flashtop.hostMemReadClient); let wcs = flashtop.hostMemWriteClient; MemServer#(PhysAddrWidth,DataBusWidth,1) hostMemServer <- mkMemServer(rcs,wcs,vec(algoMMU,backingMMU), hostMemServerIndicationProxy.ifc); // flash memory read server MemServerIndicationProxy flashMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_NandMemServerIndicationH2S); MemServer#(FlashAddrWidth,FlashDataWidth,1) flashMemServer <- mkMemServer(strstr.haystack_read_client, nil, vec(nandMMU), flashMemServerIndicationProxy.ifc); mkConnection(flashMemServer.masters[0], flashtop.memSlave); Vector#(12,StdPortal) portals; portals[0] = strstrRequestWrapper.portalIfc; portals[1] = strstrIndicationProxy.portalIfc; portals[2] = algoMMURequestWrapper.portalIfc; portals[3] = algoMMUIndicationProxy.portalIfc; portals[4] = nandMMURequestWrapper.portalIfc; portals[5] = nandMMUIndicationProxy.portalIfc; portals[6] = flashRequestWrapper.portalIfc; portals[7] = flashIndicationProxy.portalIfc; portals[8] = hostMemServerIndicationProxy.portalIfc; //portals[9] = hostMemServerRequestWrapper.portalIfc; portals[9] = flashMemServerIndicationProxy.portalIfc; portals[10] = backingMMURequestWrapper.portalIfc; portals[11] = backingMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = hostMemServer.masters; interface Top_Pins pins; interface Aurora_Pins aurora_fmc1 = flashtop.aurora_fmc1; interface Aurora_Clock_Pins aurora_clk_fmc1 = flashtop.aurora_clk_fmc1; endinterface endmodule : mkConnectalTop ================================================ FILE: tests/algo1_flashmodel/TopPins.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import AuroraCommon::*; interface Top_Pins; interface Aurora_Pins#(4) aurora_fmc1; interface Aurora_Clock_Pins aurora_clk_fmc1; endinterface ================================================ FILE: tests/algo1_flashmodel/flashaccess.cpp ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include "dmaManager.h" #include "FlashIndication.h" #include "FlashRequest.h" static int trace_memory = 0; extern "C" { #include "userReference.h" } #define BLOCKS_PER_CHIP 2 #define CHIPS_PER_BUS 8 #define NUM_BUSES 8 #define PAGE_SIZE 8192 #define NUM_TAGS 128 typedef enum { UNINIT, ERASED, WRITTEN } FlashStatusT; typedef struct { bool busy; int bus; int chip; int block; } TagTableEntry; FlashRequestProxy *device; pthread_mutex_t flashReqMutex; pthread_cond_t flashFreeTagCond; //8k * 128 size_t dstAlloc_sz = PAGE_SIZE * NUM_TAGS *sizeof(unsigned char); size_t srcAlloc_sz = PAGE_SIZE * NUM_TAGS *sizeof(unsigned char); int dstAlloc; int srcAlloc; unsigned int ref_dstAlloc; unsigned int ref_srcAlloc; unsigned int* dstBuffer; unsigned int* srcBuffer; unsigned int* readBuffers[NUM_TAGS]; unsigned int* writeBuffers[NUM_TAGS]; TagTableEntry readTagTable[NUM_TAGS]; TagTableEntry writeTagTable[NUM_TAGS]; TagTableEntry eraseTagTable[NUM_TAGS]; FlashStatusT flashStatus[NUM_BUSES][CHIPS_PER_BUS][BLOCKS_PER_CHIP]; int testPass = 1; bool verbose = true; int curReadsInFlight = 0; int curWritesInFlight = 0; int curErasesInFlight = 0; double timespec_diff_sec( timespec start, timespec end ) { double t = end.tv_sec - start.tv_sec; t += ((double)(end.tv_nsec - start.tv_nsec)/1000000000L); return t; } unsigned int hashAddrToData(int bus, int chip, int blk, int word) { return ((bus<<24) + (chip<<20) + (blk<<16) + word); } bool checkReadData(int tag) { TagTableEntry e = readTagTable[tag]; int goldenData; if (flashStatus[e.bus][e.chip][e.block]==WRITTEN) { int numErrors = 0; for (int word=0; worderaseBlock(bus,chip,block,tag); } void writePage(int bus, int chip, int block, int page, int tag) { pthread_mutex_lock(&flashReqMutex); curWritesInFlight ++; flashStatus[bus][chip][block] = WRITTEN; pthread_mutex_unlock(&flashReqMutex); if ( verbose ) fprintf(stderr, "LOG: sending write page request with tag=%d @%d %d %d %d\n", tag, bus, chip, block, page ); device->writePage(bus,chip,block,page,tag); } void readPage(int bus, int chip, int block, int page, int tag) { pthread_mutex_lock(&flashReqMutex); curReadsInFlight ++; readTagTable[tag].bus = bus; readTagTable[tag].chip = chip; readTagTable[tag].block = block; pthread_mutex_unlock(&flashReqMutex); if ( verbose ) fprintf(stderr, "LOG: sending read page request with tag=%d @%d %d %d %d\n", tag, bus, chip, block, page ); device->readPage(bus,chip,block,page,tag); } int main(int argc, const char **argv) { DmaManager *dma = platformInit(); fprintf(stderr, "Main::allocating memory...\n"); device = new FlashRequestProxy(IfcNames_NandCfgRequest); FlashIndication *deviceIndication = new FlashIndication(IfcNames_NandCfgIndication); srcAlloc = portalAlloc(srcAlloc_sz, 0); dstAlloc = portalAlloc(dstAlloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcAlloc_sz); dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstAlloc_sz); fprintf(stderr, "dstAlloc = %x\n", dstAlloc); fprintf(stderr, "srcAlloc = %x\n", srcAlloc); pthread_mutex_init(&flashReqMutex, NULL); pthread_cond_init(&flashFreeTagCond, NULL); printf( "Done initializing hw interfaces\n" ); fflush(stdout); portalCacheFlush(dstAlloc, dstBuffer, dstAlloc_sz, 1); portalCacheFlush(srcAlloc, srcBuffer, srcAlloc_sz, 1); ref_dstAlloc = dma->reference(dstAlloc); ref_srcAlloc = dma->reference(srcAlloc); for (int t = 0; t < NUM_TAGS; t++) { readTagTable[t].busy = false; writeTagTable[t].busy = false; int byteOffset = t * PAGE_SIZE; device->addDmaWriteRefs(ref_dstAlloc, byteOffset, t); device->addDmaReadRefs(ref_srcAlloc, byteOffset, t); readBuffers[t] = dstBuffer + byteOffset/sizeof(unsigned int); writeBuffers[t] = srcBuffer + byteOffset/sizeof(unsigned int); } for (int blk=0; blkstart(0); device->setDebugVals(0,0); //flag, delay device->debugDumpReq(0); sleep(1); device->debugDumpReq(0); sleep(1); //TODO: test writes and erases //test erases for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ eraseBlock(bus, chip, blk, waitIdleEraseTag()); } } } while (true) { usleep(100); if ( getNumErasesInFlight() == 0 ) break; } //read back erased pages for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ for (int bus = 0; bus < NUM_BUSES; bus++){ int page = 0; readPage(bus, chip, blk, page, waitIdleReadBuffer()); } } } while (true) { usleep(100); if ( getNumReadsInFlight() == 0 ) break; } //write pages //FIXME: in old xbsv, simulatneous DMA reads using multiple readers cause kernel panic //Issue each bus separately for now for (int bus = 0; bus < NUM_BUSES; bus++){ for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){ for (int chip = 0; chip < CHIPS_PER_BUS; chip++){ int page = 0; //get free tag int freeTag = waitIdleWriteBuffer(); //fill write memory for (int w=0; wdebugDumpReq(0); } else { elapsed--; } if ( getNumReadsInFlight() == 0 ) break; } device->debugDumpReq(0); clock_gettime(CLOCK_REALTIME, & now); fprintf(stderr, "LOG: finished reading from page! %f\n", timespec_diff_sec(start, now) ); for ( int t = 0; t < NUM_TAGS; t++ ) { for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) { fprintf(stderr, "%x %x %x\n", t, i, readBuffers[t][i] ); } } if (testPass==1) { fprintf(stderr, "LOG: TEST PASSED!\n"); } else { fprintf(stderr, "LOG: **ERROR: TEST FAILED!\n"); } } ================================================ FILE: tests/algo1_flashmodel/test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "StrstrIndication.h" #include "StrstrRequest.h" #include "MMURequest.h" #include "MMUIndication.h" #include "MemServerRequest.h" #include "MemServerIndication.h" static int trace_memory = 1; extern "C" { #include "sys/ioctl.h" #include "drivers/portalmem/portalmem.h" #include "sock_utils.h" #include "userReference.h" } #include "nandsim.h" #include "strstr.h" class MMUIndication : public MMUIndicationWrapper { DmaManager *portalMemory; public: MMUIndication(DmaManager *pm, unsigned int id, int tile=DEFAULT_TILE) : MMUIndicationWrapper(id,tile), portalMemory(pm) {} MMUIndication(DmaManager *pm, unsigned int id, PortalTransportFunctions *item, void *param) : MMUIndicationWrapper(id, item, param), portalMemory(pm) {} virtual void configResp(uint32_t pointer){ fprintf(stderr, "MMUIndication::configResp: %x\n", pointer); portalMemory->confResp(pointer); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MMUIndication::error(code=0x%x:%s, pointer=0x%x, offset=0x%"PRIx64" extra=0x%"PRIx64"\n", code, dmaErrors[code], pointer, offset, extra); if (--mmu_error_limit < 0) exit(-1); } virtual void idResponse(uint32_t sglId){ portalMemory->sglIdResp(sglId); } }; class MemServerIndication : public MemServerIndicationWrapper { MemServerRequestProxy *memServerRequestProxy; sem_t mtSem; uint64_t mtCnt; void init(){ if (sem_init(&mtSem, 0, 0)) PORTAL_PRINTF("MemServerIndication::init failed to init mtSem\n"); } public: MemServerIndication(unsigned int id, int tile=DEFAULT_TILE) : MemServerIndicationWrapper(id,tile), memServerRequestProxy(NULL) {init();} MemServerIndication(MemServerRequestProxy *p, unsigned int id, int tile=DEFAULT_TILE) : MemServerIndicationWrapper(id,tile), memServerRequestProxy(p) {init();} virtual void addrResponse(uint64_t physAddr){ fprintf(stderr, "DmaIndication::addrResponse(physAddr=%"PRIx64")\n", physAddr); } virtual void reportStateDbg(const DmaDbgRec rec){ fprintf(stderr, "MemServerIndication::reportStateDbg: {x:%08x y:%08x z:%08x w:%08x}\n", rec.x,rec.y,rec.z,rec.w); } virtual void reportMemoryTraffic(uint64_t words){ //fprintf(stderr, "reportMemoryTraffic: words=%"PRIx64"\n", words); mtCnt = words; sem_post(&mtSem); } virtual void error (uint32_t code, uint32_t pointer, uint64_t offset, uint64_t extra) { fprintf(stderr, "MemServerIndication::error(code=%x, pointer=%x, offset=%"PRIx64" extra=%"PRIx64"\n", code, pointer, offset, extra); if (--mem_error_limit < 0) exit(-1); } uint64_t receiveMemoryTraffic(){ sem_wait(&mtSem); return mtCnt; } uint64_t getMemoryTraffic(const ChannelType rc){ assert(memServerRequestProxy); memServerRequestProxy->memoryTraffic(rc); return receiveMemoryTraffic(); } }; size_t numBytes = 1 << 10; int main(int argc, const char **argv) { fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); DmaManager *hostDma = platformInit(); MMURequestProxy *nandsimMMURequest = new MMURequestProxy(IfcNames_NandMMURequestS2H); DmaManager *nandsimDma = new DmaManager(nandsimMMURequest); MMUIndication nandsimMMUIndication(nandsimDma,IfcNames_NandMMUIndicationH2S); StrstrRequestProxy *strstrRequest = new StrstrRequestProxy(IfcNames_AlgoRequestS2H); StrstrIndication *strstrIndication = new StrstrIndication(IfcNames_AlgoIndicationH2S); MemServerIndication hostMemServerIndication(IfcNames_MemServerIndicationH2S); MemServerIndication nandsimMemServerIndication(IfcNames_NandMemServerIndicationH2S); fprintf(stderr, "Main::allocating memory...\n"); // allocate memory for strstr data int needleAlloc = portalAlloc(numBytes, 0); int mpNextAlloc = portalAlloc(numBytes, 0); int ref_needleAlloc = hostDma->reference(needleAlloc); int ref_mpNextAlloc = hostDma->reference(mpNextAlloc); fprintf(stderr, "%08x %08x\n", ref_needleAlloc, ref_mpNextAlloc); char *needle = (char *)portalMmap(needleAlloc, numBytes); int *mpNext = (int *)portalMmap(mpNextAlloc, numBytes); const char *needle_text = "ababab"; int needle_len = strlen(needle_text); strncpy(needle, needle_text, needle_len); compute_MP_next(needle, mpNext, needle_len); // fprintf(stderr, "mpNext=["); // for(int i= 0; i <= needle_len; i++) // fprintf(stderr, "%d ", mpNext[i]); // fprintf(stderr, "]\nneedle=["); // for(int i= 0; i < needle_len; i++) // fprintf(stderr, "%d ", needle[i]); // fprintf(stderr, "]\n"); portalCacheFlush(needleAlloc, needle, numBytes, 1); portalCacheFlush(mpNextAlloc, mpNext, numBytes, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); // fprintf(stderr, "Main::waiting to connect to nandsim_exe\n"); // wait_for_connect_nandsim_exe(); // fprintf(stderr, "Main::connected to nandsim_exe\n"); // base of haystack in "flash" memory // this is read from nandsim_exe, but could also come from kernel driver //int haystack_base = read_from_nandsim_exe(); //int haystack_len = read_from_nandsim_exe(); int haystack_len = 0x100; // request the next sglist identifier from the sglistMMU hardware module // which is used by the mem server accessing flash memory. int id = 0; MMURequest_idRequest(nandsimDma->priv.sglDevice, 0); sem_wait(&nandsimDma->priv.sglIdSem); id = nandsimDma->priv.sglId; // pairs of ('offset','size') pointing to space in nandsim memory // this is unsafe. To do it properly, we should get this list from // nandsim_exe or from the kernel driver. This code here might overrun // the backing store allocated by nandsim_exe. // RegionRef region[] = {{0, 0x100000}, {0x100000, 0x100000}}; RegionRef region[] = {{0x100000, 0x100000}}; printf("[%s:%d]\n", __FUNCTION__, __LINE__); int ref_haystackInNandMemory = send_reference_to_portal(nandsimDma->priv.sglDevice, sizeof(region)/sizeof(region[0]), region, id); sem_wait(&(nandsimDma->priv.confSem)); fprintf(stderr, "%08x\n", ref_haystackInNandMemory); // at this point, ref_needleAlloc and ref_mpNextAlloc are valid sgListIds for use by // the host memory dma hardware, and ref_haystackInNandMemory is a valid sgListId for // use by the nandsim dma hardware fprintf(stderr, "about to setup device %d %d\n", ref_needleAlloc, ref_mpNextAlloc); strstrRequest->setup(ref_needleAlloc, ref_mpNextAlloc, needle_len); fprintf(stderr, "about to invoke search %d\n", ref_haystackInNandMemory); strstrRequest->search(ref_haystackInNandMemory, haystack_len); strstrIndication->wait(); fprintf(stderr, "algo1_flashmodel: Done\n"); sleep(2); exit(!(strstrIndication->match_cnt==3)); } ================================================ FILE: tests/algo1_nandsim_manual/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = NandCfgRequest StrstrRequest NandCfgIndication StrstrIndication BSVFILES = $(CONNECTALDIR)/lib/nandsim/bsv/NandSim.bsv $(CONNECTALDIR)/lib/strstr/bsv/Strstr.bsv $(CONNECTALDIR)/examples/algo1_nandsim/Top.bsv $(CONNECTALDIR)/lib/nandsim/bsv/NandSimNames.bsv CPPFILES=algo1.cpp CPPFILES2=nandsim_manual.c CONNECTALFLAGS += -D2 NO_CPP_PORTAL_CODE -lm CONNECTALFLAGS += -D DEGPAR=2 # -lblkid CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/strstr/cpp CONNECTALFLAGS += -DNO_POLLER_SUPPORT include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/algo1_nandsim_manual/algo1.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "NandCfgIndication.h" #include "NandCfgRequest.h" #include "StrstrIndication.h" #include "StrstrRequest.h" static int trace_memory = 1; extern "C" { #include "sys/ioctl.h" #include "drivers/portalmem/portalmem.h" #include "sock_utils.h" #include "userReference.h" } size_t numBytes = 1 << 12; #ifndef BOARD_bluesim size_t nandBytes = 1 << 24; #else size_t nandBytes = 1 << 14; #endif class NandCfgIndication : public NandCfgIndicationWrapper { public: unsigned int rDataCnt; virtual void readDone(uint32_t v){ fprintf(stderr, "NandSim::readDone v=%x\n", v); sem_post(&sem); } virtual void writeDone(uint32_t v){ fprintf(stderr, "NandSim::writeDone v=%x\n", v); sem_post(&sem); } virtual void eraseDone(uint32_t v){ fprintf(stderr, "NandSim::eraseDone v=%x\n", v); sem_post(&sem); } virtual void configureNandDone(){ fprintf(stderr, "NandSim::configureNandDone\n"); sem_post(&sem); } NandCfgIndication(int id) : NandCfgIndicationWrapper(id) { sem_init(&sem, 0, 0); } void wait() { fprintf(stderr, "NandSim::wait for semaphore\n"); sem_wait(&sem); } private: sem_t sem; }; class StrstrIndication : public StrstrIndicationWrapper { public: StrstrIndication(unsigned int id) : StrstrIndicationWrapper(id){ sem_init(&sem, 0, 0); match_cnt = 0; }; virtual void setupComplete() { fprintf(stderr, "Strstr::setupComplete\n"); sem_post(&sem); } virtual void searchResult (int v){ fprintf(stderr, "searchResult = %d\n", v); if (v == -1) sem_post(&sem); else match_cnt++; } void wait() { fprintf(stderr, "Strstr::wait for semaphore\n"); sem_wait(&sem); } int match_cnt; private: sem_t sem; }; int main(int argc, const char **argv) { fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); DmaManager *dma = platformInit(); MMURequestProxy *nandMMURequest = new MMURequestProxy(IfcNames_NandMMURequest); DmaManager *nandsimDma = new DmaManager(nandMMURequest); MMUIndication *nandMMUIndication = new MMUIndication(nandsimDma,IfcNames_NandMMUIndication); StrstrRequestProxy *strstrRequest = new StrstrRequestProxy(IfcNames_AlgoRequest); StrstrIndication *strstrIndication = new StrstrIndication(IfcNames_AlgoIndication); fprintf(stderr, "Main::allocating memory...\n"); // allocate memory for strstr data int needleAlloc = portalAlloc(numBytes, 0); int mpNextAlloc = portalAlloc(numBytes, 0); int ref_needleAlloc = hostDma->reference(needleAlloc); int ref_mpNextAlloc = hostDma->reference(mpNextAlloc); fprintf(stderr, "%08x %08x\n", ref_needleAlloc, ref_mpNextAlloc); char *needle = (char *)portalMmap(needleAlloc, numBytes); int *mpNext = (int *)portalMmap(mpNextAlloc, numBytes); const char *needle_text = "ababab"; int needle_len = strlen(needle_text); strncpy(needle, needle_text, needle_len); compute_MP_next(needle, mpNext, needle_len); // fprintf(stderr, "mpNext=["); // for(int i= 0; i <= needle_len; i++) // fprintf(stderr, "%d ", mpNext[i]); // fprintf(stderr, "]\nneedle=["); // for(int i= 0; i < needle_len; i++) // fprintf(stderr, "%d ", needle[i]); // fprintf(stderr, "]\n"); portalCacheFlush(needleAlloc, needle, numBytes, 1); portalCacheFlush(mpNextAlloc, mpNext, numBytes, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); // base of haystack in "flash" memory // this is read from nandsim_exe, but could also come from kernel driver int haystack_base = 0; int haystack_len = 64; // request the next sglist identifier from the sglistMMU hardware module // which is used by the mem server accessing flash memory. int id = 0; MMURequest_idRequest(nandsimDma->priv.sglDevice, -1); sem_wait(&nandsimDma->priv.sglIdSem); id = nandsimDma->priv.sglId; // pairs of ('offset','size') pointing to space in nandsim memory // this is unsafe. To do it properly, we should get this list from // nandsim_exe or from the kernel driver. This code here might overrun // the backing store allocated by nandsim_exe. RegionRef region[] = {{0, 0x100000}, {0x100000, 0x100000}}; printf("[%s:%d]\n", __FUNCTION__, __LINE__); int ref_haystackInNandMemory = send_reference_to_portal(nandsimDma->priv.sglDevice, sizeof(region)/sizeof(region[0]), region, id); sem_wait(&(nandsimDma->priv.confSem)); fprintf(stderr, "%08x\n", ref_haystackInNandMemory); // at this point, ref_needleAlloc and ref_mpNextAlloc are valid sgListIds for use by // the host memory dma hardware, and ref_haystackInNandMemory is a valid sgListId for // use by the nandsim dma hardware fprintf(stderr, "about to setup device %d %d\n", ref_needleAlloc, ref_mpNextAlloc); strstrRequest->setup(ref_needleAlloc, ref_mpNextAlloc, needle_len); strstrIndication->wait(); fprintf(stderr, "about to invoke search %d\n", ref_haystackInNandMemory); strstrRequest->search(ref_haystackInNandMemory, haystack_len); strstrIndication->wait(); exit(!(strstrIndication->match_cnt==3)); } ================================================ FILE: tests/algo1_nandsim_manual/haystack.txt ================================================ acabcabacababacababababababcacabcabacababacabababc 012345678912 ================================================ FILE: tests/algo1_nandsim_manual/kernel/Makefile ================================================ # grep get_pcie_portal_descriptor /proc/kallsyms ###################### Flags for using KC705 ################### #BOARD=kc705 ###################### Flags for using VC707 ################### BOARD=vc707 ###################### Flags for using zedboard ################## #BOARD=zedboard ###################### Flags for using Bluesim ################### #BOARD=bluesim ###################### End of target h/w flags ################### ifeq ($(BOARD),bluesim) HARDWARE_FLAGS=-DBSIM endif export KROOT=/lib/modules/$(shell uname -r)/build CPPDIR=../../../cpp BOARDDIR=../$(BOARD)/jni DRIVERDIR=$(src)/../../../drivers KBUILD_EXTRA_SYMBOLS := $(DRIVERDIR)/pcieportal/Module.symvers $(DRIVERDIR)/portalmem/Module.symvers #$(BOARDDIR)/DmaConfigProxy.o \ #$(BOARDDIR)/DmaIndicationWrapper.o \ kernel_exe-y := ../nandsim_manual.o \ $(BOARDDIR)/MMURequestProxy.o \ $(BOARDDIR)/MMUIndicationWrapper.o \ $(BOARDDIR)/MemServerRequestProxy.o \ $(BOARDDIR)/MemServerIndicationWrapper.o \ $(BOARDDIR)/NandCfgIndicationWrapper.o \ $(BOARDDIR)/NandCfgRequestProxy.o \ $(CPPDIR)/portal.o \ $(CPPDIR)/dmaManager.o \ $(CPPDIR)/kernel_module.o ifeq ($(BOARD),bluesim) kernel_exe-y += $(CPPDIR)/sock_utils.o endif obj-m := kernel_exe.o ccflags-y := -I$(src)/.. -I$(DRIVERDIR)/pcieportal -I$(DRIVERDIR)/portalmem -I$(src)/$(CPPDIR) -I$(src)/$(BOARDDIR) $(HARDWARE_FLAGS) -DBOARD_$(BOARD) default: $(MAKE) -C $(KROOT) M=$(PWD) modules clean: $(MAKE) -C $(KROOT) M=$(PWD) clean rm -f $(kernel_exe-y) a.out bsim_relay CURRENTMOD=$(shell lsmod | grep kernel_exe) run: host ifeq ($(BOARD),bluesim) @echo running bsim ../bluesim/bin/bsim& echo $$! >tmp.bluesim.makefile.pid else fpgajtag ../$(BOARD)/bin/mkTop.bin.gz endif ifneq ("$(CURRENTMOD)", "") sudo rmmod kernel_exe #sudo rmmod bdbm_drv endif sudo insmod kernel_exe.ko #sudo insmod bdbm_drv.ko ifeq ($(BOARD),bluesim) ./bsim_relay kill `cat tmp.bluesim.makefile.pid` #killall bluetcl endif sudo rmmod kernel_exe #sudo rmmod bdbm_drv dmesg | tail -30 @rm -f tmp.bluesim.makefile.pid # # Target for making userspace bsim_relay program CPPDIR=../../../cpp HOSTSOURCES=$(CPPDIR)/bsim_relay.c $(CPPDIR)/sock_utils.c host: $(HOSTSOURCES) ifeq ($(BOARD),bluesim) gcc -o bsim_relay -g -I$(CPPDIR) $(HOSTSOURCES) -lpthread endif ================================================ FILE: tests/algo1_nandsim_manual/nandsim_manual.c ================================================ /* Copyright (c) 2014 Sungjin Lee, MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef __KERNEL__ #include // msleep #include #else #include #include #include #include #include #endif #include "dmaManager.h" #include "sock_utils.h" // bsim_poll_interrupt() #include "GeneratedTypes.h" #include "drivers/portalmem/portalmem.h" static int trace_memory;// = 1; #define MAX_INDARRAY 4 static PortalInternal intarr[MAX_INDARRAY]; static sem_t test_sem; static int burstLen = 16; #ifndef SIMULATION #define numWords 0x1240000/4 // make sure to allocate at least one entry of each size #else #define numWords 0x1240/4 #endif static long back_sz = numWords*sizeof(unsigned int); static DmaManagerPrivate priv; int NandCfgIndicationWrappereraseDone_cb ( struct PortalInternal *p, const uint32_t tag ) { PORTAL_PRINTF( "cb: NandSim_eraseDone(tag = %x)\n", tag); sem_post(&test_sem); } int NandCfgIndicationWrapperwriteDone_cb ( struct PortalInternal *p, const uint32_t tag ) { PORTAL_PRINTF( "cb: NandSim_writeDone(tag = %x)\n", tag); sem_post(&test_sem); } int NandCfgIndicationWrapperreadDone_cb ( struct PortalInternal *p, const uint32_t tag ) { PORTAL_PRINTF( "cb: NandSim_readDone(tag = %x)\n", tag); sem_post(&test_sem); } int NandCfgIndicationWrapperconfigureNandDone_cb ( struct PortalInternal *p ) { PORTAL_PRINTF( "cb: NandSim_NandDone\n"); sem_post(&test_sem); } int MMUIndicationWrapperconfigResp_cb ( struct PortalInternal *p, const uint32_t pointer ) { PORTAL_PRINTF("cb: MMUIndicationWrapperconfigResp_cb(physAddr=%x)\n", pointer); sem_post(&priv.confSem); } int MMUIndicationWrapperidResponse_cb ( struct PortalInternal *p, const uint32_t sglId ) { PORTAL_PRINTF("cb: MMUIndicationWrapperidResponse_cb\n"); priv.sglId = sglId; sem_post(&priv.sglIdSem); } int MMUIndicationWrappererror_cb ( struct PortalInternal *p, const uint32_t code, const uint32_t pointer, const uint64_t offset, const uint64_t extra ) { PORTAL_PRINTF("cb: MMUIndicationWrappererror_cb\n"); } void manual_event(void) { int i; for (i = 0; i < MAX_INDARRAY; i++) event_hardware(&intarr[i]); } #ifdef __KERNEL__ DECLARE_COMPLETION(worker_completion); #endif static void *pthread_worker(void *p) { void *rc = NULL; while (1) { #if defined(BSIM) && !defined(__KERNEL__) if (bsim_poll_interrupt()) #endif manual_event(); #ifdef __KERNEL__ msleep(10); if (kthread_should_stop()) { PORTAL_PRINTF ("pthread_worker ends\n"); break; } #else ///////////////////////// userspace version struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000; select(0, NULL, NULL, NULL, &timeout); #endif } #ifdef __KERNEL__ complete(&worker_completion); #endif return rc; } NandCfgIndicationCb NandCfgIndication_cbTable = { NandCfgIndicationWrappereraseDone_cb, NandCfgIndicationWrapperwriteDone_cb, NandCfgIndicationWrapperreadDone_cb, NandCfgIndicationWrapperconfigureNandDone_cb, }; MMUIndicationCb MMUIndication_cbTable = { MMUIndicationWrapperconfigResp_cb, MMUIndicationWrapperidResponse_cb, MMUIndicationWrappererror_cb, }; int main(int argc, const char **argv) { int srcAlloc; int backAlloc; unsigned int *srcBuffer; unsigned int ref_srcAlloc; unsigned int *backBuffer; unsigned int ref_backAlloc; int rc = 0, i; pthread_t tid = 0; init_portal_internal(&intarr[2], IfcNames_BackingStoreMMURequest, NULL, NULL, NULL, NULL, MMURequest_reqinfo); // fpga3 init_portal_internal(&intarr[0], IfcNames_BackingStoreMMUIndication, MMUIndication_handleMessage, &MMUIndication_cbTable, NULL, NULL, MMUIndication_reqinfo); // fpga1 init_portal_internal(&intarr[3], IfcNames_NandCfgRequest, NULL, NULL, NULL, NULL, NandCfgRequest_reqinfo); // fpga4 init_portal_internal(&intarr[1], IfcNames_NandCfgIndication, NandCfgIndication_handleMessage, &NandCfgIndication_cbTable, NULL, NULL, NandCfgIndication_reqinfo); // fpga2 DmaManager_init(&priv, &intarr[2]); sem_init(&test_sem, 0, 0); PORTAL_PRINTF( "Main: creating exec thread - %lu\n", sizeof (unsigned int) ); if(pthread_create(&tid, NULL, pthread_worker, NULL)){ PORTAL_PRINTF( "error creating exec thread\n"); return -1; } backAlloc = portalAlloc (back_sz, 0); PORTAL_PRINTF("backAlloc=%d\n", backAlloc); ref_backAlloc = DmaManager_reference(&priv, backAlloc); PORTAL_PRINTF("ref_backAlloc=%d\n", ref_backAlloc); backBuffer = (unsigned int*)portalMmap(backAlloc, back_sz); portalCacheFlush(backAlloc, backBuffer, back_sz, 1); NandCfgRequest_configureNand (&intarr[3], ref_backAlloc, back_sz); PORTAL_PRINTF("Main::configure NAND fd=%d ref=%d\n", backAlloc, ref_backAlloc); sem_wait(&test_sem); srcAlloc = portalAlloc(back_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, back_sz); ref_srcAlloc = DmaManager_reference(&priv, srcAlloc); PORTAL_PRINTF("about to start write\n"); //write data to "flash" memory strcpy((char*)srcBuffer, "acabcabacababacababababababcacabcabacababacabababc\n012345678912"); NandCfgRequest_startWrite(&intarr[3], ref_srcAlloc, 0, 0, 1024, 8); sem_wait(&test_sem); // at this point, if we were synchronizing with the algo_exe, we // could tell it that it was OK to start searching PORTAL_PRINTF ("initialization of data in \"flash\" memory complete\n"); #ifdef __KERNEL__ if (tid && !kthread_stop (tid)) { PORTAL_PRINTF ("kthread stops\n"); } wait_for_completion(&worker_completion); msleep(20000); #else sleep(20); #endif #ifdef __KERNEL__ portalmem_dmabuffer_destroy(backAlloc); portalmem_dmabuffer_destroy(srcAlloc); #endif PORTAL_PRINTF ("Main: ends\n"); return 0; } ================================================ FILE: tests/avalon_mm/AvalonBfmWrapper.bsv ================================================ /* /home/hwang/dev/connectal/generated/scripts/importbvi.py -I AvalonMM -P AvalonMM -c clk_clk -r reset_reset_n -f master_0 -f slave_0 -o AvalonBfmWrapper.bsv avlm_avls_1x1.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AvalonBits::*; (* always_ready, always_enabled *) interface AvalonBfmWrapper#(numeric type addrWidth, numeric type dataWidth); //interface AvalonMMasterBits#(addrWidth, dataWidth) master_0; interface AvalonMSlaveBits#(addrWidth, dataWidth) slave_0; endinterface import "BVI" avlm_avls_1x1 = module mkAvalonBfmWrapper(AvalonBfmWrapper#(addrWidth, dataWidth)); default_clock clk(); default_reset rst(); input_clock (clk_clk) <- exposeCurrentClock; input_reset (reset_reset_n) <- exposeCurrentReset; // interface AvalonMMasterBits master_0; // method master_0_m0_address address(); // method master_0_m0_burstcount burstcount(); // method master_0_m0_byteenable byteenable(); // method master_0_m0_read read(); // method readdata(master_0_m0_readdata) enable((*inhigh*) EN_master_0_m0_readdata); // method readdatavalid(master_0_m0_readdatavalid) enable((*inhigh*) EN_master_0_m0_readdatavalid); // method waitrequest(master_0_m0_waitrequest) enable((*inhigh*) EN_master_0_m0_waitrequest); // method master_0_m0_write write(); // method master_0_m0_writedata writedata(); // endinterface interface AvalonMSlaveBits slave_0; method address(slave_0_s0_address) enable((*inhigh*) EN_slave_0_s0_address); method burstcount(slave_0_s0_burstcount) enable((*inhigh*) EN_slave_0_s0_burstcount); method byteenable(slave_0_s0_byteenable) enable((*inhigh*) EN_slave_0_s0_byteenable); method read(slave_0_s0_read) enable((*inhigh*) EN_slave_0_s0_read); method slave_0_s0_readdata readdata(); method slave_0_s0_readdatavalid readdatavalid(); method slave_0_s0_waitrequest waitrequest(); method write(slave_0_s0_write) enable((*inhigh*) EN_slave_0_s0_write); method writedata(slave_0_s0_writedata) enable((*inhigh*) EN_slave_0_s0_writedata); endinterface //schedule (master_0.address, master_0.burstcount, master_0.byteenable, master_0.read, master_0.readdata, master_0.readdatavalid, master_0.waitrequest, master_0.write, master_0.writedata, slave_0.address, slave_0.burstcount, slave_0.byteenable, slave_0.read, slave_0.readdata, slave_0.readdatavalid, slave_0.waitrequest, slave_0.write, slave_0.writedata) CF (master_0.address, master_0.burstcount, master_0.byteenable, master_0.read, master_0.readdata, master_0.readdatavalid, master_0.waitrequest, master_0.write, master_0.writedata, slave_0.address, slave_0.burstcount, slave_0.byteenable, slave_0.read, slave_0.readdata, slave_0.readdatavalid, slave_0.waitrequest, slave_0.write, slave_0.writedata); schedule (slave_0.address, slave_0.burstcount, slave_0.byteenable, slave_0.read, slave_0.readdata, slave_0.readdatavalid, slave_0.waitrequest, slave_0.write, slave_0.writedata) CF (slave_0.address, slave_0.burstcount, slave_0.byteenable, slave_0.read, slave_0.readdata, slave_0.readdatavalid, slave_0.waitrequest, slave_0.write, slave_0.writedata); endmodule ================================================ FILE: tests/avalon_mm/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Connectable::*; import FIFO::*; import GetPut::*; import Vector::*; import TestProgram::*; import AvalonBfmWrapper::*; import AvalonMasterSlave::*; import AvalonBits::*; import AvalonDma::*; import AvalonGather::*; import ConnectalMemTypes::*; import MemServerIndication::*; import MMUIndication::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action writeData(Bit#(16) addr, Bit#(64) data); method Action readData(Bit#(16) addr, Bit#(64) data); endinterface interface Echo; interface EchoRequest request; endinterface typedef 12 AddressWidth; typedef 32 DataWidth; typedef TDiv#(DataWidth, 32) WordsPerBeat; module mkEcho#(EchoIndication indication)(Echo); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); // read client interface FIFO#(PhysMemRequest#(AddressWidth, DataWidth)) readReqFifo <- mkSizedFIFO(4); FIFO#(MemData#(DataWidth)) readDataFifo <- mkSizedFIFO(32); PhysMemReadClient#(AddressWidth, DataWidth) readClient = (interface PhysMemReadClient; interface Get readReq = toGet(readReqFifo); interface Put readData = toPut(readDataFifo); endinterface); // write client interface FIFO#(PhysMemRequest#(AddressWidth, DataWidth)) writeReqFifo <- mkSizedFIFO(4); FIFO#(MemData#(DataWidth)) writeDataFifo <- mkSizedFIFO(32); FIFO#(Bit#(MemTagSize)) writeDoneFifo <- mkSizedFIFO(4); PhysMemWriteClient#(AddressWidth, DataWidth) writeClient = (interface PhysMemWriteClient; interface Get writeReq = toGet(writeReqFifo); interface Get writeData = toGet(writeDataFifo); interface Put writeDone = toPut(writeDoneFifo); endinterface); // PhysMemMaster interface PhysMemMaster#(AddressWidth, DataWidth) memMaster = (interface PhysMemMaster; interface read_client = readClient; interface write_client = writeClient; endinterface); Empty test_program <- mkTestProgram(); AvalonBfmWrapper#(AddressWidth, DataWidth) dut <- mkAvalonBfmWrapper(); AvalonMSlave#(AddressWidth, DataWidth) slaveGather <- mkAvalonMSlaveGather(dut.slave_0); AvalonMMaster#(AddressWidth, DataWidth) master <- mkAvalonDmaMaster(memMaster); mkConnection(master, slaveGather); interface EchoRequest request; method Action writeData(Bit#(16) addr, Bit#(64) data); writeReqFifo.enq(PhysMemRequest{ addr: truncate(addr), burstLen: 4, tag: 0}); function Bit#(8) plusi(Integer i); return fromInteger(i); endfunction Vector#(TMul#(4, WordsPerBeat), Bit#(8)) v = genWith(plusi); writeDataFifo.enq(MemData {data: pack(v), tag: 0, last: True}); endmethod method Action readData(Bit#(16) addr, Bit#(64) data); readReqFifo.enq(PhysMemRequest{addr: truncate(addr), burstLen: 16, tag: 0}); endmethod endinterface endmodule ================================================ FILE: tests/avalon_mm/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv CPPFILES= testecho.cpp CONNECTALFLAGS += --verilog verilog CONNECTALFLAGS += --systemverilog $(IPDIR)/$(BOARD)/synthesis/avlm_avls_1x1 prebuild:: cd $(BOARD); BUILDCACHE_CACHEDIR=$(BUILDCACHE_CACHEDIR) $(BUILDCACHE) ip-generate \ --project-directory=$(IPDIR)/$(BOARD) \ --output-directory=$(IPDIR)/$(BOARD)/synthesis/avlm_avls_1x1 \ --report-file=spd \ --file-set=SIM_VERILOG \ ../avlm_avls_1x1.qsys; \ BUILDCACHE_CACHEDIR=$(BUILDCACHE_CACHEDIR) $(BUILDCACHE) ip-make-simscript \ --spd=$(IPDIR)/$(BOARD)/synthesis/avlm_avls_1x1/avlm_avls_1x1.spd \ --compile-to-work \ --output-directory=$(IPDIR)/$(BOARD)/synthesis/avlm_avls_1x1; include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/avalon_mm/Readme.md ================================================ ### Tests for Avalon memory-mapped protocol Avalon memory-mapped interface is used by Altera device for access memories, such as DDR3 controller. This test is related to the following files in connectal/bsv directory, modelled after Axi protocol: * AvalonBit.bsv : Raw Avalon-MM interface bits * AvalonGather.bsv : Converting raw bits to Get/Put interface. * AvalonMasterSlave.bsv : Definition for AvalonMMaster and AvalonMSlave interface * AvalonSplitter.bsv : Avalon has a shared bus for both read and write operation, this module is an arbiter to enable sharing, modelled after Pcie arbiter. * AvalonDma.bsv : Converting PhysMemRequest to AvalonMMRequest AvalonMM messages are verified using Altera's BFM verification IP, hence this test will only run in modelsim. You can run tests with the following commands. ``` make build.vsim make run.vsim ``` Project structure: * avlm_avls_1x1.qsys : Qsys project to instantiate a single Avalon-MM slave, taken from avalon verification ip simulation example. * AvalonBfmWrapper.bsv : Bluespec wrapper for generated avlm_avls_1x1.v * verilog/test_program.sv : Test case written in system verilog to handle AvalonMM requests in BFM model. Currently only handle slave. * TestProgram.bsv : Bluespec wrapper for test_program.sv * Echo.bsv, testecho.cpp : Top-level connectal project files. ================================================ FILE: tests/avalon_mm/TestProgram.bsv ================================================ import Clocks::*; import DefaultValue::*; import "BVI" test_program = module mkTestProgram(Empty); default_clock clk(); default_reset rst(); endmodule ================================================ FILE: tests/avalon_mm/avlm_avls_1x1.qsys ================================================ ================================================ FILE: tests/avalon_mm/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->writeData(0x100, 0xdeadbeef); echoRequestProxy->readData(0x140, 0xdeadbeef); } int main(int argc, const char **argv) { EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int v = 42; printf("Saying %d\n", v); call_say(v); sleep(1); printf("TEST TYPE: SEM\n"); return 0; } ================================================ FILE: tests/avalon_mm/verilog/tb.sv ================================================ `timescale 1ps / 1ps module tb (); reg clk = 1'b0; reg reset = 1'b1; localparam CLOCK_PERIOD = 100; // Clock period in ps localparam INITIAL_RESET_CYCLES = 10; // Number of cycles to reset when simulation starts avlm_avls_1x1 dut( .clk_clk(clk), .reset_reset_n(~reset) ); test_program tp(); // Clock signal generator always begin #(CLOCK_PERIOD / 2); clk = ~clk; end // Initial reset initial begin repeat(INITIAL_RESET_CYCLES) @(posedge clk); reset = 1'b0; end endmodule ================================================ FILE: tests/avalon_mm/verilog/test_program.v ================================================ //--------------------------------------------------- // Macro definition //--------------------------------------------------- `define NUM_MASTERS 1 `define NUM_SLAVES 1 `define TB $root.xsimtop.xsimtop.top.lEcho_dut `define MASTER0 $root.xsimtop.xsimtop.top.lEcho_dut.master_0 `define SLAVE0 $root.xsimtop.xsimtop.top.lEcho_dut.slave_0 module test_program (); import verbosity_pkg::*; import avalon_mm_pkg::*; //--------------------------------------------------- // Constants //--------------------------------------------------- localparam ADDR_W = 12; localparam SYMBOL_W = 8; localparam NUM_SYMBOLS = 4; localparam DATA_W = NUM_SYMBOLS * SYMBOL_W; localparam BURST_W = 4; localparam MAX_BURST = 8; localparam SLAVE_SPAN = 32'h1000; localparam MAX_COMMAND_IDLE = 5; localparam MAX_COMMAND_BACKPRESSURE = 2; localparam MAX_DATA_IDLE = 3; //--------------------------------------------------- // Data structures //--------------------------------------------------- typedef logic [BURST_W-1:0] Burstcount; typedef enum bit { WRITE = 0, READ = 1 } Transaction; typedef enum bit { NOBURST = 0, BURST = 1 } Burstmode; typedef struct { Transaction trans; Burstcount burstcount; logic [ADDR_W-1: 0] addr; logic [DATA_W-1:0] data [MAX_BURST-1:0]; logic [NUM_SYMBOLS-1:0] byteenable [MAX_BURST-1:0]; bit [31:0] cmd_delay; bit [31:0] data_idles [MAX_BURST-1:0]; } Command; typedef struct { Burstcount burstcount; logic [DATA_W-1:0] data [MAX_BURST-1:0]; bit [31:0] latency [MAX_BURST-1:0]; } Response; //--------------------------------------------------- // Command and Response Queues //--------------------------------------------------- // master command queue Command write_command_queue_master[`NUM_MASTERS][$]; Command read_command_queue_master[`NUM_MASTERS][$]; // slave command queue Command write_command_queue_slave[`NUM_SLAVES][$]; Command read_command_queue_slave[`NUM_SLAVES][$]; // slave response queue Response read_response_queue_slave[`NUM_SLAVES][$]; //--------------------------------------------------- // Macro Definitions //--------------------------------------------------- `define MACRO_CONFIGURE_AND_PUSH_COMMAND_TO_MASTER(MASTER_ID) \ task automatic configure_and_push_command_to_master_``MASTER_ID ( \ Command cmd \ ); \ `MASTER``MASTER_ID.set_command_address(cmd.addr); \ `MASTER``MASTER_ID.set_command_burst_count(cmd.burstcount); \ `MASTER``MASTER_ID.set_command_burst_size(cmd.burstcount); \ `MASTER``MASTER_ID.set_command_init_latency(cmd.cmd_delay); \ \ if (cmd.trans == WRITE) begin \ `MASTER``MASTER_ID.set_command_request(REQ_WRITE); \ for (int i = 0; i < cmd.burstcount; i++) begin \ `MASTER``MASTER_ID.set_command_data(cmd.data[i], i); \ `MASTER``MASTER_ID.set_command_byte_enable(cmd.byteenable[i], i); \ `MASTER``MASTER_ID.set_command_idle(cmd.data_idles[i], i); \ end \ end else begin \ `MASTER``MASTER_ID.set_command_request(REQ_READ); \ `MASTER``MASTER_ID.set_command_idle(cmd.data_idles[0], 0); \ end \ \ `MASTER``MASTER_ID.push_command(); \ endtask // Get command received by slave, verify command. // If command is read command, send out response `define MACRO_SLAVE_THREAD(SLAVE_ID) \ always @(`SLAVE``SLAVE_ID.signal_command_received) begin \ \ Command actual_cmd, exp_cmd; \ Response rsp; \ string msg; \ \ automatic int backpressure_cycles; \ \ // set random backpressure cycles for next command \ for (int i = 0; i < MAX_BURST; i++) begin \ backpressure_cycles = $urandom_range(0, MAX_COMMAND_BACKPRESSURE); \ `SLAVE``SLAVE_ID.set_interface_wait_time(backpressure_cycles, i); \ end \ \ actual_cmd = get_command_from_slave_``SLAVE_ID(); \ \ // set read response \ if (actual_cmd.trans == READ) begin \ $sformat(msg, "read command %x %x", actual_cmd.burstcount, actual_cmd.addr); \ print(VERBOSITY_INFO, msg); \ rsp = create_response(actual_cmd.burstcount); \ configure_and_push_response_to_slave_``SLAVE_ID(rsp); \ read_response_queue_slave[``SLAVE_ID].push_back(rsp); \ end \ end `define MACRO_GET_COMMAND_FROM_SLAVE(SLAVE_ID) \ function automatic Command get_command_from_slave_``SLAVE_ID (); \ \ Command cmd; \ \ `SLAVE``SLAVE_ID.pop_command(); \ cmd.burstcount = `SLAVE``SLAVE_ID.get_command_burst_count(); \ cmd.addr = `SLAVE``SLAVE_ID.get_command_address(); \ \ if (`SLAVE``SLAVE_ID.get_command_request() == REQ_WRITE) begin \ cmd.trans = WRITE; \ for(int i = 0; i < cmd.burstcount; i++) begin \ cmd.data[i] =`SLAVE``SLAVE_ID.get_command_data(i); \ cmd.byteenable[i] =`SLAVE``SLAVE_ID.get_command_byte_enable(i); \ end \ end else begin \ cmd.trans = READ; \ end \ \ return cmd; \ endfunction `define MACRO_PENDING_READ_CYCLES(SLAVE_ID) \ int pending_read_cycles_slave_``SLAVE_ID = 0; \ always @(posedge `TB.clk_clk) begin \ if (pending_read_cycles_slave_``SLAVE_ID > 0) begin \ pending_read_cycles_slave_``SLAVE_ID--; \ end \ end `define MACRO_CONFIGURE_AND_PUSH_RESPONSE_TO_SLAVE(SLAVE_ID) \ task automatic configure_and_push_response_to_slave_``SLAVE_ID ( \ Response rsp \ ); \ \ int read_response_latency; \ \ `SLAVE``SLAVE_ID.set_response_request(REQ_READ); \ `SLAVE``SLAVE_ID.set_response_burst_size(rsp.burstcount); \ for (int i = 0; i < rsp.burstcount; i++) begin \ `SLAVE``SLAVE_ID.set_response_data(rsp.data[i], i); \ \ if (i == 0) begin \ `SLAVE``SLAVE_ID.set_response_latency(rsp.latency[i] + pending_read_cycles_slave_``SLAVE_ID, i); \ read_response_latency = rsp.latency[i]; \ end else begin \ `SLAVE``SLAVE_ID.set_response_latency(rsp.latency[i], i); \ read_response_latency = rsp.latency[i] + read_response_latency; \ end \ \ end \ `SLAVE``SLAVE_ID.push_response(); \ pending_read_cycles_slave_``SLAVE_ID = pending_read_cycles_slave_``SLAVE_ID + read_response_latency + rsp.burstcount + 2; \ endtask `define MACRO_MASTER_RESPONSE_THREAD(MASTER_ID) \ // Get read response received by master and verify read response \ always @(`MASTER``MASTER_ID.signal_read_response_complete) begin \ \ Command cmd; \ Response actual_rsp, exp_rsp; \ \ cmd = read_command_queue_master[``MASTER_ID].pop_front(); \ actual_rsp = get_read_response_from_master_``MASTER_ID(); \ exp_rsp = get_expected_read_response(cmd); \ verify_response(actual_rsp, exp_rsp); \ end \ \ // Flush out response for write command created by master bfm \ always @(`MASTER``MASTER_ID.signal_write_response_complete) begin \ `MASTER``MASTER_ID.pop_response(); \ end `define MACRO_GET_READ_RESPONSE_FROM_MASTER(MASTER_ID) \ function automatic Response get_read_response_from_master_``MASTER_ID (); \ \ Response rsp; \ \ `MASTER``MASTER_ID.pop_response(); \ rsp.burstcount = `MASTER``MASTER_ID.get_response_burst_size(); \ for (int i = 0; i < rsp.burstcount; i++) begin \ rsp.data[i] = `MASTER``MASTER_ID.get_response_data(i); \ end \ \ return rsp; \ endfunction //--------------------------------------------------- // Macro Instantiations //--------------------------------------------------- // master 0 //`MACRO_CONFIGURE_AND_PUSH_COMMAND_TO_MASTER(0) //`MACRO_MASTER_RESPONSE_THREAD(0) //`MACRO_GET_READ_RESPONSE_FROM_MASTER(0) // slave 0 `MACRO_SLAVE_THREAD(0) `MACRO_GET_COMMAND_FROM_SLAVE(0) `MACRO_PENDING_READ_CYCLES(0) `MACRO_CONFIGURE_AND_PUSH_RESPONSE_TO_SLAVE(0) //--------------------------------------------------- // Test status checking //--------------------------------------------------- bit test_success = 1; //--------------------------------------------------- // Events //--------------------------------------------------- event assert_fail; //--------------------------------------------------- // Test program //--------------------------------------------------- // master test program initial begin set_verbosity(VERBOSITY_INFO); $display("Starting master test program"); wait (`TB.reset_reset_n == 1); //$display("Master sending out non bursting write commands"); //master_send_commands(10, WRITE, NOBURST); // //$display("Master sending out non bursting read commands"); //master_send_commands(10, READ, NOBURST); // //$display("Master sending out burst write commands"); //master_send_commands(10, WRITE, BURST); // //$display("Master sending out burst read commands"); //master_send_commands(10, READ, BURST); // //$display("Master has sent out all commands"); end task automatic master_send_commands ( int num_command, Transaction trans, Burstmode burstmode ); Command cmd; Response rsp, exp_rsp; int master_id, slave_id; master_id = 0; slave_id = 0; for (int i = 0; i < num_command; i++) begin cmd = create_command ( .trans(trans), .burstmode(burstmode), .slave_id(slave_id) ); queue_command(cmd, master_id, slave_id); end endtask function automatic Command create_command ( Transaction trans, Burstmode burstmode, int slave_id ); Command cmd; if (burstmode == BURST) begin cmd.burstcount = randomize_burstcount(); end else begin cmd.burstcount = 1; end cmd.trans = trans; cmd.addr = generate_random_aligned_address(slave_id); cmd.cmd_delay = $urandom_range(0, MAX_COMMAND_IDLE); if (trans == WRITE) begin for (int i = 0; i < cmd.burstcount; i++) begin cmd.data[i] = $random; cmd.byteenable[i] = {NUM_SYMBOLS{1'b1}}; cmd.data_idles[i] = $urandom_range(0, MAX_DATA_IDLE); end end else begin cmd.data_idles[0] = $urandom_range(0, MAX_DATA_IDLE); end return cmd; endfunction function automatic Burstcount randomize_burstcount (); Burstcount burstcount; burstcount = $urandom_range(1, MAX_BURST); return burstcount; endfunction function automatic logic [ADDR_W-1: 0] generate_random_aligned_address ( int slave_id ); logic [ADDR_W-1:0] base_addr, addr; base_addr = slave_id * SLAVE_SPAN; addr = base_addr + ($random % SLAVE_SPAN); return (addr / NUM_SYMBOLS) * NUM_SYMBOLS; endfunction task automatic queue_command ( Command cmd, int master_id, int slave_id ); //save_command_master(cmd, master_id); save_command_slave(cmd, slave_id); //configure_and_push_command_to_master(cmd, master_id); endtask // task automatic save_command_master( // Command cmd, // int master_id // ); // // if (cmd.trans == WRITE) begin // write_command_queue_master[master_id].push_back(cmd); // end else begin // read_command_queue_master[master_id].push_back(cmd); // end // // endtask task automatic save_command_slave( Command cmd, int slave_id ); if (cmd.trans == WRITE) begin write_command_queue_slave[slave_id].push_back(cmd); end else begin read_command_queue_slave[slave_id].push_back(cmd); end endtask // task automatic configure_and_push_command_to_master ( // Command cmd, // int master_id // ); // if (master_id == 0) begin // configure_and_push_command_to_master_0(cmd); // end // // endtask function automatic Command get_expected_command_for_slave ( Command cmd, int slave_id ); Command exp_cmd; int found = 0; if (cmd.trans == WRITE) begin foreach (write_command_queue_slave[slave_id, i]) begin exp_cmd = write_command_queue_slave[slave_id][i]; if (exp_cmd.addr == cmd.addr) begin write_command_queue_slave[slave_id].delete(i); found = 1; break; end end if (found == 0) begin exp_cmd = write_command_queue_slave[slave_id].pop_front(); end end else begin foreach (read_command_queue_slave[slave_id, i]) begin exp_cmd = read_command_queue_slave[slave_id][i]; if (exp_cmd.addr == cmd.addr) begin read_command_queue_slave[slave_id].delete(i); found = 1; break; end end if (found == 0) begin exp_cmd = read_command_queue_slave[slave_id].pop_front(); end end return exp_cmd; endfunction task automatic verify_command ( Command actual_cmd, exp_cmd ); assert_equals("wrong address", exp_cmd.addr, actual_cmd.addr); assert_equals("wrong burstcount", exp_cmd.burstcount, actual_cmd.burstcount); if (actual_cmd.trans == WRITE) begin for (int i = 0; i < actual_cmd.burstcount; i++) begin assert_equals("wrong write data", exp_cmd.data[i], actual_cmd.data[i]); assert_equals("wrong byteenable", exp_cmd.byteenable[i], actual_cmd.byteenable[i]); end end endtask task automatic assert_equals( string message, logic [1023:0] expected_obj, logic [1023:0] actual_obj ); string data_comparison_msg; begin if (actual_obj == expected_obj) begin // Success case. Code it this way because in Verilog, // 1) "!=" and "==" give 'x' if either operand contains 'x' or 'z' // 2) 'x' evaluated as a boolean is false end else begin $sformat(data_comparison_msg, "%s, expected %0x got %0x", message, expected_obj, actual_obj); print(VERBOSITY_ERROR, data_comparison_msg); test_success = 0; -> assert_fail; end end endtask function automatic Response create_response ( Burstcount burstcount ); Response rsp; rsp.burstcount = burstcount; for (int i = 0;i < burstcount; i++) begin rsp.data[i] = $random; rsp.latency[i] = $urandom_range(0, MAX_DATA_IDLE); end return rsp; endfunction function automatic Response get_expected_read_response ( Command cmd ); Response rsp; int slave_id = cmd.addr / SLAVE_SPAN; rsp = read_response_queue_slave[slave_id].pop_front(); return rsp; endfunction task automatic verify_response ( Response actual_rsp, exp_rsp ); assert_equals("wrong burstcount", exp_rsp.burstcount, actual_rsp.burstcount); for (int i = 0; i < actual_rsp.burstcount; i++) begin assert_equals("wrong read data", exp_rsp.data[i], actual_rsp.data[i]); end endtask endmodule ================================================ FILE: tests/axieth/AxiEth.bsv ================================================ import BuildVector::*; import Connectable::*; import GetPut::*; import FIFOF::*; import BRAM::*; import Probe::*; import StmtFSM::*; import TriState::*; import Vector::*; import ConnectalXilinxCells::*; import ConnectalConfig::*; import CtrlMux::*; import HostInterface::*; import ConnectalMemTypes::*; import AxiBits::*; import AxiIntcBvi::*; import AxiEthBvi::*; import AxiDmaBvi::*; import EthPins::*; interface AxiEthTestRequest; method Action reset(); method Action setupDma(Bit#(32) memref); method Action status(); method Action read(Bit#(32) addr); method Action write(Bit#(32) addr, Bit#(32) value); endinterface interface AxiEthTestIndication; method Action irqChanged(Bit#(1) newIrq, Bit#(4) intrSources); method Action readDone(Bit#(32) value); method Action writeDone(); method Action resetDone(); method Action status(Bit#(1) mmcm_locked, Bit#(1) irq, Bit#(4) intrSources); endinterface interface AxiEth; interface AxiEthTestRequest request; interface Vector#(2, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(2, MemWriteClient#(DataBusWidth)) dmaWriteClient; interface AxiEthPins pins; endinterface module mkAxiEth#(HostInterface host, AxiEthTestIndication ind)(AxiEth); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); let axiIntcBvi <- mkAxiIntcBvi(clock, reset); let axiDmaBvi <- mkAxiDmaBvi(clock,clock,clock,clock,reset); let axiEthBvi <- mkAxiEthBvi(host.tsys_clk_200mhz_buf, clock, reset, clock, reset, reset, reset, reset); Reg#(Bit#(32)) objId <- mkReg(0); let irqLevel <- mkReg(0); let intrLevel <- mkReg(0); Bit#(4) intr = { axiDmaBvi.s2mm.introut(), axiDmaBvi.mm2s.introut(), axiEthBvi.mac.irq(), axiEthBvi.interrupt() }; rule rl_intr; axiIntcBvi.intr(intr); endrule rule rl_intr_indication; let irq = axiIntcBvi.irq; irqLevel <= irq; intrLevel <= intr; if (irq != irqLevel || intr != intrLevel) begin ind.irqChanged(irq, intr); $display("irq changed irq=%h intr sources %h", irq, intr); end endrule Reg#(Bit#(32)) cycles <- mkReg(0); Reg#(Bool) mmcm_lock <- mkReg(False); rule rl_cycles; cycles <= cycles+1; endrule rule rl_mmcm_lock if (!mmcm_lock); if (axiEthBvi.mmcm.locked_out() == 1) begin mmcm_lock <= True; $display("%d mmcm locked", cycles); end endrule FIFOF#(BRAMRequest#(Bit#(32),Bit#(32))) reqFifo <- mkFIFOF(); FIFOF#(Bit#(32)) dataFifo <- mkFIFOF(); // packet data and status from the ethernet mkConnection(axiEthBvi.m_axis_rxd, axiDmaBvi.s_axis_s2mm); mkConnection(axiEthBvi.m_axis_rxs, axiDmaBvi.s_axis_s2mm_sts); // packet data and control to the ethernet mkConnection(axiDmaBvi.m_axis_mm2s, axiEthBvi.s_axis_txd); mkConnection(axiDmaBvi.m_axis_mm2s_cntrl, axiEthBvi.s_axis_txc); Axi4MasterBits#(32,32,MemTagSize,Empty) m_axi_mm2s = toAxi4MasterBits(axiDmaBvi.m_axi_mm2s); Axi4MasterBits#(32,32,MemTagSize,Empty) m_axi_s2mm = toAxi4MasterBits(axiDmaBvi.m_axi_s2mm); Axi4MasterBits#(32,32,MemTagSize,Empty) m_axi_sg = toAxi4MasterBits(axiDmaBvi.m_axi_sg); Axi4SlaveLiteBits#(9,32) axiIntcSlaveLite = toAxi4SlaveBits(axiIntcBvi.s_axi); PhysMemSlave#(18,32) axiIntcMemSlave <- mkPhysMemSlave(axiIntcSlaveLite); PhysMemSlave#(18,32) axiDmaMemSlave <- mkPhysMemSlave(axiDmaBvi.s_axi_lite); Axi4SlaveLiteBits#(18,32) axiEthSlaveLite = toAxi4SlaveBits(axiEthBvi.s_axi); PhysMemSlave#(18,32) axiEthMemSlave <- mkPhysMemSlave(axiEthSlaveLite); PhysMemSlave#(20,32) memSlaveMux <- mkPhysMemSlaveMux(vec(axiIntcMemSlave, axiDmaMemSlave, axiEthMemSlave)); FIFOF#(Bit#(32)) dfifo <- mkFIFOF(); rule rl_axieth; axiEthBvi.signal.detect(1); // drive to 1 if not using optical transceiver, else use signal from transceiver endrule rule rl_rdata; let rdata <- memSlaveMux.read_server.readData.get(); ind.readDone(rdata.data); endrule rule rl_wdata; let wdata <- toGet(dfifo).get(); memSlaveMux.write_server.writeData.put(MemData {data: wdata, tag: 0}); endrule rule rl_writeDone; let tag <- memSlaveMux.write_server.writeDone.get(); ind.writeDone(); endrule interface AxiEthTestRequest request; method Action reset(); endmethod method Action setupDma(Bit#(32) memref); objId <= memref; endmethod method Action read(Bit#(32) addr); memSlaveMux.read_server.readReq.put(PhysMemRequest { addr: truncate(addr), burstLen: 4, tag: 0 }); endmethod method Action write(Bit#(32) addr, Bit#(32) value); memSlaveMux.write_server.writeReq.put(PhysMemRequest { addr: truncate(addr), burstLen: 4, tag: 0 }); dfifo.enq(value); endmethod method Action status(); ind.status(axiEthBvi.mmcm.locked_out(), axiIntcBvi.irq, intr); endmethod endinterface interface AxiEthPins pins; interface EthPins eth; interface AxiethbviMgt mgt = axiEthBvi.mgt; interface AxiethbviMdio sfp = axiEthBvi.sfp; interface Clock deleteme_unused_clock = clock; interface Reset deleteme_unused_reset = reset; endinterface endinterface interface Vector dmaReadClient = map(toMemReadClient(objId), vec(m_axi_mm2s, m_axi_sg)); interface Vector dmaWriteClient = map(toMemWriteClient(objId), vec(m_axi_s2mm, m_axi_sg)); endmodule ================================================ FILE: tests/axieth/EthPins.bsv ================================================ import AxiEthBvi::*; interface EthPins; interface AxiethbviSfp sfp; interface AxiethbviMgt mgt; interface Clock deleteme_unused_clock; interface Reset deleteme_unused_reset; endinterface (* always_ready, always_enabled *) interface AxiEthPins; interface EthPins eth; endinterface ================================================ FILE: tests/axieth/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = AxiEthTestRequest:AxiEth.request H2S_INTERFACES = AxiEth:AxiEthTestIndication:host MEM_READ_INTERFACES = lAxiEth.dmaReadClient MEM_WRITE_INTERFACES = lAxiEth.dmaWriteClient CONNECTALFLAGS+= -P mkConnectalTop CONNECTALFLAGS+= --shared BSVFILES = AxiEth.bsv CPPFILES=testaxieth.cpp CONNECTALFLAGS+= -DDataBusWidth=32 ## ethernet uses the 200MHz SYS clock CONNECTALFLAGS += -D XILINX_SYS_CLK -D IMPORT_HOSTIF CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_intc_0/axi_intc_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_dma_0/axi_dma_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_ethernet_0/axi_ethernet_0.xci CONNECTALFLAGS += --constraint=axieth.xdc --implconstraint=axieth.xdc ifneq ($(BOARD),xsim) PINOUT_FILE += axieth.json endif PIN_TYPE = AxiEthPins PIN_TYPE_INCLUDE = EthPins AUTOTOP = --interface pins:AxiEth.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/axieth/axieth.h ================================================ #ifndef AXIETH_H #define AXIETH_H class AxiEthTestRequestProxy; class AxiEthTestIndication; class DmaManager; class AxiEth { public: AxiEth(); ~AxiEth(); int irq ( const uint8_t newLevel ); void status(); void setupDma( uint32_t memref ); void read(unsigned long offset, uint8_t *buf); void write(unsigned long offset, const uint8_t *buf); private: AxiEthTestRequestProxy *request; AxiEthTestIndication *indication; DmaManager *dmaManager; bool didReset; void maybeReset(); }; #endif ================================================ FILE: tests/axieth/axieth.json ================================================ { "eth_mgt_clk_clk_p_v": { "pins": "si5324_clk_p" }, "eth_mgt_clk_clk_n_v": { "pins": "si5324_clk_n" }, "eth_sfp_rxp_v": { "sfp1": "rxp" }, "eth_sfp_rxn_v": { "sfp1": "rxn" }, "eth_sfp_txp": { "sfp1": "txp" }, "eth_sfp_txn": { "sfp1": "txn" } } ================================================ FILE: tests/axieth/axieth.xdc ================================================ create_clock -name eth_mgt_clk_clk -period 8.000 [get_ports eth_mgt_clk_clk_p_v] ================================================ FILE: tests/axieth/testaxieth.cpp ================================================ #include #include #include "dmaManager.h" #include "axieth.h" int verbose = 1; class AxiEthTestIndication : public AxiEthTestIndicationWrapper { sem_t sem; public: uint32_t buf[16]; void irqChanged( const uint8_t irqLevel, const uint8_t intrSources ) { fprintf(stderr, "irqLevel %d intr sources %x\n", irqLevel, intrSources); } virtual void resetDone() { fprintf(stderr, "reset done\n"); sem_post(&sem); } virtual void status ( const uint8_t mmcm_locked, const uint8_t irq, const uint8_t intrSources ) { fprintf(stderr, "axi eth status mmcm_locked=%d irq=%d intr sources=%x\n", mmcm_locked, irq, intrSources); sem_post(&sem); } void wait() { if (verbose) fprintf(stderr, " waiting ..."); sem_wait(&sem); if (verbose) fprintf(stderr, " done\n"); } void readDone ( const uint32_t value ) { buf[0] = value; if (verbose) fprintf(stderr, "readDone value=%08x\n", value); sem_post(&sem); } void writeDone ( ) { if (verbose) fprintf(stderr, "writeDone\n"); sem_post(&sem); } AxiEthTestIndication(unsigned int id) : AxiEthTestIndicationWrapper(id) { sem_init(&sem, 0, 0); } }; AxiEthTestRequestProxy *request; AxiEthTestIndication *indication; #ifdef STANDALONE int main(int argc, const char **argv) { request = new AxiEthTestRequestProxy(IfcNames_AxiEthTestRequestS2H); indication = new AxiEthTestIndication(IfcNames_AxiEthTestIndicationH2S); fprintf(stderr, "Reading ID register\n"); request->read((1<<18) + 0x4f8); indication->wait(); for (int i = 0; i < 16; i++) { fprintf(stderr, "register %04x\n", i*4); request->read((1<<18) + i*4); indication->wait(); fprintf(stderr, "now writing ...\n"); request->write((1<<18) + i*4, 0xbeef); indication->wait(); request->read((1<<18) + i*4); indication->wait(); } return 0; } #else AxiEth::AxiEth() : request(0), indication(0), dmaManager(0), didReset(false) { request = new AxiEthTestRequestProxy(IfcNames_AxiEthTestRequestS2H); indication = new AxiEthTestIndication(IfcNames_AxiEthTestIndicationH2S); dmaManager = platformInit(); } AxiEth::~AxiEth() { //delete request; //delete indication; request = 0; indication = 0; } void AxiEth::maybeReset() { if (0) if (!didReset) { fprintf(stderr, "resetting flash\n"); request->reset(); indication->wait(); //request->setParameters(50, 0); fprintf(stderr, "done resetting flash\n"); didReset = true; } } void AxiEth::status() { request->status(); indication->wait(); } void AxiEth::setupDma(uint32_t memfd) { int memref = dmaManager->reference(memfd); request->setupDma(memref); } void AxiEth::read(unsigned long offset, uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "AxiEth::read offset=%lx\n", offset); request->read(offset); indication->wait(); if (verbose) fprintf(stderr, "AxiEth::read offset=%lx value=%x\n", offset, *(short *)indication->buf); memcpy(buf, indication->buf, 4); } void AxiEth::write(unsigned long offset, const uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "AxiEth::write offset=%lx value=%x\n", offset, *(short *)buf); request->write(offset, *(uint32_t *)buf); indication->wait(); request->status(); indication->wait(); } #endif ================================================ FILE: tests/axieth/xsim_export.tcl ================================================ set partname {xc7vx690tffg1761-2} create_project -in_memory -name fooproject set_property PART $partname [current_project] read_ip /home/jamey/connectal/out/vc709/axi_ethernet_0/axi_ethernet_0.xci generate_target simulation [get_ips axi_ethernet_0] read_ip /home/jamey/connectal/out/vc709/axi_dma_0/axi_dma_0.xci generate_target simulation [get_ips axi_dma_0] read_ip /home/jamey/connectal/out/vc709/axi_intc_0/axi_intc_0.xci generate_target simulation [get_ips axi_intc_0] #puts [get_files -compile_order sources -used_in simulation -of_objects [get_ips axi_ethernet_0]] add_files [glob /home/jamey/connectal/verilog/*.sv] add_files [glob xsim/verilog/*.v] add_files [glob /home/jamey/connectal/verilog/*.v] add_files [glob /scratch/bluespec/Bluespec-2015.09.beta2/lib/Verilog.Vivado/*.v] add_files [glob /scratch/bluespec/Bluespec-2015.09.beta2/lib/Verilog/FIFO1.v] add_files [glob /scratch/bluespec/Bluespec-2015.09.beta2/lib/Verilog/FIFO2.v] add_files [get_files -compile_order sources -used_in simulation -of_objects [get_ips axi_ethernet_0]] add_files [get_files -compile_order sources -used_in simulation -of_objects [get_ips axi_dma_0]] add_files [get_files -compile_order sources -used_in simulation -of_objects [get_ips axi_intc_0]] set_property TOP xsimtop [get_filesets sim_1] export_simulation -simulator xsim ================================================ FILE: tests/bluecheck-bram/Bram2Example.bsv ================================================ /* * Copyright 2015 Matthew Naylor * All rights reserved. * * This software was developed by SRI International and the University of * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 * ("CTSRD"), as part of the DARPA CRASH research programme. * * This software was developed by SRI International and the University of * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 * ("MRC2"), as part of the DARPA MRC research programme. * * This software was developed by the University of Cambridge Computer * Laboratory as part of the Rigorous Engineering of Mainstream * Systems (REMS) project, funded by EPSRC grant EP/K008528/1. * * @BERI_LICENSE_HEADER_START@ * * Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. BERI licenses this * file to you under the BERI Hardware-Software License, Version 1.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at: * * http://www.beri-open-systems.org/legal/license-1-0.txt * * Unless required by applicable law or agreed to in writing, Work distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * * @BERI_LICENSE_HEADER_END@ */ import Vector :: *; import BRAMCore :: *; import BlueCheck :: *; import FShow :: *; import StmtFSM :: *; import Clocks :: *; import RegFile :: *; import GetPut :: *; import BRAM :: *; import FIFO :: *; import DefaultValue::*; import ConnectalBram::*; /////////////// // Interface // /////////////// ////////////////// // Specfication // ////////////////// /* Make a stack with space for 2^n elements of type a */ module mkBramSpec (BRAM2Port#(addr, data)) provisos(Bits#(addr, asz), Bits#(data, dsz), Bounded#(addr)); RegFile#(addr, data) regFile <- mkRegFileFull(); Vector#(2,FIFO#(BRAMRequest#(addr,data))) reqFifo <- replicateM(mkFIFO()); Vector#(2, FIFO#(data)) responseFifo <- replicateM(mkFIFO()); for (Integer i = 0; i < 2; i = i + 1) rule process; let req <- toGet(reqFifo[i]).get(); if (req.write) begin //$display("mkBramSpec: write address=%h data=%h", req.address, req.datain); regFile.upd(req.address, req.datain); if (req.responseOnWrite) responseFifo[i].enq(req.datain); end else begin let d = regFile.sub(req.address); //$display("mkBramSpec: read address=%h data=%h", req.address, d); responseFifo[i].enq(d); end endrule interface Server portA; interface Put request = toPut(reqFifo[0]); interface Get response = toGet(responseFifo[0]); endinterface interface Server portB; interface Put request = toPut(reqFifo[1]); interface Get response = toGet(responseFifo[1]); endinterface endmodule //////////////////// // Implementation // //////////////////// module mkBramStd(BRAM2Port#(addr,data)) provisos(Bits#(addr, asz), Bits#(data, dsz)); let cfg = defaultValue; cfg.latency = 2; let bram <- mkBRAM2Server(cfg); return bram; endmodule module mkBramImpl(BRAM2Port#(addr,data)) provisos(Bits#(addr, asz), Bits#(data, dsz)); let cfg = defaultValue; cfg.latency = 2; let bram <- ConnectalBram::mkBRAM2Server(cfg); return bram; endmodule ///////////////////////// // Equivalence testing // ///////////////////////// instance FShow#(BRAMRequest#(a, d)) provisos (FShow#(a), FShow#(d), Bits#(a, asz), Bits#(d, dsz)); function Fmt fshow(BRAMRequest#(a, d) req); return $format(""); endfunction endinstance module [BlueCheck] checkBram (); /* Specification instance */ BRAM2Port#(Bit#(2),Bit#(8)) spec <- mkBramStd(); /* Implmentation instance */ BRAM2Port#(Bit#(2),Bit#(8)) imp <- mkBramImpl(); Ensure ensure <- getEnsure; equivf(4, "reqA" , spec.portA.request.put , imp.portA.request.put); equivf(2, "respA" , spec.portA.response.get , imp.portA.response.get); equivf(4, "reqB" , spec.portB.request.put , imp.portB.request.put); equivf(2, "respB" , spec.portB.response.get , imp.portB.response.get); // prop("prop1" , prop1); // deadlocks parallel(list("reqA", "reqB")); endmodule module [Module] testBram (); blueCheck(checkBram); endmodule module [Module] testBramID (); Clock clk <- exposeCurrentClock; MakeResetIfc r <- mkReset(0, True, clk); blueCheckID(checkBram(reset_by r.new_rst), r); endmodule ================================================ FILE: tests/bluecheck-bram/BramExample.bsv ================================================ /* * Copyright 2015 Matthew Naylor * All rights reserved. * * This software was developed by SRI International and the University of * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 * ("CTSRD"), as part of the DARPA CRASH research programme. * * This software was developed by SRI International and the University of * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 * ("MRC2"), as part of the DARPA MRC research programme. * * This software was developed by the University of Cambridge Computer * Laboratory as part of the Rigorous Engineering of Mainstream * Systems (REMS) project, funded by EPSRC grant EP/K008528/1. * * @BERI_LICENSE_HEADER_START@ * * Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. BERI licenses this * file to you under the BERI Hardware-Software License, Version 1.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at: * * http://www.beri-open-systems.org/legal/license-1-0.txt * * Unless required by applicable law or agreed to in writing, Work distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * * @BERI_LICENSE_HEADER_END@ */ import Vector :: *; import BRAMCore :: *; import BlueCheck :: *; import FShow :: *; import StmtFSM :: *; import Clocks :: *; import RegFile :: *; import GetPut :: *; import BRAM :: *; import FIFO :: *; import DefaultValue::*; import ConnectalBram::*; /////////////// // Interface // /////////////// ////////////////// // Specfication // ////////////////// /* Make a stack with space for 2^n elements of type a */ module mkBramSpec (BRAMServer#(addr, data)) provisos(Bits#(addr, asz), Bits#(data, dsz), Bounded#(addr)); RegFile#(addr, data) regFile <- mkRegFileFull(); FIFO#(BRAMRequest#(addr,data)) reqFifo <- mkFIFO(); FIFO#(data) responseFifo <- mkFIFO(); rule process; let req <- toGet(reqFifo).get(); if (req.write) begin //$display("mkBramSpec: write address=%h data=%h", req.address, req.datain); regFile.upd(req.address, req.datain); if (req.responseOnWrite) responseFifo.enq(req.datain); end else begin let d = regFile.sub(req.address); //$display("mkBramSpec: read address=%h data=%h", req.address, d); responseFifo.enq(d); end endrule interface Put request = toPut(reqFifo); interface Get response = toGet(responseFifo); endmodule //////////////////// // Implementation // //////////////////// module mkBramImpl(BRAMServer#(addr,data)) provisos(Bits#(addr, asz), Bits#(data, dsz)); let cfg = defaultValue; cfg.latency = 2; let bram <- ConnectalBram::mkBRAM2Server(cfg); interface request = bram.portA.request; interface response = bram.portA.response; endmodule ///////////////////////// // Equivalence testing // ///////////////////////// instance FShow#(BRAMRequest#(a, d)) provisos (FShow#(a), FShow#(d), Bits#(a, asz), Bits#(d, dsz)); function Fmt fshow(BRAMRequest#(a, d) req); return $format(""); endfunction endinstance module [BlueCheck] checkBram (); /* Specification instance */ BRAMServer#(Bit#(2),Bit#(8)) spec <- mkBramSpec(); /* Implmentation instance */ BRAMServer#(Bit#(2),Bit#(8)) imp <- mkBramImpl(); Ensure ensure <- getEnsure; function Stmt prop1(BRAMRequest#(Bit#(2),Bit#(8)) req); return seq spec.request.put(req); imp.request.put(req); if (!req.write || req.responseOnWrite) action let vspec <- spec.response.get(); let vimp <- imp.response.get(); ensure(vspec == vimp); endaction endseq; endfunction equiv("req" , spec.request.put , imp.request.put); equiv("resp" , spec.response.get , imp.response.get); // prop("prop1" , prop1); // deadlocks parallel(list("req", "resp")); endmodule module [Module] testBram (); blueCheck(checkBram); endmodule module [Module] testBramID (); Clock clk <- exposeCurrentClock; MakeResetIfc r <- mkReset(0, True, clk); blueCheckID(checkBram(reset_by r.new_rst), r); endmodule ================================================ FILE: tests/bluecheck-bram/make.sh ================================================ #!/bin/bash # # Copyright (c) 2015 Matthew Naylor # All rights reserved. # # This software was developed by SRI International and the University of # Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 # ("CTSRD"), as part of the DARPA CRASH research programme. # # This software was developed by SRI International and the University of # Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 # ("MRC2"), as part of the DARPA MRC research programme. # # This software was developed by the University of Cambridge Computer # Laboratory as part of the Rigorous Engineering of Mainstream # Systems (REMS) project, funded by EPSRC grant EP/K008528/1. # # @BERI_LICENSE_HEADER_START@ # # Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor # license agreements. See the NOTICE file distributed with this work for # additional information regarding copyright ownership. BERI licenses this # file to you under the BERI Hardware-Software License, Version 1.0 (the # "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at: # # http://www.beri-open-systems.org/legal/license-1-0.txt # # Unless required by applicable law or agreed to in writing, Work distributed # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # # @BERI_LICENSE_HEADER_END@ # BSC="bsc" BSCFLAGS="-keep-fires -cross-info -aggressive-conditions \ -wait-for-license -suppress-warnings G0043 \ -steps-warn-interval 300000 \ -simdir bluesim -bdir bluesim -info-dir bluesim \ -p +:../../../bluecheck:../../bsv:../../lib/bsv" SUFFIXES= # UI # == echo "(11) BRAM" echo "(12) BRAM2Port" #read OPTION OPTION=12 case "$OPTION" in 11) TOPFILE=BramExample.bsv TOPMOD=testBram ;; 12) TOPFILE=Bram2Example.bsv TOPMOD=testBram ;; *) echo "Option not recognised" exit ;; esac # Build it # ======== mkdir -p bluesim echo Compiling $TOPMOD in file $TOPFILE if [ "$SYNTH" = "1" ] then bsc -suppress-warnings G0043 -u -verilog -g $TOPMOD $TOPFILE else if $BSC $BSCFLAGS -sim -g $TOPMOD -u $TOPFILE then if $BSC $BSCFLAGS -sim -o $TOPMOD -e $TOPMOD bluesim/$TOPMOD.ba then ./$TOPMOD else echo Failed to generate executable simulation model fi else echo Failed to compile fi fi ================================================ FILE: tests/bluecheck-sharedmemfifo/ConnectalProjectConfig.bsv ================================================ `define ConnectalVersion 15.10.3 `define NumberOfMasters 1 `define PinType Empty `define PinTypeInclude Misc `define NumberOfUserTiles 1 `define SlaveDataBusWidth 32 `define SlaveControlAddrWidth 5 `define BurstLenSize 8 `define project_dir $(DTOP) `define MainClockPeriod 20 `define DerivedClockPeriod 10.000000 `define BsimHostInterface `define PhysAddrWidth 40 `define SIMULATION `define BOARD_bluesim ================================================ FILE: tests/bluecheck-sharedmemfifo/SharedMemoryFifoCheck.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector :: *; import BRAMCore :: *; import BlueCheck :: *; import FShow :: *; import StmtFSM :: *; import Clocks :: *; import GetPut :: *; import FIFO :: *; import RegFile :: *; import DefaultValue::*; import Pipe :: *; import SharedMemoryFifo::*; import ConnectalMemTypes :: *; import Portal :: *; import MemReadEngine :: *; import MemWriteEngine :: *; //////////////////// // Implementation // //////////////////// interface RegFileMemory; method Action write(Bit#(10) addr, Bit#(64) data); method Bit#(64) read(Bit#(10) addr); endinterface module mkMemory#(MemReadClient#(64) readClient, MemWriteClient#(64) writeClient)(RegFileMemory); RegFile#(Bit#(10), Bit#(64)) regFile <- mkRegFileFull(); Reg#(Bit#(MemOffsetSize)) readAddr <- mkReg(0); Reg#(Bit#(BurstLenSize)) readLen <- mkReg(0); Reg#(Bit#(MemTagSize)) readTag <- mkReg(0); Reg#(Bit#(MemOffsetSize)) writeAddr <- mkReg(0); Reg#(Bit#(BurstLenSize)) writeLen <- mkReg(0); Reg#(Bit#(MemTagSize)) writeTag <- mkReg(0); FIFO#(Bit#(MemTagSize)) writeDoneFifo <- mkFIFO(); let verbose = True; rule readAddrRule if (readLen == 0 && writeLen == 0); let req <- readClient.readReq.get(); if (verbose) $display("readAddrRule addr=%h", req.offset); readAddr <= req.offset; readLen <= req.burstLen; readTag <= req.tag; endrule rule readDataRule if (readLen > 0); if (verbose) $display("readDataRule addr=%h data=%h", readAddr, regFile.sub(truncate(readAddr))); readClient.readData.put(MemData { data: regFile.sub(truncate(readAddr)), tag: readTag, last: readLen <= 8 }); readAddr <= readAddr + 8; readLen <= readLen - 8; endrule (* descending_urgency = "writeAddrRule,readAddrRule" *) rule writeAddrRule if (readLen == 0 && writeLen == 0); let req <- writeClient.writeReq.get(); if (verbose) $display("writeAddrRule addr=%h burstLen=%d", req.offset, req.burstLen); writeAddr <= req.offset; writeLen <= req.burstLen; writeTag <= req.tag; endrule rule writeDataRule if (writeLen > 0); let md <- writeClient.writeData.get(); if (verbose) $display("writeDataRule addr=%h data=%h", writeAddr, md.data); regFile.upd(truncate(writeAddr), md.data); if (writeLen <= 8) writeDoneFifo.enq(writeTag); // NOTE: this rule deadlocks if it calls writeClient.writeDone.put directly writeLen <= writeLen - 8; endrule rule writeDoneRule; let tag <- toGet(writeDoneFifo).get(); writeClient.writeDone.put(tag); endrule method Action write(Bit#(10) addr, Bit#(64) data); if (verbose) $display("mem.write addr=%h data=%h", addr, data); regFile.upd(addr, data); endmethod method Bit#(64) read(Bit#(10) addr); return regFile.sub(addr); endmethod endmodule module mkSharedMemoryFifoImpl(FIFO#(Bit#(32))); FIFO#(Bit#(32)) dataFifo <- mkFIFO(); MemReadEngine#(64,64,4, 2) readEngine <- mkMemReadEngine(); MemWriteEngine#(64,64,4, 2) writeEngine <- mkMemWriteEngine(); let mem <- mkMemory(readEngine.dmaClient, writeEngine.dmaClient); Reg#(Bit#(32)) dataReg <- mkReg(0); Reg#(Bit#(32)) wrPtrReg <- mkReg(16); Reg#(Bit#(32)) rdPtrReg[2] <- mkCReg(2,16); Bit#(32) limitPtr = 8*8; SharedMemoryPipeOut#(64,1) dut <- mkSharedMemoryPipeOut(readEngine.readServers, writeEngine.writeServers); Reg#(Bool) notFull <- mkReg(True); rule rdPtrRule if (!notFull); let v = mem.read(8); rdPtrReg[0] <= v[31:0] << 2; //$display("updating rdPtr %d", rdPtrReg[0]); endrule rule notFullRule; let nf = (wrPtrReg != (rdPtrReg[1]+8)); if (wrPtrReg == 16) nf = (rdPtrReg[1] != (limitPtr - 8)); $display("notFullRule nf=%d wrPtr %d rdPtr %d limitPtr %d", nf, wrPtrReg, rdPtrReg[1], limitPtr); notFull <= nf; endrule let fsm <- mkAutoFSM(seq mem.write(0, { wrPtrReg>>2, limitPtr }); mem.write(8, { 0, rdPtrReg[1]>>2 }); dut.cfg.setSglId(22); $display("wrote fifo wrPtr/rdPtr ptr"); while (True) seq await(notFull); dataReg <= dataFifo.first(); dataFifo.deq(); mem.write(truncate(wrPtrReg+0), {dataReg, 2}); mem.write(0, { wrPtrReg>>2, 32 }); action let wrPtr = wrPtrReg + 8; if (wrPtr >= limitPtr) begin wrPtr = 16; $display("wrapped around wrPtr=%d limitPtr=%d", wrPtr, limitPtr); end wrPtrReg <= wrPtr; endaction endseq endseq ); method enq = dataFifo.enq; method first = dut.data[0].first; method deq = dut.data[0].deq; endmodule ///////////////////////// // Equivalence testing // ///////////////////////// module [BlueCheck] checkSharedMemoryFifo (); /* Specification instance */ FIFO#(Bit#(32)) spec <- mkSizedFIFO(32); /* Implmentation instance */ FIFO#(Bit#(32)) imp <- mkSharedMemoryFifoImpl(); Ensure ensure <- getEnsure; equiv("first" , spec.first, imp.first); equiv("enq" , spec.enq, imp.enq); equiv("deq" , spec.deq, imp.deq); endmodule module [Module] testSharedMemoryFifo (); blueCheck(checkSharedMemoryFifo); endmodule ================================================ FILE: tests/bluecheck-sharedmemfifo/make.sh ================================================ #!/bin/bash # # Copyright (c) 2015 Matthew Naylor # All rights reserved. # # This software was developed by SRI International and the University of # Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 # ("CTSRD"), as part of the DARPA CRASH research programme. # # This software was developed by SRI International and the University of # Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 # ("MRC2"), as part of the DARPA MRC research programme. # # This software was developed by the University of Cambridge Computer # Laboratory as part of the Rigorous Engineering of Mainstream # Systems (REMS) project, funded by EPSRC grant EP/K008528/1. # # @BERI_LICENSE_HEADER_START@ # # Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor # license agreements. See the NOTICE file distributed with this work for # additional information regarding copyright ownership. BERI licenses this # file to you under the BERI Hardware-Software License, Version 1.0 (the # "License"); you may not use this file except in compliance with the # License. You may obtain a copy of the License at: # # http://www.beri-open-systems.org/legal/license-1-0.txt # # Unless required by applicable law or agreed to in writing, Work distributed # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # # @BERI_LICENSE_HEADER_END@ # BSC="bsc" BSCFLAGS="-keep-fires -cross-info -aggressive-conditions \ -wait-for-license -suppress-warnings G0043 \ -steps-warn-interval 300000 \ -simdir bluesim -bdir bluesim -info-dir bluesim \ -show-schedule \ -D PinTypeInclude=HostInterface -D PinType=Empty -D BurstLenSize=8 -D PhysAddrWidth=16 -D NumberOfMasters=1 \ -D SlaveDataBusWidth=32 -D SlaveControlAddrWidth=16 -D NumberOfUserTiles=16 \ -p +:../../../bluecheck:../../lib/bsv:../../bsv" SUFFIXES= # UI # == echo "(11) SharedMemoryFifo" echo "(12) SharedMemoryFifo Iterative Deepening" #read OPTION OPTION=11 case "$OPTION" in 11) TOPFILE=SharedMemoryFifoCheck.bsv TOPMOD=testSharedMemoryFifo ;; 12) TOPFILE=SharedMemoryFifoCheck.bsv TOPMOD=testSharedMemoryFifoID ;; *) echo "Option not recognised" exit ;; esac # Build it # ======== mkdir -p bluesim echo Compiling $TOPMOD in file $TOPFILE if [ "$SYNTH" = "1" ] then bsc -suppress-warnings G0043 -u -verilog -g $TOPMOD $TOPFILE else if $BSC $BSCFLAGS -sim -g $TOPMOD -u $TOPFILE then if $BSC $BSCFLAGS -sim -o $TOPMOD -e $TOPMOD bluesim/$TOPMOD.ba then ./$TOPMOD else echo Failed to generate executable simulation model fi else echo Failed to compile fi fi ================================================ FILE: tests/bluecheck_harness/Harness.bsv ================================================ import AxiBits::*; interface HarnessRequest; method Action startTest(Bit#(16) v); endinterface interface HarnessResponse; method Action testStarted(Bit#(16) v); endinterface interface Harness; interface HarnessRequest request; endinterface module [Module] mkHarness#(HarnessResponse response)(Harness); let checker <- mkMkPhysMemSlaveChecker(); interface HarnessRequest request; method Action startTest(Bit#(16) v); $display("startTest %x is a no op", v); response.testStarted(v); endmethod endinterface endmodule ================================================ FILE: tests/bluecheck_harness/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = HarnessRequest:Harness.request H2S_INTERFACES = Harness:HarnessResponse BSVFILES = Harness.bsv PYFILES = physmemrequest.py CONNECTALFLAGS += -D BLUECHECK --bsvpath=$(CONNECTALDIR)/../bluecheck include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/bluecheck_harness/harness.py ================================================ #!/usr/bin/env python3 # Copyright (c) 2016 Connectal Project # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # from __future__ import print_function import portal class BlueCheck: def __init__(self): self.proxy = portal.NativeProxy('HarnessRequest', self, responseInterface='HarnessResponse', rpc=True) self.response = None def startTest(self, v): self.proxy.startTest(v) bc = BlueCheck() print("test started") bc.startTest(22) ================================================ FILE: tests/bpiflash/BpiFlashTest.bsv ================================================ `include "ConnectalProjectConfig.bsv" import Connectable::*; import GetPut::*; import FIFOF::*; import BRAM::*; import Probe::*; import StmtFSM::*; import TriState::*; import Vector::*; import ConnectalXilinxCells::*; import BpiFlash::*; `ifdef SIMULATION import I28F512P33::*; `endif interface BpiFlashTestRequest; method Action reset(); method Action read(Bit#(25) addr); method Action write(Bit#(25) addr, Bit#(16) data); method Action setParameters(Bit#(16) cycles, Bool stallOnWaitIn); endinterface interface BpiFlashTestIndication; method Action resetDone(); method Action readDone(Bit#(16) data); method Action writeDone(); endinterface interface BpiFlashTest; interface BpiFlashTestRequest request; interface BpiPins pins; endinterface module mkBpiFlashTest#(BpiFlashTestIndication ind)(BpiFlashTest); let defaultClock <- exposeCurrentClock(); let defaultReset <- exposeCurrentReset(); Reg#(Bit#(1)) rst_o <- mkReg(0); Reg#(Bit#(1)) ce <- mkReg(1); Reg#(Bit#(1)) we <- mkReg(1); Reg#(Bit#(1)) oe <- mkReg(1); Reg#(Bit#(1)) adv <- mkReg(1); Reg#(Bit#(16)) data_o <- mkReg(0); Reg#(Bit#(25)) addr_o <- mkReg(0); Reg#(Bit#(16)) delayReg <- mkReg(10); Reg#(Bool) stallOnWaitReg <- mkReg(False); Reg#(BRAMRequest#(Bit#(25),Bit#(16))) reqReg <- mkReg(unpack(0)); FIFOF#(BRAMRequest#(Bit#(25),Bit#(16))) reqFifo <- mkFIFOF(); FIFOF#(Bit#(16)) dataFifo <- mkFIFOF(); FIFOF#(Bool) doneFifo <- mkFIFOF(); `ifndef SIMULATION Wire#(Bit#(1)) wait_in_b <- mkDWire(0); module mkDataIobuf#(Integer i)(IOBUF); (* hide *) let iobuf <- mkIOBUF(we, data_o[i]); return iobuf; endmodule function Inout#(Bit#(1)) iobuf_io(IOBUF iobuf); return iobuf.io; endfunction function Bit#(1) iobuf_o(IOBUF iobuf); return iobuf.o; endfunction Vector#(16, IOBUF) iobuf <- genWithM(mkDataIobuf); let dataIn = pack(map(iobuf_o, iobuf)); `endif `ifdef SIMULATION let flash <- mkI28f512p33Load("flash.hex"); let dataTristate <- mkTriState(oe == 1, data_o); mkConnection(dataTristate.io, flash.dq); let wait_in_b = flash.waitout(); let dataIn = dataTristate; rule rl_flash_inputs; flash.addr(addr_o); flash.advneg(adv); flash.ceneg(ce); flash.oeneg(oe); flash.weneg(we); flash.wpneg(1); flash.vpp(0); endrule `endif Reg#(Bit#(10)) i <- mkReg(0); let readFsm <- mkFSM(seq $dumpfile("bpiflash.vcd"); $dumpvars(); $dumpoff(); while (True) seq action $dumpon(); reqFifo.deq(); let req = reqFifo.first(); reqReg <= req; addr_o <= req.address >> 1; data_o <= req.datain; adv <= 0; ce <= 0; endaction delay(delayReg); adv <= 1; delay(delayReg); action if (reqReg.write) we <= 0; else oe <= 0; endaction delay(delayReg); $display("addr_o=%x\n", addr_o); $display("wait_in_b=%d dataIn=%x", wait_in_b, dataIn); if (reqReg.write) we <= 1; if (!reqReg.write && stallOnWaitReg) await (wait_in_b == 1); $display("wait_in_b=%d dataIn=%x", wait_in_b, dataIn); if (reqReg.write) doneFifo.enq(True); else dataFifo.enq(dataIn); delay(delayReg); ce <= 1; oe <= 1; delay(delayReg); endseq $dumpoff(); $dumpflush(); endseq); let resetFsm <- mkFSM(seq rst_o <= 0; delay(20); rst_o <= 1; ind.resetDone(); readFsm.start(); endseq); rule rl_readDone; let v <- toGet(dataFifo).get(); ind.readDone(v); endrule rule rl_writeDone; let v <- toGet(doneFifo).get(); ind.writeDone(); endrule let probe_addr <- mkProbe(); let probe_adv <- mkProbe(); let probe_ce <- mkProbe(); let probe_oe <- mkProbe(); let probe_we <- mkProbe(); let probe_data_in <- mkProbe(); let probe_data_out <- mkProbe(); let probe_wait_in <- mkProbe(); rule rl_probe; probe_addr <= addr_o; probe_adv <= adv; probe_ce <= ce; probe_oe <= oe; probe_we <= we; probe_data_in <= dataIn; probe_data_out <= data_o; probe_wait_in <= wait_in_b; endrule interface BpiFlashTestRequest request; method Action reset(); resetFsm.start(); endmethod method Action read(Bit#(25) addr); reqFifo.enq(BRAMRequest {address: addr, write: False, responseOnWrite: False, datain: 0}); endmethod method Action write(Bit#(25) addr, Bit#(16) data); reqFifo.enq(BRAMRequest {address: addr, write: True, responseOnWrite: False, datain: data}); endmethod method Action setParameters(Bit#(16) cycles, Bool stallOnWaitIn); delayReg <= cycles; stallOnWaitReg <= stallOnWaitIn; endmethod endinterface `ifndef SIMULATION interface BpiPins pins; interface BpiFlashPins flash; interface deleteme_unused_clock = defaultClock; // interface rst = defaultReset; interface data = map(iobuf_io, iobuf); method Bit#(25) addr = addr_o; method Bit#(1) adv_b = adv; method Bit#(1) ce_b = ce; method Bit#(1) oe_b = oe; method Bit#(1) we_b = we; `ifdef BPI_HAS_WP method Bit#(1) wp_b = 1; `endif `ifdef BPI_HAS_VPP method Bit#(1) vpp = 0; `endif method Action wait_in(Bit#(1) b); wait_in_b <= b; endmethod endinterface endinterface `endif endmodule ================================================ FILE: tests/bpiflash/I28F512P33.bsv ================================================ /* ../../generated/scripts/importbvi.py -o I28F512P33.bsv -I I28f512p33 -P StrataFlash -c CLK -r RSTNeg i28f512p33.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; (* always_ready, always_enabled *) interface I28f512p33; method Action addr(Bit#(25) v); method Action advneg(Bit#(1) v); method Action ceneg(Bit#(1) v); interface Inout#(Bit#(16)) dq; method Action oeneg(Bit#(1) v); method Action vpp(Bit#(1) v); method Bit#(1) waitout(); method Action weneg(Bit#(1) v); method Action wpneg(Bit#(1) v); endinterface import "BVI" i28f512p33 = module mkI28f512p33Load#(String memFileName)(I28f512p33); parameter mem_file_name = memFileName; parameter mem_file_name_1 = memFileName; parameter UserPreload = 1; default_clock clk(CLK); default_reset rstneg(RSTNeg); method addr(Addr) enable((*inhigh*) EN_Addr); method advneg(ADVNeg) enable((*inhigh*) EN_ADVNeg); method ceneg(CENeg) enable((*inhigh*) EN_CENeg); ifc_inout dq(DQ); method oeneg(OENeg) enable((*inhigh*) EN_OENeg); method vpp(VPP) enable((*inhigh*) EN_VPP); method WAITOut waitout(); method weneg(WENeg) enable((*inhigh*) EN_WENeg); method wpneg(WPNeg) enable((*inhigh*) EN_WPNeg); schedule (addr, advneg, ceneg, oeneg, vpp, waitout, weneg, wpneg) CF (addr, advneg, ceneg, oeneg, vpp, waitout, weneg, wpneg); endmodule module mkI28f512p33(I28f512p33); (* hide *)let flash <- mkI28f512p33Load("none"); return flash; endmodule ================================================ FILE: tests/bpiflash/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = BpiFlashTestRequest:BpiFlashTest.request H2S_INTERFACES = BpiFlashTest:BpiFlashTestIndication CONNECTALFLAGS+= -P mkConnectalTop CONNECTALFLAGS+= --shared BSVFILES = BpiFlashTest.bsv CPPFILES=testbpiflash.cpp ifneq ($(BOARD),vc709) CONNECTALFLAGS+= --verilog=i28f512p33.v endif ifeq ($(BOARD),vc709) PINOUT_FILE += bpiflash.json PIN_TYPE = BpiPins PIN_TYPE_INCLUDE = BpiFlash AUTOTOP = --interface pins:BpiFlashTest.pins endif flash.mcs: flash.hex vivado -mode batch -source genmcs.tcl include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/bpiflash/bpiflash.h ================================================ #ifndef BPIFLASH_H #define BPIFLASH_H class BpiFlashTestRequestProxy; class BpiFlashTestIndication; class BpiFlash { public: BpiFlash(); ~BpiFlash(); void read(unsigned long offset, uint8_t *buf); void write(unsigned long offset, const uint8_t *buf); private: BpiFlashTestRequestProxy *request; BpiFlashTestIndication *indication; bool didReset; void maybeReset(); }; #endif ================================================ FILE: tests/bpiflash/bpiflash.json ================================================ { "flash_data_0": { "bpi_flash": "data[0]" }, "flash_data_1": { "bpi_flash": "data[1]" }, "flash_data_2": { "bpi_flash": "data[2]" }, "flash_data_3": { "bpi_flash": "data[3]" }, "flash_data_4": { "bpi_flash": "data[4]" }, "flash_data_5": { "bpi_flash": "data[5]" }, "flash_data_6": { "bpi_flash": "data[6]" }, "flash_data_7": { "bpi_flash": "data[7]" }, "flash_data_8": { "bpi_flash": "data[8]" }, "flash_data_9": { "bpi_flash": "data[9]" }, "flash_data_10": { "bpi_flash": "data[10]" }, "flash_data_11": { "bpi_flash": "data[11]" }, "flash_data_12": { "bpi_flash": "data[12]" }, "flash_data_13": { "bpi_flash": "data[13]" }, "flash_data_14": { "bpi_flash": "data[14]" }, "flash_data_15": { "bpi_flash": "data[15]" }, "flash_addr[0]": { "bpi_flash": "addr[0]" }, "flash_addr[1]": { "bpi_flash": "addr[1]" }, "flash_addr[2]": { "bpi_flash": "addr[2]" }, "flash_addr[3]": { "bpi_flash": "addr[3]" }, "flash_addr[4]": { "bpi_flash": "addr[4]" }, "flash_addr[5]": { "bpi_flash": "addr[5]" }, "flash_addr[6]": { "bpi_flash": "addr[6]" }, "flash_addr[7]": { "bpi_flash": "addr[7]" }, "flash_addr[8]": { "bpi_flash": "addr[8]" }, "flash_addr[9]": { "bpi_flash": "addr[9]" }, "flash_addr[10]": { "bpi_flash": "addr[10]" }, "flash_addr[11]": { "bpi_flash": "addr[11]" }, "flash_addr[12]": { "bpi_flash": "addr[12]" }, "flash_addr[13]": { "bpi_flash": "addr[13]" }, "flash_addr[14]": { "bpi_flash": "addr[14]" }, "flash_addr[15]": { "bpi_flash": "addr[15]" }, "flash_addr[16]": { "bpi_flash": "addr[16]" }, "flash_addr[17]": { "bpi_flash": "addr[17]" }, "flash_addr[18]": { "bpi_flash": "addr[18]" }, "flash_addr[19]": { "bpi_flash": "addr[19]" }, "flash_addr[20]": { "bpi_flash": "addr[20]" }, "flash_addr[21]": { "bpi_flash": "addr[21]" }, "flash_addr[22]": { "bpi_flash": "addr[22]" }, "flash_addr[23]": { "bpi_flash": "addr[23]" }, "flash_addr[24]": { "bpi_flash": "addr[24]" }, "flash_oe_b": { "bpi_flash": "oe_b" }, "flash_ce_b": { "bpi_flash": "ce_b" }, "flash_adv_b": { "bpi_flash": "adv_b" }, "flash_we_b": { "bpi_flash": "we_b" }, "flash_wait_in_b": { "bpi_flash": "wait_in_b" } } ================================================ FILE: tests/bpiflash/i28f512p33.v ================================================ ////////////////////////////////////////////////////////////////////////////// // File name : i28f512p33.v ////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2007-2009 Free Model Foundry; http://www.FreeModelFoundry.com // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // MODIFICATION HISTORY: // // version: | author: | mod date: | changes made: // V1.0 I.Milutinovic 07 Jun 13 Initial Release // V1.1 J.Stoickov 09 Apr 01 Write mode corrected for the WENeg // and CENeg signals rise at same time // V1.2 S.Petrovic 09 Apr 15 ADV LOW is removed as condition // for write address latching // // Downloaded from http://www.freemodelfoundry.com/fmf_vlog_models/flash/i28f512p33.v ////////////////////////////////////////////////////////////////////////////// // PART DESCRIPTION: // // Library: FLASH // Technology: FLASH MEMORY // Part: I28F512P33 // // Description: 2 x 256 Mbit Intel Strata Flash Memory (P33) Family // ////////////////////////////////////////////////////////////////////////////// // Comments : // ////////////////////////////////////////////////////////////////////////////// // Known Bugs: // ////////////////////////////////////////////////////////////////////////////// `timescale 1 ns/1 ns ////////////////////////////////////////////////////////////////////////////// // TOP MODULE DECLARATION, Top and Bottom Parameter Block Configuration // ////////////////////////////////////////////////////////////////////////////// module i28f512p33 ( input [25:0] Addr, input [15:0] DQ, input ADVNeg, input CENeg, input CLK, input OENeg, input RSTNeg, input WENeg, input WPNeg, input VPP, output WAITOut ); // parameter declaration parameter mem_file_name = "none"; parameter mem_file_name_1 = "none"; parameter otp_blocks_file = "none"; parameter otp_blocks_file_1 = "none"; parameter prot_reg_file = "none"; parameter prot_reg_file_1 = "none"; parameter UserPreload = 1'b0; parameter TimingModel = "defaulttimingmodel"; parameter VPP_voltage = 9; wire CENeg1; wire CENeg2; wire [26:1] A; assign A[26:1] = Addr[25:0]; assign CENeg1 = (~CENeg && A[25]) ? 1'b0 : 1'b1; assign CENeg2 = (~CENeg && ~A[25]) ? 1'b0 : 1'b1; // Instance of flash memory, Top Parameter Block Configuration i28f256p33_1 #(mem_file_name, otp_blocks_file, prot_reg_file, UserPreload , TimingModel, VPP_voltage) UPPER_DIE ( .A24(A[24]), .A23(A[23]), .A22(A[22]), .A21(A[21]), .A20(A[20]), .A19(A[19]), .A18(A[18]), .A17(A[17]), .A16(A[16]), .A15(A[15]), .A14(A[14]), .A13(A[13]), .A12(A[12]), .A11(A[11]), .A10(A[10]), .A9(A[9]), .A8(A[8]), .A7(A[7]), .A6(A[6]), .A5(A[5]), .A4(A[4]), .A3(A[3]), .A2(A[2]), .A1(A[1]), .DQ15(DQ[15]), .DQ14(DQ[14]), .DQ13(DQ[13]), .DQ12(DQ[12]), .DQ11(DQ[11]), .DQ10(DQ[10]), .DQ9(DQ[9]), .DQ8(DQ[8]), .DQ7(DQ[7]), .DQ6(DQ[6]), .DQ5(DQ[5]), .DQ4(DQ[4]), .DQ3(DQ[3]), .DQ2(DQ[2]), .DQ1(DQ[1]), .DQ0(DQ[0]), .ADVNeg (ADVNeg), .CENeg (CENeg1), .CLK (CLK ), .OENeg (OENeg ), .RSTNeg (RSTNeg), .WENeg (WENeg ), .WPNeg (WPNeg ), .VPP (VPP ), .WAITOut(WAITOut) ); // Instance of flash memory, Bottom Parameter Block Configuration i28f256p33_2 #(mem_file_name_1, otp_blocks_file_1, prot_reg_file_1, UserPreload, TimingModel ,VPP_voltage) LOWER_DIE ( .A24(A[24]), .A23(A[23]), .A22(A[22]), .A21(A[21]), .A20(A[20]), .A19(A[19]), .A18(A[18]), .A17(A[17]), .A16(A[16]), .A15(A[15]), .A14(A[14]), .A13(A[13]), .A12(A[12]), .A11(A[11]), .A10(A[10]), .A9(A[9]), .A8(A[8]), .A7(A[7]), .A6(A[6]), .A5(A[5]), .A4(A[4]), .A3(A[3]), .A2(A[2]), .A1(A[1]), .DQ15(DQ[15]), .DQ14(DQ[14]), .DQ13(DQ[13]), .DQ12(DQ[12]), .DQ11(DQ[11]), .DQ10(DQ[10]), .DQ9(DQ[9]), .DQ8(DQ[8]), .DQ7(DQ[7]), .DQ6(DQ[6]), .DQ5(DQ[5]), .DQ4(DQ[4]), .DQ3(DQ[3]), .DQ2(DQ[2]), .DQ1(DQ[1]), .DQ0(DQ[0]), .ADVNeg (ADVNeg), .CENeg (CENeg2), .CLK (CLK ), .OENeg (OENeg ), .RSTNeg (RSTNeg), .WENeg (WENeg ), .WPNeg (WPNeg ), .VPP (VPP ), .WAITOut(WAITOut) ); endmodule ////////////////////////////////////////////////////////////////////////////// // MODULE DECLARATION, Top Parameter Block Configuration // ////////////////////////////////////////////////////////////////////////////// module i28f256p33_1 ( A24 , A23 , A22 , A21 , A20 , A19 , A18 , A17 , A16 , A15 , A14 , A13 , A12 , A11 , A10 , A9 , A8 , A7 , A6 , A5 , A4 , A3 , A2 , A1 , DQ15 , DQ14 , DQ13 , DQ12 , DQ11 , DQ10 , DQ9 , DQ8 , DQ7 , DQ6 , DQ5 , DQ4 , DQ3 , DQ2 , DQ1 , DQ0 , ADVNeg , CENeg , CLK , OENeg , RSTNeg , WENeg , WPNeg , VPP , WAITOut ); //////////////////////////////////////////////////////////////////////// // Port / Part Pin Declarations //////////////////////////////////////////////////////////////////////// input A24 ; input A23 ; input A22 ; input A21 ; input A20 ; input A19 ; input A18 ; input A17 ; input A16 ; input A15 ; input A14 ; input A13 ; input A12 ; input A11 ; input A10 ; input A9 ; input A8 ; input A7 ; input A6 ; input A5 ; input A4 ; input A3 ; input A2 ; input A1 ; inout DQ15 ; inout DQ14 ; inout DQ13 ; inout DQ12 ; inout DQ11 ; inout DQ10 ; inout DQ9 ; inout DQ8 ; inout DQ7 ; inout DQ6 ; inout DQ5 ; inout DQ4 ; inout DQ3 ; inout DQ2 ; inout DQ1 ; inout DQ0 ; input ADVNeg ; input CENeg ; input CLK ; input OENeg ; input RSTNeg ; input WENeg ; input WPNeg ; input VPP ; output WAITOut ; // interconnect path delay signals wire A24_ipd ; wire A23_ipd ; wire A22_ipd ; wire A21_ipd ; wire A20_ipd ; wire A19_ipd ; wire A18_ipd ; wire A17_ipd ; wire A16_ipd ; wire A15_ipd ; wire A14_ipd ; wire A13_ipd ; wire A12_ipd ; wire A11_ipd ; wire A10_ipd ; wire A9_ipd ; wire A8_ipd ; wire A7_ipd ; wire A6_ipd ; wire A5_ipd ; wire A4_ipd ; wire A3_ipd ; wire A2_ipd ; wire A1_ipd ; wire [23 : 0] A; assign A = { A24_ipd, A23_ipd, A22_ipd, A21_ipd, A20_ipd, A19_ipd, A18_ipd, A17_ipd, A16_ipd, A15_ipd, A14_ipd, A13_ipd, A12_ipd, A11_ipd, A10_ipd, A9_ipd, A8_ipd, A7_ipd, A6_ipd, A5_ipd, A4_ipd, A3_ipd, A2_ipd, A1_ipd }; wire DQ15_ipd ; wire DQ14_ipd ; wire DQ13_ipd ; wire DQ12_ipd ; wire DQ11_ipd ; wire DQ10_ipd ; wire DQ9_ipd ; wire DQ8_ipd ; wire DQ7_ipd ; wire DQ6_ipd ; wire DQ5_ipd ; wire DQ4_ipd ; wire DQ3_ipd ; wire DQ2_ipd ; wire DQ1_ipd ; wire DQ0_ipd ; wire [15 : 0 ] DQIn; assign DQIn = {DQ15_ipd, DQ14_ipd, DQ13_ipd, DQ12_ipd, DQ11_ipd, DQ10_ipd, DQ9_ipd, DQ8_ipd, DQ7_ipd, DQ6_ipd, DQ5_ipd, DQ4_ipd, DQ3_ipd, DQ2_ipd, DQ1_ipd, DQ0_ipd }; wire [15 : 0 ] DQOut; assign DQOut = {DQ15, DQ14, DQ13, DQ12, DQ11, DQ10, DQ9, DQ8, DQ7, DQ6, DQ5, DQ4, DQ3, DQ2, DQ1, DQ0 }; wire ADVNeg_ipd ; wire CENeg_ipd ; wire CLK_ipd ; wire OENeg_ipd ; wire RSTNeg_ipd ; wire WENeg_ipd ; wire WPNeg_ipd ; wire DQ15_zd ; wire DQ14_zd ; wire DQ13_zd ; wire DQ12_zd ; wire DQ11_zd ; wire DQ10_zd ; wire DQ9_zd ; wire DQ8_zd ; wire DQ7_zd ; wire DQ6_zd ; wire DQ5_zd ; wire DQ4_zd ; wire DQ3_zd ; wire DQ2_zd ; wire DQ1_zd ; wire DQ0_zd ; wire DQ15_Pass ; wire DQ14_Pass ; wire DQ13_Pass ; wire DQ12_Pass ; wire DQ11_Pass ; wire DQ10_Pass ; wire DQ9_Pass ; wire DQ8_Pass ; wire DQ7_Pass ; wire DQ6_Pass ; wire DQ5_Pass ; wire DQ4_Pass ; wire DQ3_Pass ; wire DQ2_Pass ; wire DQ1_Pass ; wire DQ0_Pass ; reg [15 : 0] DQOut_zd = 16'bz; reg [15 : 0] DQOut_Pass = 16'bz; assign {DQ15_zd, DQ14_zd, DQ13_zd, DQ12_zd, DQ11_zd, DQ10_zd, DQ9_zd, DQ8_zd, DQ7_zd, DQ6_zd, DQ5_zd, DQ4_zd, DQ3_zd, DQ2_zd, DQ1_zd, DQ0_zd } = DQOut_zd; assign {DQ15_Pass, DQ14_Pass, DQ13_Pass, DQ12_Pass, DQ11_Pass, DQ10_Pass, DQ9_Pass, DQ8_Pass, DQ7_Pass, DQ6_Pass, DQ5_Pass, DQ4_Pass, DQ3_Pass, DQ2_Pass, DQ1_Pass, DQ0_Pass } = DQOut_Pass; reg WAITOut_zd = 1'bz; parameter mem_file_name = "none"; parameter otp_blocks_file = "none"; parameter prot_reg_file = "none"; parameter UserPreload = 1'b0; parameter TimingModel = "DefaultTimingModel"; parameter VPP_voltage = 9; // this parameter specifies if // 9V or 2V is applied to Vpp pin // (when VPP pin is 1'b1) parameter MaxData = 16'hFFFF; parameter HiAddrBit = 23; parameter MemSize = 32'hFFFFFF; parameter BlockNum = 258; parameter DeviceID_B = 16'h8922; parameter DeviceID_T = 16'h891F; parameter MainBlockSize = 32'h10000; parameter ParameterBlockSize = 32'h04000; // If speedsimulation is needed uncomment following line // `define SPEEDSIM; // FSM states parameter RESET_POWER_DOWN = 5'd0; parameter READY = 5'd1; parameter LOCK_SETUP = 5'd2; parameter OTP_SETUP = 5'd3; parameter OTP_BUSY = 5'd4; parameter PROG_SETUP = 5'd5; parameter PROG_BUSY = 5'd6; parameter PROG_SUSP = 5'd7; parameter BP_SETUP = 5'd8; parameter BP_LOAD = 5'd9; parameter BP_CONFIRM = 5'd10; parameter BP_BUSY = 5'd11; parameter BP_SUSP = 5'd12; parameter ERASE_SETUP = 5'd13; parameter ERASE_BUSY = 5'd14; parameter ERS_SUSP = 5'd15; parameter PROG_SETUP_ERS_SUSP = 5'd16; parameter PROG_BUSY_ERS_SUSP = 5'd17; parameter PROG_SUSP_ERS_SUSP = 5'd18; parameter BP_SETUP_ERS_SUSP = 5'd19; parameter BP_LOAD_ERS_SUSP = 5'd20; parameter BP_CONFIRM_ERS_SUSP = 5'd21; parameter BP_BUSY_ERS_SUSP = 5'd22; parameter BP_SUSP_ERS_SUSP = 5'd23; parameter LOCK_SETUP_ERS_SUSP = 5'd24; parameter BEFP_SETUP = 5'd25; parameter BEFP_LOAD = 5'd26; parameter BEFP_BUSY = 5'd27; // read mode parameter READ_ARRAY = 2'd0; parameter READ_ID = 2'd1; parameter READ_QUERY = 2'd2; parameter READ_STATUS = 2'd3; reg [5:0] current_state; reg [5:0] next_state; reg [1:0] read_state; reg deq; // Memory declaration integer MemData[0:MemSize]; // internal delays reg WordProgram_in = 1'b0; reg WordProgram_out = 1'b0; reg BuffProgram_in = 1'b0; reg BuffProgram_out = 1'b0; reg BEFP_in = 1'b0; reg BEFP_out = 1'b0; reg BEFPsetup_in = 1'b0; reg BEFPsetup_out = 1'b0; reg ParameterErase_in = 1'b0; reg MainErase_in = 1'b0; reg ParameterErase_out = 1'b0; reg MainErase_out = 1'b0; reg ProgramSuspend_in = 1'b0; reg ProgramSuspend_out = 1'b0; reg EraseSuspend_in = 1'b0; reg EraseSuspend_out = 1'b0; reg RstDuringErsPrg_in = 1'b0; reg RstDuringErsPrg_out = 1'b0; // event control registers reg falling_edge_ADVNeg = 1'b0; reg falling_edge_RSTNeg = 1'b0; reg falling_edge_BEFPsetup_out = 1'b0; reg falling_edge_BEFP_out = 1'b0; reg falling_edge_Read = 1'b0; reg falling_edge_OENeg = 1'b0; reg falling_edge_CENeg = 1'b0; reg rising_edge_ADVNeg = 1'b0; reg rising_edge_CLOCK = 1'b0; reg rising_edge_WENeg = 1'b0; reg rising_edge_CENeg = 1'b0; reg rising_edge_RSTNeg = 1'b0; reg rising_edge_Write = 1'b0; reg rising_edge_Read = 1'b0; reg RstDuringErsPrg_out_event = 1'b0; reg WordProgram_out_event = 1'b0; reg abort_event = 1'b0; reg ProgramSuspend_out_event = 1'b0; reg BuffProgram_out_event = 1'b0; reg ExtendProgTime_event = 1'b0; reg ParameterErase_out_event = 1'b0; reg falling_edge_MainErase_out = 1'b0; reg falling_edge_EraseSuspend_out = 1'b0; reg Ahigh_event = 1'b0; reg Alow_event = 1'b0; reg A_event = 1'b0; reg rising_edge_OENeg = 1'b0; reg AssertWAITOut_event = 1'b0; reg DeassertWAITOut_event = 1'b0; reg rising_edge_MainErase_in = 1'b0; reg rising_edge_ParameterErase_in = 1'b0; reg EraseSuspend_event = 1'b0; reg rising_edge_MainEraseResume = 1'b0; reg rising_edge_ParameterEraseResume = 1'b0; integer i,j; // Bus cycle decode reg CLOCK = 1'b0; reg Write = 1'b0; reg Read = 1'b0; reg Pmode = 1'b0; // Functional reg abort = 1'b0; reg ExtendProgTime = 1'b0; reg AssertWAITOut = 1'b0; reg DeassertWAITOut = 1'b0; //Block Lock Status parameter UNLOCKED = 2'd0; parameter LOCKED = 2'd1; parameter LOCKED_DOWN = 2'd2; integer Block_Lock[BlockNum:0]; reg [BlockNum:0] BlockLockBit; reg [BlockNum:0] BlockLockDownBit; reg OTP[0:BlockNum]; // Status Register reg[7:0] SR = 8'b10000000; // Read Configuration Register reg[15:0] RCR = 16'b1011111111001111; // Protection registers integer PR[9'h80:9'h109]; // CFI array integer CFI_array[9'h10:9'h156]; reg LATCHED = 1'b0; reg [15:0] LatchedData; reg [HiAddrBit:0] LatchedAddr; integer ReadAddr; integer DataBuff[0:31]; integer AddrBuff[0:31]; integer burst_cntr; integer BurstLength; integer BurstDelay; integer DataHold; integer WCount; integer word_cntr; integer word_cnt; integer word_number; integer block_number; integer erasing_block; integer lowest_addr; integer highest_addr; integer start_addr; integer BEFP_addr; integer BEFP_block; integer BEFP_block2; reg [15:0] mem_bits; reg [15:0] prog_bits; reg [15:0] DQOut_tmp; reg read_out = 1'b0; reg suspended_bp = 1'b0; reg suspended_erase = 1'b0; reg aborted ; integer block_size; reg ParameterEraseResume; reg MainEraseResume; reg WordProgramResume; reg BP_ProgramResume; time merase_duration; time perase_duration; time melapsed; time pelapsed; time mstart; time pstart; event merase_event; event perase_event; // timing check violation reg Viol = 1'b0; //TPD_XX_DATA time OEDQ_t; time CEDQ_t; time ADDRDQ_t; time OENeg_event; time CENeg_event; time ADDR_event; reg FROMOE; reg FROMCE; reg FROMADDR; reg OPENLATCH; integer OEDQ_01; integer CEDQ_01; integer ADDRDQIN_01; integer ADDRDQPAGE_01; reg [15:0] TempData; wire InitialPageAccess; assign InitialPageAccess = FROMADDR && ~Pmode; wire SubsequentPageAccess; assign SubsequentPageAccess = FROMADDR && Pmode; wire CLK_rising; assign CLK_rising = RCR[6] && ~CENeg_ipd; wire CLK_falling; assign CLK_falling = ~(RCR[6]) && ~CENeg_ipd; /////////////////////////////////////////////////////////////////////////////// //Interconnect Path Delay Section /////////////////////////////////////////////////////////////////////////////// buf (A24_ipd, A24); buf (A23_ipd, A23); buf (A22_ipd, A22); buf (A21_ipd, A21); buf (A20_ipd, A20); buf (A19_ipd, A19); buf (A18_ipd, A18); buf (A17_ipd, A17); buf (A16_ipd, A16); buf (A15_ipd, A15); buf (A14_ipd, A14); buf (A13_ipd, A13); buf (A12_ipd, A12); buf (A11_ipd, A11); buf (A10_ipd, A10); buf (A9_ipd , A9 ); buf (A8_ipd , A8 ); buf (A7_ipd , A7 ); buf (A6_ipd , A6 ); buf (A5_ipd , A5 ); buf (A4_ipd , A4 ); buf (A3_ipd , A3 ); buf (A2_ipd , A2 ); buf (A1_ipd , A1 ); buf (DQ15_ipd, DQ15); buf (DQ14_ipd, DQ14); buf (DQ13_ipd, DQ13); buf (DQ12_ipd, DQ12); buf (DQ11_ipd, DQ11); buf (DQ10_ipd, DQ10); buf (DQ9_ipd , DQ9 ); buf (DQ8_ipd , DQ8 ); buf (DQ7_ipd , DQ7 ); buf (DQ6_ipd , DQ6 ); buf (DQ5_ipd , DQ5 ); buf (DQ4_ipd , DQ4 ); buf (DQ3_ipd , DQ3 ); buf (DQ2_ipd , DQ2 ); buf (DQ1_ipd , DQ1 ); buf (DQ0_ipd , DQ0 ); buf (RSTNeg_ipd , RSTNeg ); buf (ADVNeg_ipd , ADVNeg ); buf (CLK_ipd , CLK ); buf (CENeg_ipd , CENeg ); buf (OENeg_ipd , OENeg ); buf (WENeg_ipd , WENeg ); buf (WPNeg_ipd , WPNeg ); /////////////////////////////////////////////////////////////////////////////// // Propagation delay Section /////////////////////////////////////////////////////////////////////////////// nmos (DQ15, DQ15_Pass , 1); nmos (DQ14, DQ14_Pass , 1); nmos (DQ13, DQ13_Pass , 1); nmos (DQ12, DQ12_Pass , 1); nmos (DQ11, DQ11_Pass , 1); nmos (DQ10, DQ10_Pass , 1); nmos (DQ9 , DQ9_Pass , 1); nmos (DQ8 , DQ8_Pass , 1); nmos (DQ7 , DQ7_Pass , 1); nmos (DQ6 , DQ6_Pass , 1); nmos (DQ5 , DQ5_Pass , 1); nmos (DQ4 , DQ4_Pass , 1); nmos (DQ3 , DQ3_Pass , 1); nmos (DQ2 , DQ2_Pass , 1); nmos (DQ1 , DQ1_Pass , 1); nmos (DQ0 , DQ0_Pass , 1); nmos (WAITOut, WAITOut_zd, 1); wire deg; specify // tipd delays: interconnect path delays , mapped to input port delays. // In Verilog is not necessary to declare any tipd_ delay variables, // they can be taken from SDF file // With all the other delays real delays would be taken from SDF file // tpd delays specparam tpd_A1_DQ0 =1; specparam tpd_A1_DQ1 =1; specparam tpd_A1_DQ2 =1; specparam tpd_A1_DQ3 =1; specparam tpd_A1_DQ4 =1; specparam tpd_A1_DQ5 =1; specparam tpd_A1_DQ6 =1; specparam tpd_A1_DQ7 =1; specparam tpd_A1_DQ8 =1; specparam tpd_A1_DQ9 =1; specparam tpd_A1_DQ10 =1; specparam tpd_A1_DQ11 =1; specparam tpd_A1_DQ12 =1; specparam tpd_A1_DQ13 =1; specparam tpd_A1_DQ14 =1; specparam tpd_A1_DQ15 =1; specparam tpd_A2_DQ0 =1; specparam tpd_A2_DQ1 =1; specparam tpd_A2_DQ2 =1; specparam tpd_A2_DQ3 =1; specparam tpd_A2_DQ4 =1; specparam tpd_A2_DQ5 =1; specparam tpd_A2_DQ6 =1; specparam tpd_A2_DQ7 =1; specparam tpd_A2_DQ8 =1; specparam tpd_A2_DQ9 =1; specparam tpd_A2_DQ10 =1; specparam tpd_A2_DQ11 =1; specparam tpd_A2_DQ12 =1; specparam tpd_A2_DQ13 =1; specparam tpd_A2_DQ14 =1; specparam tpd_A2_DQ15 =1; specparam tpd_A3_DQ0 =1; specparam tpd_A3_DQ1 =1; specparam tpd_A3_DQ2 =1; specparam tpd_A3_DQ3 =1; specparam tpd_A3_DQ4 =1; specparam tpd_A3_DQ5 =1; specparam tpd_A3_DQ6 =1; specparam tpd_A3_DQ7 =1; specparam tpd_A3_DQ8 =1; specparam tpd_A3_DQ9 =1; specparam tpd_A3_DQ10 =1; specparam tpd_A3_DQ11 =1; specparam tpd_A3_DQ12 =1; specparam tpd_A3_DQ13 =1; specparam tpd_A3_DQ14 =1; specparam tpd_A3_DQ15 =1; specparam tpd_A4_DQ0 =1; specparam tpd_A4_DQ1 =1; specparam tpd_A4_DQ2 =1; specparam tpd_A4_DQ3 =1; specparam tpd_A4_DQ4 =1; specparam tpd_A4_DQ5 =1; specparam tpd_A4_DQ6 =1; specparam tpd_A4_DQ7 =1; specparam tpd_A4_DQ8 =1; specparam tpd_A4_DQ9 =1; specparam tpd_A4_DQ10 =1; specparam tpd_A4_DQ11 =1; specparam tpd_A4_DQ12 =1; specparam tpd_A4_DQ13 =1; specparam tpd_A4_DQ14 =1; specparam tpd_A4_DQ15 =1; specparam tpd_A5_DQ0 =1; specparam tpd_A5_DQ1 =1; specparam tpd_A5_DQ2 =1; specparam tpd_A5_DQ3 =1; specparam tpd_A5_DQ4 =1; specparam tpd_A5_DQ5 =1; specparam tpd_A5_DQ6 =1; specparam tpd_A5_DQ7 =1; specparam tpd_A5_DQ8 =1; specparam tpd_A5_DQ9 =1; specparam tpd_A5_DQ10 =1; specparam tpd_A5_DQ11 =1; specparam tpd_A5_DQ12 =1; specparam tpd_A5_DQ13 =1; specparam tpd_A5_DQ14 =1; specparam tpd_A5_DQ15 =1; specparam tpd_A6_DQ0 =1; specparam tpd_A6_DQ1 =1; specparam tpd_A6_DQ2 =1; specparam tpd_A6_DQ3 =1; specparam tpd_A6_DQ4 =1; specparam tpd_A6_DQ5 =1; specparam tpd_A6_DQ6 =1; specparam tpd_A6_DQ7 =1; specparam tpd_A6_DQ8 =1; specparam tpd_A6_DQ9 =1; specparam tpd_A6_DQ10 =1; specparam tpd_A6_DQ11 =1; specparam tpd_A6_DQ12 =1; specparam tpd_A6_DQ13 =1; specparam tpd_A6_DQ14 =1; specparam tpd_A6_DQ15 =1; specparam tpd_A7_DQ0 =1; specparam tpd_A7_DQ1 =1; specparam tpd_A7_DQ2 =1; specparam tpd_A7_DQ3 =1; specparam tpd_A7_DQ4 =1; specparam tpd_A7_DQ5 =1; specparam tpd_A7_DQ6 =1; specparam tpd_A7_DQ7 =1; specparam tpd_A7_DQ8 =1; specparam tpd_A7_DQ9 =1; specparam tpd_A7_DQ10 =1; specparam tpd_A7_DQ11 =1; specparam tpd_A7_DQ12 =1; specparam tpd_A7_DQ13 =1; specparam tpd_A7_DQ14 =1; specparam tpd_A7_DQ15 =1; specparam tpd_A8_DQ0 =1; specparam tpd_A8_DQ1 =1; specparam tpd_A8_DQ2 =1; specparam tpd_A8_DQ3 =1; specparam tpd_A8_DQ4 =1; specparam tpd_A8_DQ5 =1; specparam tpd_A8_DQ6 =1; specparam tpd_A8_DQ7 =1; specparam tpd_A8_DQ8 =1; specparam tpd_A8_DQ9 =1; specparam tpd_A8_DQ10 =1; specparam tpd_A8_DQ11 =1; specparam tpd_A8_DQ12 =1; specparam tpd_A8_DQ13 =1; specparam tpd_A8_DQ14 =1; specparam tpd_A8_DQ15 =1; specparam tpd_A9_DQ0 =1; specparam tpd_A9_DQ1 =1; specparam tpd_A9_DQ2 =1; specparam tpd_A9_DQ3 =1; specparam tpd_A9_DQ4 =1; specparam tpd_A9_DQ5 =1; specparam tpd_A9_DQ6 =1; specparam tpd_A9_DQ7 =1; specparam tpd_A9_DQ8 =1; specparam tpd_A9_DQ9 =1; specparam tpd_A9_DQ10 =1; specparam tpd_A9_DQ11 =1; specparam tpd_A9_DQ12 =1; specparam tpd_A9_DQ13 =1; specparam tpd_A9_DQ14 =1; specparam tpd_A9_DQ15 =1; specparam tpd_A10_DQ0 =1; specparam tpd_A10_DQ1 =1; specparam tpd_A10_DQ2 =1; specparam tpd_A10_DQ3 =1; specparam tpd_A10_DQ4 =1; specparam tpd_A10_DQ5 =1; specparam tpd_A10_DQ6 =1; specparam tpd_A10_DQ7 =1; specparam tpd_A10_DQ8 =1; specparam tpd_A10_DQ9 =1; specparam tpd_A10_DQ10 =1; specparam tpd_A10_DQ11 =1; specparam tpd_A10_DQ12 =1; specparam tpd_A10_DQ13 =1; specparam tpd_A10_DQ14 =1; specparam tpd_A10_DQ15 =1; specparam tpd_A11_DQ0 =1; specparam tpd_A11_DQ1 =1; specparam tpd_A11_DQ2 =1; specparam tpd_A11_DQ3 =1; specparam tpd_A11_DQ4 =1; specparam tpd_A11_DQ5 =1; specparam tpd_A11_DQ6 =1; specparam tpd_A11_DQ7 =1; specparam tpd_A11_DQ8 =1; specparam tpd_A11_DQ9 =1; specparam tpd_A11_DQ10 =1; specparam tpd_A11_DQ11 =1; specparam tpd_A11_DQ12 =1; specparam tpd_A11_DQ13 =1; specparam tpd_A11_DQ14 =1; specparam tpd_A11_DQ15 =1; specparam tpd_A12_DQ0 =1; specparam tpd_A12_DQ1 =1; specparam tpd_A12_DQ2 =1; specparam tpd_A12_DQ3 =1; specparam tpd_A12_DQ4 =1; specparam tpd_A12_DQ5 =1; specparam tpd_A12_DQ6 =1; specparam tpd_A12_DQ7 =1; specparam tpd_A12_DQ8 =1; specparam tpd_A12_DQ9 =1; specparam tpd_A12_DQ10 =1; specparam tpd_A12_DQ11 =1; specparam tpd_A12_DQ12 =1; specparam tpd_A12_DQ13 =1; specparam tpd_A12_DQ14 =1; specparam tpd_A12_DQ15 =1; specparam tpd_A13_DQ0 =1; specparam tpd_A13_DQ1 =1; specparam tpd_A13_DQ2 =1; specparam tpd_A13_DQ3 =1; specparam tpd_A13_DQ4 =1; specparam tpd_A13_DQ5 =1; specparam tpd_A13_DQ6 =1; specparam tpd_A13_DQ7 =1; specparam tpd_A13_DQ8 =1; specparam tpd_A13_DQ9 =1; specparam tpd_A13_DQ10 =1; specparam tpd_A13_DQ11 =1; specparam tpd_A13_DQ12 =1; specparam tpd_A13_DQ13 =1; specparam tpd_A13_DQ14 =1; specparam tpd_A13_DQ15 =1; specparam tpd_A14_DQ0 =1; specparam tpd_A14_DQ1 =1; specparam tpd_A14_DQ2 =1; specparam tpd_A14_DQ3 =1; specparam tpd_A14_DQ4 =1; specparam tpd_A14_DQ5 =1; specparam tpd_A14_DQ6 =1; specparam tpd_A14_DQ7 =1; specparam tpd_A14_DQ8 =1; specparam tpd_A14_DQ9 =1; specparam tpd_A14_DQ10 =1; specparam tpd_A14_DQ11 =1; specparam tpd_A14_DQ12 =1; specparam tpd_A14_DQ13 =1; specparam tpd_A14_DQ14 =1; specparam tpd_A14_DQ15 =1; specparam tpd_A15_DQ0 =1; specparam tpd_A15_DQ1 =1; specparam tpd_A15_DQ2 =1; specparam tpd_A15_DQ3 =1; specparam tpd_A15_DQ4 =1; specparam tpd_A15_DQ5 =1; specparam tpd_A15_DQ6 =1; specparam tpd_A15_DQ7 =1; specparam tpd_A15_DQ8 =1; specparam tpd_A15_DQ9 =1; specparam tpd_A15_DQ10 =1; specparam tpd_A15_DQ11 =1; specparam tpd_A15_DQ12 =1; specparam tpd_A15_DQ13 =1; specparam tpd_A15_DQ14 =1; specparam tpd_A15_DQ15 =1; specparam tpd_A16_DQ0 =1; specparam tpd_A16_DQ1 =1; specparam tpd_A16_DQ2 =1; specparam tpd_A16_DQ3 =1; specparam tpd_A16_DQ4 =1; specparam tpd_A16_DQ5 =1; specparam tpd_A16_DQ6 =1; specparam tpd_A16_DQ7 =1; specparam tpd_A16_DQ8 =1; specparam tpd_A16_DQ9 =1; specparam tpd_A16_DQ10 =1; specparam tpd_A16_DQ11 =1; specparam tpd_A16_DQ12 =1; specparam tpd_A16_DQ13 =1; specparam tpd_A16_DQ14 =1; specparam tpd_A16_DQ15 =1; specparam tpd_A17_DQ0 =1; specparam tpd_A17_DQ1 =1; specparam tpd_A17_DQ2 =1; specparam tpd_A17_DQ3 =1; specparam tpd_A17_DQ4 =1; specparam tpd_A17_DQ5 =1; specparam tpd_A17_DQ6 =1; specparam tpd_A17_DQ7 =1; specparam tpd_A17_DQ8 =1; specparam tpd_A17_DQ9 =1; specparam tpd_A17_DQ10 =1; specparam tpd_A17_DQ11 =1; specparam tpd_A17_DQ12 =1; specparam tpd_A17_DQ13 =1; specparam tpd_A17_DQ14 =1; specparam tpd_A17_DQ15 =1; specparam tpd_A18_DQ0 =1; specparam tpd_A18_DQ1 =1; specparam tpd_A18_DQ2 =1; specparam tpd_A18_DQ3 =1; specparam tpd_A18_DQ4 =1; specparam tpd_A18_DQ5 =1; specparam tpd_A18_DQ6 =1; specparam tpd_A18_DQ7 =1; specparam tpd_A18_DQ8 =1; specparam tpd_A18_DQ9 =1; specparam tpd_A18_DQ10 =1; specparam tpd_A18_DQ11 =1; specparam tpd_A18_DQ12 =1; specparam tpd_A18_DQ13 =1; specparam tpd_A18_DQ14 =1; specparam tpd_A18_DQ15 =1; specparam tpd_A19_DQ0 =1; specparam tpd_A19_DQ1 =1; specparam tpd_A19_DQ2 =1; specparam tpd_A19_DQ3 =1; specparam tpd_A19_DQ4 =1; specparam tpd_A19_DQ5 =1; specparam tpd_A19_DQ6 =1; specparam tpd_A19_DQ7 =1; specparam tpd_A19_DQ8 =1; specparam tpd_A19_DQ9 =1; specparam tpd_A19_DQ10 =1; specparam tpd_A19_DQ11 =1; specparam tpd_A19_DQ12 =1; specparam tpd_A19_DQ13 =1; specparam tpd_A19_DQ14 =1; specparam tpd_A19_DQ15 =1; specparam tpd_A20_DQ0 =1; specparam tpd_A20_DQ1 =1; specparam tpd_A20_DQ2 =1; specparam tpd_A20_DQ3 =1; specparam tpd_A20_DQ4 =1; specparam tpd_A20_DQ5 =1; specparam tpd_A20_DQ6 =1; specparam tpd_A20_DQ7 =1; specparam tpd_A20_DQ8 =1; specparam tpd_A20_DQ9 =1; specparam tpd_A20_DQ10 =1; specparam tpd_A20_DQ11 =1; specparam tpd_A20_DQ12 =1; specparam tpd_A20_DQ13 =1; specparam tpd_A20_DQ14 =1; specparam tpd_A20_DQ15 =1; specparam tpd_A21_DQ0 =1; specparam tpd_A21_DQ1 =1; specparam tpd_A21_DQ2 =1; specparam tpd_A21_DQ3 =1; specparam tpd_A21_DQ4 =1; specparam tpd_A21_DQ5 =1; specparam tpd_A21_DQ6 =1; specparam tpd_A21_DQ7 =1; specparam tpd_A21_DQ8 =1; specparam tpd_A21_DQ9 =1; specparam tpd_A21_DQ10 =1; specparam tpd_A21_DQ11 =1; specparam tpd_A21_DQ12 =1; specparam tpd_A21_DQ13 =1; specparam tpd_A21_DQ14 =1; specparam tpd_A21_DQ15 =1; specparam tpd_A22_DQ0 =1; specparam tpd_A22_DQ1 =1; specparam tpd_A22_DQ2 =1; specparam tpd_A22_DQ3 =1; specparam tpd_A22_DQ4 =1; specparam tpd_A22_DQ5 =1; specparam tpd_A22_DQ6 =1; specparam tpd_A22_DQ7 =1; specparam tpd_A22_DQ8 =1; specparam tpd_A22_DQ9 =1; specparam tpd_A22_DQ10 =1; specparam tpd_A22_DQ11 =1; specparam tpd_A22_DQ12 =1; specparam tpd_A22_DQ13 =1; specparam tpd_A22_DQ14 =1; specparam tpd_A22_DQ15 =1; specparam tpd_A23_DQ0 =1; specparam tpd_A23_DQ1 =1; specparam tpd_A23_DQ2 =1; specparam tpd_A23_DQ3 =1; specparam tpd_A23_DQ4 =1; specparam tpd_A23_DQ5 =1; specparam tpd_A23_DQ6 =1; specparam tpd_A23_DQ7 =1; specparam tpd_A23_DQ8 =1; specparam tpd_A23_DQ9 =1; specparam tpd_A23_DQ10 =1; specparam tpd_A23_DQ11 =1; specparam tpd_A23_DQ12 =1; specparam tpd_A23_DQ13 =1; specparam tpd_A23_DQ14 =1; specparam tpd_A23_DQ15 =1; specparam tpd_A24_DQ0 =1; specparam tpd_A24_DQ1 =1; specparam tpd_A24_DQ2 =1; specparam tpd_A24_DQ3 =1; specparam tpd_A24_DQ4 =1; specparam tpd_A24_DQ5 =1; specparam tpd_A24_DQ6 =1; specparam tpd_A24_DQ7 =1; specparam tpd_A24_DQ8 =1; specparam tpd_A24_DQ9 =1; specparam tpd_A24_DQ10 =1; specparam tpd_A24_DQ11 =1; specparam tpd_A24_DQ12 =1; specparam tpd_A24_DQ13 =1; specparam tpd_A24_DQ14 =1; specparam tpd_A24_DQ15 =1; specparam tpd_CENeg_DQ0 =1; specparam tpd_CENeg_DQ1 =1; specparam tpd_CENeg_DQ2 =1; specparam tpd_CENeg_DQ3 =1; specparam tpd_CENeg_DQ4 =1; specparam tpd_CENeg_DQ5 =1; specparam tpd_CENeg_DQ6 =1; specparam tpd_CENeg_DQ7 =1; specparam tpd_CENeg_DQ8 =1; specparam tpd_CENeg_DQ9 =1; specparam tpd_CENeg_DQ10 =1; specparam tpd_CENeg_DQ11 =1; specparam tpd_CENeg_DQ12 =1; specparam tpd_CENeg_DQ13 =1; specparam tpd_CENeg_DQ14 =1; specparam tpd_CENeg_DQ15 =1; specparam tpd_OENeg_DQ0 =1; specparam tpd_OENeg_DQ1 =1; specparam tpd_OENeg_DQ2 =1; specparam tpd_OENeg_DQ3 =1; specparam tpd_OENeg_DQ4 =1; specparam tpd_OENeg_DQ5 =1; specparam tpd_OENeg_DQ6 =1; specparam tpd_OENeg_DQ7 =1; specparam tpd_OENeg_DQ8 =1; specparam tpd_OENeg_DQ9 =1; specparam tpd_OENeg_DQ10 =1; specparam tpd_OENeg_DQ11 =1; specparam tpd_OENeg_DQ12 =1; specparam tpd_OENeg_DQ13 =1; specparam tpd_OENeg_DQ14 =1; specparam tpd_OENeg_DQ15 =1; specparam tpd_CLK_DQ0 =1; specparam tpd_CLK_DQ1 =1; specparam tpd_CLK_DQ2 =1; specparam tpd_CLK_DQ3 =1; specparam tpd_CLK_DQ4 =1; specparam tpd_CLK_DQ5 =1; specparam tpd_CLK_DQ6 =1; specparam tpd_CLK_DQ7 =1; specparam tpd_CLK_DQ8 =1; specparam tpd_CLK_DQ9 =1; specparam tpd_CLK_DQ10 =1; specparam tpd_CLK_DQ11 =1; specparam tpd_CLK_DQ12 =1; specparam tpd_CLK_DQ13 =1; specparam tpd_CLK_DQ14 =1; specparam tpd_CLK_DQ15 =1; specparam tpd_CE0Neg_WAITOut =1; specparam tpd_OE0Neg_WAITOut =1; specparam tpd_CLK_WAITOut =1; //tsetup values specparam tsetup_A1_ADVNeg =1; specparam tsetup_A2_ADVNeg =1; specparam tsetup_A3_ADVNeg =1; specparam tsetup_A4_ADVNeg =1; specparam tsetup_A5_ADVNeg =1; specparam tsetup_A6_ADVNeg =1; specparam tsetup_A7_ADVNeg =1; specparam tsetup_A8_ADVNeg =1; specparam tsetup_A9_ADVNeg =1; specparam tsetup_A10_ADVNeg =1; specparam tsetup_A11_ADVNeg =1; specparam tsetup_A12_ADVNeg =1; specparam tsetup_A13_ADVNeg =1; specparam tsetup_A14_ADVNeg =1; specparam tsetup_A15_ADVNeg =1; specparam tsetup_A16_ADVNeg =1; specparam tsetup_A17_ADVNeg =1; specparam tsetup_A18_ADVNeg =1; specparam tsetup_A19_ADVNeg =1; specparam tsetup_A20_ADVNeg =1; specparam tsetup_A21_ADVNeg =1; specparam tsetup_A22_ADVNeg =1; specparam tsetup_A23_ADVNeg =1; specparam tsetup_A24_ADVNeg =1; specparam tsetup_CENeg_ADVNeg =1; specparam tsetup_RSTNeg_ADVNeg =1; specparam tsetup_CLK_ADVNeg =1; specparam tsetup_WENeg_ADVNeg =1; specparam tsetup_A1_CLK =1; specparam tsetup_A2_CLK =1; specparam tsetup_A3_CLK =1; specparam tsetup_A4_CLK =1; specparam tsetup_A5_CLK =1; specparam tsetup_A6_CLK =1; specparam tsetup_A7_CLK =1; specparam tsetup_A8_CLK =1; specparam tsetup_A9_CLK =1; specparam tsetup_A10_CLK =1; specparam tsetup_A11_CLK =1; specparam tsetup_A12_CLK =1; specparam tsetup_A13_CLK =1; specparam tsetup_A14_CLK =1; specparam tsetup_A15_CLK =1; specparam tsetup_A16_CLK =1; specparam tsetup_A17_CLK =1; specparam tsetup_A18_CLK =1; specparam tsetup_A19_CLK =1; specparam tsetup_A20_CLK =1; specparam tsetup_A21_CLK =1; specparam tsetup_A22_CLK =1; specparam tsetup_A23_CLK =1; specparam tsetup_A24_CLK =1; specparam tsetup_ADVNeg_CLK =1; specparam tsetup_CENeg_CLK =1; specparam tsetup_WENeg_CLK =1; specparam tsetup_CENeg_WENeg =1; specparam tsetup_DQ0_WENeg =1; specparam tsetup_DQ1_WENeg =1; specparam tsetup_DQ2_WENeg =1; specparam tsetup_DQ3_WENeg =1; specparam tsetup_DQ4_WENeg =1; specparam tsetup_DQ5_WENeg =1; specparam tsetup_DQ6_WENeg =1; specparam tsetup_DQ7_WENeg =1; specparam tsetup_DQ8_WENeg =1; specparam tsetup_DQ9_WENeg =1; specparam tsetup_DQ10_WENeg =1; specparam tsetup_DQ11_WENeg =1; specparam tsetup_DQ12_WENeg =1; specparam tsetup_DQ13_WENeg =1; specparam tsetup_DQ14_WENeg =1; specparam tsetup_DQ15_WENeg =1; specparam tsetup_A1_WENeg =1; specparam tsetup_A2_WENeg =1; specparam tsetup_A3_WENeg =1; specparam tsetup_A4_WENeg =1; specparam tsetup_A5_WENeg =1; specparam tsetup_A6_WENeg =1; specparam tsetup_A7_WENeg =1; specparam tsetup_A8_WENeg =1; specparam tsetup_A9_WENeg =1; specparam tsetup_A10_WENeg =1; specparam tsetup_A11_WENeg =1; specparam tsetup_A12_WENeg =1; specparam tsetup_A13_WENeg =1; specparam tsetup_A14_WENeg =1; specparam tsetup_A15_WENeg =1; specparam tsetup_A16_WENeg =1; specparam tsetup_A17_WENeg =1; specparam tsetup_A18_WENeg =1; specparam tsetup_A19_WENeg =1; specparam tsetup_A20_WENeg =1; specparam tsetup_A21_WENeg =1; specparam tsetup_A22_WENeg =1; specparam tsetup_A23_WENeg =1; specparam tsetup_A24_WENeg =1; specparam tsetup_WPNeg_WENeg =1; specparam tsetup_ADVNeg_WENeg =1; specparam tsetup_CLK_WENeg =1; specparam tsetup_WENeg_OENeg =1; // thold values: hold times specparam thold_A1_ADVNeg =1; specparam thold_A2_ADVNeg =1; specparam thold_A3_ADVNeg =1; specparam thold_A4_ADVNeg =1; specparam thold_A5_ADVNeg =1; specparam thold_A6_ADVNeg =1; specparam thold_A7_ADVNeg =1; specparam thold_A8_ADVNeg =1; specparam thold_A9_ADVNeg =1; specparam thold_A10_ADVNeg =1; specparam thold_A11_ADVNeg =1; specparam thold_A12_ADVNeg =1; specparam thold_A13_ADVNeg =1; specparam thold_A14_ADVNeg =1; specparam thold_A15_ADVNeg =1; specparam thold_A16_ADVNeg =1; specparam thold_A17_ADVNeg =1; specparam thold_A18_ADVNeg =1; specparam thold_A19_ADVNeg =1; specparam thold_A20_ADVNeg =1; specparam thold_A21_ADVNeg =1; specparam thold_A22_ADVNeg =1; specparam thold_A23_ADVNeg =1; specparam thold_A24_ADVNeg =1; specparam thold_A1_CLK =1; specparam thold_A2_CLK =1; specparam thold_A3_CLK =1; specparam thold_A4_CLK =1; specparam thold_A5_CLK =1; specparam thold_A6_CLK =1; specparam thold_A7_CLK =1; specparam thold_A8_CLK =1; specparam thold_A9_CLK =1; specparam thold_A10_CLK =1; specparam thold_A11_CLK =1; specparam thold_A12_CLK =1; specparam thold_A13_CLK =1; specparam thold_A14_CLK =1; specparam thold_A15_CLK =1; specparam thold_A16_CLK =1; specparam thold_A17_CLK =1; specparam thold_A18_CLK =1; specparam thold_A19_CLK =1; specparam thold_A20_CLK =1; specparam thold_A21_CLK =1; specparam thold_A22_CLK =1; specparam thold_A23_CLK =1; specparam thold_A24_CLK =1; specparam thold_CENeg_WENeg =1; specparam thold_DQ0_WENeg =1; specparam thold_DQ1_WENeg =1; specparam thold_DQ2_WENeg =1; specparam thold_DQ3_WENeg =1; specparam thold_DQ4_WENeg =1; specparam thold_DQ5_WENeg =1; specparam thold_DQ6_WENeg =1; specparam thold_DQ7_WENeg =1; specparam thold_DQ8_WENeg =1; specparam thold_DQ9_WENeg =1; specparam thold_DQ10_WENeg =1; specparam thold_DQ11_WENeg =1; specparam thold_DQ12_WENeg =1; specparam thold_DQ13_WENeg =1; specparam thold_DQ14_WENeg =1; specparam thold_DQ15_WENeg =1; specparam thold_A1_WENeg =1; specparam thold_A2_WENeg =1; specparam thold_A3_WENeg =1; specparam thold_A4_WENeg =1; specparam thold_A5_WENeg =1; specparam thold_A6_WENeg =1; specparam thold_A7_WENeg =1; specparam thold_A8_WENeg =1; specparam thold_A9_WENeg =1; specparam thold_A10_WENeg =1; specparam thold_A11_WENeg =1; specparam thold_A12_WENeg =1; specparam thold_A13_WENeg =1; specparam thold_A14_WENeg =1; specparam thold_A15_WENeg =1; specparam thold_A16_WENeg =1; specparam thold_A17_WENeg =1; specparam thold_A18_WENeg =1; specparam thold_A19_WENeg =1; specparam thold_A20_WENeg =1; specparam thold_A21_WENeg =1; specparam thold_A22_WENeg =1; specparam thold_A23_WENeg =1; specparam thold_A24_WENeg =1; //tpw values specparam tpw_CENeg_posedge = 1; specparam tpw_ADVNeg_posedge = 1; specparam tpw_ADVNeg_negedge = 1; specparam tpw_WENeg_negedge = 1; specparam tpw_WENeg_posedge = 1; specparam tpw_RSTNeg_negedge = 1; specparam tpw_CLK_posedge = 1; specparam tpw_CLK_negedge = 1; specparam tperiod_CLK = 1; // tdevice values: values for internal delays `ifdef SPEEDSIM // Program BUffProgram specparam tdevice_BuffProgram = 88000; // Program BUffProgram specparam tdevice_BuffProgram9V = 68000; // Program BEFP specparam tdevice_BEFP = 32000; // Program EraseParameter specparam tdevice_EraseParameter_td = 2500; // Program EraseMain specparam tdevice_EraseMain_td = 4000; `else // Program BUffProgram specparam tdevice_BuffProgram = 880000; // Program BUffProgram specparam tdevice_BuffProgram9V = 680000; // Program BEFP specparam tdevice_BEFP = 320000; // Program EraseParameter specparam tdevice_EraseParameter_td = 2500000; // Program EraseMain specparam tdevice_EraseMain_td = 4000000; `endif // SPEEDSIM // Program Word specparam tdevice_WordProgram = 200000; // Program Word specparam tdevice_WordProgram9V = 190000; // Program BEFPsetup specparam tdevice_BEFPsetup = 5000; // Program ProgramSuspend specparam tdevice_ProgramSuspend = 25000; // Program ProgramSuspend specparam tdevice_EraseSuspend = 25000; // Reset during Program or Erase specparam tdevice_RstDuringErsPrg = 25000; /////////////////////////////////////////////////////////////////////////////// // Input Port Delays don't require Verilog description /////////////////////////////////////////////////////////////////////////////// // Path delays // /////////////////////////////////////////////////////////////////////////////// if (InitialPageAccess) (A1 *> DQ0) = tpd_A1_DQ0; if (InitialPageAccess) (A1 *> DQ1) = tpd_A1_DQ1; if (InitialPageAccess) (A1 *> DQ2) = tpd_A1_DQ2; if (InitialPageAccess) (A1 *> DQ3) = tpd_A1_DQ3; if (InitialPageAccess) (A1 *> DQ4) = tpd_A1_DQ4; if (InitialPageAccess) (A1 *> DQ5) = tpd_A1_DQ5; if (InitialPageAccess) (A1 *> DQ6) = tpd_A1_DQ6; if (InitialPageAccess) (A1 *> DQ7) = tpd_A1_DQ7; if (InitialPageAccess) (A1 *> DQ8) = tpd_A1_DQ8; if (InitialPageAccess) (A1 *> DQ9) = tpd_A1_DQ9; if (InitialPageAccess) (A1 *> DQ10) = tpd_A1_DQ10; if (InitialPageAccess) (A1 *> DQ11) = tpd_A1_DQ11; if (InitialPageAccess) (A1 *> DQ12) = tpd_A1_DQ12; if (InitialPageAccess) (A1 *> DQ13) = tpd_A1_DQ13; if (InitialPageAccess) (A1 *> DQ14) = tpd_A1_DQ14; if (InitialPageAccess) (A1 *> DQ15) = tpd_A1_DQ15; if (InitialPageAccess) (A2 *> DQ0) = tpd_A2_DQ0; if (InitialPageAccess) (A2 *> DQ1) = tpd_A2_DQ1; if (InitialPageAccess) (A2 *> DQ2) = tpd_A2_DQ2; if (InitialPageAccess) (A2 *> DQ3) = tpd_A2_DQ3; if (InitialPageAccess) (A2 *> DQ4) = tpd_A2_DQ4; if (InitialPageAccess) (A2 *> DQ5) = tpd_A2_DQ5; if (InitialPageAccess) (A2 *> DQ6) = tpd_A2_DQ6; if (InitialPageAccess) (A2 *> DQ7) = tpd_A2_DQ7; if (InitialPageAccess) (A2 *> DQ8) = tpd_A2_DQ8; if (InitialPageAccess) (A2 *> DQ9) = tpd_A2_DQ9; if (InitialPageAccess) (A2 *> DQ10) = tpd_A2_DQ10; if (InitialPageAccess) (A2 *> DQ11) = tpd_A2_DQ11; if (InitialPageAccess) (A2 *> DQ12) = tpd_A2_DQ12; if (InitialPageAccess) (A2 *> DQ13) = tpd_A2_DQ13; if (InitialPageAccess) (A2 *> DQ14) = tpd_A2_DQ14; if (InitialPageAccess) (A2 *> DQ15) = tpd_A2_DQ15; if (InitialPageAccess) (A3 *> DQ0) = tpd_A3_DQ0; if (InitialPageAccess) (A3 *> DQ1) = tpd_A3_DQ1; if (InitialPageAccess) (A3 *> DQ2) = tpd_A3_DQ2; if (InitialPageAccess) (A3 *> DQ3) = tpd_A3_DQ3; if (InitialPageAccess) (A3 *> DQ4) = tpd_A3_DQ4; if (InitialPageAccess) (A3 *> DQ5) = tpd_A3_DQ5; if (InitialPageAccess) (A3 *> DQ6) = tpd_A3_DQ6; if (InitialPageAccess) (A3 *> DQ7) = tpd_A3_DQ7; if (InitialPageAccess) (A3 *> DQ8) = tpd_A3_DQ8; if (InitialPageAccess) (A3 *> DQ9) = tpd_A3_DQ9; if (InitialPageAccess) (A3 *> DQ10) = tpd_A3_DQ10; if (InitialPageAccess) (A3 *> DQ11) = tpd_A3_DQ11; if (InitialPageAccess) (A3 *> DQ12) = tpd_A3_DQ12; if (InitialPageAccess) (A3 *> DQ13) = tpd_A3_DQ13; if (InitialPageAccess) (A3 *> DQ14) = tpd_A3_DQ14; if (InitialPageAccess) (A3 *> DQ15) = tpd_A3_DQ15; if (InitialPageAccess) (A4 *> DQ0) = tpd_A4_DQ0; if (InitialPageAccess) (A4 *> DQ1) = tpd_A4_DQ1; if (InitialPageAccess) (A4 *> DQ2) = tpd_A4_DQ2; if (InitialPageAccess) (A4 *> DQ3) = tpd_A4_DQ3; if (InitialPageAccess) (A4 *> DQ4) = tpd_A4_DQ4; if (InitialPageAccess) (A4 *> DQ5) = tpd_A4_DQ5; if (InitialPageAccess) (A4 *> DQ6) = tpd_A4_DQ6; if (InitialPageAccess) (A4 *> DQ7) = tpd_A4_DQ7; if (InitialPageAccess) (A4 *> DQ8) = tpd_A4_DQ8; if (InitialPageAccess) (A4 *> DQ9) = tpd_A4_DQ9; if (InitialPageAccess) (A4 *> DQ10) = tpd_A4_DQ10; if (InitialPageAccess) (A4 *> DQ11) = tpd_A4_DQ11; if (InitialPageAccess) (A4 *> DQ12) = tpd_A4_DQ12; if (InitialPageAccess) (A4 *> DQ13) = tpd_A4_DQ13; if (InitialPageAccess) (A4 *> DQ14) = tpd_A4_DQ14; if (InitialPageAccess) (A4 *> DQ15) = tpd_A4_DQ15; if (InitialPageAccess) (A5 *> DQ0) = tpd_A5_DQ0; if (InitialPageAccess) (A5 *> DQ1) = tpd_A5_DQ1; if (InitialPageAccess) (A5 *> DQ2) = tpd_A5_DQ2; if (InitialPageAccess) (A5 *> DQ3) = tpd_A5_DQ3; if (InitialPageAccess) (A5 *> DQ4) = tpd_A5_DQ4; if (InitialPageAccess) (A5 *> DQ5) = tpd_A5_DQ5; if (InitialPageAccess) (A5 *> DQ6) = tpd_A5_DQ6; if (InitialPageAccess) (A5 *> DQ7) = tpd_A5_DQ7; if (InitialPageAccess) (A5 *> DQ8) = tpd_A5_DQ8; if (InitialPageAccess) (A5 *> DQ9) = tpd_A5_DQ9; if (InitialPageAccess) (A5 *> DQ10) = tpd_A5_DQ10; if (InitialPageAccess) (A5 *> DQ11) = tpd_A5_DQ11; if (InitialPageAccess) (A5 *> DQ12) = tpd_A5_DQ12; if (InitialPageAccess) (A5 *> DQ13) = tpd_A5_DQ13; if (InitialPageAccess) (A5 *> DQ14) = tpd_A5_DQ14; if (InitialPageAccess) (A5 *> DQ15) = tpd_A5_DQ15; if (InitialPageAccess) (A6 *> DQ0) = tpd_A6_DQ0; if (InitialPageAccess) (A6 *> DQ1) = tpd_A6_DQ1; if (InitialPageAccess) (A6 *> DQ2) = tpd_A6_DQ2; if (InitialPageAccess) (A6 *> DQ3) = tpd_A6_DQ3; if (InitialPageAccess) (A6 *> DQ4) = tpd_A6_DQ4; if (InitialPageAccess) (A6 *> DQ5) = tpd_A6_DQ5; if (InitialPageAccess) (A6 *> DQ6) = tpd_A6_DQ6; if (InitialPageAccess) (A6 *> DQ7) = tpd_A6_DQ7; if (InitialPageAccess) (A6 *> DQ8) = tpd_A6_DQ8; if (InitialPageAccess) (A6 *> DQ9) = tpd_A6_DQ9; if (InitialPageAccess) (A6 *> DQ10) = tpd_A6_DQ10; if (InitialPageAccess) (A6 *> DQ11) = tpd_A6_DQ11; if (InitialPageAccess) (A6 *> DQ12) = tpd_A6_DQ12; if (InitialPageAccess) (A6 *> DQ13) = tpd_A6_DQ13; if (InitialPageAccess) (A6 *> DQ14) = tpd_A6_DQ14; if (InitialPageAccess) (A6 *> DQ15) = tpd_A6_DQ15; if (InitialPageAccess) (A7 *> DQ0) = tpd_A7_DQ0; if (InitialPageAccess) (A7 *> DQ1) = tpd_A7_DQ1; if (InitialPageAccess) (A7 *> DQ2) = tpd_A7_DQ2; if (InitialPageAccess) (A7 *> DQ3) = tpd_A7_DQ3; if (InitialPageAccess) (A7 *> DQ4) = tpd_A7_DQ4; if (InitialPageAccess) (A7 *> DQ5) = tpd_A7_DQ5; if (InitialPageAccess) (A7 *> DQ6) = tpd_A7_DQ6; if (InitialPageAccess) (A7 *> DQ7) = tpd_A7_DQ7; if (InitialPageAccess) (A7 *> DQ8) = tpd_A7_DQ8; if (InitialPageAccess) (A7 *> DQ9) = tpd_A7_DQ9; if (InitialPageAccess) (A7 *> DQ10) = tpd_A7_DQ10; if (InitialPageAccess) (A7 *> DQ11) = tpd_A7_DQ11; if (InitialPageAccess) (A7 *> DQ12) = tpd_A7_DQ12; if (InitialPageAccess) (A7 *> DQ13) = tpd_A7_DQ13; if (InitialPageAccess) (A7 *> DQ14) = tpd_A7_DQ14; if (InitialPageAccess) (A7 *> DQ15) = tpd_A7_DQ15; if (InitialPageAccess) (A8 *> DQ0) = tpd_A8_DQ0; if (InitialPageAccess) (A8 *> DQ1) = tpd_A8_DQ1; if (InitialPageAccess) (A8 *> DQ2) = tpd_A8_DQ2; if (InitialPageAccess) (A8 *> DQ3) = tpd_A8_DQ3; if (InitialPageAccess) (A8 *> DQ4) = tpd_A8_DQ4; if (InitialPageAccess) (A8 *> DQ5) = tpd_A8_DQ5; if (InitialPageAccess) (A8 *> DQ6) = tpd_A8_DQ6; if (InitialPageAccess) (A8 *> DQ7) = tpd_A8_DQ7; if (InitialPageAccess) (A8 *> DQ8) = tpd_A8_DQ8; if (InitialPageAccess) (A8 *> DQ9) = tpd_A8_DQ9; if (InitialPageAccess) (A8 *> DQ10) = tpd_A8_DQ10; if (InitialPageAccess) (A8 *> DQ11) = tpd_A8_DQ11; if (InitialPageAccess) (A8 *> DQ12) = tpd_A8_DQ12; if (InitialPageAccess) (A8 *> DQ13) = tpd_A8_DQ13; if (InitialPageAccess) (A8 *> DQ14) = tpd_A8_DQ14; if (InitialPageAccess) (A8 *> DQ15) = tpd_A8_DQ15; if (InitialPageAccess) (A9 *> DQ0) = tpd_A9_DQ0; if (InitialPageAccess) (A9 *> DQ1) = tpd_A9_DQ1; if (InitialPageAccess) (A9 *> DQ2) = tpd_A9_DQ2; if (InitialPageAccess) (A9 *> DQ3) = tpd_A9_DQ3; if (InitialPageAccess) (A9 *> DQ4) = tpd_A9_DQ4; if (InitialPageAccess) (A9 *> DQ5) = tpd_A9_DQ5; if (InitialPageAccess) (A9 *> DQ6) = tpd_A9_DQ6; if (InitialPageAccess) (A9 *> DQ7) = tpd_A9_DQ7; if (InitialPageAccess) (A9 *> DQ8) = tpd_A9_DQ8; if (InitialPageAccess) (A9 *> DQ9) = tpd_A9_DQ9; if (InitialPageAccess) (A9 *> DQ10) = tpd_A9_DQ10; if (InitialPageAccess) (A9 *> DQ11) = tpd_A9_DQ11; if (InitialPageAccess) (A9 *> DQ12) = tpd_A9_DQ12; if (InitialPageAccess) (A9 *> DQ13) = tpd_A9_DQ13; if (InitialPageAccess) (A9 *> DQ14) = tpd_A9_DQ14; if (InitialPageAccess) (A9 *> DQ15) = tpd_A9_DQ15; if (InitialPageAccess) (A10 *> DQ0) = tpd_A10_DQ0; if (InitialPageAccess) (A10 *> DQ1) = tpd_A10_DQ1; if (InitialPageAccess) (A10 *> DQ2) = tpd_A10_DQ2; if (InitialPageAccess) (A10 *> DQ3) = tpd_A10_DQ3; if (InitialPageAccess) (A10 *> DQ4) = tpd_A10_DQ4; if (InitialPageAccess) (A10 *> DQ5) = tpd_A10_DQ5; if (InitialPageAccess) (A10 *> DQ6) = tpd_A10_DQ6; if (InitialPageAccess) (A10 *> DQ7) = tpd_A10_DQ7; if (InitialPageAccess) (A10 *> DQ8) = tpd_A10_DQ8; if (InitialPageAccess) (A10 *> DQ9) = tpd_A10_DQ9; if (InitialPageAccess) (A10 *> DQ10) = tpd_A10_DQ10; if (InitialPageAccess) (A10 *> DQ11) = tpd_A10_DQ11; if (InitialPageAccess) (A10 *> DQ12) = tpd_A10_DQ12; if (InitialPageAccess) (A10 *> DQ13) = tpd_A10_DQ13; if (InitialPageAccess) (A10 *> DQ14) = tpd_A10_DQ14; if (InitialPageAccess) (A10 *> DQ15) = tpd_A10_DQ15; if (InitialPageAccess) (A11 *> DQ0) = tpd_A11_DQ0; if (InitialPageAccess) (A11 *> DQ1) = tpd_A11_DQ1; if (InitialPageAccess) (A11 *> DQ2) = tpd_A11_DQ2; if (InitialPageAccess) (A11 *> DQ3) = tpd_A11_DQ3; if (InitialPageAccess) (A11 *> DQ4) = tpd_A11_DQ4; if (InitialPageAccess) (A11 *> DQ5) = tpd_A11_DQ5; if (InitialPageAccess) (A11 *> DQ6) = tpd_A11_DQ6; if (InitialPageAccess) (A11 *> DQ7) = tpd_A11_DQ7; if (InitialPageAccess) (A11 *> DQ8) = tpd_A11_DQ8; if (InitialPageAccess) (A11 *> DQ9) = tpd_A11_DQ9; if (InitialPageAccess) (A11 *> DQ10) = tpd_A11_DQ10; if (InitialPageAccess) (A11 *> DQ11) = tpd_A11_DQ11; if (InitialPageAccess) (A11 *> DQ12) = tpd_A11_DQ12; if (InitialPageAccess) (A11 *> DQ13) = tpd_A11_DQ13; if (InitialPageAccess) (A11 *> DQ14) = tpd_A11_DQ14; if (InitialPageAccess) (A11 *> DQ15) = tpd_A11_DQ15; if (InitialPageAccess) (A12 *> DQ0) = tpd_A12_DQ0; if (InitialPageAccess) (A12 *> DQ1) = tpd_A12_DQ1; if (InitialPageAccess) (A12 *> DQ2) = tpd_A12_DQ2; if (InitialPageAccess) (A12 *> DQ3) = tpd_A12_DQ3; if (InitialPageAccess) (A12 *> DQ4) = tpd_A12_DQ4; if (InitialPageAccess) (A12 *> DQ5) = tpd_A12_DQ5; if (InitialPageAccess) (A12 *> DQ6) = tpd_A12_DQ6; if (InitialPageAccess) (A12 *> DQ7) = tpd_A12_DQ7; if (InitialPageAccess) (A12 *> DQ8) = tpd_A12_DQ8; if (InitialPageAccess) (A12 *> DQ9) = tpd_A12_DQ9; if (InitialPageAccess) (A12 *> DQ10) = tpd_A12_DQ10; if (InitialPageAccess) (A12 *> DQ11) = tpd_A12_DQ11; if (InitialPageAccess) (A12 *> DQ12) = tpd_A12_DQ12; if (InitialPageAccess) (A12 *> DQ13) = tpd_A12_DQ13; if (InitialPageAccess) (A12 *> DQ14) = tpd_A12_DQ14; if (InitialPageAccess) (A12 *> DQ15) = tpd_A12_DQ15; if (InitialPageAccess) (A13 *> DQ0) = tpd_A13_DQ0; if (InitialPageAccess) (A13 *> DQ1) = tpd_A13_DQ1; if (InitialPageAccess) (A13 *> DQ2) = tpd_A13_DQ2; if (InitialPageAccess) (A13 *> DQ3) = tpd_A13_DQ3; if (InitialPageAccess) (A13 *> DQ4) = tpd_A13_DQ4; if (InitialPageAccess) (A13 *> DQ5) = tpd_A13_DQ5; if (InitialPageAccess) (A13 *> DQ6) = tpd_A13_DQ6; if (InitialPageAccess) (A13 *> DQ7) = tpd_A13_DQ7; if (InitialPageAccess) (A13 *> DQ8) = tpd_A13_DQ8; if (InitialPageAccess) (A13 *> DQ9) = tpd_A13_DQ9; if (InitialPageAccess) (A13 *> DQ10) = tpd_A13_DQ10; if (InitialPageAccess) (A13 *> DQ11) = tpd_A13_DQ11; if (InitialPageAccess) (A13 *> DQ12) = tpd_A13_DQ12; if (InitialPageAccess) (A13 *> DQ13) = tpd_A13_DQ13; if (InitialPageAccess) (A13 *> DQ14) = tpd_A13_DQ14; if (InitialPageAccess) (A13 *> DQ15) = tpd_A13_DQ15; if (InitialPageAccess) (A14 *> DQ0) = tpd_A14_DQ0; if (InitialPageAccess) (A14 *> DQ1) = tpd_A14_DQ1; if (InitialPageAccess) (A14 *> DQ2) = tpd_A14_DQ2; if (InitialPageAccess) (A14 *> DQ3) = tpd_A14_DQ3; if (InitialPageAccess) (A14 *> DQ4) = tpd_A14_DQ4; if (InitialPageAccess) (A14 *> DQ5) = tpd_A14_DQ5; if (InitialPageAccess) (A14 *> DQ6) = tpd_A14_DQ6; if (InitialPageAccess) (A14 *> DQ7) = tpd_A14_DQ7; if (InitialPageAccess) (A14 *> DQ8) = tpd_A14_DQ8; if (InitialPageAccess) (A14 *> DQ9) = tpd_A14_DQ9; if (InitialPageAccess) (A14 *> DQ10) = tpd_A14_DQ10; if (InitialPageAccess) (A14 *> DQ11) = tpd_A14_DQ11; if (InitialPageAccess) (A14 *> DQ12) = tpd_A14_DQ12; if (InitialPageAccess) (A14 *> DQ13) = tpd_A14_DQ13; if (InitialPageAccess) (A14 *> DQ14) = tpd_A14_DQ14; if (InitialPageAccess) (A14 *> DQ15) = tpd_A14_DQ15; if (InitialPageAccess) (A15 *> DQ0) = tpd_A15_DQ0; if (InitialPageAccess) (A15 *> DQ1) = tpd_A15_DQ1; if (InitialPageAccess) (A15 *> DQ2) = tpd_A15_DQ2; if (InitialPageAccess) (A15 *> DQ3) = tpd_A15_DQ3; if (InitialPageAccess) (A15 *> DQ4) = tpd_A15_DQ4; if (InitialPageAccess) (A15 *> DQ5) = tpd_A15_DQ5; if (InitialPageAccess) (A15 *> DQ6) = tpd_A15_DQ6; if (InitialPageAccess) (A15 *> DQ7) = tpd_A15_DQ7; if (InitialPageAccess) (A15 *> DQ8) = tpd_A15_DQ8; if (InitialPageAccess) (A15 *> DQ9) = tpd_A15_DQ9; if (InitialPageAccess) (A15 *> DQ10) = tpd_A15_DQ10; if (InitialPageAccess) (A15 *> DQ11) = tpd_A15_DQ11; if (InitialPageAccess) (A15 *> DQ12) = tpd_A15_DQ12; if (InitialPageAccess) (A15 *> DQ13) = tpd_A15_DQ13; if (InitialPageAccess) (A15 *> DQ14) = tpd_A15_DQ14; if (InitialPageAccess) (A15 *> DQ15) = tpd_A15_DQ15; if (InitialPageAccess) (A16 *> DQ0) = tpd_A16_DQ0; if (InitialPageAccess) (A16 *> DQ1) = tpd_A16_DQ1; if (InitialPageAccess) (A16 *> DQ2) = tpd_A16_DQ2; if (InitialPageAccess) (A16 *> DQ3) = tpd_A16_DQ3; if (InitialPageAccess) (A16 *> DQ4) = tpd_A16_DQ4; if (InitialPageAccess) (A16 *> DQ5) = tpd_A16_DQ5; if (InitialPageAccess) (A16 *> DQ6) = tpd_A16_DQ6; if (InitialPageAccess) (A16 *> DQ7) = tpd_A16_DQ7; if (InitialPageAccess) (A16 *> DQ8) = tpd_A16_DQ8; if (InitialPageAccess) (A16 *> DQ9) = tpd_A16_DQ9; if (InitialPageAccess) (A16 *> DQ10) = tpd_A16_DQ10; if (InitialPageAccess) (A16 *> DQ11) = tpd_A16_DQ11; if (InitialPageAccess) (A16 *> DQ12) = tpd_A16_DQ12; if (InitialPageAccess) (A16 *> DQ13) = tpd_A16_DQ13; if (InitialPageAccess) (A16 *> DQ14) = tpd_A16_DQ14; if (InitialPageAccess) (A16 *> DQ15) = tpd_A16_DQ15; if (InitialPageAccess) (A17 *> DQ0) = tpd_A17_DQ0; if (InitialPageAccess) (A17 *> DQ1) = tpd_A17_DQ1; if (InitialPageAccess) (A17 *> DQ2) = tpd_A17_DQ2; if (InitialPageAccess) (A17 *> DQ3) = tpd_A17_DQ3; if (InitialPageAccess) (A17 *> DQ4) = tpd_A17_DQ4; if (InitialPageAccess) (A17 *> DQ5) = tpd_A17_DQ5; if (InitialPageAccess) (A17 *> DQ6) = tpd_A17_DQ6; if (InitialPageAccess) (A17 *> DQ7) = tpd_A17_DQ7; if (InitialPageAccess) (A17 *> DQ8) = tpd_A17_DQ8; if (InitialPageAccess) (A17 *> DQ9) = tpd_A17_DQ9; if (InitialPageAccess) (A17 *> DQ10) = tpd_A17_DQ10; if (InitialPageAccess) (A17 *> DQ11) = tpd_A17_DQ11; if (InitialPageAccess) (A17 *> DQ12) = tpd_A17_DQ12; if (InitialPageAccess) (A17 *> DQ13) = tpd_A17_DQ13; if (InitialPageAccess) (A17 *> DQ14) = tpd_A17_DQ14; if (InitialPageAccess) (A17 *> DQ15) = tpd_A17_DQ15; if (InitialPageAccess) (A18 *> DQ0) = tpd_A18_DQ0; if (InitialPageAccess) (A18 *> DQ1) = tpd_A18_DQ1; if (InitialPageAccess) (A18 *> DQ2) = tpd_A18_DQ2; if (InitialPageAccess) (A18 *> DQ3) = tpd_A18_DQ3; if (InitialPageAccess) (A18 *> DQ4) = tpd_A18_DQ4; if (InitialPageAccess) (A18 *> DQ5) = tpd_A18_DQ5; if (InitialPageAccess) (A18 *> DQ6) = tpd_A18_DQ6; if (InitialPageAccess) (A18 *> DQ7) = tpd_A18_DQ7; if (InitialPageAccess) (A18 *> DQ8) = tpd_A18_DQ8; if (InitialPageAccess) (A18 *> DQ9) = tpd_A18_DQ9; if (InitialPageAccess) (A18 *> DQ10) = tpd_A18_DQ10; if (InitialPageAccess) (A18 *> DQ11) = tpd_A18_DQ11; if (InitialPageAccess) (A18 *> DQ12) = tpd_A18_DQ12; if (InitialPageAccess) (A18 *> DQ13) = tpd_A18_DQ13; if (InitialPageAccess) (A18 *> DQ14) = tpd_A18_DQ14; if (InitialPageAccess) (A18 *> DQ15) = tpd_A18_DQ15; if (InitialPageAccess) (A19 *> DQ0) = tpd_A19_DQ0; if (InitialPageAccess) (A19 *> DQ1) = tpd_A19_DQ1; if (InitialPageAccess) (A19 *> DQ2) = tpd_A19_DQ2; if (InitialPageAccess) (A19 *> DQ3) = tpd_A19_DQ3; if (InitialPageAccess) (A19 *> DQ4) = tpd_A19_DQ4; if (InitialPageAccess) (A19 *> DQ5) = tpd_A19_DQ5; if (InitialPageAccess) (A19 *> DQ6) = tpd_A19_DQ6; if (InitialPageAccess) (A19 *> DQ7) = tpd_A19_DQ7; if (InitialPageAccess) (A19 *> DQ8) = tpd_A19_DQ8; if (InitialPageAccess) (A19 *> DQ9) = tpd_A19_DQ9; if (InitialPageAccess) (A19 *> DQ10) = tpd_A19_DQ10; if (InitialPageAccess) (A19 *> DQ11) = tpd_A19_DQ11; if (InitialPageAccess) (A19 *> DQ12) = tpd_A19_DQ12; if (InitialPageAccess) (A19 *> DQ13) = tpd_A19_DQ13; if (InitialPageAccess) (A19 *> DQ14) = tpd_A19_DQ14; if (InitialPageAccess) (A19 *> DQ15) = tpd_A19_DQ15; if (InitialPageAccess) (A20 *> DQ0) = tpd_A20_DQ0; if (InitialPageAccess) (A20 *> DQ1) = tpd_A20_DQ1; if (InitialPageAccess) (A20 *> DQ2) = tpd_A20_DQ2; if (InitialPageAccess) (A20 *> DQ3) = tpd_A20_DQ3; if (InitialPageAccess) (A20 *> DQ4) = tpd_A20_DQ4; if (InitialPageAccess) (A20 *> DQ5) = tpd_A20_DQ5; if (InitialPageAccess) (A20 *> DQ6) = tpd_A20_DQ6; if (InitialPageAccess) (A20 *> DQ7) = tpd_A20_DQ7; if (InitialPageAccess) (A20 *> DQ8) = tpd_A20_DQ8; if (InitialPageAccess) (A20 *> DQ9) = tpd_A20_DQ9; if (InitialPageAccess) (A20 *> DQ10) = tpd_A20_DQ10; if (InitialPageAccess) (A20 *> DQ11) = tpd_A20_DQ11; if (InitialPageAccess) (A20 *> DQ12) = tpd_A20_DQ12; if (InitialPageAccess) (A20 *> DQ13) = tpd_A20_DQ13; if (InitialPageAccess) (A20 *> DQ14) = tpd_A20_DQ14; if (InitialPageAccess) (A20 *> DQ15) = tpd_A20_DQ15; if (InitialPageAccess) (A21 *> DQ0) = tpd_A21_DQ0; if (InitialPageAccess) (A21 *> DQ1) = tpd_A21_DQ1; if (InitialPageAccess) (A21 *> DQ2) = tpd_A21_DQ2; if (InitialPageAccess) (A21 *> DQ3) = tpd_A21_DQ3; if (InitialPageAccess) (A21 *> DQ4) = tpd_A21_DQ4; if (InitialPageAccess) (A21 *> DQ5) = tpd_A21_DQ5; if (InitialPageAccess) (A21 *> DQ6) = tpd_A21_DQ6; if (InitialPageAccess) (A21 *> DQ7) = tpd_A21_DQ7; if (InitialPageAccess) (A21 *> DQ8) = tpd_A21_DQ8; if (InitialPageAccess) (A21 *> DQ9) = tpd_A21_DQ9; if (InitialPageAccess) (A21 *> DQ10) = tpd_A21_DQ10; if (InitialPageAccess) (A21 *> DQ11) = tpd_A21_DQ11; if (InitialPageAccess) (A21 *> DQ12) = tpd_A21_DQ12; if (InitialPageAccess) (A21 *> DQ13) = tpd_A21_DQ13; if (InitialPageAccess) (A21 *> DQ14) = tpd_A21_DQ14; if (InitialPageAccess) (A21 *> DQ15) = tpd_A21_DQ15; if (InitialPageAccess) (A22 *> DQ0) = tpd_A22_DQ0; if (InitialPageAccess) (A22 *> DQ1) = tpd_A22_DQ1; if (InitialPageAccess) (A22 *> DQ2) = tpd_A22_DQ2; if (InitialPageAccess) (A22 *> DQ3) = tpd_A22_DQ3; if (InitialPageAccess) (A22 *> DQ4) = tpd_A22_DQ4; if (InitialPageAccess) (A22 *> DQ5) = tpd_A22_DQ5; if (InitialPageAccess) (A22 *> DQ6) = tpd_A22_DQ6; if (InitialPageAccess) (A22 *> DQ7) = tpd_A22_DQ7; if (InitialPageAccess) (A22 *> DQ8) = tpd_A22_DQ8; if (InitialPageAccess) (A22 *> DQ9) = tpd_A22_DQ9; if (InitialPageAccess) (A22 *> DQ10) = tpd_A22_DQ10; if (InitialPageAccess) (A22 *> DQ11) = tpd_A22_DQ11; if (InitialPageAccess) (A22 *> DQ12) = tpd_A22_DQ12; if (InitialPageAccess) (A22 *> DQ13) = tpd_A22_DQ13; if (InitialPageAccess) (A22 *> DQ14) = tpd_A22_DQ14; if (InitialPageAccess) (A22 *> DQ15) = tpd_A22_DQ15; if (InitialPageAccess) (A23 *> DQ0) = tpd_A23_DQ0; if (InitialPageAccess) (A23 *> DQ1) = tpd_A23_DQ1; if (InitialPageAccess) (A23 *> DQ2) = tpd_A23_DQ2; if (InitialPageAccess) (A23 *> DQ3) = tpd_A23_DQ3; if (InitialPageAccess) (A23 *> DQ4) = tpd_A23_DQ4; if (InitialPageAccess) (A23 *> DQ5) = tpd_A23_DQ5; if (InitialPageAccess) (A23 *> DQ6) = tpd_A23_DQ6; if (InitialPageAccess) (A23 *> DQ7) = tpd_A23_DQ7; if (InitialPageAccess) (A23 *> DQ8) = tpd_A23_DQ8; if (InitialPageAccess) (A23 *> DQ9) = tpd_A23_DQ9; if (InitialPageAccess) (A23 *> DQ10) = tpd_A23_DQ10; if (InitialPageAccess) (A23 *> DQ11) = tpd_A23_DQ11; if (InitialPageAccess) (A23 *> DQ12) = tpd_A23_DQ12; if (InitialPageAccess) (A23 *> DQ13) = tpd_A23_DQ13; if (InitialPageAccess) (A23 *> DQ14) = tpd_A23_DQ14; if (InitialPageAccess) (A23 *> DQ15) = tpd_A23_DQ15; if (InitialPageAccess) (A24 *> DQ0) = tpd_A24_DQ0; if (InitialPageAccess) (A24 *> DQ1) = tpd_A24_DQ1; if (InitialPageAccess) (A24 *> DQ2) = tpd_A24_DQ2; if (InitialPageAccess) (A24 *> DQ3) = tpd_A24_DQ3; if (InitialPageAccess) (A24 *> DQ4) = tpd_A24_DQ4; if (InitialPageAccess) (A24 *> DQ5) = tpd_A24_DQ5; if (InitialPageAccess) (A24 *> DQ6) = tpd_A24_DQ6; if (InitialPageAccess) (A24 *> DQ7) = tpd_A24_DQ7; if (InitialPageAccess) (A24 *> DQ8) = tpd_A24_DQ8; if (InitialPageAccess) (A24 *> DQ9) = tpd_A24_DQ9; if (InitialPageAccess) (A24 *> DQ10) = tpd_A24_DQ10; if (InitialPageAccess) (A24 *> DQ11) = tpd_A24_DQ11; if (InitialPageAccess) (A24 *> DQ12) = tpd_A24_DQ12; if (InitialPageAccess) (A24 *> DQ13) = tpd_A24_DQ13; if (InitialPageAccess) (A24 *> DQ14) = tpd_A24_DQ14; if (InitialPageAccess) (A24 *> DQ15) = tpd_A24_DQ15; if (SubsequentPageAccess) (A1 *> DQ0) = tpd_A1_DQ0; if (SubsequentPageAccess) (A1 *> DQ1) = tpd_A1_DQ1; if (SubsequentPageAccess) (A1 *> DQ2) = tpd_A1_DQ2; if (SubsequentPageAccess) (A1 *> DQ3) = tpd_A1_DQ3; if (SubsequentPageAccess) (A1 *> DQ4) = tpd_A1_DQ4; if (SubsequentPageAccess) (A1 *> DQ5) = tpd_A1_DQ5; if (SubsequentPageAccess) (A1 *> DQ6) = tpd_A1_DQ6; if (SubsequentPageAccess) (A1 *> DQ7) = tpd_A1_DQ7; if (SubsequentPageAccess) (A1 *> DQ8) = tpd_A1_DQ8; if (SubsequentPageAccess) (A1 *> DQ9) = tpd_A1_DQ9; if (SubsequentPageAccess) (A1 *> DQ10) = tpd_A1_DQ10; if (SubsequentPageAccess) (A1 *> DQ11) = tpd_A1_DQ11; if (SubsequentPageAccess) (A1 *> DQ12) = tpd_A1_DQ12; if (SubsequentPageAccess) (A1 *> DQ13) = tpd_A1_DQ13; if (SubsequentPageAccess) (A1 *> DQ14) = tpd_A1_DQ14; if (SubsequentPageAccess) (A1 *> DQ15) = tpd_A1_DQ15; if (SubsequentPageAccess) (A2 *> DQ0) = tpd_A2_DQ0; if (SubsequentPageAccess) (A2 *> DQ1) = tpd_A2_DQ1; if (SubsequentPageAccess) (A2 *> DQ2) = tpd_A2_DQ2; if (SubsequentPageAccess) (A2 *> DQ3) = tpd_A2_DQ3; if (SubsequentPageAccess) (A2 *> DQ4) = tpd_A2_DQ4; if (SubsequentPageAccess) (A2 *> DQ5) = tpd_A2_DQ5; if (SubsequentPageAccess) (A2 *> DQ6) = tpd_A2_DQ6; if (SubsequentPageAccess) (A2 *> DQ7) = tpd_A2_DQ7; if (SubsequentPageAccess) (A2 *> DQ8) = tpd_A2_DQ8; if (SubsequentPageAccess) (A2 *> DQ9) = tpd_A2_DQ9; if (SubsequentPageAccess) (A2 *> DQ10) = tpd_A2_DQ10; if (SubsequentPageAccess) (A2 *> DQ11) = tpd_A2_DQ11; if (SubsequentPageAccess) (A2 *> DQ12) = tpd_A2_DQ12; if (SubsequentPageAccess) (A2 *> DQ13) = tpd_A2_DQ13; if (SubsequentPageAccess) (A2 *> DQ14) = tpd_A2_DQ14; if (SubsequentPageAccess) (A2 *> DQ15) = tpd_A2_DQ15; if (FROMCE) (CENeg *> DQ0) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ1) = tpd_CENeg_DQ1; if (FROMCE) (CENeg *> DQ2) = tpd_CENeg_DQ2; if (FROMCE) (CENeg *> DQ3) = tpd_CENeg_DQ3; if (FROMCE) (CENeg *> DQ4) = tpd_CENeg_DQ4; if (FROMCE) (CENeg *> DQ5) = tpd_CENeg_DQ5; if (FROMCE) (CENeg *> DQ6) = tpd_CENeg_DQ6; if (FROMCE) (CENeg *> DQ7) = tpd_CENeg_DQ7; if (FROMCE) (CENeg *> DQ8) = tpd_CENeg_DQ8; if (FROMCE) (CENeg *> DQ9) = tpd_CENeg_DQ9; if (FROMCE) (CENeg *> DQ10)= tpd_CENeg_DQ10; if (FROMCE) (CENeg *> DQ11)= tpd_CENeg_DQ11; if (FROMCE) (CENeg *> DQ12)= tpd_CENeg_DQ12; if (FROMCE) (CENeg *> DQ13)= tpd_CENeg_DQ13; if (FROMCE) (CENeg *> DQ14)= tpd_CENeg_DQ14; if (FROMCE) (CENeg *> DQ15)= tpd_CENeg_DQ15; if (FROMOE) (OENeg *> DQ0) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ1) = tpd_OENeg_DQ1; if (FROMOE) (OENeg *> DQ2) = tpd_OENeg_DQ2; if (FROMOE) (OENeg *> DQ3) = tpd_OENeg_DQ3; if (FROMOE) (OENeg *> DQ4) = tpd_OENeg_DQ4; if (FROMOE) (OENeg *> DQ5) = tpd_OENeg_DQ5; if (FROMOE) (OENeg *> DQ6) = tpd_OENeg_DQ6; if (FROMOE) (OENeg *> DQ7) = tpd_OENeg_DQ7; if (FROMOE) (OENeg *> DQ8) = tpd_OENeg_DQ8; if (FROMOE) (OENeg *> DQ9) = tpd_OENeg_DQ9; if (FROMOE) (OENeg *> DQ10) = tpd_OENeg_DQ10; if (FROMOE) (OENeg *> DQ11) = tpd_OENeg_DQ11; if (FROMOE) (OENeg *> DQ12) = tpd_OENeg_DQ12; if (FROMOE) (OENeg *> DQ13) = tpd_OENeg_DQ13; if (FROMOE) (OENeg *> DQ14) = tpd_OENeg_DQ14; if (FROMOE) (OENeg *> DQ15) = tpd_OENeg_DQ15; if (RCR[15] === 1'b0) ( CLK *> DQ0 ) = tpd_CLK_DQ0 ; if (RCR[15] === 1'b0) ( CLK *> DQ1 ) = tpd_CLK_DQ1 ; if (RCR[15] === 1'b0) ( CLK *> DQ2 ) = tpd_CLK_DQ2 ; if (RCR[15] === 1'b0) ( CLK *> DQ3 ) = tpd_CLK_DQ3 ; if (RCR[15] === 1'b0) ( CLK *> DQ4 ) = tpd_CLK_DQ4 ; if (RCR[15] === 1'b0) ( CLK *> DQ5 ) = tpd_CLK_DQ5 ; if (RCR[15] === 1'b0) ( CLK *> DQ6 ) = tpd_CLK_DQ6 ; if (RCR[15] === 1'b0) ( CLK *> DQ7 ) = tpd_CLK_DQ7 ; if (RCR[15] === 1'b0) ( CLK *> DQ8 ) = tpd_CLK_DQ8 ; if (RCR[15] === 1'b0) ( CLK *> DQ9 ) = tpd_CLK_DQ9 ; if (RCR[15] === 1'b0) ( CLK *> DQ10) = tpd_CLK_DQ10 ; if (RCR[15] === 1'b0) ( CLK *> DQ11) = tpd_CLK_DQ11 ; if (RCR[15] === 1'b0) ( CLK *> DQ12) = tpd_CLK_DQ12 ; if (RCR[15] === 1'b0) ( CLK *> DQ13) = tpd_CLK_DQ13 ; if (RCR[15] === 1'b0) ( CLK *> DQ14) = tpd_CLK_DQ14 ; if (RCR[15] === 1'b0) ( CLK *> DQ15) = tpd_CLK_DQ15 ; ( CENeg *> WAITOut) = tpd_CE0Neg_WAITOut ; ( OENeg *> WAITOut) = tpd_OE0Neg_WAITOut ; if (RCR[15] === 1'b0) ( CLK *> WAITOut) = tpd_CLK_WAITOut; /////////////////////////////////////////////////////////////////////////////// // Timing Violation // /////////////////////////////////////////////////////////////////////////////// $setup ( A1 , posedge ADVNeg, tsetup_A1_ADVNeg, Viol); $setup ( A2 , posedge ADVNeg, tsetup_A2_ADVNeg, Viol); $setup ( A3 , posedge ADVNeg, tsetup_A3_ADVNeg, Viol); $setup ( A4 , posedge ADVNeg, tsetup_A4_ADVNeg, Viol); $setup ( A5 , posedge ADVNeg, tsetup_A5_ADVNeg, Viol); $setup ( A6 , posedge ADVNeg, tsetup_A6_ADVNeg, Viol); $setup ( A7 , posedge ADVNeg, tsetup_A7_ADVNeg, Viol); $setup ( A8 , posedge ADVNeg, tsetup_A8_ADVNeg, Viol); $setup ( A9 , posedge ADVNeg, tsetup_A9_ADVNeg, Viol); $setup ( A10 , posedge ADVNeg, tsetup_A10_ADVNeg, Viol); $setup ( A11 , posedge ADVNeg, tsetup_A11_ADVNeg, Viol); $setup ( A12 , posedge ADVNeg, tsetup_A12_ADVNeg, Viol); $setup ( A13 , posedge ADVNeg, tsetup_A13_ADVNeg, Viol); $setup ( A14 , posedge ADVNeg, tsetup_A14_ADVNeg, Viol); $setup ( A15 , posedge ADVNeg, tsetup_A15_ADVNeg, Viol); $setup ( A16 , posedge ADVNeg, tsetup_A16_ADVNeg, Viol); $setup ( A17 , posedge ADVNeg, tsetup_A17_ADVNeg, Viol); $setup ( A18 , posedge ADVNeg, tsetup_A18_ADVNeg, Viol); $setup ( A19 , posedge ADVNeg, tsetup_A19_ADVNeg, Viol); $setup ( A20 , posedge ADVNeg, tsetup_A20_ADVNeg, Viol); $setup ( A21 , posedge ADVNeg, tsetup_A21_ADVNeg, Viol); $setup ( A22 , posedge ADVNeg, tsetup_A22_ADVNeg, Viol); $setup ( A23 , posedge ADVNeg, tsetup_A23_ADVNeg, Viol); $setup ( A24 , posedge ADVNeg, tsetup_A24_ADVNeg, Viol); $setup ( negedge CENeg , posedge ADVNeg, tsetup_CENeg_ADVNeg, Viol); $setup ( negedge RSTNeg , posedge ADVNeg, tsetup_RSTNeg_ADVNeg,Viol); $setup ( posedge WENeg , posedge ADVNeg, tsetup_WENeg_ADVNeg, Viol); $setup ( A1 , posedge CLK &&& CLK_rising, tsetup_A1_CLK, Viol); $setup ( A2 , posedge CLK &&& CLK_rising, tsetup_A2_CLK, Viol); $setup ( A3 , posedge CLK &&& CLK_rising, tsetup_A3_CLK, Viol); $setup ( A4 , posedge CLK &&& CLK_rising, tsetup_A4_CLK, Viol); $setup ( A5 , posedge CLK &&& CLK_rising, tsetup_A5_CLK, Viol); $setup ( A6 , posedge CLK &&& CLK_rising, tsetup_A6_CLK, Viol); $setup ( A7 , posedge CLK &&& CLK_rising, tsetup_A7_CLK, Viol); $setup ( A8 , posedge CLK &&& CLK_rising, tsetup_A8_CLK, Viol); $setup ( A9 , posedge CLK &&& CLK_rising, tsetup_A9_CLK, Viol); $setup ( A10 , posedge CLK &&& CLK_rising, tsetup_A10_CLK, Viol); $setup ( A11 , posedge CLK &&& CLK_rising, tsetup_A11_CLK, Viol); $setup ( A12 , posedge CLK &&& CLK_rising, tsetup_A12_CLK, Viol); $setup ( A13 , posedge CLK &&& CLK_rising, tsetup_A13_CLK, Viol); $setup ( A14 , posedge CLK &&& CLK_rising, tsetup_A14_CLK, Viol); $setup ( A15 , posedge CLK &&& CLK_rising, tsetup_A15_CLK, Viol); $setup ( A16 , posedge CLK &&& CLK_rising, tsetup_A16_CLK, Viol); $setup ( A17 , posedge CLK &&& CLK_rising, tsetup_A17_CLK, Viol); $setup ( A18 , posedge CLK &&& CLK_rising, tsetup_A18_CLK, Viol); $setup ( A19 , posedge CLK &&& CLK_rising, tsetup_A19_CLK, Viol); $setup ( A20 , posedge CLK &&& CLK_rising, tsetup_A20_CLK, Viol); $setup ( A21 , posedge CLK &&& CLK_rising, tsetup_A21_CLK, Viol); $setup ( A22 , posedge CLK &&& CLK_rising, tsetup_A22_CLK, Viol); $setup ( A23 , posedge CLK &&& CLK_rising, tsetup_A23_CLK, Viol); $setup ( A24 , posedge CLK &&& CLK_rising, tsetup_A24_CLK, Viol); $setup ( A1 , negedge CLK &&& CLK_falling, tsetup_A1_CLK, Viol); $setup ( A2 , negedge CLK &&& CLK_falling, tsetup_A2_CLK, Viol); $setup ( A3 , negedge CLK &&& CLK_falling, tsetup_A3_CLK, Viol); $setup ( A4 , negedge CLK &&& CLK_falling, tsetup_A4_CLK, Viol); $setup ( A5 , negedge CLK &&& CLK_falling, tsetup_A5_CLK, Viol); $setup ( A6 , negedge CLK &&& CLK_falling, tsetup_A6_CLK, Viol); $setup ( A7 , negedge CLK &&& CLK_falling, tsetup_A7_CLK, Viol); $setup ( A8 , negedge CLK &&& CLK_falling, tsetup_A8_CLK, Viol); $setup ( A9 , negedge CLK &&& CLK_falling, tsetup_A9_CLK, Viol); $setup ( A10 , negedge CLK &&& CLK_falling, tsetup_A10_CLK, Viol); $setup ( A11 , negedge CLK &&& CLK_falling, tsetup_A11_CLK, Viol); $setup ( A12 , negedge CLK &&& CLK_falling, tsetup_A12_CLK, Viol); $setup ( A13 , negedge CLK &&& CLK_falling, tsetup_A13_CLK, Viol); $setup ( A14 , negedge CLK &&& CLK_falling, tsetup_A14_CLK, Viol); $setup ( A15 , negedge CLK &&& CLK_falling, tsetup_A15_CLK, Viol); $setup ( A16 , negedge CLK &&& CLK_falling, tsetup_A16_CLK, Viol); $setup ( A17 , negedge CLK &&& CLK_falling, tsetup_A17_CLK, Viol); $setup ( A18 , negedge CLK &&& CLK_falling, tsetup_A18_CLK, Viol); $setup ( A19 , negedge CLK &&& CLK_falling, tsetup_A19_CLK, Viol); $setup ( A20 , negedge CLK &&& CLK_falling, tsetup_A20_CLK, Viol); $setup ( A21 , negedge CLK &&& CLK_falling, tsetup_A21_CLK, Viol); $setup ( A22 , negedge CLK &&& CLK_falling, tsetup_A22_CLK, Viol); $setup ( A23 , negedge CLK &&& CLK_falling, tsetup_A23_CLK, Viol); $setup ( A24 , negedge CLK &&& CLK_falling, tsetup_A24_CLK, Viol); $setup ( negedge ADVNeg , posedge CLK &&& CLK_rising , tsetup_ADVNeg_CLK, Viol); $setup ( negedge ADVNeg , negedge CLK &&& CLK_falling , tsetup_ADVNeg_CLK, Viol); $setup ( negedge CENeg , posedge CLK &&& CLK_rising , tsetup_CENeg_CLK, Viol); $setup ( negedge CENeg , negedge CLK &&& CLK_falling , tsetup_CENeg_CLK, Viol); $setup ( posedge WENeg , posedge CLK &&& CLK_rising , tsetup_WENeg_CLK, Viol); $setup ( posedge WENeg , negedge CLK &&& CLK_falling , tsetup_WENeg_CLK, Viol); $setup ( negedge CENeg , negedge WENeg , tsetup_CENeg_WENeg, Viol); $setup ( DQ0 , posedge WENeg , tsetup_DQ0_WENeg, Viol); $setup ( DQ1 , posedge WENeg , tsetup_DQ1_WENeg, Viol); $setup ( DQ2 , posedge WENeg , tsetup_DQ2_WENeg, Viol); $setup ( DQ3 , posedge WENeg , tsetup_DQ3_WENeg, Viol); $setup ( DQ4 , posedge WENeg , tsetup_DQ4_WENeg, Viol); $setup ( DQ5 , posedge WENeg , tsetup_DQ5_WENeg, Viol); $setup ( DQ6 , posedge WENeg , tsetup_DQ6_WENeg, Viol); $setup ( DQ7 , posedge WENeg , tsetup_DQ7_WENeg, Viol); $setup ( DQ8 , posedge WENeg , tsetup_DQ8_WENeg, Viol); $setup ( DQ9 , posedge WENeg , tsetup_DQ9_WENeg, Viol); $setup ( DQ10 , posedge WENeg , tsetup_DQ10_WENeg, Viol); $setup ( DQ11 , posedge WENeg , tsetup_DQ11_WENeg, Viol); $setup ( DQ12 , posedge WENeg , tsetup_DQ12_WENeg, Viol); $setup ( DQ13 , posedge WENeg , tsetup_DQ13_WENeg, Viol); $setup ( DQ14 , posedge WENeg , tsetup_DQ14_WENeg, Viol); $setup ( DQ15 , posedge WENeg , tsetup_DQ15_WENeg, Viol); $setup ( A1 , posedge WENeg , tsetup_A1_WENeg, Viol); $setup ( A2 , posedge WENeg , tsetup_A2_WENeg, Viol); $setup ( A3 , posedge WENeg , tsetup_A3_WENeg, Viol); $setup ( A4 , posedge WENeg , tsetup_A4_WENeg, Viol); $setup ( A5 , posedge WENeg , tsetup_A5_WENeg, Viol); $setup ( A6 , posedge WENeg , tsetup_A6_WENeg, Viol); $setup ( A7 , posedge WENeg , tsetup_A7_WENeg, Viol); $setup ( A8 , posedge WENeg , tsetup_A8_WENeg, Viol); $setup ( A9 , posedge WENeg , tsetup_A9_WENeg, Viol); $setup ( A10 , posedge WENeg , tsetup_A10_WENeg, Viol); $setup ( A11 , posedge WENeg , tsetup_A11_WENeg, Viol); $setup ( A12 , posedge WENeg , tsetup_A12_WENeg, Viol); $setup ( A13 , posedge WENeg , tsetup_A13_WENeg, Viol); $setup ( A14 , posedge WENeg , tsetup_A14_WENeg, Viol); $setup ( A15 , posedge WENeg , tsetup_A15_WENeg, Viol); $setup ( A16 , posedge WENeg , tsetup_A16_WENeg, Viol); $setup ( A17 , posedge WENeg , tsetup_A17_WENeg, Viol); $setup ( A18 , posedge WENeg , tsetup_A18_WENeg, Viol); $setup ( A19 , posedge WENeg , tsetup_A19_WENeg, Viol); $setup ( A20 , posedge WENeg , tsetup_A20_WENeg, Viol); $setup ( A21 , posedge WENeg , tsetup_A21_WENeg, Viol); $setup ( A22 , posedge WENeg , tsetup_A22_WENeg, Viol); $setup ( A23 , posedge WENeg , tsetup_A23_WENeg, Viol); $setup ( A24 , posedge WENeg , tsetup_A24_WENeg, Viol); $setup (posedge ADVNeg, posedge WENeg , tsetup_ADVNeg_WENeg, Viol); $setup (posedge WPNeg, posedge WENeg , tsetup_WPNeg_WENeg, Viol); $setup (posedge CLK &&& CLK_rising, negedge WENeg , tsetup_CLK_WENeg, Viol); $setup (negedge CLK &&& CLK_falling, negedge WENeg , tsetup_CLK_WENeg, Viol); $setup (posedge WENeg, negedge OENeg , tsetup_WENeg_OENeg, Viol); $hold ( posedge WENeg, CENeg, thold_CENeg_WENeg, Viol); $hold ( posedge WENeg ,DQ0 , thold_DQ0_WENeg, Viol); $hold ( posedge WENeg ,DQ1 , thold_DQ1_WENeg, Viol); $hold ( posedge WENeg ,DQ2 , thold_DQ2_WENeg, Viol); $hold ( posedge WENeg ,DQ3 , thold_DQ3_WENeg, Viol); $hold ( posedge WENeg ,DQ4 , thold_DQ4_WENeg, Viol); $hold ( posedge WENeg ,DQ5 , thold_DQ5_WENeg, Viol); $hold ( posedge WENeg ,DQ6 , thold_DQ6_WENeg, Viol); $hold ( posedge WENeg ,DQ7 , thold_DQ7_WENeg, Viol); $hold ( posedge WENeg ,DQ8 , thold_DQ8_WENeg, Viol); $hold ( posedge WENeg ,DQ9 , thold_DQ9_WENeg, Viol); $hold ( posedge WENeg ,DQ10, thold_DQ10_WENeg, Viol); $hold ( posedge WENeg ,DQ11, thold_DQ11_WENeg, Viol); $hold ( posedge WENeg ,DQ12, thold_DQ12_WENeg, Viol); $hold ( posedge WENeg ,DQ13, thold_DQ13_WENeg, Viol); $hold ( posedge WENeg ,DQ14, thold_DQ14_WENeg, Viol); $hold ( posedge WENeg ,DQ15, thold_DQ15_WENeg, Viol); $hold ( posedge WENeg ,A1, thold_A1_WENeg, Viol); $hold ( posedge WENeg ,A2, thold_A2_WENeg, Viol); $hold ( posedge WENeg ,A3, thold_A3_WENeg, Viol); $hold ( posedge WENeg ,A4, thold_A4_WENeg, Viol); $hold ( posedge WENeg ,A5, thold_A5_WENeg, Viol); $hold ( posedge WENeg ,A6, thold_A6_WENeg, Viol); $hold ( posedge WENeg ,A7, thold_A7_WENeg, Viol); $hold ( posedge WENeg ,A8, thold_A8_WENeg, Viol); $hold ( posedge WENeg ,A9, thold_A9_WENeg, Viol); $hold ( posedge WENeg ,A10, thold_A10_WENeg, Viol); $hold ( posedge WENeg ,A11, thold_A11_WENeg, Viol); $hold ( posedge WENeg ,A12, thold_A12_WENeg, Viol); $hold ( posedge WENeg ,A13, thold_A13_WENeg, Viol); $hold ( posedge WENeg ,A14, thold_A14_WENeg, Viol); $hold ( posedge WENeg ,A15, thold_A15_WENeg, Viol); $hold ( posedge WENeg ,A16, thold_A16_WENeg, Viol); $hold ( posedge WENeg ,A17, thold_A17_WENeg, Viol); $hold ( posedge WENeg ,A18, thold_A18_WENeg, Viol); $hold ( posedge WENeg ,A19, thold_A19_WENeg, Viol); $hold ( posedge WENeg ,A20, thold_A20_WENeg, Viol); $hold ( posedge WENeg ,A21, thold_A21_WENeg, Viol); $hold ( posedge WENeg ,A22, thold_A22_WENeg, Viol); $hold ( posedge WENeg ,A23, thold_A23_WENeg, Viol); $hold ( posedge WENeg ,A24, thold_A24_WENeg, Viol); $hold ( posedge ADVNeg ,A1, thold_A1_ADVNeg, Viol); $hold ( posedge ADVNeg ,A2, thold_A2_ADVNeg, Viol); $hold ( posedge ADVNeg ,A3, thold_A3_ADVNeg, Viol); $hold ( posedge ADVNeg ,A4, thold_A4_ADVNeg, Viol); $hold ( posedge ADVNeg ,A5, thold_A5_ADVNeg, Viol); $hold ( posedge ADVNeg ,A6, thold_A6_ADVNeg, Viol); $hold ( posedge ADVNeg ,A7, thold_A7_ADVNeg, Viol); $hold ( posedge ADVNeg ,A8, thold_A8_ADVNeg, Viol); $hold ( posedge ADVNeg ,A9, thold_A9_ADVNeg, Viol); $hold ( posedge ADVNeg ,A10, thold_A10_ADVNeg, Viol); $hold ( posedge ADVNeg ,A11, thold_A11_ADVNeg, Viol); $hold ( posedge ADVNeg ,A12, thold_A12_ADVNeg, Viol); $hold ( posedge ADVNeg ,A13, thold_A13_ADVNeg, Viol); $hold ( posedge ADVNeg ,A14, thold_A14_ADVNeg, Viol); $hold ( posedge ADVNeg ,A15, thold_A15_ADVNeg, Viol); $hold ( posedge ADVNeg ,A16, thold_A16_ADVNeg, Viol); $hold ( posedge ADVNeg ,A17, thold_A17_ADVNeg, Viol); $hold ( posedge ADVNeg ,A18, thold_A18_ADVNeg, Viol); $hold ( posedge ADVNeg ,A19, thold_A19_ADVNeg, Viol); $hold ( posedge ADVNeg ,A20, thold_A20_ADVNeg, Viol); $hold ( posedge ADVNeg ,A21, thold_A21_ADVNeg, Viol); $hold ( posedge ADVNeg ,A22, thold_A22_ADVNeg, Viol); $hold ( posedge ADVNeg ,A23, thold_A23_ADVNeg, Viol); $hold ( posedge ADVNeg ,A24, thold_A24_ADVNeg, Viol); $hold ( posedge CLK &&& CLK_rising, A1 , thold_A1_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A2 , thold_A2_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A3 , thold_A3_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A4 , thold_A4_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A5 , thold_A5_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A6 , thold_A6_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A7 , thold_A7_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A8 , thold_A8_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A9 , thold_A9_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A10 , thold_A10_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A11 , thold_A11_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A12 , thold_A12_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A13 , thold_A13_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A14 , thold_A14_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A15 , thold_A15_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A16 , thold_A16_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A17 , thold_A17_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A18 , thold_A18_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A19 , thold_A19_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A20 , thold_A20_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A21 , thold_A21_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A22 , thold_A22_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A23 , thold_A23_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A24 , thold_A24_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A1 , thold_A1_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A2 , thold_A2_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A3 , thold_A3_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A4 , thold_A4_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A5 , thold_A5_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A6 , thold_A6_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A7 , thold_A7_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A8 , thold_A8_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A9 , thold_A9_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A10 , thold_A10_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A11 , thold_A11_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A12 , thold_A12_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A13 , thold_A13_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A14 , thold_A14_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A15 , thold_A15_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A16 , thold_A16_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A17 , thold_A17_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A18 , thold_A18_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A19 , thold_A19_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A20 , thold_A20_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A21 , thold_A21_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A22 , thold_A22_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A23 , thold_A23_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A24 , thold_A24_CLK, Viol); $width ( posedge CENeg , tpw_CENeg_posedge ); $width ( posedge ADVNeg, tpw_ADVNeg_posedge ); $width ( negedge ADVNeg, tpw_ADVNeg_negedge ); $width ( posedge CLK , tpw_CLK_posedge ); $width ( negedge CLK , tpw_CLK_negedge ); $width ( posedge WENeg , tpw_WENeg_posedge ); $width ( negedge WENeg , tpw_WENeg_negedge ); $width ( negedge RSTNeg, tpw_RSTNeg_negedge ); $period( posedge CLK , tperiod_CLK); $period( negedge CLK , tperiod_CLK); endspecify //tdevice parameters aligned to model timescale // Program EraseParameter time tdevice_EraseParameter = tdevice_EraseParameter_td*1000; //2.5 sec; // Parameter Block Erase - 12V time tdevice_EraseMain = tdevice_EraseMain_td*1000; //4 sec; /////////////////////////////////////////////////////////////////////////////// // Main Behavior Block // /////////////////////////////////////////////////////////////////////////////// always @(DQIn, DQOut) begin if (DQIn==DQOut) deq=1'b1; else deq=1'b0; end // chech when data is generated from model to avoid setuphold check in // those occasion assign deg=deq; // initialize memory and load preload files if any initial begin: InitMemory integer i; for (i=0;i<=MemSize;i=i+1) begin MemData[i]=MaxData; end if ((UserPreload) && !(mem_file_name == "none")) begin // File Read Section //#i28f512p33_1 memory file //# / - comment //# @aaaaa - stands for address //# dddd - is word to be written at Mem(aaaaa++) //# (aaaaa is incremented at every load) //# //# only first 1-6 columns are loaded. NO empty lines ! $readmemh(mem_file_name, MemData); end for (i=0;i<=BlockNum;i=i+1) begin OTP[i]=1'b0; end if ((UserPreload) && !(otp_blocks_file == "none")) begin // File Read Section //#i28f512p33_1 memory file //# / - comment //# @aaa - stands for address //# dddd - is word to be written at OTP(aaa++) //# (aaa is incremented at every load) //# //# only first 1-6 columns are loaded. NO empty lines ! $readmemh(otp_blocks_file, OTP); end PR[9'h80] = 16'hFFFE; for (i=9'h81;i<=9'h109;i=i+1) begin PR[i]=MaxData; end if ((UserPreload) && !(prot_reg_file == "none")) begin // File Read Section //#i28f512p33_1 memory file //# / - comment //# @aaa - stands for address //# dddd - is word to be written at PR(aaa++) //# (aaa is incremented at every load) //# //# only first 1-6 columns are loaded. NO empty lines ! $readmemh(prot_reg_file, PR); end for (i=0;i<=BlockNum;i=i+1) begin Block_Lock[i] = LOCKED; BlockLockBit[i] = 1'b1; BlockLockDownBit[i] = 1'b0; end end initial begin /////////////////////////////////////////////////////////////////////// //CFI array data /////////////////////////////////////////////////////////////////////// CFI_array[9'h10]=16'h51; CFI_array[9'h11]=16'h52; CFI_array[9'h12]=16'h59; CFI_array[9'h13]=16'h01; CFI_array[9'h14]=16'h00; CFI_array[9'h15]=16'h0A; CFI_array[9'h16]=16'h01; CFI_array[9'h17]=16'h00; CFI_array[9'h18]=16'h00; CFI_array[9'h19]=16'h00; CFI_array[9'h1A]=16'h00; // System Interface Information CFI_array[9'h1B]=16'h23; CFI_array[9'h1C]=16'h36; CFI_array[9'h1D]=16'h85; CFI_array[9'h1E]=16'h95; CFI_array[9'h1F]=16'h08; CFI_array[9'h20]=16'h09; CFI_array[9'h21]=16'h0A; CFI_array[9'h22]=16'h00; CFI_array[9'h23]=16'h01; CFI_array[9'h24]=16'h01; CFI_array[9'h25]=16'h02; CFI_array[9'h26]=16'h00; // Device Geometry definition CFI_array[9'h27]=16'h19; CFI_array[9'h28]=16'h01; CFI_array[9'h29]=16'h00; CFI_array[9'h2A]=16'h06; CFI_array[9'h2B]=16'h00; CFI_array[9'h2C]=16'h02; CFI_array[9'h2D]=16'hFE; CFI_array[9'h2E]=16'h00; CFI_array[9'h2F]=16'h00; CFI_array[9'h30]=16'h02; CFI_array[9'h31]=16'h03; CFI_array[9'h32]=16'h00; CFI_array[9'h33]=16'h80; CFI_array[9'h34]=16'h00; CFI_array[9'h35]=16'h00; CFI_array[9'h36]=16'h00; CFI_array[9'h37]=16'h00; CFI_array[9'h38]=16'h00; // Primary-vendor specific extended query CFI_array[9'h10A]=16'h50; CFI_array[9'h10B]=16'h52; CFI_array[9'h10C]=16'h49; CFI_array[9'h10D]=16'h31; CFI_array[9'h10E]=16'h34; CFI_array[9'h10F]=16'hE6; CFI_array[9'h110]=16'h01; CFI_array[9'h111]=16'h00; CFI_array[9'h112]=16'h40; // TOP PARAMETER BLOCK UPPER DIE CFI_array[9'h113]=16'h01; CFI_array[9'h114]=16'h03; CFI_array[9'h115]=16'h00; CFI_array[9'h116]=16'h30; CFI_array[9'h117]=16'h90; // Protection register information CFI_array[9'h118]=16'h02; CFI_array[9'h119]=16'h80; CFI_array[9'h11A]=16'h00; CFI_array[9'h11B]=16'h03; CFI_array[9'h11C]=16'h03; CFI_array[9'h11D]=16'h89; CFI_array[9'h11E]=16'h00; CFI_array[9'h11F]=16'h00; CFI_array[9'h120]=16'h00; CFI_array[9'h121]=16'h00; CFI_array[9'h122]=16'h00; CFI_array[9'h123]=16'h00; CFI_array[9'h124]=16'h10; CFI_array[9'h125]=16'h00; CFI_array[9'h126]=16'h04; // Burst read information CFI_array[9'h127]=16'h03; CFI_array[9'h128]=16'h04; CFI_array[9'h129]=16'h01; CFI_array[9'h12A]=16'h02; CFI_array[9'h12B]=16'h03; CFI_array[9'h12C]=16'h07; //Partition and Erase Block Region Information CFI_array[9'h12D]=16'h01; CFI_array[9'h12E]=16'h24; CFI_array[9'h12F]=16'h00; CFI_array[9'h130]=16'h01; CFI_array[9'h131]=16'h00; CFI_array[9'h132]=16'h11; CFI_array[9'h133]=16'h00; CFI_array[9'h134]=16'h00; CFI_array[9'h135]=16'h02; CFI_array[9'h136]=16'hFE; CFI_array[9'h137]=16'h00; CFI_array[9'h138]=16'h00; CFI_array[9'h139]=16'h02; CFI_array[9'h13A]=16'h64; CFI_array[9'h13B]=16'h00; CFI_array[9'h13C]=16'h02; CFI_array[9'h13D]=16'h03; CFI_array[9'h13E]=16'h00; CFI_array[9'h13F]=16'h80; CFI_array[9'h140]=16'h00; CFI_array[9'h141]=16'h00; CFI_array[9'h142]=16'h00; CFI_array[9'h143]=16'h80; CFI_array[9'h144]=16'h03; CFI_array[9'h145]=16'h00; CFI_array[9'h146]=16'h80; CFI_array[9'h147]=16'h00; CFI_array[9'h148]=16'h64; CFI_array[9'h149]=16'h00; CFI_array[9'h14A]=16'h02; CFI_array[9'h14B]=16'h03; CFI_array[9'h14C]=16'h00; CFI_array[9'h14D]=16'h80; CFI_array[9'h14E]=16'h00; CFI_array[9'h14F]=16'h00; CFI_array[9'h150]=16'h00; CFI_array[9'h151]=16'h80; CFI_array[9'h152]=16'h10; CFI_array[9'h153]=16'h20; CFI_array[9'h154]=16'h00; CFI_array[9'h155]=16'h00; CFI_array[9'h156]=16'h10; end initial begin current_state = RESET_POWER_DOWN; next_state = RESET_POWER_DOWN; read_state = READ_ARRAY; WordProgram_in = 1'b0; BuffProgram_in = 1'b0; BEFP_in = 1'b0; BEFPsetup_in = 1'b0; ParameterErase_in = 1'b0; MainErase_in = 1'b0; ProgramSuspend_in = 1'b0; EraseSuspend_in = 1'b0; RstDuringErsPrg_in = 1'b0; CLOCK = 1'b0; Write = 1'b0; Read = 1'b0; Pmode = 1'b0; abort = 1'b0; ExtendProgTime = 1'b0; AssertWAITOut = 1'b0; DeassertWAITOut = 1'b0; read_out = 1'b0; SR = 8'b10000000; RCR = 16'b1011111111001111; LATCHED = 1'b0; Viol = 1'b0; word_cntr = 0; end /////////////////////////////////////////////////////////////////////////// //// Internal Delays /////////////////////////////////////////////////////////////////////////// always @(posedge BEFP_in) begin:BEFP BEFP_out = 1'b1; #tdevice_BEFP BEFP_out = 1'b0; end always @(posedge BEFPsetup_in) begin:BEFPsetup BEFPsetup_out = 1'b1; #tdevice_BEFPsetup BEFPsetup_out = 1'b0; end always @(posedge ProgramSuspend_in) begin:ProgramSuspend ProgramSuspend_out = 1'b1; #tdevice_ProgramSuspend ProgramSuspend_out = 1'b0; end always @(posedge EraseSuspend_in) begin:EraseSuspend EraseSuspend_out = 1'b1; #tdevice_EraseSuspend EraseSuspend_out = 1'b0; end always @(posedge RstDuringErsPrg_in) begin:RstDuringErsPrg RstDuringErsPrg_out = 1'b1; #tdevice_RstDuringErsPrg RstDuringErsPrg_out = 1'b0; end ////////////////////////////////////////////////////////////// // Clock control ////////////////////////////////////////////////////////////// always @ (posedge CLK_ipd) begin : CLKControl1 if ((RSTNeg_ipd) && (~CENeg_ipd) && (WENeg_ipd) && (RCR[15] == 1'b0) && (RCR[6] == 1'b1) && (current_state != RESET_POWER_DOWN)) begin CLOCK = 1'b1; #1 CLOCK <= 1'b0; end end always @ (negedge CLK_ipd) begin : CLKControl2 if ((RSTNeg_ipd) && (~CENeg_ipd) && (WENeg_ipd) && (RCR[15] == 1'b0) && (RCR[6] == 1'b0) && (current_state != RESET_POWER_DOWN)) begin CLOCK = 1'b1; #1 CLOCK <= 1'b0; end end always @ (negedge RSTNeg_ipd) begin : RSTControl if (WordProgram_out || BuffProgram_out || ParameterErase_out || MainErase_out || BEFP_out) begin RstDuringErsPrg_in = 1'b0; #1 RstDuringErsPrg_in <= 1'b1; end end ////////////////////////////////////////////////////////////////////////// //// bus cycle decode ////////////////////////////////////////////////////////////////////////// always @ (falling_edge_ADVNeg or rising_edge_ADVNeg or rising_edge_CLOCK or OENeg or RSTNeg or rising_edge_WENeg or rising_edge_CENeg or WENeg or CENeg or Alow_event) begin : BusCycleDecode if (~RSTNeg || CENeg || falling_edge_ADVNeg) LATCHED = 0; if (RSTNeg && current_state != RESET_POWER_DOWN) begin if (~CENeg && ~LATCHED && ((rising_edge_ADVNeg && WENeg) || (~ADVNeg && WENeg && ~RCR[15] && rising_edge_CLOCK) ) ) begin LatchedAddr = A; ReadAddr = A; LATCHED = 1'b1; burst_cntr = 0; BurstDelay = RCR[13:11]; case (RCR[2:0]) 3'b001: BurstLength = 4; 3'b010: BurstLength = 8; 3'b011: BurstLength = 16; 3'b111: BurstLength = 0; endcase DataHold = 0; end // Write control if (OENeg) begin if (~WENeg && ~CENeg) Write = 0; else if ((~CENeg && rising_edge_WENeg) || (~WENeg && rising_edge_CENeg)||(rising_edge_CENeg && rising_edge_WENeg)) begin LatchedData = DQIn; LatchedAddr = A; Write = 1; end end // Read control if (RCR[15]) begin if (WENeg && ~CENeg && ~OENeg) begin if (~ADVNeg) ReadAddr = A; Read = 1; end else begin Read = 0; Pmode = 0; end if (Read && Alow_event) begin Pmode = 1; Pmode <= #2 0; end end else begin if (rising_edge_CLOCK) begin if (BurstDelay > 0) begin #1 BurstDelay = BurstDelay - 1; if (RCR[8] && (BurstDelay == 0 || (BurstDelay == 1 && RCR[9] ) ) ) DeassertWAITOut = ~(DeassertWAITOut); end else begin if (DataHold == 0) begin burst_cntr = burst_cntr + 1; if (~OENeg) Read = ~(Read); if (RCR[9]) DataHold = 1; if ( (burst_cntr > (BurstLength - RCR[8]) ) && BurstLength > 0) AssertWAITOut = ~(AssertWAITOut); else if (read_state == READ_ARRAY && ~RCR[9] && RCR[13:11] > 4) begin if (~RCR[8]) begin if (burst_cntr > 4 || burst_cntr <= 0) AssertWAITOut = ~(AssertWAITOut); else DeassertWAITOut = ~(DeassertWAITOut); end else begin if (burst_cntr >= 4 || burst_cntr < 0) AssertWAITOut = ~(AssertWAITOut); else DeassertWAITOut = ~(DeassertWAITOut); end end DeassertWAITOut = ~(DeassertWAITOut); end else DataHold = DataHold - 1; end end end end end ////////////////////////////////////////////////////////////////////////////// //// sequential process for reset control and FSM state transition ////////////////////////////////////////////////////////////////////////////// always @(next_state) begin : FSM if (ExtendProgTime == 1'b0) current_state = next_state; end //////////////////////////////////////////////////////////////////////////// // obtain 'LAST_EVENT information //////////////////////////////////////////////////////////////////////////// always @(negedge OENeg_ipd) begin OENeg_event = $time; end always @(negedge CENeg_ipd) begin CENeg_event = $time; end always @(A) begin ADDR_event = $time; end /////////////////////////////////////////////////////////////////////////// // FSM - Combinational process for next state generation /////////////////////////////////////////////////////////////////////////// always @(falling_edge_RSTNeg or rising_edge_RSTNeg or rising_edge_Write or RstDuringErsPrg_out_event or WordProgram_out_event or abort or ProgramSuspend_out_event or BuffProgram_out_event or ExtendProgTime_event or falling_edge_EraseSuspend_out or ParameterErase_out_event or falling_edge_MainErase_out or falling_edge_BEFPsetup_out or falling_edge_BEFP_out ) begin : StateGen if (falling_edge_RSTNeg) next_state = RESET_POWER_DOWN; else begin case (current_state) RESET_POWER_DOWN : begin if (((rising_edge_RSTNeg && ~RstDuringErsPrg_out) || (RstDuringErsPrg_out_event && ~RstDuringErsPrg_out)) && $time > 0 ) begin next_state = READY; end end READY: begin if (rising_edge_Write) begin case (LatchedData) 16'h10, 16'h40 : next_state = PROG_SETUP; 16'hE8 : next_state = BP_SETUP; 16'h20 : next_state = ERASE_SETUP; 16'h80 : next_state = BEFP_SETUP; 16'h60 : next_state = LOCK_SETUP; 16'hC0 : next_state = OTP_SETUP; default : next_state = current_state; endcase end end LOCK_SETUP : begin if (rising_edge_Write) next_state = READY; end OTP_SETUP : begin if (rising_edge_Write) next_state = OTP_BUSY; end OTP_BUSY : begin if (abort || (WordProgram_out_event && ~WordProgram_out) ) next_state = READY; end PROG_SETUP : begin if (rising_edge_Write) next_state = PROG_BUSY; end PROG_BUSY : begin if (abort || (WordProgram_out_event && ~WordProgram_out) ) next_state = READY; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = PROG_SUSP; end PROG_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = PROG_BUSY; end BP_SETUP : begin if (rising_edge_Write) begin word_cnt = LatchedData + 1; next_state = BP_LOAD; end end BP_LOAD : begin if (rising_edge_Write) begin word_cnt = word_cnt - 1; if (word_cnt == 0) next_state = BP_CONFIRM; end end BP_CONFIRM : begin if (rising_edge_Write) begin if (LatchedData == 16'hD0) next_state = BP_BUSY; else next_state = READY; end end BP_BUSY : begin if (abort || (BuffProgram_out_event && ~BuffProgram_out && ~ExtendProgTime)) next_state = READY; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = BP_SUSP; else if (ExtendProgTime_event) next_state = current_state; end BP_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = BP_BUSY; end ERASE_SETUP : begin if (rising_edge_Write) begin if (LatchedData == 16'hD0) next_state = ERASE_BUSY; else next_state = READY; end end ERASE_BUSY : begin if ((abort || (ParameterErase_out_event && ~ParameterErase_out) || (falling_edge_MainErase_out ) ) && ~suspended_erase) next_state = READY; else if (falling_edge_EraseSuspend_out) next_state = ERS_SUSP; end ERS_SUSP : begin if (rising_edge_Write) begin case (LatchedData) 16'h10, 16'h40: next_state = PROG_SETUP_ERS_SUSP; 16'hE8 : next_state = BP_SETUP_ERS_SUSP; 16'hD0: next_state = ERASE_BUSY; 16'h60: next_state = LOCK_SETUP_ERS_SUSP; default: next_state = current_state; endcase end end PROG_SETUP_ERS_SUSP : begin if (rising_edge_Write) next_state = PROG_BUSY_ERS_SUSP; end PROG_BUSY_ERS_SUSP : begin if (abort || (WordProgram_out_event && ~WordProgram_out) ) next_state = ERS_SUSP; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = PROG_SUSP_ERS_SUSP; end PROG_SUSP_ERS_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = PROG_BUSY_ERS_SUSP; end BP_SETUP_ERS_SUSP : begin if (rising_edge_Write) begin word_cnt = LatchedData + 1; next_state = BP_LOAD_ERS_SUSP; end end BP_LOAD_ERS_SUSP : begin if (rising_edge_Write) begin word_cnt = word_cnt - 1; if (word_cnt == 0) next_state = BP_CONFIRM_ERS_SUSP; end end BP_CONFIRM_ERS_SUSP : begin if (rising_edge_Write) begin if (LatchedData == 16'hD0) next_state = BP_BUSY_ERS_SUSP; else next_state = ERS_SUSP; end end BP_BUSY_ERS_SUSP : begin if (abort || (BuffProgram_out_event && ~BuffProgram_out && ~ExtendProgTime)) next_state = ERS_SUSP; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = BP_SUSP_ERS_SUSP; else if (ExtendProgTime_event) next_state = current_state; end BP_SUSP_ERS_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = BP_BUSY_ERS_SUSP; end LOCK_SETUP_ERS_SUSP : begin if (rising_edge_Write) next_state = ERS_SUSP; end BEFP_SETUP : begin if (rising_edge_Write) begin if (LatchedData != 16'hD0) next_state = READY; else begin BEFP_block2 = BlockNumber(LatchedAddr); word_cnt = 32; end end else if (falling_edge_BEFPsetup_out) begin if (SR[4] == 1'b0) next_state = BEFP_LOAD; else next_state = READY; end end BEFP_LOAD : begin if (rising_edge_Write) begin if ((BlockNumber(LatchedAddr) != BEFP_block2) && LatchedData == 16'hFFFF) next_state = READY; else begin word_cnt = word_cnt - 1; if (word_cnt == 0) next_state = BEFP_BUSY; end end end BEFP_BUSY : begin if (falling_edge_BEFP_out) begin word_cnt = 32; next_state = BEFP_LOAD; end end endcase end end //////////////////////////////////////////////////////////////////////////// // Functional //////////////////////////////////////////////////////////////////////////// always @(rising_edge_Write or WordProgram_out_event or BuffProgram_out_event or falling_edge_RSTNeg or ParameterErase_out_event or falling_edge_MainErase_out or falling_edge_BEFPsetup_out or falling_edge_BEFP_out or abort or falling_edge_EraseSuspend_out or ProgramSuspend_out_event) begin if (rising_edge_Write) begin if ((current_state != RESET_POWER_DOWN) && (current_state != OTP_BUSY) && (current_state != PROG_BUSY) && (current_state != BP_BUSY) && (current_state != ERASE_BUSY) && (current_state != PROG_BUSY_ERS_SUSP) && (current_state != BP_BUSY_ERS_SUSP) && (current_state != BEFP_SETUP) && (current_state != BEFP_LOAD) && (LatchedData == 8'h50)) SR = 8'b10000000; end case (current_state) RESET_POWER_DOWN : begin SR = 8'b10000000; for (i=0;i<=BlockNum;i=i+1) begin Block_Lock[i] = LOCKED; BlockLockBit[i] = 1'b1; BlockLockDownBit[i] = 1'b0; end read_state = READ_ARRAY; RCR = 16'b1011111111001111; end READY : begin if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; endcase end end LOCK_SETUP, LOCK_SETUP_ERS_SUSP : begin if (rising_edge_Write) begin block_number = BlockNumber(LatchedAddr); if (LatchedData == 16'h03) begin RCR = A[15:0]; read_state = READ_ARRAY; end else if (LatchedData == 16'h01) begin read_state = READ_STATUS; if (Block_Lock[block_number] == UNLOCKED) Block_Lock[block_number] = LOCKED; BlockLockBit[block_number] = 1'b1; end else if (LatchedData == 16'hD0) begin read_state = READ_STATUS; if (!( (Block_Lock[block_number] == LOCKED_DOWN) && WPNeg == 1'b0) ) begin Block_Lock[block_number] = UNLOCKED; BlockLockBit[block_number] = 0; end end else if (LatchedData == 16'h2F) begin read_state = READ_STATUS; Block_Lock[block_number] = LOCKED_DOWN; BlockLockBit[block_number] = 1'b1; BlockLockDownBit[block_number] = 1'b1; end else begin read_state = READ_STATUS; SR[4] = 1'b1; SR[5] = 1'b1; end end else read_state = READ_STATUS; end OTP_SETUP : begin read_state = READ_STATUS; if (rising_edge_Write) begin DataBuff[0] = LatchedData; AddrBuff[0] = LatchedAddr; WordProgram_in = 1'b1; WordProgram_in <= #1 1'b0; end end OTP_BUSY : begin if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70, 16'h90, 16'h98 : read_state = READ_STATUS; endcase end mem_bits = PR[9'h80]; prog_bits = PR[9'h89]; if (VPP != 1'b1) begin SR[3] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] < 9'h80) || (AddrBuff[0] > 9'h109)) begin SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] > 9'h80) && (AddrBuff[0] < 9'h85)) begin SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] > 9'h84) && (AddrBuff[0] < 9'h89) && (mem_bits[1] != 1'b1)) begin SR[1] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] > 9'h89) && (AddrBuff[0] < 9'h10A) && (prog_bits[(AddrBuff[0]-9'h8A)/8] != 1'b1)) begin SR[1] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else SR[7] = 1'b0; if (falling_edge_RSTNeg) PR[AddrBuff[0]] = -1; if (WordProgram_out_event && ~WordProgram_out && ~abort) begin if (PR[AddrBuff[0]] > -1) begin prog_bits = DataBuff[0]; mem_bits = PR[AddrBuff[0]]; for (i=0; i<= 15; i=i+1) begin if (prog_bits[i] == 0) mem_bits[i] = 0; end PR[AddrBuff[0]] = mem_bits; end SR[7] = 1; end end PROG_SETUP, PROG_SETUP_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin DataBuff[0] = LatchedData; AddrBuff[0] = LatchedAddr; WordProgram_in = 1; WordProgram_in <= #1 0; end end PROG_BUSY, PROG_BUSY_ERS_SUSP : begin SR[2] = 0; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hB0 : begin ProgramSuspend_in = 1'b1; ProgramSuspend_in <= #1 1'b0; end endcase end block_number = BlockNumber(AddrBuff[0]); if (VPP == 1'b0) begin SR[3] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if (OTP[block_number] == 1'b1) begin SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if (Block_Lock[block_number] != UNLOCKED) begin SR[1] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else SR[7] = 1'b0; if (falling_edge_RSTNeg ) MemData[AddrBuff[0]] = -1; if (WordProgram_out_event && ~WordProgram_out && ~abort) begin if (MemData[AddrBuff[0]] > -1 ) begin prog_bits = DataBuff[0]; mem_bits = MemData[AddrBuff[0]]; for (i= 0; i<= 15; i=i+1) if (prog_bits[i] == 0) mem_bits[i] = 0; MemData[AddrBuff[0]] = mem_bits; end SR[7] = 1; end end PROG_SUSP, PROG_SUSP_ERS_SUSP : begin SR[2] = 1'b1; SR[7] = 1'b1; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hD0 : begin WordProgramResume = 1'b1; WordProgramResume <= #1 1'b0; end endcase end end BP_SETUP, BP_SETUP_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin word_number = LatchedData; word_cntr = 0; end end BP_LOAD, BP_LOAD_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin DataBuff[word_cntr] = LatchedData; AddrBuff[word_cntr] = LatchedAddr; if (word_cntr == 0) begin lowest_addr = LatchedAddr; highest_addr = LatchedAddr; end else begin if (LatchedAddr < lowest_addr) lowest_addr = LatchedAddr; if (LatchedAddr > highest_addr) highest_addr = LatchedAddr; end word_cntr = word_cntr + 1; end end BP_CONFIRM, BP_CONFIRM_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin if (LatchedData != 16'hD0) begin SR[7] = 1'b1; SR[5] = 1'b1; SR[4] = 1'b1; end else if (LatchedData == 16'hD0) begin BuffProgram_in = 1; BuffProgram_in <= #1 0; end end end BP_BUSY, BP_BUSY_ERS_SUSP : begin SR[2] = 0; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hB0 : begin suspended_bp = 1'b1; ProgramSuspend_in = 1'b1; ProgramSuspend_in <= #1 1'b0; end endcase end block_number = BlockNumber(AddrBuff[0]); if (VPP == 0) begin SR[3] = 1; SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if (OTP[block_number] == 1) begin SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if (Block_Lock[block_number] != UNLOCKED) begin SR[1] = 1; SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if ((lowest_addr < AddrBuff[0]) || (highest_addr > (AddrBuff[0]+word_number)) && (word_number != -1)) begin SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if (BlockNumber(highest_addr) != block_number) begin SR[4] = 1; SR[5] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else SR[7] = 0; if (falling_edge_RSTNeg) begin for (j=0;j<=word_number; j=j+1) MemData[AddrBuff[j]] = -1; end if ( BuffProgram_out_event && ~BuffProgram_out && ~suspended_bp && ~abort ) begin for (j=0; j<= word_number; j=j+1) begin if (MemData[AddrBuff[j]] > -1 ) begin prog_bits = DataBuff[j]; mem_bits = MemData[AddrBuff[j]]; for (i=0; i<=15; i=i+1) begin if (prog_bits[i] == 1'b0) mem_bits[i] = 1'b0; end MemData[AddrBuff[j]] = mem_bits; end end for (j=0; j<= word_number; j=j+1) begin if ((AddrBuff[j] / 32) != (AddrBuff[0]/32)) begin ExtendProgTime = 1; ExtendProgTime <= #1 0; word_number = -1; BuffProgram_in = 1'b1; BuffProgram_in <= #1 1'b0; end end SR[7] = 1; end end BP_SUSP, BP_SUSP_ERS_SUSP : begin SR[2] = 1'b1; SR[7] = 1'b1; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hD0 : begin suspended_bp = 1'b0; BP_ProgramResume = 1'b1; BP_ProgramResume <= #1 1'b0; end endcase end end ERASE_SETUP : begin read_state = READ_STATUS; if (rising_edge_Write) begin if (LatchedData == 16'hD0) begin erasing_block = BlockNumber(LatchedAddr); if (BlockSize(erasing_block) == ParameterBlockSize) begin ParameterErase_in = 1; ParameterErase_in <= #1 0; end else begin MainErase_in = 1; MainErase_in <= #1 0; end end else begin SR[7] = 1'b1; SR[5] = 1'b1; SR[4] = 1'b1; end end end ERASE_BUSY : begin SR[6] = 0; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hB0 : begin suspended_erase = 1'b1; EraseSuspend_in = 1'b1; EraseSuspend_in <= #1 1'b0; end endcase end aborted = 1'b0; if (VPP == 1'b0) begin SR[3] = 1'b1; SR[5] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; aborted = 1'b1; end else if (OTP[erasing_block] == 1'b1) begin SR[5] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; aborted = 1'b1; end else if (Block_Lock[erasing_block] != UNLOCKED) begin SR[1] = 1'b1; SR[5] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; aborted = 1'b1; end else SR[7] = 1'b0; block_size = BlockSize(erasing_block); start_addr = StartBlockAddr(erasing_block); if (~aborted) begin for (i = 0; i< block_size; i=i+1 ) MemData[start_addr + i] = -1; end if ( ( (ParameterErase_out_event && ~ParameterErase_out) || (falling_edge_MainErase_out)) && ~abort && ~suspended_erase) begin SR[7] = 1'b1; for (i=0;i<=block_size;i=i+1) MemData[start_addr + i] = MaxData; end end ERS_SUSP : begin SR[6] = 1'b1; SR[7] = 1'b1; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hD0 : begin suspended_erase = 1'b0; if (BlockSize(erasing_block) == ParameterBlockSize) begin ParameterEraseResume = 1'b1; ParameterEraseResume <= #1 1'b0; end else begin MainEraseResume = 1'b1; MainEraseResume <= #1 1'b0; end end endcase end end BEFP_SETUP : begin read_state = READ_STATUS; if (rising_edge_Write && (LatchedData == 16'hD0)) begin BEFP_addr = LatchedAddr; BEFP_block = BlockNumber(LatchedAddr); word_cntr = 0; if ((VPP != 1'b1) || (VPP_voltage != 9)) begin SR[3] = 1'b1; SR[4] = 1'b1; end if (Block_Lock[BEFP_block] != UNLOCKED) begin SR[1] = 1'b1; SR[4] = 1'b1; end else if (((BEFP_addr % 32) != 0) || (OTP[BEFP_block] == 1'b1)) SR[4] = 1'b1; BEFPsetup_in = 1'b1; BEFPsetup_in <= #1 1'b0; end else if (falling_edge_BEFPsetup_out) begin if (SR[4] == 0) begin SR[7] = 0; SR[0] = 0; end end end BEFP_LOAD : begin if (rising_edge_Write) begin if ((BlockNumber(LatchedAddr) != BEFP_block) && (LatchedData == 16'hFFFF)) begin SR[7] = 1'b1; SR[0] = 1'b0; end else begin DataBuff[word_cntr] = LatchedData; word_cntr = word_cntr + 1; if (word_cntr == 31) begin BEFP_in = 1'b1; BEFP_in <= #1 1'b0; end end end end BEFP_BUSY : begin if (falling_edge_RSTNeg) begin for (j = 0 ; j<= 31; j=j+1) MemData[BEFP_addr+j] = -1; end if (falling_edge_BEFP_out) begin for (j=0;j<=31;j=j+1) begin if (MemData[BEFP_addr+j] > -1) begin prog_bits = DataBuff[j]; mem_bits = MemData[BEFP_addr + j]; for (i=0;i<=15;i=i+1) begin if (prog_bits[i] == 1'b0) mem_bits[i] = 1'b0; end MemData[BEFP_addr + j] = mem_bits; end end BEFP_addr = BEFP_addr + 32; if ((BEFP_addr > MemSize) || (BlockNumber(BEFP_addr) > BEFP_block)) BEFP_addr = BEFP_addr - BlockSize(BEFP_block); SR[0] = 1'b0; word_cntr = 0; end else SR[0] = 1'b1; end endcase end /////////////////////////////////////////////////////////// // Combinatorial output generation /////////////////////////////////////////////////////////// always @(Ahigh_event or Alow_event or rising_edge_Read or A_event or OENeg or falling_edge_Read or CENeg ) begin : Output case (read_state) READ_ARRAY : begin if (RCR[15] == 1'b1) begin if (Ahigh_event && ~ADVNeg) ReadAddr = A; else if (Alow_event) ReadAddr = ReadAddr - (ReadAddr % 4) + A[1:0]; end if (current_state == PROG_BUSY || current_state == PROG_BUSY_ERS_SUSP || current_state == BP_BUSY || current_state == BP_BUSY_ERS_SUSP || current_state == ERASE_BUSY) DQOut_tmp = 16'bx; else begin if (MemData[ReadAddr] > -1) DQOut_tmp = MemData[ReadAddr]; else DQOut_tmp = 16'bx; end end READ_ID : begin if ( ( ( (ReadAddr-2) % MainBlockSize) == 0) || ((ReadAddr > (MemSize - MainBlockSize)) && (((ReadAddr-2) % ParameterBlockSize) == 0))) begin DQOut_tmp[0] = BlockLockBit[BlockNumber(ReadAddr)]; DQOut_tmp[1] = BlockLockDownBit[BlockNumber(ReadAddr)]; DQOut_tmp[15:2] = 14'b0; end else if (ReadAddr == 0) DQOut_tmp = 16'h0089; else if (ReadAddr == 1) begin DQOut_tmp = DeviceID_T; end else if (ReadAddr == 5) DQOut_tmp = RCR; else if ((ReadAddr >= 9'h80) && (ReadAddr <= 9'h109)) begin if (PR[ReadAddr] > -1) DQOut_tmp = PR[ReadAddr]; else DQOut_tmp = 16'bx; end end READ_QUERY : begin if (((ReadAddr >= 9'h10) && (ReadAddr <= 9'h38)) || ((ReadAddr >= 9'h10A) && (ReadAddr <= 9'h156))) DQOut_tmp = CFI_array[ReadAddr]; else DQOut_tmp = 16'b0; end READ_STATUS : begin DQOut_tmp[15:8] = 8'b0; DQOut_tmp[7:0] = SR; end endcase if (RCR[15] == 1'b1) // Asynchronous read begin if (rising_edge_Read || (Read && ((A_event && ~ADVNeg) || Alow_event))) DQOut_zd = DQOut_tmp; else if (falling_edge_Read) DQOut_zd = 16'bz; end else // Burst read begin if (rising_edge_Read || falling_edge_Read) begin if ((burst_cntr > BurstLength) && (BurstLength != 0)) read_out = 1'b0; else if (read_state == READ_ARRAY) begin if ((RCR[9] == 1'b0) && (RCR[13:11] > 4) && ((burst_cntr >= 5) || (burst_cntr < 1))) begin read_out = 1'b0; if (burst_cntr >= 5) burst_cntr = 5 - RCR[13:11]; end else begin read_out = 1'b1; if (ReadAddr < MemSize) ReadAddr = ReadAddr + 1; if ((RCR[3] == 1'b0) && (BurstLength != 0) && ((ReadAddr % BurstLength) == 0)) ReadAddr = ReadAddr - BurstLength; end end else read_out = 1'b1; if (read_out) begin DQOut_zd = DQOut_tmp; end end end end always @(CENeg, OENeg) begin : OutputDisable if ((CENeg) || (OENeg)) DQOut_zd = 16'bz; else if ((~CENeg) && (~OENeg) && (RCR[15] == 1'b0)) DQOut_zd = 16'bx; end //////////////////////////////////////////////////////////////// // WAIT output control process //////////////////////////////////////////////////////////////// always @(AssertWAITOut_event or DeassertWAITOut_event or falling_edge_OENeg or OENeg or CENeg or falling_edge_CENeg) begin : WAITOut_control if (OENeg || CENeg || ~RSTNeg || (current_state == RESET_POWER_DOWN)) WAITOut_zd = 1'bz; else if ((falling_edge_OENeg && ~CENeg) || (falling_edge_CENeg && ~OENeg)) begin if (RCR[15] == 1'b1) begin if (~RCR[10]) WAITOut_zd = 1'b1; else WAITOut_zd = 1'b0; end else begin if (~RCR[10]) WAITOut_zd = 1'b0; else WAITOut_zd = 1'b1; end end else if (AssertWAITOut_event) begin if (~RCR[10]) WAITOut_zd = 1'b0; else WAITOut_zd = 1'b1; end else if (DeassertWAITOut_event) begin if (~RCR[10]) WAITOut_zd = 1'b1; else WAITOut_zd = 1'b0; end end /////////////////////////////////////////////////////////////////// // Timing control for erase start, suspend and resume /////////////////////////////////////////////////////////////////// always @(rising_edge_MainErase_in or rising_edge_ParameterErase_in or RstDuringErsPrg_out_event or abort_event or rising_edge_ParameterEraseResume or EraseSuspend_event or rising_edge_MainEraseResume ) begin : erase_time merase_duration = tdevice_EraseMain; perase_duration = tdevice_EraseParameter; if (rising_edge_MainErase_in) begin melapsed = 0; MainErase_out <= #1 1'b1; ->merase_event; mstart = $time; end if (rising_edge_ParameterErase_in) begin pelapsed = 0; ParameterErase_out <= #1 1'b1; ->perase_event; pstart = $time; end if ((RstDuringErsPrg_out_event && ~RstDuringErsPrg_out) || abort_event) begin disable merase_process; disable perase_process; MainErase_out = 1'b0; ParameterErase_out = 1'b0; end if (EraseSuspend_event && ~EraseSuspend_out) begin disable merase_process; melapsed = $time - mstart; merase_duration = merase_duration - melapsed; disable perase_process; pelapsed = $time - pstart; perase_duration = perase_duration - pelapsed; end if (rising_edge_MainEraseResume) begin mstart = $time; MainErase_out = 1'b1; -> merase_event; end if (rising_edge_ParameterEraseResume) begin pstart = $time; ParameterErase_out = 1'b1; ->perase_event; end end always @(merase_event) begin : merase_process #merase_duration MainErase_out = 1'b0; end always @(perase_event) begin : perase_process #perase_duration ParameterErase_out = 1'b0; end ///////////////////////////////////////////////////////////////// // Timing control for programming start, suspend and resume ///////////////////////////////////////////////////////////////// time buffp_duration; time wordp_duration; time welapsed; time elapsed; event prog_event; event buffp_event; time wstart; time start; reg rising_edge_WordProgram_in = 1'b0; reg rising_edge_BuffProgram_in = 1'b0; reg rising_edge_WordProgramResume = 1'b0; reg rising_edge_BP_ProgramResume = 1'b0; always @(rising_edge_WordProgram_in or rising_edge_BuffProgram_in or RstDuringErsPrg_out_event or abort_event or ProgramSuspend_out_event or rising_edge_WordProgramResume or rising_edge_BP_ProgramResume) begin if (VPP_voltage != 9) begin buffp_duration = tdevice_BuffProgram; wordp_duration = tdevice_WordProgram; end else begin buffp_duration = tdevice_BuffProgram9V; wordp_duration = tdevice_WordProgram9V; end if (rising_edge_WordProgram_in) begin welapsed = 0; WordProgram_out <= #1 1'b1; -> prog_event; wstart = $time; end if (rising_edge_BuffProgram_in) begin elapsed = 0; BuffProgram_out = 1'b1; -> buffp_event; start = $time; end if ((RstDuringErsPrg_out_event && ~RstDuringErsPrg_out) || abort_event) begin disable prog_process; disable buffp_process; WordProgram_out = 1'b0; BuffProgram_out = 1'b0; end if (ProgramSuspend_out_event && ~ProgramSuspend_out) begin disable prog_process; disable buffp_process; elapsed = $time - start; welapsed = $time - wstart; buffp_duration = buffp_duration - elapsed; wordp_duration = wordp_duration - welapsed; end if (rising_edge_WordProgramResume) begin wstart = $time; WordProgram_out = 1'b1; -> prog_event; end if (rising_edge_BP_ProgramResume) begin start = $time; BuffProgram_out = 1'b1; -> buffp_event; end end always @(prog_event) begin : prog_process #wordp_duration WordProgram_out = 1'b0; end always @(buffp_event) begin : buffp_process #buffp_duration BuffProgram_out = 1'b0; end //////////////////////////////////////////////////////////////////// //Output timing control //////////////////////////////////////////////////////////////////// always @(DQOut_zd) begin : OutputGen if (DQOut_zd[0] !== 1'bz) begin CEDQ_t = CENeg_event + CEDQ_01; OEDQ_t = OENeg_event + OEDQ_01; ADDRDQ_t = ADDR_event + ADDRDQIN_01; if (Pmode) ADDRDQ_t = ADDR_event + ADDRDQPAGE_01; FROMCE = ((CEDQ_t >= OEDQ_t) && (CEDQ_t >= $time)); FROMOE = ((OEDQ_t >= CEDQ_t) && (OEDQ_t >= $time)); FROMADDR = 1'b1; DQOut_Pass = DQOut_zd; end end always @(DQOut_zd) begin if (DQOut_zd[0] === 1'bz) begin disable OutputGen; FROMCE = 1'b1; FROMOE = 1'b1; FROMADDR = 1'b0; DQOut_Pass = DQOut_zd; end end reg BuffInOE, BuffInCE, BuffInADDRIN, BuffInADDRPAGE; wire BuffOutOE, BuffOutCE, BuffOutADDRIN, BuffOutADDRPAGE; BUFFER BUFOE (BuffOutOE, BuffInOE); BUFFER BUFCE (BuffOutCE, BuffInCE); BUFFER BUFADDRIN (BuffOutADDRIN, BuffInADDRIN); BUFFER BUFADDRPAGE (BuffOutADDRPAGE, BuffInADDRPAGE); initial begin BuffInOE = 1'b1; BuffInCE = 1'b1; BuffInADDRIN = 1'b1; BuffInADDRPAGE = 1'b1; end always @(posedge BuffOutOE) begin OEDQ_01 = $time; end always @(posedge BuffOutCE) begin CEDQ_01 = $time; end always @(posedge BuffOutADDRIN) begin ADDRDQIN_01 = $time; end always @(posedge BuffOutADDRPAGE) begin ADDRDQPAGE_01 = $time; end ///////////////////////////////////////////////////////////////////////////// // functions & tasks ///////////////////////////////////////////////////////////////////////////// function integer BlockNumber; input [HiAddrBit:0] ADDR; integer block_number; begin block_number = ADDR / MainBlockSize; if (block_number == (MemSize/MainBlockSize)) block_number = block_number + (ADDR % MainBlockSize) / ParameterBlockSize; BlockNumber = block_number; end endfunction function integer StartBlockAddr; input [16:0] block_number; integer start_block_addr; begin start_block_addr = block_number * MainBlockSize; if (block_number > (BlockNum - 3)) start_block_addr = start_block_addr - (block_number + 3 - BlockNum) * MainBlockSize + (block_number + 3 - BlockNum) * ParameterBlockSize; StartBlockAddr = start_block_addr; end endfunction function integer BlockSize; input [16:0] block_number; integer block_number; integer block_size; begin if ((block_number < 4) || (block_number > (BlockNum - 4)) ) block_size = ParameterBlockSize; else block_size = MainBlockSize; BlockSize = block_size; end endfunction //////////////////////////////////////////////////////////////// // edge controll processes //////////////////////////////////////////////////////////////// always @(negedge ADVNeg) begin falling_edge_ADVNeg = 1; #1 falling_edge_ADVNeg = 0; end always @(posedge ADVNeg) begin rising_edge_ADVNeg = 1; #1 rising_edge_ADVNeg = 0; end always @(posedge CLOCK) begin rising_edge_CLOCK = 1; #1 rising_edge_CLOCK = 0; end always @(negedge RSTNeg) begin falling_edge_RSTNeg = 1; #1 falling_edge_RSTNeg = 0; end always @(posedge RSTNeg) begin rising_edge_RSTNeg = 1; #1 rising_edge_RSTNeg = 0; end always @(posedge Write) begin rising_edge_Write = 1; #1 rising_edge_Write = 0; end always @(RstDuringErsPrg_out) begin RstDuringErsPrg_out_event = 1; #1 RstDuringErsPrg_out_event = 0; end always @(WordProgram_out) begin WordProgram_out_event = 1; #1 WordProgram_out_event = 0; end always @(ProgramSuspend_out) begin ProgramSuspend_out_event = 1; #1 ProgramSuspend_out_event = 0; end always @(BuffProgram_out) begin if (~suspended_bp) begin BuffProgram_out_event = 1; #1 BuffProgram_out_event = 0; end end always @(posedge ExtendProgTime) begin ExtendProgTime_event = 1; #1 ExtendProgTime_event = 0; end always @(ParameterErase_out) begin ParameterErase_out_event = 1; #1 ParameterErase_out_event = 0; end always @(negedge MainErase_out) begin falling_edge_MainErase_out = 1; #1 falling_edge_MainErase_out = 0; end always @(negedge EraseSuspend_out) begin falling_edge_EraseSuspend_out = 1; #1 falling_edge_EraseSuspend_out = 0; end always @(negedge BEFPsetup_out) begin falling_edge_BEFPsetup_out = 1; #1 falling_edge_BEFPsetup_out = 0; end always @(negedge BEFP_out) begin falling_edge_BEFP_out = 1; #1 falling_edge_BEFP_out = 0; end always @(A[HiAddrBit:2]) begin Ahigh_event = 1; #1 Ahigh_event = 0; end always @(A[1:0]) begin Alow_event = 1; #1 Alow_event = 0; end always @(A) begin A_event = 1; #1 A_event = 0; end always @(posedge Read) begin rising_edge_Read = 1; #1 rising_edge_Read = 0; end always @(negedge Read) begin falling_edge_Read = 1; #1 falling_edge_Read = 0; end always @(posedge CENeg) begin rising_edge_CENeg = 1; #1 rising_edge_CENeg = 0; end always @(posedge OENeg) begin rising_edge_OENeg = 1; #1 rising_edge_OENeg = 0; end always @(AssertWAITOut) begin AssertWAITOut_event = 1; #1 AssertWAITOut_event = 0; end always @(DeassertWAITOut) begin DeassertWAITOut_event = 1; #1 DeassertWAITOut_event = 0; end always @(negedge OENeg) begin falling_edge_OENeg = 1; #1 falling_edge_OENeg = 0; end always @(negedge CENeg) begin falling_edge_CENeg = 1; #1 falling_edge_CENeg = 0; end always @(posedge WENeg) begin rising_edge_WENeg = 1; #1 rising_edge_WENeg = 0; end always @(posedge WordProgram_in) begin rising_edge_WordProgram_in = 1'b1; #1 rising_edge_WordProgram_in = 1'b0; end always @(posedge BuffProgram_in) begin rising_edge_BuffProgram_in = 1'b1; #1 rising_edge_BuffProgram_in = 1'b0; end always @(posedge BP_ProgramResume) begin rising_edge_BP_ProgramResume = 1'b1; #1 rising_edge_BP_ProgramResume = 1'b0; end always @(posedge WordProgramResume) begin rising_edge_WordProgramResume = 1'b1; #1 rising_edge_WordProgramResume = 1'b0; end always @(posedge MainErase_in) begin rising_edge_MainErase_in = 1'b1; #1 rising_edge_MainErase_in = 1'b0; end always @(posedge ParameterErase_in) begin rising_edge_ParameterErase_in = 1'b1; #1 rising_edge_ParameterErase_in = 1'b0; end always @(posedge MainEraseResume) begin rising_edge_MainEraseResume = 1'b1; #1 rising_edge_MainEraseResume = 1'b0; end always @(posedge ParameterEraseResume) begin rising_edge_ParameterEraseResume = 1'b1; #1 rising_edge_ParameterEraseResume = 1'b0; end always @(EraseSuspend_out) begin EraseSuspend_event = 1'b1; #1 EraseSuspend_event = 1'b0; end endmodule ////////////////////////////////////////////////////////////////////////////// // MODULE DECLARATION, Bottom Parameter Block Configuration // ////////////////////////////////////////////////////////////////////////////// module i28f256p33_2 ( A24 , A23 , A22 , A21 , A20 , A19 , A18 , A17 , A16 , A15 , A14 , A13 , A12 , A11 , A10 , A9 , A8 , A7 , A6 , A5 , A4 , A3 , A2 , A1 , DQ15 , DQ14 , DQ13 , DQ12 , DQ11 , DQ10 , DQ9 , DQ8 , DQ7 , DQ6 , DQ5 , DQ4 , DQ3 , DQ2 , DQ1 , DQ0 , ADVNeg , CENeg , CLK , OENeg , RSTNeg , WENeg , WPNeg , VPP , WAITOut ); //////////////////////////////////////////////////////////////////////// // Port / Part Pin Declarations //////////////////////////////////////////////////////////////////////// input A24 ; input A23 ; input A22 ; input A21 ; input A20 ; input A19 ; input A18 ; input A17 ; input A16 ; input A15 ; input A14 ; input A13 ; input A12 ; input A11 ; input A10 ; input A9 ; input A8 ; input A7 ; input A6 ; input A5 ; input A4 ; input A3 ; input A2 ; input A1 ; inout DQ15 ; inout DQ14 ; inout DQ13 ; inout DQ12 ; inout DQ11 ; inout DQ10 ; inout DQ9 ; inout DQ8 ; inout DQ7 ; inout DQ6 ; inout DQ5 ; inout DQ4 ; inout DQ3 ; inout DQ2 ; inout DQ1 ; inout DQ0 ; input ADVNeg ; input CENeg ; input CLK ; input OENeg ; input RSTNeg ; input WENeg ; input WPNeg ; input VPP ; output WAITOut ; // interconnect path delay signals wire A24_ipd ; wire A23_ipd ; wire A22_ipd ; wire A21_ipd ; wire A20_ipd ; wire A19_ipd ; wire A18_ipd ; wire A17_ipd ; wire A16_ipd ; wire A15_ipd ; wire A14_ipd ; wire A13_ipd ; wire A12_ipd ; wire A11_ipd ; wire A10_ipd ; wire A9_ipd ; wire A8_ipd ; wire A7_ipd ; wire A6_ipd ; wire A5_ipd ; wire A4_ipd ; wire A3_ipd ; wire A2_ipd ; wire A1_ipd ; wire [23 : 0] A; assign A = { A24_ipd, A23_ipd, A22_ipd, A21_ipd, A20_ipd, A19_ipd, A18_ipd, A17_ipd, A16_ipd, A15_ipd, A14_ipd, A13_ipd, A12_ipd, A11_ipd, A10_ipd, A9_ipd, A8_ipd, A7_ipd, A6_ipd, A5_ipd, A4_ipd, A3_ipd, A2_ipd, A1_ipd }; wire DQ15_ipd ; wire DQ14_ipd ; wire DQ13_ipd ; wire DQ12_ipd ; wire DQ11_ipd ; wire DQ10_ipd ; wire DQ9_ipd ; wire DQ8_ipd ; wire DQ7_ipd ; wire DQ6_ipd ; wire DQ5_ipd ; wire DQ4_ipd ; wire DQ3_ipd ; wire DQ2_ipd ; wire DQ1_ipd ; wire DQ0_ipd ; wire [15 : 0 ] DQIn; assign DQIn = {DQ15_ipd, DQ14_ipd, DQ13_ipd, DQ12_ipd, DQ11_ipd, DQ10_ipd, DQ9_ipd, DQ8_ipd, DQ7_ipd, DQ6_ipd, DQ5_ipd, DQ4_ipd, DQ3_ipd, DQ2_ipd, DQ1_ipd, DQ0_ipd }; wire [15 : 0 ] DQOut; assign DQOut = {DQ15, DQ14, DQ13, DQ12, DQ11, DQ10, DQ9, DQ8, DQ7, DQ6, DQ5, DQ4, DQ3, DQ2, DQ1, DQ0 }; wire ADVNeg_ipd ; wire CENeg_ipd ; wire CLK_ipd ; wire OENeg_ipd ; wire RSTNeg_ipd ; wire WENeg_ipd ; wire WPNeg_ipd ; wire DQ15_zd ; wire DQ14_zd ; wire DQ13_zd ; wire DQ12_zd ; wire DQ11_zd ; wire DQ10_zd ; wire DQ9_zd ; wire DQ8_zd ; wire DQ7_zd ; wire DQ6_zd ; wire DQ5_zd ; wire DQ4_zd ; wire DQ3_zd ; wire DQ2_zd ; wire DQ1_zd ; wire DQ0_zd ; wire DQ15_Pass ; wire DQ14_Pass ; wire DQ13_Pass ; wire DQ12_Pass ; wire DQ11_Pass ; wire DQ10_Pass ; wire DQ9_Pass ; wire DQ8_Pass ; wire DQ7_Pass ; wire DQ6_Pass ; wire DQ5_Pass ; wire DQ4_Pass ; wire DQ3_Pass ; wire DQ2_Pass ; wire DQ1_Pass ; wire DQ0_Pass ; reg [15 : 0] DQOut_zd = 16'bz; reg [15 : 0] DQOut_Pass = 16'bz; assign {DQ15_zd, DQ14_zd, DQ13_zd, DQ12_zd, DQ11_zd, DQ10_zd, DQ9_zd, DQ8_zd, DQ7_zd, DQ6_zd, DQ5_zd, DQ4_zd, DQ3_zd, DQ2_zd, DQ1_zd, DQ0_zd } = DQOut_zd; assign {DQ15_Pass, DQ14_Pass, DQ13_Pass, DQ12_Pass, DQ11_Pass, DQ10_Pass, DQ9_Pass, DQ8_Pass, DQ7_Pass, DQ6_Pass, DQ5_Pass, DQ4_Pass, DQ3_Pass, DQ2_Pass, DQ1_Pass, DQ0_Pass } = DQOut_Pass; reg WAITOut_zd = 1'bz; parameter mem_file_name = "none"; parameter otp_blocks_file = "none"; parameter prot_reg_file = "none"; parameter UserPreload = 1'b0; parameter TimingModel = "DefaultTimingModel"; parameter VPP_voltage = 9; // this parameter specifies if // 9V or 2V is applied to Vpp pin // (when VPP pin is 1'b1) parameter MaxData = 16'hFFFF; parameter HiAddrBit = 23; parameter MemSize = 32'hFFFFFF; parameter BlockNum = 258; parameter DeviceID_B = 16'h8922; parameter DeviceID_T = 16'h891F; parameter MainBlockSize = 32'h10000; parameter ParameterBlockSize = 32'h04000; // If speedsimulation is needed uncomment following line // `define SPEEDSIM; // FSM states parameter RESET_POWER_DOWN = 5'd0; parameter READY = 5'd1; parameter LOCK_SETUP = 5'd2; parameter OTP_SETUP = 5'd3; parameter OTP_BUSY = 5'd4; parameter PROG_SETUP = 5'd5; parameter PROG_BUSY = 5'd6; parameter PROG_SUSP = 5'd7; parameter BP_SETUP = 5'd8; parameter BP_LOAD = 5'd9; parameter BP_CONFIRM = 5'd10; parameter BP_BUSY = 5'd11; parameter BP_SUSP = 5'd12; parameter ERASE_SETUP = 5'd13; parameter ERASE_BUSY = 5'd14; parameter ERS_SUSP = 5'd15; parameter PROG_SETUP_ERS_SUSP = 5'd16; parameter PROG_BUSY_ERS_SUSP = 5'd17; parameter PROG_SUSP_ERS_SUSP = 5'd18; parameter BP_SETUP_ERS_SUSP = 5'd19; parameter BP_LOAD_ERS_SUSP = 5'd20; parameter BP_CONFIRM_ERS_SUSP = 5'd21; parameter BP_BUSY_ERS_SUSP = 5'd22; parameter BP_SUSP_ERS_SUSP = 5'd23; parameter LOCK_SETUP_ERS_SUSP = 5'd24; parameter BEFP_SETUP = 5'd25; parameter BEFP_LOAD = 5'd26; parameter BEFP_BUSY = 5'd27; // read mode parameter READ_ARRAY = 2'd0; parameter READ_ID = 2'd1; parameter READ_QUERY = 2'd2; parameter READ_STATUS = 2'd3; reg [5:0] current_state; reg [5:0] next_state; reg [1:0] read_state; reg deq; // Memory declaration integer MemData[0:MemSize]; // internal delays reg WordProgram_in = 1'b0; reg WordProgram_out = 1'b0; reg BuffProgram_in = 1'b0; reg BuffProgram_out = 1'b0; reg BEFP_in = 1'b0; reg BEFP_out = 1'b0; reg BEFPsetup_in = 1'b0; reg BEFPsetup_out = 1'b0; reg ParameterErase_in = 1'b0; reg MainErase_in = 1'b0; reg ParameterErase_out = 1'b0; reg MainErase_out = 1'b0; reg ProgramSuspend_in = 1'b0; reg ProgramSuspend_out = 1'b0; reg EraseSuspend_in = 1'b0; reg EraseSuspend_out = 1'b0; reg RstDuringErsPrg_in = 1'b0; reg RstDuringErsPrg_out = 1'b0; // event control registers reg falling_edge_ADVNeg = 1'b0; reg falling_edge_RSTNeg = 1'b0; reg falling_edge_BEFPsetup_out = 1'b0; reg falling_edge_BEFP_out = 1'b0; reg falling_edge_Read = 1'b0; reg falling_edge_OENeg = 1'b0; reg falling_edge_CENeg = 1'b0; reg rising_edge_ADVNeg = 1'b0; reg rising_edge_CLOCK = 1'b0; reg rising_edge_WENeg = 1'b0; reg rising_edge_CENeg = 1'b0; reg rising_edge_RSTNeg = 1'b0; reg rising_edge_Write = 1'b0; reg rising_edge_Read = 1'b0; reg RstDuringErsPrg_out_event = 1'b0; reg WordProgram_out_event = 1'b0; reg abort_event = 1'b0; reg ProgramSuspend_out_event = 1'b0; reg BuffProgram_out_event = 1'b0; reg ExtendProgTime_event = 1'b0; reg ParameterErase_out_event = 1'b0; reg falling_edge_MainErase_out = 1'b0; reg falling_edge_EraseSuspend_out = 1'b0; reg Ahigh_event = 1'b0; reg Alow_event = 1'b0; reg A_event = 1'b0; reg rising_edge_OENeg = 1'b0; reg AssertWAITOut_event = 1'b0; reg DeassertWAITOut_event = 1'b0; reg rising_edge_MainErase_in = 1'b0; reg rising_edge_ParameterErase_in = 1'b0; reg EraseSuspend_event = 1'b0; reg rising_edge_MainEraseResume = 1'b0; reg rising_edge_ParameterEraseResume = 1'b0; integer i,j; // Bus cycle decode reg CLOCK = 1'b0; reg Write = 1'b0; reg Read = 1'b0; reg Pmode = 1'b0; // Functional reg abort = 1'b0; reg ExtendProgTime = 1'b0; reg AssertWAITOut = 1'b0; reg DeassertWAITOut = 1'b0; //Block Lock Status parameter UNLOCKED = 2'd0; parameter LOCKED = 2'd1; parameter LOCKED_DOWN = 2'd2; integer Block_Lock[BlockNum:0]; reg [BlockNum:0] BlockLockBit; reg [BlockNum:0] BlockLockDownBit; reg OTP[0:BlockNum]; // Status Register reg[7:0] SR = 8'b10000000; // Read Configuration Register reg[15:0] RCR = 16'b1011111111001111; // Protection registers integer PR[9'h80:9'h109]; // CFI array integer CFI_array[9'h10:9'h156]; reg LATCHED = 1'b0; reg [15:0] LatchedData; reg [HiAddrBit:0] LatchedAddr; integer ReadAddr; integer DataBuff[0:31]; integer AddrBuff[0:31]; integer burst_cntr; integer BurstLength; integer BurstDelay; integer DataHold; integer WCount; integer word_cntr; integer word_cnt; integer word_number; integer block_number; integer erasing_block; integer lowest_addr; integer highest_addr; integer start_addr; integer BEFP_addr; integer BEFP_block; integer BEFP_block2; reg [15:0] mem_bits; reg [15:0] prog_bits; reg [15:0] DQOut_tmp; reg read_out = 1'b0; reg suspended_bp = 1'b0; reg suspended_erase = 1'b0; reg aborted ; integer block_size; reg ParameterEraseResume; reg MainEraseResume; reg WordProgramResume; reg BP_ProgramResume; time merase_duration; time perase_duration; time melapsed; time pelapsed; time mstart; time pstart; event merase_event; event perase_event; // timing check violation reg Viol = 1'b0; //TPD_XX_DATA time OEDQ_t; time CEDQ_t; time ADDRDQ_t; time OENeg_event; time CENeg_event; time ADDR_event; reg FROMOE; reg FROMCE; reg FROMADDR; reg OPENLATCH; integer OEDQ_01; integer CEDQ_01; integer ADDRDQIN_01; integer ADDRDQPAGE_01; reg [15:0] TempData; wire InitialPageAccess; assign InitialPageAccess = FROMADDR && ~Pmode; wire SubsequentPageAccess; assign SubsequentPageAccess = FROMADDR && Pmode; wire CLK_rising; assign CLK_rising = RCR[6] && ~CENeg_ipd; wire CLK_falling; assign CLK_falling = ~(RCR[6]) && ~CENeg_ipd; /////////////////////////////////////////////////////////////////////////////// //Interconnect Path Delay Section /////////////////////////////////////////////////////////////////////////////// buf (A24_ipd, A24); buf (A23_ipd, A23); buf (A22_ipd, A22); buf (A21_ipd, A21); buf (A20_ipd, A20); buf (A19_ipd, A19); buf (A18_ipd, A18); buf (A17_ipd, A17); buf (A16_ipd, A16); buf (A15_ipd, A15); buf (A14_ipd, A14); buf (A13_ipd, A13); buf (A12_ipd, A12); buf (A11_ipd, A11); buf (A10_ipd, A10); buf (A9_ipd , A9 ); buf (A8_ipd , A8 ); buf (A7_ipd , A7 ); buf (A6_ipd , A6 ); buf (A5_ipd , A5 ); buf (A4_ipd , A4 ); buf (A3_ipd , A3 ); buf (A2_ipd , A2 ); buf (A1_ipd , A1 ); buf (DQ15_ipd, DQ15); buf (DQ14_ipd, DQ14); buf (DQ13_ipd, DQ13); buf (DQ12_ipd, DQ12); buf (DQ11_ipd, DQ11); buf (DQ10_ipd, DQ10); buf (DQ9_ipd , DQ9 ); buf (DQ8_ipd , DQ8 ); buf (DQ7_ipd , DQ7 ); buf (DQ6_ipd , DQ6 ); buf (DQ5_ipd , DQ5 ); buf (DQ4_ipd , DQ4 ); buf (DQ3_ipd , DQ3 ); buf (DQ2_ipd , DQ2 ); buf (DQ1_ipd , DQ1 ); buf (DQ0_ipd , DQ0 ); buf (RSTNeg_ipd , RSTNeg ); buf (ADVNeg_ipd , ADVNeg ); buf (CLK_ipd , CLK ); buf (CENeg_ipd , CENeg ); buf (OENeg_ipd , OENeg ); buf (WENeg_ipd , WENeg ); buf (WPNeg_ipd , WPNeg ); /////////////////////////////////////////////////////////////////////////////// // Propagation delay Section /////////////////////////////////////////////////////////////////////////////// nmos (DQ15, DQ15_Pass , 1); nmos (DQ14, DQ14_Pass , 1); nmos (DQ13, DQ13_Pass , 1); nmos (DQ12, DQ12_Pass , 1); nmos (DQ11, DQ11_Pass , 1); nmos (DQ10, DQ10_Pass , 1); nmos (DQ9 , DQ9_Pass , 1); nmos (DQ8 , DQ8_Pass , 1); nmos (DQ7 , DQ7_Pass , 1); nmos (DQ6 , DQ6_Pass , 1); nmos (DQ5 , DQ5_Pass , 1); nmos (DQ4 , DQ4_Pass , 1); nmos (DQ3 , DQ3_Pass , 1); nmos (DQ2 , DQ2_Pass , 1); nmos (DQ1 , DQ1_Pass , 1); nmos (DQ0 , DQ0_Pass , 1); nmos (WAITOut, WAITOut_zd, 1); wire deg; specify // tipd delays: interconnect path delays , mapped to input port delays. // In Verilog is not necessary to declare any tipd_ delay variables, // they can be taken from SDF file // With all the other delays real delays would be taken from SDF file // tpd delays specparam tpd_A1_DQ0 =1; specparam tpd_A1_DQ1 =1; specparam tpd_A1_DQ2 =1; specparam tpd_A1_DQ3 =1; specparam tpd_A1_DQ4 =1; specparam tpd_A1_DQ5 =1; specparam tpd_A1_DQ6 =1; specparam tpd_A1_DQ7 =1; specparam tpd_A1_DQ8 =1; specparam tpd_A1_DQ9 =1; specparam tpd_A1_DQ10 =1; specparam tpd_A1_DQ11 =1; specparam tpd_A1_DQ12 =1; specparam tpd_A1_DQ13 =1; specparam tpd_A1_DQ14 =1; specparam tpd_A1_DQ15 =1; specparam tpd_A2_DQ0 =1; specparam tpd_A2_DQ1 =1; specparam tpd_A2_DQ2 =1; specparam tpd_A2_DQ3 =1; specparam tpd_A2_DQ4 =1; specparam tpd_A2_DQ5 =1; specparam tpd_A2_DQ6 =1; specparam tpd_A2_DQ7 =1; specparam tpd_A2_DQ8 =1; specparam tpd_A2_DQ9 =1; specparam tpd_A2_DQ10 =1; specparam tpd_A2_DQ11 =1; specparam tpd_A2_DQ12 =1; specparam tpd_A2_DQ13 =1; specparam tpd_A2_DQ14 =1; specparam tpd_A2_DQ15 =1; specparam tpd_A3_DQ0 =1; specparam tpd_A3_DQ1 =1; specparam tpd_A3_DQ2 =1; specparam tpd_A3_DQ3 =1; specparam tpd_A3_DQ4 =1; specparam tpd_A3_DQ5 =1; specparam tpd_A3_DQ6 =1; specparam tpd_A3_DQ7 =1; specparam tpd_A3_DQ8 =1; specparam tpd_A3_DQ9 =1; specparam tpd_A3_DQ10 =1; specparam tpd_A3_DQ11 =1; specparam tpd_A3_DQ12 =1; specparam tpd_A3_DQ13 =1; specparam tpd_A3_DQ14 =1; specparam tpd_A3_DQ15 =1; specparam tpd_A4_DQ0 =1; specparam tpd_A4_DQ1 =1; specparam tpd_A4_DQ2 =1; specparam tpd_A4_DQ3 =1; specparam tpd_A4_DQ4 =1; specparam tpd_A4_DQ5 =1; specparam tpd_A4_DQ6 =1; specparam tpd_A4_DQ7 =1; specparam tpd_A4_DQ8 =1; specparam tpd_A4_DQ9 =1; specparam tpd_A4_DQ10 =1; specparam tpd_A4_DQ11 =1; specparam tpd_A4_DQ12 =1; specparam tpd_A4_DQ13 =1; specparam tpd_A4_DQ14 =1; specparam tpd_A4_DQ15 =1; specparam tpd_A5_DQ0 =1; specparam tpd_A5_DQ1 =1; specparam tpd_A5_DQ2 =1; specparam tpd_A5_DQ3 =1; specparam tpd_A5_DQ4 =1; specparam tpd_A5_DQ5 =1; specparam tpd_A5_DQ6 =1; specparam tpd_A5_DQ7 =1; specparam tpd_A5_DQ8 =1; specparam tpd_A5_DQ9 =1; specparam tpd_A5_DQ10 =1; specparam tpd_A5_DQ11 =1; specparam tpd_A5_DQ12 =1; specparam tpd_A5_DQ13 =1; specparam tpd_A5_DQ14 =1; specparam tpd_A5_DQ15 =1; specparam tpd_A6_DQ0 =1; specparam tpd_A6_DQ1 =1; specparam tpd_A6_DQ2 =1; specparam tpd_A6_DQ3 =1; specparam tpd_A6_DQ4 =1; specparam tpd_A6_DQ5 =1; specparam tpd_A6_DQ6 =1; specparam tpd_A6_DQ7 =1; specparam tpd_A6_DQ8 =1; specparam tpd_A6_DQ9 =1; specparam tpd_A6_DQ10 =1; specparam tpd_A6_DQ11 =1; specparam tpd_A6_DQ12 =1; specparam tpd_A6_DQ13 =1; specparam tpd_A6_DQ14 =1; specparam tpd_A6_DQ15 =1; specparam tpd_A7_DQ0 =1; specparam tpd_A7_DQ1 =1; specparam tpd_A7_DQ2 =1; specparam tpd_A7_DQ3 =1; specparam tpd_A7_DQ4 =1; specparam tpd_A7_DQ5 =1; specparam tpd_A7_DQ6 =1; specparam tpd_A7_DQ7 =1; specparam tpd_A7_DQ8 =1; specparam tpd_A7_DQ9 =1; specparam tpd_A7_DQ10 =1; specparam tpd_A7_DQ11 =1; specparam tpd_A7_DQ12 =1; specparam tpd_A7_DQ13 =1; specparam tpd_A7_DQ14 =1; specparam tpd_A7_DQ15 =1; specparam tpd_A8_DQ0 =1; specparam tpd_A8_DQ1 =1; specparam tpd_A8_DQ2 =1; specparam tpd_A8_DQ3 =1; specparam tpd_A8_DQ4 =1; specparam tpd_A8_DQ5 =1; specparam tpd_A8_DQ6 =1; specparam tpd_A8_DQ7 =1; specparam tpd_A8_DQ8 =1; specparam tpd_A8_DQ9 =1; specparam tpd_A8_DQ10 =1; specparam tpd_A8_DQ11 =1; specparam tpd_A8_DQ12 =1; specparam tpd_A8_DQ13 =1; specparam tpd_A8_DQ14 =1; specparam tpd_A8_DQ15 =1; specparam tpd_A9_DQ0 =1; specparam tpd_A9_DQ1 =1; specparam tpd_A9_DQ2 =1; specparam tpd_A9_DQ3 =1; specparam tpd_A9_DQ4 =1; specparam tpd_A9_DQ5 =1; specparam tpd_A9_DQ6 =1; specparam tpd_A9_DQ7 =1; specparam tpd_A9_DQ8 =1; specparam tpd_A9_DQ9 =1; specparam tpd_A9_DQ10 =1; specparam tpd_A9_DQ11 =1; specparam tpd_A9_DQ12 =1; specparam tpd_A9_DQ13 =1; specparam tpd_A9_DQ14 =1; specparam tpd_A9_DQ15 =1; specparam tpd_A10_DQ0 =1; specparam tpd_A10_DQ1 =1; specparam tpd_A10_DQ2 =1; specparam tpd_A10_DQ3 =1; specparam tpd_A10_DQ4 =1; specparam tpd_A10_DQ5 =1; specparam tpd_A10_DQ6 =1; specparam tpd_A10_DQ7 =1; specparam tpd_A10_DQ8 =1; specparam tpd_A10_DQ9 =1; specparam tpd_A10_DQ10 =1; specparam tpd_A10_DQ11 =1; specparam tpd_A10_DQ12 =1; specparam tpd_A10_DQ13 =1; specparam tpd_A10_DQ14 =1; specparam tpd_A10_DQ15 =1; specparam tpd_A11_DQ0 =1; specparam tpd_A11_DQ1 =1; specparam tpd_A11_DQ2 =1; specparam tpd_A11_DQ3 =1; specparam tpd_A11_DQ4 =1; specparam tpd_A11_DQ5 =1; specparam tpd_A11_DQ6 =1; specparam tpd_A11_DQ7 =1; specparam tpd_A11_DQ8 =1; specparam tpd_A11_DQ9 =1; specparam tpd_A11_DQ10 =1; specparam tpd_A11_DQ11 =1; specparam tpd_A11_DQ12 =1; specparam tpd_A11_DQ13 =1; specparam tpd_A11_DQ14 =1; specparam tpd_A11_DQ15 =1; specparam tpd_A12_DQ0 =1; specparam tpd_A12_DQ1 =1; specparam tpd_A12_DQ2 =1; specparam tpd_A12_DQ3 =1; specparam tpd_A12_DQ4 =1; specparam tpd_A12_DQ5 =1; specparam tpd_A12_DQ6 =1; specparam tpd_A12_DQ7 =1; specparam tpd_A12_DQ8 =1; specparam tpd_A12_DQ9 =1; specparam tpd_A12_DQ10 =1; specparam tpd_A12_DQ11 =1; specparam tpd_A12_DQ12 =1; specparam tpd_A12_DQ13 =1; specparam tpd_A12_DQ14 =1; specparam tpd_A12_DQ15 =1; specparam tpd_A13_DQ0 =1; specparam tpd_A13_DQ1 =1; specparam tpd_A13_DQ2 =1; specparam tpd_A13_DQ3 =1; specparam tpd_A13_DQ4 =1; specparam tpd_A13_DQ5 =1; specparam tpd_A13_DQ6 =1; specparam tpd_A13_DQ7 =1; specparam tpd_A13_DQ8 =1; specparam tpd_A13_DQ9 =1; specparam tpd_A13_DQ10 =1; specparam tpd_A13_DQ11 =1; specparam tpd_A13_DQ12 =1; specparam tpd_A13_DQ13 =1; specparam tpd_A13_DQ14 =1; specparam tpd_A13_DQ15 =1; specparam tpd_A14_DQ0 =1; specparam tpd_A14_DQ1 =1; specparam tpd_A14_DQ2 =1; specparam tpd_A14_DQ3 =1; specparam tpd_A14_DQ4 =1; specparam tpd_A14_DQ5 =1; specparam tpd_A14_DQ6 =1; specparam tpd_A14_DQ7 =1; specparam tpd_A14_DQ8 =1; specparam tpd_A14_DQ9 =1; specparam tpd_A14_DQ10 =1; specparam tpd_A14_DQ11 =1; specparam tpd_A14_DQ12 =1; specparam tpd_A14_DQ13 =1; specparam tpd_A14_DQ14 =1; specparam tpd_A14_DQ15 =1; specparam tpd_A15_DQ0 =1; specparam tpd_A15_DQ1 =1; specparam tpd_A15_DQ2 =1; specparam tpd_A15_DQ3 =1; specparam tpd_A15_DQ4 =1; specparam tpd_A15_DQ5 =1; specparam tpd_A15_DQ6 =1; specparam tpd_A15_DQ7 =1; specparam tpd_A15_DQ8 =1; specparam tpd_A15_DQ9 =1; specparam tpd_A15_DQ10 =1; specparam tpd_A15_DQ11 =1; specparam tpd_A15_DQ12 =1; specparam tpd_A15_DQ13 =1; specparam tpd_A15_DQ14 =1; specparam tpd_A15_DQ15 =1; specparam tpd_A16_DQ0 =1; specparam tpd_A16_DQ1 =1; specparam tpd_A16_DQ2 =1; specparam tpd_A16_DQ3 =1; specparam tpd_A16_DQ4 =1; specparam tpd_A16_DQ5 =1; specparam tpd_A16_DQ6 =1; specparam tpd_A16_DQ7 =1; specparam tpd_A16_DQ8 =1; specparam tpd_A16_DQ9 =1; specparam tpd_A16_DQ10 =1; specparam tpd_A16_DQ11 =1; specparam tpd_A16_DQ12 =1; specparam tpd_A16_DQ13 =1; specparam tpd_A16_DQ14 =1; specparam tpd_A16_DQ15 =1; specparam tpd_A17_DQ0 =1; specparam tpd_A17_DQ1 =1; specparam tpd_A17_DQ2 =1; specparam tpd_A17_DQ3 =1; specparam tpd_A17_DQ4 =1; specparam tpd_A17_DQ5 =1; specparam tpd_A17_DQ6 =1; specparam tpd_A17_DQ7 =1; specparam tpd_A17_DQ8 =1; specparam tpd_A17_DQ9 =1; specparam tpd_A17_DQ10 =1; specparam tpd_A17_DQ11 =1; specparam tpd_A17_DQ12 =1; specparam tpd_A17_DQ13 =1; specparam tpd_A17_DQ14 =1; specparam tpd_A17_DQ15 =1; specparam tpd_A18_DQ0 =1; specparam tpd_A18_DQ1 =1; specparam tpd_A18_DQ2 =1; specparam tpd_A18_DQ3 =1; specparam tpd_A18_DQ4 =1; specparam tpd_A18_DQ5 =1; specparam tpd_A18_DQ6 =1; specparam tpd_A18_DQ7 =1; specparam tpd_A18_DQ8 =1; specparam tpd_A18_DQ9 =1; specparam tpd_A18_DQ10 =1; specparam tpd_A18_DQ11 =1; specparam tpd_A18_DQ12 =1; specparam tpd_A18_DQ13 =1; specparam tpd_A18_DQ14 =1; specparam tpd_A18_DQ15 =1; specparam tpd_A19_DQ0 =1; specparam tpd_A19_DQ1 =1; specparam tpd_A19_DQ2 =1; specparam tpd_A19_DQ3 =1; specparam tpd_A19_DQ4 =1; specparam tpd_A19_DQ5 =1; specparam tpd_A19_DQ6 =1; specparam tpd_A19_DQ7 =1; specparam tpd_A19_DQ8 =1; specparam tpd_A19_DQ9 =1; specparam tpd_A19_DQ10 =1; specparam tpd_A19_DQ11 =1; specparam tpd_A19_DQ12 =1; specparam tpd_A19_DQ13 =1; specparam tpd_A19_DQ14 =1; specparam tpd_A19_DQ15 =1; specparam tpd_A20_DQ0 =1; specparam tpd_A20_DQ1 =1; specparam tpd_A20_DQ2 =1; specparam tpd_A20_DQ3 =1; specparam tpd_A20_DQ4 =1; specparam tpd_A20_DQ5 =1; specparam tpd_A20_DQ6 =1; specparam tpd_A20_DQ7 =1; specparam tpd_A20_DQ8 =1; specparam tpd_A20_DQ9 =1; specparam tpd_A20_DQ10 =1; specparam tpd_A20_DQ11 =1; specparam tpd_A20_DQ12 =1; specparam tpd_A20_DQ13 =1; specparam tpd_A20_DQ14 =1; specparam tpd_A20_DQ15 =1; specparam tpd_A21_DQ0 =1; specparam tpd_A21_DQ1 =1; specparam tpd_A21_DQ2 =1; specparam tpd_A21_DQ3 =1; specparam tpd_A21_DQ4 =1; specparam tpd_A21_DQ5 =1; specparam tpd_A21_DQ6 =1; specparam tpd_A21_DQ7 =1; specparam tpd_A21_DQ8 =1; specparam tpd_A21_DQ9 =1; specparam tpd_A21_DQ10 =1; specparam tpd_A21_DQ11 =1; specparam tpd_A21_DQ12 =1; specparam tpd_A21_DQ13 =1; specparam tpd_A21_DQ14 =1; specparam tpd_A21_DQ15 =1; specparam tpd_A22_DQ0 =1; specparam tpd_A22_DQ1 =1; specparam tpd_A22_DQ2 =1; specparam tpd_A22_DQ3 =1; specparam tpd_A22_DQ4 =1; specparam tpd_A22_DQ5 =1; specparam tpd_A22_DQ6 =1; specparam tpd_A22_DQ7 =1; specparam tpd_A22_DQ8 =1; specparam tpd_A22_DQ9 =1; specparam tpd_A22_DQ10 =1; specparam tpd_A22_DQ11 =1; specparam tpd_A22_DQ12 =1; specparam tpd_A22_DQ13 =1; specparam tpd_A22_DQ14 =1; specparam tpd_A22_DQ15 =1; specparam tpd_A23_DQ0 =1; specparam tpd_A23_DQ1 =1; specparam tpd_A23_DQ2 =1; specparam tpd_A23_DQ3 =1; specparam tpd_A23_DQ4 =1; specparam tpd_A23_DQ5 =1; specparam tpd_A23_DQ6 =1; specparam tpd_A23_DQ7 =1; specparam tpd_A23_DQ8 =1; specparam tpd_A23_DQ9 =1; specparam tpd_A23_DQ10 =1; specparam tpd_A23_DQ11 =1; specparam tpd_A23_DQ12 =1; specparam tpd_A23_DQ13 =1; specparam tpd_A23_DQ14 =1; specparam tpd_A23_DQ15 =1; specparam tpd_A24_DQ0 =1; specparam tpd_A24_DQ1 =1; specparam tpd_A24_DQ2 =1; specparam tpd_A24_DQ3 =1; specparam tpd_A24_DQ4 =1; specparam tpd_A24_DQ5 =1; specparam tpd_A24_DQ6 =1; specparam tpd_A24_DQ7 =1; specparam tpd_A24_DQ8 =1; specparam tpd_A24_DQ9 =1; specparam tpd_A24_DQ10 =1; specparam tpd_A24_DQ11 =1; specparam tpd_A24_DQ12 =1; specparam tpd_A24_DQ13 =1; specparam tpd_A24_DQ14 =1; specparam tpd_A24_DQ15 =1; specparam tpd_CENeg_DQ0 =1; specparam tpd_CENeg_DQ1 =1; specparam tpd_CENeg_DQ2 =1; specparam tpd_CENeg_DQ3 =1; specparam tpd_CENeg_DQ4 =1; specparam tpd_CENeg_DQ5 =1; specparam tpd_CENeg_DQ6 =1; specparam tpd_CENeg_DQ7 =1; specparam tpd_CENeg_DQ8 =1; specparam tpd_CENeg_DQ9 =1; specparam tpd_CENeg_DQ10 =1; specparam tpd_CENeg_DQ11 =1; specparam tpd_CENeg_DQ12 =1; specparam tpd_CENeg_DQ13 =1; specparam tpd_CENeg_DQ14 =1; specparam tpd_CENeg_DQ15 =1; specparam tpd_OENeg_DQ0 =1; specparam tpd_OENeg_DQ1 =1; specparam tpd_OENeg_DQ2 =1; specparam tpd_OENeg_DQ3 =1; specparam tpd_OENeg_DQ4 =1; specparam tpd_OENeg_DQ5 =1; specparam tpd_OENeg_DQ6 =1; specparam tpd_OENeg_DQ7 =1; specparam tpd_OENeg_DQ8 =1; specparam tpd_OENeg_DQ9 =1; specparam tpd_OENeg_DQ10 =1; specparam tpd_OENeg_DQ11 =1; specparam tpd_OENeg_DQ12 =1; specparam tpd_OENeg_DQ13 =1; specparam tpd_OENeg_DQ14 =1; specparam tpd_OENeg_DQ15 =1; specparam tpd_CLK_DQ0 =1; specparam tpd_CLK_DQ1 =1; specparam tpd_CLK_DQ2 =1; specparam tpd_CLK_DQ3 =1; specparam tpd_CLK_DQ4 =1; specparam tpd_CLK_DQ5 =1; specparam tpd_CLK_DQ6 =1; specparam tpd_CLK_DQ7 =1; specparam tpd_CLK_DQ8 =1; specparam tpd_CLK_DQ9 =1; specparam tpd_CLK_DQ10 =1; specparam tpd_CLK_DQ11 =1; specparam tpd_CLK_DQ12 =1; specparam tpd_CLK_DQ13 =1; specparam tpd_CLK_DQ14 =1; specparam tpd_CLK_DQ15 =1; specparam tpd_CE0Neg_WAITOut =1; specparam tpd_OE0Neg_WAITOut =1; specparam tpd_CLK_WAITOut =1; //tsetup values specparam tsetup_A1_ADVNeg =1; specparam tsetup_A2_ADVNeg =1; specparam tsetup_A3_ADVNeg =1; specparam tsetup_A4_ADVNeg =1; specparam tsetup_A5_ADVNeg =1; specparam tsetup_A6_ADVNeg =1; specparam tsetup_A7_ADVNeg =1; specparam tsetup_A8_ADVNeg =1; specparam tsetup_A9_ADVNeg =1; specparam tsetup_A10_ADVNeg =1; specparam tsetup_A11_ADVNeg =1; specparam tsetup_A12_ADVNeg =1; specparam tsetup_A13_ADVNeg =1; specparam tsetup_A14_ADVNeg =1; specparam tsetup_A15_ADVNeg =1; specparam tsetup_A16_ADVNeg =1; specparam tsetup_A17_ADVNeg =1; specparam tsetup_A18_ADVNeg =1; specparam tsetup_A19_ADVNeg =1; specparam tsetup_A20_ADVNeg =1; specparam tsetup_A21_ADVNeg =1; specparam tsetup_A22_ADVNeg =1; specparam tsetup_A23_ADVNeg =1; specparam tsetup_A24_ADVNeg =1; specparam tsetup_CENeg_ADVNeg =1; specparam tsetup_RSTNeg_ADVNeg =1; specparam tsetup_CLK_ADVNeg =1; specparam tsetup_WENeg_ADVNeg =1; specparam tsetup_A1_CLK =1; specparam tsetup_A2_CLK =1; specparam tsetup_A3_CLK =1; specparam tsetup_A4_CLK =1; specparam tsetup_A5_CLK =1; specparam tsetup_A6_CLK =1; specparam tsetup_A7_CLK =1; specparam tsetup_A8_CLK =1; specparam tsetup_A9_CLK =1; specparam tsetup_A10_CLK =1; specparam tsetup_A11_CLK =1; specparam tsetup_A12_CLK =1; specparam tsetup_A13_CLK =1; specparam tsetup_A14_CLK =1; specparam tsetup_A15_CLK =1; specparam tsetup_A16_CLK =1; specparam tsetup_A17_CLK =1; specparam tsetup_A18_CLK =1; specparam tsetup_A19_CLK =1; specparam tsetup_A20_CLK =1; specparam tsetup_A21_CLK =1; specparam tsetup_A22_CLK =1; specparam tsetup_A23_CLK =1; specparam tsetup_A24_CLK =1; specparam tsetup_ADVNeg_CLK =1; specparam tsetup_CENeg_CLK =1; specparam tsetup_WENeg_CLK =1; specparam tsetup_CENeg_WENeg =1; specparam tsetup_DQ0_WENeg =1; specparam tsetup_DQ1_WENeg =1; specparam tsetup_DQ2_WENeg =1; specparam tsetup_DQ3_WENeg =1; specparam tsetup_DQ4_WENeg =1; specparam tsetup_DQ5_WENeg =1; specparam tsetup_DQ6_WENeg =1; specparam tsetup_DQ7_WENeg =1; specparam tsetup_DQ8_WENeg =1; specparam tsetup_DQ9_WENeg =1; specparam tsetup_DQ10_WENeg =1; specparam tsetup_DQ11_WENeg =1; specparam tsetup_DQ12_WENeg =1; specparam tsetup_DQ13_WENeg =1; specparam tsetup_DQ14_WENeg =1; specparam tsetup_DQ15_WENeg =1; specparam tsetup_A1_WENeg =1; specparam tsetup_A2_WENeg =1; specparam tsetup_A3_WENeg =1; specparam tsetup_A4_WENeg =1; specparam tsetup_A5_WENeg =1; specparam tsetup_A6_WENeg =1; specparam tsetup_A7_WENeg =1; specparam tsetup_A8_WENeg =1; specparam tsetup_A9_WENeg =1; specparam tsetup_A10_WENeg =1; specparam tsetup_A11_WENeg =1; specparam tsetup_A12_WENeg =1; specparam tsetup_A13_WENeg =1; specparam tsetup_A14_WENeg =1; specparam tsetup_A15_WENeg =1; specparam tsetup_A16_WENeg =1; specparam tsetup_A17_WENeg =1; specparam tsetup_A18_WENeg =1; specparam tsetup_A19_WENeg =1; specparam tsetup_A20_WENeg =1; specparam tsetup_A21_WENeg =1; specparam tsetup_A22_WENeg =1; specparam tsetup_A23_WENeg =1; specparam tsetup_A24_WENeg =1; specparam tsetup_WPNeg_WENeg =1; specparam tsetup_ADVNeg_WENeg =1; specparam tsetup_CLK_WENeg =1; specparam tsetup_WENeg_OENeg =1; // thold values: hold times specparam thold_A1_ADVNeg =1; specparam thold_A2_ADVNeg =1; specparam thold_A3_ADVNeg =1; specparam thold_A4_ADVNeg =1; specparam thold_A5_ADVNeg =1; specparam thold_A6_ADVNeg =1; specparam thold_A7_ADVNeg =1; specparam thold_A8_ADVNeg =1; specparam thold_A9_ADVNeg =1; specparam thold_A10_ADVNeg =1; specparam thold_A11_ADVNeg =1; specparam thold_A12_ADVNeg =1; specparam thold_A13_ADVNeg =1; specparam thold_A14_ADVNeg =1; specparam thold_A15_ADVNeg =1; specparam thold_A16_ADVNeg =1; specparam thold_A17_ADVNeg =1; specparam thold_A18_ADVNeg =1; specparam thold_A19_ADVNeg =1; specparam thold_A20_ADVNeg =1; specparam thold_A21_ADVNeg =1; specparam thold_A22_ADVNeg =1; specparam thold_A23_ADVNeg =1; specparam thold_A24_ADVNeg =1; specparam thold_A1_CLK =1; specparam thold_A2_CLK =1; specparam thold_A3_CLK =1; specparam thold_A4_CLK =1; specparam thold_A5_CLK =1; specparam thold_A6_CLK =1; specparam thold_A7_CLK =1; specparam thold_A8_CLK =1; specparam thold_A9_CLK =1; specparam thold_A10_CLK =1; specparam thold_A11_CLK =1; specparam thold_A12_CLK =1; specparam thold_A13_CLK =1; specparam thold_A14_CLK =1; specparam thold_A15_CLK =1; specparam thold_A16_CLK =1; specparam thold_A17_CLK =1; specparam thold_A18_CLK =1; specparam thold_A19_CLK =1; specparam thold_A20_CLK =1; specparam thold_A21_CLK =1; specparam thold_A22_CLK =1; specparam thold_A23_CLK =1; specparam thold_A24_CLK =1; specparam thold_CENeg_WENeg =1; specparam thold_DQ0_WENeg =1; specparam thold_DQ1_WENeg =1; specparam thold_DQ2_WENeg =1; specparam thold_DQ3_WENeg =1; specparam thold_DQ4_WENeg =1; specparam thold_DQ5_WENeg =1; specparam thold_DQ6_WENeg =1; specparam thold_DQ7_WENeg =1; specparam thold_DQ8_WENeg =1; specparam thold_DQ9_WENeg =1; specparam thold_DQ10_WENeg =1; specparam thold_DQ11_WENeg =1; specparam thold_DQ12_WENeg =1; specparam thold_DQ13_WENeg =1; specparam thold_DQ14_WENeg =1; specparam thold_DQ15_WENeg =1; specparam thold_A1_WENeg =1; specparam thold_A2_WENeg =1; specparam thold_A3_WENeg =1; specparam thold_A4_WENeg =1; specparam thold_A5_WENeg =1; specparam thold_A6_WENeg =1; specparam thold_A7_WENeg =1; specparam thold_A8_WENeg =1; specparam thold_A9_WENeg =1; specparam thold_A10_WENeg =1; specparam thold_A11_WENeg =1; specparam thold_A12_WENeg =1; specparam thold_A13_WENeg =1; specparam thold_A14_WENeg =1; specparam thold_A15_WENeg =1; specparam thold_A16_WENeg =1; specparam thold_A17_WENeg =1; specparam thold_A18_WENeg =1; specparam thold_A19_WENeg =1; specparam thold_A20_WENeg =1; specparam thold_A21_WENeg =1; specparam thold_A22_WENeg =1; specparam thold_A23_WENeg =1; specparam thold_A24_WENeg =1; //tpw values specparam tpw_CENeg_posedge = 1; specparam tpw_ADVNeg_posedge = 1; specparam tpw_ADVNeg_negedge = 1; specparam tpw_WENeg_negedge = 1; specparam tpw_WENeg_posedge = 1; specparam tpw_RSTNeg_negedge = 1; specparam tpw_CLK_posedge = 1; specparam tpw_CLK_negedge = 1; specparam tperiod_CLK = 1; // tdevice values: values for internal delays `ifdef SPEEDSIM // Program BUffProgram specparam tdevice_BuffProgram = 88000; // Program BUffProgram specparam tdevice_BuffProgram9V = 68000; // Program BEFP specparam tdevice_BEFP = 32000; // Program EraseParameter specparam tdevice_EraseParameter_td = 2500; // Program EraseMain specparam tdevice_EraseMain_td = 4000; `else // Program BUffProgram specparam tdevice_BuffProgram = 880000; // Program BUffProgram specparam tdevice_BuffProgram9V = 680000; // Program BEFP specparam tdevice_BEFP = 320000; // Program EraseParameter specparam tdevice_EraseParameter_td = 2500000; // Program EraseMain specparam tdevice_EraseMain_td = 4000000; `endif // SPEEDSIM // Program Word specparam tdevice_WordProgram = 200000; // Program Word specparam tdevice_WordProgram9V = 190000; // Program BEFPsetup specparam tdevice_BEFPsetup = 5000; // Program ProgramSuspend specparam tdevice_ProgramSuspend = 25000; // Program ProgramSuspend specparam tdevice_EraseSuspend = 25000; // Reset during Program or Erase specparam tdevice_RstDuringErsPrg = 25000; /////////////////////////////////////////////////////////////////////////////// // Input Port Delays don't require Verilog description /////////////////////////////////////////////////////////////////////////////// // Path delays // /////////////////////////////////////////////////////////////////////////////// if (InitialPageAccess) (A1 *> DQ0) = tpd_A1_DQ0; if (InitialPageAccess) (A1 *> DQ1) = tpd_A1_DQ1; if (InitialPageAccess) (A1 *> DQ2) = tpd_A1_DQ2; if (InitialPageAccess) (A1 *> DQ3) = tpd_A1_DQ3; if (InitialPageAccess) (A1 *> DQ4) = tpd_A1_DQ4; if (InitialPageAccess) (A1 *> DQ5) = tpd_A1_DQ5; if (InitialPageAccess) (A1 *> DQ6) = tpd_A1_DQ6; if (InitialPageAccess) (A1 *> DQ7) = tpd_A1_DQ7; if (InitialPageAccess) (A1 *> DQ8) = tpd_A1_DQ8; if (InitialPageAccess) (A1 *> DQ9) = tpd_A1_DQ9; if (InitialPageAccess) (A1 *> DQ10) = tpd_A1_DQ10; if (InitialPageAccess) (A1 *> DQ11) = tpd_A1_DQ11; if (InitialPageAccess) (A1 *> DQ12) = tpd_A1_DQ12; if (InitialPageAccess) (A1 *> DQ13) = tpd_A1_DQ13; if (InitialPageAccess) (A1 *> DQ14) = tpd_A1_DQ14; if (InitialPageAccess) (A1 *> DQ15) = tpd_A1_DQ15; if (InitialPageAccess) (A2 *> DQ0) = tpd_A2_DQ0; if (InitialPageAccess) (A2 *> DQ1) = tpd_A2_DQ1; if (InitialPageAccess) (A2 *> DQ2) = tpd_A2_DQ2; if (InitialPageAccess) (A2 *> DQ3) = tpd_A2_DQ3; if (InitialPageAccess) (A2 *> DQ4) = tpd_A2_DQ4; if (InitialPageAccess) (A2 *> DQ5) = tpd_A2_DQ5; if (InitialPageAccess) (A2 *> DQ6) = tpd_A2_DQ6; if (InitialPageAccess) (A2 *> DQ7) = tpd_A2_DQ7; if (InitialPageAccess) (A2 *> DQ8) = tpd_A2_DQ8; if (InitialPageAccess) (A2 *> DQ9) = tpd_A2_DQ9; if (InitialPageAccess) (A2 *> DQ10) = tpd_A2_DQ10; if (InitialPageAccess) (A2 *> DQ11) = tpd_A2_DQ11; if (InitialPageAccess) (A2 *> DQ12) = tpd_A2_DQ12; if (InitialPageAccess) (A2 *> DQ13) = tpd_A2_DQ13; if (InitialPageAccess) (A2 *> DQ14) = tpd_A2_DQ14; if (InitialPageAccess) (A2 *> DQ15) = tpd_A2_DQ15; if (InitialPageAccess) (A3 *> DQ0) = tpd_A3_DQ0; if (InitialPageAccess) (A3 *> DQ1) = tpd_A3_DQ1; if (InitialPageAccess) (A3 *> DQ2) = tpd_A3_DQ2; if (InitialPageAccess) (A3 *> DQ3) = tpd_A3_DQ3; if (InitialPageAccess) (A3 *> DQ4) = tpd_A3_DQ4; if (InitialPageAccess) (A3 *> DQ5) = tpd_A3_DQ5; if (InitialPageAccess) (A3 *> DQ6) = tpd_A3_DQ6; if (InitialPageAccess) (A3 *> DQ7) = tpd_A3_DQ7; if (InitialPageAccess) (A3 *> DQ8) = tpd_A3_DQ8; if (InitialPageAccess) (A3 *> DQ9) = tpd_A3_DQ9; if (InitialPageAccess) (A3 *> DQ10) = tpd_A3_DQ10; if (InitialPageAccess) (A3 *> DQ11) = tpd_A3_DQ11; if (InitialPageAccess) (A3 *> DQ12) = tpd_A3_DQ12; if (InitialPageAccess) (A3 *> DQ13) = tpd_A3_DQ13; if (InitialPageAccess) (A3 *> DQ14) = tpd_A3_DQ14; if (InitialPageAccess) (A3 *> DQ15) = tpd_A3_DQ15; if (InitialPageAccess) (A4 *> DQ0) = tpd_A4_DQ0; if (InitialPageAccess) (A4 *> DQ1) = tpd_A4_DQ1; if (InitialPageAccess) (A4 *> DQ2) = tpd_A4_DQ2; if (InitialPageAccess) (A4 *> DQ3) = tpd_A4_DQ3; if (InitialPageAccess) (A4 *> DQ4) = tpd_A4_DQ4; if (InitialPageAccess) (A4 *> DQ5) = tpd_A4_DQ5; if (InitialPageAccess) (A4 *> DQ6) = tpd_A4_DQ6; if (InitialPageAccess) (A4 *> DQ7) = tpd_A4_DQ7; if (InitialPageAccess) (A4 *> DQ8) = tpd_A4_DQ8; if (InitialPageAccess) (A4 *> DQ9) = tpd_A4_DQ9; if (InitialPageAccess) (A4 *> DQ10) = tpd_A4_DQ10; if (InitialPageAccess) (A4 *> DQ11) = tpd_A4_DQ11; if (InitialPageAccess) (A4 *> DQ12) = tpd_A4_DQ12; if (InitialPageAccess) (A4 *> DQ13) = tpd_A4_DQ13; if (InitialPageAccess) (A4 *> DQ14) = tpd_A4_DQ14; if (InitialPageAccess) (A4 *> DQ15) = tpd_A4_DQ15; if (InitialPageAccess) (A5 *> DQ0) = tpd_A5_DQ0; if (InitialPageAccess) (A5 *> DQ1) = tpd_A5_DQ1; if (InitialPageAccess) (A5 *> DQ2) = tpd_A5_DQ2; if (InitialPageAccess) (A5 *> DQ3) = tpd_A5_DQ3; if (InitialPageAccess) (A5 *> DQ4) = tpd_A5_DQ4; if (InitialPageAccess) (A5 *> DQ5) = tpd_A5_DQ5; if (InitialPageAccess) (A5 *> DQ6) = tpd_A5_DQ6; if (InitialPageAccess) (A5 *> DQ7) = tpd_A5_DQ7; if (InitialPageAccess) (A5 *> DQ8) = tpd_A5_DQ8; if (InitialPageAccess) (A5 *> DQ9) = tpd_A5_DQ9; if (InitialPageAccess) (A5 *> DQ10) = tpd_A5_DQ10; if (InitialPageAccess) (A5 *> DQ11) = tpd_A5_DQ11; if (InitialPageAccess) (A5 *> DQ12) = tpd_A5_DQ12; if (InitialPageAccess) (A5 *> DQ13) = tpd_A5_DQ13; if (InitialPageAccess) (A5 *> DQ14) = tpd_A5_DQ14; if (InitialPageAccess) (A5 *> DQ15) = tpd_A5_DQ15; if (InitialPageAccess) (A6 *> DQ0) = tpd_A6_DQ0; if (InitialPageAccess) (A6 *> DQ1) = tpd_A6_DQ1; if (InitialPageAccess) (A6 *> DQ2) = tpd_A6_DQ2; if (InitialPageAccess) (A6 *> DQ3) = tpd_A6_DQ3; if (InitialPageAccess) (A6 *> DQ4) = tpd_A6_DQ4; if (InitialPageAccess) (A6 *> DQ5) = tpd_A6_DQ5; if (InitialPageAccess) (A6 *> DQ6) = tpd_A6_DQ6; if (InitialPageAccess) (A6 *> DQ7) = tpd_A6_DQ7; if (InitialPageAccess) (A6 *> DQ8) = tpd_A6_DQ8; if (InitialPageAccess) (A6 *> DQ9) = tpd_A6_DQ9; if (InitialPageAccess) (A6 *> DQ10) = tpd_A6_DQ10; if (InitialPageAccess) (A6 *> DQ11) = tpd_A6_DQ11; if (InitialPageAccess) (A6 *> DQ12) = tpd_A6_DQ12; if (InitialPageAccess) (A6 *> DQ13) = tpd_A6_DQ13; if (InitialPageAccess) (A6 *> DQ14) = tpd_A6_DQ14; if (InitialPageAccess) (A6 *> DQ15) = tpd_A6_DQ15; if (InitialPageAccess) (A7 *> DQ0) = tpd_A7_DQ0; if (InitialPageAccess) (A7 *> DQ1) = tpd_A7_DQ1; if (InitialPageAccess) (A7 *> DQ2) = tpd_A7_DQ2; if (InitialPageAccess) (A7 *> DQ3) = tpd_A7_DQ3; if (InitialPageAccess) (A7 *> DQ4) = tpd_A7_DQ4; if (InitialPageAccess) (A7 *> DQ5) = tpd_A7_DQ5; if (InitialPageAccess) (A7 *> DQ6) = tpd_A7_DQ6; if (InitialPageAccess) (A7 *> DQ7) = tpd_A7_DQ7; if (InitialPageAccess) (A7 *> DQ8) = tpd_A7_DQ8; if (InitialPageAccess) (A7 *> DQ9) = tpd_A7_DQ9; if (InitialPageAccess) (A7 *> DQ10) = tpd_A7_DQ10; if (InitialPageAccess) (A7 *> DQ11) = tpd_A7_DQ11; if (InitialPageAccess) (A7 *> DQ12) = tpd_A7_DQ12; if (InitialPageAccess) (A7 *> DQ13) = tpd_A7_DQ13; if (InitialPageAccess) (A7 *> DQ14) = tpd_A7_DQ14; if (InitialPageAccess) (A7 *> DQ15) = tpd_A7_DQ15; if (InitialPageAccess) (A8 *> DQ0) = tpd_A8_DQ0; if (InitialPageAccess) (A8 *> DQ1) = tpd_A8_DQ1; if (InitialPageAccess) (A8 *> DQ2) = tpd_A8_DQ2; if (InitialPageAccess) (A8 *> DQ3) = tpd_A8_DQ3; if (InitialPageAccess) (A8 *> DQ4) = tpd_A8_DQ4; if (InitialPageAccess) (A8 *> DQ5) = tpd_A8_DQ5; if (InitialPageAccess) (A8 *> DQ6) = tpd_A8_DQ6; if (InitialPageAccess) (A8 *> DQ7) = tpd_A8_DQ7; if (InitialPageAccess) (A8 *> DQ8) = tpd_A8_DQ8; if (InitialPageAccess) (A8 *> DQ9) = tpd_A8_DQ9; if (InitialPageAccess) (A8 *> DQ10) = tpd_A8_DQ10; if (InitialPageAccess) (A8 *> DQ11) = tpd_A8_DQ11; if (InitialPageAccess) (A8 *> DQ12) = tpd_A8_DQ12; if (InitialPageAccess) (A8 *> DQ13) = tpd_A8_DQ13; if (InitialPageAccess) (A8 *> DQ14) = tpd_A8_DQ14; if (InitialPageAccess) (A8 *> DQ15) = tpd_A8_DQ15; if (InitialPageAccess) (A9 *> DQ0) = tpd_A9_DQ0; if (InitialPageAccess) (A9 *> DQ1) = tpd_A9_DQ1; if (InitialPageAccess) (A9 *> DQ2) = tpd_A9_DQ2; if (InitialPageAccess) (A9 *> DQ3) = tpd_A9_DQ3; if (InitialPageAccess) (A9 *> DQ4) = tpd_A9_DQ4; if (InitialPageAccess) (A9 *> DQ5) = tpd_A9_DQ5; if (InitialPageAccess) (A9 *> DQ6) = tpd_A9_DQ6; if (InitialPageAccess) (A9 *> DQ7) = tpd_A9_DQ7; if (InitialPageAccess) (A9 *> DQ8) = tpd_A9_DQ8; if (InitialPageAccess) (A9 *> DQ9) = tpd_A9_DQ9; if (InitialPageAccess) (A9 *> DQ10) = tpd_A9_DQ10; if (InitialPageAccess) (A9 *> DQ11) = tpd_A9_DQ11; if (InitialPageAccess) (A9 *> DQ12) = tpd_A9_DQ12; if (InitialPageAccess) (A9 *> DQ13) = tpd_A9_DQ13; if (InitialPageAccess) (A9 *> DQ14) = tpd_A9_DQ14; if (InitialPageAccess) (A9 *> DQ15) = tpd_A9_DQ15; if (InitialPageAccess) (A10 *> DQ0) = tpd_A10_DQ0; if (InitialPageAccess) (A10 *> DQ1) = tpd_A10_DQ1; if (InitialPageAccess) (A10 *> DQ2) = tpd_A10_DQ2; if (InitialPageAccess) (A10 *> DQ3) = tpd_A10_DQ3; if (InitialPageAccess) (A10 *> DQ4) = tpd_A10_DQ4; if (InitialPageAccess) (A10 *> DQ5) = tpd_A10_DQ5; if (InitialPageAccess) (A10 *> DQ6) = tpd_A10_DQ6; if (InitialPageAccess) (A10 *> DQ7) = tpd_A10_DQ7; if (InitialPageAccess) (A10 *> DQ8) = tpd_A10_DQ8; if (InitialPageAccess) (A10 *> DQ9) = tpd_A10_DQ9; if (InitialPageAccess) (A10 *> DQ10) = tpd_A10_DQ10; if (InitialPageAccess) (A10 *> DQ11) = tpd_A10_DQ11; if (InitialPageAccess) (A10 *> DQ12) = tpd_A10_DQ12; if (InitialPageAccess) (A10 *> DQ13) = tpd_A10_DQ13; if (InitialPageAccess) (A10 *> DQ14) = tpd_A10_DQ14; if (InitialPageAccess) (A10 *> DQ15) = tpd_A10_DQ15; if (InitialPageAccess) (A11 *> DQ0) = tpd_A11_DQ0; if (InitialPageAccess) (A11 *> DQ1) = tpd_A11_DQ1; if (InitialPageAccess) (A11 *> DQ2) = tpd_A11_DQ2; if (InitialPageAccess) (A11 *> DQ3) = tpd_A11_DQ3; if (InitialPageAccess) (A11 *> DQ4) = tpd_A11_DQ4; if (InitialPageAccess) (A11 *> DQ5) = tpd_A11_DQ5; if (InitialPageAccess) (A11 *> DQ6) = tpd_A11_DQ6; if (InitialPageAccess) (A11 *> DQ7) = tpd_A11_DQ7; if (InitialPageAccess) (A11 *> DQ8) = tpd_A11_DQ8; if (InitialPageAccess) (A11 *> DQ9) = tpd_A11_DQ9; if (InitialPageAccess) (A11 *> DQ10) = tpd_A11_DQ10; if (InitialPageAccess) (A11 *> DQ11) = tpd_A11_DQ11; if (InitialPageAccess) (A11 *> DQ12) = tpd_A11_DQ12; if (InitialPageAccess) (A11 *> DQ13) = tpd_A11_DQ13; if (InitialPageAccess) (A11 *> DQ14) = tpd_A11_DQ14; if (InitialPageAccess) (A11 *> DQ15) = tpd_A11_DQ15; if (InitialPageAccess) (A12 *> DQ0) = tpd_A12_DQ0; if (InitialPageAccess) (A12 *> DQ1) = tpd_A12_DQ1; if (InitialPageAccess) (A12 *> DQ2) = tpd_A12_DQ2; if (InitialPageAccess) (A12 *> DQ3) = tpd_A12_DQ3; if (InitialPageAccess) (A12 *> DQ4) = tpd_A12_DQ4; if (InitialPageAccess) (A12 *> DQ5) = tpd_A12_DQ5; if (InitialPageAccess) (A12 *> DQ6) = tpd_A12_DQ6; if (InitialPageAccess) (A12 *> DQ7) = tpd_A12_DQ7; if (InitialPageAccess) (A12 *> DQ8) = tpd_A12_DQ8; if (InitialPageAccess) (A12 *> DQ9) = tpd_A12_DQ9; if (InitialPageAccess) (A12 *> DQ10) = tpd_A12_DQ10; if (InitialPageAccess) (A12 *> DQ11) = tpd_A12_DQ11; if (InitialPageAccess) (A12 *> DQ12) = tpd_A12_DQ12; if (InitialPageAccess) (A12 *> DQ13) = tpd_A12_DQ13; if (InitialPageAccess) (A12 *> DQ14) = tpd_A12_DQ14; if (InitialPageAccess) (A12 *> DQ15) = tpd_A12_DQ15; if (InitialPageAccess) (A13 *> DQ0) = tpd_A13_DQ0; if (InitialPageAccess) (A13 *> DQ1) = tpd_A13_DQ1; if (InitialPageAccess) (A13 *> DQ2) = tpd_A13_DQ2; if (InitialPageAccess) (A13 *> DQ3) = tpd_A13_DQ3; if (InitialPageAccess) (A13 *> DQ4) = tpd_A13_DQ4; if (InitialPageAccess) (A13 *> DQ5) = tpd_A13_DQ5; if (InitialPageAccess) (A13 *> DQ6) = tpd_A13_DQ6; if (InitialPageAccess) (A13 *> DQ7) = tpd_A13_DQ7; if (InitialPageAccess) (A13 *> DQ8) = tpd_A13_DQ8; if (InitialPageAccess) (A13 *> DQ9) = tpd_A13_DQ9; if (InitialPageAccess) (A13 *> DQ10) = tpd_A13_DQ10; if (InitialPageAccess) (A13 *> DQ11) = tpd_A13_DQ11; if (InitialPageAccess) (A13 *> DQ12) = tpd_A13_DQ12; if (InitialPageAccess) (A13 *> DQ13) = tpd_A13_DQ13; if (InitialPageAccess) (A13 *> DQ14) = tpd_A13_DQ14; if (InitialPageAccess) (A13 *> DQ15) = tpd_A13_DQ15; if (InitialPageAccess) (A14 *> DQ0) = tpd_A14_DQ0; if (InitialPageAccess) (A14 *> DQ1) = tpd_A14_DQ1; if (InitialPageAccess) (A14 *> DQ2) = tpd_A14_DQ2; if (InitialPageAccess) (A14 *> DQ3) = tpd_A14_DQ3; if (InitialPageAccess) (A14 *> DQ4) = tpd_A14_DQ4; if (InitialPageAccess) (A14 *> DQ5) = tpd_A14_DQ5; if (InitialPageAccess) (A14 *> DQ6) = tpd_A14_DQ6; if (InitialPageAccess) (A14 *> DQ7) = tpd_A14_DQ7; if (InitialPageAccess) (A14 *> DQ8) = tpd_A14_DQ8; if (InitialPageAccess) (A14 *> DQ9) = tpd_A14_DQ9; if (InitialPageAccess) (A14 *> DQ10) = tpd_A14_DQ10; if (InitialPageAccess) (A14 *> DQ11) = tpd_A14_DQ11; if (InitialPageAccess) (A14 *> DQ12) = tpd_A14_DQ12; if (InitialPageAccess) (A14 *> DQ13) = tpd_A14_DQ13; if (InitialPageAccess) (A14 *> DQ14) = tpd_A14_DQ14; if (InitialPageAccess) (A14 *> DQ15) = tpd_A14_DQ15; if (InitialPageAccess) (A15 *> DQ0) = tpd_A15_DQ0; if (InitialPageAccess) (A15 *> DQ1) = tpd_A15_DQ1; if (InitialPageAccess) (A15 *> DQ2) = tpd_A15_DQ2; if (InitialPageAccess) (A15 *> DQ3) = tpd_A15_DQ3; if (InitialPageAccess) (A15 *> DQ4) = tpd_A15_DQ4; if (InitialPageAccess) (A15 *> DQ5) = tpd_A15_DQ5; if (InitialPageAccess) (A15 *> DQ6) = tpd_A15_DQ6; if (InitialPageAccess) (A15 *> DQ7) = tpd_A15_DQ7; if (InitialPageAccess) (A15 *> DQ8) = tpd_A15_DQ8; if (InitialPageAccess) (A15 *> DQ9) = tpd_A15_DQ9; if (InitialPageAccess) (A15 *> DQ10) = tpd_A15_DQ10; if (InitialPageAccess) (A15 *> DQ11) = tpd_A15_DQ11; if (InitialPageAccess) (A15 *> DQ12) = tpd_A15_DQ12; if (InitialPageAccess) (A15 *> DQ13) = tpd_A15_DQ13; if (InitialPageAccess) (A15 *> DQ14) = tpd_A15_DQ14; if (InitialPageAccess) (A15 *> DQ15) = tpd_A15_DQ15; if (InitialPageAccess) (A16 *> DQ0) = tpd_A16_DQ0; if (InitialPageAccess) (A16 *> DQ1) = tpd_A16_DQ1; if (InitialPageAccess) (A16 *> DQ2) = tpd_A16_DQ2; if (InitialPageAccess) (A16 *> DQ3) = tpd_A16_DQ3; if (InitialPageAccess) (A16 *> DQ4) = tpd_A16_DQ4; if (InitialPageAccess) (A16 *> DQ5) = tpd_A16_DQ5; if (InitialPageAccess) (A16 *> DQ6) = tpd_A16_DQ6; if (InitialPageAccess) (A16 *> DQ7) = tpd_A16_DQ7; if (InitialPageAccess) (A16 *> DQ8) = tpd_A16_DQ8; if (InitialPageAccess) (A16 *> DQ9) = tpd_A16_DQ9; if (InitialPageAccess) (A16 *> DQ10) = tpd_A16_DQ10; if (InitialPageAccess) (A16 *> DQ11) = tpd_A16_DQ11; if (InitialPageAccess) (A16 *> DQ12) = tpd_A16_DQ12; if (InitialPageAccess) (A16 *> DQ13) = tpd_A16_DQ13; if (InitialPageAccess) (A16 *> DQ14) = tpd_A16_DQ14; if (InitialPageAccess) (A16 *> DQ15) = tpd_A16_DQ15; if (InitialPageAccess) (A17 *> DQ0) = tpd_A17_DQ0; if (InitialPageAccess) (A17 *> DQ1) = tpd_A17_DQ1; if (InitialPageAccess) (A17 *> DQ2) = tpd_A17_DQ2; if (InitialPageAccess) (A17 *> DQ3) = tpd_A17_DQ3; if (InitialPageAccess) (A17 *> DQ4) = tpd_A17_DQ4; if (InitialPageAccess) (A17 *> DQ5) = tpd_A17_DQ5; if (InitialPageAccess) (A17 *> DQ6) = tpd_A17_DQ6; if (InitialPageAccess) (A17 *> DQ7) = tpd_A17_DQ7; if (InitialPageAccess) (A17 *> DQ8) = tpd_A17_DQ8; if (InitialPageAccess) (A17 *> DQ9) = tpd_A17_DQ9; if (InitialPageAccess) (A17 *> DQ10) = tpd_A17_DQ10; if (InitialPageAccess) (A17 *> DQ11) = tpd_A17_DQ11; if (InitialPageAccess) (A17 *> DQ12) = tpd_A17_DQ12; if (InitialPageAccess) (A17 *> DQ13) = tpd_A17_DQ13; if (InitialPageAccess) (A17 *> DQ14) = tpd_A17_DQ14; if (InitialPageAccess) (A17 *> DQ15) = tpd_A17_DQ15; if (InitialPageAccess) (A18 *> DQ0) = tpd_A18_DQ0; if (InitialPageAccess) (A18 *> DQ1) = tpd_A18_DQ1; if (InitialPageAccess) (A18 *> DQ2) = tpd_A18_DQ2; if (InitialPageAccess) (A18 *> DQ3) = tpd_A18_DQ3; if (InitialPageAccess) (A18 *> DQ4) = tpd_A18_DQ4; if (InitialPageAccess) (A18 *> DQ5) = tpd_A18_DQ5; if (InitialPageAccess) (A18 *> DQ6) = tpd_A18_DQ6; if (InitialPageAccess) (A18 *> DQ7) = tpd_A18_DQ7; if (InitialPageAccess) (A18 *> DQ8) = tpd_A18_DQ8; if (InitialPageAccess) (A18 *> DQ9) = tpd_A18_DQ9; if (InitialPageAccess) (A18 *> DQ10) = tpd_A18_DQ10; if (InitialPageAccess) (A18 *> DQ11) = tpd_A18_DQ11; if (InitialPageAccess) (A18 *> DQ12) = tpd_A18_DQ12; if (InitialPageAccess) (A18 *> DQ13) = tpd_A18_DQ13; if (InitialPageAccess) (A18 *> DQ14) = tpd_A18_DQ14; if (InitialPageAccess) (A18 *> DQ15) = tpd_A18_DQ15; if (InitialPageAccess) (A19 *> DQ0) = tpd_A19_DQ0; if (InitialPageAccess) (A19 *> DQ1) = tpd_A19_DQ1; if (InitialPageAccess) (A19 *> DQ2) = tpd_A19_DQ2; if (InitialPageAccess) (A19 *> DQ3) = tpd_A19_DQ3; if (InitialPageAccess) (A19 *> DQ4) = tpd_A19_DQ4; if (InitialPageAccess) (A19 *> DQ5) = tpd_A19_DQ5; if (InitialPageAccess) (A19 *> DQ6) = tpd_A19_DQ6; if (InitialPageAccess) (A19 *> DQ7) = tpd_A19_DQ7; if (InitialPageAccess) (A19 *> DQ8) = tpd_A19_DQ8; if (InitialPageAccess) (A19 *> DQ9) = tpd_A19_DQ9; if (InitialPageAccess) (A19 *> DQ10) = tpd_A19_DQ10; if (InitialPageAccess) (A19 *> DQ11) = tpd_A19_DQ11; if (InitialPageAccess) (A19 *> DQ12) = tpd_A19_DQ12; if (InitialPageAccess) (A19 *> DQ13) = tpd_A19_DQ13; if (InitialPageAccess) (A19 *> DQ14) = tpd_A19_DQ14; if (InitialPageAccess) (A19 *> DQ15) = tpd_A19_DQ15; if (InitialPageAccess) (A20 *> DQ0) = tpd_A20_DQ0; if (InitialPageAccess) (A20 *> DQ1) = tpd_A20_DQ1; if (InitialPageAccess) (A20 *> DQ2) = tpd_A20_DQ2; if (InitialPageAccess) (A20 *> DQ3) = tpd_A20_DQ3; if (InitialPageAccess) (A20 *> DQ4) = tpd_A20_DQ4; if (InitialPageAccess) (A20 *> DQ5) = tpd_A20_DQ5; if (InitialPageAccess) (A20 *> DQ6) = tpd_A20_DQ6; if (InitialPageAccess) (A20 *> DQ7) = tpd_A20_DQ7; if (InitialPageAccess) (A20 *> DQ8) = tpd_A20_DQ8; if (InitialPageAccess) (A20 *> DQ9) = tpd_A20_DQ9; if (InitialPageAccess) (A20 *> DQ10) = tpd_A20_DQ10; if (InitialPageAccess) (A20 *> DQ11) = tpd_A20_DQ11; if (InitialPageAccess) (A20 *> DQ12) = tpd_A20_DQ12; if (InitialPageAccess) (A20 *> DQ13) = tpd_A20_DQ13; if (InitialPageAccess) (A20 *> DQ14) = tpd_A20_DQ14; if (InitialPageAccess) (A20 *> DQ15) = tpd_A20_DQ15; if (InitialPageAccess) (A21 *> DQ0) = tpd_A21_DQ0; if (InitialPageAccess) (A21 *> DQ1) = tpd_A21_DQ1; if (InitialPageAccess) (A21 *> DQ2) = tpd_A21_DQ2; if (InitialPageAccess) (A21 *> DQ3) = tpd_A21_DQ3; if (InitialPageAccess) (A21 *> DQ4) = tpd_A21_DQ4; if (InitialPageAccess) (A21 *> DQ5) = tpd_A21_DQ5; if (InitialPageAccess) (A21 *> DQ6) = tpd_A21_DQ6; if (InitialPageAccess) (A21 *> DQ7) = tpd_A21_DQ7; if (InitialPageAccess) (A21 *> DQ8) = tpd_A21_DQ8; if (InitialPageAccess) (A21 *> DQ9) = tpd_A21_DQ9; if (InitialPageAccess) (A21 *> DQ10) = tpd_A21_DQ10; if (InitialPageAccess) (A21 *> DQ11) = tpd_A21_DQ11; if (InitialPageAccess) (A21 *> DQ12) = tpd_A21_DQ12; if (InitialPageAccess) (A21 *> DQ13) = tpd_A21_DQ13; if (InitialPageAccess) (A21 *> DQ14) = tpd_A21_DQ14; if (InitialPageAccess) (A21 *> DQ15) = tpd_A21_DQ15; if (InitialPageAccess) (A22 *> DQ0) = tpd_A22_DQ0; if (InitialPageAccess) (A22 *> DQ1) = tpd_A22_DQ1; if (InitialPageAccess) (A22 *> DQ2) = tpd_A22_DQ2; if (InitialPageAccess) (A22 *> DQ3) = tpd_A22_DQ3; if (InitialPageAccess) (A22 *> DQ4) = tpd_A22_DQ4; if (InitialPageAccess) (A22 *> DQ5) = tpd_A22_DQ5; if (InitialPageAccess) (A22 *> DQ6) = tpd_A22_DQ6; if (InitialPageAccess) (A22 *> DQ7) = tpd_A22_DQ7; if (InitialPageAccess) (A22 *> DQ8) = tpd_A22_DQ8; if (InitialPageAccess) (A22 *> DQ9) = tpd_A22_DQ9; if (InitialPageAccess) (A22 *> DQ10) = tpd_A22_DQ10; if (InitialPageAccess) (A22 *> DQ11) = tpd_A22_DQ11; if (InitialPageAccess) (A22 *> DQ12) = tpd_A22_DQ12; if (InitialPageAccess) (A22 *> DQ13) = tpd_A22_DQ13; if (InitialPageAccess) (A22 *> DQ14) = tpd_A22_DQ14; if (InitialPageAccess) (A22 *> DQ15) = tpd_A22_DQ15; if (InitialPageAccess) (A23 *> DQ0) = tpd_A23_DQ0; if (InitialPageAccess) (A23 *> DQ1) = tpd_A23_DQ1; if (InitialPageAccess) (A23 *> DQ2) = tpd_A23_DQ2; if (InitialPageAccess) (A23 *> DQ3) = tpd_A23_DQ3; if (InitialPageAccess) (A23 *> DQ4) = tpd_A23_DQ4; if (InitialPageAccess) (A23 *> DQ5) = tpd_A23_DQ5; if (InitialPageAccess) (A23 *> DQ6) = tpd_A23_DQ6; if (InitialPageAccess) (A23 *> DQ7) = tpd_A23_DQ7; if (InitialPageAccess) (A23 *> DQ8) = tpd_A23_DQ8; if (InitialPageAccess) (A23 *> DQ9) = tpd_A23_DQ9; if (InitialPageAccess) (A23 *> DQ10) = tpd_A23_DQ10; if (InitialPageAccess) (A23 *> DQ11) = tpd_A23_DQ11; if (InitialPageAccess) (A23 *> DQ12) = tpd_A23_DQ12; if (InitialPageAccess) (A23 *> DQ13) = tpd_A23_DQ13; if (InitialPageAccess) (A23 *> DQ14) = tpd_A23_DQ14; if (InitialPageAccess) (A23 *> DQ15) = tpd_A23_DQ15; if (InitialPageAccess) (A24 *> DQ0) = tpd_A24_DQ0; if (InitialPageAccess) (A24 *> DQ1) = tpd_A24_DQ1; if (InitialPageAccess) (A24 *> DQ2) = tpd_A24_DQ2; if (InitialPageAccess) (A24 *> DQ3) = tpd_A24_DQ3; if (InitialPageAccess) (A24 *> DQ4) = tpd_A24_DQ4; if (InitialPageAccess) (A24 *> DQ5) = tpd_A24_DQ5; if (InitialPageAccess) (A24 *> DQ6) = tpd_A24_DQ6; if (InitialPageAccess) (A24 *> DQ7) = tpd_A24_DQ7; if (InitialPageAccess) (A24 *> DQ8) = tpd_A24_DQ8; if (InitialPageAccess) (A24 *> DQ9) = tpd_A24_DQ9; if (InitialPageAccess) (A24 *> DQ10) = tpd_A24_DQ10; if (InitialPageAccess) (A24 *> DQ11) = tpd_A24_DQ11; if (InitialPageAccess) (A24 *> DQ12) = tpd_A24_DQ12; if (InitialPageAccess) (A24 *> DQ13) = tpd_A24_DQ13; if (InitialPageAccess) (A24 *> DQ14) = tpd_A24_DQ14; if (InitialPageAccess) (A24 *> DQ15) = tpd_A24_DQ15; if (SubsequentPageAccess) (A1 *> DQ0) = tpd_A1_DQ0; if (SubsequentPageAccess) (A1 *> DQ1) = tpd_A1_DQ1; if (SubsequentPageAccess) (A1 *> DQ2) = tpd_A1_DQ2; if (SubsequentPageAccess) (A1 *> DQ3) = tpd_A1_DQ3; if (SubsequentPageAccess) (A1 *> DQ4) = tpd_A1_DQ4; if (SubsequentPageAccess) (A1 *> DQ5) = tpd_A1_DQ5; if (SubsequentPageAccess) (A1 *> DQ6) = tpd_A1_DQ6; if (SubsequentPageAccess) (A1 *> DQ7) = tpd_A1_DQ7; if (SubsequentPageAccess) (A1 *> DQ8) = tpd_A1_DQ8; if (SubsequentPageAccess) (A1 *> DQ9) = tpd_A1_DQ9; if (SubsequentPageAccess) (A1 *> DQ10) = tpd_A1_DQ10; if (SubsequentPageAccess) (A1 *> DQ11) = tpd_A1_DQ11; if (SubsequentPageAccess) (A1 *> DQ12) = tpd_A1_DQ12; if (SubsequentPageAccess) (A1 *> DQ13) = tpd_A1_DQ13; if (SubsequentPageAccess) (A1 *> DQ14) = tpd_A1_DQ14; if (SubsequentPageAccess) (A1 *> DQ15) = tpd_A1_DQ15; if (SubsequentPageAccess) (A2 *> DQ0) = tpd_A2_DQ0; if (SubsequentPageAccess) (A2 *> DQ1) = tpd_A2_DQ1; if (SubsequentPageAccess) (A2 *> DQ2) = tpd_A2_DQ2; if (SubsequentPageAccess) (A2 *> DQ3) = tpd_A2_DQ3; if (SubsequentPageAccess) (A2 *> DQ4) = tpd_A2_DQ4; if (SubsequentPageAccess) (A2 *> DQ5) = tpd_A2_DQ5; if (SubsequentPageAccess) (A2 *> DQ6) = tpd_A2_DQ6; if (SubsequentPageAccess) (A2 *> DQ7) = tpd_A2_DQ7; if (SubsequentPageAccess) (A2 *> DQ8) = tpd_A2_DQ8; if (SubsequentPageAccess) (A2 *> DQ9) = tpd_A2_DQ9; if (SubsequentPageAccess) (A2 *> DQ10) = tpd_A2_DQ10; if (SubsequentPageAccess) (A2 *> DQ11) = tpd_A2_DQ11; if (SubsequentPageAccess) (A2 *> DQ12) = tpd_A2_DQ12; if (SubsequentPageAccess) (A2 *> DQ13) = tpd_A2_DQ13; if (SubsequentPageAccess) (A2 *> DQ14) = tpd_A2_DQ14; if (SubsequentPageAccess) (A2 *> DQ15) = tpd_A2_DQ15; if (FROMCE) (CENeg *> DQ0) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ1) = tpd_CENeg_DQ1; if (FROMCE) (CENeg *> DQ2) = tpd_CENeg_DQ2; if (FROMCE) (CENeg *> DQ3) = tpd_CENeg_DQ3; if (FROMCE) (CENeg *> DQ4) = tpd_CENeg_DQ4; if (FROMCE) (CENeg *> DQ5) = tpd_CENeg_DQ5; if (FROMCE) (CENeg *> DQ6) = tpd_CENeg_DQ6; if (FROMCE) (CENeg *> DQ7) = tpd_CENeg_DQ7; if (FROMCE) (CENeg *> DQ8) = tpd_CENeg_DQ8; if (FROMCE) (CENeg *> DQ9) = tpd_CENeg_DQ9; if (FROMCE) (CENeg *> DQ10)= tpd_CENeg_DQ10; if (FROMCE) (CENeg *> DQ11)= tpd_CENeg_DQ11; if (FROMCE) (CENeg *> DQ12)= tpd_CENeg_DQ12; if (FROMCE) (CENeg *> DQ13)= tpd_CENeg_DQ13; if (FROMCE) (CENeg *> DQ14)= tpd_CENeg_DQ14; if (FROMCE) (CENeg *> DQ15)= tpd_CENeg_DQ15; if (FROMOE) (OENeg *> DQ0) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ1) = tpd_OENeg_DQ1; if (FROMOE) (OENeg *> DQ2) = tpd_OENeg_DQ2; if (FROMOE) (OENeg *> DQ3) = tpd_OENeg_DQ3; if (FROMOE) (OENeg *> DQ4) = tpd_OENeg_DQ4; if (FROMOE) (OENeg *> DQ5) = tpd_OENeg_DQ5; if (FROMOE) (OENeg *> DQ6) = tpd_OENeg_DQ6; if (FROMOE) (OENeg *> DQ7) = tpd_OENeg_DQ7; if (FROMOE) (OENeg *> DQ8) = tpd_OENeg_DQ8; if (FROMOE) (OENeg *> DQ9) = tpd_OENeg_DQ9; if (FROMOE) (OENeg *> DQ10) = tpd_OENeg_DQ10; if (FROMOE) (OENeg *> DQ11) = tpd_OENeg_DQ11; if (FROMOE) (OENeg *> DQ12) = tpd_OENeg_DQ12; if (FROMOE) (OENeg *> DQ13) = tpd_OENeg_DQ13; if (FROMOE) (OENeg *> DQ14) = tpd_OENeg_DQ14; if (FROMOE) (OENeg *> DQ15) = tpd_OENeg_DQ15; if (RCR[15] === 1'b0) ( CLK *> DQ0 ) = tpd_CLK_DQ0 ; if (RCR[15] === 1'b0) ( CLK *> DQ1 ) = tpd_CLK_DQ1 ; if (RCR[15] === 1'b0) ( CLK *> DQ2 ) = tpd_CLK_DQ2 ; if (RCR[15] === 1'b0) ( CLK *> DQ3 ) = tpd_CLK_DQ3 ; if (RCR[15] === 1'b0) ( CLK *> DQ4 ) = tpd_CLK_DQ4 ; if (RCR[15] === 1'b0) ( CLK *> DQ5 ) = tpd_CLK_DQ5 ; if (RCR[15] === 1'b0) ( CLK *> DQ6 ) = tpd_CLK_DQ6 ; if (RCR[15] === 1'b0) ( CLK *> DQ7 ) = tpd_CLK_DQ7 ; if (RCR[15] === 1'b0) ( CLK *> DQ8 ) = tpd_CLK_DQ8 ; if (RCR[15] === 1'b0) ( CLK *> DQ9 ) = tpd_CLK_DQ9 ; if (RCR[15] === 1'b0) ( CLK *> DQ10) = tpd_CLK_DQ10 ; if (RCR[15] === 1'b0) ( CLK *> DQ11) = tpd_CLK_DQ11 ; if (RCR[15] === 1'b0) ( CLK *> DQ12) = tpd_CLK_DQ12 ; if (RCR[15] === 1'b0) ( CLK *> DQ13) = tpd_CLK_DQ13 ; if (RCR[15] === 1'b0) ( CLK *> DQ14) = tpd_CLK_DQ14 ; if (RCR[15] === 1'b0) ( CLK *> DQ15) = tpd_CLK_DQ15 ; ( CENeg *> WAITOut) = tpd_CE0Neg_WAITOut ; ( OENeg *> WAITOut) = tpd_OE0Neg_WAITOut ; if (RCR[15] === 1'b0) ( CLK *> WAITOut) = tpd_CLK_WAITOut; /////////////////////////////////////////////////////////////////////////////// // Timing Violation // /////////////////////////////////////////////////////////////////////////////// $setup ( A1 , posedge ADVNeg, tsetup_A1_ADVNeg, Viol); $setup ( A2 , posedge ADVNeg, tsetup_A2_ADVNeg, Viol); $setup ( A3 , posedge ADVNeg, tsetup_A3_ADVNeg, Viol); $setup ( A4 , posedge ADVNeg, tsetup_A4_ADVNeg, Viol); $setup ( A5 , posedge ADVNeg, tsetup_A5_ADVNeg, Viol); $setup ( A6 , posedge ADVNeg, tsetup_A6_ADVNeg, Viol); $setup ( A7 , posedge ADVNeg, tsetup_A7_ADVNeg, Viol); $setup ( A8 , posedge ADVNeg, tsetup_A8_ADVNeg, Viol); $setup ( A9 , posedge ADVNeg, tsetup_A9_ADVNeg, Viol); $setup ( A10 , posedge ADVNeg, tsetup_A10_ADVNeg, Viol); $setup ( A11 , posedge ADVNeg, tsetup_A11_ADVNeg, Viol); $setup ( A12 , posedge ADVNeg, tsetup_A12_ADVNeg, Viol); $setup ( A13 , posedge ADVNeg, tsetup_A13_ADVNeg, Viol); $setup ( A14 , posedge ADVNeg, tsetup_A14_ADVNeg, Viol); $setup ( A15 , posedge ADVNeg, tsetup_A15_ADVNeg, Viol); $setup ( A16 , posedge ADVNeg, tsetup_A16_ADVNeg, Viol); $setup ( A17 , posedge ADVNeg, tsetup_A17_ADVNeg, Viol); $setup ( A18 , posedge ADVNeg, tsetup_A18_ADVNeg, Viol); $setup ( A19 , posedge ADVNeg, tsetup_A19_ADVNeg, Viol); $setup ( A20 , posedge ADVNeg, tsetup_A20_ADVNeg, Viol); $setup ( A21 , posedge ADVNeg, tsetup_A21_ADVNeg, Viol); $setup ( A22 , posedge ADVNeg, tsetup_A22_ADVNeg, Viol); $setup ( A23 , posedge ADVNeg, tsetup_A23_ADVNeg, Viol); $setup ( A24 , posedge ADVNeg, tsetup_A24_ADVNeg, Viol); $setup ( negedge CENeg , posedge ADVNeg, tsetup_CENeg_ADVNeg, Viol); $setup ( negedge RSTNeg , posedge ADVNeg, tsetup_RSTNeg_ADVNeg,Viol); $setup ( posedge WENeg , posedge ADVNeg, tsetup_WENeg_ADVNeg, Viol); $setup ( A1 , posedge CLK &&& CLK_rising, tsetup_A1_CLK, Viol); $setup ( A2 , posedge CLK &&& CLK_rising, tsetup_A2_CLK, Viol); $setup ( A3 , posedge CLK &&& CLK_rising, tsetup_A3_CLK, Viol); $setup ( A4 , posedge CLK &&& CLK_rising, tsetup_A4_CLK, Viol); $setup ( A5 , posedge CLK &&& CLK_rising, tsetup_A5_CLK, Viol); $setup ( A6 , posedge CLK &&& CLK_rising, tsetup_A6_CLK, Viol); $setup ( A7 , posedge CLK &&& CLK_rising, tsetup_A7_CLK, Viol); $setup ( A8 , posedge CLK &&& CLK_rising, tsetup_A8_CLK, Viol); $setup ( A9 , posedge CLK &&& CLK_rising, tsetup_A9_CLK, Viol); $setup ( A10 , posedge CLK &&& CLK_rising, tsetup_A10_CLK, Viol); $setup ( A11 , posedge CLK &&& CLK_rising, tsetup_A11_CLK, Viol); $setup ( A12 , posedge CLK &&& CLK_rising, tsetup_A12_CLK, Viol); $setup ( A13 , posedge CLK &&& CLK_rising, tsetup_A13_CLK, Viol); $setup ( A14 , posedge CLK &&& CLK_rising, tsetup_A14_CLK, Viol); $setup ( A15 , posedge CLK &&& CLK_rising, tsetup_A15_CLK, Viol); $setup ( A16 , posedge CLK &&& CLK_rising, tsetup_A16_CLK, Viol); $setup ( A17 , posedge CLK &&& CLK_rising, tsetup_A17_CLK, Viol); $setup ( A18 , posedge CLK &&& CLK_rising, tsetup_A18_CLK, Viol); $setup ( A19 , posedge CLK &&& CLK_rising, tsetup_A19_CLK, Viol); $setup ( A20 , posedge CLK &&& CLK_rising, tsetup_A20_CLK, Viol); $setup ( A21 , posedge CLK &&& CLK_rising, tsetup_A21_CLK, Viol); $setup ( A22 , posedge CLK &&& CLK_rising, tsetup_A22_CLK, Viol); $setup ( A23 , posedge CLK &&& CLK_rising, tsetup_A23_CLK, Viol); $setup ( A24 , posedge CLK &&& CLK_rising, tsetup_A24_CLK, Viol); $setup ( A1 , negedge CLK &&& CLK_falling, tsetup_A1_CLK, Viol); $setup ( A2 , negedge CLK &&& CLK_falling, tsetup_A2_CLK, Viol); $setup ( A3 , negedge CLK &&& CLK_falling, tsetup_A3_CLK, Viol); $setup ( A4 , negedge CLK &&& CLK_falling, tsetup_A4_CLK, Viol); $setup ( A5 , negedge CLK &&& CLK_falling, tsetup_A5_CLK, Viol); $setup ( A6 , negedge CLK &&& CLK_falling, tsetup_A6_CLK, Viol); $setup ( A7 , negedge CLK &&& CLK_falling, tsetup_A7_CLK, Viol); $setup ( A8 , negedge CLK &&& CLK_falling, tsetup_A8_CLK, Viol); $setup ( A9 , negedge CLK &&& CLK_falling, tsetup_A9_CLK, Viol); $setup ( A10 , negedge CLK &&& CLK_falling, tsetup_A10_CLK, Viol); $setup ( A11 , negedge CLK &&& CLK_falling, tsetup_A11_CLK, Viol); $setup ( A12 , negedge CLK &&& CLK_falling, tsetup_A12_CLK, Viol); $setup ( A13 , negedge CLK &&& CLK_falling, tsetup_A13_CLK, Viol); $setup ( A14 , negedge CLK &&& CLK_falling, tsetup_A14_CLK, Viol); $setup ( A15 , negedge CLK &&& CLK_falling, tsetup_A15_CLK, Viol); $setup ( A16 , negedge CLK &&& CLK_falling, tsetup_A16_CLK, Viol); $setup ( A17 , negedge CLK &&& CLK_falling, tsetup_A17_CLK, Viol); $setup ( A18 , negedge CLK &&& CLK_falling, tsetup_A18_CLK, Viol); $setup ( A19 , negedge CLK &&& CLK_falling, tsetup_A19_CLK, Viol); $setup ( A20 , negedge CLK &&& CLK_falling, tsetup_A20_CLK, Viol); $setup ( A21 , negedge CLK &&& CLK_falling, tsetup_A21_CLK, Viol); $setup ( A22 , negedge CLK &&& CLK_falling, tsetup_A22_CLK, Viol); $setup ( A23 , negedge CLK &&& CLK_falling, tsetup_A23_CLK, Viol); $setup ( A24 , negedge CLK &&& CLK_falling, tsetup_A24_CLK, Viol); $setup ( negedge ADVNeg , posedge CLK &&& CLK_rising , tsetup_ADVNeg_CLK, Viol); $setup ( negedge ADVNeg , negedge CLK &&& CLK_falling , tsetup_ADVNeg_CLK, Viol); $setup ( negedge CENeg , posedge CLK &&& CLK_rising , tsetup_CENeg_CLK, Viol); $setup ( negedge CENeg , negedge CLK &&& CLK_falling , tsetup_CENeg_CLK, Viol); $setup ( posedge WENeg , posedge CLK &&& CLK_rising , tsetup_WENeg_CLK, Viol); $setup ( posedge WENeg , negedge CLK &&& CLK_falling , tsetup_WENeg_CLK, Viol); $setup ( negedge CENeg , negedge WENeg , tsetup_CENeg_WENeg, Viol); $setup ( DQ0 , posedge WENeg , tsetup_DQ0_WENeg, Viol); $setup ( DQ1 , posedge WENeg , tsetup_DQ1_WENeg, Viol); $setup ( DQ2 , posedge WENeg , tsetup_DQ2_WENeg, Viol); $setup ( DQ3 , posedge WENeg , tsetup_DQ3_WENeg, Viol); $setup ( DQ4 , posedge WENeg , tsetup_DQ4_WENeg, Viol); $setup ( DQ5 , posedge WENeg , tsetup_DQ5_WENeg, Viol); $setup ( DQ6 , posedge WENeg , tsetup_DQ6_WENeg, Viol); $setup ( DQ7 , posedge WENeg , tsetup_DQ7_WENeg, Viol); $setup ( DQ8 , posedge WENeg , tsetup_DQ8_WENeg, Viol); $setup ( DQ9 , posedge WENeg , tsetup_DQ9_WENeg, Viol); $setup ( DQ10 , posedge WENeg , tsetup_DQ10_WENeg, Viol); $setup ( DQ11 , posedge WENeg , tsetup_DQ11_WENeg, Viol); $setup ( DQ12 , posedge WENeg , tsetup_DQ12_WENeg, Viol); $setup ( DQ13 , posedge WENeg , tsetup_DQ13_WENeg, Viol); $setup ( DQ14 , posedge WENeg , tsetup_DQ14_WENeg, Viol); $setup ( DQ15 , posedge WENeg , tsetup_DQ15_WENeg, Viol); $setup ( A1 , posedge WENeg , tsetup_A1_WENeg, Viol); $setup ( A2 , posedge WENeg , tsetup_A2_WENeg, Viol); $setup ( A3 , posedge WENeg , tsetup_A3_WENeg, Viol); $setup ( A4 , posedge WENeg , tsetup_A4_WENeg, Viol); $setup ( A5 , posedge WENeg , tsetup_A5_WENeg, Viol); $setup ( A6 , posedge WENeg , tsetup_A6_WENeg, Viol); $setup ( A7 , posedge WENeg , tsetup_A7_WENeg, Viol); $setup ( A8 , posedge WENeg , tsetup_A8_WENeg, Viol); $setup ( A9 , posedge WENeg , tsetup_A9_WENeg, Viol); $setup ( A10 , posedge WENeg , tsetup_A10_WENeg, Viol); $setup ( A11 , posedge WENeg , tsetup_A11_WENeg, Viol); $setup ( A12 , posedge WENeg , tsetup_A12_WENeg, Viol); $setup ( A13 , posedge WENeg , tsetup_A13_WENeg, Viol); $setup ( A14 , posedge WENeg , tsetup_A14_WENeg, Viol); $setup ( A15 , posedge WENeg , tsetup_A15_WENeg, Viol); $setup ( A16 , posedge WENeg , tsetup_A16_WENeg, Viol); $setup ( A17 , posedge WENeg , tsetup_A17_WENeg, Viol); $setup ( A18 , posedge WENeg , tsetup_A18_WENeg, Viol); $setup ( A19 , posedge WENeg , tsetup_A19_WENeg, Viol); $setup ( A20 , posedge WENeg , tsetup_A20_WENeg, Viol); $setup ( A21 , posedge WENeg , tsetup_A21_WENeg, Viol); $setup ( A22 , posedge WENeg , tsetup_A22_WENeg, Viol); $setup ( A23 , posedge WENeg , tsetup_A23_WENeg, Viol); $setup ( A24 , posedge WENeg , tsetup_A24_WENeg, Viol); $setup (posedge ADVNeg, posedge WENeg , tsetup_ADVNeg_WENeg, Viol); $setup (posedge WPNeg, posedge WENeg , tsetup_WPNeg_WENeg, Viol); $setup (posedge CLK &&& CLK_rising, negedge WENeg , tsetup_CLK_WENeg, Viol); $setup (negedge CLK &&& CLK_falling, negedge WENeg , tsetup_CLK_WENeg, Viol); $setup (posedge WENeg, negedge OENeg , tsetup_WENeg_OENeg, Viol); $hold ( posedge WENeg, CENeg, thold_CENeg_WENeg, Viol); $hold ( posedge WENeg ,DQ0 , thold_DQ0_WENeg, Viol); $hold ( posedge WENeg ,DQ1 , thold_DQ1_WENeg, Viol); $hold ( posedge WENeg ,DQ2 , thold_DQ2_WENeg, Viol); $hold ( posedge WENeg ,DQ3 , thold_DQ3_WENeg, Viol); $hold ( posedge WENeg ,DQ4 , thold_DQ4_WENeg, Viol); $hold ( posedge WENeg ,DQ5 , thold_DQ5_WENeg, Viol); $hold ( posedge WENeg ,DQ6 , thold_DQ6_WENeg, Viol); $hold ( posedge WENeg ,DQ7 , thold_DQ7_WENeg, Viol); $hold ( posedge WENeg ,DQ8 , thold_DQ8_WENeg, Viol); $hold ( posedge WENeg ,DQ9 , thold_DQ9_WENeg, Viol); $hold ( posedge WENeg ,DQ10, thold_DQ10_WENeg, Viol); $hold ( posedge WENeg ,DQ11, thold_DQ11_WENeg, Viol); $hold ( posedge WENeg ,DQ12, thold_DQ12_WENeg, Viol); $hold ( posedge WENeg ,DQ13, thold_DQ13_WENeg, Viol); $hold ( posedge WENeg ,DQ14, thold_DQ14_WENeg, Viol); $hold ( posedge WENeg ,DQ15, thold_DQ15_WENeg, Viol); $hold ( posedge WENeg ,A1, thold_A1_WENeg, Viol); $hold ( posedge WENeg ,A2, thold_A2_WENeg, Viol); $hold ( posedge WENeg ,A3, thold_A3_WENeg, Viol); $hold ( posedge WENeg ,A4, thold_A4_WENeg, Viol); $hold ( posedge WENeg ,A5, thold_A5_WENeg, Viol); $hold ( posedge WENeg ,A6, thold_A6_WENeg, Viol); $hold ( posedge WENeg ,A7, thold_A7_WENeg, Viol); $hold ( posedge WENeg ,A8, thold_A8_WENeg, Viol); $hold ( posedge WENeg ,A9, thold_A9_WENeg, Viol); $hold ( posedge WENeg ,A10, thold_A10_WENeg, Viol); $hold ( posedge WENeg ,A11, thold_A11_WENeg, Viol); $hold ( posedge WENeg ,A12, thold_A12_WENeg, Viol); $hold ( posedge WENeg ,A13, thold_A13_WENeg, Viol); $hold ( posedge WENeg ,A14, thold_A14_WENeg, Viol); $hold ( posedge WENeg ,A15, thold_A15_WENeg, Viol); $hold ( posedge WENeg ,A16, thold_A16_WENeg, Viol); $hold ( posedge WENeg ,A17, thold_A17_WENeg, Viol); $hold ( posedge WENeg ,A18, thold_A18_WENeg, Viol); $hold ( posedge WENeg ,A19, thold_A19_WENeg, Viol); $hold ( posedge WENeg ,A20, thold_A20_WENeg, Viol); $hold ( posedge WENeg ,A21, thold_A21_WENeg, Viol); $hold ( posedge WENeg ,A22, thold_A22_WENeg, Viol); $hold ( posedge WENeg ,A23, thold_A23_WENeg, Viol); $hold ( posedge WENeg ,A24, thold_A24_WENeg, Viol); $hold ( posedge ADVNeg ,A1, thold_A1_ADVNeg, Viol); $hold ( posedge ADVNeg ,A2, thold_A2_ADVNeg, Viol); $hold ( posedge ADVNeg ,A3, thold_A3_ADVNeg, Viol); $hold ( posedge ADVNeg ,A4, thold_A4_ADVNeg, Viol); $hold ( posedge ADVNeg ,A5, thold_A5_ADVNeg, Viol); $hold ( posedge ADVNeg ,A6, thold_A6_ADVNeg, Viol); $hold ( posedge ADVNeg ,A7, thold_A7_ADVNeg, Viol); $hold ( posedge ADVNeg ,A8, thold_A8_ADVNeg, Viol); $hold ( posedge ADVNeg ,A9, thold_A9_ADVNeg, Viol); $hold ( posedge ADVNeg ,A10, thold_A10_ADVNeg, Viol); $hold ( posedge ADVNeg ,A11, thold_A11_ADVNeg, Viol); $hold ( posedge ADVNeg ,A12, thold_A12_ADVNeg, Viol); $hold ( posedge ADVNeg ,A13, thold_A13_ADVNeg, Viol); $hold ( posedge ADVNeg ,A14, thold_A14_ADVNeg, Viol); $hold ( posedge ADVNeg ,A15, thold_A15_ADVNeg, Viol); $hold ( posedge ADVNeg ,A16, thold_A16_ADVNeg, Viol); $hold ( posedge ADVNeg ,A17, thold_A17_ADVNeg, Viol); $hold ( posedge ADVNeg ,A18, thold_A18_ADVNeg, Viol); $hold ( posedge ADVNeg ,A19, thold_A19_ADVNeg, Viol); $hold ( posedge ADVNeg ,A20, thold_A20_ADVNeg, Viol); $hold ( posedge ADVNeg ,A21, thold_A21_ADVNeg, Viol); $hold ( posedge ADVNeg ,A22, thold_A22_ADVNeg, Viol); $hold ( posedge ADVNeg ,A23, thold_A23_ADVNeg, Viol); $hold ( posedge ADVNeg ,A24, thold_A24_ADVNeg, Viol); $hold ( posedge CLK &&& CLK_rising, A1 , thold_A1_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A2 , thold_A2_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A3 , thold_A3_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A4 , thold_A4_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A5 , thold_A5_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A6 , thold_A6_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A7 , thold_A7_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A8 , thold_A8_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A9 , thold_A9_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A10 , thold_A10_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A11 , thold_A11_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A12 , thold_A12_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A13 , thold_A13_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A14 , thold_A14_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A15 , thold_A15_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A16 , thold_A16_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A17 , thold_A17_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A18 , thold_A18_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A19 , thold_A19_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A20 , thold_A20_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A21 , thold_A21_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A22 , thold_A22_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A23 , thold_A23_CLK, Viol); $hold ( posedge CLK &&& CLK_rising, A24 , thold_A24_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A1 , thold_A1_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A2 , thold_A2_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A3 , thold_A3_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A4 , thold_A4_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A5 , thold_A5_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A6 , thold_A6_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A7 , thold_A7_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A8 , thold_A8_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A9 , thold_A9_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A10 , thold_A10_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A11 , thold_A11_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A12 , thold_A12_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A13 , thold_A13_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A14 , thold_A14_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A15 , thold_A15_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A16 , thold_A16_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A17 , thold_A17_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A18 , thold_A18_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A19 , thold_A19_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A20 , thold_A20_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A21 , thold_A21_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A22 , thold_A22_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A23 , thold_A23_CLK, Viol); $hold ( negedge CLK &&& CLK_falling, A24 , thold_A24_CLK, Viol); $width ( posedge CENeg , tpw_CENeg_posedge ); $width ( posedge ADVNeg, tpw_ADVNeg_posedge ); $width ( negedge ADVNeg, tpw_ADVNeg_negedge ); $width ( posedge CLK , tpw_CLK_posedge ); $width ( negedge CLK , tpw_CLK_negedge ); $width ( posedge WENeg , tpw_WENeg_posedge ); $width ( negedge WENeg , tpw_WENeg_negedge ); $width ( negedge RSTNeg, tpw_RSTNeg_negedge ); $period( posedge CLK , tperiod_CLK); $period( negedge CLK , tperiod_CLK); endspecify //tdevice parameters aligned to model timescale // Program EraseParameter time tdevice_EraseParameter = tdevice_EraseParameter_td*1000; //2.5 sec; // Parameter Block Erase - 12V time tdevice_EraseMain = tdevice_EraseMain_td*1000; //4 sec; /////////////////////////////////////////////////////////////////////////////// // Main Behavior Block // /////////////////////////////////////////////////////////////////////////////// always @(DQIn, DQOut) begin if (DQIn==DQOut) deq=1'b1; else deq=1'b0; end // chech when data is generated from model to avoid setuphold check in // those occasion assign deg=deq; // initialize memory and load preload files if any initial begin: InitMemory integer i; for (i=0;i<=MemSize;i=i+1) begin MemData[i]=MaxData; end if ((UserPreload) && !(mem_file_name == "none")) begin // File Read Section //#i28f512p33_2 memory file //# / - comment //# @aaaaa - stands for address //# dddd - is word to be written at Mem(aaaaa++) //# (aaaaa is incremented at every load) //# //# only first 1-6 columns are loaded. NO empty lines ! $readmemh(mem_file_name, MemData); end for (i=0;i<=BlockNum;i=i+1) begin OTP[i]=1'b0; end if ((UserPreload) && !(otp_blocks_file == "none")) begin // File Read Section //#i28f512p33_2 memory file //# / - comment //# @aaa - stands for address //# dddd - is word to be written at OTP(aaa++) //# (aaa is incremented at every load) //# //# only first 1-6 columns are loaded. NO empty lines ! $readmemh(otp_blocks_file, OTP); end PR[9'h80] = 16'hFFFE; for (i=9'h81;i<=9'h109;i=i+1) begin PR[i]=MaxData; end if ((UserPreload) && !(prot_reg_file == "none")) begin // File Read Section //#i28f512p33_2 memory file //# / - comment //# @aaa - stands for address //# dddd - is word to be written at PR(aaa++) //# (aaa is incremented at every load) //# //# only first 1-6 columns are loaded. NO empty lines ! $readmemh(prot_reg_file, PR); end for (i=0;i<=BlockNum;i=i+1) begin Block_Lock[i] = LOCKED; BlockLockBit[i] = 1'b1; BlockLockDownBit[i] = 1'b0; end end initial begin /////////////////////////////////////////////////////////////////////// //CFI array data /////////////////////////////////////////////////////////////////////// CFI_array[9'h10]=16'h51; CFI_array[9'h11]=16'h52; CFI_array[9'h12]=16'h59; CFI_array[9'h13]=16'h01; CFI_array[9'h14]=16'h00; CFI_array[9'h15]=16'h0A; CFI_array[9'h16]=16'h01; CFI_array[9'h17]=16'h00; CFI_array[9'h18]=16'h00; CFI_array[9'h19]=16'h00; CFI_array[9'h1A]=16'h00; // System Interface Information CFI_array[9'h1B]=16'h23; CFI_array[9'h1C]=16'h36; CFI_array[9'h1D]=16'h85; CFI_array[9'h1E]=16'h95; CFI_array[9'h1F]=16'h08; CFI_array[9'h20]=16'h09; CFI_array[9'h21]=16'h0A; CFI_array[9'h22]=16'h00; CFI_array[9'h23]=16'h01; CFI_array[9'h24]=16'h01; CFI_array[9'h25]=16'h02; CFI_array[9'h26]=16'h00; // Device Geometry definition CFI_array[9'h27]=16'h19; CFI_array[9'h28]=16'h01; CFI_array[9'h29]=16'h00; CFI_array[9'h2A]=16'h06; CFI_array[9'h2B]=16'h00; CFI_array[9'h2C]=16'h02; CFI_array[9'h2D]=16'h03; CFI_array[9'h2E]=16'h00; CFI_array[9'h2F]=16'h80; CFI_array[9'h30]=16'h00; CFI_array[9'h31]=16'hFE; CFI_array[9'h32]=16'h00; CFI_array[9'h33]=16'h00; CFI_array[9'h34]=16'h02; CFI_array[9'h35]=16'h00; CFI_array[9'h36]=16'h00; CFI_array[9'h37]=16'h00; CFI_array[9'h38]=16'h00; // Primary-vendor specific extended query CFI_array[9'h10A]=16'h50; CFI_array[9'h10B]=16'h52; CFI_array[9'h10C]=16'h49; CFI_array[9'h10D]=16'h31; CFI_array[9'h10E]=16'h34; CFI_array[9'h10F]=16'hE6; CFI_array[9'h110]=16'h01; CFI_array[9'h111]=16'h00; CFI_array[9'h112]=16'h00; // Bottom Parameter Block Lower die CFI_array[9'h113]=16'h01; CFI_array[9'h114]=16'h03; CFI_array[9'h115]=16'h00; CFI_array[9'h116]=16'h30; CFI_array[9'h117]=16'h90; // Protection register information CFI_array[9'h118]=16'h02; CFI_array[9'h119]=16'h80; CFI_array[9'h11A]=16'h00; CFI_array[9'h11B]=16'h03; CFI_array[9'h11C]=16'h03; CFI_array[9'h11D]=16'h89; CFI_array[9'h11E]=16'h00; CFI_array[9'h11F]=16'h00; CFI_array[9'h120]=16'h00; CFI_array[9'h121]=16'h00; CFI_array[9'h122]=16'h00; CFI_array[9'h123]=16'h00; CFI_array[9'h124]=16'h10; CFI_array[9'h125]=16'h00; CFI_array[9'h126]=16'h04; // Burst read information CFI_array[9'h127]=16'h03; CFI_array[9'h128]=16'h04; CFI_array[9'h129]=16'h01; CFI_array[9'h12A]=16'h02; CFI_array[9'h12B]=16'h03; CFI_array[9'h12C]=16'h07; //Partition and Erase Block Region Information CFI_array[9'h12D]=16'h01; CFI_array[9'h12E]=16'h24; CFI_array[9'h12F]=16'h00; CFI_array[9'h130]=16'h01; CFI_array[9'h131]=16'h00; CFI_array[9'h132]=16'h11; CFI_array[9'h133]=16'h00; CFI_array[9'h134]=16'h00; CFI_array[9'h135]=16'h02; CFI_array[9'h136]=16'h03; CFI_array[9'h137]=16'h00; CFI_array[9'h138]=16'h80; CFI_array[9'h139]=16'h00; CFI_array[9'h13A]=16'h64; CFI_array[9'h13B]=16'h00; CFI_array[9'h13C]=16'h02; CFI_array[9'h13D]=16'h03; CFI_array[9'h13E]=16'h00; CFI_array[9'h13F]=16'h80; CFI_array[9'h140]=16'h00; CFI_array[9'h141]=16'h00; CFI_array[9'h142]=16'h00; CFI_array[9'h143]=16'h80; CFI_array[9'h144]=16'hFE; CFI_array[9'h145]=16'h00; CFI_array[9'h146]=16'h00; CFI_array[9'h147]=16'h02; CFI_array[9'h148]=16'h64; CFI_array[9'h149]=16'h00; CFI_array[9'h14A]=16'h02; CFI_array[9'h14B]=16'h03; CFI_array[9'h14C]=16'h00; CFI_array[9'h14D]=16'h80; CFI_array[9'h14E]=16'h00; CFI_array[9'h14F]=16'h00; CFI_array[9'h150]=16'h00; CFI_array[9'h151]=16'h80; CFI_array[9'h152]=16'hFF; CFI_array[9'h153]=16'hFF; CFI_array[9'h154]=16'hFF; CFI_array[9'h155]=16'hFF; CFI_array[9'h156]=16'hFF; end initial begin current_state = RESET_POWER_DOWN; next_state = RESET_POWER_DOWN; read_state = READ_ARRAY; WordProgram_in = 1'b0; BuffProgram_in = 1'b0; BEFP_in = 1'b0; BEFPsetup_in = 1'b0; ParameterErase_in = 1'b0; MainErase_in = 1'b0; ProgramSuspend_in = 1'b0; EraseSuspend_in = 1'b0; RstDuringErsPrg_in = 1'b0; CLOCK = 1'b0; Write = 1'b0; Read = 1'b0; Pmode = 1'b0; abort = 1'b0; ExtendProgTime = 1'b0; AssertWAITOut = 1'b0; DeassertWAITOut = 1'b0; read_out = 1'b0; SR = 8'b10000000; RCR = 16'b1011111111001111; LATCHED = 1'b0; Viol = 1'b0; word_cntr = 0; end /////////////////////////////////////////////////////////////////////////// //// Internal Delays /////////////////////////////////////////////////////////////////////////// always @(posedge BEFP_in) begin:BEFP BEFP_out = 1'b1; #tdevice_BEFP BEFP_out = 1'b0; end always @(posedge BEFPsetup_in) begin:BEFPsetup BEFPsetup_out = 1'b1; #tdevice_BEFPsetup BEFPsetup_out = 1'b0; end always @(posedge ProgramSuspend_in) begin:ProgramSuspend ProgramSuspend_out = 1'b1; #tdevice_ProgramSuspend ProgramSuspend_out = 1'b0; end always @(posedge EraseSuspend_in) begin:EraseSuspend EraseSuspend_out = 1'b1; #tdevice_EraseSuspend EraseSuspend_out = 1'b0; end always @(posedge RstDuringErsPrg_in) begin:RstDuringErsPrg RstDuringErsPrg_out = 1'b1; #tdevice_RstDuringErsPrg RstDuringErsPrg_out = 1'b0; end ////////////////////////////////////////////////////////////// // Clock control ////////////////////////////////////////////////////////////// always @ (posedge CLK_ipd) begin : CLKControl1 if ((RSTNeg_ipd) && (~CENeg_ipd) && (WENeg_ipd) && (RCR[15] == 1'b0) && (RCR[6] == 1'b1) && (current_state != RESET_POWER_DOWN)) begin CLOCK = 1'b1; #1 CLOCK <= 1'b0; end end always @ (negedge CLK_ipd) begin : CLKControl2 if ((RSTNeg_ipd) && (~CENeg_ipd) && (WENeg_ipd) && (RCR[15] == 1'b0) && (RCR[6] == 1'b0) && (current_state != RESET_POWER_DOWN)) begin CLOCK = 1'b1; #1 CLOCK <= 1'b0; end end always @ (negedge RSTNeg_ipd) begin : RSTControl if (WordProgram_out || BuffProgram_out || ParameterErase_out || MainErase_out || BEFP_out) begin RstDuringErsPrg_in = 1'b0; #1 RstDuringErsPrg_in <= 1'b1; end end ////////////////////////////////////////////////////////////////////////// //// bus cycle decode ////////////////////////////////////////////////////////////////////////// always @ (falling_edge_ADVNeg or rising_edge_ADVNeg or rising_edge_CLOCK or OENeg or RSTNeg or rising_edge_WENeg or rising_edge_CENeg or WENeg or CENeg or Alow_event) begin : BusCycleDecode if (~RSTNeg || CENeg || falling_edge_ADVNeg) LATCHED = 0; if (RSTNeg && current_state != RESET_POWER_DOWN) begin if (~CENeg && ~LATCHED && ((rising_edge_ADVNeg && WENeg) || (~ADVNeg && WENeg && ~RCR[15] && rising_edge_CLOCK) ) ) begin LatchedAddr = A; ReadAddr = A; LATCHED = 1'b1; burst_cntr = 0; BurstDelay = RCR[13:11]; case (RCR[2:0]) 3'b001: BurstLength = 4; 3'b010: BurstLength = 8; 3'b011: BurstLength = 16; 3'b111: BurstLength = 0; endcase DataHold = 0; end // Write control if (OENeg) begin if (~WENeg && ~CENeg) Write = 0; else if ((~CENeg && rising_edge_WENeg) || (~WENeg && rising_edge_CENeg)||(rising_edge_CENeg && rising_edge_WENeg)) begin LatchedData = DQIn; LatchedAddr = A; Write = 1; end end // Read control if (RCR[15]) begin if (WENeg && ~CENeg && ~OENeg) begin if (~ADVNeg) ReadAddr = A; Read = 1; end else begin Read = 0; Pmode = 0; end if (Read && Alow_event) begin Pmode = 1; Pmode <= #2 0; end end else begin if (rising_edge_CLOCK) begin if (BurstDelay > 0) begin #1 BurstDelay = BurstDelay - 1; if (RCR[8] && (BurstDelay == 0 || (BurstDelay == 1 && RCR[9] ) ) ) DeassertWAITOut = ~(DeassertWAITOut); end else begin if (DataHold == 0) begin burst_cntr = burst_cntr + 1; if (~OENeg) Read = ~(Read); if (RCR[9]) DataHold = 1; if ( (burst_cntr > (BurstLength - RCR[8]) ) && BurstLength > 0) AssertWAITOut = ~(AssertWAITOut); else if (read_state == READ_ARRAY && ~RCR[9] && RCR[13:11] > 4) begin if (~RCR[8]) begin if (burst_cntr > 4 || burst_cntr <= 0) AssertWAITOut = ~(AssertWAITOut); else DeassertWAITOut = ~(DeassertWAITOut); end else begin if (burst_cntr >= 4 || burst_cntr < 0) AssertWAITOut = ~(AssertWAITOut); else DeassertWAITOut = ~(DeassertWAITOut); end end DeassertWAITOut = ~(DeassertWAITOut); end else DataHold = DataHold - 1; end end end end end ////////////////////////////////////////////////////////////////////////////// //// sequential process for reset control and FSM state transition ////////////////////////////////////////////////////////////////////////////// always @(next_state) begin : FSM if (ExtendProgTime == 1'b0) current_state = next_state; end //////////////////////////////////////////////////////////////////////////// // obtain 'LAST_EVENT information //////////////////////////////////////////////////////////////////////////// always @(negedge OENeg_ipd) begin OENeg_event = $time; end always @(negedge CENeg_ipd) begin CENeg_event = $time; end always @(A) begin ADDR_event = $time; end /////////////////////////////////////////////////////////////////////////// // FSM - Combinational process for next state generation /////////////////////////////////////////////////////////////////////////// always @(falling_edge_RSTNeg or rising_edge_RSTNeg or rising_edge_Write or RstDuringErsPrg_out_event or WordProgram_out_event or abort or ProgramSuspend_out_event or BuffProgram_out_event or ExtendProgTime_event or falling_edge_EraseSuspend_out or ParameterErase_out_event or falling_edge_MainErase_out or falling_edge_BEFPsetup_out or falling_edge_BEFP_out ) begin : StateGen if (falling_edge_RSTNeg) next_state = RESET_POWER_DOWN; else begin case (current_state) RESET_POWER_DOWN : begin if (((rising_edge_RSTNeg && ~RstDuringErsPrg_out) || (RstDuringErsPrg_out_event && ~RstDuringErsPrg_out)) && $time > 0 ) begin next_state = READY; end end READY: begin if (rising_edge_Write) begin case (LatchedData) 16'h10, 16'h40 : next_state = PROG_SETUP; 16'hE8 : next_state = BP_SETUP; 16'h20 : next_state = ERASE_SETUP; 16'h80 : next_state = BEFP_SETUP; 16'h60 : next_state = LOCK_SETUP; 16'hC0 : next_state = OTP_SETUP; default : next_state = current_state; endcase end end LOCK_SETUP : begin if (rising_edge_Write) next_state = READY; end OTP_SETUP : begin if (rising_edge_Write) next_state = OTP_BUSY; end OTP_BUSY : begin if (abort || (WordProgram_out_event && ~WordProgram_out) ) next_state = READY; end PROG_SETUP : begin if (rising_edge_Write) next_state = PROG_BUSY; end PROG_BUSY : begin if (abort || (WordProgram_out_event && ~WordProgram_out) ) next_state = READY; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = PROG_SUSP; end PROG_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = PROG_BUSY; end BP_SETUP : begin if (rising_edge_Write) begin word_cnt = LatchedData + 1; next_state = BP_LOAD; end end BP_LOAD : begin if (rising_edge_Write) begin word_cnt = word_cnt - 1; if (word_cnt == 0) next_state = BP_CONFIRM; end end BP_CONFIRM : begin if (rising_edge_Write) begin if (LatchedData == 16'hD0) next_state = BP_BUSY; else next_state = READY; end end BP_BUSY : begin if (abort || (BuffProgram_out_event && ~BuffProgram_out && ~ExtendProgTime)) next_state = READY; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = BP_SUSP; else if (ExtendProgTime_event) next_state = current_state; end BP_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = BP_BUSY; end ERASE_SETUP : begin if (rising_edge_Write) begin if (LatchedData == 16'hD0) next_state = ERASE_BUSY; else next_state = READY; end end ERASE_BUSY : begin if ((abort || (ParameterErase_out_event && ~ParameterErase_out) || (falling_edge_MainErase_out ) ) && ~suspended_erase) next_state = READY; else if (falling_edge_EraseSuspend_out) next_state = ERS_SUSP; end ERS_SUSP : begin if (rising_edge_Write) begin case (LatchedData) 16'h10, 16'h40: next_state = PROG_SETUP_ERS_SUSP; 16'hE8 : next_state = BP_SETUP_ERS_SUSP; 16'hD0: next_state = ERASE_BUSY; 16'h60: next_state = LOCK_SETUP_ERS_SUSP; default: next_state = current_state; endcase end end PROG_SETUP_ERS_SUSP : begin if (rising_edge_Write) next_state = PROG_BUSY_ERS_SUSP; end PROG_BUSY_ERS_SUSP : begin if (abort || (WordProgram_out_event && ~WordProgram_out) ) next_state = ERS_SUSP; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = PROG_SUSP_ERS_SUSP; end PROG_SUSP_ERS_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = PROG_BUSY_ERS_SUSP; end BP_SETUP_ERS_SUSP : begin if (rising_edge_Write) begin word_cnt = LatchedData + 1; next_state = BP_LOAD_ERS_SUSP; end end BP_LOAD_ERS_SUSP : begin if (rising_edge_Write) begin word_cnt = word_cnt - 1; if (word_cnt == 0) next_state = BP_CONFIRM_ERS_SUSP; end end BP_CONFIRM_ERS_SUSP : begin if (rising_edge_Write) begin if (LatchedData == 16'hD0) next_state = BP_BUSY_ERS_SUSP; else next_state = ERS_SUSP; end end BP_BUSY_ERS_SUSP : begin if (abort || (BuffProgram_out_event && ~BuffProgram_out && ~ExtendProgTime)) next_state = ERS_SUSP; else if (ProgramSuspend_out_event && ~ProgramSuspend_out) next_state = BP_SUSP_ERS_SUSP; else if (ExtendProgTime_event) next_state = current_state; end BP_SUSP_ERS_SUSP : begin if (rising_edge_Write && LatchedData == 16'hD0) next_state = BP_BUSY_ERS_SUSP; end LOCK_SETUP_ERS_SUSP : begin if (rising_edge_Write) next_state = ERS_SUSP; end BEFP_SETUP : begin if (rising_edge_Write) begin if (LatchedData != 16'hD0) next_state = READY; else begin BEFP_block2 = BlockNumber(LatchedAddr); word_cnt = 32; end end else if (falling_edge_BEFPsetup_out) begin if (SR[4] == 1'b0) next_state = BEFP_LOAD; else next_state = READY; end end BEFP_LOAD : begin if (rising_edge_Write) begin if ((BlockNumber(LatchedAddr) != BEFP_block2) && LatchedData == 16'hFFFF) next_state = READY; else begin word_cnt = word_cnt - 1; if (word_cnt == 0) next_state = BEFP_BUSY; end end end BEFP_BUSY : begin if (falling_edge_BEFP_out) begin word_cnt = 32; next_state = BEFP_LOAD; end end endcase end end //////////////////////////////////////////////////////////////////////////// // Functional //////////////////////////////////////////////////////////////////////////// always @(rising_edge_Write or WordProgram_out_event or BuffProgram_out_event or falling_edge_RSTNeg or ParameterErase_out_event or falling_edge_MainErase_out or falling_edge_BEFPsetup_out or falling_edge_BEFP_out or abort or falling_edge_EraseSuspend_out or ProgramSuspend_out_event) begin if (rising_edge_Write) begin if ((current_state != RESET_POWER_DOWN) && (current_state != OTP_BUSY) && (current_state != PROG_BUSY) && (current_state != BP_BUSY) && (current_state != ERASE_BUSY) && (current_state != PROG_BUSY_ERS_SUSP) && (current_state != BP_BUSY_ERS_SUSP) && (current_state != BEFP_SETUP) && (current_state != BEFP_LOAD) && (LatchedData == 8'h50)) SR = 8'b10000000; end case (current_state) RESET_POWER_DOWN : begin SR = 8'b10000000; for (i=0;i<=BlockNum;i=i+1) begin Block_Lock[i] = LOCKED; BlockLockBit[i] = 1'b1; BlockLockDownBit[i] = 1'b0; end read_state = READ_ARRAY; RCR = 16'b1011111111001111; end READY : begin if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; endcase end end LOCK_SETUP, LOCK_SETUP_ERS_SUSP : begin if (rising_edge_Write) begin block_number = BlockNumber(LatchedAddr); if (LatchedData == 16'h03) begin RCR = A[15:0]; read_state = READ_ARRAY; end else if (LatchedData == 16'h01) begin read_state = READ_STATUS; if (Block_Lock[block_number] == UNLOCKED) Block_Lock[block_number] = LOCKED; BlockLockBit[block_number] = 1'b1; end else if (LatchedData == 16'hD0) begin read_state = READ_STATUS; if (!( (Block_Lock[block_number] == LOCKED_DOWN) && WPNeg == 1'b0) ) begin Block_Lock[block_number] = UNLOCKED; BlockLockBit[block_number] = 0; end end else if (LatchedData == 16'h2F) begin read_state = READ_STATUS; Block_Lock[block_number] = LOCKED_DOWN; BlockLockBit[block_number] = 1'b1; BlockLockDownBit[block_number] = 1'b1; end else begin read_state = READ_STATUS; SR[4] = 1'b1; SR[5] = 1'b1; end end else read_state = READ_STATUS; end OTP_SETUP : begin read_state = READ_STATUS; if (rising_edge_Write) begin DataBuff[0] = LatchedData; AddrBuff[0] = LatchedAddr; WordProgram_in = 1'b1; WordProgram_in <= #1 1'b0; end end OTP_BUSY : begin if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70, 16'h90, 16'h98 : read_state = READ_STATUS; endcase end mem_bits = PR[9'h80]; prog_bits = PR[9'h89]; if (VPP != 1'b1) begin SR[3] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] < 9'h80) || (AddrBuff[0] > 9'h109)) begin SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] > 9'h80) && (AddrBuff[0] < 9'h85)) begin SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] > 9'h84) && (AddrBuff[0] < 9'h89) && (mem_bits[1] != 1'b1)) begin SR[1] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if ((AddrBuff[0] > 9'h89) && (AddrBuff[0] < 9'h10A) && (prog_bits[(AddrBuff[0]-9'h8A)/8] != 1'b1)) begin SR[1] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else SR[7] = 1'b0; if (falling_edge_RSTNeg) PR[AddrBuff[0]] = -1; if (WordProgram_out_event && ~WordProgram_out && ~abort) begin if (PR[AddrBuff[0]] > -1) begin prog_bits = DataBuff[0]; mem_bits = PR[AddrBuff[0]]; for (i=0; i<= 15; i=i+1) begin if (prog_bits[i] == 0) mem_bits[i] = 0; end PR[AddrBuff[0]] = mem_bits; end SR[7] = 1; end end PROG_SETUP, PROG_SETUP_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin DataBuff[0] = LatchedData; AddrBuff[0] = LatchedAddr; WordProgram_in = 1; WordProgram_in <= #1 0; end end PROG_BUSY, PROG_BUSY_ERS_SUSP : begin SR[2] = 0; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hB0 : begin ProgramSuspend_in = 1'b1; ProgramSuspend_in <= #1 1'b0; end endcase end block_number = BlockNumber(AddrBuff[0]); if (VPP == 1'b0) begin SR[3] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if (OTP[block_number] == 1'b1) begin SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else if (Block_Lock[block_number] != UNLOCKED) begin SR[1] = 1'b1; SR[4] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; end else SR[7] = 1'b0; if (falling_edge_RSTNeg ) MemData[AddrBuff[0]] = -1; if (WordProgram_out_event && ~WordProgram_out && ~abort) begin if (MemData[AddrBuff[0]] > -1 ) begin prog_bits = DataBuff[0]; mem_bits = MemData[AddrBuff[0]]; for (i= 0; i<= 15; i=i+1) if (prog_bits[i] == 0) mem_bits[i] = 0; MemData[AddrBuff[0]] = mem_bits; end SR[7] = 1; end end PROG_SUSP, PROG_SUSP_ERS_SUSP : begin SR[2] = 1'b1; SR[7] = 1'b1; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hD0 : begin WordProgramResume = 1'b1; WordProgramResume <= #1 1'b0; end endcase end end BP_SETUP, BP_SETUP_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin word_number = LatchedData; word_cntr = 0; end end BP_LOAD, BP_LOAD_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin DataBuff[word_cntr] = LatchedData; AddrBuff[word_cntr] = LatchedAddr; if (word_cntr == 0) begin lowest_addr = LatchedAddr; highest_addr = LatchedAddr; end else begin if (LatchedAddr < lowest_addr) lowest_addr = LatchedAddr; if (LatchedAddr > highest_addr) highest_addr = LatchedAddr; end word_cntr = word_cntr + 1; end end BP_CONFIRM, BP_CONFIRM_ERS_SUSP : begin read_state = READ_STATUS; if (rising_edge_Write) begin if (LatchedData != 16'hD0) begin SR[7] = 1'b1; SR[5] = 1'b1; SR[4] = 1'b1; end else if (LatchedData == 16'hD0) begin BuffProgram_in = 1; BuffProgram_in <= #1 0; end end end BP_BUSY, BP_BUSY_ERS_SUSP : begin SR[2] = 0; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hB0 : begin suspended_bp = 1'b1; ProgramSuspend_in = 1'b1; ProgramSuspend_in <= #1 1'b0; end endcase end block_number = BlockNumber(AddrBuff[0]); if (VPP == 0) begin SR[3] = 1; SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if (OTP[block_number] == 1) begin SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if (Block_Lock[block_number] != UNLOCKED) begin SR[1] = 1; SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if ((lowest_addr < AddrBuff[0]) || (highest_addr > (AddrBuff[0]+word_number)) && (word_number != -1)) begin SR[4] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else if (BlockNumber(highest_addr) != block_number) begin SR[4] = 1; SR[5] = 1; SR[7] = 1; abort = 1'b1; abort <= #1 1'b0; end else SR[7] = 0; if (falling_edge_RSTNeg) begin for (j=0;j<=word_number; j=j+1) MemData[AddrBuff[j]] = -1; end if ( BuffProgram_out_event && ~BuffProgram_out && ~suspended_bp && ~abort ) begin for (j=0; j<= word_number; j=j+1) begin if (MemData[AddrBuff[j]] > -1 ) begin prog_bits = DataBuff[j]; mem_bits = MemData[AddrBuff[j]]; for (i=0; i<=15; i=i+1) begin if (prog_bits[i] == 1'b0) mem_bits[i] = 1'b0; end MemData[AddrBuff[j]] = mem_bits; end end for (j=0; j<= word_number; j=j+1) begin if ((AddrBuff[j] / 32) != (AddrBuff[0]/32)) begin ExtendProgTime = 1; ExtendProgTime <= #1 0; word_number = -1; BuffProgram_in = 1'b1; BuffProgram_in <= #1 1'b0; end end SR[7] = 1; end end BP_SUSP, BP_SUSP_ERS_SUSP : begin SR[2] = 1'b1; SR[7] = 1'b1; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hD0 : begin suspended_bp = 1'b0; BP_ProgramResume = 1'b1; BP_ProgramResume <= #1 1'b0; end endcase end end ERASE_SETUP : begin read_state = READ_STATUS; if (rising_edge_Write) begin if (LatchedData == 16'hD0) begin erasing_block = BlockNumber(LatchedAddr); if (BlockSize(erasing_block) == ParameterBlockSize) begin ParameterErase_in = 1; ParameterErase_in <= #1 0; end else begin MainErase_in = 1; MainErase_in <= #1 0; end end else begin SR[7] = 1'b1; SR[5] = 1'b1; SR[4] = 1'b1; end end end ERASE_BUSY : begin SR[6] = 0; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hB0 : begin suspended_erase = 1'b1; EraseSuspend_in = 1'b1; EraseSuspend_in <= #1 1'b0; end endcase end aborted = 1'b0; if (VPP == 1'b0) begin SR[3] = 1'b1; SR[5] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; aborted = 1'b1; end else if (OTP[erasing_block] == 1'b1) begin SR[5] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; aborted = 1'b1; end else if (Block_Lock[erasing_block] != UNLOCKED) begin SR[1] = 1'b1; SR[5] = 1'b1; SR[7] = 1'b1; abort = 1'b1; abort <= #1 1'b0; aborted = 1'b1; end else SR[7] = 1'b0; block_size = BlockSize(erasing_block); start_addr = StartBlockAddr(erasing_block); if (~aborted) begin for (i = 0; i< block_size; i=i+1 ) MemData[start_addr + i] = -1; end if ( ( (ParameterErase_out_event && ~ParameterErase_out) || (falling_edge_MainErase_out)) && ~abort && ~suspended_erase) begin SR[7] = 1'b1; for (i=0;i<=block_size;i=i+1) MemData[start_addr + i] = MaxData; end end ERS_SUSP : begin SR[6] = 1'b1; SR[7] = 1'b1; if (rising_edge_Write) begin case (LatchedData) 16'hFF : read_state = READ_ARRAY; 16'h70 : read_state = READ_STATUS; 16'h90 : read_state = READ_ID; 16'h98 : read_state = READ_QUERY; 16'hD0 : begin suspended_erase = 1'b0; if (BlockSize(erasing_block) == ParameterBlockSize) begin ParameterEraseResume = 1'b1; ParameterEraseResume <= #1 1'b0; end else begin MainEraseResume = 1'b1; MainEraseResume <= #1 1'b0; end end endcase end end BEFP_SETUP : begin read_state = READ_STATUS; if (rising_edge_Write && (LatchedData == 16'hD0)) begin BEFP_addr = LatchedAddr; BEFP_block = BlockNumber(LatchedAddr); word_cntr = 0; if ((VPP != 1'b1) || (VPP_voltage != 9)) begin SR[3] = 1'b1; SR[4] = 1'b1; end if (Block_Lock[BEFP_block] != UNLOCKED) begin SR[1] = 1'b1; SR[4] = 1'b1; end else if (((BEFP_addr % 32) != 0) || (OTP[BEFP_block] == 1'b1)) SR[4] = 1'b1; BEFPsetup_in = 1'b1; BEFPsetup_in <= #1 1'b0; end else if (falling_edge_BEFPsetup_out) begin if (SR[4] == 0) begin SR[7] = 0; SR[0] = 0; end end end BEFP_LOAD : begin if (rising_edge_Write) begin if ((BlockNumber(LatchedAddr) != BEFP_block) && (LatchedData == 16'hFFFF)) begin SR[7] = 1'b1; SR[0] = 1'b0; end else begin DataBuff[word_cntr] = LatchedData; word_cntr = word_cntr + 1; if (word_cntr == 31) begin BEFP_in = 1'b1; BEFP_in <= #1 1'b0; end end end end BEFP_BUSY : begin if (falling_edge_RSTNeg) begin for (j = 0 ; j<= 31; j=j+1) MemData[BEFP_addr+j] = -1; end if (falling_edge_BEFP_out) begin for (j=0;j<=31;j=j+1) begin if (MemData[BEFP_addr+j] > -1) begin prog_bits = DataBuff[j]; mem_bits = MemData[BEFP_addr + j]; for (i=0;i<=15;i=i+1) begin if (prog_bits[i] == 1'b0) mem_bits[i] = 1'b0; end MemData[BEFP_addr + j] = mem_bits; end end BEFP_addr = BEFP_addr + 32; if ((BEFP_addr > MemSize) || (BlockNumber(BEFP_addr) > BEFP_block)) BEFP_addr = BEFP_addr - BlockSize(BEFP_block); SR[0] = 1'b0; word_cntr = 0; end else SR[0] = 1'b1; end endcase end /////////////////////////////////////////////////////////// // Combinatorial output generation /////////////////////////////////////////////////////////// always @(Ahigh_event or Alow_event or rising_edge_Read or A_event or OENeg or falling_edge_Read or CENeg ) begin : Output case (read_state) READ_ARRAY : begin if (RCR[15] == 1'b1) begin if (Ahigh_event && ~ADVNeg) ReadAddr = A; else if (Alow_event) ReadAddr = ReadAddr - (ReadAddr % 4) + A[1:0]; end if (current_state == PROG_BUSY || current_state == PROG_BUSY_ERS_SUSP || current_state == BP_BUSY || current_state == BP_BUSY_ERS_SUSP || current_state == ERASE_BUSY) DQOut_tmp = 16'bx; else begin if (MemData[ReadAddr] > -1) DQOut_tmp = MemData[ReadAddr]; else DQOut_tmp = 16'bx; end end READ_ID : begin if ((((ReadAddr-2) % MainBlockSize) == 0) || ((ReadAddr < MainBlockSize) && (((ReadAddr-2) % ParameterBlockSize) == 0))) begin DQOut_tmp[0] = BlockLockBit[BlockNumber(ReadAddr)]; DQOut_tmp[1] = BlockLockDownBit[BlockNumber(ReadAddr)]; DQOut_tmp[15:2] = 14'b0; end else if (ReadAddr == 0) DQOut_tmp = 16'h0089; else if (ReadAddr == 1) begin DQOut_tmp = DeviceID_B; end else if (ReadAddr == 5) DQOut_tmp = RCR; else if ((ReadAddr >= 9'h80) && (ReadAddr <= 9'h109)) begin if (PR[ReadAddr] > -1) DQOut_tmp = PR[ReadAddr]; else DQOut_tmp = 16'bx; end end READ_QUERY : begin if (((ReadAddr >= 9'h10) && (ReadAddr <= 9'h38)) || ((ReadAddr >= 9'h10A) && (ReadAddr <= 9'h156))) DQOut_tmp = CFI_array[ReadAddr]; else DQOut_tmp = 16'b0; end READ_STATUS : begin DQOut_tmp[15:8] = 8'b0; DQOut_tmp[7:0] = SR; end endcase if (RCR[15] == 1'b1) // Asynchronous read begin if (rising_edge_Read || (Read && ((A_event && ~ADVNeg) || Alow_event))) DQOut_zd = DQOut_tmp; else if (falling_edge_Read) DQOut_zd = 16'bz; end else // Burst read begin if (rising_edge_Read || falling_edge_Read) begin if ((burst_cntr > BurstLength) && (BurstLength != 0)) read_out = 1'b0; else if (read_state == READ_ARRAY) begin if ((RCR[9] == 1'b0) && (RCR[13:11] > 4) && ((burst_cntr >= 5) || (burst_cntr < 1))) begin read_out = 1'b0; if (burst_cntr >= 5) burst_cntr = 5 - RCR[13:11]; end else begin read_out = 1'b1; if (ReadAddr < MemSize) ReadAddr = ReadAddr + 1; if ((RCR[3] == 1'b0) && (BurstLength != 0) && ((ReadAddr % BurstLength) == 0)) ReadAddr = ReadAddr - BurstLength; end end else read_out = 1'b1; if (read_out) begin DQOut_zd = DQOut_tmp; end end end end always @(CENeg, OENeg) begin : OutputDisable if ((CENeg) || (OENeg)) DQOut_zd = 16'bz; else if ((~CENeg) && (~OENeg) && (RCR[15] == 1'b0)) DQOut_zd = 16'bx; end //////////////////////////////////////////////////////////////// // WAIT output control process //////////////////////////////////////////////////////////////// always @(AssertWAITOut_event or DeassertWAITOut_event or falling_edge_OENeg or OENeg or CENeg or falling_edge_CENeg) begin : WAITOut_control if (OENeg || CENeg || ~RSTNeg || (current_state == RESET_POWER_DOWN)) WAITOut_zd = 1'bz; else if ((falling_edge_OENeg && ~CENeg) || (falling_edge_CENeg && ~OENeg)) begin if (RCR[15] == 1'b1) begin if (~RCR[10]) WAITOut_zd = 1'b1; else WAITOut_zd = 1'b0; end else begin if (~RCR[10]) WAITOut_zd = 1'b0; else WAITOut_zd = 1'b1; end end else if (AssertWAITOut_event) begin if (~RCR[10]) WAITOut_zd = 1'b0; else WAITOut_zd = 1'b1; end else if (DeassertWAITOut_event) begin if (~RCR[10]) WAITOut_zd = 1'b1; else WAITOut_zd = 1'b0; end end /////////////////////////////////////////////////////////////////// // Timing control for erase start, suspend and resume /////////////////////////////////////////////////////////////////// always @(rising_edge_MainErase_in or rising_edge_ParameterErase_in or RstDuringErsPrg_out_event or abort_event or rising_edge_ParameterEraseResume or EraseSuspend_event or rising_edge_MainEraseResume ) begin : erase_time merase_duration = tdevice_EraseMain; perase_duration = tdevice_EraseParameter; if (rising_edge_MainErase_in) begin melapsed = 0; MainErase_out <= #1 1'b1; ->merase_event; mstart = $time; end if (rising_edge_ParameterErase_in) begin pelapsed = 0; ParameterErase_out <= #1 1'b1; ->perase_event; pstart = $time; end if ((RstDuringErsPrg_out_event && ~RstDuringErsPrg_out) || abort_event) begin disable merase_process; disable perase_process; MainErase_out = 1'b0; ParameterErase_out = 1'b0; end if (EraseSuspend_event && ~EraseSuspend_out) begin disable merase_process; melapsed = $time - mstart; merase_duration = merase_duration - melapsed; disable perase_process; pelapsed = $time - pstart; perase_duration = perase_duration - pelapsed; end if (rising_edge_MainEraseResume) begin mstart = $time; MainErase_out = 1'b1; -> merase_event; end if (rising_edge_ParameterEraseResume) begin pstart = $time; ParameterErase_out = 1'b1; ->perase_event; end end always @(merase_event) begin : merase_process #merase_duration MainErase_out = 1'b0; end always @(perase_event) begin : perase_process #perase_duration ParameterErase_out = 1'b0; end ///////////////////////////////////////////////////////////////// // Timing control for programming start, suspend and resume ///////////////////////////////////////////////////////////////// time buffp_duration; time wordp_duration; time welapsed; time elapsed; event prog_event; event buffp_event; time wstart; time start; reg rising_edge_WordProgram_in = 1'b0; reg rising_edge_BuffProgram_in = 1'b0; reg rising_edge_WordProgramResume = 1'b0; reg rising_edge_BP_ProgramResume = 1'b0; always @(rising_edge_WordProgram_in or rising_edge_BuffProgram_in or RstDuringErsPrg_out_event or abort_event or ProgramSuspend_out_event or rising_edge_WordProgramResume or rising_edge_BP_ProgramResume) begin if (VPP_voltage != 9) begin buffp_duration = tdevice_BuffProgram; wordp_duration = tdevice_WordProgram; end else begin buffp_duration = tdevice_BuffProgram9V; wordp_duration = tdevice_WordProgram9V; end if (rising_edge_WordProgram_in) begin welapsed = 0; WordProgram_out <= #1 1'b1; -> prog_event; wstart = $time; end if (rising_edge_BuffProgram_in) begin elapsed = 0; BuffProgram_out = 1'b1; -> buffp_event; start = $time; end if ((RstDuringErsPrg_out_event && ~RstDuringErsPrg_out) || abort_event) begin disable prog_process; disable buffp_process; WordProgram_out = 1'b0; BuffProgram_out = 1'b0; end if (ProgramSuspend_out_event && ~ProgramSuspend_out) begin disable prog_process; disable buffp_process; elapsed = $time - start; welapsed = $time - wstart; buffp_duration = buffp_duration - elapsed; wordp_duration = wordp_duration - welapsed; end if (rising_edge_WordProgramResume) begin wstart = $time; WordProgram_out = 1'b1; -> prog_event; end if (rising_edge_BP_ProgramResume) begin start = $time; BuffProgram_out = 1'b1; -> buffp_event; end end always @(prog_event) begin : prog_process #wordp_duration WordProgram_out = 1'b0; end always @(buffp_event) begin : buffp_process #buffp_duration BuffProgram_out = 1'b0; end //////////////////////////////////////////////////////////////////// //Output timing control //////////////////////////////////////////////////////////////////// always @(DQOut_zd) begin : OutputGen if (DQOut_zd[0] !== 1'bz) begin CEDQ_t = CENeg_event + CEDQ_01; OEDQ_t = OENeg_event + OEDQ_01; ADDRDQ_t = ADDR_event + ADDRDQIN_01; if (Pmode) ADDRDQ_t = ADDR_event + ADDRDQPAGE_01; FROMCE = ((CEDQ_t >= OEDQ_t) && (CEDQ_t >= $time)); FROMOE = ((OEDQ_t >= CEDQ_t) && (OEDQ_t >= $time)); FROMADDR = 1'b1; DQOut_Pass = DQOut_zd; end end always @(DQOut_zd) begin if (DQOut_zd[0] === 1'bz) begin disable OutputGen; FROMCE = 1'b1; FROMOE = 1'b1; FROMADDR = 1'b0; DQOut_Pass = DQOut_zd; end end reg BuffInOE, BuffInCE, BuffInADDRIN, BuffInADDRPAGE; wire BuffOutOE, BuffOutCE, BuffOutADDRIN, BuffOutADDRPAGE; BUFFER BUFOE (BuffOutOE, BuffInOE); BUFFER BUFCE (BuffOutCE, BuffInCE); BUFFER BUFADDRIN (BuffOutADDRIN, BuffInADDRIN); BUFFER BUFADDRPAGE (BuffOutADDRPAGE, BuffInADDRPAGE); initial begin BuffInOE = 1'b1; BuffInCE = 1'b1; BuffInADDRIN = 1'b1; BuffInADDRPAGE = 1'b1; end always @(posedge BuffOutOE) begin OEDQ_01 = $time; end always @(posedge BuffOutCE) begin CEDQ_01 = $time; end always @(posedge BuffOutADDRIN) begin ADDRDQIN_01 = $time; end always @(posedge BuffOutADDRPAGE) begin ADDRDQPAGE_01 = $time; end ///////////////////////////////////////////////////////////////////////////// // functions & tasks ///////////////////////////////////////////////////////////////////////////// function integer BlockNumber; input [HiAddrBit:0] ADDR; integer block_number; begin block_number = ADDR / MainBlockSize; if (block_number == 0) block_number = block_number + (ADDR % MainBlockSize) / ParameterBlockSize; else block_number = block_number + MainBlockSize / ParameterBlockSize - 1; BlockNumber = block_number; end endfunction function integer StartBlockAddr; input [16:0] block_number; integer start_block_addr; begin if (block_number < 4) start_block_addr = block_number * ParameterBlockSize; else start_block_addr = (block_number - 3) * MainBlockSize; StartBlockAddr = start_block_addr; end endfunction function integer BlockSize; input [16:0] block_number; integer block_number; integer block_size; begin if ((block_number < 4) || (block_number > (BlockNum - 4) )) block_size = ParameterBlockSize; else block_size = MainBlockSize; BlockSize = block_size; end endfunction //////////////////////////////////////////////////////////////// // edge controll processes //////////////////////////////////////////////////////////////// always @(negedge ADVNeg) begin falling_edge_ADVNeg = 1; #1 falling_edge_ADVNeg = 0; end always @(posedge ADVNeg) begin rising_edge_ADVNeg = 1; #1 rising_edge_ADVNeg = 0; end always @(posedge CLOCK) begin rising_edge_CLOCK = 1; #1 rising_edge_CLOCK = 0; end always @(negedge RSTNeg) begin falling_edge_RSTNeg = 1; #1 falling_edge_RSTNeg = 0; end always @(posedge RSTNeg) begin rising_edge_RSTNeg = 1; #1 rising_edge_RSTNeg = 0; end always @(posedge Write) begin rising_edge_Write = 1; #1 rising_edge_Write = 0; end always @(RstDuringErsPrg_out) begin RstDuringErsPrg_out_event = 1; #1 RstDuringErsPrg_out_event = 0; end always @(WordProgram_out) begin WordProgram_out_event = 1; #1 WordProgram_out_event = 0; end always @(ProgramSuspend_out) begin ProgramSuspend_out_event = 1; #1 ProgramSuspend_out_event = 0; end always @(BuffProgram_out) begin if (~suspended_bp) begin BuffProgram_out_event = 1; #1 BuffProgram_out_event = 0; end end always @(posedge ExtendProgTime) begin ExtendProgTime_event = 1; #1 ExtendProgTime_event = 0; end always @(ParameterErase_out) begin ParameterErase_out_event = 1; #1 ParameterErase_out_event = 0; end always @(negedge MainErase_out) begin falling_edge_MainErase_out = 1; #1 falling_edge_MainErase_out = 0; end always @(negedge EraseSuspend_out) begin falling_edge_EraseSuspend_out = 1; #1 falling_edge_EraseSuspend_out = 0; end always @(negedge BEFPsetup_out) begin falling_edge_BEFPsetup_out = 1; #1 falling_edge_BEFPsetup_out = 0; end always @(negedge BEFP_out) begin falling_edge_BEFP_out = 1; #1 falling_edge_BEFP_out = 0; end always @(A[HiAddrBit:2]) begin Ahigh_event = 1; #1 Ahigh_event = 0; end always @(A[1:0]) begin Alow_event = 1; #1 Alow_event = 0; end always @(A) begin A_event = 1; #1 A_event = 0; end always @(posedge Read) begin rising_edge_Read = 1; #1 rising_edge_Read = 0; end always @(negedge Read) begin falling_edge_Read = 1; #1 falling_edge_Read = 0; end always @(posedge CENeg) begin rising_edge_CENeg = 1; #1 rising_edge_CENeg = 0; end always @(posedge OENeg) begin rising_edge_OENeg = 1; #1 rising_edge_OENeg = 0; end always @(AssertWAITOut) begin AssertWAITOut_event = 1; #1 AssertWAITOut_event = 0; end always @(DeassertWAITOut) begin DeassertWAITOut_event = 1; #1 DeassertWAITOut_event = 0; end always @(negedge OENeg) begin falling_edge_OENeg = 1; #1 falling_edge_OENeg = 0; end always @(negedge CENeg) begin falling_edge_CENeg = 1; #1 falling_edge_CENeg = 0; end always @(posedge WENeg) begin rising_edge_WENeg = 1; #1 rising_edge_WENeg = 0; end always @(posedge WordProgram_in) begin rising_edge_WordProgram_in = 1'b1; #1 rising_edge_WordProgram_in = 1'b0; end always @(posedge BuffProgram_in) begin rising_edge_BuffProgram_in = 1'b1; #1 rising_edge_BuffProgram_in = 1'b0; end always @(posedge BP_ProgramResume) begin rising_edge_BP_ProgramResume = 1'b1; #1 rising_edge_BP_ProgramResume = 1'b0; end always @(posedge WordProgramResume) begin rising_edge_WordProgramResume = 1'b1; #1 rising_edge_WordProgramResume = 1'b0; end always @(posedge MainErase_in) begin rising_edge_MainErase_in = 1'b1; #1 rising_edge_MainErase_in = 1'b0; end always @(posedge ParameterErase_in) begin rising_edge_ParameterErase_in = 1'b1; #1 rising_edge_ParameterErase_in = 1'b0; end always @(posedge MainEraseResume) begin rising_edge_MainEraseResume = 1'b1; #1 rising_edge_MainEraseResume = 1'b0; end always @(posedge ParameterEraseResume) begin rising_edge_ParameterEraseResume = 1'b1; #1 rising_edge_ParameterEraseResume = 1'b0; end always @(EraseSuspend_out) begin EraseSuspend_event = 1'b1; #1 EraseSuspend_event = 1'b0; end endmodule module BUFFER (OUT,IN); input IN; output OUT; buf (OUT, IN); endmodule ================================================ FILE: tests/bpiflash/testbpiflash.cpp ================================================ #include #include #include "bpiflash.h" class BpiFlashTestIndication : public BpiFlashTestIndicationWrapper { sem_t sem; public: unsigned short buf[16]; virtual void resetDone() { fprintf(stderr, "reset done\n"); sem_post(&sem); } virtual void readDone(uint16_t v) { //fprintf(stderr, "read %x\n", v); buf[0] = v; sem_post(&sem); } virtual void writeDone() { //fprintf(stderr, "write done\n"); sem_post(&sem); } void wait() { sem_wait(&sem); } BpiFlashTestIndication(unsigned int id) : BpiFlashTestIndicationWrapper(id) { sem_init(&sem, 0, 0); } }; BpiFlashTestRequestProxy *request; BpiFlashTestIndication *indication; #ifdef STANDALONE int main(int argc, const char **argv) { request = new BpiFlashTestRequestProxy(IfcNames_BpiFlashTestRequestS2H); indication = new BpiFlashTestIndication(IfcNames_BpiFlashTestIndicationH2S); request->reset(); indication->wait(); for (int i = 0; i < 20; i++) { request->read(i<<1); indication->wait(); } return 0; } #else BpiFlash::BpiFlash() : request(0), indication(0), didReset(false) { request = new BpiFlashTestRequestProxy(IfcNames_BpiFlashTestRequestS2H); indication = new BpiFlashTestIndication(IfcNames_BpiFlashTestIndicationH2S); } BpiFlash::~BpiFlash() { //delete request; //delete indication; request = 0; indication = 0; } void BpiFlash::maybeReset() { if (!didReset) { fprintf(stderr, "resetting flash\n"); request->reset(); indication->wait(); request->setParameters(50, 0); fprintf(stderr, "done resetting flash\n"); didReset = true; } } int verbose = 0; void BpiFlash::read(unsigned long offset, uint8_t *buf) { maybeReset(); //fprintf(stderr, "BpiFlash::read offset=%lx\n", offset); request->read(offset); indication->wait(); if (verbose) fprintf(stderr, "BpiFlash::read offset=%lx value=%x\n", offset, *(short *)indication->buf); memcpy(buf, indication->buf, 2); } void BpiFlash::write(unsigned long offset, const uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "BpiFlash::write offset=%lx value=%x\n", offset, *(short *)buf); request->write(offset, *(uint16_t *)buf); indication->wait(); } #endif ================================================ FILE: tests/ddr3/Ddr3Test.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import Vector::*; import BuildVector::*; import GetPut::*; import Connectable::*; import ClientServer::*; import ConnectalMemory::*; import ConnectalBramFifo::*; import FIFOF::*; import Gearbox::*; import GearboxGetPut::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; import AxiDdr3Controller::*; import GetPutWithClocks::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import AxiDdr3Wrapper ::*; import AxiDma::*; import ConnectalConfig::*; import HostInterface::*; import Probe::*; interface Ddr3TestRequest; method Action startWriteDram(Bit#(32) sglId, Bit#(32) transferBytes); method Action startReadDram(Bit#(32) sglId, Bit#(32) transferBytes); endinterface interface Ddr3TestIndication; method Action writeDone(Bit#(32) v); method Action readDone(Bit#(32) v); endinterface interface Ddr3Test; interface Ddr3TestRequest request; interface Vector#(1, MemReadClient#(DataBusWidth)) readClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) writeClient; interface Ddr3Pins ddr3; endinterface typedef TDiv#(Ddr3DataWidth,DataBusWidth) BusRatio; typedef TDiv#(Ddr3DataWidth,8) Ddr3DataBytes; module mkDdr3Test#(HostInterface host, Ddr3TestIndication indication)(Ddr3Test); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Reg#(Bit#(Ddr3AddrWidth)) transferLen <- mkReg(256); Clock clk200 = host.tsys_clk_200mhz_buf; let ddr3Controller <- mkDdr3(clk200); MemReadEngine#(DataBusWidth,DataBusWidth,1,1) re <- mkMemReadEngine(); MemWriteEngine#(DataBusWidth,DataBusWidth,1,1) we <- mkMemWriteEngine(); FIFOF#(Bit#(32)) writeReqFifo <- mkFIFOF(); FIFOF#(Bit#(32)) readReqFifo <- mkFIFOF(); Probe#(Bit#(Ddr3AddrWidth)) aw_req_probe <- mkProbe(); Reg#(Bit#(Ddr3AddrWidth)) dramWriteLimitProbe <- mkReg(0); Reg#(Bit#(Ddr3AddrWidth)) dramReadLimitProbe <- mkReg(0); Probe#(Bit#(Ddr3AddrWidth)) awAddrProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Bit#(8)) awLenProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Bit#(3)) awSizeProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Vector#(BusRatio,Bit#(DataBusWidth))) wdataProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Axi4WriteResponse#(6)) bProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Bit#(Ddr3AddrWidth)) arAddrProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Bit#(8)) arLenProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Bit#(3)) arSizeProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); Probe#(Vector#(BusRatio,Bit#(DataBusWidth))) rdataProbe <- mkProbe(clocked_by ddr3Controller.uiClock, reset_by ddr3Controller.uiReset); let sglWriteProbe <- mkProbe(); let sglReadProbe <- mkProbe(); Gearbox#(1,BusRatio,Bit#(DataBusWidth)) dramWriteGearbox <- mk1toNGearbox(clock, reset, clock, reset); FIFOF#(Vector#(BusRatio,Bit#(DataBusWidth))) dramWriteFifo <- mkDualClockBramFIFOF(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); FIFOF#(Axi4WriteRequest#(Ddr3AddrWidth,6)) awfifo <- mkDualClockBramFIFOF(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); FIFOF#(Axi4WriteResponse#(6)) bfifo <- mkDualClockBramFIFOF(ddr3Controller.uiClock, ddr3Controller.uiReset, clock, reset); //mkConnection(toGet(awfifo), ddr3Controller.slave.req_aw); //mkConnection(ddr3Controller.slave.resp_b, toPut(bfifo)); rule rl_awfifo; let req <- toGet(awfifo).get(); awAddrProbe <= req.address; awLenProbe <= req.len; awSizeProbe <= req.size; ddr3Controller.slave.req_aw.put(req); endrule rule rl_bfifo; let b <- ddr3Controller.slave.resp_b.get(); bProbe <= b; bfifo.enq(b); endrule Reg#(Bit#(Ddr3AddrWidth)) dramWriteOffset <- mkReg(0); Reg#(Bit#(Ddr3AddrWidth)) dramWriteLimit <- mkReg(0); rule rl_req_aw if (dramWriteOffset < dramWriteLimit); Axi4WriteRequest#(Ddr3AddrWidth,6) req = Axi4WriteRequest { address: truncate(dramWriteOffset), len: 0, // indicates 1 beat of data size: axiBusSize(valueOf(Ddr3DataWidth)), id: 0, burst: 2'b01, prot: 3'b000, //ignored cache: 4'b0011, //ignored lock: 2'b00, //ignored qos: 4'b0000 //ignored }; awfifo.enq(req); aw_req_probe <= req.address; dramWriteOffset <= dramWriteOffset + fromInteger(valueOf(Ddr3DataBytes)); endrule rule rl_wdata_gb; let rdata <- toGet(re.readServers[0].data).get(); dramWriteGearbox.enq(vec(rdata.data)); endrule rule rl_wdata; let mds <- toGet(dramWriteGearbox).get(); dramWriteFifo.enq(mds); endrule rule rl_writeDataFifo; let mds <- toGet(dramWriteFifo).get(); wdataProbe <= mds; ddr3Controller.slave.resp_write.put(Axi4WriteData { data: pack(mds), byteEnable: maxBound, last: 1, id: 0 }); endrule rule rl_b; // consume the writeDone let b <- toGet(bfifo).get(); // let's see an indication, but we should be counting how many words were sent indication.writeDone(extend(b.id)); endrule rule rl_write_start; let sglId <- toGet(writeReqFifo).get(); dramWriteOffset <= 0; dramWriteLimit <= transferLen; dramWriteLimitProbe <= transferLen; re.readServers[0].request.put(MemengineCmd { sglId: sglId, base: 0, burstLen: 128, len: extend(transferLen), tag: 0 }); endrule Gearbox#(BusRatio,1,Bit#(DataBusWidth)) dramReadGearbox <- mkNto1Gearbox(ddr3Controller.uiClock, ddr3Controller.uiReset, ddr3Controller.uiClock, ddr3Controller.uiReset); FIFOF#(Bit#(DataBusWidth)) dramReadFifo <- mkDualClockBramFIFOF(ddr3Controller.uiClock, ddr3Controller.uiReset, clock, reset); FIFOF#(Axi4ReadRequest#(Ddr3AddrWidth,6)) arfifo <- mkDualClockBramFIFOF(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); //mkConnection(toGet(arfifo), ddr3Controller.slave.req_ar); rule rl_arfifo; let req <- toGet(arfifo).get(); arAddrProbe <= req.address; arLenProbe <= req.len; arSizeProbe <= req.size; ddr3Controller.slave.req_ar.put(req); endrule Reg#(Bit#(Ddr3AddrWidth)) dramReadOffset <- mkReg(0); Reg#(Bit#(Ddr3AddrWidth)) dramReadLimit <- mkReg(0); rule rl_req_ar if (dramReadOffset < dramReadLimit); Axi4ReadRequest#(Ddr3AddrWidth,6) req = Axi4ReadRequest { address: truncate(dramReadOffset), len: 0, // indicates one beat of data size: axiBusSize(valueOf(Ddr3DataWidth)), id: 0, burst: 2'b01, prot: 3'b000, //ignored cache: 4'b0011, //ignored lock: 2'b00, //ignored qos: 4'b0000 //ignored }; arfifo.enq(req); dramReadOffset <= dramReadOffset + fromInteger(valueOf(Ddr3DataBytes)); endrule rule rl_rdata; let resp <- ddr3Controller.slave.resp_read.get(); Vector#(BusRatio, Bit#(DataBusWidth)) data = unpack(resp.data); rdataProbe <= data; dramReadGearbox.enq(data); endrule rule rl_rdata_gb; Bit#(DataBusWidth) rdata <- toGet(dramReadGearbox).get(); dramReadFifo.enq(rdata); endrule rule rl_rdata_slack; let rdata <- toGet(dramReadFifo).get(); //fixme last field we.writeServers[0].data.enq(rdata); endrule rule rl_read_start; let sglId <- toGet(readReqFifo).get(); dramReadOffset <= 0; dramReadLimit <= transferLen; dramReadLimitProbe <= transferLen; we.writeServers[0].request.put(MemengineCmd { sglId: sglId, base: 0, burstLen: 128, len: extend(transferLen), tag: 0 }); endrule rule rl_read_done; let done <- we.writeServers[0].done.get(); indication.readDone(0); endrule interface Ddr3TestRequest request; method Action startWriteDram(Bit#(32) sglId, Bit#(32) transferBytes); sglWriteProbe <= sglId; transferLen <= truncate(transferBytes); writeReqFifo.enq(sglId); endmethod method Action startReadDram(Bit#(32) sglId, Bit#(32) transferBytes); sglReadProbe <= sglId; transferLen <= truncate(transferBytes); readReqFifo.enq(sglId); endmethod endinterface interface MemReadClient readClient = vec(re.dmaClient); interface MemWriteClient writeClient = vec(we.dmaClient); interface AxiDdr3 ddr3 = ddr3Controller.ddr3; endmodule ================================================ FILE: tests/ddr3/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = Ddr3TestRequest:Ddr3Test.request H2S_INTERFACES = Ddr3Test:Ddr3TestIndication:host MEM_READ_INTERFACES = lDdr3Test.readClient MEM_WRITE_INTERFACES = lDdr3Test.writeClient ifneq ($(BOARD),zc706) ifneq ($(BOARD),miniitx100) CONNECTALFLAGS += -D DataBusWidth=128 endif endif CONNECTALFLAGS += -D IMPORT_HOSTIF -D XILINX_SYS_CLK CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/axiddr3/axiddr3.xci BSVFILES = Ddr3Test.bsv CPPFILES=testddr3.cpp PIN_TYPE = Ddr3Pins PIN_TYPE_INCLUDE = AxiDdr3Controller AUTOTOP = --interface pins:Ddr3Test.ddr3 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/ddr3/synth-ip.tcl ================================================ source board.tcl source $connectaldir/scripts/connectal-synth-axiddr3.tcl ================================================ FILE: tests/ddr3/testddr3.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "Ddr3TestIndication.h" #include "Ddr3TestRequest.h" sem_t write_sem; sem_t read_sem; unsigned int alloc_sz = 1<<10; class Ddr3TestIndication : public Ddr3TestIndicationWrapper { public: Ddr3TestIndication(unsigned int id) : Ddr3TestIndicationWrapper(id){} virtual void writeDone(uint32_t v) { fprintf(stderr, "writeDone %d\n", v); sem_post(&write_sem); } virtual void readDone(uint32_t v) { fprintf(stderr, "readDone %d\n", v); sem_post(&read_sem); } }; int main(int argc, const char **argv) { DmaManager *dma = platformInit(); Ddr3TestRequestProxy *testRequest = new Ddr3TestRequestProxy(IfcNames_Ddr3TestRequestS2H); Ddr3TestIndication testIndication(IfcNames_Ddr3TestIndicationH2S); if(sem_init(&write_sem, 1, 0)){ fprintf(stderr, "failed to init write_sem\n"); return -1; } if(sem_init(&read_sem, 1, 0)){ fprintf(stderr, "failed to init read_sem\n"); return -1; } int srcAlloc = portalAlloc(alloc_sz, 0); int dstAlloc = portalAlloc(alloc_sz, 0); int *srcBuffer = (int *)portalMmap(srcAlloc, alloc_sz); int *dstBuffer = (int *)portalMmap(dstAlloc, alloc_sz); for (int i = 0; i < 1024/4; i++) { srcBuffer[i] = i; fprintf(stderr, "src dram[%04x]=%08x\n", i*4, srcBuffer[i]); } int ref_srcAlloc = dma->reference(srcAlloc); int ref_dstAlloc = dma->reference(dstAlloc); if (1) { int transferLen = 1024; testRequest->startWriteDram(ref_srcAlloc, transferLen); fprintf(stderr, "Started writing dram\n"); for (int i = 0; i < transferLen; i += DataBusWidth) sem_wait(&write_sem); testRequest->startReadDram(ref_dstAlloc, transferLen); sem_wait(&read_sem); } for (int i = 0; i < 1024/4; i++) { fprintf(stderr, "dst dram[%04x]=%08x\n", i*4, dstBuffer[i]); } int mismatches = 0; for (int i = 0; i < 1024/4; i++) { if (i != dstBuffer[i]) { mismatches++; fprintf(stderr, "mismatch dram[%04x]=%08x expected %08x\n", i*4, dstBuffer[i], i); } } fprintf(stderr, "%d mismatches\n", mismatches); return mismatches ? 1 : 0; } ================================================ FILE: tests/ddr3_altera/Ddr3Test.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Clocks::*; import Vector::*; import BuildVector::*; import GetPut::*; import Connectable::*; import ClientServer::*; import ConnectalMemory::*; import FIFOF::*; import Gearbox::*; import GearboxGetPut::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; import AvalonDdr3Controller::*; import GetPutWithClocks::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import ALTERA_DDR3_WRAPPER::*; import AxiDma::*; import ConnectalConfig::*; import ConnectalClocks::*; import HostInterface::*; interface Ddr3TestRequest; method Action startWriteDram(Bit#(32) sglId); method Action startReadDram(Bit#(32) sglId); endinterface interface Ddr3TestIndication; method Action writeDone(Bit#(32) v); method Action readDone(Bit#(32) v); endinterface interface Ddr3Test; interface Ddr3TestRequest request; interface Vector#(1, MemReadClient#(DataBusWidth)) readClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) writeClient; interface Ddr3Pins pins; endinterface typedef TDiv#(Ddr3DataWidth,DataBusWidth) BusRatio; module mkDdr3Test#(HostInterface host, Ddr3TestIndication indication)(Ddr3Test); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); B2C1 iclock_50 <- mkB2C1(); let ddr3Controller <- mkDdr3(iclock_50.c); // MemReadEngine#(DataBusWidth,DataBusWidth,1,1) re <- mkMemReadEngine(); // MemWriteEngine#(DataBusWidth,DataBusWidth,1,1) ddr3we <- mkMemWriteEngine(); // MemWriteEngine#(DataBusWidth,DataBusWidth,1,1) we <- mkMemWriteEngine(); // MemReadEngine#(DataBusWidth,DataBusWidth,1,1) ddr3re <- mkMemReadEngine(); // // FIFOF#(Bit#(32)) writeReqFifo <- mkFIFOF(); // FIFOF#(Bit#(32)) readReqFifo <- mkFIFOF(); // // Gearbox#(1,BusRatio,MemData#(DataBusWidth)) dramWriteGearbox <- mk1toNGearbox(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); // SyncFIFOIfc#(Axi4WriteRequest#(Ddr3AddrWidth,6)) awfifo <- mkSyncFIFO(4, clock, reset, ddr3Controller.uiClock); // SyncFIFOIfc#(Axi4WriteResponse#(6)) bfifo <- mkSyncFIFO(4, ddr3Controller.uiClock, ddr3Controller.uiReset, clock); // mkConnection(toGet(awfifo), ddr3Controller.slave.req_aw); // mkConnection(ddr3Controller.slave.resp_b, toPut(bfifo)); // // rule rl_req_aw; // let req <- ddr3we.dmaClient.writeReq.get(); // awfifo.enq(Axi4WriteRequest { // address: truncate(req.offset), // len: 1, // size: axiBusSize(valueOf(Ddr3DataWidth)), // id: req.tag, // burst: 2'b01, // prot: 3'b000, //ignored // cache: 4'b0011, //ignored // lock: 2'b00, //ignored // qos: 4'b0000 //ignored // }); // endrule // // mkConnection(ddr3we.dmaClient.writeData, toPut(dramWriteGearbox)); // rule rl_wdata; // let mds <- toGet(dramWriteGearbox).get(); // function Bit#(DataBusWidth) md_data(Integer i); return mds[i].data; endfunction // Vector#(BusRatio, Bit#(DataBusWidth)) data = genWith(md_data); // ddr3Controller.slave.resp_write.put(Axi4WriteData { // data: pack(data), // byteEnable: maxBound, // last: 1, // id: mds[0].tag // }); // endrule // // rule rl_b; // let b <- toGet(bfifo).get(); // ddr3we.dmaClient.writeDone.put(b.id); // endrule // // rule rl_write_start; // let sglId <- toGet(writeReqFifo).get(); // re.readServers[0].request.put(MemengineCmd { sglId: sglId, // base: 0, // burstLen: fromInteger(valueOf(TDiv#(Ddr3DataWidth,8))), // len: 1024, // tag: 0 // }); // ddr3we.writeServers[0].request.put(MemengineCmd { sglId: 0, // base: 0, // burstLen: fromInteger(valueOf(TDiv#(Ddr3DataWidth,8))), // len: 1024, // tag: 0 // }); // endrule // // Gearbox#(BusRatio,1,MemData#(DataBusWidth)) dramReadGearbox <- mkNto1Gearbox(ddr3Controller.uiClock, ddr3Controller.uiReset, clock, reset); // SyncFIFOIfc#(Axi4ReadRequest#(Ddr3AddrWidth,6)) arfifo <- mkSyncFIFO(4, clock, reset, ddr3Controller.uiClock); // mkConnection(toGet(arfifo), ddr3Controller.slave.req_ar); // // rule rl_req_ar; // let req <- ddr3re.dmaClient.readReq.get(); // arfifo.enq(Axi4ReadRequest { // address: truncate(req.offset), // len: 1, // size: axiBusSize(valueOf(Ddr3DataWidth)), // id: req.tag, // burst: 2'b01, // prot: 3'b000, //ignored // cache: 4'b0011, //ignored // lock: 2'b00, //ignored // qos: 4'b0000 //ignored // }); // endrule // // rule rl_rdata; // let resp <- ddr3Controller.slave.resp_read.get(); // Vector#(BusRatio, Bit#(DataBusWidth)) datavec = unpack(resp.data); // // function MemData#(DataBusWidth) to_md_data(Integer i); // return MemData { data: datavec[i], last: True, tag: resp.id }; // endfunction // Vector#(BusRatio, MemData#(DataBusWidth)) data = genWith(to_md_data); // dramReadGearbox.enq(data); // endrule // mkConnection(toGet(dramReadGearbox), ddr3re.dmaClient.readData); // // rule rl_read_start; // let sglId <- toGet(readReqFifo).get(); // we.writeServers[0].request.put(MemengineCmd { sglId: sglId, // base: 0, // burstLen: fromInteger(valueOf(TDiv#(Ddr3DataWidth,8))), // len: 1024, // tag: 0 // }); // ddr3re.readServers[0].request.put(MemengineCmd { sglId: 0, // base: 0, // burstLen: fromInteger(valueOf(TDiv#(Ddr3DataWidth,8))), // len: 1024, // tag: 0 // }); // endrule // interface Ddr3TestRequest request; // method Action startWriteDram(Bit#(32) sglId); // writeReqFifo.enq(sglId); // endmethod // method Action startReadDram(Bit#(32) sglId); // readReqFifo.enq(sglId); // endmethod // endinterface // interface MemReadClient readClient = vec(re.dmaClient); // interface MemWriteClient writeClient = vec(we.dmaClient); interface `PinType pins; method Action osc_50(Bit#(1) b3d, Bit#(1) b4a, Bit#(1) b4d, Bit#(1) b7a, Bit#(1) b7d, Bit#(1) b8a, Bit#(1) b8d); iclock_50.inputclock(b7a); endmethod interface ddr3 = (interface Ddr3; interface rzq_4 = ddr3Controller.rzq_4; interface ddr3b = ddr3Controller.ddr3b; interface sysclk_deleteme_unused_clock = ddr3Controller.sysclk_deleteme_unused_clock; interface sysrst_deleteme_unused_reset = ddr3Controller.sysrst_deleteme_unused_reset; endinterface); endinterface endmodule ================================================ FILE: tests/ddr3_altera/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = Ddr3TestRequest:Ddr3Test.request H2S_INTERFACES = Ddr3Test:Ddr3TestIndication:host MEM_READ_INTERFACES = lDdr3Test.readClient ifneq ($(BOARD),zc706) CONNECTALFLAGS += -D DataBusWidth=128 endif CONNECTALFLAGS += -D IMPORT_HOSTIF -D XILINX_SYS_CLK CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/synthesis/altera_mem_if_ddr3_emif_wrapper/altera_mem_if_ddr3_emif_wrapper.qip BSVFILES = Ddr3Test.bsv CPPFILES=testddr3.cpp PIN_BINDINGS ?= DDR3B:DDR3B PCIE:PCIE OSC:OSC RZQ:RZQ PINOUT_FILE = de5.json PIN_TYPE = Ddr3Pins PIN_TYPE_INCLUDE = AvalonDdr3Controller AUTOTOP = --interface pins:Ddr3Test.pins prebuild:: (cd $(BOARD); BUILDCACHE_CACHEDIR=$(BUILDCACHE_CACHEDIR) $(BUILDCACHE) $(QUARTUS_SH) -t $(CONNECTALDIR)/scripts/connectal-synth-avalonddr3.tcl) include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/ddr3_altera/de5.json ================================================ { "PCIE_tx_p[0]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[0]" }, "PCIE_tx_p[1]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[1]" }, "PCIE_tx_p[2]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[2]" }, "PCIE_tx_p[3]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[3]" }, "PCIE_tx_p[4]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[4]" }, "PCIE_tx_p[5]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[5]" }, "PCIE_tx_p[6]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[6]" }, "PCIE_tx_p[7]": { "PIO_DIRECTION": "OUTPUT", "PCIE": "PCIE_TX_p[7]" }, "PCIE_rx_p[0]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[0]" }, "PCIE_rx_p[1]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[1]" }, "PCIE_rx_p[2]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[2]" }, "PCIE_rx_p[3]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[3]" }, "PCIE_rx_p[4]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[4]" }, "PCIE_rx_p[5]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[5]" }, "PCIE_rx_p[6]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[6]" }, "PCIE_rx_p[7]": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_RX_p[7]" }, "pcie_refclk_p": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_REFCLK_p" }, "pcie_perst_n": { "PIO_DIRECTION": "INPUT", "PCIE": "PCIE_PERST_n" }, "osc_50_b3b": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B3B" }, "osc_50_b3d": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B3D" }, "osc_50_b4a": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B4A" }, "osc_50_b4d": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B4D" }, "osc_50_b7a": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B7A" }, "osc_50_b7d": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B7D" }, "osc_50_b8a": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B8A" }, "osc_50_b8d": { "PIO_DIRECTION": "INPUT", "OSC": "OSC_50_B8D" }, "rzq_4": { "PIO_DIRECTION": "INPUT", "RZQ": "RZQ_4" }, "ddr3b_a[0]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[0]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[1]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[1]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[2]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[2]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[3]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[3]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[4]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[4]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[5]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[5]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[6]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[6]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[7]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[7]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[8]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[8]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[9]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[9]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[10]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[10]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[11]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[11]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[12]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[12]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[13]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[13]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[14]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[14]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_a[15]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_A[15]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_ba[0]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_BA[0]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_ba[1]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_BA[1]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_ba[2]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_BA[2]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_cas_n": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_CAS_n", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_cke": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_CKE[0]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_ck": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_CK[0]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_ck_n": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_CK_n[0]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_cs_n": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_CS_n[0]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_we_n": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_WE_n", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_scl": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_SCL" }, "ddr3b_sda": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_SDA" }, "ddr3b_ras_n": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_RAS_n", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_reset_n": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_RESET_n", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_odt": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_ODT[0]", "CURRENT_STRENGTH_NEW": "MAXIMUM CURRENT", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_event_n": { "PIO_DIRECTION": "INPUT", "DDR3B": "DDR3B_EVENT_n" }, "ddr3b_dm[0]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[0]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[1]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[1]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[2]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[2]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[3]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[3]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[4]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[4]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[5]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[5]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[6]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[6]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dm[7]": { "PIO_DIRECTION": "OUTPUT", "DDR3B": "DDR3B_DM[7]", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[0]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[0]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[1]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[1]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[2]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[2]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[3]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[3]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[4]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[4]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[5]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[5]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[6]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[6]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs[7]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS[7]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[0]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[0]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[1]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[1]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[2]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[2]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[3]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[3]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[4]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[4]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[5]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[5]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[6]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[6]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dqs_n[7]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQS_n[7]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[0]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[0]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[1]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[1]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[2]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[2]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[3]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[3]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[4]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[4]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[5]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[5]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[6]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[6]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[7]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[7]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[8]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[8]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[9]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[9]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[10]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[10]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[11]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[11]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[12]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[12]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[13]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[13]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[14]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[14]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[15]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[15]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[16]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[16]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[17]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[17]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[18]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[18]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[19]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[19]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[20]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[20]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[21]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[21]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[22]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[22]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[23]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[23]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[24]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[24]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[25]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[25]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[26]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[26]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[27]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[27]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[28]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[28]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[29]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[29]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[30]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[30]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[31]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[31]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[32]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[32]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[33]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[33]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[34]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[34]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[35]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[35]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[36]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[36]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[37]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[37]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[38]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[38]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[39]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[39]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[40]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[40]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[41]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[41]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[42]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[42]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[43]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[43]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[44]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[44]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[45]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[45]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[46]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[46]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[47]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[47]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[48]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[48]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[49]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[49]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[50]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[50]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[51]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[51]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[52]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[52]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[53]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[53]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[54]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[54]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[55]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[55]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[56]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[56]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[57]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[57]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[58]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[58]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[59]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[59]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[60]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[60]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[61]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[61]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[62]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[62]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" }, "ddr3b_dq[63]": { "PIO_DIRECTION": "BIDIR", "DDR3B": "DDR3B_DQ[63]", "INPUT_TERMINATION": "PARALLEL 50 OHM WITH CALIBRATION", "OUTPUT_TERMINATION": "SERIES 50 OHM WITH CALIBRATION", "PACKAGE_SKEW_COMPENSATION": "ON" } } ================================================ FILE: tests/ddr3_altera/synth-ip.tcl ================================================ source $connectaldir/scripts/connectal-synth-avalonddr3.tcl ================================================ FILE: tests/ddr3_altera/testddr3.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "Ddr3TestIndication.h" #include "Ddr3TestRequest.h" sem_t test_sem; unsigned int alloc_sz = 1<<10; class Ddr3TestIndication : public Ddr3TestIndicationWrapper { public: Ddr3TestIndication(unsigned int id) : Ddr3TestIndicationWrapper(id){} virtual void writeDone(uint32_t v) { fprintf(stderr, "writeDone %d\n", v); sem_post(&test_sem); } virtual void readDone(uint32_t v) { fprintf(stderr, "readDone %d\n", v); sem_post(&test_sem); } }; int main(int argc, const char **argv) { DmaManager *dma = platformInit(); Ddr3TestRequestProxy *testRequest = new Ddr3TestRequestProxy(IfcNames_Ddr3TestRequestS2H); Ddr3TestIndication testIndication(IfcNames_Ddr3TestIndicationH2S); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } int srcAlloc = portalAlloc(alloc_sz, 0); //unsigned int *srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); int ref_srcAlloc = dma->reference(srcAlloc); testRequest->startWriteDram(ref_srcAlloc); sem_wait(&test_sem); testRequest->startWriteDram(ref_srcAlloc); sem_wait(&test_sem); return 0; } ================================================ FILE: tests/ddr_minimal/Ddr3Test.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import Vector::*; import BuildVector::*; import GetPut::*; import Connectable::*; import ClientServer::*; import ConnectalMemory::*; import ConnectalBramFifo::*; import FIFOF::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; import AxiDdr3Controller::*; import GetPutWithClocks::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import AxiDdr3Wrapper ::*; import AxiDma::*; import ConnectalConfig::*; import HostInterface::*; interface Ddr3TestRequest; method Action startWriteDram(Bit#(32) sglId, Bit#(32) transferBytes); method Action startReadDram(Bit#(32) sglId, Bit#(32) transferBytes); endinterface interface Ddr3TestIndication; method Action writeDone(Bit#(32) v); method Action readDone(Bit#(32) v); endinterface interface Ddr3Test; interface Ddr3TestRequest request; interface Ddr3Pins ddr3; endinterface typedef TDiv#(Ddr3DataWidth,8) Ddr3DataBytes; // This minimal example only have one request or response flying at a time. Ensured by software. module mkDdr3Test#(HostInterface host, Ddr3TestIndication indication)(Ddr3Test); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); Reg#(Bit#(Ddr3AddrWidth)) transferLen <- mkReg(256); Clock clk200 = host.tsys_clk_200mhz_buf; let ddr3Controller <- mkDdr3(clk200); let idC <- mkReg(0); FIFOF#(Bit#(32)) writeReqFifo <- mkFIFOF(); FIFOF#(Bit#(32)) readReqFifo <- mkFIFOF(); // Logic to handle writes Reg#(Bit#(Ddr3AddrWidth)) dramWriteOffset <- mkReg(0); Reg#(Bit#(Ddr3AddrWidth)) dramWriteLimit <- mkReg(0); FIFOF#(Bit#(Ddr3DataWidth)) dramWriteFifo <- mkDualClockBramFIFOF(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); FIFOF#(Axi4WriteRequest#(Ddr3AddrWidth,6)) awfifo <- mkDualClockBramFIFOF(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); FIFOF#(Axi4WriteResponse#(6)) bfifo <- mkDualClockBramFIFOF(ddr3Controller.uiClock, ddr3Controller.uiReset, clock, reset); rule rl_write_start; let dummy <- toGet(writeReqFifo).get(); dramWriteOffset <= 0; dramWriteLimit <= transferLen; endrule rule rl_req_aw if (dramWriteOffset < dramWriteLimit); Axi4WriteRequest#(Ddr3AddrWidth,6) req = Axi4WriteRequest { address: truncate(dramWriteOffset), len: 0, // indicates 1 beat of data size: axiBusSize(valueOf(Ddr3DataWidth)), id: idC, burst: 2'b01, prot: 3'b000, //ignored cache: 4'b0011, //ignored lock: 2'b00, //ignored qos: 4'b0000 //ignored }; idC <= idC + 1; awfifo.enq(req); dramWriteFifo.enq(zeroExtend(dramWriteOffset)); dramWriteOffset <= dramWriteOffset + fromInteger(valueOf(Ddr3DataBytes)); endrule ////////// Begin DDR clock domain rule rl_awfifo; let req <- toGet(awfifo).get(); ddr3Controller.slave.req_aw.put(req); endrule rule rl_writeDataFifo; let mds <- toGet(dramWriteFifo).get(); ddr3Controller.slave.resp_write.put(Axi4WriteData { data: pack(mds), byteEnable: maxBound, last: 1, id: 0 }); endrule // Response from the DDR rule rl_bfifo; let b <- ddr3Controller.slave.resp_b.get(); bfifo.enq(b); endrule /////////// End clock domain DDR rule rl_b; let b <- toGet(bfifo).get(); indication.writeDone(extend(b.id)); endrule // Logic to handle read Reg#(Bit#(Ddr3AddrWidth)) dramReadOffset <- mkReg(0); Reg#(Bit#(Ddr3AddrWidth)) dramReadLimit <- mkReg(0); FIFOF#(Bit#(Ddr3DataWidth)) dramReadFifo <- mkDualClockBramFIFOF(ddr3Controller.uiClock, ddr3Controller.uiReset, clock, reset); FIFOF#(Axi4ReadRequest#(Ddr3AddrWidth,6)) arfifo <- mkDualClockBramFIFOF(clock, reset, ddr3Controller.uiClock, ddr3Controller.uiReset); rule rl_read_start; let sglId <- toGet(readReqFifo).get(); dramReadOffset <= 0; dramReadLimit <= transferLen; endrule rule rl_req_ar if (dramReadOffset < dramReadLimit); Axi4ReadRequest#(Ddr3AddrWidth,6) req = Axi4ReadRequest { address: truncate(dramReadOffset), len: 0, // indicates one beat of data size: axiBusSize(valueOf(Ddr3DataWidth)), id: idC, burst: 2'b01, prot: 3'b000, //ignored cache: 4'b0011, //ignored lock: 2'b00, //ignored qos: 4'b0000 //ignored }; arfifo.enq(req); idC <= idC + 1; dramReadOffset <= dramReadOffset + fromInteger(valueOf(Ddr3DataBytes)); endrule /////// Begin DDR clock domain rule rl_arfifo; let req <- toGet(arfifo).get(); ddr3Controller.slave.req_ar.put(req); endrule rule rl_rdata; let resp <- ddr3Controller.slave.resp_read.get(); Bit#(Ddr3DataWidth) data = resp.data; dramReadFifo.enq(data); endrule ////// End DDR clock domain rule rl_read_done; let res <- toGet(dramReadFifo).get(); indication.readDone(res[31:0]); // Lazy here endrule interface Ddr3TestRequest request; method Action startWriteDram(Bit#(32) sglId, Bit#(32) transferBytes); transferLen <= truncate(transferBytes); writeReqFifo.enq(sglId); endmethod method Action startReadDram(Bit#(32) sglId, Bit#(32) transferBytes); transferLen <= truncate(transferBytes); readReqFifo.enq(sglId); endmethod endinterface interface AxiDdr3 ddr3 = ddr3Controller.ddr3; endmodule ================================================ FILE: tests/ddr_minimal/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = Ddr3TestRequest:Ddr3Test.request H2S_INTERFACES = Ddr3Test:Ddr3TestIndication:host ifneq ($(BOARD),zc706) ifneq ($(BOARD),miniitx100) CONNECTALFLAGS += -D DataBusWidth=128 endif endif CONNECTALFLAGS += -D IMPORT_HOSTIF -D XILINX_SYS_CLK CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/axiddr3/axiddr3.xci BSVFILES = Ddr3Test.bsv CPPFILES=testddr3.cpp PIN_TYPE = Ddr3Pins PIN_TYPE_INCLUDE = AxiDdr3Controller AUTOTOP = --interface pins:Ddr3Test.ddr3 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/ddr_minimal/synth-ip.tcl ================================================ source board.tcl source $connectaldir/scripts/connectal-synth-axiddr3.tcl ================================================ FILE: tests/ddr_minimal/testddr3.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "Ddr3TestIndication.h" #include "Ddr3TestRequest.h" sem_t write_sem; sem_t read_sem; unsigned int readExpected = 0 ; class Ddr3TestIndication : public Ddr3TestIndicationWrapper { public: Ddr3TestIndication(unsigned int id) : Ddr3TestIndicationWrapper(id){} virtual void writeDone(uint32_t v) { fprintf(stderr, "writeDone %d\n", (int) v*64); sem_post(&write_sem); } virtual void readDone(uint32_t v) { if(v != readExpected) { fprintf(stderr, "read %d v expecting %d", (int) v,(int) readExpected); exit(1);} readExpected += 64; fprintf(stderr, "readDone %d\n", v); sem_post(&read_sem); } }; int main(int argc, const char **argv) { Ddr3TestRequestProxy *testRequest = new Ddr3TestRequestProxy(IfcNames_Ddr3TestRequestS2H); Ddr3TestIndication testIndication(IfcNames_Ddr3TestIndicationH2S); if(sem_init(&write_sem, 1, 0)){ fprintf(stderr, "failed to init write_sem\n"); return -1; } if(sem_init(&read_sem, 1, 0)){ fprintf(stderr, "failed to init read_sem\n"); return -1; } if (1) { int transferLen = 4096; fprintf(stderr, "Start writing dram\n"); testRequest->startWriteDram(0, transferLen); for (int i = 0; i < transferLen; i += 64) sem_wait(&write_sem); fprintf(stderr, "Finished writing dram\n"); testRequest->startReadDram(0, transferLen); for (int i = 0; i < transferLen; i += 64) sem_wait(&read_sem); } return 0; } ================================================ FILE: tests/dma2bram/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = TestRequest:Test.request H2S_INTERFACES = Test:TestIndication MEM_READ_INTERFACES = lTest.dmaClient BSVFILES = Test.bsv CPPFILES=test.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/dma2bram/Test.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import ClientServer::*; import BRAM::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import BlueScope::*; import MemReadEngine::*; import MemWriteEngine::*; import Dma2BRAM::*; import Pipe::*; interface TestRequest; method Action startWrite(Bit#(32) sglId); endinterface interface TestIndication; method Action writeDone(Bit#(32) v); endinterface interface Test; interface TestRequest request; interface Vector#(1, MemReadClient#(64)) dmaClient; endinterface module mkTest#(TestIndication indication)(Test); MemReadEngine#(64,64,1,1) re <- mkMemReadEngine; BRAM1Port#(Bit#(10),Bit#(8)) bram <- mkBRAM1Server(defaultValue); BRAMWriter#(10,64) bramWriter <- mkBRAMWriter(2, bram.portA, re.readServers[0]); rule finishWrite; let rv <- bramWriter.finish; indication.writeDone(0); endrule interface TestRequest request; method Action startWrite(Bit#(32) sglId); bramWriter.start(sglId, 0, minBound, maxBound); endmethod endinterface interface dmaClient = vec(re.dmaClient); endmodule ================================================ FILE: tests/dma2bram/test.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "TestIndication.h" #include "TestRequest.h" sem_t test_sem; unsigned int alloc_sz = 1<<10; class TestIndication : public TestIndicationWrapper { public: TestIndication(unsigned int id) : TestIndicationWrapper(id){} virtual void writeDone(uint32_t v) { fprintf(stderr, "writeDone %d\n", v); sem_post(&test_sem); } }; int main(int argc, const char **argv) { DmaManager *dma = platformInit(); TestRequestProxy *testRequest = new TestRequestProxy(IfcNames_TestRequestS2H); TestIndication testIndication(IfcNames_TestIndicationH2S); if(sem_init(&test_sem, 1, 0)){ fprintf(stderr, "failed to init test_sem\n"); return -1; } int srcAlloc = portalAlloc(alloc_sz, 0); //unsigned int *srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); int ref_srcAlloc = dma->reference(srcAlloc); testRequest->startWrite(ref_srcAlloc); sem_wait(&test_sem); testRequest->startWrite(ref_srcAlloc); sem_wait(&test_sem); return 0; } ================================================ FILE: tests/dram_awsf1/Axi4.bsv ================================================ import AxiBits::*; import Axi4MasterSlave::*; import FIFOF::*; import ConnectalFIFO::*; import GetPut::*; typedef 64 DdrAddrWidth; typedef 16 DdrIdWidth; typedef 512 DdrBusWidth; typedef Axi4MasterBits#(DdrAddrWidth,DdrBusWidth,DdrIdWidth,Empty) Axi4; interface Ddr3TestRequest; method Action startWriteDram(Bit#(16) id, Bit#(64) addr, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3, Bit#(32) v4, Bit#(32) v5, Bit#(32) v6,Bit#(32) v7, Bit#(32) v8, Bit#(32) v9, Bit#(32) v10, Bit#(32) v11, Bit#(32) v12, Bit#(32) v13, Bit#(32) v14, Bit#(32) v15, Bit#(32) v16); method Action startReadDram(Bit#(16) id, Bit#(64) addr); endinterface interface Ddr3TestIndication; method Action writeDone(Bit#(32) v); method Action readDone(Bit#(16) id, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3, Bit#(32) v4, Bit#(32) v5, Bit#(32) v6,Bit#(32) v7, Bit#(32) v8, Bit#(32) v9, Bit#(32) v10, Bit#(32) v11, Bit#(32) v12, Bit#(32) v13, Bit#(32) v14, Bit#(32) v15, Bit#(32) v16); method Action error(Bit#(32) code, Bit#(32) data); endinterface interface DdrAws; interface Ddr3TestRequest request; interface Axi4 ddr3; endinterface module mkAxi4MasterBitsEmpty#(Axi4Master#(addrWidth,dataWidth,tagWidth) m)(Axi4MasterBits#(addrWidth,busDataWidth,busTagWidth,Empty)) provisos (Add#(dataWidth,d__,busDataWidth), Div#(dataWidth,32,dataWidthWords), Add#(tagWidth,t__,busTagWidth), Add#(a__, TDiv#(dataWidth, 8), TDiv#(busDataWidth, 8))); let arfifo <- mkCFFIFOF(); let araddrWire <- mkDWire(0); let arburstWire <- mkDWire(0); let arcacheWire <- mkDWire(0); let aridWire <- mkDWire(0); let arreadyWire <- mkDWire(False); let arprotWire <- mkDWire(0); let arlenWire <- mkDWire(0); let arsizeWire <- mkDWire(0); let awfifo <- mkCFFIFOF(); let awaddrWire <- mkDWire(0); let awburstWire <- mkDWire(0); let awcacheWire <- mkDWire(0); let awidWire <- mkDWire(0); let awreadyWire <- mkDWire(False); let awprotWire <- mkDWire(0); let awlenWire <- mkDWire(0); let awsizeWire <- mkDWire(0); let rfifo <- mkCFFIFOF(); let rdataWire <- mkDWire(0); let rrespWire <- mkDWire(0); let rlastWire <- mkDWire(0); let ridWire <- mkDWire(0); let rvalidWire <- mkDWire(False); let wfifo <- mkCFFIFOF(); let wdataWire <- mkDWire(0); let widWire <- mkDWire(0); let wstrbWire <- mkDWire(0); let wlastWire <- mkDWire(0); let wreadyWire <- mkDWire(False); let bfifo <- mkCFFIFOF(); let bidWire <- mkDWire(0); let brespWire <- mkDWire(0); let bvalidWire <- mkDWire(False); rule arfifo_enq; let req <- m.req_ar.get(); arfifo.enq(req); endrule rule arwire_rule; araddrWire <= arfifo.first.address; arlenWire <= arfifo.first.len; Bit#(11) dwlen = extend(arfifo.first.len) / fromInteger(valueOf(dataWidthWords)); Bit#(8) mustbeone = 8'hf; arsizeWire <= arfifo.first.size; arburstWire <= 2'b01; //arfifo.first.burst; arprotWire <= 3'b000; //arfifo.first.prot; arcacheWire <= 4'b0011; // arfifo.first.cache; aridWire <= arfifo.first.id; endrule rule ar_handshake if (arreadyWire); arfifo.deq(); endrule rule awfifo_enq; let req <- m.req_aw.get(); awfifo.enq(req); endrule rule awwire_rule; awaddrWire <= awfifo.first.address; let lenbytes = awfifo.first.len; awlenWire <= lenbytes; Bit#(11) dwlen = extend(lenbytes) / fromInteger(valueOf(dataWidthWords)); Bit#(4) firstBE = 4'hf; Bit#(4) lastBE = (lenbytes > 4) ? 4'hf : 0; awsizeWire <= awfifo.first.size; awburstWire <= 2'b01; //awfifo.first.burst; awprotWire <= 3'b000; //awfifo.first.prot; awcacheWire <= 4'b0011; // awfifo.first.cache; awidWire <= awfifo.first.id; endrule rule aw_handshake if (awreadyWire); awfifo.deq(); endrule rule rdata_put; let data <- toGet(rfifo).get(); m.resp_read.put(data); endrule rule r_handshake if (rvalidWire); rfifo.enq(Axi4ReadResponse {data: truncate(rdataWire), resp: rrespWire, last: rlastWire, id: ridWire }); endrule rule wdata_get; let data <- m.resp_write.get(); wfifo.enq(data); endrule rule w_handshake if (wreadyWire); let data <- toGet(wfifo).get(); wdataWire <= extend(data.data); wlastWire <= pack(data.last); wstrbWire <= data.byteEnable; widWire <= data.id; endrule rule bresp_put; let resp <- toGet(bfifo).get(); m.resp_b.put(resp); endrule rule b_handshake if (bvalidWire); bfifo.enq(Axi4WriteResponse {resp: brespWire, id: bidWire }); endrule interface Empty extra; endinterface method araddr = araddrWire; method arburst = arburstWire; method arcache = arcacheWire; method aresetn = 1; method arid = extend(aridWire); method arlen = arlenWire; // method Bit#(2) arlock(); method arprot = arprotWire; // method Bit#(4) arqos(); method Action arready(Bit#(1) v); arreadyWire <= unpack(v); endmethod method arsize = arsizeWire; method arvalid = pack(arfifo.notEmpty); method awaddr = awaddrWire; method awburst = awburstWire; method awcache = awcacheWire; method awid = extend(awidWire); method awlen = awlenWire; //method awlock = awlockWire; method awprot = awprotWire; // method Bit#(4) awqos(); method Action awready(Bit#(1) v); awreadyWire <= unpack(v); endmethod method awsize = awsizeWire; method awvalid = pack(awfifo.notEmpty); method Action bid(Bit#(busTagWidth) v); bidWire <= truncate(v); endmethod method bready = pack(bfifo.notFull()); method Action bresp(Bit#(2) v); brespWire <= v; endmethod method Action bvalid(Bit#(1) v); bvalidWire <= unpack(v); endmethod method Action rdata(Bit#(busDataWidth) v); rdataWire <= v; endmethod method Action rid(Bit#(busTagWidth) v); ridWire <= truncate(v); endmethod method Action rlast(Bit#(1) v); rlastWire <= unpack(v); endmethod method rready = pack(rfifo.notFull()); method Action rresp(Bit#(2) v); rrespWire <= v; endmethod method Action rvalid(Bit#(1) v); rvalidWire <= unpack(v); endmethod method wdata = wdataWire; method wid = extend(widWire); method wlast = wlastWire; method Action wready(Bit#(1) v); wreadyWire <= unpack(v); endmethod method wstrb = extend(wstrbWire); method wvalid = pack(wfifo.notEmpty); endmodule ================================================ FILE: tests/dram_awsf1/DdrAws.bsv ================================================ // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Clocks::*; import Vector::*; import BuildVector::*; import GetPut::*; import Connectable::*; import ClientServer::*; import ConnectalMemory::*; import ConnectalBramFifo::*; import FIFOF::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; import AxiDdr3Controller::*; import GetPutWithClocks::*; import AxiMasterSlave::*; import Axi4MasterSlave::*; import AxiDdr3Wrapper ::*; import AxiDma::*; import ConnectalConfig::*; import HostInterface::*; import Probe::*; import Axi4::*; module mkDdrAws#(Ddr3TestIndication ind)(DdrAws); Reg#(Bool) flying <- mkReg(False); FIFOF#(Axi4ReadRequest#(DdrAddrWidth, DdrIdWidth)) fifo_req_ar <- mkFIFOF(); FIFOF#(Axi4ReadResponse#(DdrBusWidth, DdrIdWidth)) fifo_resp_read <- mkFIFOF(); FIFOF#(Axi4WriteRequest#(DdrAddrWidth, DdrIdWidth)) fifo_req_aw <- mkFIFOF(); FIFOF#(Axi4WriteData#(DdrBusWidth, DdrIdWidth)) fifo_resp_write <- mkFIFOF(); FIFOF#(Axi4WriteResponse#(DdrIdWidth)) fifo_resp_b <- mkFIFOF(); let aximaster = (interface Axi4Master; interface req_ar = toGet(fifo_req_ar); interface resp_read = toPut(fifo_resp_read); interface req_aw = toGet(fifo_req_aw); interface resp_write = toGet(fifo_resp_write); interface resp_b = toPut(fifo_resp_b); endinterface); Axi4 ddr3bits <- mkAxi4MasterBitsEmpty(aximaster); rule gotRead; fifo_resp_read.deq(); let respread = fifo_resp_read.first(); let resp = respread.data; let id = respread.id; let last = respread.last; let error = respread.resp; if (error != 0 || last != 1) begin ind.error(zeroExtend(error),zeroExtend(id)); end flying <= False; ind.readDone(id,resp[31:0],resp[63:32],resp[95:64],resp[127:96], resp[159:128],resp[191:160],resp[223:192],resp[255:224], resp[287:256],resp[319:288],resp[351:320],resp[383:352], resp[415:384],resp[447:416],resp[479:448],resp[511:480]); endrule rule gotWrite; fifo_resp_b.deq(); let resp = fifo_resp_b.first(); let error = resp.resp; let id = resp.id; flying <= False; if (error != 0) begin ind.error(zeroExtend(error), zeroExtend(id)); end ind.writeDone(zeroExtend(id)); endrule // len = nb pack512 -1 // size axiBusSize // burst: 1 // prot: 0 // cache:3 // lock: 0 // qos: 0 // resp: 0 if no error // last: 1 for the last burst. interface Ddr3TestRequest request; method Action startWriteDram(Bit#(16) id, Bit#(64) address, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3, Bit#(32) v4, Bit#(32) v5, Bit#(32) v6,Bit#(32) v7, Bit#(32) v8, Bit#(32) v9, Bit#(32) v10, Bit#(32) v11, Bit#(32) v12, Bit#(32) v13, Bit#(32) v14, Bit#(32) v15, Bit#(32) v16) if (!flying); flying <= True; fifo_req_aw.enq(Axi4WriteRequest{address: address, len: 0, size: 6, burst: 1, prot: 0, cache: 3, id: id, lock: 0, qos: 0 }); fifo_resp_write.enq(Axi4WriteData{data: {v16,v15,v14,v13,v12,v11,v10,v9,v8,v7,v6,v5,v4,v3,v2,v1}, byteEnable: maxBound, last: 1, id: id}); endmethod method Action startReadDram(Bit#(16) id, Bit#(64) address) if (!flying); flying <= True; fifo_req_ar.enq(Axi4ReadRequest{address: address, len: 0, size: 6, burst: 1, prot: 0, cache: 3, id: id, lock: 0, qos: 0 }); endmethod endinterface interface ddr3 = ddr3bits; endmodule ================================================ FILE: tests/dram_awsf1/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = Ddr3TestRequest:DdrAws.request H2S_INTERFACES = DdrAws:Ddr3TestIndication BSVFILES= \ DdrAws.bsv\ Axi4.bsv CPPFILES= testddr3.cpp PIN_TYPE = Axi4 PIN_TYPE_INCLUDE = Axi4 AUTOTOP = --interface pins:DdrAws.ddr3 CONNECTALFLAGS += -D AWSF1_DDR_A include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/dram_awsf1/testddr3.cpp ================================================ /* * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "Ddr3TestIndication.h" #include "Ddr3TestRequest.h" sem_t write_sem; sem_t read_sem; uint32_t value = 0; class Ddr3TestIndication : public Ddr3TestIndicationWrapper { public: Ddr3TestIndication(unsigned int id) : Ddr3TestIndicationWrapper(id){} virtual void writeDone(uint32_t id) { // fprintf(stderr, "writeDone id %d\n", id); sem_post(&write_sem); } virtual void readDone(uint16_t v, uint32_t v1,uint32_t v2,uint32_t v3,uint32_t v4, uint32_t v5,uint32_t v6,uint32_t v7,uint32_t v8, uint32_t v9,uint32_t v10,uint32_t v11,uint32_t v12, uint32_t v13,uint32_t v14,uint32_t v15,uint32_t v16 ) { fprintf(stderr, "readDone %d\n", v); fprintf(stderr, " readValue %d\n", v1 ); fprintf(stderr, " readValue %d\n", v2 ); fprintf(stderr, " readValue %d\n", v3 ); fprintf(stderr, " readValue %d\n", v4 ); fprintf(stderr, " readValue %d\n", v5 ); fprintf(stderr, " readValue %d\n", v6 ); fprintf(stderr, " readValue %d\n", v7 ); fprintf(stderr, " readValue %d\n", v8 ); fprintf(stderr, " readValue %d\n", v9 ); fprintf(stderr, " readValue %d\n", v10); fprintf(stderr, " readValue %d\n", v11); fprintf(stderr, " readValue %d\n", v12); fprintf(stderr, " readValue %d\n", v13); fprintf(stderr, " readValue %d\n", v14); fprintf(stderr, " readValue %d\n", v15); fprintf(stderr, " readValue %d\n", v16); // if (!(value == v1)) {fprintf(stderr, "Value problem expected %d",value); exit(1);} sem_post(&read_sem); } virtual void error(uint32_t code, uint32_t data){ fprintf(stderr, "Error code %d, data %d", code, data); exit(1); } }; int main(int argc, const char **argv) { Ddr3TestRequestProxy *testRequest = new Ddr3TestRequestProxy(IfcNames_Ddr3TestRequestS2H); Ddr3TestIndication testIndication(IfcNames_Ddr3TestIndicationH2S); if(sem_init(&write_sem, 1, 0)){ fprintf(stderr, "failed to init write_sem\n"); return -1; } if(sem_init(&read_sem, 1, 0)){ fprintf(stderr, "failed to init read_sem\n"); return -1; } for (uint64_t i = 0; i< 1000000; i += 1){ if (i%10000 == 0) printf("%d",(int) i); value = 512*i; uint64_t address = i; uint16_t id = i; fflush(stdout); testRequest->startWriteDram(id, address, value,value+32,value+64, value+96, value+4*32,value+5*32,value+6*32, value+7*32, value+8*32,value+9*32,value+10*32, value+11*32, value+12*32,value+13*32,value+14*32, value+15*32); sem_wait(&write_sem); /* testRequest->startReadDram(2, address); sem_wait(&read_sem);*/ } return 0; } ================================================ FILE: tests/echosoft2/EchoId.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; //import Vector::*; interface EchoIndication; method Action heard(Bit#(32) id, Bit#(32) v); method Action heard2(Bit#(32) id, Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) id, Bit#(32) v); method Action say2(Bit#(32) id, Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(32) id, Bit#(8) v); endinterface interface EchoId; interface EchoRequest request; endinterface typedef struct { Bit#(32) id; Bit#(32) v; } EchoPair1 deriving (Bits); typedef struct { Bit#(32) id; Bit#(16) a; Bit#(16) b; } EchoPair2 deriving (Bits); module mkEchoId#(EchoIndication indication)(EchoId); FIFO#(EchoPair1) delay1 <- mkSizedFIFO(8); FIFO#(EchoPair2) delay2 <- mkSizedFIFO(8); rule heard; delay1.deq; indication.heard(delay1.first.id, delay1.first.v); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.id, delay2.first.b, delay2.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) id, Bit#(32) v); delay1.enq(EchoPair1 { id: id, v: v}); endmethod method Action say2(Bit#(32) id, Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair2 { id: id, a: a, b: b}); endmethod method Action setLeds(Bit#(32) id, Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: tests/echosoft2/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:EchoId.request SwallowRequest:Swallow.request H2S_INTERFACES = EchoId:EchoIndication BSVFILES = EchoId.bsv ../../examples/echosoft/Swallow.bsv CPPFILES=testecho.cpp CPPFILES2=daemon.cpp AUTOTOP = --portname IfcNames_EchoIndication2H2S --portname IfcNames_EchoRequest2S2H include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/echosoft2/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "sock_utils.h" #include "EchoRequest.h" #include "EchoIndication.h" EchoRequestProxy *echoRequestProxy; EchoIndicationProxy *sIndicationProxy; EchoIndicationProxy *sIndicationProxy2; static int daemon_trace = 1; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t id, uint32_t v) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo: %u %u\n", id, v); if (id == 1) { sIndicationProxy->heard(id, v); } else if (id == 2) { sIndicationProxy2->heard(id, v); } else { fprintf (stderr, "id is wrong (%u)", id); } } void heard2(uint32_t id, uint16_t a, uint16_t b) { if (daemon_trace) fprintf(stderr, "daemon: heard an echo2: %u %d %d\n", id, a, b); if (id == 1) { sIndicationProxy->heard2(id, a, b); } else if (id == 2) { sIndicationProxy2->heard2(id, a, b); } else { fprintf (stderr, "id is wrong (%u)", id); } } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; class EchoRequest : public EchoRequestWrapper { public: void say (const uint32_t id, const uint32_t v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d] %u %u\n", __FUNCTION__, __LINE__, id, v); echoRequestProxy->say(id, v); } void say2 (const uint32_t id, const uint16_t a, const uint16_t b ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d] %u %u %u\n", __FUNCTION__, __LINE__, id, a, b); echoRequestProxy->say2(id, a, b); } void setLeds (const uint32_t id, const uint8_t v ) { fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); echoRequestProxy->setLeds(id, v); sleep(1); exit(1); } EchoRequest(unsigned int id, PortalTransportFunctions *item, void *param) : EchoRequestWrapper(id, item, param) {} }; int main(int argc, const char **argv) { sIndicationProxy = new EchoIndicationProxy(IfcNames_EchoIndicationH2S, &transportSocketResp, NULL); sIndicationProxy2 = new EchoIndicationProxy(IfcNames_EchoIndication2H2S, &transportSocketResp, NULL); EchoRequest sRequest(IfcNames_EchoRequestS2H, &transportSocketResp, NULL); EchoRequest sRequest2(IfcNames_EchoRequest2S2H, &transportSocketResp, NULL); EchoIndication echoIndication(IfcNames_EchoIndicationH2S, NULL, NULL); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: tests/echosoft2/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include /* POSIX Threads */ #include "EchoRequest.h" #include "EchoIndication.h" /****************** client1 ******************/ EchoRequestProxy *sRequestProxy; static sem_t sem_heard; class EchoIndication : public EchoIndicationWrapper { public: void heard(uint32_t id, uint32_t v) { fprintf(stderr, "[client1] heard an s: %d\n", v); sRequestProxy->say2(id, v, 2*v); } void heard2(uint32_t id, uint16_t a, uint16_t b) { sem_post(&sem_heard); //fprintf(stderr, "heard an s2: %ld %ld\n", a, b); } EchoIndication(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; EchoIndication *sIndication; static void call_say(int v) { printf("[client1] [%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy->say(1, v); sem_wait(&sem_heard); } static void call_say2(int v, int v2) { printf("[client1] [%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy->say2(1, v, v2); sem_wait(&sem_heard); } void* client1 (void *ptr) { int v = 42; fprintf(stderr, "[client1] Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); fprintf(stderr, "[client1] sleeping...\n"); portal_disconnect(&sRequestProxy->pint); sleep(5); pthread_exit(0); /* exit */ } /****************** client2 ******************/ EchoRequestProxy *sRequestProxy2; static sem_t sem_heard2; class EchoIndication2 : public EchoIndicationWrapper { public: void heard(uint32_t id, uint32_t v) { fprintf(stderr, "[client2] heard an s: %d\n", v); sRequestProxy2->say2(id, v, 2*v); } void heard2(uint32_t id, uint16_t a, uint16_t b) { sem_post(&sem_heard2); //fprintf(stderr, "heard an s2: %ld %ld\n", a, b); } EchoIndication2(unsigned int id, PortalTransportFunctions *item, void *param) : EchoIndicationWrapper(id, item, param) {} }; EchoIndication2 *sIndication2; static void call2_say(int v) { printf("[client2] [%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy2->say(2, v); sem_wait(&sem_heard2); } static void call2_say2(int v, int v2) { printf("[client2] [%s:%d] %d\n", __FUNCTION__, __LINE__, v); sRequestProxy2->say2(2, v, v2); sem_wait(&sem_heard2); } void* client2 (void *ptr) { int v = 42; fprintf(stderr, "[client2] Saying2 %d\n", v); call2_say(v); call2_say(v); call2_say(v*5); call2_say(v*17); call2_say(v*93); call2_say2(v, v*3); fprintf(stderr, "[client2] sleeping...\n"); portal_disconnect(&sRequestProxy2->pint); sleep(5); pthread_exit(0); /* exit */ } int main(int argc, const char **argv) { pthread_t thread1, thread2; /* thread variables */ printf ("*** Two clients version ***\n"); sleep(2); sIndication = new EchoIndication(IfcNames_EchoIndicationH2S, &transportSocketInit, NULL); sRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H, &transportSocketInit, NULL); sIndication2 = new EchoIndication2(IfcNames_EchoIndication2H2S, &transportSocketInit, NULL); sRequestProxy2 = new EchoRequestProxy(IfcNames_EchoRequest2S2H, &transportSocketInit, NULL); pthread_create (&thread1, NULL, client1, (void*)NULL); pthread_create (&thread2, NULL, client2, (void*)NULL); printf ("main: before pthread_join\n"); pthread_join (thread1, NULL); pthread_join (thread2, NULL); printf ("main: done\n"); exit(0); } #ifdef COMMENT int main(int argc, const char **argv) { PortalSocketParam param; printf ("*** version 2 ***\n"); // Client 1 EchoIndication *sIndication = new EchoIndication(IfcNames_EchoIndication, &transportSocketInit, NULL); sRequestProxy = new EchoRequestProxy(IfcNames_EchoRequest, &transportSocketInit, NULL); // Client 2 EchoIndication *sIndication2 = new EchoIndication(IfcNames_EchoIndication2, &transportSocketInit, NULL); sRequestProxy2 = new EchoRequestProxy(IfcNames_EchoRequest2, &transportSocketInit, NULL); int v = 42; fprintf(stderr, "Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); //sRequestProxy->setLeds(9); printf ("-----------------------\n"); call2_say(v); call2_say(v); call2_say(v*5); call2_say(v*17); call2_say(v*93); call2_say2(v, v*3); //freeaddrinfo(param.addr); return 0; } #endif ================================================ FILE: tests/fastecho/FastEcho.bsv ================================================ // Copyright (c) 2017 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface FastEchoIndicationA; method Action indication(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoRequestA; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoIndicationB; method Action indication(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoRequestB; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoIndicationC; method Action indication(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoRequestC; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoIndicationD; method Action indication(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEchoRequestD; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d); endinterface interface FastEcho; interface FastEchoRequestA requestA; interface FastEchoRequestB requestB; interface FastEchoRequestC requestC; interface FastEchoRequestD requestD; endinterface module mkFastEcho#( FastEchoIndicationA indicationA, FastEchoIndicationB indicationB, FastEchoIndicationC indicationC, FastEchoIndicationD indicationD )(FastEcho); Reg#(Bool) validDataA <- mkReg(False); Reg#(Bit#(64)) aRegA <- mkReg(0); Reg#(Bit#(64)) bRegA <- mkReg(0); Reg#(Bit#(64)) cRegA <- mkReg(0); Reg#(Bit#(64)) dRegA <- mkReg(0); Reg#(Bool) validDataB <- mkReg(False); Reg#(Bit#(64)) aRegB <- mkReg(0); Reg#(Bit#(64)) bRegB <- mkReg(0); Reg#(Bit#(64)) cRegB <- mkReg(0); Reg#(Bit#(64)) dRegB <- mkReg(0); Reg#(Bool) validDataC <- mkReg(False); Reg#(Bit#(64)) aRegC <- mkReg(0); Reg#(Bit#(64)) bRegC <- mkReg(0); Reg#(Bit#(64)) cRegC <- mkReg(0); Reg#(Bit#(64)) dRegC <- mkReg(0); Reg#(Bool) validDataD <- mkReg(False); Reg#(Bit#(64)) aRegD <- mkReg(0); Reg#(Bit#(64)) bRegD <- mkReg(0); Reg#(Bit#(64)) cRegD <- mkReg(0); Reg#(Bit#(64)) dRegD <- mkReg(0); rule sendIndicationA(validDataA); indicationA.indication(aRegA, bRegA, cRegA, dRegA); validDataA <= False; endrule rule sendIndicationB(validDataB); indicationB.indication(aRegB, bRegB, cRegB, dRegB); validDataB <= False; endrule rule sendIndicationC(validDataC); indicationC.indication(aRegC, bRegC, cRegC, dRegC); validDataC <= False; endrule rule sendIndicationD(validDataD); indicationD.indication(aRegD, bRegD, cRegD, dRegD); validDataD <= False; endrule interface FastEchoRequestA requestA; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d) if (!validDataA); validDataA <= True; aRegA <= a; bRegA <= b; cRegA <= c; dRegA <= d; endmethod endinterface interface FastEchoRequestB requestB; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d) if (!validDataB); validDataB <= True; aRegB <= a; bRegB <= b; cRegB <= c; dRegB <= d; endmethod endinterface interface FastEchoRequestC requestC; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d) if (!validDataC); validDataC <= True; aRegC <= a; bRegC <= b; cRegC <= c; dRegC <= d; endmethod endinterface interface FastEchoRequestD requestD; method Action request(Bit#(64) a, Bit#(64) b, Bit#(64) c, Bit#(64) d) if (!validDataD); validDataD <= True; aRegD <= a; bRegD <= b; cRegD <= c; dRegD <= d; endmethod endinterface endmodule ================================================ FILE: tests/fastecho/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = \ FastEchoRequestA:FastEcho.requestA \ FastEchoRequestB:FastEcho.requestB \ FastEchoRequestC:FastEcho.requestC \ FastEchoRequestD:FastEcho.requestD \ H2S_INTERFACES = \ FastEcho:FastEchoIndicationA \ FastEcho:FastEchoIndicationB \ FastEcho:FastEchoIndicationC \ FastEcho:FastEchoIndicationD \ BSVFILES = FastEcho.bsv CPPFILES = testfastecho.cpp # This matches the frequency of the original design where the bug was found CONNECTALFLAGS += --mainclockperiod=32 CONNECTALFLAGS += -D GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/dual_clock_axis_fifo_32x8/dual_clock_axis_fifo_32x8.xci include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/fastecho/about_this_test.txt ================================================ This test reproduces the bug reported in issue #133 on github. https://github.com/cambridgehackers/connectal/issues/133 When this design is built for kc705g2 and run on FPGA, it typically stalls after a few thousand requests and indications. ================================================ FILE: tests/fastecho/synth-ip.tcl ================================================ source "board.tcl" source "$connectaldir/../fpgamake/tcl/ipcore.tcl" if {[version -short] >= "2016.1"} { set dual_clock_axis_fifo_version 13.1 } else { set dual_clock_axis_fifo_version 13.0 } fpgamake_ipcore fifo_generator $dual_clock_axis_fifo_version dual_clock_axis_fifo_32x8 [list \ config.interface_type {axi_stream} \ config.clock_type_axi {independent_clock} \ config.tdata_num_bytes {4} \ config.tuser_width {0} \ config.enable_tlast {true} \ config.has_tkeep {true} \ config.fifo_application_type_axis {data_fifo} \ config.reset_type {asynchronous_reset} \ ] ================================================ FILE: tests/fastecho/testfastecho.cpp ================================================ /* Copyright (c) 2017 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include "FastEchoIndicationA.h" #include "FastEchoRequestA.h" #include "GeneratedTypes.h" class FastEcho : public FastEchoIndicationAWrapper { public: FastEcho(unsigned int indicationId, unsigned int requestId) : FastEchoIndicationAWrapper(indicationId), fastEchoRequestProxy(requestId) { sem_init(&sem, 1, 0); } virtual void indication(uint64_t a, uint64_t b, uint64_t c, uint64_t d) { aResp = a; bResp = b; cResp = c; dResp = d; sem_post(&sem); } bool doEcho(uint64_t a, uint64_t b, uint64_t c, uint64_t d) { fastEchoRequestProxy.request(a, b, c, d); sem_wait(&sem); if (aResp != a || bResp != b || cResp != c || dResp != d) { std::cerr << "ERROR: echo failed" << std::endl; return false; } else { return true; } } private: FastEchoRequestAProxy fastEchoRequestProxy; sem_t sem; uint64_t aResp, bResp, cResp, dResp; }; int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); FastEcho fastEcho(IfcNames_FastEchoIndicationAH2S, IfcNames_FastEchoRequestAS2H); for (uint64_t i = 0 ; i < 100000 ; i++) { if (i % 1000 == 0) { std::cout << "i = " << i << std::endl; } fastEcho.doEcho(i, i + 10, i ^ 2510, i >> 32); } std::cout << "Done" << std::endl; return 0; } ================================================ FILE: tests/float/FloatTest.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FloatingPoint::*; import StmtFSM::*; import FShow::*; module mkFloatTestBench(Empty); let once <- mkOnce(action Real re = 3.14159; $display("Real 0x%x %f", fromReal(re), re); //not supported: $display(fshow(re)); Float fl = 3.14159; //not supported: $display("Float 0x%x %f", pack(fl), $bitstoreal(pack(fl))); $display("Float 0x%x %f", pack(fl), fl); $display(fshow(fl)); Double doub = 3.14159; $display("Double 0x%x %f", pack(doub), $bitstoreal(pack(doub))); $display(fshow(doub)); $finish; endaction); rule foobar; once.start(); endrule endmodule ================================================ FILE: tests/float/Makefile ================================================ CONNECTALDIR?=../.. run: floatTestBench ./floatTestBench ctest: gcc -o ftest ftest.c ./ftest rm -f ftest floatTestBench: FloatTest.bsv mkdir -p obj bsc --show-schedule -sim -info-dir obj -bdir obj -p +:$(CONNECTALDIR)/lib/bsv -g mkFloatTestBench -u $< bsc --show-schedule -sim -info-dir obj -bdir obj -e mkFloatTestBench -o floatTestBench clean: rm -rf floatTestBench* mkFloatTestBench.* model_mkFloatTestBench.* dump.vcd obj ================================================ FILE: tests/float/ftest.c ================================================ #include int main() { union { float f; unsigned int i; } dfloat; union { double f; unsigned long i; } ddouble; printf("[%s:%d] sizeof(float) %ld sizeof(double) %ld\n", __FUNCTION__, __LINE__, sizeof(float), sizeof(double)); dfloat.i = 0x3f60be97; printf("[%s:%d] f %f\n", __FUNCTION__, __LINE__, dfloat.f); printf("[%s:%d] i %x\n", __FUNCTION__, __LINE__, dfloat.i); dfloat.f = 3.14159; printf("[%s:%d] 2f %f\n", __FUNCTION__, __LINE__, dfloat.f); printf("[%s:%d] 2i %x\n", __FUNCTION__, __LINE__, dfloat.i); ddouble.f = 3.14159; printf("[%s:%d] 2f %f\n", __FUNCTION__, __LINE__, ddouble.f); printf("[%s:%d] 2i %lx\n", __FUNCTION__, __LINE__, ddouble.i); return 0; } ================================================ FILE: tests/fp/BviFpAdd.bsv ================================================ /* ../../scripts/importbvi.py -o BviFpAdd.bsv -c aclk -f s_axis_a -f s_axis_b -f m_axis_result -I BviFpAdd -P BviFpAdd ../../generated/xilinx/zc706/fp_add/fp_add_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import FloatingPoint::*; interface BviFpAdd; method Action s_axis_a(Float v); method Action s_axis_b(Float v); method Action s_axis_operation(Bit#(8) v); method ActionValue#(Float) m_axis_result(); endinterface import "BVI" fp_add = module mkBviFpAdd (BviFpAdd); default_clock aclk(aclk); default_reset aresetn(aresetn); method s_axis_a (s_axis_a_tdata) ready (s_axis_a_tready) enable (s_axis_a_tvalid); method s_axis_b (s_axis_b_tdata) ready (s_axis_b_tready) enable (s_axis_b_tvalid); method s_axis_operation (s_axis_operation_tdata) ready (s_axis_operation_tready) enable (s_axis_operation_tvalid); method m_axis_result_tdata m_axis_result () ready (m_axis_result_tvalid) enable (m_axis_result_tready); schedule (s_axis_a, s_axis_b, s_axis_operation, m_axis_result) CF (s_axis_a, s_axis_b, s_axis_operation, m_axis_result); endmodule ================================================ FILE: tests/fp/FpOps.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import BviFpAdd::*; import Clocks::*; import GetPut::*; import ClientServer::*; import FloatingPoint::*; import FIFO::*; `ifdef SIMULATION module mkXilinxFPAdder(Server#(Tuple2#(Float,Float), Float)); FIFO#(Float) resultFifo <- mkFIFO(); interface Put request; method Action put(Tuple2#(Float,Float) req); match { .a, .b } = req; resultFifo.enq(a+b); endmethod endinterface interface Get response = toGet(resultFifo); endmodule: mkXilinxFPAdder `else module mkXilinxFPAdder(Server#(Tuple2#(Float,Float), Float)); let fpAdd <- mkBviFpAdd(); interface Put request; method Action put(Tuple2#(Float,Float) req); match { .a, .b } = req; fpAdd.s_axis_a(a); fpAdd.s_axis_b(b); fpAdd.s_axis_operation(0); endmethod endinterface interface Get response = toGet(fpAdd.m_axis_result); endmodule `endif ================================================ FILE: tests/fp/FpTest.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FloatingPoint::*; import GetPut::*; import ClientServer::*; import FpOps::*; interface FpRequest; method Action add(Float a, Float b); endinterface interface FpIndication; method Action added(Float a); endinterface interface FpTest; interface FpRequest request; endinterface module mkFpTest#(FpIndication indication)(FpTest); Server#(Tuple2#(Float,Float),Float) adder <- mkXilinxFPAdder(); rule result; let v <- adder.response.get(); indication.added(v); endrule interface FpRequest request; method Action add(Float a, Float b); adder.request.put(tuple2(a, b)); endmethod endinterface endmodule ================================================ FILE: tests/fp/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = FpRequest:FpTest.request H2S_INTERFACES = FpTest:FpIndication BSVFILES = FpTest.bsv CPPFILES=testfp.cpp CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/fp_add/fp_add.xci --xci=$(IPDIR)/$(BOARD)/fp_mul/fp_mul.xci FP_ADD_V = $(IPDIR)/$(BOARD)/fp_add/fp_add_stub.v ifeq ($(BOARD),bluesim) # not for bluesim else ## ## the prebuild target will be made after the project directory is generated, e.g., by make gen.zedboard ## prebuild:: $(FP_ADD_V) BviFpAdd.bsv $(FP_ADD_V): synth-ip.tcl (cd $(BOARD); vivado -mode batch -source ../synth-ip.tcl) endif ## ## Generate the import "BVI" from the generated stub for the core: fp_add_stub.v ## Then, hand-modified so it works BviFpAdd.bsv: $(CONNECTALDIR)/scripts/importbvi.py -o BviFpAdd.bsv -c aclk -f s_axis_a -f s_axis_b -f m_axis_result -I BviFpAdd -P BviFpAdd $(FP_ADD_V) include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/fp/synth-ip.tcl ================================================ source board.tcl source $connectaldir/scripts/connectal-synth-ip.tcl connectal_synth_ip floating_point 7.0 fp_add [list CONFIG.Axi_Optimize_Goal {Performance} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] connectal_synth_ip floating_point 7.0 fp_mul [list CONFIG.Operation_Type {Multiply} CONFIG.Axi_Optimize_Goal {Resources} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] ================================================ FILE: tests/fp/testfp.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ //#include //#include //#include //#include #include "FpIndication.h" #include "FpRequest.h" class FpIndication : public FpIndicationWrapper { public: uint32_t cnt; void incr_cnt(){ if (++cnt == 1) exit(0); } void added ( float a ) { fprintf(stderr, "Result=%f\n", a); incr_cnt(); } FpIndication(unsigned int id) : FpIndicationWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { FpIndication indication(IfcNames_FpIndicationH2S); FpRequestProxy *device = new FpRequestProxy(IfcNames_FpRequestS2H); float a = 1.0, b = 0.5; device->add(a, b); // wait for answer sleep(10); } ================================================ FILE: tests/guard/GuardTest.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF ::*; interface MemServer; method Action myMethod(Bool rc); endinterface // Warning: "GuardTest.bsv", line 34, column 9: (G0010) // Rule "dbgrRule" was treated as more urgent than "toprule". Conflicts: // "dbgrRule" cannot fire before "toprule": // calls to myFlag.write vs. myFlag.read // "toprule" cannot fire before "dbgrRule": // calls to myFlag.write vs. myFlag.read module mkGuardTestBench(Empty); FIFOF#(Bool) fifo <- mkFIFOF1; Reg#(Bool) myFlag <- mkReg(False); rule dbgrRule if (myFlag); myFlag <= False; endrule rule toprule; if (fifo.first && !myFlag) myFlag <= fifo.first; endrule endmodule // this version does not generate the extra warning module mkGuardTestBenchNonAgressive(Empty); FIFOF#(Bool) fifo <- mkFIFOF1; Reg#(Bool) myFlag <- mkReg(False); rule dbgrRule if (myFlag); myFlag <= False; endrule rule toprule if (!myFlag); if (fifo.first) myFlag <= fifo.first; endrule endmodule ================================================ FILE: tests/guard/Makefile ================================================ CONNECTALDIR?=../.. run: guardTestBench #./guardTestBench guardTestBench: GuardTest.bsv mkdir -p obj bsc --show-schedule -aggressive-conditions \ -sim -info-dir obj -bdir obj -p +:$(CONNECTALDIR)/lib/bsv -g mkGuardTestBench -u $< bsc --show-schedule -sim -info-dir obj -bdir obj -e mkGuardTestBench -o guardTestBench clean: rm -rf guardTestBench* mkGuardTestBench.* model_mkGuardTestBench.* dump.vcd obj ================================================ FILE: tests/guard/gtest.c ================================================ #include int main() { return 0; } ================================================ FILE: tests/ipcperf/IpcTest.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; interface IpcTestIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface IpcTestRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface IpcTest; interface IpcTestRequest request; endinterface typedef struct { Bit#(16) a; Bit#(16) b; } IpcTestPair deriving (Bits); module mkIpcTest#(IpcTestIndication indication)(IpcTest); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(IpcTestPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule interface IpcTestRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(IpcTestPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: tests/ipcperf/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = IpcTestRequest:IpcTest.request H2S_INTERFACES = IpcTest:IpcTestIndication BSVFILES = IpcTest.bsv CPPFILES=testipctest.cpp ## for testing fpgamake: FPGAMAKE_CONNECTALFLAGS += -P mkIpcTestIndicationProxySynth -P mkIpcTestRequestWrapperMemPortalPipes include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/ipcperf/testipctest.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include "IpcTestIndication.h" #include "IpcTestRequest.h" #include "GeneratedTypes.h" #include #include "drivers/zynqportal/zynqportal.h" #include #define LOOP_COUNT 5 IpcTestRequestProxy *ipcTestRequestProxy = 0; static int silent; static int flag_heard; static sem_t sem_heard; static pthread_mutex_t mutex_heard; PortalPoller *poller = 0; static int use_mutex = 0; static int use_inline = 0; pthread_t threaddata; class IpcTestIndication : public IpcTestIndicationWrapper { public: virtual void heard(uint32_t v) { if (!silent) fprintf(stderr, "heard an ipcTest: %d\n", v); flag_heard++; if (use_mutex) pthread_mutex_unlock(&mutex_heard); else sem_post(&sem_heard); } virtual void heard2(uint16_t v1, uint16_t v2) {} IpcTestIndication(unsigned int id, PortalPoller *poller) : IpcTestIndicationWrapper(id, poller) {} }; static void run_test(void) { #define PCYC_LEN 20 int i; uint64_t pcyc[PCYC_LEN]; uint64_t lastp = 0; memset(pcyc, 0, sizeof(pcyc)); pcyc[0] = portalCycleCount(); flag_heard = 0; pcyc[3] = portalCycleCount(); ipcTestRequestProxy->say(22); pcyc[8] = portalCycleCount(); if (use_inline) { while (!flag_heard) { poller->event(); } pcyc[9] = pcyc[8]; pcyc[12] = pcyc[8]; pcyc[17] = pcyc[8]; } else { if (use_mutex) pthread_mutex_lock(&mutex_heard); else sem_wait(&sem_heard); if (ipcTestRequestProxy->pint.fpga_fd >= 0) { PortalInterruptTime inttime; ioctl(ipcTestRequestProxy->pint.fpga_fd, PORTAL_INTERRUPT_TIME, &inttime); pcyc[9] = (((uint64_t)inttime.msb)<<32) | ((uint64_t)inttime.lsb); } pcyc[12] = poll_return_time; // time after poll() returns pcyc[17] = poll_enter_time; // time poll() reentered } pcyc[18] = portalCycleCount(); for (i = 0; i < PCYC_LEN; i++) if (pcyc[i]) { if (i) printf(" %d:%5lld;", i, (long long)(pcyc[i] - lastp)); lastp = pcyc[i]; } printf("\n"); } int main(int argc, const char **argv) { int i; poller = new PortalPoller(); IpcTestIndication ipcTestIndication(IfcNames_IpcTestIndicationH2S, poller); ipcTestRequestProxy = new IpcTestRequestProxy(IfcNames_IpcTestRequestS2H); pthread_mutex_lock(&mutex_heard); sem_init(&sem_heard, 0, 0); poller->start(); run_test(); printf("turn off printf in responder\n"); silent = 1; for (i = 0; i < LOOP_COUNT; i++) run_test(); printf("now try as mutex\n"); use_mutex = 1; for (i = 0; i < LOOP_COUNT; i++) run_test(); use_mutex = 0; struct sched_param sched_param; int sched_policy; pthread_getschedparam(pthread_self(), &sched_policy, &sched_param); sched_param.sched_priority = sched_get_priority_max(SCHED_RR); pthread_setschedparam(pthread_self(), SCHED_RR, &sched_param); printf("[%s:%d] scheduling policy changed to SCHED_RR\n", __FUNCTION__, __LINE__); for (i = 0; i < LOOP_COUNT; i++) run_test(); printf("disable interrupts for ipcTestIndication\n"); poller->stop(); printf("now try inline\n"); use_inline = 1; for (i = 0; i < LOOP_COUNT; i++) run_test(); printf("[%s:%d] end\n", __FUNCTION__, __LINE__); return 0; } ================================================ FILE: tests/ipcperf/vc707_floorplan.xdc ================================================ startgroup create_pblock pblock_ep7 resize_pblock pblock_ep7 -add {SLICE_X184Y54:SLICE_X221Y166 DSP48_X18Y22:DSP48_X19Y65 RAMB18_X12Y22:RAMB18_X14Y65 RAMB36_X12Y11:RAMB36_X14Y32} add_cells_to_pblock pblock_ep7 [get_cells [list host_ep7]] -clear_locs set_property HD.PARTPIN_RANGE {SLICE_X185Y54:SLICE_X186Y166} [get_pins host_ep7/*] set_property CONTAIN_ROUTING true [get_pblocks pblock_ep7] endgroup startgroup create_pblock pblock_pciehost resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X173Y197 DSP48_X9Y22:DSP48_X16Y77 RAMB18_X7Y22:RAMB18_X10Y77 RAMB36_X7Y11:RAMB36_X10Y38} add_cells_to_pblock pblock_pciehost [get_cells [list host_pciehost]] -clear_locs set_property HD.PARTPIN_RANGE {SLICE_X112Y55:SLICE_X113Y197} [get_pins host_pciehost/*] set_property HD.PARTPIN_RANGE {SLICE_X172Y55:SLICE_X173Y197} [get_pins host_pciehost/*pci_re*] set_property HD.PARTPIN_RANGE {SLICE_X172Y55:SLICE_X173Y197} [get_pins host_pciehost/*pci*] set_property CONTAIN_ROUTING true [get_pblocks pblock_pciehost] endgroup # startgroup # create_pblock pblock_pciehost # resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X221Y197 DSP48_X9Y22:DSP48_X19Y77 RAMB18_X7Y22:RAMB18_X14Y77 RAMB36_X7Y11:RAMB36_X14Y38} # add_cells_to_pblock pblock_pciehost [get_cells [list host]] -clear_locs # set_property HD.PARTPIN_RANGE {SLICE_X112Y55:SLICE_X113Y197} [get_pins host/*] # endgroup ================================================ FILE: tests/memcpy_manysglists/Makefile ================================================ CONNECTALDIR?=../.. MEMCPYDIR=$(CONNECTALDIR)/examples/memcpy INTERFACES = MemcpyRequest MemcpyIndication BSVFILES = $(MEMCPYDIR)/Memcpy.bsv Top.bsv CPPFILES=testmemcpy.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memcpy_manysglists/Top.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import SpecialFIFOs::*; import Vector::*; import BuildVector::*; import StmtFSM::*; import FIFO::*; import CtrlMux::*; import Portal::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemServer::*; import ConnectalMMU::*; import ConnectalConfig::*; import MemcpyRequest::*; import MemServerRequest::*; import MMURequest::*; import MemcpyIndication::*; import MemServerIndication::*; import MMUIndication::*; import Memcpy::*; typedef enum {IfcNames_MemcpyIndication, IfcNames_MemcpyRequest, IfcNames_MemServerIndicationH2S, IfcNames_MemServerRequestS2H, IfcNames_MMU0ConfigRequest, IfcNames_MMU0ConfigIndication, IfcNames_MMU1ConfigRequest, IfcNames_MMU1ConfigIndication, IfcNames_MMU2ConfigRequest, IfcNames_MMU2ConfigIndication, IfcNames_MMU3ConfigRequest, IfcNames_MMU3ConfigIndication } IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); MemcpyIndicationProxy memcpyIndicationProxy <- mkMemcpyIndicationProxy(IfcNames_MemcpyIndication); Memcpy memcpy <- mkMemcpy(memcpyIndicationProxy.ifc); MemcpyRequestWrapper memcpyRequestWrapper <- mkMemcpyRequestWrapper(IfcNames_MemcpyRequest,memcpy.request); MMUIndicationProxy hostMMU0ConfigIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMU0ConfigIndication); MMU#(PhysAddrWidth) hostMMU0 <- mkMMU(0, True, hostMMU0ConfigIndicationProxy.ifc); MMURequestWrapper hostMMU0ConfigRequestWrapper <- mkMMURequestWrapper(IfcNames_MMU0ConfigRequest, hostMMU0.request); MMUIndicationProxy hostMMU1ConfigIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMU1ConfigIndication); MMU#(PhysAddrWidth) hostMMU1 <- mkMMU(1, True, hostMMU1ConfigIndicationProxy.ifc); MMURequestWrapper hostMMU1ConfigRequestWrapper <- mkMMURequestWrapper(IfcNames_MMU1ConfigRequest, hostMMU1.request); MMUIndicationProxy hostMMU2ConfigIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMU2ConfigIndication); MMU#(PhysAddrWidth) hostMMU2 <- mkMMU(2, True, hostMMU2ConfigIndicationProxy.ifc); MMURequestWrapper hostMMU2ConfigRequestWrapper <- mkMMURequestWrapper(IfcNames_MMU2ConfigRequest, hostMMU2.request); MMUIndicationProxy hostMMU3ConfigIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMU3ConfigIndication); MMU#(PhysAddrWidth) hostMMU3 <- mkMMU(3, True, hostMMU3ConfigIndicationProxy.ifc); MMURequestWrapper hostMMU3ConfigRequestWrapper <- mkMMURequestWrapper(IfcNames_MMU3ConfigRequest, hostMMU3.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_MemServerIndication); let sgls = vec(hostMMU0,hostMMU1,hostMMU2,hostMMU3); MemServer#(PhysAddrWidth,64,1) dma <- mkMemServer(memcpy.dmaReadClient, memcpy.dmaWriteClient, sgls, hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_MemServerRequest, dma.request); Vector#(12,StdPortal) portals; portals[0] = memcpyRequestWrapper.portalIfc; portals[1] = memcpyIndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = hostMemServerIndicationProxy.portalIfc; portals[4] = hostMMU0ConfigRequestWrapper.portalIfc; portals[5] = hostMMU0ConfigIndicationProxy.portalIfc; portals[6] = hostMMU1ConfigRequestWrapper.portalIfc; portals[7] = hostMMU1ConfigIndicationProxy.portalIfc; portals[8] = hostMMU2ConfigRequestWrapper.portalIfc; portals[9] = hostMMU2ConfigIndicationProxy.portalIfc; portals[10] = hostMMU3ConfigRequestWrapper.portalIfc; portals[11] = hostMMU3ConfigIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = dma.masters; endmodule ================================================ FILE: tests/memcpy_manysglists/testmemcpy.cpp ================================================ /* Copyright (c) 2013 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "dmaManager.h" #include "MemcpyIndication.h" #include "MemcpyRequest.h" sem_t done_sem; int srcAlloc; int dstAlloc; unsigned int *srcBuffer = 0; unsigned int *dstBuffer = 0; int numWords = 16 << 2; size_t alloc_sz = numWords*sizeof(unsigned int); bool memcmp_fail = false; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (unsigned int i = 0; i < len ; i++) { fprintf(stderr, "%02x", (unsigned char)buf[i]); if (i % 32 == 31) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } class MemcpyIndication : public MemcpyIndicationWrapper { public: MemcpyIndication(unsigned int id) : MemcpyIndicationWrapper(id){} virtual void started(){ fprintf(stderr, "started\n"); } virtual void done() { sem_post(&done_sem); fprintf(stderr, "done\n"); memcmp_fail = memcmp(srcBuffer, dstBuffer, alloc_sz); //dump("xxx ", (char*)dstBuffer, alloc_sz); } }; int do_copy(int srcAlloc, int sgl_config_request_id, int sgl_config_indication_id) { MemcpyRequestProxy *device = new MemcpyRequestProxy(IfcNames_MemcpyRequest); MemcpyIndication deviceIndication(IfcNames_MemcpyIndication); DmaManager *dma = platformInit(); //MMURequestProxy *dmap = new MMURequestProxy(sgl_config_request_id); //MMUIndication *hostMMUIndication = new MMUIndication(dma, sgl_config_indication_id); fprintf(stderr, "Main::allocating memory...\n"); size_t dstBytes = alloc_sz; size_t srcBytes = dstBytes; bool first = false; int dstAlloc = portalAlloc(dstBytes, 0); if(!srcAlloc) { srcAlloc = portalAlloc(srcBytes, 0); first = true; } int ref_dstAlloc = dma->reference(dstAlloc); int ref_srcAlloc = dma->reference(srcAlloc); srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcBytes); dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstBytes); for (int i = 0; i < numWords; i++){ if (first) srcBuffer[i] = i; dstBuffer[i] = 0x5a5abeef; } portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); device->startCopy(ref_dstAlloc, ref_srcAlloc, numWords, 16, 1); sem_wait(&done_sem); return dstAlloc; } int main(int argc, const char **argv) { if(sem_init(&done_sem, 1, 0)){ fprintf(stderr, "failed to init done_sem\n"); exit(1); } bool memcmp_fails[4] = {false, false, false, false}; int dst_ref0 = do_copy(0, IfcNames_MMU0ConfigRequest, IfcNames_MMU0ConfigIndication); memcmp_fails[0] = memcmp_fail; int dst_ref1 = do_copy(dst_ref0, IfcNames_MMU1ConfigRequest, IfcNames_MMU1ConfigIndication); memcmp_fails[1] = memcmp_fail; do_copy(dst_ref1, IfcNames_MMU2ConfigRequest, IfcNames_MMU2ConfigIndication); memcmp_fails[2] = memcmp_fail; int dst_ref3 = do_copy(dst_ref3, IfcNames_MMU3ConfigRequest, IfcNames_MMU3ConfigIndication); memcmp_fails[3] = memcmp_fail; fprintf(stderr, "memcpy_manysglists: Done %d %d %d %d\n", memcmp_fails[0], memcmp_fails[1], memcmp_fails[2], memcmp_fails[3]); sleep(2); exit(memcmp_fails[0] | memcmp_fails[1] | memcmp_fails[2] | memcmp_fails[3] ); } ================================================ FILE: tests/memread_err/Makefile ================================================ CONNECTALDIR ?= ../.. S2H_INTERFACES = MemreadRequest:Memread.request H2S_INTERFACES = Memread:MemreadIndication MEM_READ_INTERFACES = cons\(lMemread.dmaClient,nil\) BSVFILES = Memread.bsv CPPFILES=testmemread.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memread_err/Memread.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import StmtFSM::*; import GetPut::*; import ClientServer::*; import ConnectalMemTypes::*; import MemReadEngine::*; import Pipe::*; interface MemreadRequest; method Action startRead(Bit#(32) pointer, Bit#(32) offset, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface Memread; interface MemreadRequest request; interface MemReadClient#(64) dmaClient; endinterface interface MemreadIndication; method Action started(Bit#(32) numWords); method Action readDone(Bit#(32) mismatchCount); endinterface module mkMemread#(MemreadIndication indication) (Memread); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) srcGen <- mkReg(0); Reg#(Bit#(32)) mismatchCount <- mkReg(0); MemReadEngine#(64,64,1,1) re <- mkMemReadEngine; let debug = True; rule check; let v <- toGet(re.readServers[0].data).get; let expectedV = {srcGen+1,srcGen}; let misMatch = v.data != expectedV; if (debug && misMatch) $display("check %h %h", v, expectedV); mismatchCount <= mismatchCount + (misMatch ? 1 : 0); if (srcGen+2 == numWords) begin srcGen <= 0; end else srcGen <= srcGen+2; if (v.last) begin if (debug) $display("finish"); indication.readDone(mismatchCount); end endrule interface dmaClient = re.dmaClient; interface MemreadRequest request; method Action startRead(Bit#(32) rp, Bit#(32) off, Bit#(32) nw, Bit#(32) bl); if (debug) $display("startRead rdPointer=%d offset=%d numWords=%h burstLen=%d", rp, off, nw, bl); indication.started(nw); numWords <= nw; burstLen <= bl; mismatchCount <= 0; srcGen <= 0; let cmd = MemengineCmd{sglId:rp, base:extend(off*4), len:nw*4, burstLen:truncate(bl*4), tag:0}; re.readServers[0].request.put(cmd); endmethod endinterface endmodule ================================================ FILE: tests/memread_err/testmemread.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "dmaManager.h" #include "MemreadRequest.h" #include "MemreadIndication.h" sem_t test_sem; #ifdef PCIE int burstLen = 32; #else int burstLen = 16; #endif #ifndef SIMULATION int numWords = 0x1240000/4; // make sure to allocate at least one entry of each size #else int numWords = 0x1240/4; #endif size_t test_sz = numWords*sizeof(unsigned int); size_t alloc_sz = test_sz; int mismatchCount = 0; void dump(const char *prefix, char *buf, size_t len) { fprintf(stderr, "%s ", prefix); for (unsigned int i = 0; i < (len > 16 ? 16 : len) ; i++) fprintf(stderr, "%02x", (unsigned char)buf[i]); fprintf(stderr, "\n"); } class MemreadIndication : public MemreadIndicationWrapper { public: unsigned int rDataCnt; virtual void readDone(uint32_t v){ fprintf(stderr, "Memread::readDone(%x)\n", v); mismatchCount += v; sem_post(&test_sem); } virtual void started(uint32_t words){ fprintf(stderr, "Memread::started(%x)\n", words); } virtual void rData ( uint64_t v ){ fprintf(stderr, "rData(%08x): ", rDataCnt++); dump("", (char*)&v, sizeof(v)); } MemreadIndication(int id) : MemreadIndicationWrapper(id){} }; int runtest(int argc, const char ** argv) { int test_result = 0; int srcAlloc; unsigned int *srcBuffer = 0; fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); MemreadRequestProxy *device = new MemreadRequestProxy(IfcNames_MemreadRequestS2H); MemreadIndication deviceIndication(IfcNames_MemreadIndicationH2S); DmaManager *dma = platformInit(); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(alloc_sz, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); #ifdef FPGA0_CLOCK_FREQ long req_freq = FPGA0_CLOCK_FREQ; long freq = 0; setClockFrequency(0, req_freq, &freq); fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq); #endif for (int i = 0; i < numWords; i++){ srcBuffer[i] = i; } portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); fprintf(stderr, "ref_srcAlloc=%d\n", ref_srcAlloc); if(true) { fprintf(stderr, "Main::test read %08x\n", numWords); // first attempt should get the right answer device->startRead(ref_srcAlloc, 0, numWords, burstLen); sem_wait(&test_sem); if (mismatchCount) { fprintf(stderr, "Main::first test failed to match %d.\n", mismatchCount); test_result++; // failed } } int err = 5; switch (err){ case 0: { fprintf(stderr, "Main: attempt to use a de-referenced sglist\n"); dma->dereference(ref_srcAlloc); device->startRead(ref_srcAlloc, 0, numWords, burstLen); break; } case 1: { fprintf(stderr, "Main: attempt to use an out-of-range sglist\n"); device->startRead(ref_srcAlloc+32, 0, numWords, burstLen); break; } case 2: { fprintf(stderr, "Main: attempt to use an invalid sglist\n"); device->startRead(ref_srcAlloc+1, 0, numWords, burstLen); break; } case 3: { fprintf(stderr, "Main: attempt to use an invalid mmusel\n"); device->startRead(ref_srcAlloc | (1<<16), 0, numWords, burstLen); break; } case 4: { fprintf(stderr, "Main: attempt to read off the end of the region\n"); device->startRead(ref_srcAlloc, numWords<<2, burstLen, burstLen); break; } default: { device->startRead(ref_srcAlloc, 0, numWords, burstLen); } } sem_wait(&test_sem); if (mismatchCount) { fprintf(stderr, "Main::first test failed to match %d.\n", mismatchCount); test_result++; // failed } return test_result; } int main(int argc, const char **argv) { int ret = runtest(argc, argv); exit(ret ? 1 : 0); } ================================================ FILE: tests/memread_manual/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest:ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClient BSVFILES = ReadTest.bsv CPPFILES=memread_manual_manager.c #CONNECTALFLAGS += -D NO_CPP_PORTAL_CODE -D NO_POLLER_SUPPORT include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memread_manual/ReadTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import BuildVector::*; import GetPut::*; import ClientServer::*; import Pipe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import Pipe::*; import ConnectalConfig::*; interface ReadTestRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numBytes, Bit#(32) burstLen, Bit#(32) iterCnt); endinterface interface ReadTest; interface ReadTestRequest request; interface Vector#(1,MemReadClient#(DataBusWidth)) dmaClient; endinterface interface ReadTestIndication; method Action readDone(Bit#(32) mismatchCount); endinterface module mkReadTest#(ReadTestIndication indication) (ReadTest); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numBytes <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenBytes <- mkReg(0); Reg#(Bit#(32)) itersToFinish <- mkReg(0); Reg#(Bit#(32)) itersToStart <- mkReg(0); Reg#(Bit#(32)) wordsRead <- mkReg(0); Reg#(Bit#(32)) mismatchCounts <- mkReg(0); MemReadEngine#(DataBusWidth,DataBusWidth,1,1) re <- mkMemReadEngine; rule start (itersToStart > 0); $display("Test: request.put"); re.readServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:numBytes, burstLen:burstLenBytes, tag:0}); itersToStart <= itersToStart-1; endrule rule check; let v <- toGet(re.readServers[0].data).get; let rval = wordsRead/4; let expectedV = {rval+1,rval}; let misMatch = v.data != expectedV; mismatchCounts <= mismatchCounts + (misMatch ? 1 : 0); let new_wordsRead = wordsRead + fromInteger(valueOf(DataBusWidth))/8; //$display("Test: check new=%x numBytes=%x wordsRead=%x misMatch=%x read=%x expect=%x", new_wordsRead, numBytes, wordsRead, misMatch, v, expectedV); if (v.last) begin $display("Test: itersToFinish %x", itersToFinish); if (itersToFinish == 1) begin indication.readDone(mismatchCounts); end itersToFinish <= itersToFinish - 1; new_wordsRead = 0; end wordsRead <= new_wordsRead; endrule interface dmaClient = vec(re.dmaClient); interface ReadTestRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nb, Bit#(32) bl, Bit#(32) ic) if (itersToStart == 0 && itersToFinish == 0); $display("startRead pointer=%x numBytes %x burstLen %x iteration %x", rp, nb, bl, ic); pointer <= rp; numBytes <= nb; burstLenBytes <= truncate(bl); itersToFinish <= ic; itersToStart <= ic; mismatchCounts <= 0; wordsRead <= 0; endmethod endinterface endmodule ================================================ FILE: tests/memread_manual/design_vc707.tcl ================================================ ############################################################### ### Tcl Variables ############################################################### #set tclParams [list ... ] set tclParams [list place.closeImportedSites 1 \ hd.StrictContainRouting 1 \ ] #Define location for "Tcl" directory. Defaults to "../Tcl" set tclHome "../../scripts/xilinx/tcl" if {[file exists $tclHome]} { set tclDir $tclHome } elseif {[file exists "./Tcl"]} { set tclDir "./Tcl" } else { error "ERROR: No valid location found for required Tcl scripts. Set \$tclDir in design.tcl to a valid location." } ############################################################### ### Part Variables - Define Device, Package, Speedgrade ############################################################### set device "xc7vx485t" set package "ffg1761" set speed "-2" set part $device$package$speed ############################################################### ### Setup Variables ############################################################### ####flow control set run.topSynth 0 set run.oocSynth 1 set run.tdImpl 1 set run.oocImpl 1 set run.topImpl 1 set run.flatImpl 0 ####Report and DCP controls - values: 0-required min; 1-few extra; 2-all set verbose 1 set dcpLevel 1 ####Output Directories set synthDir "./Synth" set implDir "./Implement" set dcpDir "./Checkpoint" ####Input Directories set srcDir "./vc707" set rtlDir "$srcDir/verilog" set prjDir "$srcDir/prj" set xdcDir "$srcDir/constraints" set coreDir "$srcDir/cores" set netlistDir "$srcDir/netlist" ####Source required Tcl Procs source $tclDir/design_utils.tcl source $tclDir/synth_utils.tcl source $tclDir/impl_utils.tcl source $tclDir/hd_floorplan_utils.tcl ############################################################### ### Top Definition ############################################################### set top "mkPcieTop" add_module $top set_attribute module $top top_level 1 set_attribute module $top vlog [concat [glob $rtlDir/top/*.v] [glob $rtlDir/lib/*.v] ] set_attribute module $top ip [] #set_attribute module $top vlog_headers [glob $rtlDir/top/*Stub.v] set_attribute module $top synth ${run.topSynth} add_implementation $top set_attribute impl $top top $top set_attribute impl $top implXDC [glob $xdcDir/vc707.xdc] set_attribute impl $top impl ${run.topImpl} set_attribute impl $top hd.impl 1 #################################################################### ### OOC Module Definition and OOC Implementation for each instance #################################################################### set module1 "mkPcieHost" add_module $module1 set_attribute module $module1 vlog [concat [glob $rtlDir/lib/*.v] [glob $rtlDir/pciehost/*.v]] set_attribute module $module1 ip [] set_attribute module $module1 synth ${run.oocSynth} set instance "pciehost" add_ooc_implementation $instance set_attribute ooc $instance module $module1 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing set module2 "mkPCIExpressEndpointX7" add_module $module2 set_attribute module $module2 vlog [concat [glob $rtlDir/lib/*.v] [list $rtlDir/ep7/mkPCIExpressEndpointX7.v]] set_attribute module $module2 ip [glob /scratch/jamey/connectal/generated/xilinx/vc707/*/*.xci] set_attribute module $module2 synth ${run.oocSynth} set instance "ep7" add_ooc_implementation $instance set_attribute ooc $instance module $module2 set_attribute ooc $instance inst $instance set_attribute ooc $instance hierInst $instance set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ $xdcDir/${instance}_ooc_timing.xdc \ $xdcDir/${instance}_ooc_budget.xdc \ $xdcDir/${instance}_ooc_optimize.xdc \ ] set_attribute ooc $instance impl ${run.oocImpl} set_attribute ooc $instance preservation routing # set module3 "mkSynthesizeableConnectalTop" # add_module $module3 # set_attribute module $module3 vlog [concat [glob $rtlDir/lib/*.v] [list $rtlDir/portal/mkSynthesizeableConnectalTop.v]] # set_attribute module $module3 ip [] # set_attribute module $module3 synth ${run.oocSynth} # set instance "portalTop" # add_ooc_implementation $instance # set_attribute ooc $instance module $module3 # set_attribute ooc $instance inst $instance # set_attribute ooc $instance hierInst $instance # set_attribute ooc $instance implXDC [list $xdcDir/${instance}_phys.xdc \ # $xdcDir/${instance}_ooc_timing.xdc \ # $xdcDir/${instance}_ooc_budget.xdc \ # $xdcDir/${instance}_ooc_optimize.xdc \ # ] # set_attribute ooc $instance impl ${run.oocImpl} # set_attribute ooc $instance preservation routing #################################################################### ### Create TopDown implementation run #################################################################### set module1File "$synthDir/$module1/${module1}_synth.dcp" set module2File "$synthDir/$module2/${module2}_synth.dcp" #set module3File "$synthDir/$module3/${module3}_synth.dcp" add_implementation TopDown set_attribute impl TopDown top $top set_attribute impl TopDown implXDC [list $xdcDir/floorplan_vc707.xdc $xdcDir/vc707.xdc] set_attribute impl TopDown td.impl 1 set_attribute impl TopDown cores [list $module1File \ $module2File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ [get_attribute module $module2 cores] \ ] set_attribute impl TopDown impl ${run.tdImpl} set_attribute impl TopDown route 0 #################################################################### ### Create Flat implementation run #################################################################### add_implementation Flat set_attribute impl Flat top $top set_attribute impl Flat implXDC [list $xdcDir/${top}_flpn.xdc $xdcDir/vc707.xdc] set_attribute impl Flat cores [list $module1File \ $module2File \ [get_attribute module $top cores] \ [get_attribute module $module1 cores] \ [get_attribute module $module2 cores] \ ] set_attribute impl Flat impl ${run.flatImpl} ######################################################################## ### Task / flow portion ######################################################################## set_property SEVERITY {Warning} [get_drc_checks HDOOC-4] # Build the designs source $tclDir/run.tcl exit ================================================ FILE: tests/memread_manual/kernel/Makefile ================================================ # grep get_pcie_portal_descriptor /proc/kallsyms ###################### Flags for using KC705 ################### #BOARD=kc705 ###################### Flags for using VC707 ################### #BOARD=vc707 ###################### Flags for using zedboard ################## #BOARD=zedboard ###################### Flags for using Bluesim ################### BOARD=bluesim ###################### End of target h/w flags ################### ifeq ($(BOARD),bluesim) HARDWARE_FLAGS=-DBSIM endif export KROOT=/lib/modules/$(shell uname -r)/build CPPDIR=../../../cpp BOARDDIR=../$(BOARD)/jni DRIVERDIR=$(src)/../../../drivers KBUILD_EXTRA_SYMBOLS := $(DRIVERDIR)/pcieportal/Module.symvers $(DRIVERDIR)/portalmem/Module.symvers kernel_exe-y := ../memread_manual_manager.o \ $(BOARDDIR)/MMURequestProxy.o \ $(BOARDDIR)/MMUIndicationWrapper.o \ $(BOARDDIR)/MemServerRequestProxy.o \ $(BOARDDIR)/MemServerIndicationWrapper.o \ $(BOARDDIR)/RtestIndicationWrapper.o \ $(BOARDDIR)/RtestRequestProxy.o \ $(CPPDIR)/portal.o \ $(CPPDIR)/dmaManager.o \ $(CPPDIR)/kernel_module.o ifeq ($(BOARD),bluesim) kernel_exe-y += $(CPPDIR)/sock_utils.o endif obj-m := kernel_exe.o ccflags-y := -I$(src)/.. -I$(DRIVERDIR)/pcieportal -I$(DRIVERDIR)/portalmem -I$(src)/$(CPPDIR) -I$(src)/$(BOARDDIR) $(HARDWARE_FLAGS) -DBOARD_$(BOARD) default: $(MAKE) -C $(KROOT) M=$(PWD) modules clean: $(MAKE) -C $(KROOT) M=$(PWD) clean rm -f $(kernel_exe-y) a.out bsim_relay CURRENTMOD=$(shell lsmod | grep kernel_exe) run: host ifeq ($(BOARD),bluesim) @echo running bsim ../bluesim/bin/bsim& echo $$! >tmp.bluesim.makefile.pid else fpgajtag ../$(BOARD)/bin/mkTop.bin.gz endif ifneq ("$(CURRENTMOD)", "") sudo rmmod kernel_exe endif sudo insmod kernel_exe.ko ifeq ($(BOARD),bluesim) ./bsim_relay kill `cat tmp.bluesim.makefile.pid` #killall bluetcl endif sudo rmmod kernel_exe dmesg | tail -30 @rm -f tmp.bluesim.makefile.pid # # Target for making userspace bsim_relay program CPPDIR=../../../cpp HOSTSOURCES=$(CPPDIR)/bsim_relay.c $(CPPDIR)/sock_utils.c host: $(HOSTSOURCES) ifeq ($(BOARD),bluesim) gcc -o bsim_relay -g -I$(CPPDIR) $(HOSTSOURCES) -lpthread endif ================================================ FILE: tests/memread_manual/memread_manual_manager.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef __KERNEL__ #include // msleep #include #else #include #include #include #include #include #endif #include "dmaManager.h" #include "sock_utils.h" // bsim_poll_interrupt() #include "GeneratedTypes.h" #define MAX_INDARRAY 4 #if defined(BSIM) || defined(BOARD_xsim) #define numBytes 0x1240 #else #define numBytes 0x1240000 // make sure to allocate at least one entry of each size #endif static PortalInternal intarr[MAX_INDARRAY]; static sem_t test_sem; static int burstLen = 16 * sizeof(uint32_t); static DmaManagerPrivate priv; int ReadTestIndicationWrapperreadDone_cb ( struct PortalInternal *p, const uint32_t mismatchCount ) { PORTAL_PRINTF( "ReadTest_readDone(mismatch = %x)\n", mismatchCount); sem_post(&test_sem); return 0; } int MMUIndicationWrapperconfigResp_cb ( struct PortalInternal *p, const uint32_t pointer) { //PORTAL_PRINTF("configResp %x\n", pointer); sem_post(&priv.confSem); return 0; } int MMUIndicationWrapperidResponse_cb ( struct PortalInternal *p, const uint32_t sglId ) { priv.sglId = sglId; sem_post(&priv.sglIdSem); return 0; }; int MMUIndicationWrappererror_cb ( struct PortalInternal *p, const uint32_t code, const uint32_t pointer, const uint64_t offset, const uint64_t extra ) { static int maxnumber = 10; if (maxnumber-- > 0) PORTAL_PRINTF("DmaIndication::dmaError(code=%x, pointer=%x, offset=%"PRIx64" extra=%"PRIx64"\n", code, pointer, offset, extra); return 0; } void manual_event(void) { int i; for (i = 0; i < MAX_INDARRAY; i++) intarr[i].item->event(&intarr[i]); } #ifdef __KERNEL__ DECLARE_COMPLETION(worker_completion); #endif static void *pthread_worker(void *p) { void *rc = NULL; while (1) { #if defined(BSIM) && !defined(__KERNEL__) if (bsim_poll_interrupt()) #endif manual_event(); #ifdef __KERNEL__ msleep(10); if (kthread_should_stop()) break; #else ///////////////////////// userspace version struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000; select(0, NULL, NULL, NULL, &timeout); #endif } #ifdef __KERNEL__ complete(&worker_completion); #endif return rc; } static MMUIndicationCb TestMMUIndication_cbTable = { portal_disconnect, MMUIndicationWrapperidResponse_cb, MMUIndicationWrapperconfigResp_cb, MMUIndicationWrappererror_cb, }; static ReadTestIndicationCb TestReadTestIndication_cbTable = { portal_disconnect, ReadTestIndicationWrapperreadDone_cb, }; int main(int argc, const char **argv) { int srcAlloc; unsigned int *srcBuffer; unsigned int ref_srcAlloc; unsigned int i; pthread_t tid = 0; init_portal_internal(&intarr[0], IfcNames_MMUIndicationH2S, 0, MMUIndication_handleMessage, &TestMMUIndication_cbTable, NULL, NULL, MMUIndication_reqinfo);// fpga1 init_portal_internal(&intarr[1], IfcNames_ReadTestIndicationH2S,DEFAULT_TILE, ReadTestIndication_handleMessage, &TestReadTestIndication_cbTable, NULL, NULL, ReadTestIndication_reqinfo); // fpga2 init_portal_internal(&intarr[2], IfcNames_MMURequestS2H, 0, NULL, NULL, NULL, NULL, MMURequest_reqinfo); // fpga3 init_portal_internal(&intarr[3], IfcNames_ReadTestRequestS2H,DEFAULT_TILE, NULL, NULL, NULL, NULL, ReadTestRequest_reqinfo); // fpga4 sem_init(&test_sem, 0, 0); DmaManager_init(&priv, &intarr[2]); srcAlloc = portalAlloc(numBytes, 0); if (srcAlloc < 0){ PORTAL_PRINTF("portal alloc failed rc=%d\n", srcAlloc); return srcAlloc; } srcBuffer = (unsigned int *)portalMmap(srcAlloc, numBytes); for (i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) srcBuffer[i] = i; portalCacheFlush(srcAlloc, srcBuffer, numBytes, 1); PORTAL_PRINTF( "Main: creating exec thread\n"); if(pthread_create(&tid, NULL, pthread_worker, NULL)){ PORTAL_PRINTF( "error creating exec thread\n"); return -1; } PORTAL_PRINTF( "Test 1: check for match\n"); PORTAL_PRINTF( "Main: before DmaManager_reference(%x)\n", srcAlloc); ref_srcAlloc = DmaManager_reference(&priv, srcAlloc); PORTAL_PRINTF( "Main: starting read %08x\n", numBytes); ReadTestRequest_startRead (&intarr[3], ref_srcAlloc, numBytes, burstLen, 1); PORTAL_PRINTF( "Main: waiting for semaphore1\n"); sem_wait(&test_sem); PORTAL_PRINTF( "Test 2: check that mismatch is detected\n"); srcBuffer[0] = -1; srcBuffer[numBytes/sizeof(srcBuffer[0])/2] = -1; srcBuffer[numBytes/sizeof(srcBuffer[0])-1] = -1; portalCacheFlush(srcAlloc, srcBuffer, numBytes, 1); ReadTestRequest_startRead (&intarr[3], ref_srcAlloc, numBytes, burstLen, 1); PORTAL_PRINTF( "Main: waiting for semaphore2\n"); sem_wait(&test_sem); PORTAL_PRINTF( "Main: all done\n"); #ifdef __KERNEL__ if (tid && !kthread_stop (tid)) { printk("kthread stops"); } wait_for_completion(&worker_completion); #endif #ifdef __KERNEL__ portalmem_dmabuffer_destroy(srcAlloc); #endif return 0; } ================================================ FILE: tests/memread_manual/vc707_floorplan.xdc ================================================ startgroup create_pblock pblock_ep7 resize_pblock pblock_ep7 -add {SLICE_X184Y54:SLICE_X221Y166 DSP48_X18Y22:DSP48_X19Y65 RAMB18_X12Y22:RAMB18_X14Y65 RAMB36_X12Y11:RAMB36_X14Y32} add_cells_to_pblock pblock_ep7 [get_cells [list ep7]] -clear_locs endgroup startgroup create_pblock pblock_pciehost resize_pblock pblock_pciehost -add {SLICE_X112Y55:SLICE_X171Y197 DSP48_X9Y22:DSP48_X16Y77 RAMB18_X7Y22:RAMB18_X10Y77 RAMB36_X7Y11:RAMB36_X10Y38 BUFGCTRL_X0Y16} add_cells_to_pblock pblock_pciehost [get_cells [list pciehost]] -clear_locs endgroup startgroup create_pblock pblock_portalTop resize_pblock pblock_portalTop -add {SLICE_X0Y25:SLICE_X101Y247 DSP48_X0Y10:DSP48_X7Y97 RAMB18_X0Y10:RAMB18_X6Y97 RAMB36_X0Y5:RAMB36_X6Y48} add_cells_to_pblock pblock_portalTop [get_cells [list portalTop]] -clear_locs endgroup ================================================ FILE: tests/memread_manyclients/Makefile ================================================ CONNECTALDIR?=../.. MEMREADDIR=$(CONNECTALDIR)/examples/memread S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest:ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClient BSVFILES = $(MEMREADDIR)/ReadTest.bsv CPPFILES = $(MEMREADDIR)/testmemread.cpp CONNECTALFLAGS += -D NumEngineServers=16 CONNECTALFLAGS += -I$(CONNECTALDIR)/examples/memread include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memread_manyclients/performance.txt ================================================ Memread Manyclients DataBusWidth | BufferSize | NumServers | NumRequests | Utilization | Bandwidth 64 | 256 | 16 | 2 | 0.944658 | 0.995 GB/s 128 | 256 | 16 | 2 | 0.559449 | 1.119 GB/s 128 | 256 | 16 | 4 | locks up 128 | 512 | 8 | 4 | locks up 128 | 512 | 8 | 2 | stalls 128 | 512 | 1 | 2 | ================================================ FILE: tests/memread_manyclients128/Makefile ================================================ CONNECTALDIR?=../.. MEMREADDIR=$(CONNECTALDIR)/examples/memread S2H_INTERFACES = MemreadRequest:Memread.request H2S_INTERFACES = Memread:MemreadIndication MEM_READ_INTERFACES = lMemread.dmaClient BSVFILES = $(MEMREADDIR)/Memread.bsv CPPFILES = $(MEMREADDIR)/testmemread.cpp CONNECTALFLAGS += -D NumEngineServers=8 -D DataBusWidth=128 CONNECTALFLAGS += -I$(CONNECTALDIR)/examples/memread include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memread_manyengines/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = ReadTestRequest:ReadTest.request H2S_INTERFACES = ReadTest\#\(\`NumEngines\):ReadTestIndication MEM_READ_INTERFACES = lReadTest.dmaClients BSVFILES = ReadTest.bsv CPPFILES = ../../examples/memread/testmemread.cpp CONNECTALFLAGS += --bscflags " -D DataBusWidth=128 -D NumEngines=4" CONNECTALFLAGS += -I$(CONNECTALDIR)/examples/memread include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memread_manyengines/ReadTest.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import StmtFSM::*; import GetPut::*; import ClientServer::*; import Pipe::*; import ConnectalMemTypes::*; import MemReadEngine::*; import ConnectalConfig::*; interface ReadTestRequest; method Action startRead(Bit#(32) pointer, Bit#(32) numBytes, Bit#(32) burstLen, Bit#(32) iterCnt); method Action getStateDbg(); endinterface interface ReadTest#(numeric type nClients); interface ReadTestRequest request; interface Vector#(nClients,MemReadClient#(DataBusWidth)) dmaClients; endinterface interface ReadTestIndication; method Action started(Bit#(32) numBytes); method Action reportStateDbg(Bit#(32) streamRdCnt, Bit#(32) mismatchCount); method Action readDone(Bit#(32) mismatchCount); endinterface module mkReadTest#(ReadTestIndication indication) (ReadTest#(4)); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numBytes <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenBytes <- mkReg(0); Reg#(Bit#(32)) itersToStart <- mkReg(0); Reg#(Bit#(32)) startBase <- mkReg(0); Reg#(Bit#(3)) startPtr <- mkReg(0); Reg#(Bit#(3)) finishPtr <- mkReg(0); Reg#(Bit#(32)) mismatchAccum <- mkReg(0); Vector#(4,MemReadEngine#(DataBusWidth,DataBusWidth,1,1)) res <- replicateM(mkMemReadEngine); FIFO#(void) startFifo <- mkFIFO; Vector#(4,Reg#(Bit#(32))) srcGens <- replicateM(mkReg(0)); Vector#(4,Reg#(Bit#(32))) mismatchCounts <- replicateM(mkReg(0)); Vector#(4,FIFO#(void)) doneFifo <- replicateM(mkFIFO); Stmt startStmt = seq startBase <= 0; for(startPtr <= 0; startPtr < 4; startPtr <= startPtr+1) (action let cmd = MemengineCmd{sglId:pointer, base:extend(startBase), len:numBytes, burstLen:truncate(burstLenBytes), tag:0}; res[startPtr].readServers[0].request.put(cmd); startBase <= startBase+numBytes; //$display("start:%d %h %d %h (%d)", startPtr, startBase, numBytes, burstLenBytes*4, itersToStart); endaction); endseq; FSM startFSM <- mkFSM(startStmt); Stmt finishStmt = seq mismatchAccum <= 0; for(finishPtr <= 0; finishPtr < 4; finishPtr <= finishPtr+1) mismatchAccum <= mismatchAccum + mismatchCounts[finishPtr]; indication.readDone(mismatchAccum); //$display("finishStmt: %h", mismatchAccum); endseq; FSM finishFSM <- mkFSM(finishStmt); rule start (itersToStart > 0); startFifo.deq; startFSM.start; itersToStart <= itersToStart-1; endrule rule finish; for(Integer i = 0; i < 4; i=i+1) doneFifo[i].deq; //$display("finish: %d (%d)", i, itersToStart); if (itersToStart == 0) finishFSM.start; else startFifo.enq(?); endrule for(Integer i = 0; i < 4; i=i+1) rule check; let v <- toGet(res[i].readServers[0].data).get; let expectedV = {srcGens[i]+3,srcGens[i]+2,srcGens[i]+1,srcGens[i]}; let misMatch = v.data != expectedV; mismatchCounts[i] <= mismatchCounts[i] + (misMatch ? 1 : 0); if (srcGens[i]+4 == fromInteger(i+1)*(numBytes>>2)) begin //$display("check %d %d", i, srcGens[i]+1); srcGens[i] <= fromInteger(i)*(numBytes>>2); end else srcGens[i] <= srcGens[i]+4; if (v.last) doneFifo[i].enq(?); endrule function MemReadClient#(DataBusWidth) dc(MemReadEngine#(DataBusWidth,DataBusWidth,1,1) re) = re.dmaClient; interface dmaClients = map(dc,res); interface ReadTestRequest request; method Action startRead(Bit#(32) rp, Bit#(32) nb, Bit#(32) bl, Bit#(32) ic); //$display("startRead rdPointer=%d numBytes=%h burstLenBytes=%d itersToStart=%d", rp, nb, bl, ic); indication.started(nb); pointer <= rp; numBytes <= nb; burstLenBytes <= truncate(bl); itersToStart <= ic; for(Integer i = 0; i < 4; i=i+1) begin mismatchCounts[i] <= 0; srcGens[i] <= fromInteger(i)*(nb>>2); end startFifo.enq(?); endmethod method Action getStateDbg(); indication.reportStateDbg(itersToStart, mismatchCounts[0]); endmethod endinterface endmodule ================================================ FILE: tests/memserver_copy/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemcopyRequest:Memcopy.request H2S_INTERFACES = Memcopy:MemcopyIndication MEM_READ_INTERFACES = lMemcopy.readClients MEM_WRITE_INTERFACES = lMemcopy.writeClients BSVFILES = ../memserver_copy/Memcopy.bsv CPPFILES = ../memserver_copy/testmemcopy.cpp CONNECTALFLAGS += -D USE_ACP -P mkConnectalTop include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memserver_copy/Memcopy.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import FIFO::*; import FIFOF::*; import BRAMFIFO::*; import ClientServer::*; import GetPut::*; import ConnectalConfig::*; import ConnectalMemTypes::*; import Pipe::*; import ConfigCounter::*; typedef TDiv#(DataBusWidth,32) WordsPerBeat; interface MemcopyRequest; method Action startCopy(Bit#(32) readPointer, Bit#(32) writePointer, Bit#(32) numWords, Bit#(32) numReqs, Bit#(32) burstLen); endinterface interface MemcopyIndication; method Action copyDone(Bit#(32) v); method Action copyProgress(Bit#(32) v); endinterface interface Memcopy; interface MemcopyRequest request; interface Vector#(1, MemReadClient#(DataBusWidth)) readClients; interface Vector#(1, MemWriteClient#(DataBusWidth)) writeClients; endinterface module mkMemcopy#(MemcopyIndication indication) (Memcopy); Reg#(SGLId) readPointer <- mkReg(0); Reg#(SGLId) writePointer <- mkReg(0); Reg#(Bit#(32)) numReqs <- mkReg(0); Reg#(Bit#(32)) numDone <- mkReg(0); Reg#(Bit#(MemOffsetSize)) reqOffset <- mkReg(0); Reg#(Bit#(3)) tag <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenBytes <- mkReg(0); Reg#(Bit#(32)) srcGens <- mkReg(0); ConfigCounter#(16) counter <- mkConfigCounter(0); FIFO#(MemRequest) readReqFifo <- mkFIFO(); FIFO#(MemRequest) writeReqFifo <- mkFIFO(); FIFO#(MemData#(DataBusWidth)) dataFifo <- mkSizedBRAMFIFO(1024); FIFO#(Bit#(MemTagSize)) doneFifo <- mkFIFO(); let verboseProgress = False; rule startReqRule if (numReqs != 0 && counter.read() <= unpack(extend(burstLenBytes) << 3)); counter.increment(unpack(extend(burstLenBytes))); readReqFifo.enq(MemRequest { sglId: readPointer, offset: reqOffset, burstLen: burstLenBytes, tag: extend(tag) }); writeReqFifo.enq(MemRequest { sglId: writePointer, offset: reqOffset, burstLen: burstLenBytes, tag: extend(tag) }); numReqs <= numReqs - 1; reqOffset <= reqOffset + extend(burstLenBytes); tag <= tag + 1; $display("start numReqs %d offset %d", numReqs, reqOffset); endrule rule finish; let donetag <- toGet(doneFifo).get(); $display("finished num todo=%d", numDone); if (numDone == 1) begin indication.copyDone(0); end numDone <= numDone - 1; if (verboseProgress) indication.copyProgress(extend(donetag)); endrule MemReadClient#(DataBusWidth) readClient = (interface MemReadClient; interface Get readReq = toGet(readReqFifo); interface Put readData; method Action put(MemData#(DataBusWidth) md); dataFifo.enq(md); counter.decrement(fromInteger(valueOf(TDiv#(DataBusWidth,8)))); endmethod endinterface endinterface ); MemWriteClient#(DataBusWidth) writeClient = (interface MemWriteClient; interface Get writeReq = toGet(writeReqFifo); interface Get writeData = toGet(dataFifo); interface Put writeDone = toPut(doneFifo); endinterface ); interface MemcopyRequest request; method Action startCopy(Bit#(32) rp, Bit#(32) wp, Bit#(32) nw, Bit#(32) nreq, Bit#(32) bl); //$dumpvars(); $display("startCopy readPointer=%d writePointer=%d numWords=%d (%d) numReqs=%d burstLen=%d", rp, wp, nw, nreq*bl, nreq, bl); readPointer <= rp; writePointer <= wp; numWords <= nw; burstLenBytes <= truncate(bl); numReqs <= nreq; numDone <= nreq; endmethod endinterface interface readClients = vec(readClient); interface writeClients = vec(writeClient); endmodule ================================================ FILE: tests/memserver_copy/testmemcopy.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "MemcopyIndication.h" #include "MemcopyRequest.h" static void memdump(unsigned char *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printf("\n"); printf("%s: ",title); } printf("%02x ", *p++); i++; len--; } printf("\n"); } static sem_t done_sem; class MemcopyIndication : public MemcopyIndicationWrapper { public: MemcopyIndication(int id) : MemcopyIndicationWrapper(id){} virtual void copyDone ( uint32_t srcGen ){ fprintf(stderr, "Memcopy::writeDone (%08x)\n", srcGen); sem_post(&done_sem); } virtual void copyProgress ( uint32_t numtodo ){ fprintf(stderr, "Memcopy::writeProgress (%08x)\n", numtodo); } }; int main(int argc, const char **argv) { #ifdef SIMULATION size_t alloc_sz = 4*1024; #else size_t alloc_sz = 10*1024*1024; #endif MemcopyRequestProxy *device = new MemcopyRequestProxy(IfcNames_MemcopyRequestS2H); MemcopyIndication deviceIndication(IfcNames_MemcopyIndicationH2S); DmaManager *dma = platformInit(); sem_init(&done_sem, 1, 0); int srcAlloc = portalAlloc(alloc_sz, 0); unsigned int *srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); int dstAlloc = portalAlloc(alloc_sz, 0); unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (size_t i = 0; i < alloc_sz/sizeof(uint32_t); i++) { srcBuffer[i] = 7*i-3; dstBuffer[i] = 0xDEADBEEF; } #ifndef USE_ACP fprintf(stderr, "flushing cache\n"); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); #endif fprintf(stderr, "parent::starting write\n"); unsigned int ref_srcAlloc = dma->reference(srcAlloc); unsigned int ref_dstAlloc = dma->reference(dstAlloc); int burstLenBytes = 32*sizeof(uint32_t); portalTimerStart(0); device->startCopy(ref_srcAlloc, ref_dstAlloc, alloc_sz, alloc_sz / burstLenBytes, burstLenBytes); sem_wait(&done_sem); platformStatistics(); memdump((unsigned char *)dstBuffer, 32, "MEM"); int mismatchCount = 0; for (size_t i = 0; i < alloc_sz/sizeof(uint32_t); i++) { if (dstBuffer[i] != srcBuffer[i]) mismatchCount++; } fprintf(stderr, "%s: done mismatchCount=%d\n", __FUNCTION__, mismatchCount); return (mismatchCount == 0) ? 0 : 1; } ================================================ FILE: tests/memserver_copy128/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemcopyRequest:Memcopy.request H2S_INTERFACES = Memcopy:MemcopyIndication MEM_READ_INTERFACES = lMemcopy.readClients MEM_WRITE_INTERFACES = lMemcopy.writeClients BSVFILES = ../memserver_copy/Memcopy.bsv CPPFILES = ../memserver_copy/testmemcopy.cpp CONNECTALFLAGS += -D USE_ACP -P mkConnectalTop -D DataBusWidth=128 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memserver_copy_slow/Makefile ================================================ include ../memserver_copy/Makefile CONNECTALFLAGS += --mainclockperiod=30 ================================================ FILE: tests/memserver_write/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClients BSVFILES = Memwrite.bsv CPPFILES = testmemwrite.cpp CONNECTALFLAGS += -D USE_ACP -P mkConnectalTop -D BYTE_ENABLES include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memserver_write/Memwrite.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Vector::*; import BuildVector::*; import FIFO::*; import FIFOF::*; import BRAMFIFO::*; import ClientServer::*; import GetPut::*; import ConnectalConfig::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import Pipe::*; import AddressGenerator::*; typedef TDiv#(DataBusWidth,32) WordsPerBeat; interface MemwriteRequest; method Action startWrite(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) numReqs, Bit#(32) burstLen, Bit#(8) byteEnable); endinterface interface MemwriteIndication; method Action writeDone(Bit#(32) v); method Action writeProgress(Bit#(32) v); endinterface interface Memwrite; interface MemwriteRequest request; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaClients; endinterface module mkMemwrite#(MemwriteIndication indication) (Memwrite); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numReqs <- mkReg(0); Reg#(Bit#(32)) numDone <- mkReg(0); Reg#(Bit#(MemOffsetSize)) reqOffset <- mkReg(0); Reg#(Bit#(3)) tag <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(BurstLenSize)) burstLenBytes <- mkReg(0); Reg#(Bit#(32)) srcGens <- mkReg(3); Reg#(Bit#(8)) byteEnable <- mkReg('hff); AddressGenerator#(32, DataBusWidth) addrGenerator <- mkAddressGenerator(); FIFO#(MemRequest) reqFifo <- mkSizedFIFO(4); FIFO#(PhysMemRequest#(32,DataBusWidth)) preqFifo <- mkSizedFIFO(4); FIFO#(MemData#(DataBusWidth)) dataFifo <- mkSizedBRAMFIFO(1024); FIFO#(Bit#(MemTagSize)) doneFifo <- mkSizedFIFO(4); let verboseProgress = False; `ifdef BYTE_ENABLES Bit#(TDiv#(DataBusWidth,8)) firstbe = maxBound; Bit#(TDiv#(DataBusWidth,8)) lastbe = maxBound; // just apply the byteEnable to the first and last 32-bit word of a burst firstbe[3:0] = byteEnable[3:0]; lastbe[valueOf(ByteEnableSize)-1:valueOf(ByteEnableSize)-4] = byteEnable[7:4]; `endif rule start if (numReqs != 0); `ifdef BYTE_ENABLES $display("Memwrite.start firstbe=%h lastbe=%h", firstbe, lastbe); `endif reqFifo.enq(MemRequest { sglId: pointer, offset: reqOffset, burstLen: burstLenBytes, tag: extend(tag) `ifdef BYTE_ENABLES , firstbe: firstbe, lastbe: lastbe `endif }); preqFifo.enq(PhysMemRequest { addr: 0, burstLen: burstLenBytes, tag: extend(tag) `ifdef BYTE_ENABLES , firstbe: firstbe, lastbe: lastbe `endif }); numReqs <= numReqs - 1; reqOffset <= reqOffset + extend(burstLenBytes); tag <= tag + 1; //$display("start numReqs", numReqs); endrule rule preq; let preq <- toGet(preqFifo).get(); addrGenerator.request.put(preq); endrule rule finish; let donetag <- toGet(doneFifo).get(); //$display("finished num todo=%d", numDone); if (numDone == 1) begin indication.writeDone(0); end numDone <= numDone - 1; if (verboseProgress) indication.writeProgress(extend(donetag)); endrule rule src if (numWords != 0); let b <- addrGenerator.addrBeat.get(); function Bit#(32) plusi(Integer i); return srcGens + fromInteger(i); endfunction Vector#(WordsPerBeat, Bit#(32)) v = genWith(plusi); dataFifo.enq(MemData { data: pack(v), tag: b.tag, last: b.last}); srcGens <= srcGens+fromInteger(valueOf(WordsPerBeat)); numWords <= numWords - fromInteger(valueOf(WordsPerBeat)); endrule MemWriteClient#(DataBusWidth) dmaClient = (interface MemWriteClient; interface Get writeReq = toGet(reqFifo); interface Get writeData = toGet(dataFifo); interface Put writeDone = toPut(doneFifo); endinterface ); interface MemwriteRequest request; method Action startWrite(Bit#(32) wp, Bit#(32) nw, Bit#(32) nreq, Bit#(32) bl, Bit#(8) be); //$dumpvars(); $display("startWrite pointer=%d numWords=%d (%d) numReqs=%d burstLen=%d", pointer, nw, nreq*bl, nreq, bl); pointer <= wp; numWords <= nw; burstLenBytes <= truncate(bl); numReqs <= nreq; numDone <= nreq; reqOffset <= 0; srcGens <= 3; byteEnable <= be; endmethod endinterface interface dmaClients = vec(dmaClient); endmodule ================================================ FILE: tests/memserver_write/testmemwrite.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "dmaManager.h" #include "MemwriteIndication.h" #include "MemwriteRequest.h" static void memdump(unsigned char *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printf("\n"); printf("%s: ",title); } printf("%02x ", *p++); i++; len--; } printf("\n"); } static sem_t done_sem; class MemwriteIndication : public MemwriteIndicationWrapper { public: MemwriteIndication(int id) : MemwriteIndicationWrapper(id){} virtual void writeDone ( uint32_t srcGen ){ fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen); sem_post(&done_sem); } virtual void writeProgress ( uint32_t numtodo ){ fprintf(stderr, "Memwrite::writeProgress (%08x)\n", numtodo); } }; MemwriteIndication *deviceIndication; int main(int argc, const char **argv) { #ifdef SIMULATION size_t alloc_sz = 4*1024; #else size_t alloc_sz = 16*1024*1024; #endif MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H); deviceIndication = new MemwriteIndication(IfcNames_MemwriteIndicationH2S); DmaManager *dma = platformInit(); device->pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ //dmap->pint.busyType = BUSY_SPIN; /* spin until request portal 'notFull' */ sem_init(&done_sem, 1, 0); int iters = 2; uint32_t mismatchCount = 0; for (int iter = 0; iter < iters; iter++) { int dstAlloc = portalAlloc(alloc_sz, 1); unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (uint32_t i = 0; i < alloc_sz/sizeof(uint32_t); i++) dstBuffer[i] = 0xDEADBEEF; #ifndef USE_ACP fprintf(stderr, "flushing cache\n"); portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); #endif fprintf(stderr, "parent::starting write\n"); mismatchCount = 0; unsigned int ref_dstAlloc = dma->reference(dstAlloc); fprintf(stderr, "dma->reference %d\n", ref_dstAlloc); int burstLenBytes = 32*sizeof(uint32_t); int byteEnable = (iter == 0) ? 0xFF : 0x5a; portalTimerStart(0); device->startWrite(ref_dstAlloc, alloc_sz, alloc_sz / burstLenBytes, burstLenBytes, byteEnable); sem_wait(&done_sem); platformStatistics(); memdump((unsigned char *)dstBuffer, 32, "MEM"); for (uint32_t i = 0; i < alloc_sz/sizeof(uint32_t); i++) { if (dstBuffer[i] != (i+3)) mismatchCount++; } uint32_t expectedMismatchCount = (byteEnable == 0xff) ? 0 : 2*(alloc_sz / burstLenBytes); fprintf(stderr, "%s: done mismatchCount=%d expected %d\n", __FUNCTION__, mismatchCount, expectedMismatchCount); if (mismatchCount == expectedMismatchCount) mismatchCount=0; fprintf(stderr, "%s: calling munmap\n", __FUNCTION__); int unmapped = munmap(dstBuffer, alloc_sz); if (unmapped != 0) fprintf(stderr, "Failed to unmap dstBuffer errno=%d:%s\n", errno, strerror(errno)); fprintf(stderr, "%s: close\n", __FUNCTION__); close(dstAlloc); fprintf(stderr, "%s: calling dereference\n", __FUNCTION__); dma->dereference(ref_dstAlloc); fprintf(stderr, "%s: after dereference\n", __FUNCTION__); } return (mismatchCount == 0) ? 0 : 1; } ================================================ FILE: tests/memserver_write128/Makefile ================================================ CONNECTALDIR?=../.. MSWDIR=../memserver_write/ S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClients BSVFILES = $(MSWDIR)/Memwrite.bsv CPPFILES = $(MSWDIR)/testmemwrite.cpp CONNECTALFLAGS += -D USE_ACP -P mkConnectalTop -D DataBusWidth=128 -D BYTE_ENABLES include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memtopcie_bluesim/Makefile ================================================ CONNECTALDIR?=../.. MEMREADDIR=$(CONNECTALDIR)/examples/memread INTERFACES = MemreadRequest MemreadIndication BSVFILES = $(MEMREADDIR)/Memread.bsv Top.bsv CPPFILES = $(MEMREADDIR)/testmemread.cpp CONNECTALFLAGS += -D NumEngineServers=16 -D DataBusWidth=128 CONNECTALFLAGS += -I$(CONNECTALDIR)/examples/memread #CONNECTALFLAGS += --bscflags " -show-schedule" include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memtopcie_bluesim/Top.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import SpecialFIFOs::*; import Vector::*; import BuildVector::*; import StmtFSM::*; import FIFO::*; import GetPut::*; import ClientServer::*; import Connectable::*; import PCIE::*; import DefaultValue::*; import MemServer::*; import ConnectalMMU::*; import CtrlMux::*; import Portal::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import ConnectalConfig::*; import MemToPcie::*; import AddressGenerator::*; import MemreadRequest::*; import MemServerRequest::*; import MMURequest::*; import MemreadIndication::*; import MemServerIndication::*; import MMUIndication::*; import Memread::*; typedef enum {IfcNames_MemreadIndicationH2S, IfcNames_MemreadRequestS2H, IfcNames_MemServerIndicationH2S, IfcNames_MemServerRequestS2H, IfcNames_MMURequestS2H, IfcNames_MMUIndicationH2S} IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); MemreadIndicationProxy memreadIndicationProxy <- mkMemreadIndicationProxy(IfcNames_MemreadIndicationH2S); Memread memread <- mkMemread(memreadIndicationProxy.ifc); MemreadRequestWrapper memreadRequestWrapper <- mkMemreadRequestWrapper(IfcNames_MemreadRequestS2H,memread.request); MMUIndicationProxy hostMMUIndicationProxy <- mkMMUIndicationProxy(IfcNames_MMUIndicationH2S); MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, hostMMUIndicationProxy.ifc); MMURequestWrapper hostMMURequestWrapper <- mkMMURequestWrapper(IfcNames_MMURequestS2H, hostMMU.request); MemServerIndicationProxy hostMemServerIndicationProxy <- mkMemServerIndicationProxy(IfcNames_MemServerIndicationH2S); MemServer#(PhysAddrWidth,DataBusWidth,1) dma <- mkMemServer(memread.dmaClient, nil, vec(hostMMU), hostMemServerIndicationProxy.ifc); MemServerRequestWrapper hostMemServerRequestWrapper <- mkMemServerRequestWrapper(IfcNames_MemServerRequestS2H, dma.request); PhysMemMaster#(PhysAddrWidth,DataBusWidth) dma1 = (interface PhysMemMaster; interface PhysMemReadClient read_client; interface Get readReq; method ActionValue#(PhysMemRequest#(PhysAddrWidth)) get() if (False); return ?; endmethod endinterface endinterface interface PhysMemWriteClient write_client; interface Get writeReq; method ActionValue#(PhysMemRequest#(PhysAddrWidth)) get() if (False); return ?; endmethod endinterface endinterface endinterface); Reg#(Bit#(32)) cycles <- mkReg(0); Reg#(Bit#(32)) reqCycles <- mkReg(0); Reg#(Bit#(32)) lastCycle <- mkReg(0); rule count; cycles <= cycles + 1; if (cycles == 1) //$dumpvars(); if (cycles == 10000) $dumpoff(); endrule let my_id = PciId {bus: 4, dev: 2, func: 0}; MemToPcie#(DataBusWidth) memSlaveEngine <- mkMemToPcie(my_id); mkConnection(dma.masters[0], memSlaveEngine.slave); AddressGenerator#(32, DataBusWidth) addrGenerator <- mkAddressGenerator(); FIFO#(TLPData#(16)) tlpFifo <- mkSizedFIFO(1); FIFO#(TLPData#(16)) tlpOutFifo <- mkSizedFIFO(16); rule displayTlp; let tlp <- memSlaveEngine.tlp.request.get(); TLPMemory4DWHeader hdr4dw = unpack(tlp.data); TLPMemoryIO3DWHeader hdr3dw = unpack(tlp.data); let newReqCycles = cycles; Bit#(32) addr = extend(hdr3dw.addr); TLPTag tag = hdr3dw.tag; TLPLength burstLen = hdr3dw.length; if (tlp.sof && hdr4dw.format == MEM_READ_4DW_NO_DATA) begin $display("%d 4dw req %h len=%d %d", cycles-reqCycles, hdr4dw.addr<<2, hdr3dw.length, fromInteger(valueOf(DataBusWidth))); addr = truncate(hdr4dw.addr); tag = hdr4dw.tag; burstLen = hdr4dw.length; end else if (tlp.sof && hdr3dw.format == MEM_READ_3DW_NO_DATA) begin $display("%d 3dw req %h len=%h %d", cycles-reqCycles, hdr3dw.addr<<2, hdr4dw.length, fromInteger(valueOf(DataBusWidth))); end else if (tlp.sof) begin $display("%d sof %h", cycles-reqCycles, tlp.data); end else begin $display("unknown tlp %h", tlp); end addrGenerator.request.put(PhysMemRequest {addr: addr, burstLen: truncate(pack(burstLen<<2)), tag: truncate(tag) }); reqCycles <= newReqCycles; tlpFifo.enq(tlp); TLPData#(16) resptlp; resptlp.sof = True; resptlp.eof = (burstLen == 1); resptlp.be = 16'hffff; resptlp.hit = 0; Vector#(4, Bit#(32)) vec = unpack(0); TLPCompletionHeader completion = defaultValue; completion.format = MEM_WRITE_3DW_DATA; completion.pkttype = COMPLETION; completion.relaxed = hdr3dw.relaxed; completion.nosnoop = hdr3dw.nosnoop; completion.length = hdr3dw.length; completion.tclass = hdr3dw.tclass; completion.cmplid = my_id; completion.tag = truncate(hdr3dw.tag); completion.bytecount = extend(burstLen)*4; completion.reqid = hdr3dw.reqid; completion.loweraddr = getLowerAddr(hdr3dw.addr, hdr3dw.firstbe); completion.data = byteSwap(0); resptlp.data = pack(completion); tlpOutFifo.enq(resptlp); lastCycle <= cycles; $display("%d: gen tlp resp %h burstLen %d", cycles-lastCycle, resptlp, burstLen); endrule rule dataRule; let addrBeat <- addrGenerator.addrBeat.get(); if (addrBeat.last) tlpFifo.deq(); TLPData#(16) resptlp; resptlp.sof = False; resptlp.eof = addrBeat.last; resptlp.be = 16'hffff; resptlp.hit = 0; if (addrBeat.last) begin resptlp.be = 16'hfff0; end Vector#(4, Bit#(32)) vec = unpack(0); resptlp.data = pack(vec); $display(" addr %h", addrBeat.addr << 2); $display("%d: gen tlp data %h last=%d", cycles-lastCycle, resptlp, addrBeat.last); lastCycle <= cycles; tlpOutFifo.enq(resptlp); endrule rule tlpout; let resptlp <- toGet(tlpOutFifo).get(); memSlaveEngine.tlp.response.put(resptlp); endrule Vector#(6,StdPortal) portals; portals[0] = hostMemServerIndicationProxy.portalIfc; portals[1] = memreadIndicationProxy.portalIfc; portals[2] = hostMemServerRequestWrapper.portalIfc; portals[3] = memreadRequestWrapper.portalIfc; portals[4] = hostMMURequestWrapper.portalIfc; portals[5] = hostMMUIndicationProxy.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = vec(dma1); endmodule : mkConnectalTop ================================================ FILE: tests/memwrite_acp/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = Memwrite.bsv CPPFILES = testmemwrite.cpp CONNECTALFLAGS += -D USE_ACP include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memwrite_acp/Memwrite.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFOF::*; import ClientServer::*; import GetPut::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import Pipe::*; import ConnectalConfig::*; interface MemwriteRequest; method Action startWrite(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface MemwriteIndication; method Action writeDone(Bit#(32) v); endinterface interface Memwrite; interface MemwriteRequest request; interface Vector#(1,MemWriteClient#(DataBusWidth)) dmaClient; endinterface module mkMemwrite#(MemwriteIndication indication) (Memwrite); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) srcGens <- mkReg(0); Reg#(Bool) doOnce <- mkReg(False); MemWriteEngine#(DataBusWidth,DataBusWidth,2,1) we <- mkMemWriteEngine; rule start if (doOnce); we.writeServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:truncate(numWords), burstLen:truncate(burstLen), tag:0}); $display("start"); doOnce <= False; endrule rule finish; $display("finish"); let rv <- we.writeServers[0].done.get; indication.writeDone(0); endrule rule src if (numWords != 0); let v = {srcGens+1,srcGens}; we.writeServers[0].data.enq(v); srcGens <= srcGens+2; numWords <= numWords - 8; endrule interface MemwriteRequest request; method Action startWrite(Bit#(32) wp, Bit#(32) nw, Bit#(32) bl); $display("startWrite pointer=%d numWords=%h burstLen=%d", pointer, nw, bl); pointer <= wp; numWords <= nw; burstLen <= bl; doOnce <= True; endmethod endinterface interface MemWriteClient dmaClient = cons(we.dmaClient,nil); endmodule ================================================ FILE: tests/memwrite_acp/testmemwrite.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "MemwriteIndication.h" #include "MemwriteRequest.h" static void memdump(unsigned char *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printf("\n"); printf("%s: ",title); } printf("%02x ", *p++); i++; len--; } printf("\n"); } static sem_t done_sem; class MemwriteIndication : public MemwriteIndicationWrapper { public: MemwriteIndication(int id) : MemwriteIndicationWrapper(id){} virtual void writeDone ( uint32_t srcGen ){ fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen); sem_post(&done_sem); } }; int main(int argc, const char **argv) { size_t alloc_sz = 1024*1024; MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H); MemwriteIndication deviceIndication(IfcNames_MemwriteIndicationH2S); DmaManager *dma = platformInit(); sem_init(&done_sem, 1, 0); int dstAlloc = portalAlloc(alloc_sz, 0); unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (unsigned int i = 0; i < alloc_sz/sizeof(uint32_t); i++) dstBuffer[i] = 0xDEADBEEF; portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "parent::starting write\n"); unsigned int ref_dstAlloc = dma->reference(dstAlloc); device->startWrite(ref_dstAlloc, alloc_sz, 2 * sizeof(uint32_t)); sem_wait(&done_sem); memdump((unsigned char *)dstBuffer, 32, "MEM"); fprintf(stderr, "%s: done\n", __FUNCTION__); } ================================================ FILE: tests/memwrite_manyclients/Makefile ================================================ CONNECTALDIR?=../.. MEMWRITEDIR=$(CONNECTALDIR)/examples/memwrite S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = $(MEMWRITEDIR)/Memwrite.bsv CPPFILES = $(MEMWRITEDIR)/testmemwrite.cpp CONNECTALFLAGS += -D NumEngineServers=16 CONNECTALFLAGS += --bscflags " -show-schedule" #CONNECTALFLAGS += --bscflags " -ddumpschedule" include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memwrite_manyclients128/Makefile ================================================ CONNECTALDIR?=../.. MEMWRITEDIR=$(CONNECTALDIR)/examples/memwrite S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = $(MEMWRITEDIR)/Memwrite.bsv CPPFILES = $(MEMWRITEDIR)/testmemwrite.cpp CONNECTALFLAGS += -D NumEngineServers=8 -D DataBusWidth=128 CONNECTALFLAGS += --bscflags " -show-schedule" #CONNECTALFLAGS += --bscflags " -ddumpschedule" include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memwrite_trivial/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication MEM_WRITE_INTERFACES = lMemwrite.dmaClient BSVFILES = Memwrite.bsv CPPFILES = testmemwrite.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memwrite_trivial/Memwrite.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import FIFOF::*; import ClientServer::*; import GetPut::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import Pipe::*; import ConnectalConfig::*; interface MemwriteRequest; method Action startWrite(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface MemwriteIndication; method Action writeDone(Bit#(32) v); endinterface interface Memwrite; interface MemwriteRequest request; interface Vector#(1,MemWriteClient#(DataBusWidth)) dmaClient; endinterface module mkMemwrite#(MemwriteIndication indication) (Memwrite); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) srcGens <- mkReg(0); Reg#(Bool) doOnce <- mkReg(False); MemWriteEngine#(DataBusWidth,DataBusWidth,2,1) we <- mkMemWriteEngine; rule start if (doOnce); we.writeServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:truncate(numWords), burstLen:truncate(burstLen)}); $display("start"); doOnce <= False; endrule rule finish; $display("finish"); let rv <- we.writeServers[0].done.get; indication.writeDone(0); endrule rule src if (numWords != 0); let v = {srcGens+1,srcGens}; we.writeServers[0].data.enq(v); srcGens <= srcGens+2; numWords <= numWords - 8; endrule interface MemwriteRequest request; method Action startWrite(Bit#(32) wp, Bit#(32) nw, Bit#(32) bl); $display("startWrite pointer=%d numWords=%h burstLen=%d", pointer, nw, bl); pointer <= wp; numWords <= nw; burstLen <= bl; doOnce <= True; endmethod endinterface interface MemWriteClient dmaClient = cons(we.dmaClient,nil); endmodule ================================================ FILE: tests/memwrite_trivial/testmemwrite.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "MemwriteIndication.h" #include "MemwriteRequest.h" static void memdump(unsigned char *p, int len, const char *title) { int i; i = 0; while (len > 0) { if (!(i & 0xf)) { if (i > 0) printf("\n"); printf("%s: ",title); } printf("%02x ", *p++); i++; len--; } printf("\n"); } static sem_t done_sem; class MemwriteIndication : public MemwriteIndicationWrapper { public: MemwriteIndication(int id) : MemwriteIndicationWrapper(id){} virtual void writeDone ( uint32_t srcGen ){ fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen); sem_post(&done_sem); } }; int main(int argc, const char **argv) { size_t alloc_sz = 0x1240; MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H); MemwriteIndication deviceIndication(IfcNames_MemwriteIndicationH2S); DmaManager *dma = platformInit(); sem_init(&done_sem, 1, 0); int dstAlloc = portalAlloc(alloc_sz, 0); unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (unsigned int i = 0; i < alloc_sz/sizeof(uint32_t); i++) dstBuffer[i] = 0xDEADBEEF; portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "parent::starting write\n"); unsigned int ref_dstAlloc = dma->reference(dstAlloc); device->startWrite(ref_dstAlloc, alloc_sz, 2 * sizeof(uint32_t)); sem_wait(&done_sem); memdump((unsigned char *)dstBuffer, 32, "MEM"); fprintf(stderr, "%s: done\n", __FUNCTION__); } ================================================ FILE: tests/memwriteengine_test/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MemwriteRequest:Memwrite.request H2S_INTERFACES = Memwrite:MemwriteIndication #MEM_WRITE_INTERFACES = lMemwrite.dmaClients BSVFILES = Memwrite.bsv CPPFILES = testmemwrite.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/memwriteengine_test/MemWriteEngineTest.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import FIFOF::*; import Vector::*; import GetPut::*; import Connectable::*; import BRAMFIFO::*; import ConnectalMemTypes::*; import AddressGenerator::*; interface MemWriteEngineTest; interface MemWriteServer#(64) dmaServer; // connect this to memwrite engine interface MemWriteClient#(64) dmaClient; // connect this to memserver interface Get#(Bit#(32)) req; interface Get#(Bit#(MemTagSize)) done; interface Get#(Tuple2#(Bit#(32),Bit#(64))) mismatch; endinterface (* synthesize *) module mkMemWriteEngineTest(MemWriteEngineTest); FIFO#(MemRequest) writeReqInFifo <- mkSizedBRAMFIFO(32); FIFO#(MemData#(64)) writeDataInFifo <- mkSizedBRAMFIFO(128); FIFO#(Bit#(MemTagSize)) writeDoneInFifo <- mkSizedBRAMFIFO(32); FIFO#(MemRequest) writeReqOutFifo <- mkSizedBRAMFIFO(32); FIFO#(MemData#(64)) writeDataOutFifo <- mkSizedBRAMFIFO(128); FIFO#(Bit#(MemTagSize)) writeDoneOutFifo <- mkSizedBRAMFIFO(32); AddressGenerator#(32,64) addrGenerator <- mkAddressGenerator(); FIFOF#(Bit#(32)) addrFifo <- mkSizedBRAMFIFOF(32); FIFOF#(Tuple2#(Bit#(32),Bit#(64))) mismatchFifo <- mkSizedBRAMFIFOF(32); FIFOF#(Bit#(MemTagSize)) doneFifo <- mkSizedBRAMFIFOF(32); rule reqRule; let req <- toGet(writeReqInFifo).get(); $display("req: offset=%h burstLen=%d tag=%h", req.offset, req.burstLen, req.tag); //writeReqOutFifo.enq(req); addrGenerator.request.put(PhysMemRequest{addr:truncate(req.offset), burstLen: req.burstLen, tag: req.tag }); addrFifo.enq(truncate(req.offset)); endrule rule dataRule; let b <- addrGenerator.addrBeat.get(); let data <- toGet(writeDataInFifo).get(); let traceAllData = False; if (traceAllData) mismatchFifo.enq(tuple2(b.addr, data.data)); //writeDataOutFifo.enq(data); Vector#(2, Bit#(32)) v = unpack(data.data); if (v[0] != (b.addr>>2) || v[1] != ((b.addr>>2)+1)) begin $display("mismatch: addr=%h data=%h", b.addr, data.data); if (!traceAllData && mismatchFifo.notFull()) mismatchFifo.enq(tuple2(b.addr, data.data)); end if (b.last) writeDoneOutFifo.enq(b.tag); endrule rule doneRule; let done <- toGet(writeDoneInFifo).get(); $display("done: tag=%h", done); writeDoneOutFifo.enq(done); doneFifo.enq(done); endrule interface MemWriteServer dmaServer; interface Put writeReq = toPut(writeReqInFifo); interface Put writeData = toPut(writeDataInFifo); interface Get writeDone = toGet(writeDoneOutFifo); endinterface interface MemWriteClient dmaClient; interface Get writeReq = toGet(writeReqOutFifo); interface Get writeData = toGet(writeDataOutFifo); interface Put writeDone = toPut(writeDoneInFifo); endinterface interface Get req = toGet(addrFifo); interface Get done = toGet(doneFifo); interface Get mismatch = toGet(mismatchFifo); endmodule ================================================ FILE: tests/memwriteengine_test/Memwrite.bsv ================================================ // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import CtrlMux::*; import Vector::*; import FIFOF::*; import ClientServer::*; import GetPut::*; import Connectable::*; import ConnectalMemTypes::*; import MemWriteEngine::*; import Pipe::*; import MemWriteEngineTest::*; interface MemwriteRequest; method Action startWrite(Bit#(32) pointer, Bit#(32) numWords, Bit#(32) burstLen); endinterface interface MemwriteIndication; method Action writeDone(Bit#(32) v); method Action req(Bit#(32) addr); method Action done(Bit#(32) tag); method Action mismatch(Bit#(32) addr, Bit#(64) data); endinterface interface Memwrite; interface MemwriteRequest request; interface Vector#(1,MemWriteClient#(64)) dmaClients; endinterface module mkMemwrite#(MemwriteIndication indication) (Memwrite); Reg#(SGLId) pointer <- mkReg(0); Reg#(Bit#(32)) numWords <- mkReg(0); Reg#(Bit#(32)) burstLen <- mkReg(0); Reg#(Bit#(32)) srcGens <- mkReg(0); Reg#(Bool) doOnce <- mkReg(False); MemWriteEngine#(64,64,2,1) we <- mkMemWriteEngine; MemWriteEngineTest wet <- mkMemWriteEngineTest(); mkConnection(we.dmaClient, wet.dmaServer); rule reqRule; let addr <- wet.req.get(); indication.req(addr); endrule rule doneRule; let tag <- wet.done.get(); indication.done(extend(tag)); endrule rule mismatchRule; match { .addr, .data } <- wet.mismatch.get(); indication.mismatch(addr, data); endrule rule start if (doOnce); we.writeServers[0].request.put(MemengineCmd{sglId:pointer, base:0, len:truncate(numWords), burstLen:truncate(burstLen), tag: 7}); $display("start"); doOnce <= False; endrule rule finish; $display("finish"); let rv <- we.writeServers[0].done.get; indication.writeDone(0); endrule rule src if (numWords != 0); let v = {srcGens+1,srcGens}; we.writeServers[0].data.enq(v); srcGens <= srcGens+2; numWords <= numWords - 8; endrule interface MemwriteRequest request; method Action startWrite(Bit#(32) wp, Bit#(32) nw, Bit#(32) bl); $display("startWrite pointer=%d numWords=%h burstLen=%d", pointer, nw, bl); pointer <= wp; numWords <= nw; burstLen <= bl; doOnce <= True; endmethod endinterface interface Vector dmaClients = cons(wet.dmaClient,nil); endmodule ================================================ FILE: tests/memwriteengine_test/testmemwrite.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "MemwriteIndication.h" #include "MemwriteRequest.h" #define NUMBER_OF_WORDS 0x1240 static sem_t done_sem; class MemwriteIndication : public MemwriteIndicationWrapper { public: MemwriteIndication(int id) : MemwriteIndicationWrapper(id){} virtual void writeDone ( uint32_t srcGen ){ fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen); sem_post(&done_sem); } virtual void req ( uint32_t addr ){ fprintf(stderr, "req.addr=%08x\n", addr); } virtual void done ( uint32_t tag ){ fprintf(stderr, "done.tag=%x\n", tag); } virtual void mismatch ( const uint32_t addr, const uint64_t data ){ fprintf(stderr, "mismatch: addr=%08x data = %08lx %08lx\n", addr, (long)((data >> 32) & 0xFFFFFFFF), (long)(data & 0xFFFFFFFF)); } }; int main(int argc, const char **argv) { size_t alloc_sz = NUMBER_OF_WORDS; MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H); MemwriteIndication deviceIndication(IfcNames_MemwriteIndicationH2S); #if (NumberOfMasters != 0) DmaManager *dma = platformInit(); #endif sem_init(&done_sem, 1, 0); #if (NumberOfMasters != 0) int dstAlloc = portalAlloc(alloc_sz, 0); unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz); for (unsigned int i = 0; i < alloc_sz/sizeof(uint32_t); i++) dstBuffer[i] = 0xDEADBEEF; portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1); fprintf(stderr, "parent::starting write\n"); unsigned int ref_dstAlloc = dma->reference(dstAlloc); #else unsigned int ref_dstAlloc = 1; #endif device->startWrite(ref_dstAlloc, alloc_sz, 2 * sizeof(uint32_t)); sem_wait(&done_sem); fprintf(stderr, "%s: done\n", __FUNCTION__); sleep(2); return 0; } ================================================ FILE: tests/method/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MethodRequest:Method.request BSVFILES = Method.bsv CPPFILES= mtest.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/method/Method.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import LinkerLib::*; import GetPut::*; import FIFO::*; interface Inverter; method Action m(Bool v); method ActionValue#(Bool) mInv; endinterface (* synthesize *) module mkInverter(Inverter); PutInverter#(Bool) inv <- mkPutInverter(); method Action m(Bool v); inv.mod.put(v); endmethod method ActionValue#(Bool) mInv; let v <- inv.inverse.get; return v; endmethod endmodule interface Invertm; method Action actual(Bool v); endinterface (* synthesize *) module mkInvertm(Invertm); FIFO#(Bool) fifo <- mkFIFO; method Action actual(Bool v); fifo.enq(v); endmethod endmodule interface MethodRequest; method Action startme; endinterface interface Method; interface MethodRequest request; endinterface (* synthesize *) module mkMethod(Method); Inverter einst <- mkInverter; Invertm eact <- mkInvertm; FIFO#(Bool) fifo <- mkFIFO; rule invoke_rule; einst.m(fifo.first); endrule PutInverter#(Bool) conn <- mkPutInverter(); rule connect_rule1; let v <- einst.mInv; conn.mod.put(v); endrule rule connect_rule2; let v <- conn.inverse.get(); eact.actual(v); endrule interface MethodRequest request; method Action startme; endmethod endinterface endmodule ================================================ FILE: tests/method/mtest.cpp ================================================ #include int main() { return 0; } ================================================ FILE: tests/mifo/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = MifoTestRequest:MifoTest.request H2S_INTERFACES = MifoTest:MifoTestIndication BSVFILES = MifoTest.bsv CPPFILES=testmifo.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/mifo/MifoTest.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFO::*; import MIFO::*; import Pipe::*; import Vector::*; interface MifoTestIndication; method Action mifo32(Bit#(32) v); method Action mifo64(Bit#(32) v, Bit#(32) w); method Action fimo64(Bit#(32) v0, Bit#(32) v1); method Action fimo96(Bit#(32) v0, Bit#(32) v1, Bit#(32) v2); method Action fimo128(Bit#(32) v0, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); endinterface interface MifoTestRequest; method Action mifo32(Bit#(32) n, Bit#(32) v0, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); method Action mifo64(Bit#(32) n, Bit#(32) v0, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); method Action fimo32(Bit#(32) v0); endinterface interface MifoTest; interface MifoTestRequest request; endinterface module mkMifoTest#(MifoTestIndication indication)(MifoTest); MIFO#(4,1,4,Bit#(32)) mifo1 <- mkMIFO(); MIFO#(4,2,4,Bit#(32)) mifo2 <- mkMIFO(); FIMO#(1,4,4,Bit#(32)) fimo1 <- mkFIMO(); FIMO#(1,4,4,Bit#(32)) fimo2 <- mkFIMO(); FIMO#(1,4,4,Bit#(32)) fimo3 <- mkFIMO(); rule mifo32out if (mifo1.deqReady()); let v = mifo1.first(); mifo1.deq(); indication.mifo32(v[0]); endrule rule mifo64out if (mifo2.deqReady()); let v = mifo2.first(); mifo2.deq(); indication.mifo64(v[0], v[1]); endrule rule fimo64out; let v = fimo1.out[2].first(); fimo1.out[2].deq(); $display("fimo32 value: %h", v); indication.fimo64(v[0], v[1]); endrule rule fimo96out; let v = fimo2.out[3].first(); fimo2.out[3].deq(); $display("fimo96 value: %h", v); indication.fimo96(v[0], v[1], v[2]); endrule rule fimo128out; let v = fimo3.out[4].first(); fimo3.out[4].deq(); $display("fimo128 value: %h", v); indication.fimo128(v[0], v[1], v[2], v[3]); endrule interface MifoTestRequest request; method Action mifo32(Bit#(32) n, Bit#(32) v0, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); Vector#(4, Bit#(32)) vec = newVector(); vec[0] = v0; vec[1] = v1; vec[2] = v2; vec[3] = v3; mifo1.enq(unpack(truncate(n)), vec); endmethod method Action mifo64(Bit#(32) n, Bit#(32) v0, Bit#(32) v1, Bit#(32) v2, Bit#(32) v3); Vector#(4, Bit#(32)) vec = newVector(); vec[0] = v0; vec[1] = v1; vec[2] = v2; vec[3] = v3; mifo2.enq(unpack(truncate(n)), vec); endmethod method Action fimo32(Bit#(32) v); Vector#(1, Bit#(32)) vec = replicate(v); fimo1.in.enq(vec); fimo2.in.enq(vec); fimo3.in.enq(vec); endmethod endinterface endmodule ================================================ FILE: tests/mifo/testmifo.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "MifoTestIndication.h" #include "MifoTestRequest.h" static uint32_t vs[4] = { 22, 0, 1, 2}; class MifoTestIndication : public MifoTestIndicationWrapper { public: uint32_t cnt; void incr_cnt(){ if (++cnt == (32+0)) exit(0); } virtual void mifo32(uint32_t a) { uint32_t ea = vs[cnt % 4]; fprintf(stderr, "mifo32(%d expected %d)\n", a, ea); assert(a == ea); incr_cnt(); } virtual void mifo64(uint32_t a, uint32_t b) { uint32_t ea = vs[cnt % 4]; uint32_t eb = vs[(cnt+1) % 4]; fprintf(stderr, "mifo64(%d,%d) expected (%d,%d)\n", a, b, ea, eb); assert(a == ea); assert(b == eb); incr_cnt(); incr_cnt(); } virtual void fimo64(uint32_t a, uint32_t b) { uint32_t ea = 68; uint32_t eb = 47; fprintf(stderr, "fimo64(%d,%d) expected (%d,%d)\n", a, b, ea, eb); assert(a == ea); assert(b == eb); //incr_cnt(); //incr_cnt(); } virtual void fimo96(uint32_t a, uint32_t b, uint32_t c) { uint32_t ea = 68; uint32_t eb = 47; uint32_t ec = 22; fprintf(stderr, "fimo96(%d,%d,%d) expected (%d,%d,%d)\n", a, b, c, ea, eb, ec); assert(a == ea); assert(b == eb); assert(c == ec); //incr_cnt(); //incr_cnt(); } virtual void fimo128(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { uint32_t ea = 68; uint32_t eb = 47; uint32_t ec = 22; uint32_t ed = 23; fprintf(stderr, "fimo128(%d,%d,%d,%d) expected (%d,%d,%d,%d)\n", a, b, c, d, ea, eb, ec, ed); assert(a == ea); assert(b == eb); assert(c == ec); assert(d == ed); //incr_cnt(); //incr_cnt(); } MifoTestIndication(unsigned int id) : MifoTestIndicationWrapper(id), cnt(0){} }; int main(int argc, const char **argv) { MifoTestIndication indication(IfcNames_MifoTestIndicationH2S); MifoTestRequestProxy *device = new MifoTestRequestProxy(IfcNames_MifoTestRequestS2H); device->fimo32(68); sleep(1); device->fimo32(47); sleep(1); device->fimo32(22); sleep(1); device->fimo32(23); sleep(1); fprintf(stderr, "Main::calling mifo32(%d)\n", 22); device->mifo32(4, 22, 0, 1, 2); sleep(1); device->mifo32(1, 22, 7, 7, 7); sleep(1); device->mifo32(1, 0, 7, 7, 7); sleep(1); device->mifo32(1, 1, 7, 7, 7); sleep(1); device->mifo32(1, 2, 7, 7, 7); sleep(1); device->mifo32(2, 22, 0, 7, 7); sleep(1); device->mifo32(2, 1, 2, 7, 7); sleep(1); device->mifo32(1, 22, 7, 7, 7); sleep(1); device->mifo32(3, 0, 1, 2, 7); sleep(1); device->mifo64(4, 22, 0, 1, 2); sleep(1); device->mifo64(1, 22, 7, 7, 7); sleep(1); device->mifo64(1, 0, 7, 7, 7); sleep(1); device->mifo64(1, 1, 7, 7, 7); sleep(1); device->mifo64(1, 2, 7, 7, 7); sleep(1); device->mifo64(1, 22, 7, 7, 7); sleep(1); device->mifo64(3, 0, 1, 2, 7); sleep(1); device->mifo64(3, 22, 0, 1, 7); sleep(1); device->mifo64(1, 2, 7, 7, 7); sleep(1); fprintf(stderr, "Main::about to go to sleep\n"); while(true){sleep(2);} } ================================================ FILE: tests/nandsim_manual/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = NandCfgRequest:NandSim.request H2S_INTERFACES = NandSim:NandCfgIndication MEM_READ_INTERFACES = lNandSim.readClient MEM_WRITE_INTERFACES = lNandSim.writeClient NANDLIB = ../../lib/nandsim BSVFILES = $(NANDLIB)/bsv/NandSim.bsv CPPFILES=testnandsim_test.cpp #CPPFILES=testnandsim.cpp #CPPFILES=nandsim_manual.c include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/nandsim_manual/kernel/Makefile ================================================ # grep get_pcie_portal_descriptor /proc/kallsyms ###################### Flags for using KC705 ################### #BOARD=kc705 ###################### Flags for using VC707 ################### #BOARD=vc707 ###################### Flags for using zedboard ################## #BOARD=zedboard ###################### Flags for using Bluesim ################### BOARD=bluesim ###################### End of target h/w flags ################### ifeq ($(BOARD),bluesim) HARDWARE_FLAGS=-DBSIM endif export KROOT=/lib/modules/$(shell uname -r)/build CPPDIR=../../../cpp BOARDDIR=../$(BOARD)/jni DRIVERDIR=$(src)/../../../drivers KBUILD_EXTRA_SYMBOLS := $(DRIVERDIR)/pcieportal/Module.symvers $(DRIVERDIR)/portalmem/Module.symvers kernel_exe-y := ../nandsim_manual.o \ $(BOARDDIR)/DmaConfigProxy.o \ $(BOARDDIR)/DmaIndicationWrapper.o \ $(BOARDDIR)/NandSimIndicationWrapper.o \ $(BOARDDIR)/NandSimRequestProxy.o \ $(CPPDIR)/portal.o \ $(CPPDIR)/dmaManager.o \ $(CPPDIR)/kernel_module.o ifeq ($(BOARD),bluesim) kernel_exe-y += $(CPPDIR)/sock_utils.o endif obj-m := kernel_exe.o ccflags-y := -I$(src)/.. -I$(DRIVERDIR)/pcieportal -I$(DRIVERDIR)/portalmem -I$(src)/$(CPPDIR) -I$(src)/$(BOARDDIR) $(HARDWARE_FLAGS) -DBOARD_$(BOARD) default: $(MAKE) -C $(KROOT) M=$(PWD) modules clean: $(MAKE) -C $(KROOT) M=$(PWD) clean rm -f $(kernel_exe-y) a.out bsim_relay CURRENTMOD=$(shell lsmod | grep kernel_exe) run: host ifeq ($(BOARD),bluesim) @echo running bsim ../bluesim/bin/bsim& echo $$! >tmp.bluesim.makefile.pid else fpgajtag ../$(BOARD)/bin/mkTop.bin.gz endif ifneq ("$(CURRENTMOD)", "") sudo rmmod kernel_exe #sudo rmmod bdbm_drv endif sudo insmod kernel_exe.ko #sudo insmod bdbm_drv.ko ifeq ($(BOARD),bluesim) ./bsim_relay kill `cat tmp.bluesim.makefile.pid` #killall bluetcl endif sudo rmmod kernel_exe #sudo rmmod bdbm_drv dmesg | tail -30 @rm -f tmp.bluesim.makefile.pid # # Target for making userspace bsim_relay program CPPDIR=../../../cpp HOSTSOURCES=$(CPPDIR)/bsim_relay.c $(CPPDIR)/sock_utils.c host: $(HOSTSOURCES) ifeq ($(BOARD),bluesim) gcc -o bsim_relay -g -I$(CPPDIR) $(HOSTSOURCES) -lpthread endif ================================================ FILE: tests/nandsim_manual/nandsim_manual.c ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef __KERNEL__ #include // msleep #include #else #include #include #include #include #include #endif #include "dmaManager.h" #include "sock_utils.h" // bsim_poll_interrupt() #include "GeneratedTypes.h" #define MAX_INDARRAY 4 static PortalInternal intarr[MAX_INDARRAY]; static sem_t test_sem; #ifndef SIMULATION #define numWords 0x1240000/4 // make sure to allocate at least one entry of each size #else #define numWords 0x124000/4 #endif static long alloc_sz = numWords*sizeof(unsigned int); static DmaManagerPrivate priv; size_t numBytes = 1 << 12; size_t nandBytes = 1 << 24; int NandCfgIndicationWrappereraseDone_cb( struct PortalInternal *p, const uint32_t tag ) { PORTAL_PRINTF( "NandCfg_eraseDone(tag = %x)\n", tag); sem_post(&test_sem); return 0; } int NandCfgIndicationWrapperwriteDone_cb( struct PortalInternal *p, const uint32_t tag ) { PORTAL_PRINTF( "NandCfg_writeDone(tag = %x)\n", tag); sem_post(&test_sem); return 0; } int NandCfgIndicationWrapperreadDone_cb( struct PortalInternal *p, const uint32_t tag ) { PORTAL_PRINTF( "NandCfg_readDone(tag = %x)\n", tag); sem_post(&test_sem); return 0; } int NandCfgIndicationWrapperconfigureNandDone_cb( struct PortalInternal *p ) { PORTAL_PRINTF( "NandCfg_NandDone\n"); sem_post(&test_sem); return 0; } int DmaIndicationWrapperconfigResp_cb( struct PortalInternal *p, const uint32_t pointer ) { PORTAL_PRINTF("DmaIndication_configResp(physAddr=%x)\n", pointer); sem_post(&priv.confSem); return 0; } int DmaIndicationWrapperaddrResponse_cb( struct PortalInternal *p, const uint64_t physAddr ) { PORTAL_PRINTF("DmaIndication_addrResponse(physAddr=%"PRIx64")\n", physAddr); return 0; } int DmaIndicationWrapperreportStateDbg_cb( struct PortalInternal *p, const DmaDbgRec rec ) { PORTAL_PRINTF("reportStateDbg: {x:%08x y:%08x z:%08x w:%08x}\n", rec.x,rec.y,rec.z,rec.w); sem_post(&priv.dbgSem); return 0; } int DmaIndicationWrapperreportMemoryTraffic_cb( struct PortalInternal *p, const uint64_t words ) { //PORTAL_PRINTF("reportMemoryTraffic: words=%"PRIx64"\n", words); priv.mtCnt = words; sem_post(&priv.mtSem); return 0; } int DmaIndicationWrapperdmaError_cb( struct PortalInternal *p, const uint32_t code, const uint32_t pointer, const uint64_t offset, const uint64_t extra ) { PORTAL_PRINTF("DmaIndication::dmaError(code=%x, pointer=%x, offset=%"PRIx64" extra=%"PRIx64"\n", code, pointer, offset, extra); return 0; } void manual_event(void) { int i; for(i = 0; i < MAX_INDARRAY; i++) event_hardware(&intarr[i]); } #ifdef __KERNEL__ DECLARE_COMPLETION(worker_completion); #endif static void *pthread_worker(void *p) { void *rc = NULL; while(1) { #if defined(BSIM) && !defined(__KERNEL__) if(bsim_poll_interrupt()) #endif manual_event(); #ifdef __KERNEL__ msleep(10); if(kthread_should_stop()) { PORTAL_PRINTF("pthread_worker ends\n"); break; } #else ///////////////////////// userspace version struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000; select(0, NULL, NULL, NULL, &timeout); #endif } #ifdef __KERNEL__ complete(&worker_completion); #endif return rc; } int main(int argc, const char **argv) { int srcAlloc; int nandAlloc; unsigned int *srcBuffer; unsigned int ref_srcAlloc; unsigned int ref_nandAlloc; int rc = 0; unsigned int i; pthread_t tid = 0; init_portal_internal(&intarr[0], IfcNames_DmaIndicationH2S, DEFAULT_TILE, DmaIndication_handleMessage, NULL, NULL, NULL, DmaIndication_reqinfo); init_portal_internal(&intarr[1], IfcNames_NandCfgIndicationH2S, DEFAULT_TILE, NandCfgIndication_handleMessage, NULL, NULL, NULL, NandCfgIndication_reqinfo); init_portal_internal(&intarr[2], IfcNames_MMURequestS2H, DEFAULT_TILE, NULL, NULL, NULL, NULL, MMURequest_reqinfo); init_portal_internal(&intarr[3], IfcNames_NandCfgRequestS2H, DEFAULT_TILE, NULL, NULL, NULL, NULL, NandCfgRequest_reqinfo); sem_init(&test_sem, 0, 0); DmaManager_init(&priv, &intarr[2]); srcAlloc = portalAlloc(alloc_sz, 0); if(rc){ PORTAL_PRINTF("portal alloc failed rc=%d\n", rc); return rc; } PORTAL_PRINTF( "Main: creating exec thread\n"); if(pthread_create(&tid, NULL, pthread_worker, NULL)){ PORTAL_PRINTF( "error creating exec thread\n"); return -1; } srcBuffer = (unsigned int *)portalMmap(srcAlloc, alloc_sz); for(i = 0; i < numWords; i++) { srcBuffer[i] = i; } PORTAL_PRINTF("Test 1: check for operations\n"); portalCacheFlush(srcAlloc, srcBuffer, alloc_sz, 1); PORTAL_PRINTF("Main: before DmaManager_reference(%u)\n", srcAlloc); ref_srcAlloc = DmaManager_reference(&priv, srcAlloc); nandAlloc = portalAlloc(nandBytes, 0); ref_nandAlloc = DmaManager_reference(&priv, nandAlloc); PORTAL_PRINTF("Main::configure NAND fd=%d ref=%d\n", nandAlloc, ref_nandAlloc); NandCfgRequest_configureNand(&intarr[3], ref_nandAlloc, nandBytes); sem_wait(&test_sem); PORTAL_PRINTF( "Main::starting write - begin %08lx\n", (long)numBytes); NandCfgRequest_startWrite(&intarr[3], ref_srcAlloc, 0, 0, numBytes, 16); PORTAL_PRINTF( "Main:: wait for semaphore\n"); sem_wait(&test_sem); for(i = 0; i < numWords; i++) { srcBuffer[i] = 0; } PORTAL_PRINTF( "Main::starting read %08lx\n", (long)numBytes); NandCfgRequest_startRead(&intarr[3], ref_srcAlloc, 0, 0, numBytes, 16); sem_wait(&test_sem); PORTAL_PRINTF("read: %u %u %u %u\n", srcBuffer[0], srcBuffer[1], srcBuffer[2], srcBuffer[3]); PORTAL_PRINTF( "Main::starting erase %08lx\n", (long)numBytes); NandCfgRequest_startErase(&intarr[3], 0, numBytes); sem_wait(&test_sem); PORTAL_PRINTF( "Main::starting read %08lx\n", (long)numBytes); NandCfgRequest_startRead(&intarr[3], ref_srcAlloc, 0, 0, numBytes, 16); sem_wait(&test_sem); PORTAL_PRINTF("read: %u %u %u %u\n", srcBuffer[0], srcBuffer[1], srcBuffer[2], srcBuffer[3]); PORTAL_PRINTF("\n\nTest 2: check for match\n"); { unsigned long loop = 0; unsigned long match = 0, mismatch = 0; while(loop < nandBytes) { unsigned int i; for(i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) { srcBuffer[i] = loop+i; } /*PORTAL_PRINTF("Main::starting write ref=%d, len=%08lx (%lu)\n", ref_srcAlloc, (long)numBytes, loop);*/ NandCfgRequest_startWrite(&intarr[3], ref_srcAlloc, 0, loop, numBytes, 16); sem_wait(&test_sem); loop+=numBytes; } loop = 0; while(loop < nandBytes) { unsigned int i; /*PORTAL_PRINTF("Main::starting read %08lx (%lu)\n", (long)numBytes, loop);*/ NandCfgRequest_startRead(&intarr[3], ref_srcAlloc, 0, loop, numBytes, 16); sem_wait(&test_sem); for(i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) { if(srcBuffer[i] != loop+i) { PORTAL_PRINTF("Main::mismatch [%08lx] != [%08lx]\n", (long)loop+i, (long)srcBuffer[i]); mismatch++; } else { match++; } } loop+=numBytes; } PORTAL_PRINTF("Main::Summary: match=%lu mismatch:%lu (%lu) (%f percent)\n", match, mismatch, match+mismatch, (float)mismatch/(float)(match+mismatch)*100.0); } PORTAL_PRINTF( "Main: all done\n"); #ifdef __KERNEL__ if(tid && !kthread_stop(tid)) { PORTAL_PRINTF("kthread stops\n"); } wait_for_completion(&worker_completion); #endif PORTAL_PRINTF("Main: ends\n"); return 0; } ================================================ FILE: tests/nandsim_manual/testnandsim.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "NandCfgIndication.h" #include "NandCfgRequest.h" int srcAlloc, nandAlloc; unsigned int *srcBuffer = 0; size_t numBytes = 1 << 12; size_t nandBytes = 1 << 24; class NandCfgIndication : public NandCfgIndicationWrapper { public: unsigned int rDataCnt; virtual void readDone(uint32_t v){ fprintf(stderr, "NandCfg::readDone v=%x\n", v); sem_post(&sem); } virtual void writeDone(uint32_t v){ fprintf(stderr, "NandCfg::writeDone v=%x\n", v); sem_post(&sem); } virtual void eraseDone(uint32_t v){ fprintf(stderr, "NandCfg::eraseDone v=%x\n", v); sem_post(&sem); } virtual void configureNandDone(){ fprintf(stderr, "NandCfg::configureNandDone\n"); sem_post(&sem); } NandCfgIndication(int id) : NandCfgIndicationWrapper(id) { sem_init(&sem, 0, 0); } void wait() { fprintf(stderr, "NandCfg::wait for semaphore\n"); sem_wait(&sem); } private: sem_t sem; }; int main(int argc, const char **argv) { unsigned int srcGen = 0; NandCfgRequestProxy *device = 0; NandCfgIndication *deviceIndication = 0; fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); device = new NandCfgRequestProxy(IfcNames_NandCfgRequestS2H); deviceIndication = new NandCfgIndication(IfcNames_NandCfgIndicationH2S); DmaManager *dma = platformInit(); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(numBytes, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, numBytes); fprintf(stderr, "fd=%d, srcBuffer=%p\n", srcAlloc, srcBuffer); for (unsigned int i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) srcBuffer[i] = srcGen++; portalCacheFlush(srcAlloc, srcBuffer, numBytes, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); sleep(1); unsigned int ref_srcAlloc = dma->reference(srcAlloc); nandAlloc = portalAlloc(nandBytes, 0); int ref_nandAlloc = dma->reference(nandAlloc); fprintf(stderr, "NAND alloc fd=%d ref=%d\n", nandAlloc, ref_nandAlloc); device->configureNand(ref_nandAlloc, nandBytes); deviceIndication->wait(); fprintf(stderr, "Main::starting write ref=%d, len=%08lx\n", ref_srcAlloc, (long)numBytes); device->startWrite(ref_srcAlloc, 0, 0, numBytes, 16); deviceIndication->wait(); fprintf(stderr, "Main::starting read %08lx\n", (long)numBytes); device->startRead(ref_srcAlloc, 0, 0, numBytes, 16); deviceIndication->wait(); fprintf(stderr, "Main::starting erase %08lx\n", (long)numBytes); device->startErase(0, numBytes); deviceIndication->wait(); fprintf(stderr, "Main::starting read %08lx\n", (long)numBytes); device->startRead(ref_srcAlloc, 0, 0, numBytes, 16); deviceIndication->wait(); return 0; } ================================================ FILE: tests/nandsim_manual/testnandsim_test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "NandCfgIndication.h" #include "NandCfgRequest.h" int srcAlloc, nandAlloc; unsigned int *srcBuffer = 0; size_t numBytes = 1 << 12; #ifndef BOARD_bluesim size_t nandBytes = 1 << 24; #else size_t nandBytes = 1 << 14; #endif class NandCfgIndication : public NandCfgIndicationWrapper { public: unsigned int rDataCnt; virtual void readDone(uint32_t v){ fprintf(stderr, "NandCfg::readDone v=%x\n", v); sem_post(&sem); } virtual void writeDone(uint32_t v){ fprintf(stderr, "NandCfg::writeDone v=%x\n", v); sem_post(&sem); } virtual void eraseDone(uint32_t v){ fprintf(stderr, "NandCfg::eraseDone v=%x\n", v); sem_post(&sem); } virtual void configureNandDone(){ fprintf(stderr, "NandCfg::configureNandDone\n"); sem_post(&sem); } NandCfgIndication(int id) : NandCfgIndicationWrapper(id) { sem_init(&sem, 0, 0); } void wait() { fprintf(stderr, "NandCfg::wait for semaphore\n"); sem_wait(&sem); } private: sem_t sem; }; int main(int argc, const char **argv) { unsigned int srcGen = 0; NandCfgRequestProxy *device = 0; NandCfgIndication *deviceIndication = 0; fprintf(stderr, "chamdoo-test\n"); fprintf(stderr, "Main::%s %s\n", __DATE__, __TIME__); device = new NandCfgRequestProxy(IfcNames_NandCfgRequestS2H); deviceIndication = new NandCfgIndication(IfcNames_NandCfgIndicationH2S); DmaManager *dma = platformInit(); fprintf(stderr, "Main::allocating memory...\n"); srcAlloc = portalAlloc(numBytes, 0); srcBuffer = (unsigned int *)portalMmap(srcAlloc, numBytes); fprintf(stderr, "fd=%d, srcBuffer=%p\n", srcAlloc, srcBuffer); for (unsigned int i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) srcBuffer[i] = srcGen++; portalCacheFlush(srcAlloc, srcBuffer, numBytes, 1); fprintf(stderr, "Main::flush and invalidate complete\n"); sleep(1); unsigned int ref_srcAlloc = dma->reference(srcAlloc); nandAlloc = portalAlloc(nandBytes, 0); int ref_nandAlloc = dma->reference(nandAlloc); fprintf(stderr, "NAND alloc fd=%d ref=%d\n", nandAlloc, ref_nandAlloc); device->configureNand(ref_nandAlloc, nandBytes); deviceIndication->wait(); /* do tests */ unsigned long loop = 0; unsigned long match = 0, mismatch = 0; while (loop < nandBytes) { unsigned int i; for (i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) { srcBuffer[i] = loop+i; } fprintf(stderr, "Main::starting write ref=%d, len=%08lx (%lu)\n", ref_srcAlloc, (long)numBytes, loop); device->startWrite(ref_srcAlloc, 0, loop, numBytes, 16); deviceIndication->wait(); loop+=numBytes; } loop = 0; while (loop < nandBytes) { unsigned int i; fprintf(stderr, "Main::starting read %08lx (%lu)\n", (long)numBytes, loop); device->startRead(ref_srcAlloc, 0, loop, numBytes, 16); deviceIndication->wait(); for (i = 0; i < numBytes/sizeof(srcBuffer[0]); i++) { if (srcBuffer[i] != loop+i) { fprintf(stderr, "Main::mismatch [%08lx] != [%08lx]\n", (long)loop+i, (long)srcBuffer[i]); mismatch++; } else { match++; } } loop+=numBytes; } /* end */ fprintf(stderr, "Main::Summary: match=%lu mismatch:%lu (%lu) (%f percent)\n", match, mismatch, match+mismatch, (float)mismatch/(float)(match+mismatch)*100.0); return (mismatch > 0); } ================================================ FILE: tests/nvme_core/string_search.cpp ================================================ #include //#include "jsoncpp/json/json.h" #include #include #include #include #include #include #include #include // BlocksPerRequest #include "nvme.h" #include "mp.h" enum MsgFromSoftwareTag { REQ_Loopback, REQ_Needle, REQ_MpNext, REQ_Clear, REQ_Opcode, REQ_StartBlock, REQ_NumBlocks, REQ_Start }; struct MsgFromSoftware { int data : 24; MsgFromSoftwareTag tag : 8; }; enum MsgToSoftwareTag { RESP_Loopback=1, RESP_LocDone=2, RESP_TransferDone=3 }; struct MsgToSoftware { int data : 24; MsgToSoftwareTag tag : 8; }; union Msg { MsgToSoftware to; MsgFromSoftware from; int bits; }; static Nvme *nvme; void sendMessage(MsgFromSoftwareTag tag, int data, bool last=false) { Msg msg; msg.from.tag = tag; msg.from.data = data; fprintf(stderr, "%s:%d tag=%x data=%06x last=%d msg=%08x\n", __FUNCTION__, __LINE__, tag, data, last, msg.bits); nvme->messageFromSoftware(msg.bits, last); } int main(int argc, char * const *argv) { nvme = new Nvme(); int opt; const char *filename = 0; int source_fd = -1; const char *needle = "needle"; int dotrace = 0; int dowrite = 0; while ((opt = getopt(argc, argv, "n:w:t")) != -1) { switch (opt) { case 'n': needle = optarg; break; case 't': dotrace = 1; break; case 'w': filename = optarg; dowrite = 1; break; } } if (dowrite) { struct stat statbuf; int rc = stat(filename, &statbuf); if (rc < 0) { fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno)); return rc; } } sleep(1); nvme->setup(); sleep(1); nvme->allocIOQueues(0); int needle_len = strlen(needle); int border[needle_len+1]; compute_borders(nvme->needleBuffer.buffer(), border, needle_len); compute_MP_next(nvme->needleBuffer.buffer(), (struct MP *)nvme->mpNextBuffer.buffer(), needle_len); nvme->needleBuffer.cacheInvalidate(0, 1); // flush the whole thing nvme->mpNextBuffer.cacheInvalidate(0, 1); // flush the whole thing fprintf(stderr, "CSTS %08x\n", nvme->read32( 0x1c)); int startBlock = 100000; // base and extent of test file in SSD int blocksPerRequest = BlocksPerRequest; //12*BlocksPerRequest; int numBlocks = 1*blocksPerRequest; // 55; //8177; sendMessage(REQ_Loopback, 22); // send needle and mpNext for (int i = 0; i < needle_len; i++) { struct MP *mpNext = (struct MP *)nvme->mpNextBuffer.buffer(); bool last = ((i + 1) == needle_len); fprintf(stderr, "needle[%d]=%02x mpNext[%d]=%2x.%02x\n", i, needle[i], i, mpNext[i].index, mpNext[i].x); sendMessage(REQ_Needle, needle[i], last); sendMessage(REQ_MpNext, *(int *)&mpNext[i], last); } // send search command sendMessage(REQ_Opcode, nvme_read); sendMessage(REQ_StartBlock, startBlock); sendMessage(REQ_NumBlocks, numBlocks); sendMessage(REQ_Start, needle_len); sleep(10); nvme->dumpTrace(); return 0; } ================================================ FILE: tests/nvme_strstr/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = NvmeRequest:NvmeSearch.request NvmeDriverRequest:NvmeSearch.driverRequest MemServerPortalRequest:NvmeSearch.bramRequest StringSearchRequest:NvmeSearch.searchRequest H2S_INTERFACES = NvmeSearch:NvmeIndication,NvmeDriverIndication,NvmeTrace,MemServerPortalIndication,StringSearchResponse MEM_READ_INTERFACES = lNvmeSearch.dmaReadClient MEM_WRITE_INTERFACES = lNvmeSearch.dmaWriteClient BSVPATH = $(CONNECTALDIR)/lib/strstr/bsv BSVFILES = $(CONNECTALDIR)/lib/nvme/bsv/NvmeIfc.bsv StringSearchIfc.bsv $(CONNECTALDIR)/bsv/ConnectalConfig.bsv CPPFILES += $(CONNECTALDIR)/lib/nvme/cpp/nvme.cpp main.cpp CPPFILES += $(CONNECTALDIR)/cpp/DmaBuffer.cpp CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/nvme/cpp ifeq ($(BOARD),miniitx100) PINOUT_FILE += nvme.json CONNECTALFLAGS += -D PcieDataBusWidth=128 CONNECTALFLAGS += -D USE_ACP CONNECTALFLAGS += -D TOP_SOURCES_PORTAL_CLOCK CONNECTALFLAGS += --mainclockperiod=8 else PINOUT_FILE += fmc.json CONNECTALFLAGS += -D PcieDataBusWidth=128 endif CONNECTALFLAGS += -D BlocksPerRequest=8 PIN_TYPE = NvmePins PIN_TYPE_INCLUDE = NvmePins AUTOTOP = --interface pins:NvmeSearch.pins AUTOTOP += --portalclock=lNvmeSearch.portalClockSource CONNECTALFLAGS += --cxxflags=-std=c++11 CONNECTALFLAGS += --stl=c++_static CONNECTALFLAGS += -I $(CONNECTALDIR)/lib/strstr/cpp CONNECTALFLAGS += --bsvpath=../spikehw CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/axi_pcie_rp/axi_pcie_rp.xci CONNECTALFLAGS += --implconstraint=nvme.xdc #CONNECTALFLAGS += -DNVME_ACCELERATOR_INTERFACE=1 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/nvme_strstr/NvmeSearch.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Arbitrate::*; import BRAM::*; import BuildVector::*; import Clocks::*; import Connectable::*; import FIFOF::*; import Gearbox::*; import GetPut::*; import Probe::*; import StmtFSM::*; import Vector::*; import AddressGenerator::*; import AxiBits::*; import AxiStream::*; import ConnectalClocks::*; import ConnectalConfig::*; import DefaultValue::*; import GearboxGetPut::*; import HostInterface::*; import MemReadEngine::*; import ConnectalMemTypes::*; import PhysMemSlaveFromBram::*; import Pipe::*; import TraceMemClient::*; import XilinxCells::*; import MPEngine::*; import Nvme::*; import NvmeIfc::*; import NvmePins::*; import StringSearchIfc::*; interface NvmeSearch; interface NvmeRequest request; interface NvmeDriverRequest driverRequest; interface MemServerPortalRequest bramRequest; interface StringSearchRequest searchRequest; interface NvmeTrace trace; interface NvmePins pins; interface Vector#(2, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaWriteClient; `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource; `endif endinterface typedef enum { Loopback, Needle, MpNext, Clear, Opcode, StartBlock, NumBlocks, Start } MsgFromSoftwareTag deriving (Bits,Eq); typedef struct { MsgFromSoftwareTag tag; Bit#(24) data; } MsgFromSoftware deriving (Bits); typedef enum { Loopback=1, LocDone=2, TransferDone=3 } MsgToSoftwareTag deriving (Bits,Eq); typedef struct { MsgToSoftwareTag tag; Bit#(24) data; } MsgToSoftware deriving (Bits); (* synthesize *) module mkSearchAcceleratorClient(NvmeAcceleratorClient); Reg#(Bit#(32)) dataCounter <- mkReg(0); FIFOF#(Bit#(32)) dataLengthFifo <- mkFIFOF(); Reg#(Bit#(24)) needleLenReg <- mkReg(0); MPStreamEngine#(PcieDataBusWidth,DataBusWidth) mpEngine <- mkMPStreamEngine(); FIFOF#(MemData#(32)) msgFromSoftwareFifo <- mkFIFOF(); FIFOF#(MemData#(32)) msgToSoftwareFifo <- mkFIFOF(); FIFOF#(MemDataF#(PcieDataBusWidth)) dataFromNvmeFifo <- mkFIFOF(); FIFOF#(MemDataF#(PcieDataBusWidth)) dataToNvmeFifo <- mkFIFOF(); FIFOF#(Bit#(SizeOf#(NvmeIoCommand))) requestFifo <- mkFIFOF(); FIFOF#(Bit#(SizeOf#(NvmeIoResponse))) responseFifo <- mkFIFOF(); mkConnection(toPipeOut(dataFromNvmeFifo), mpEngine.haystack); Reg#(Bit#(8)) opcode <- mkReg(extend(pack(NvmeRead))); Reg#(Bit#(32)) startBlock <- mkReg(0); Reg#(Bit#(32)) numBlocks <- mkReg(0); Reg#(Bit#(16)) requestId <- mkReg(0); let inmsgTagProbe <- mkProbe(); let inmsgDataProbe <- mkProbe(); let outmsgTagProbe <- mkProbe(); let outmsgDataProbe <- mkProbe(); let responseProbe <- mkProbe(); rule rl_msg_from_software; let md <- toGet(msgFromSoftwareFifo).get(); MsgFromSoftware msg = unpack(truncate(md.data)); inmsgTagProbe <= msg.tag; inmsgDataProbe <= msg.data; case (msg.tag) matches Loopback: begin MsgToSoftware outmsg = MsgToSoftware { tag: Loopback, data: msg.data }; outmsgTagProbe <= outmsg.tag; outmsgDataProbe <= outmsg.data; msgToSoftwareFifo.enq(MemData { data: extend(pack(outmsg)), last: md.last }); end Needle: mpEngine.needle.enq(MemDataF { data: extend(msg.data), first: False, last: md.last, tag: 0 }); MpNext: mpEngine.mpNext.enq(MemDataF { data: extend(msg.data), first: False, last: md.last, tag: 0 }); Clear: mpEngine.clear(); Opcode: opcode <= truncate(msg.data); StartBlock: startBlock <= extend(msg.data); NumBlocks: numBlocks <= extend(msg.data); Start: begin mpEngine.start(extend(msg.data)); needleLenReg <= msg.data; requestFifo.enq(pack(NvmeIoCommand { opcode: opcode, flags: 0, requestId: requestId, startBlock: extend(startBlock), numBlocks: numBlocks, dsm: 'h71 // FIXME copied value from nvme.cpp, but where did this come from? })); requestId <= requestId + 1; end endcase endrule rule rl_response; let r <- toGet(responseFifo).get(); NvmeIoResponse response = unpack(r); Bit#(8) sct = truncate(response.statusCodeType); responseProbe <= response.statusCode; MsgToSoftware outmsg = MsgToSoftware { tag: TransferDone, data: { sct, response.statusCode }}; outmsgTagProbe <= outmsg.tag; outmsgDataProbe <= outmsg.data; msgToSoftwareFifo.enq(MemData { data: extend(pack(outmsg)), last: True }); endrule rule rl_match; let loc <- toGet(mpEngine.locdone).get(); MsgToSoftware outmsg = MsgToSoftware { tag: LocDone, data: truncate(pack(loc)) }; outmsgTagProbe <= outmsg.tag; outmsgDataProbe <= outmsg.data; msgToSoftwareFifo.enq(MemData { data: extend(pack(outmsg)), last: (loc == -1) }); endrule AxiStreamSlave#(32) msgFromSoftwareStream <- mkAxiStream(msgFromSoftwareFifo); AxiStreamMaster#(32) msgToSoftwareStream <- mkAxiStream(msgToSoftwareFifo); AxiStreamSlave#(PcieDataBusWidth) dataFromNvmeStream <- mkAxiStream(dataFromNvmeFifo); AxiStreamMaster#(PcieDataBusWidth) dataToNvmeStream <- mkAxiStream(dataToNvmeFifo); AxiStreamMaster#(SizeOf#(NvmeIoCommand)) requestStream <- mkAxiStream(requestFifo); AxiStreamSlave#(SizeOf#(NvmeIoResponse)) responseStream <- mkAxiStream(responseFifo); interface AxiStreamSlave msgFromSoftware = msgFromSoftwareStream; interface AxiStreamMaster msgToSoftware = msgToSoftwareStream; interface AxiStreamSlave dataFromNvme = dataFromNvmeStream; interface AxiStreamMaster dataToNvme = dataToNvmeStream; interface AxiStreamMaster request = requestStream; interface AxiStreamSlave response = responseStream; endmodule module mkNvmeSearch#(NvmeIndication ind, NvmeDriverIndication driverInd, NvmeTrace trace, MemServerPortalIndication bramIndication, StringSearchResponse searchIndication)(NvmeSearch); let nvme <- mkNvme(ind, driverInd, trace, bramIndication); MemReadEngine#(DataBusWidth,DataBusWidth,2,3) re <- mkMemReadEngine(); `ifndef NVME_ACCELERATOR_INTERFACE Reg#(Bit#(32)) dataCounter <- mkReg(0); FIFOF#(Bit#(32)) dataLengthFifo <- mkFIFOF(); FIFOF#(MemDataF#(PcieDataBusWidth)) fifoToMp <- mkFIFOF(); let needleLenReg <- mkReg(0); MPStreamEngine#(PcieDataBusWidth,DataBusWidth) mpEngine <- mkMPStreamEngine(); mkConnection(re.readServers[0].data, mpEngine.needle); mkConnection(re.readServers[1].data, mpEngine.mpNext); mkConnection(toPipeOut(fifoToMp), mpEngine.haystack); Reg#(Bool) firstReg <- mkReg(True); rule rl_count_data_to_mp; let data <- toGet(nvme.dataFromNvme).get(); if (dataLengthFifo.notEmpty()) begin data.last = (dataCounter+fromInteger(valueOf(PcieDataBusWidth)/8)) >= dataLengthFifo.first; let md = MemDataF {data: data.data, last: data.last, first: firstReg, tag: 0}; firstReg <= data.last; fifoToMp.enq(md); end dataCounter <= dataCounter + 1; endrule rule rl_locdone; let loc <- toGet(mpEngine.locdone).get(); searchIndication.strstrLoc(pack(loc)); endrule `endif interface NvmeRequest request = nvme.request; interface NvmeDriverRequest driverRequest = nvme.driverRequest; interface MemServerPortalRequest bramRequest = nvme.bramRequest; interface NvmeTrace trace = nvme.trace; interface NvmePins pins = nvme.pins; interface StringSearchRequest searchRequest; method Action setSearchString(Bit#(32) needleSglId, Bit#(32) mpNextSglId, Bit#(32) needleLen); `ifndef NVME_ACCELERATOR_INTERFACE mpEngine.clear(); needleLenReg <= needleLen; let burstLen = fromInteger(valueOf(DataBusWidth)/8); let mask = burstLen - 1; needleLen = (needleLen + mask) & ~mask; re.readServers[0].request.put(MemengineCmd {sglId: needleSglId, base: 0, burstLen: burstLen, len: needleLen, tag: 0}); re.readServers[1].request.put(MemengineCmd {sglId: mpNextSglId, base: 0, burstLen: burstLen, len: needleLen*4, tag: 0}); `endif endmethod method Action startSearch(Bit#(32) haystackLen); `ifndef NVME_ACCELERATOR_INTERFACE mpEngine.start(needleLenReg); dataLengthFifo.enq(haystackLen); `endif endmethod endinterface `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource = nvme.portalClockSource; `endif interface Vector dmaReadClient = append(nvme.dmaReadClient, vec(re.dmaClient)); interface Vector dmaWriteClient = nvme.dmaWriteClient; endmodule ================================================ FILE: tests/nvme_strstr/StringSearchIfc.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface StringSearchRequest; method Action setSearchString(Bit#(32) needleSglId, Bit#(32) mpNextSglId, Bit#(32) needleLen); method Action startSearch(Bit#(32) searchLen); endinterface interface StringSearchResponse; method Action strstrLoc(Bit#(32) loc); endinterface ================================================ FILE: tests/nvme_strstr/fmc.json ================================================ { "pcie_refclk_p": { "FMC": "FMC_GBTCLK_P[00]" }, "pcie_refclk_n": { "FMC": "FMC_GBTCLK_N[00]" }, "RST_N_pcie_sys_reset_n": { "FMC": "FMC_LA_P[00]", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } } ================================================ FILE: tests/nvme_strstr/main.cpp ================================================ #include //#include "jsoncpp/json/json.h" #include #include #include #include #include #include #include #include "ConnectalProjectConfig.h" #include "nvme.h" #include "mp.h" class StringSearchResponse : public StringSearchResponseWrapper { public: virtual void strstrLoc ( const uint32_t pos ) { if (pos != (uint32_t)-1) fprintf(stderr, "string search at character pos=%d\n", pos); } StringSearchResponse(int id, PortalPoller *poller = 0) : StringSearchResponseWrapper(id, poller) { } }; int main(int argc, char * const *argv) { Nvme nvme; StringSearchRequestProxy search(IfcNames_StringSearchRequestS2H); StringSearchResponse searchResponse(IfcNames_StringSearchResponseH2S); int opt; const char *filename = NULL; const char *needle = "needle"; int source_fd = -1; int doidentify; int dosearch = 0; int dotrace = 0; int dowrite = 0; while ((opt = getopt(argc, argv, "iw:s:t")) != -1) { switch (opt) { case 'i': doidentify = 1; break; case 's': needle = optarg; dosearch = 1; break; case 't': dotrace = 1; break; case 'w': filename = optarg; dowrite = 1; break; } } if (dowrite) { struct stat statbuf; int rc = stat(filename, &statbuf); if (rc < 0) { fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno)); return rc; } } sleep(1); nvme.setup(); if (dosearch) { int needle_len = strlen(needle); int border[needle_len+1]; compute_borders(nvme.needleBuffer.buffer(), border, needle_len); compute_MP_next(nvme.needleBuffer.buffer(), (struct MP *)nvme.mpNextBuffer.buffer(), needle_len); nvme.needleBuffer.cacheInvalidate(0, 1); // flush the whole thing nvme.mpNextBuffer.cacheInvalidate(0, 1); // flush the whole thing //FIXME: read the text from NVME storage //MP(needle, haystack, mpNext, needle_len, haystack_len, &sw_match_cnt); // the MPEngine will read in the needle and mpNext search.setSearchString(nvme.needleRef, nvme.mpNextRef, needle_len); } if (doidentify) nvme.identify(); nvme.getFeatures(); nvme.allocIOQueues(0); fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c)); int startBlock = 100000; // base and extent of test file in SSD int blocksPerRequest = 8; //12*BlocksPerRequest; int numBlocks = 1*blocksPerRequest; // 55; //8177; if (dosearch) { search.startSearch(numBlocks*512); } else { // if search is not running, then data read below will be discarded } if (dowrite) { struct stat statbuf; int rc = stat(filename, &statbuf); if (rc < 0) { fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno)); return rc; } numBlocks = statbuf.st_blocks; numBlocks -= (numBlocks % blocksPerRequest); fprintf(stderr, "Writing %d blocks from file %s to flash at block %d\n", numBlocks, filename, startBlock); source_fd = open(filename, O_RDONLY); } for (int block = 0; block < numBlocks; block += blocksPerRequest) { nvme_io_opcode opcode = (dowrite) ? nvme_write : nvme_read; fprintf(stderr, "starting transfer dowrite=%d opcode=%d\n", dowrite, opcode); if (opcode == nvme_write) { if (filename) { size_t bytesToRead = 512*blocksPerRequest; char *buffer = (char *)nvme.transferBuffer.buffer(); do { size_t bytesRead = read(source_fd, buffer, bytesToRead); if (bytesRead <= 0) { fprintf(stderr, "%s:%d Requested %ld bytes, received %ld bytes errno=%d:%s\n", __FUNCTION__, __LINE__, bytesToRead, bytesRead, errno, strerror(errno)); break; } bytesToRead -= bytesRead; buffer += bytesRead; } while (bytesToRead); } else { int *buffer = (int *)nvme.transferBuffer.buffer(); for (int i = 0; i < numBlocks*512/4; i ++) buffer[i] = i; } } int sc = nvme.doIO(opcode, startBlock, blocksPerRequest, (opcode == nvme_read ? 2 : 1), dotrace); nvme.status(); if (sc != 0) break; startBlock += blocksPerRequest; } nvme.dumpTrace(); //nvme.transferStats(); fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c)); return 0; } ================================================ FILE: tests/nvme_strstr/nfsume.json ================================================ { "pcie_refclk_p": { "FMC": "FMC_GBTCLK_P[00]" }, "pcie_refclk_n": { "FMC": "FMC_GBTCLK_N[00]" }, "RST_N_pcie_sys_reset_n": { "FMC": "FMC_LA_P[00]", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } } ================================================ FILE: tests/nvme_strstr/nvme.json ================================================ { "pcie_refclk_p": { "pcie": "sys_clk_p" }, "pcie_refclk_n": { "pcie": "sys_clk_n" }, "RST_N_pcie_sys_reset_n": { "pcie": "sys_reset_n" } } ================================================ FILE: tests/nvme_strstr/nvme.xdc ================================================ create_clock -name root_pci_refclk -period 10 [get_ports pcie_refclk_p] set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {userclk1}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {userclk1}] 4.0 -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {clk_125mhz_mux_*}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {clk_125mhz_mux_*}] 4.0 -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {clk_250mhz_mux_*}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {clk_250mhz_mux_*}] 4.0 -datapath_only ================================================ FILE: tests/nvme_strstr/package100.tcl ================================================ #----------------------------------------------------------- # Vivado v2016.2 (64-bit) # SW Build 1577090 on Thu Jun 2 16:32:35 MDT 2016 # IP Build 1577682 on Fri Jun 3 12:00:54 MDT 2016 # Start of session at: Tue Aug 16 11:26:40 2016 # Process ID: 16256 # Current directory: /home/jamey/connectal/tests/nvme_strstr/miniitx100 # Command line: vivado # Log file: /home/jamey/connectal/tests/nvme_strstr/miniitx100/vivado.log # Journal file: /home/jamey/connectal/tests/nvme_strstr/miniitx100/vivado.jou #----------------------------------------------------------- file delete -force -- nvmecore create_project nvmecore nvmecore -part xc7z100ffg900-2 #set_property board_part xilinx.com:zc706:part0:1.3 [current_project] add_files ../miniitx100/verilog add_files -norecurse ../cores/miniitx100/axi_pcie_rp/axi_pcie_rp.xci export_ip_user_files -of_objects [get_files /home/jamey/connectal/tests/nvme_strstr/cores/miniitx100/axi_pcie_rp/axi_pcie_rp.xci] -force -quiet update_compile_order -fileset sources_1 update_compile_order -fileset sim_1 update_compile_order -fileset sources_1 ipx::package_project -root_dir . -vendor user.org -library user -taxonomy /UserIP set_property library {} [ipx::current_core] set_property vendor accelerated.tech [ipx::current_core] set_property library user [ipx::current_core] set_property name nvme100 [ipx::current_core] set_property display_name nvme100 [ipx::current_core] set_property description {nvme for avnet mini-itx 100} [ipx::current_core] ipx::add_bus_interface ddr3 [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:ddrx_rtl:1.0 [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:ddrx:1.0 [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] ipx::add_port_map CS_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_CS_n [ipx::get_port_maps CS_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map CK_P [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_Clk_p [ipx::get_port_maps CK_P -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map CK_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_Clk_n [ipx::get_port_maps CK_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map DM [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_DM [ipx::get_port_maps DM -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map CAS_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_CAS_n [ipx::get_port_maps CAS_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map DQ [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_DQ [ipx::get_port_maps DQ -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map ADDR [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_Addr [ipx::get_port_maps ADDR -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map RAS_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_RAS_n [ipx::get_port_maps RAS_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map RESET_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_DRSTB [ipx::get_port_maps RESET_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map DQS_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_DQS_n [ipx::get_port_maps DQS_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map DQS_P [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_DQS_p [ipx::get_port_maps DQS_P -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map WE_N [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_WEB [ipx::get_port_maps WE_N -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map CKE [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_CKE [ipx::get_port_maps CKE -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map ODT [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_ODT [ipx::get_port_maps ODT -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_port_map BA [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]] set_property physical_name DDR_BankAddr [ipx::get_port_maps BA -of_objects [ipx::get_bus_interfaces ddr3 -of_objects [ipx::current_core]]] ipx::add_bus_interface pcie_mgt [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:pcie_7x_mgt_rtl:1.0 [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:pcie_7x_mgt:1.0 [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] ipx::add_port_map rxn [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pcie_exp_rxn_v [ipx::get_port_maps rxn -of_objects [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]]] ipx::add_port_map txn [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pcie_exp_txn [ipx::get_port_maps txn -of_objects [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]]] ipx::add_port_map rxp [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pcie_exp_rxp_v [ipx::get_port_maps rxp -of_objects [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]]] ipx::add_port_map txp [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]] set_property physical_name pcie_exp_txp [ipx::get_port_maps txp -of_objects [ipx::get_bus_interfaces pcie_mgt -of_objects [ipx::current_core]]] ipx::add_bus_interface pcie_refclk [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:diff_clock_rtl:1.0 [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:diff_clock:1.0 [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]] set_property interface_mode slave [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]] ipx::add_port_map CLK_P [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]] set_property physical_name pcie_refclk_p [ipx::get_port_maps CLK_P -of_objects [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]]] ipx::add_port_map CLK_N [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]] set_property physical_name pcie_refclk_n [ipx::get_port_maps CLK_N -of_objects [ipx::get_bus_interfaces pcie_refclk -of_objects [ipx::current_core]]] ipx::remove_bus_interface CLK_deleteme_unused_clock [ipx::current_core] ipx::remove_bus_interface CLK_GATE_deleteme_unused_clock [ipx::current_core] ipx::remove_port CLK_deleteme_unused_clock [ipx::current_core] ipx::remove_port CLK_GATE_deleteme_unused_clock [ipx::current_core] ipx::remove_port CLK_deleteme_unused_clock_0 [ipx::current_core] ipx::remove_port CLK_GATE_deleteme_unused_clock_0 [ipx::current_core] ipx::remove_port CLK_deleteme_unused_clock_1 [ipx::current_core] ipx::remove_port CLK_GATE_deleteme_unused_clock_1 [ipx::current_core] ipx::remove_port CLK_deleteme_unused_clock_2 [ipx::current_core] ipx::remove_port CLK_GATE_deleteme_unused_clock_2 [ipx::current_core] ipx::remove_port CLK_deleteme_unused_clock_3 [ipx::current_core] ipx::remove_port CLK_GATE_deleteme_unused_clock_3 [ipx::current_core] ipx::remove_port RST_N_deleteme_unused_reset_0 [ipx::current_core] ipx::remove_port RST_N_deleteme_unused_reset_1 [ipx::current_core] ipx::remove_port RST_N_deleteme_unused_reset_2 [ipx::current_core] ipx::remove_port RST_N_deleteme_unused_reset_3 [ipx::current_core] ipx::associate_bus_interfaces -busif ddr3 -clock DDR_Clk_p [ipx::current_core] ipx::associate_bus_interfaces -busif ddr3 -clock DDR_Clk_n [ipx::current_core] ipx::remove_bus_interface CLK [ipx::current_core] ipx::remove_port CLK [ipx::current_core] ipx::remove_port RST_N [ipx::current_core] ipx::add_bus_interface pcie_sys_reset_n [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:signal:reset_rtl:1.0 [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:signal:reset:1.0 [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property interface_mode slave [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property interface_mode master [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] ipx::add_port_map RST [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]] set_property physical_name RST_N_pcie_sys_reset_n [ipx::get_port_maps RST -of_objects [ipx::get_bus_interfaces pcie_sys_reset_n -of_objects [ipx::current_core]]] ipx::infer_bus_interface FIXED_IO_ddr_vrn xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface {FIXED_IO_ddr_vrp MIO FIXED_IO_ps_porb FIXED_IO_ps_srstb} xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface FIXED_IO_ddr_vrp xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface FIXED_IO_ps_porb xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface FIXED_IO_ps_srstb xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface MIO xilinx.com:signal:data_rtl:1.0 [ipx::current_core] set_property core_revision 2 [ipx::current_core] ipx::create_xgui_files [ipx::current_core] ipx::update_checksums [ipx::current_core] ipx::save_core [ipx::current_core] set_property ip_repo_paths /home/jamey/connectal/tests/nvme_strstr [current_project] update_ip_catalog ipx::check_integrity -quiet [ipx::current_core] ipx::archive_core /home/jamey/connectal/tests/nvme_strstr/accelerated.tech_user_nvme_strstr_1.0.zip [ipx::current_core] set_property core_revision 3 [ipx::current_core] ipx::create_xgui_files [ipx::current_core] ipx::update_checksums [ipx::current_core] ipx::save_core [ipx::current_core] update_ip_catalog -rebuild -repo_path /home/jamey/connectal/tests/nvme_strstr ipx::check_integrity -quiet [ipx::current_core] ipx::archive_core /home/jamey/connectal/tests/nvme_strstr/accelerated.tech_user_nvme_strstr_1.0.zip [ipx::current_core] launch_runs synth_1 -jobs 12 wait_on_run synth_1 ipx::remove_bus_interface FIXED_IO_ddr_vrn [ipx::current_core] ipx::remove_bus_interface FIXED_IO_ddr_vrp [ipx::current_core] ipx::remove_bus_interface FIXED_IO_ps_porb [ipx::current_core] ipx::remove_bus_interface FIXED_IO_ps_srstb [ipx::current_core] ipx::remove_bus_interface MIO [ipx::current_core] ipx::remove_bus_interface FIXED_IO_ps_clk [ipx::current_core] ipx::create_abstraction_definition xilinx zynq7 FIXED_IO_rtl 1.0 ipx::create_bus_definition xilinx zynq7 FIXED_IO 1.0 set_property xml_file_name /home/jamey/connectal/tests/nvme_strstr/ip_repo/FIXED_IO_rtl.xml [ipx::current_busabs] set_property xml_file_name /home/jamey/connectal/tests/nvme_strstr/ip_repo/FIXED_IO.xml [ipx::current_busdef] set_property bus_type_vlnv xilinx:zynq7:FIXED_IO:1.0 [ipx::current_busabs] ipx::save_abstraction_definition [ipx::current_busabs] ipx::save_bus_definition [ipx::current_busdef] ipx::add_bus_abstraction_port FIXED_IO_ddr_vrn [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ddr_vrp [ipx::current_busabs] ipx::add_bus_abstraction_port MIO [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ps_clk [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ps_porb [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ps_srstb [ipx::current_busabs] ipx::save_bus_definition [ipx::current_busdef] ipx::save_abstraction_definition [ipx::current_busabs] update_ip_catalog -rebuild update_ip_catalog -rebuild -repo_path /home/jamey/connectal/tests/nvme_strstr ipx::infer_bus_interface {FIXED_IO_ddr_vrn FIXED_IO_ddr_vrp MIO FIXED_IO_ps_clk FIXED_IO_ps_porb FIXED_IO_ps_srstb} xilinx:zynq7:FIXED_IO:1.0 [ipx::current_core] set_property name FIXED_IO [ipx::get_bus_interfaces FIXED_IO_1 -of_objects [ipx::current_core]] ipx::remove_bus_interface FIXED_IO_ddr_vrn [ipx::current_core] ipx::remove_bus_interface FIXED_IO_ps_clk [ipx::current_core] ipx::create_abstraction_definition accelerated.tech zynq7 FIXED_IO_rtl 1.0 ipx::create_bus_definition accelerated.tech zynq7 FIXED_IO 1.0 set_property xml_file_name /home/jamey/connectal/tests/nvme_strstr/ip_repo/FIXED_IO_rtl.xml [ipx::current_busabs] set_property xml_file_name /home/jamey/connectal/tests/nvme_strstr/ip_repo/FIXED_IO.xml [ipx::current_busdef] set_property bus_type_vlnv accelerated.tech:zynq7:FIXED_IO:1.0 [ipx::current_busabs] ipx::save_abstraction_definition [ipx::current_busabs] ipx::save_bus_definition [ipx::current_busdef] set_property ip_repo_paths /home/jamey/connectal/tests/nvme_strstr/ip_repo [current_project] ipx::add_bus_abstraction_port FIXED_IO_ddr_vrn [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ddr_vrp [ipx::current_busabs] ipx::add_bus_abstraction_port MIO [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ps_clk [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ps_porb [ipx::current_busabs] ipx::add_bus_abstraction_port FIXED_IO_ps_srstb [ipx::current_busabs] ipx::save_bus_definition [ipx::current_busdef] ipx::save_abstraction_definition [ipx::current_busabs] update_ip_catalog -rebuild update_ip_catalog ipx::infer_bus_interface {FIXED_IO_ddr_vrn FIXED_IO_ddr_vrp MIO FIXED_IO_ps_clk FIXED_IO_ps_porb FIXED_IO_ps_srstb} accelerated.tech:zynq7:FIXED_IO:1.0 [ipx::current_core] set_property name FIXED_IO [ipx::get_bus_interfaces FIXED_IO_1 -of_objects [ipx::current_core]] set_property core_revision 2 [ipx::current_core] ipx::create_xgui_files [ipx::current_core] ipx::update_checksums [ipx::current_core] ipx::save_core [ipx::current_core] set_property ip_repo_paths {/home/jamey/connectal/tests/nvme_strstr /home/jamey/connectal/tests/nvme_strstr/ip_repo} [current_project] update_ip_catalog ipx::check_integrity -quiet [ipx::current_core] ipx::archive_core /home/jamey/connectal/tests/nvme_strstr/accelerated.tech_user_nvme100_1.0.zip [ipx::current_core] update_compile_order -fileset sources_1 ipx::infer_bus_interface FIXED_IO_ddr_vrp xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface FIXED_IO_ps_porb xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface FIXED_IO_ps_srstb xilinx.com:signal:data_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface MIO xilinx.com:signal:video_frame_sync_rtl:1.0 [ipx::current_core] ipx::add_bus_interface accel_request [ipx::current_core] set_property abstraction_type_vlnv xilinx.com:interface:axis_rtl:1.0 [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] set_property bus_type_vlnv xilinx.com:interface:axis:1.0 [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] ipx::add_port_map TDATA [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] set_property physical_name accel_request_tdata_v [ipx::get_port_maps TDATA -of_objects [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]]] ipx::add_port_map TLAST [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] set_property physical_name accel_request_tlast_v [ipx::get_port_maps TLAST -of_objects [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]]] ipx::add_port_map TVALID [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] set_property physical_name accel_request_tvalid_v [ipx::get_port_maps TVALID -of_objects [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]]] ipx::add_port_map TKEEP [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] set_property physical_name accel_request_tkeep_v [ipx::get_port_maps TKEEP -of_objects [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]]] ipx::add_port_map TREADY [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]] set_property physical_name accel_request_tready [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces accel_request -of_objects [ipx::current_core]]] ipx::infer_bus_interface {accel_msgIn_tdata_v accel_msgIn_tkeep_v accel_msgIn_tlast_v accel_msgIn_tready accel_msgIn_tvalid_v} xilinx.com:interface:axis_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface {accel_dataIn_tdata_v accel_dataIn_tkeep_v accel_dataIn_tlast_v accel_dataIn_tready accel_dataIn_tvalid_v} xilinx.com:interface:axis_rtl:1.0 [ipx::current_core] set_property name MIO [ipx::get_bus_interfaces video_frame_sync_1 -of_objects [ipx::current_core]] ipx::add_port_map TREADY [ipx::get_bus_interfaces accel_msgOut -of_objects [ipx::current_core]] set_property physical_name accel_msgOut_tready_v [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces accel_msgOut -of_objects [ipx::current_core]]] ipx::add_port_map TREADY [ipx::get_bus_interfaces accel_dataOut -of_objects [ipx::current_core]] set_property physical_name accel_dataOut_tready_v [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces accel_dataOut -of_objects [ipx::current_core]]] ipx::add_port_map TREADY [ipx::get_bus_interfaces accel_response -of_objects [ipx::current_core]] set_property physical_name accel_response_tready_v [ipx::get_port_maps TREADY -of_objects [ipx::get_bus_interfaces accel_response -of_objects [ipx::current_core]]] set_property core_revision 3 [ipx::current_core] ipx::create_xgui_files [ipx::current_core] ipx::update_checksums [ipx::current_core] ipx::save_core [ipx::current_core] set_property ip_repo_paths /home/jamey/connectal.bisect/tests/nvme_strstr/miniitx100 [current_project] update_ip_catalog ================================================ FILE: tests/nvme_strstr/synth-ip.tcl ================================================ source "board.tcl" if {$boardname == {nfsume}} { set partname {xc7vx690tffg1761-3} set databuswidth 128 set pcie_blk_locn {X0Y0} } if {$boardname == {vc709}} { set partname {xc7vx690tffg1761-2} set databuswidth 128 set pcie_blk_locn {X0Y2} } if {$boardname == {miniitx100}} { set partname {xc7z100ffg900-2} set databuswidth 128 } if {$boardname == {zc706}} { set partname {xc7z045ffg900-2} set databuswidth 128 } puts "partname=$partname" puts "databuswidth=$databuswidth" create_project -name local_synthesized_ip -in_memory -part $partname if {$boardname == {nfsume}} { set_property board_part xilinx.com:vc709:part0:1.0 [current_project] } proc fpgamake_ipcore {core_name core_version ip_name params} { global ipdir boardname set generate_ip 0 if [file exists $ipdir/$boardname/$ip_name/$ip_name.xci] { } else { puts "no xci file $ip_name.xci" set generate_ip 1 } if [file exists $ipdir/$boardname/$ip_name/vivadoversion.txt] { gets [open $ipdir/$boardname/$ip_name/vivadoversion.txt r] generated_version set current_version [version -short] puts "core was generated by vivado $generated_version, currently running vivado $current_version" if {$current_version != $generated_version} { puts "vivado version does not match" set generate_ip 1 } } else { puts "no vivado version recorded" set generate_ip 1 } ## check requested core version and parameters if [file exists $ipdir/$boardname/$ip_name/coreversion.txt] { gets [open $ipdir/$boardname/$ip_name/coreversion.txt r] generated_version set current_version "$core_name $core_version $params" puts "Core generated: $generated_version" puts "Core requested: $current_version" if {$current_version != $generated_version} { puts "core version or params does not match" set generate_ip 1 } } else { puts "no core version recorded" set generate_ip 1 } if $generate_ip { file delete -force $ipdir/$boardname/$ip_name file mkdir $ipdir/$boardname create_ip -name $core_name -version $core_version -vendor xilinx.com -library ip -module_name $ip_name -dir $ipdir/$boardname if [llength $params] { set_property -dict $params [get_ips $ip_name] } report_property -file $ipdir/$boardname/$ip_name.properties.log [get_ips $ip_name] generate_target all [get_files $ipdir/$boardname/$ip_name/$ip_name.xci] set versionfd [open $ipdir/$boardname/$ip_name/vivadoversion.txt w] puts $versionfd [version -short] close $versionfd set corefd [open $ipdir/$boardname/$ip_name/coreversion.txt w] puts $corefd "$core_name $core_version $params" close $corefd } else { read_ip $ipdir/$boardname/$ip_name/$ip_name.xci } if [file exists $ipdir/$boardname/$ip_name/$ip_name.dcp] { } else { synth_ip [get_ips $ip_name] } } if {$partname != {xc7vx690tffg1761-2} && $partname != {xc7vx690tffg1761-3}} { fpgamake_ipcore axi_pcie 2.8 axi_pcie_rp [list \ CONFIG.AXIBAR2PCIEBAR_0 {0x00000000} \ CONFIG.AXIBAR_0 {0x00000000} \ CONFIG.AXIBAR_HIGHADDR_0 {0xfFFFFFFF} \ CONFIG.BAR0_SCALE {Gigabytes} \ CONFIG.BAR0_SIZE {1} \ CONFIG.BASEADDR {0x00000000} \ CONFIG.BASE_CLASS_MENU {Bridge_device} \ CONFIG.DEVICE_ID {0x7022} \ CONFIG.HIGHADDR {0xffffffff} \ CONFIG.INCLUDE_BAROFFSET_REG {false} \ CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} \ CONFIG.MAX_LINK_SPEED {5.0_GT/s} \ CONFIG.M_AXI_DATA_WIDTH {128} \ CONFIG.NO_OF_LANES {X4} \ CONFIG.NUM_MSI_REQ {5} \ CONFIG.SUB_CLASS_INTERFACE_MENU {InfiniBand_to_PCI_host_bridge} \ CONFIG.S_AXI_DATA_WIDTH {128} \ CONFIG.S_AXI_SUPPORTS_NARROW_BURST {true} \ CONFIG.XLNX_REF_BOARD {ZC706} \ CONFIG.shared_logic_in_core {true} \ ] } else { fpgamake_ipcore axi_pcie3 2.1 axi_pcie_rp [list \ CONFIG.pcie_blk_locn $pcie_blk_locn \ CONFIG.axi_data_width {128_bit} \ CONFIG.axibar_highaddr_0 {0xffffffffffffffff} \ CONFIG.axisten_freq {125} \ CONFIG.dedicate_perst {false} \ CONFIG.device_port_type {Root_Port_of_PCI_Express_Root_Complex} \ CONFIG.mode_selection {Advanced} \ CONFIG.pcie_blk_locn $pcie_blk_locn \ CONFIG.pf0_bar0_scale {Gigabytes} \ CONFIG.pf0_bar0_size {2} \ CONFIG.pf0_base_class_menu {Bridge_device} \ CONFIG.pf0_class_code {060700} \ CONFIG.pf0_class_code_base {06} \ CONFIG.pf0_class_code_sub {07} \ CONFIG.pf0_device_id {7131} \ CONFIG.pf0_link_status_slot_clock_config {true} \ CONFIG.pf0_sub_class_interface_menu {CardBus_bridge} \ CONFIG.pl_link_cap_max_link_speed {5.0_GT/s} \ CONFIG.pl_link_cap_max_link_width {X4} \ CONFIG.plltype {QPLL1} \ CONFIG.s_axi_id_width {4} \ ] } ================================================ FILE: tests/nvme_test/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = NvmeRequest:NvmeTest.request NvmeDriverRequest:NvmeTest.driverRequest MemServerPortalRequest:NvmeTest.bramRequest H2S_INTERFACES = NvmeTest:NvmeIndication,NvmeDriverIndication,NvmeTrace,MemServerPortalIndication MEM_READ_INTERFACES = lNvmeTest.dmaReadClient MEM_WRITE_INTERFACES = lNvmeTest.dmaWriteClient BSVPATH = $(CONNECTALDIR)/lib/strstr/bsv BSVFILES = $(CONNECTALDIR)/lib/nvme/bsv/NvmeIfc.bsv $(CONNECTALDIR)/bsv/ConnectalConfig.bsv CPPFILES += $(CONNECTALDIR)/lib/nvme/cpp/nvme.cpp main.cpp CPPFILES += $(CONNECTALDIR)/cpp/DmaBuffer.cpp CONNECTALFLAGS += -I$(CONNECTALDIR)/lib/nvme/cpp CONNECTALFLAGS += -DTRACE_PORTAL ifeq ($(BOARD),miniitx100) PINOUT_FILE += nvme.json CONNECTALFLAGS += -D PcieDataBusWidth=128 CONNECTALFLAGS += -D USE_ACP CONNECTALFLAGS += -D TOP_SOURCES_PORTAL_CLOCK CONNECTALFLAGS += --mainclockperiod=8 else ifeq ($(BOARD),kc705g2) CONNECTALFLAGS += --pin-binding FMC:fmc1 endif ifeq ($(BOARD),nfsume) CONNECTALFLAGS += --implconstraint=nfsume.xdc endif #PINOUT_FILE += fmc.json CONNECTALFLAGS += -D PcieDataBusWidth=128 endif CONNECTALFLAGS += -D BlocksPerRequest=8 PIN_TYPE = NvmePins PIN_TYPE_INCLUDE = NvmePins AUTOTOP = --interface pins:NvmeTest.pins AUTOTOP += --portalclock=lNvmeTest.portalClockSource CONNECTALFLAGS += --cxxflags=-std=c++11 CONNECTALFLAGS += --stl=c++_static CONNECTALFLAGS += -I $(CONNECTALDIR)/lib/strstr/cpp CONNECTALFLAGS += --bsvpath=../spikehw CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/axi_pcie_rp/axi_pcie_rp.xci CONNECTALFLAGS += -D GET_PUT_WITH_CLOCKS_USE_XILINX_FIFO CONNECTALFLAGS += --xci=$(IPDIR)/$(BOARD)/dual_clock_axis_fifo_32x8/dual_clock_axis_fifo_32x8.xci CONNECTALFLAGS += --implconstraint=nvme.xdc #CONNECTALFLAGS += -DNVME_ACCELERATOR_INTERFACE=1 include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/nvme_test/NvmeTest.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import Arbitrate::*; import BRAM::*; import BuildVector::*; import Clocks::*; import Connectable::*; import FIFOF::*; import Gearbox::*; import GetPut::*; import Probe::*; import StmtFSM::*; import Vector::*; import AddressGenerator::*; import AxiBits::*; import AxiStream::*; import ConnectalClocks::*; import ConnectalConfig::*; import DefaultValue::*; import GearboxGetPut::*; import HostInterface::*; import MemReadEngine::*; import ConnectalMemTypes::*; import PhysMemSlaveFromBram::*; import Pipe::*; import TraceMemClient::*; import XilinxCells::*; import MPEngine::*; import Nvme::*; import NvmeIfc::*; import NvmePins::*; interface NvmeTest; interface NvmeRequest request; interface NvmeDriverRequest driverRequest; interface MemServerPortalRequest bramRequest; interface NvmeTrace trace; interface NvmePins pins; interface Vector#(1, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaWriteClient; `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource; `endif endinterface typedef enum { Loopback, Needle, MpNext, Clear, Opcode, StartBlock, NumBlocks, Start } MsgFromSoftwareTag deriving (Bits,Eq); typedef struct { MsgFromSoftwareTag tag; Bit#(24) data; } MsgFromSoftware deriving (Bits); typedef enum { Loopback=1, LocDone=2, TransferDone=3 } MsgToSoftwareTag deriving (Bits,Eq); typedef struct { MsgToSoftwareTag tag; Bit#(24) data; } MsgToSoftware deriving (Bits); module mkNvmeTest#(NvmeIndication ind, NvmeDriverIndication driverInd, NvmeTrace trace, MemServerPortalIndication bramIndication)(NvmeTest); let nvme <- mkNvme(ind, driverInd, trace, bramIndication); `ifndef NVME_ACCELERATOR_INTERFACE Reg#(Bit#(32)) dataCounter <- mkReg(0); FIFOF#(Bit#(32)) dataLengthFifo <- mkFIFOF(); FIFOF#(MemDataF#(PcieDataBusWidth)) fifoToMp <- mkFIFOF(); let needleLenReg <- mkReg(0); Reg#(Bool) firstReg <- mkReg(True); rule rl_count_data_to_mp; let data <- toGet(nvme.dataFromNvme).get(); if (dataLengthFifo.notEmpty()) begin data.last = (dataCounter+fromInteger(valueOf(PcieDataBusWidth)/8)) >= dataLengthFifo.first; let md = MemDataF {data: data.data, last: data.last, first: firstReg, tag: 0}; firstReg <= data.last; fifoToMp.enq(md); end dataCounter <= dataCounter + 1; endrule `endif interface NvmeRequest request = nvme.request; interface NvmeDriverRequest driverRequest = nvme.driverRequest; interface MemServerPortalRequest bramRequest = nvme.bramRequest; interface NvmeTrace trace = nvme.trace; interface NvmePins pins = nvme.pins; `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource = nvme.portalClockSource; `endif interface Vector dmaReadClient = nvme.dmaReadClient; interface Vector dmaWriteClient = nvme.dmaWriteClient; endmodule ================================================ FILE: tests/nvme_test/fmc.json ================================================ { "pcie_refclk_p": { "FMC": "FMC_GBTCLK_P[00]" }, "pcie_refclk_n": { "FMC": "FMC_GBTCLK_N[00]" }, "RST_N_pcie_sys_reset_n": { "FMC": "FMC_LA_P[00]", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } } ================================================ FILE: tests/nvme_test/impl.tcl ================================================ set dbgs [get_nets -hierarchical -filter {MARK_DEBUG}] if {[llength $dbgs] > 0} { set_property mark_debug false $dbgs } opt_design place_design phys_opt_design route_design write_bitstream -force debug.bit write_debug_probes -force debug.ltx report_timing_summary -file debug_timing_summary.txt ================================================ FILE: tests/nvme_test/main.cpp ================================================ #include //#include "jsoncpp/json/json.h" #include #include #include #include #include #include #include #include "ConnectalProjectConfig.h" #include "nvme.h" int main(int argc, char * const *argv) { int opt; const char *filename = NULL; int source_fd = -1; int doidentify; int dotrace = 0; int dowrite = 0; bool verbose = false; while ((opt = getopt(argc, argv, "iw:tv")) != -1) { switch (opt) { case 'i': doidentify = 1; break; case 't': dotrace = 1; break; case 'v': verbose = true; break; case 'w': filename = optarg; dowrite = 1; break; } } if (dowrite) { struct stat statbuf; int rc = stat(filename, &statbuf); if (rc < 0) { fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno)); return rc; } } Nvme nvme(verbose); sleep(1); nvme.setup(); if (doidentify) nvme.identify(); nvme.getFeatures(); nvme.allocIOQueues(0); fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c)); int startBlock = 100000; // base and extent of test file in SSD int blocksPerRequest = 8; //12*BlocksPerRequest; int numBlocks = 1*blocksPerRequest; // 55; //8177; if (dowrite) { struct stat statbuf; int rc = stat(filename, &statbuf); if (rc < 0) { fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno)); return rc; } numBlocks = statbuf.st_blocks; numBlocks -= (numBlocks % blocksPerRequest); fprintf(stderr, "Writing %d blocks from file %s to flash at block %d\n", numBlocks, filename, startBlock); source_fd = open(filename, O_RDONLY); } for (int block = 0; block < numBlocks; block += blocksPerRequest) { nvme_io_opcode opcode = (dowrite) ? nvme_write : nvme_read; fprintf(stderr, "starting transfer dowrite=%d opcode=%d\n", dowrite, opcode); if (opcode == nvme_write) { if (filename) { size_t bytesToRead = 512*blocksPerRequest; char *buffer = (char *)nvme.transferBuffer.buffer(); do { size_t bytesRead = read(source_fd, buffer, bytesToRead); if (bytesRead <= 0) { fprintf(stderr, "%s:%d Requested %ld bytes, received %ld bytes errno=%d:%s\n", __FUNCTION__, __LINE__, bytesToRead, bytesRead, errno, strerror(errno)); break; } bytesToRead -= bytesRead; buffer += bytesRead; } while (bytesToRead); } else { int *buffer = (int *)nvme.transferBuffer.buffer(); for (int i = 0; i < numBlocks*512/4; i ++) buffer[i] = i; } } int sc = nvme.doIO(opcode, startBlock, blocksPerRequest, (opcode == nvme_read ? 2 : 1), dotrace); nvme.status(); if (sc != 0) break; startBlock += blocksPerRequest; } nvme.dumpTrace(); //nvme.transferStats(); fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c)); return 0; } ================================================ FILE: tests/nvme_test/miniitx100.json ================================================ { "pcie_refclk_p": { "pcie": "sys_clk_p" }, "pcie_refclk_n": { "pcie": "sys_clk_n" }, "RST_N_pcie_sys_reset_n": { "pcie": "sys_reset_n" } } ================================================ FILE: tests/nvme_test/nfsume.json ================================================ { "pcie_refclk_p": { "FMC": "FMC_GBTCLK_P[00]" }, "pcie_refclk_n": { "FMC": "FMC_GBTCLK_N[00]" }, "RST_N_pcie_sys_reset_n": { "FMC": "FMC_LA_P[00]", "IOSTANDARD": "LVCMOS18", "PIO_DIRECTION": "OUTPUT" } } ================================================ FILE: tests/nvme_test/nfsume.xdc ================================================ set_property PACKAGE_PIN "AT8" [get_ports "pcie_refclk_p"] set_property DIFF_TERM "TRUE" [get_ports "pcie_refclk_p"] set_property PACKAGE_PIN "AT7" [get_ports "pcie_refclk_n"] set_property DIFF_TERM "TRUE" [get_ports "pcie_refclk_n"] set_property PACKAGE_PIN "AU28" [get_ports "RST_N_pcie_sys_reset_n"] set_property IOSTANDARD "LVCMOS18" [get_ports "RST_N_pcie_sys_reset_n"] set_property PIO_DIRECTION "OUTPUT" [get_ports "RST_N_pcie_sys_reset_n"] ================================================ FILE: tests/nvme_test/nvme.xdc ================================================ create_clock -name root_pci_refclk -period 10 [get_ports pcie_refclk_p] set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {userclk1}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {userclk1}] 4.0 -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {userclk2_1}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {userclk2_1}] 4.0 -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {clk_125mhz_mux_*}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {clk_125mhz_mux_*}] 4.0 -datapath_only set_max_delay -from [get_clocks {userclk2}] -to [get_clocks {clk_250mhz_mux_*}] 4.0 -datapath_only set_max_delay -to [get_clocks {userclk2}] -from [get_clocks {clk_250mhz_mux_*}] 4.0 -datapath_only set_property LOC GTHE2_CHANNEL_X1Y7 [get_cells {tile_0/*axiRootPort/inst/pcie3_ip_i/inst/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gth_channel.gthe2_channel_i}] # PCIe Lane 1 set_property LOC GTHE2_CHANNEL_X1Y6 [get_cells {tile_0/*axiRootPort/inst/pcie3_ip_i/inst/gt_top_i/pipe_wrapper_i/pipe_lane[1].gt_wrapper_i/gth_channel.gthe2_channel_i}] # PCIe Lane 2 set_property LOC GTHE2_CHANNEL_X1Y5 [get_cells {tile_0/*axiRootPort/inst/pcie3_ip_i/inst/gt_top_i/pipe_wrapper_i/pipe_lane[2].gt_wrapper_i/gth_channel.gthe2_channel_i}] # PCIe Lane 3 set_property LOC GTHE2_CHANNEL_X1Y4 [get_cells {tile_0/*axiRootPort/inst/pcie3_ip_i/inst/gt_top_i/pipe_wrapper_i/pipe_lane[3].gt_wrapper_i/gth_channel.gthe2_channel_i}] ================================================ FILE: tests/nvme_test/synth-ip.tcl ================================================ source "board.tcl" if {$boardname == {nfsume}} { set partname {xc7vx690tffg1761-3} set databuswidth 128 set pcie_blk_locn {X0Y0} } if {$boardname == {vc709}} { set partname {xc7vx690tffg1761-2} set databuswidth 128 set pcie_blk_locn {X0Y2} } if {$boardname == {miniitx100}} { set databuswidth 128 set pcie_blk_locn {X1Y0} } if {$boardname == {zc706}} { set databuswidth 128 set pcie_blk_locn {X1Y0} } if {$boardname == {vc707g2}} { set databuswidth 128 set pcie_blk_locn {X1Y1} } puts "partname=$partname" puts "databuswidth=$databuswidth" create_project -name local_synthesized_ip -in_memory -part $partname if {$boardname == {nfsume}} { set_property board_part xilinx.com:vc709:part0:1.0 [current_project] } proc fpgamake_ipcore {core_name core_version ip_name params} { global ipdir boardname set generate_ip 0 if [file exists $ipdir/$boardname/$ip_name/$ip_name.xci] { } else { puts "no xci file $ip_name.xci" set generate_ip 1 } if [file exists $ipdir/$boardname/$ip_name/vivadoversion.txt] { gets [open $ipdir/$boardname/$ip_name/vivadoversion.txt r] generated_version set current_version [version -short] puts "core was generated by vivado $generated_version, currently running vivado $current_version" if {$current_version != $generated_version} { puts "vivado version does not match" set generate_ip 1 } } else { puts "no vivado version recorded" set generate_ip 1 } ## check requested core version and parameters if [file exists $ipdir/$boardname/$ip_name/coreversion.txt] { gets [open $ipdir/$boardname/$ip_name/coreversion.txt r] generated_version set current_version "$core_name $core_version $params" puts "Core generated: $generated_version" puts "Core requested: $current_version" if {$current_version != $generated_version} { puts "core version or params does not match" set generate_ip 1 } } else { puts "no core version recorded" set generate_ip 1 } if $generate_ip { file delete -force $ipdir/$boardname/$ip_name file mkdir $ipdir/$boardname create_ip -name $core_name -version $core_version -vendor xilinx.com -library ip -module_name $ip_name -dir $ipdir/$boardname if [llength $params] { set_property -dict $params [get_ips $ip_name] } report_property -file $ipdir/$boardname/$ip_name.properties.log [get_ips $ip_name] generate_target all [get_files $ipdir/$boardname/$ip_name/$ip_name.xci] set versionfd [open $ipdir/$boardname/$ip_name/vivadoversion.txt w] puts $versionfd [version -short] close $versionfd set corefd [open $ipdir/$boardname/$ip_name/coreversion.txt w] puts $corefd "$core_name $core_version $params" close $corefd } else { read_ip $ipdir/$boardname/$ip_name/$ip_name.xci } if [file exists $ipdir/$boardname/$ip_name/$ip_name.dcp] { } else { synth_ip [get_ips $ip_name] } } if {$partname != {xc7vx690tffg1761-2} && $partname != {xc7vx690tffg1761-3}} { fpgamake_ipcore axi_pcie 2.8 axi_pcie_rp [list \ CONFIG.AXIBAR2PCIEBAR_0 {0x00000000} \ CONFIG.AXIBAR_0 {0x00000000} \ CONFIG.AXIBAR_HIGHADDR_0 {0xfFFFFFFF} \ CONFIG.BAR0_SCALE {Gigabytes} \ CONFIG.BAR0_SIZE {1} \ CONFIG.BASEADDR {0x00000000} \ CONFIG.BASE_CLASS_MENU {Bridge_device} \ CONFIG.DEVICE_ID {0x7022} \ CONFIG.HIGHADDR {0xffffffff} \ CONFIG.INCLUDE_BAROFFSET_REG {false} \ CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} \ CONFIG.MAX_LINK_SPEED {5.0_GT/s} \ CONFIG.M_AXI_DATA_WIDTH {128} \ CONFIG.NO_OF_LANES {X4} \ CONFIG.NUM_MSI_REQ {5} \ CONFIG.PCIE_BLK_LOCN $pcie_blk_locn \ CONFIG.SUB_CLASS_INTERFACE_MENU {InfiniBand_to_PCI_host_bridge} \ CONFIG.S_AXI_DATA_WIDTH {128} \ CONFIG.S_AXI_SUPPORTS_NARROW_BURST {true} \ CONFIG.shared_logic_in_core {true} \ ] } else { if {[version -short] >= "2016.1"} { set axi_pcie3_version 2.1 } else { set axi_pcie3_version 2.0 } fpgamake_ipcore axi_pcie3 $axi_pcie3_version axi_pcie_rp [list \ CONFIG.axi_data_width {128_bit} \ CONFIG.axibar_highaddr_0 {0xffffffffffffffff} \ CONFIG.dedicate_perst {false} \ CONFIG.device_port_type {Root_Port_of_PCI_Express_Root_Complex} \ CONFIG.mode_selection {Advanced} \ CONFIG.pcie_blk_locn $pcie_blk_locn \ CONFIG.pf0_bar0_scale {Gigabytes} \ CONFIG.pf0_bar0_size {2} \ CONFIG.pf0_base_class_menu {Bridge_device} \ CONFIG.pf0_class_code {060700} \ CONFIG.pf0_class_code_base {06} \ CONFIG.pf0_class_code_sub {07} \ CONFIG.pf0_device_id {7131} \ CONFIG.pf0_sub_class_interface_menu {CardBus_bridge} \ CONFIG.pl_link_cap_max_link_speed {5.0_GT/s} \ CONFIG.pl_link_cap_max_link_width {X4} \ CONFIG.s_axi_id_width {4} \ ] } if {[version -short] >= "2016.1"} { set dual_clock_axis_fifo_version 13.1 } else { set dual_clock_axis_fifo_version 13.0 } fpgamake_ipcore fifo_generator $dual_clock_axis_fifo_version dual_clock_axis_fifo_32x8 [list \ CONFIG.INTERFACE_TYPE {AXI_STREAM} \ CONFIG.Clock_Type_AXI {Independent_Clock} \ CONFIG.TDATA_NUM_BYTES {4} \ CONFIG.TUSER_WIDTH {0} \ CONFIG.Enable_TLAST {true} \ CONFIG.HAS_TKEEP {true} \ CONFIG.FIFO_Application_Type_axis {Data_FIFO} \ CONFIG.Reset_Type {Asynchronous_Reset} \ ] ================================================ FILE: tests/ov7670/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = Ov7670ControllerRequest:Ov7670Controller.request H2S_INTERFACES = Ov7670Controller:Ov7670ControllerIndication MEM_WRITE_INTERFACES = lOv7670Controller.dmaClient BSVFILES = Ov7670Interface.bsv CPPFILES= testcam.cpp PIN_TYPE = Ov7670Pins PIN_TYPE_INCLUDE = Ov7670Interface PINOUT_FILE = pinout.json AUTOTOP = --interface pins:Ov7670Controller.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/ov7670/Ov7670Controller.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import BuildVector::*; import Clocks::*; import GetPut::*; import ClientServer::*; import SCCB::*; import FIFOF::*; import BRAMFIFO::*; import Gearbox::*; import ConnectalMemTypes::*; import ConnectalConfig::*; import MemWriteEngine::*; import Pipe::*; import ConnectalClocks::*; import ConnectalXilinxCells::*; import Ov7670Interface::*; interface Ov7670Controller; interface Ov7670ControllerRequest request; interface Ov7670Pins pins; interface Vector#(1,MemWriteClient#(DataBusWidth)) dmaClient; endinterface module mkOv7670Controller#(Ov7670ControllerIndication ind)(Ov7670Controller); Integer divisor = 12; Clock defaultClock <- exposeCurrentClock; Reset defaultReset <- exposeCurrentReset; ClockDividerIfc clockDivider <- mkClockDivider(divisor); B2C1 b2c <- mkB2C1; let pclk = b2c.c; Reset preset <- mkAsyncReset(2, defaultReset, pclk); SyncFIFOIfc#(Tuple2#(Bit#(32),Bit#(1))) vsyncFifo <- mkSyncFIFO(32, pclk, preset, defaultClock); SyncFIFOIfc#(Tuple3#(Bool, Bool, Bit#(8))) dataFifo <- mkSyncBRAMFIFO(16384, pclk, preset, defaultClock, defaultReset); Gearbox#(1, 8, Bit#(8)) dataGearbox <- mk1toNGearbox(defaultClock, defaultReset, defaultClock, defaultReset); MemWriteEngine#(DataBusWidth,DataBusWidth,8,1) writeEngine <- mkMemWriteEngineBuff(2048); FIFOF#(Bool) sofFifo <- mkFIFOF(); Reg#(Bit#(32)) pointerReg <- mkReg(0); Reg#(Bool) transferDoneReg <- mkReg(False); Reg#(Bit#(32)) cycleReg <- mkReg(0, clocked_by pclk, reset_by preset); Reg#(Bit#(32)) lastVsyncReg <- mkReg(0, clocked_by pclk, reset_by preset); Reg#(Bit#(32)) lastDataReg <- mkReg(0, clocked_by pclk, reset_by preset); Reg#(Bit#(1)) vsyncReg <- mkReg(0, clocked_by pclk, reset_by preset); Reg#(Bit#(1)) hrefReg <- mkReg(0, clocked_by pclk, reset_by preset); Reg#(Bit#(8)) dataReg <- mkReg(0, clocked_by pclk, reset_by preset); Reg#(Bool) firstReg <- mkReg(False, clocked_by pclk, reset_by preset); Reg#(Bool) lastReg <- mkReg(False, clocked_by pclk, reset_by preset); Reg#(Bit#(16)) dataGapCycles <- mkReg(0, clocked_by pclk, reset_by preset); Wire#(Bool) dataRuleFired <- mkDWire(False, clocked_by pclk, reset_by preset); Vector#(3, SCCB) i2c <- replicateM(mkSCCB(1000)); Reg#(bit) resetReg <- mkReg(0); Reg#(bit) pwdnReg <- mkReg(0); Reg#(Bit#(1)) rSCL <- mkReg(1); Reg#(Bit#(1)) rSDA <- mkReg(1); Reg#(Bool) rOutEn <- mkReg(True); for (Integer i = 0; i < 3; i = i + 1) rule i2c_response_rule; let response <- i2c[i].user.response.get(); ind.i2cResponse(fromInteger(i), response.data); endrule rule cycleRule; cycleReg <= cycleReg + 1; endrule rule vsyncRule; if (vsyncReg == 1) begin vsyncFifo.enq(tuple2(cycleReg - lastVsyncReg, hrefReg)); lastVsyncReg <= cycleReg; end endrule rule vsyncSyncRule; match { .cycles, .href } <- toGet(vsyncFifo).get(); ind.vsync(cycles, href); if (sofFifo.notFull()) sofFifo.enq(True); endrule rule dataRule; if (hrefReg == 1) begin dataRuleFired <= True; let gap = dataGapCycles != 0; dataFifo.enq(tuple3(firstReg, (firstReg ? False : gap), dataReg)); lastDataReg <= cycleReg; firstReg <= False; end else begin firstReg <= True; end endrule rule dataRuleGap if (hrefReg == 1); if (!dataRuleFired) dataGapCycles <= dataGapCycles + 1; else dataGapCycles <= 0; endrule rule dataSyncRule; match { .first, .gap, .pxl } <- toGet(dataFifo).get(); if (sofFifo.notEmpty() && transferDoneReg) begin sofFifo.deq(); transferDoneReg <= False; writeEngine.writeServers[0].request.put(MemengineCmd { sglId: pointerReg, base: 0, burstLen: 8*8, len: 640*480, tag: 0}); ind.frameStarted(pack(first)); end dataGearbox.enq(unpack(pxl)); if (gap) ind.data(pack(first), pack(gap), pxl); endrule rule dataIndRule; let d = dataGearbox.first(); dataGearbox.deq(); //ind.data8(pack(d)); if (pointerReg != 0) writeEngine.writeServers[0].data.enq(pack(d)); endrule rule transferDoneRule; let d <- writeEngine.writeServers[0].done.get(); transferDoneReg <= True; ind.frameTransferred(); endrule interface Ov7670ControllerRequest request; method Action setFramePointer(Bit#(32) frameId); pointerReg <= frameId; transferDoneReg <= True; // prime the pump endmethod method Action i2cRequest(Bit#(8) bus, Bool write, Bit#(7) slaveaddr, Bit#(8) address, Bit#(8) data); i2c[bus].user.request.put(SCCBRequest {write: write, slaveaddr: slaveaddr, address: address, data: data}); endmethod method Action setReset(Bit#(1) rval); resetReg <= rval; endmethod method Action setPowerDown(Bit#(1) pwdn); pwdnReg <= pwdn; endmethod endinterface interface Ov7670Pins pins; interface SCCB_Pins i2c0 = i2c[0].i2c; interface SCCB_Pins i2c1 = i2c[1].i2c; interface SCCB_Pins i2c2 = i2c[2].i2c; interface Clock xclk = clockDivider.slowClock; interface Clock pclk_deleteme_unused_clock = pclk; method bit reset() = resetReg; method bit pwdn() = pwdnReg; method Action pclk(Bit#(1) v); b2c.inputclock(v); endmethod method Action pxl(Bit#(1) vsync, Bit#(1) href, Bit#(8) data); vsyncReg <= vsync; hrefReg <= href; dataReg <= data; endmethod endinterface interface Vector dmaClient = vec(writeEngine.dmaClient); endmodule ================================================ FILE: tests/ov7670/Ov7670Interface.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import SCCB::*; interface Ov7670ControllerRequest; method Action setFramePointer(Bit#(32) frameId); method Action i2cRequest(Bit#(8) bus, Bool write, Bit#(7) slaveaddr, Bit#(8) address, Bit#(8) data); method Action setReset(Bit#(1) rval); method Action setPowerDown(Bit#(1) pwdn); endinterface interface Ov7670ControllerIndication; method Action i2cResponse(Bit#(8) bus, Bit#(8) data); method Action vsync(Bit#(32) cycles, Bit#(1) href); method Action data(Bit#(1) first, Bit#(1) gap, Bit#(8) pxl); method Action data4(Bit#(32) pxls); method Action frameStarted(Bit#(1) first); method Action frameTransferred(); endinterface interface Ov7670Pins; interface SCCB_Pins i2c0; interface SCCB_Pins i2c1; interface SCCB_Pins i2c2; interface Clock xclk; interface Clock pclk_deleteme_unused_clock; method bit reset(); method bit pwdn(); method Action pclk(Bit#(1) v); method Action pxl(Bit#(1) vsync, Bit#(1) href, Bit#(8) data); endinterface ================================================ FILE: tests/ov7670/SCCB.bsv ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2011 Bluespec, Inc. ALL RIGHTS RESERVED. // $Revision : $ // $Date : $ //////////////////////////////////////////////////////////////////////////////// // Filename : SCCB.bsv // Description : SCCB master read/write controller //////////////////////////////////////////////////////////////////////////////// package SCCB; // Notes : //////////////////////////////////////////////////////////////////////////////// /// Imports //////////////////////////////////////////////////////////////////////////////// import Vector ::*; import FIFO ::*; import FIFOF ::*; import Counter ::*; import TriState ::*; import BUtils ::*; import Arbitrate ::*; import Connectable ::*; import GetPut ::*; import ClientServer ::*; import ConnectalXilinxCells::*; //////////////////////////////////////////////////////////////////////////////// /// Exports //////////////////////////////////////////////////////////////////////////////// export SCCB_Pins(..); export SCCB(..); export SCCBController(..); export SCCBRequest(..); export SCCBResponse(..); export mkSCCB; export mkSCCBController; //////////////////////////////////////////////////////////////////////////////// /// Types //////////////////////////////////////////////////////////////////////////////// typedef struct { Bool write; Bit#(7) slaveaddr; Bit#(8) address; Bit#(8) data; } SCCBRequest deriving (Bits, Eq); typedef struct { Bit#(8) data; } SCCBResponse deriving (Bits, Eq); instance ArbRequestTC#(SCCBRequest); function Bool isReadRequest(SCCBRequest a) = !a.write; function Bool isWriteRequest(SCCBRequest a) = a.write; endinstance typedef enum { Idle, Running } State deriving (Bits, Eq); //////////////////////////////////////////////////////////////////////////////// /// Interfaces //////////////////////////////////////////////////////////////////////////////// (* always_enabled, always_ready *) interface SCCB_Pins; (* prefix = "SDA" *) interface Inout#(Bit#(1)) sda; (* prefix = "SCL" *) interface Inout#(Bit#(1)) scl; endinterface interface SCCB; (* prefix = "" *) interface SCCB_Pins i2c; interface Server#(SCCBRequest, SCCBResponse) user; endinterface interface SCCBController#(numeric type n); (* prefix = "" *) interface SCCB_Pins i2c; interface Vector#(n, Server#(SCCBRequest, SCCBResponse)) users; endinterface //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// module mkSCCB#(Integer prescale)(SCCB); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// FIFOF#(SCCBRequest) fRequest <- mkSizedFIFOF(16); FIFO#(SCCBResponse) fResponse <- mkSizedFIFO(16); Reg#(Bit#(1)) rSCL <- mkReg(1); Reg#(Bit#(1)) rSDA <- mkReg(1); Reg#(Bool) rOutEn <- mkReg(True); TriState#(Bit#(1)) tSCL <- mkTriState(True, rSCL); //TriState#(Bit#(1)) tSDA <- mkTriState(rOutEn, rSDA); //IOBUF ioSCL <- mkIOBUF(pack(True), rSCL); IOBUF ioSDA <- mkIOBUF(rOutEn ? 0 : 1, rSDA); Counter#(32) rPrescaler <- mkCounter(fromInteger(prescale)); PulseWire pwTick <- mkPulseWire; Counter#(10) rPlayIndex <- mkCounter(0); Reg#(State) rState <- mkReg(Idle); Reg#(Bool) rWrite <- mkRegU; Reg#(Bit#(7)) rSlaveAddr <- mkRegU; Reg#(Bit#(8)) rAddress <- mkRegU; Reg#(Bit#(8)) rWriteData <- mkRegU; Vector#(8, Reg#(Bit#(1))) vrReadData <- replicateM(mkRegU); Bit#(7) slv = rSlaveAddr; Bit#(3) s6 = duplicate(slv[6]); Bit#(3) s5 = duplicate(slv[5]); Bit#(3) s4 = duplicate(slv[4]); Bit#(3) s3 = duplicate(slv[3]); Bit#(3) s2 = duplicate(slv[2]); Bit#(3) s1 = duplicate(slv[1]); Bit#(3) s0 = duplicate(slv[0]); Bit#(8) adr = rAddress; Bit#(3) a7 = duplicate(adr[7]); Bit#(3) a6 = duplicate(adr[6]); Bit#(3) a5 = duplicate(adr[5]); Bit#(3) a4 = duplicate(adr[4]); Bit#(3) a3 = duplicate(adr[3]); Bit#(3) a2 = duplicate(adr[2]); Bit#(3) a1 = duplicate(adr[1]); Bit#(3) a0 = duplicate(adr[0]); Bit#(8) dat = rWriteData; Bit#(3) d7 = duplicate(dat[7]); Bit#(3) d6 = duplicate(dat[6]); Bit#(3) d5 = duplicate(dat[5]); Bit#(3) d4 = duplicate(dat[4]); Bit#(3) d3 = duplicate(dat[3]); Bit#(3) d2 = duplicate(dat[2]); Bit#(3) d1 = duplicate(dat[1]); Bit#(3) d0 = duplicate(dat[0]); //////////////////////////////////////////////////////////////////////////////// /// Reads //////////////////////////////////////////////////////////////////////////////// Integer readLength = 120; // start slv[6] slv[5] slv[4] slv[3] slv[2] slv[1] slv[0] write ack adr[7] adr[6] adr[5] adr[4] adr[3] adr[2] adr[1] adr[0] ack stop start slv[6] slv[5] slv[4] slv[3] slv[2] slv[1] slv[0] read ack dat[7] dat[6] dat[5] dat[4] dat[3] dat[2] dat[1] dat[0] ack stop let wRdClock = { 3'b110, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b011, 3'b111, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b011 }; let wRdData = { 3'b100, s6, s5, s4, s3, s2, s1, s0, 3'b000, 3'b000, a7, a6, a5, a4, a3, a2, a1, a0, 3'b000, 3'b001, 3'b110, s6, s5, s4, s3, s2, s1, s0, 3'b111, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b001 }; let wRdOutEn = { 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b000, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b000, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b111 }; let wRdSample = { 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b000, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b000, 3'b000 }; //////////////////////////////////////////////////////////////////////////////// /// Writes //////////////////////////////////////////////////////////////////////////////// Integer writeLength = 87; // start slv[6] slv[5] slv[4] slv[3] slv[2] slv[1] slv[0] write ack adr[7] adr[6] adr[5] adr[4] adr[3] adr[2] adr[1] adr[0] ack dat[7] dat[6] dat[5] dat[4] dat[3] dat[2] dat[1] dat[0] ack stop let wWrClock = { 3'b110, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b010, 3'b011 }; let wWrData = { 3'b100, s6, s5, s4, s3, s2, s1, s0, 3'b000, 3'b000, a7, a6, a5, a4, a3, a2, a1, a0, 3'b000, d7, d6, d5, d4, d3, d2, d1, d0, 3'b000, 3'b001 }; let wWrOutEn = { 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b000, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b000, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b111, 3'b000, 3'b111 }; //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// (* fire_when_enabled, no_implicit_conditions *) rule update_prescaler(rPrescaler.value > 0); rPrescaler.down; endrule (* fire_when_enabled, no_implicit_conditions *) rule reset_prescaler(rPrescaler.value == 0); rPrescaler.setF(fromInteger(prescale)); pwTick.send; endrule rule start(rState == Idle); let request = fRequest.first; fRequest.deq; rSlaveAddr <= request.slaveaddr; rAddress <= request.address; rWriteData <= request.data; rWrite <= request.write; rState <= Running; if (request.write) rPlayIndex.setF(fromInteger(writeLength-1)); else rPlayIndex.setF(fromInteger(readLength-1)); endrule rule running_write(rState == Running && rWrite && pwTick && rPlayIndex.value > 0); rPlayIndex.down; rOutEn <= wWrOutEn[rPlayIndex.value] == 1; rSDA <= wWrData[rPlayIndex.value]; rSCL <= wWrClock[rPlayIndex.value]; endrule rule running_read(rState == Running && !rWrite && pwTick && rPlayIndex.value > 0); rPlayIndex.down; rOutEn <= wRdOutEn[rPlayIndex.value] == 1; rSDA <= wRdData[rPlayIndex.value]; rSCL <= wRdClock[rPlayIndex.value]; if (wRdSample[rPlayIndex.value] == 1) writeVReg(vrReadData, shiftInAt0(readVReg(vrReadData), ioSDA.o())); endrule rule done_write(rState == Running && rWrite && pwTick && rPlayIndex.value == 0); rPlayIndex.down; rOutEn <= wWrOutEn[rPlayIndex.value] == 1; rSDA <= wWrData[rPlayIndex.value]; rSCL <= wWrClock[rPlayIndex.value]; rState <= Idle; endrule rule done_read(rState == Running && !rWrite && pwTick && rPlayIndex.value == 0); rOutEn <= wRdOutEn[rPlayIndex.value] == 1; rSDA <= wRdData[rPlayIndex.value]; rSCL <= wRdClock[rPlayIndex.value]; rState <= Idle; fResponse.enq(unpack(pack(readVReg(vrReadData)))); endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface SCCB_Pins i2c; interface sda = ioSDA.io; interface scl = tSCL.io; endinterface interface Server user; interface request = toPut(fRequest); interface response = toGet(fResponse); endinterface endmodule //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation of SCCB Controller /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// module mkSCCBController(SCCBController#(n)) provisos( Add#(1, _1, n) ); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// Arbitrate#(n) mRoundRobin <- mkRoundRobin; Arbiter#(n, SCCBRequest, SCCBResponse) mArbiter <- mkArbiter(mRoundRobin, 16); SCCB mSCCB <- mkSCCB(1024); //////////////////////////////////////////////////////////////////////////////// /// Submodule Connections //////////////////////////////////////////////////////////////////////////////// mkConnection(mArbiter.master, mSCCB.user); //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// interface i2c = mSCCB.i2c; interface users = mArbiter.users; endmodule endpackage: SCCB ================================================ FILE: tests/ov7670/pinout.json ================================================ { "i2c0_SCL" : { "PIO_DIRECTION": "OUTPUT", "pmodb" : "J4" }, "i2c0_SDA" : { "PIO_DIRECTION": "BIDIR", "PULLTYPE": "PULLUP", "pmodb" : "J10" }, "pxl_vsync" : { "PIO_DIRECTION": "INPUT", "pmodb" : "J3" }, "pxl_href" : { "PIO_DIRECTION": "INPUT", "pmodb" : "J9" }, "CLK_xclk" : { "PIO_DIRECTION": "OUTPUT", "pmodb" : "J2" }, "pclk_v" : { "PIO_DIRECTION": "INPUT", "pmodb" : "J8" }, "pxl_data[6]": { "PIO_DIRECTION": "INPUT", "pmodb" : "J1" }, "pxl_data[7]": { "PIO_DIRECTION": "INPUT", "pmodb" : "J7" }, "pxl_data[4]": { "PIO_DIRECTION": "INPUT", "pmoda" : "J4" }, "pxl_data[5]": { "PIO_DIRECTION": "INPUT", "pmoda" : "J10" }, "pxl_data[2]": { "PIO_DIRECTION": "INPUT", "pmoda" : "J3" }, "pxl_data[3]": { "PIO_DIRECTION": "INPUT", "pmoda" : "J9" }, "pxl_data[0]": { "PIO_DIRECTION": "INPUT", "pmoda" : "J2" }, "pxl_data[1]": { "PIO_DIRECTION": "INPUT", "pmoda" : "J8" }, "pwdn" : { "PIO_DIRECTION": "OUTPUT", "pmoda" : "J1" }, "reset" : { "PIO_DIRECTION": "OUTPUT", "pmoda" : "J7" }, "i2c1_SCL" : { "PIO_DIRECTION": "OUTPUT", "pmodc" : "J3" }, "i2c1_SDA" : { "PIO_DIRECTION": "BIDIR", "PULLTYPE": "PULLUP", "pmodc" : "J4" }, "i2c2_SCL" : { "PIO_DIRECTION": "OUTPUT", "pmodd" : "J3" }, "i2c2_SDA" : { "PIO_DIRECTION": "BIDIR", "PULLTYPE": "PULLUP", "pmodd" : "J4" } } ================================================ FILE: tests/ov7670/testcam.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "dmaManager.h" #include "Ov7670ControllerRequest.h" #include "Ov7670ControllerIndication.h" int slaveaddr[3]; int addr; sem_t bit_sem; class Ov7670ControllerIndication : public Ov7670ControllerIndicationWrapper { int datacount; int gapcount; public: Ov7670ControllerIndication(unsigned int id) : Ov7670ControllerIndicationWrapper(id), datacount(0), gapcount(0) {} ~Ov7670ControllerIndication() {} virtual void i2cResponse(uint8_t bus, uint8_t data) { fprintf(stderr, "i2c bus %d device %d addr %x response %02x\n", bus, slaveaddr[bus], addr, data); sem_post(&bit_sem); } virtual void vsync(uint32_t cycles, uint8_t href) { //fprintf(stderr, "vsync %8d href %d\n", cycles, href); if (datacount) { fprintf(stderr, "vsync datacount=%8d gapcount=%8d\n", datacount, gapcount); datacount = 0; gapcount = 0; } } virtual void data(uint8_t first, uint8_t gap, uint8_t data) { //if (gap) fprintf(stderr, "data %8x first %d gap %d\n", data, first, gap); datacount++; if (gap) gapcount++; } virtual void frameStarted(uint8_t first) { //if (first) fprintf(stderr, "frameStarted %d\n", first); } virtual void frameTransferred() { //fprintf(stderr, "frameTransferred\n"); } virtual void data4(uint32_t data) { } }; int main(int argc, const char **argv) { DmaManager *dma = platformInit(); Ov7670ControllerRequestProxy device(IfcNames_Ov7670ControllerRequestS2H); Ov7670ControllerIndication deviceResponse(IfcNames_Ov7670ControllerIndicationH2S); int len = 640*480*4; int nfbAlloc = portalAlloc(4096, 0); unsigned int *nfbBuffer = (unsigned int *)portalMmap(nfbAlloc, 4096); unsigned int ref_nfbAlloc = dma->reference(nfbAlloc); int fbAlloc = portalAlloc(len, 0); unsigned int *fbBuffer = (unsigned int *)portalMmap(fbAlloc, len); unsigned int ref_fbAlloc = dma->reference(fbAlloc); sem_init(&bit_sem, 0, 0); device.setPowerDown(0); device.setReset(0); sleep(1); device.setReset(1); sleep(1); fprintf(stderr, "ref_fbAlloc=%d\n", ref_fbAlloc); device.setFramePointer(ref_fbAlloc); // register reset device.i2cRequest(0, 1, 0x21, 0x12, 0x80); // hsync instead of href //device.i2cRequest(0, 1, 0x21, 0x15, 0x40); // always has href // device.i2cRequest(0, 1, slaveaddr[0], 0x3c, 0x80); slaveaddr[0] = 0x21; slaveaddr[1] = 0x1e; slaveaddr[2] = 0x69; addr = 0x5a; for (int i = 0; i < 128; i++) { int write = 0; int val = 0x33; addr = i; device.i2cRequest(0, write, slaveaddr[0], addr, val); if (!write) sem_wait(&bit_sem); device.i2cRequest(1, write, slaveaddr[1], addr, val); if (!write) sem_wait(&bit_sem); device.i2cRequest(2, write, slaveaddr[2], addr, val); if (!write) sem_wait(&bit_sem); } if (1) { // product ID: 0x76 device.i2cRequest(0, 0, slaveaddr[0], 0x0a, 0); sem_wait(&bit_sem); // product VER: 0x70 device.i2cRequest(0, 0, slaveaddr[0], 0x0b, 0); sem_wait(&bit_sem); // mfg id: 0x7F device.i2cRequest(0, 0, slaveaddr[0], 0x1c, 0); sem_wait(&bit_sem); // mfg id: 0xA2 device.i2cRequest(0, 0, slaveaddr[0], 0x1d, 0); sem_wait(&bit_sem); } for (int i = 0; i < 64; i++) fprintf(stderr, " %02x", fbBuffer[i] & 0xff); fprintf(stderr, "\n"); return 0; } ================================================ FILE: tests/partial/Bounce.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Pipe::*; typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); interface Bounce; interface PipeOut#(Bit#(32)) outDelay; interface PipeIn#(Bit#(32)) inDelay; interface PipeOut#(EchoPair) outPair; interface PipeIn#(EchoPair) inPair; endinterface ================================================ FILE: tests/partial/Bounce1.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import Pipe::*; import Bounce::*; (* synthesize *) module mkBounce(Bounce); FIFOF#(Bit#(32)) delay <- mkSizedFIFOF(8); FIFOF#(EchoPair) delay2 <- mkSizedFIFOF(8); interface outDelay = toPipeOut(delay); interface inDelay = toPipeIn(delay); interface outPair = toPipeOut(delay2); interface inPair = toPipeIn(delay2); endmodule ================================================ FILE: tests/partial/Bounce2.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import Pipe::*; import Bounce::*; (* synthesize *) module mkBounce(Bounce); FIFOF#(Bit#(32)) delay <- mkSizedFIFOF(8); FIFOF#(EchoPair) delay2 <- mkSizedFIFOF(8); interface outDelay = toPipeOut(delay); interface PipeIn inDelay; method Action enq(Bit#(32) v); delay.enq(v + 32); endmethod method Bool notFull(); return delay.notFull; endmethod endinterface interface outPair = toPipeOut(delay2); interface PipeIn inPair; method Action enq(EchoPair v); delay2.enq(EchoPair {b:v.a, a:v.b}); endmethod method Bool notFull(); return delay2.notFull; endmethod endinterface endmodule ================================================ FILE: tests/partial/Bounce3.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import FIFOF::*; import Pipe::*; import Bounce::*; (* synthesize *) module mkBounce(Bounce); FIFOF#(Bit#(32)) delay <- mkSizedFIFOF(8); FIFOF#(EchoPair) delay2 <- mkSizedFIFOF(8); interface outDelay = toPipeOut(delay); interface PipeIn inDelay; method Action enq(Bit#(32) v); delay.enq(v * 2); endmethod method Bool notFull(); return delay.notFull; endmethod endinterface interface outPair = toPipeOut(delay2); interface PipeIn inPair; method Action enq(EchoPair v); delay2.enq(EchoPair {b:v.a + 2, a:v.b - 2}); endmethod method Bool notFull(); return delay2.notFull; endmethod endinterface endmodule ================================================ FILE: tests/partial/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Bounce::*; `ifdef RedefInstance import `RedefInstance::*; `endif import Pipe::*; interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface Echo; interface EchoRequest request; endinterface module mkEcho#(EchoIndication indication)(Echo); Bounce bounce <- mkBounce(); rule heard; bounce.outDelay.deq(); indication.heard(bounce.outDelay.first); endrule rule heard2; bounce.outPair.deq(); indication.heard2(bounce.outPair.first.b, bounce.outPair.first.a); endrule interface EchoRequest request; method Action say(Bit#(32) v); bounce.inDelay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); bounce.inPair.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: tests/partial/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:Echo.request H2S_INTERFACES = Echo:EchoIndication BSVFILES = Echo.bsv CPPFILES= testecho.cpp VARIANT?=1 VARIANT_LIST = 2 3 PARTIAL_MODULE = Bounce RECONFIG_MODULE = lEcho_bounce CONNECTALFLAGS += -P mk$(PARTIAL_MODULE) --implconstraint=floorplan-$(BOARD).xdc -DRedefInstance=$(PARTIAL_MODULE)$(VARIANT) include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/partial/README ================================================ To program PR bitfile: echo 1 /sys/devices/amba.2/f8007000.devcfg/is_partial_bitstream cat variant2/Impl/ReTop/mkTop_pblock_lEcho_bounce_partial.bin >/dev/xdevcfg cat variant2/Impl/ReTop/mkTop_pblock_lEcho_bounce_partial.bin >/dev/xdevcfg ./android.exe Note: is_partial_bitstream is persistent ================================================ FILE: tests/partial/floorplan-zc702.xdc ================================================ create_pblock pblock_lEcho_bounce add_cells_to_pblock [get_pblocks pblock_lEcho_bounce] [get_cells -quiet [list top/lEcho_bounce]] resize_pblock [get_pblocks pblock_lEcho_bounce] -add {SLICE_X34Y100:SLICE_X47Y149} resize_pblock [get_pblocks pblock_lEcho_bounce] -add {DSP48_X2Y40:DSP48_X2Y59} set_property SNAPPING_MODE ON [get_pblocks pblock_lEcho_bounce] ================================================ FILE: tests/partial/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); int v = 42; printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: tests/pcie-debug/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = EchoRequest:TracePcie.request ChangeRequest:TracePcie.changeRequest H2S_INTERFACES = TracePcie:ChangeIndication:host TracePcie:EchoIndication BSVFILES = TracePcie.bsv CPPFILES= tracepcie.cpp CONNECTALFLAGS += -D TRACE_PORTAL CONNECTALFLAGS += -D IMPORT_HOSTIF -D PCIE_CHANGES_HOSTIF -D TracePcieStateMachine CONNECTALFLAGS += -D PCIE_CHANGES_SERIAL CONNECTALFLAGS += -D PCIE_CHANGES_UART CONNECTALFLAGS += -D PCIE_ALT_BRAM_SERVER -D PCIE_TRACE_PORT PINOUT_FILE += pin_translation.json PIN_TYPE = TestPins PIN_TYPE_INCLUDE = TestPins AUTOTOP = --interface pins:TracePcie.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/pcie-debug/TestPins.bsv ================================================ import Clocks::*; (* always_ready, always_enabled *) interface UartPins; method Bit#(1) sout(); method Action sin(Bit#(1) v); interface Clock deleteme_unused_clock; endinterface interface TestPins; interface UartPins uart; endinterface ================================================ FILE: tests/pcie-debug/TracePcie.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFO::*; import FIFOF::*; import Vector::*; `ifdef PCIE_CHANGES_HOSTIF import BuildVector::*; import ClientServer::*; import BRAM::*; import Clocks::*; import GetPut::*; import Pipe::*; import Probe::*; import HostInterface::*; import Gearbox::*; import RS232::*; import TestPins::*; import PcieTracer::*; `ifdef PCIE3 import Pcie3EndpointX7::*; `else import PcieStateChanges::*; `endif interface ChangeRequest; method Action setDivisor(Bit#(16) v); method Action putchar(Bit#(8) c); endinterface interface ChangeIndication; method Action change(Bit#(32) timestamp, Bit#(8) src, Bit#(24) value); method Action changeByte(Bit#(8) c); endinterface `endif // these are here so the app can drive some traffic interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface interface TracePcie; interface EchoRequest request; interface ChangeRequest changeRequest; `ifdef PCIE_CHANGES_UART interface TestPins pins; `endif endinterface typedef struct { Bit#(16) a; Bit#(16) b; } EchoPair deriving (Bits); (* synthesize *) module mkTraceGearbox(Gearbox#(TAdd#(TMul#(2,TDiv#(SizeOf#(TimestampedTlpData),8)),2), 1, Bit#(8))); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; let gb <- mkNto1Gearbox(clock, reset, clock, reset); return gb; endmodule module mkTracePcie#( `ifdef PCIE_CHANGES_HOSTIF HostInterface host, ChangeIndication changeIndication, `endif EchoIndication indication )(TracePcie); FIFO#(Bit#(32)) delay <- mkSizedFIFO(8); FIFO#(EchoPair) delay2 <- mkSizedFIFO(8); rule heard; delay.deq; indication.heard(delay.first); endrule rule heard2; delay2.deq; indication.heard2(delay2.first.b, delay2.first.a); endrule `ifdef PCIE_CHANGES_HOSTIF `ifdef PCIE_CHANGES_SERIAL let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; Gearbox#(18, 1, Bit#(8)) serializeGearbox <- mkNto1Gearbox(clock, reset, clock, reset); `ifdef PCIE_CHANGES_UART Reg#(Bit#(16)) uartDivisor <- mkReg(136); UART#(128) uart <- mkUART(8, NONE, STOP_1, uartDivisor); `endif function Bit#(8) toHex(Bit#(4) v); if (v >= 0 && v <= 9) return 48 + zeroExtend(v); else return 97 + zeroExtend(v) - 10; endfunction function Vector#(TMul#(2,len),Bit#(8)) toHexVector(Vector#(len, Bit#(8)) bytes); Vector#(TMul#(2,len),Bit#(8)) chars; for (Integer i = 0; i < valueOf(len); i = i + 1) begin chars[2 * i + 0] = toHex(bytes[i][3:0]); chars[2 * i + 1] = toHex(bytes[i][7:4]); end return chars; endfunction Vector#(2, Bit#(8)) endl = vec(10, 13); rule rl_changes; Bit#(64) bits <- toGet(host.tchanges).get(); Vector#(8, Bit#(8)) bytes = unpack(bits); Vector#(18, Bit#(8)) chars = append(reverse(toHexVector(bytes)), endl); serializeGearbox.enq(chars); endrule `ifdef DISABLE rule rl_serial; Bit#(8) char = serializeGearbox.first()[0]; serializeGearbox.deq(); `ifndef PCIE_CHANGES_UART changeIndication.changeByte(char); `else uart.rx.put(char); `endif endrule `endif Reg#(Bit#(12)) traceAddrReg <- mkReg(0); Reg#(Bool) requested <- mkReg(False); Gearbox#(TAdd#(TMul#(2,TDiv#(SizeOf#(TimestampedTlpData),8)),2), 1, Bit#(8)) testGearbox <- mkTraceGearbox(); Gearbox#(TAdd#(TMul#(2,TDiv#(SizeOf#(TimestampedTlpData),8)),2), 1, Bit#(8)) traceGearbox <- mkTraceGearbox(); FIFOF#(Bit#(8)) testFifo <- mkFIFOF(); FIFOF#(Bit#(8)) traceFifo <- mkFIFOF(); Reg#(Bool) testPattern <- mkReg(False); rule rl_testpattern if (!testPattern); testPattern <= True; Vector#(TDiv#(SizeOf#(TimestampedTlpData),8), Bit#(8)) tracebytes; for (Integer i = 0; i < valueOf(TDiv#(SizeOf#(TimestampedTlpData),8)); i = i + 1) begin tracebytes[i]= fromInteger(i); end let bytes = append(reverse(toHexVector(tracebytes)), endl); testGearbox.enq(bytes); endrule rule rl_test_pipeline; let char = testGearbox.first()[0]; testGearbox.deq(); testFifo.enq(char); endrule rule rl_trace_from_pcie_req if (!requested && testPattern); if (traceAddrReg < extend(host.tpciehost.tlpTraceBramWrAddr)) begin host.tpciehost.traceBramServer.request.put(BRAMRequest { write: False, responseOnWrite: False, address: traceAddrReg, datain: ? }); requested <= True; end endrule rule rl_trace_from_pcie_resp if (requested); let resp <- host.tpciehost.traceBramServer.response.get(); Bit#(SizeOf#(TimestampedTlpData)) tracebits = pack(resp); Vector#(TDiv#(SizeOf#(TimestampedTlpData),8), Bit#(8)) tracebytes = unpack(tracebits); let bytes = append(reverse(toHexVector(tracebytes)), endl); // wait until there is a valid entry if (True) begin traceGearbox.enq(bytes); traceAddrReg <= traceAddrReg + 1; end requested <= False; endrule rule rl_trace_pipeline; let char = traceGearbox.first()[0]; traceGearbox.deq(); traceFifo.enq(char); endrule rule rl_trace_serial; if (testFifo.notEmpty()) begin Bit#(8) char = testFifo.first(); testFifo.deq(); uart.rx.put(char); end else if (traceFifo.notEmpty()) begin Bit#(8) char = traceFifo.first(); traceFifo.deq(); uart.rx.put(char); end endrule `else rule rl_changes; Bit#(64) bits <- toGet(host.tchanges).get(); RegChange change = unpack(bits); changeIndication.change(change.timestamp, change.src, change.value); endrule `endif `endif `ifdef PCIE_CHANGES_UART interface TestPins pins; interface UartPins uart; method sin = uart.rs232.sin; method sout = uart.rs232.sout; interface Clock deleteme_unused_clock = clock; endinterface endinterface interface ChangeRequest changeRequest; method Action setDivisor(Bit#(16) v); uartDivisor <= v; endmethod method Action putchar(Bit#(8) c); uart.rx.put(c); endmethod endinterface `endif interface EchoRequest request; method Action say(Bit#(32) v); delay.enq(v); endmethod method Action say2(Bit#(16) a, Bit#(16) b); delay2.enq(EchoPair { a: a, b: b}); endmethod method Action setLeds(Bit#(8) v); endmethod endinterface endmodule ================================================ FILE: tests/pcie-debug/pin_translation.json ================================================ { "uart_sout": { "uart": "d_out" }, "uart_sin_v": { "uart": "d_in" } } ================================================ FILE: tests/pcie-debug/tracepcie.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include "ChangeRequest.h" #include "ChangeIndication.h" #include "EchoIndication.h" #include "EchoRequest.h" #include "GeneratedTypes.h" static EchoRequestProxy *echoRequestProxy = 0; static ChangeRequestProxy *changeRequestProxy = 0; static sem_t sem_heard2; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard(uint32_t v) { printf("heard an echo: %d\n", v); echoRequestProxy->say2(v, 2*v); } virtual void heard2(uint16_t a, uint16_t b) { sem_post(&sem_heard2); //printf("heard an echo2: %ld %ld\n", a, b); } EchoIndication(unsigned int id) : EchoIndicationWrapper(id) {} }; class ChangeIndication : public ChangeIndicationWrapper { public: virtual void change(uint32_t timestamp, uint8_t src, uint32_t value) { fprintf(stderr, "PCIE change at %08d: src=%#x value=%#04x\n", timestamp, src, value); } virtual void changeByte(uint8_t c) { fputc(c, stderr); } ChangeIndication(unsigned int id) : ChangeIndicationWrapper(id) {} }; static void call_say(int v) { printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, v); echoRequestProxy->say(v); sem_wait(&sem_heard2); } static void call_say2(int v, int v2) { echoRequestProxy->say2(v, v2); sem_wait(&sem_heard2); } int main(int argc, const char **argv) { long actualFrequency = 0; long requestedFrequency = 1e9 / MainClockPeriod; EchoIndication echoIndication(IfcNames_EchoIndicationH2S); echoRequestProxy = new EchoRequestProxy(IfcNames_EchoRequestS2H); changeRequestProxy = new ChangeRequestProxy(IfcNames_ChangeRequestS2H); ChangeIndication changeIndication(IfcNames_ChangeIndicationH2S); int status = setClockFrequency(0, requestedFrequency, &actualFrequency); fprintf(stderr, "Requested main clock frequency %5.2f, actual clock frequency %5.2f MHz status=%d errno=%d\n", (double)requestedFrequency * 1.0e-6, (double)actualFrequency * 1.0e-6, status, (status != 0) ? errno : 0); int v = 42; const char *msg = "Hello World\n"; for (unsigned int i = 0; i < strlen(msg); i++) { changeRequestProxy->putchar(msg[i]); } printf("Saying %d\n", v); call_say(v); call_say(v*5); call_say(v*17); call_say(v*93); call_say2(v, v*3); printf("TEST TYPE: SEM\n"); echoRequestProxy->setLeds(9); return 0; } ================================================ FILE: tests/pciememcheck/CheckMPM.bsv ================================================ import BRAM :: *; import Connectable :: *; import DefaultValue :: *; import FIFO :: *; import GetPut :: *; import PCIE :: *; import StmtFSM :: *; import Vector :: *; import BlueCheck :: *; import ConnectalMemTypes :: *; import PcieToMem :: *; import PcieTracer :: *; import PhysMemSlaveFromBram :: *; import MemToPcie :: *; module mkRefMem(PhysMemSlave#(32, 32)); BRAM_Configure cfg = defaultValue; cfg.memorySize = 32*1024; BRAM1Port#(Bit#(32), Bit#(32)) bramPort <- mkBRAM1Server(cfg); BRAMServer#(Bit#(32), Bit#(32)) br = bramPort.portA; PhysMemSlave#(32, 32) bramPhysMem <- mkPhysMemSlaveFromBram(br); return bramPhysMem; endmodule module mkMemToPcieToMem(PhysMemSlave#(40, 32)); PciId my_id = defaultValue; MemToPcie#(32) memToPcie <- mkMemToPcie(my_id); PcieToMem pcieToMem <- mkPcieToMem(my_id); BRAM_Configure cfg = defaultValue; cfg.memorySize = 32*1024; BRAM1Port#(Bit#(32), Bit#(32)) bramPort <- mkBRAM1Server(cfg); BRAMServer#(Bit#(32), Bit#(32)) br = bramPort.portA; PhysMemSlave#(32, 32) bramPhysMem <- mkPhysMemSlaveFromBram(br); //mkConnection(memToPcie.tlp.request, pcieToMem.tlp.response); //mkConnection(memToPcie.tlp.response, pcieToMem.tlp.request); //mkConnection(pcieToMem.master, bramPhysMem); let fhandle <- mkReg(InvalidFile); let didOnce <- mkReg(False); rule once if (!didOnce); //let mcd <- $fopen("pcielog.txt", "w"); //fhandle <= mcd; didOnce <= True; endrule Reg#(Bit#(32)) cycles <- mkReg(0); rule rl_cycles; cycles <= cycles + 1; endrule rule rl_to_bram; let tlp <- memToPcie.tlp.request.get(); pcieToMem.tlp.response.put(tlp); TimestampedTlpData ttd = TimestampedTlpData { tlp: tlp, source: 4, timestamp: cycles }; //$fwriteh(fhandle, ttd); $display("tracetb %h", ttd); endrule rule rl_from_bram; let tlp <- pcieToMem.tlp.request.get(); memToPcie.tlp.response.put(tlp); TimestampedTlpData ttd = TimestampedTlpData { tlp: tlp, source: 8, timestamp: cycles }; //$fwriteh(fhandle, ttd); $display("tracefb %h", ttd); endrule rule rl_rd_addr; let req <- pcieToMem.master.read_client.readReq.get(); bramPhysMem.read_server.readReq.put(req); $display("impl read %x tag %x", req.addr[5:2], req.tag); endrule rule rl_wr_addr; let req <- pcieToMem.master.write_client.writeReq.get(); bramPhysMem.write_server.writeReq.put(req); $display("impl write %x tag %x", req.addr[5:2], req.tag); endrule rule rl_rd_data; let md <- bramPhysMem.read_server.readData.get(); pcieToMem.master.read_client.readData.put(md); $display("impl read data %x tag %x", md.data, md.tag); endrule rule rl_wr_data; let md <- pcieToMem.master.write_client.writeData.get(); bramPhysMem.write_server.writeData.put(md); $display("impl write data %x tag %x", md.data, md.tag); endrule rule rl_wr_done; let tag <- bramPhysMem.write_server.writeDone.get(); pcieToMem.master.write_client.writeDone.put(tag); $display("impl write done tag %x", tag); endrule return memToPcie.slave; endmodule typedef struct { Bool write; Bit#(12) address; Bit#(32) data; Bit#(MemTagSize) tag; } Req deriving (Bits, Eq, FShow); module [BlueCheck] checkMPM(Empty); let verbose = True; PhysMemSlave#(32, 32) refmem <- mkRefMem(); PhysMemSlave#(40, 32) pciemem <- mkMemToPcieToMem(); FIFO#(Bool) isWriteFifo <- mkSizedFIFO(128); FIFO#(Bit#(4)) doneFifo <- mkSizedFIFO(128); FIFO#(Bit#(4)) addrFifo <- mkSizedFIFO(128); Vector#(16, FIFO#(Bool)) scoreboard <- replicateM(mkFIFO1); Vector#(16, FIFO#(Bool)) tagscoreboard <- replicateM(mkFIFO1); let writeDataFifo <- mkSizedFIFO(128); rule rl_write_data; let writeData <- toGet(writeDataFifo).get(); refmem.write_server.writeData.put(writeData); pciemem.write_server.writeData.put(writeData); if (verbose) $display("rl_write_data %h tag %h", writeData.data, writeData.tag); endrule rule rl_write_done; let address <- toGet(doneFifo).get(); let reftag <- refmem.write_server.writeDone.get(); let pcietag <- pciemem.write_server.writeDone.get(); scoreboard[address].deq(); tagscoreboard[reftag].deq(); if (verbose) $display("reftag %x", reftag); endrule function Action sendPhysMemReq(Bool write, Bit#(4) address, Bit#(32) data, Bit#(4) tag); return (action PhysMemRequest#(32, 32) refreq = PhysMemRequest { addr: zeroExtend(address) << 2, burstLen: 4, tag: zeroExtend(tag) }; PhysMemRequest#(40, 32) pciereq = PhysMemRequest { addr: zeroExtend(address) << 2, burstLen: 4, tag: zeroExtend(tag) }; $display((write ? "write " : "read "), address, " data ", data, " tag ", tag); isWriteFifo.enq(write); scoreboard[address].enq(True); tagscoreboard[tag].enq(True); if (write) begin MemData#(32) writeData = MemData {data: data, tag: zeroExtend(tag), last: True }; refmem.write_server.writeReq.put(refreq); pciemem.write_server.writeReq.put(pciereq); writeDataFifo.enq(writeData); doneFifo.enq(address); end else begin refmem.read_server.readReq.put(refreq); pciemem.read_server.readReq.put(pciereq); addrFifo.enq(address); end endaction); endfunction ActionValue#(Bool) checkPhysMemResp = (actionvalue let isWrite <- toGet(isWriteFifo).get(); if (isWrite) begin return True; end else begin let address <- toGet(addrFifo).get(); let refresp <- refmem.read_server.readData.get(); let pcieresp <- pciemem.read_server.readData.get(); if (verbose) $display("refresp ", address, " data ", refresp.data, " tag ", refresp.tag, " pcieresp ", pcieresp.data, " tag ", pcieresp.tag); scoreboard[address].deq(); tagscoreboard[refresp.tag].deq(); return refresp == pcieresp; end endactionvalue); prop("read", sendPhysMemReq(False)); prop("write", sendPhysMemReq(True)); prop("check", checkPhysMemResp); endmodule interface PcieMemChecker; interface FSM fsm; method Action start(Bit#(32) numIterations, Bool verbose); method ActionValue#(Bool) done(); endinterface (* synthesize *) module [Module] mkPcieMemChecker(PcieMemChecker); BlueCheck_Params params = bcParams; Reg#(Bit#(32)) numIterations <- mkReg(100000); params.numIterations = numIterations; params.verbose = True; let test <- mkModelChecker(checkMPM, params); Reg#(Bool) started <- mkReg(False); let _fsm <- mkFSM(test); interface fsm = _fsm; method Action start(Bit#(32) numiters, Bool v) if (!started); numIterations <= numiters; _fsm.start(); started <= True; endmethod method ActionValue#(Bool) done() if (started && _fsm.done); started <= False; return True; endmethod endmodule ================================================ FILE: tests/pciememcheck/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = PcieMemCheckRequest:PcieMemCheck.request H2S_INTERFACES = PcieMemCheck:PcieMemCheckIndication BSVFILES = PcieMemCheck.bsv CPPFILES = pciememcheck.cpp CONNECTALFLAGS += -D USE_ACP -P mkConnectalTop include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/pciememcheck/PcieMemCheck.bsv ================================================ import BRAM :: *; import Connectable :: *; import GetPut :: *; import DefaultValue :: *; import PCIE :: *; import StmtFSM :: *; import BlueCheck :: *; import CheckMPM :: *; import ConnectalMemTypes :: *; import PcieToMem :: *; import PhysMemSlaveFromBram :: *; import MemToPcie :: *; interface PcieMemCheckRequest; method Action startCheck(Bit#(32) numIterations, Bool verbose); endinterface interface PcieMemCheckIndication; method Action checkFinished(); endinterface interface PcieMemCheck; interface PcieMemCheckRequest request; endinterface module [Module] mkPcieMemCheck#(PcieMemCheckIndication ind)(PcieMemCheck); PcieMemChecker checker <- mkPcieMemChecker(); rule rl_done; let done <- checker.done(); ind.checkFinished(); endrule interface PcieMemCheckRequest request; method Action startCheck(Bit#(32) numIterations, Bool verbose); checker.start(numIterations, verbose); endmethod endinterface endmodule ================================================ FILE: tests/pciememcheck/pciememcheck.cpp ================================================ #include #include #include #include #include volatile int done = 0; class PcieMemCheckIndication : public PcieMemCheckIndicationWrapper { public: virtual void checkFinished() { fprintf(stderr, "finished\n"); done = 1; } PcieMemCheckIndication(unsigned int id) : PcieMemCheckIndicationWrapper(id) {} }; int main(int argc, char* const*argv) { int opt; int numIterations = 100000; int verbose = 0; while ((opt = getopt(argc, argv, "n:v")) != -1) { switch (opt) { case 'n': numIterations = strtoul(optarg, 0, 0); break; case 'v': verbose = 1; break; } } fprintf(stderr, "numIterations=%d\n", numIterations); PcieMemCheckRequestProxy *request = new PcieMemCheckRequestProxy(IfcNames_PcieMemCheckRequestS2H); request->startCheck(numIterations, verbose); while (!done) { sleep(1); } return 0; } ================================================ FILE: tests/physmaster/Echo.bsv ================================================ // Copyright (c) 2013 Nokia, Inc. // Copyright (c) 2013 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface EchoIndication; method Action heard(Bit#(32) v); method Action heard2(Bit#(16) a, Bit#(16) b); endinterface interface EchoRequest; method Action say(Bit#(32) v); method Action say2(Bit#(16) a, Bit#(16) b); method Action setLeds(Bit#(8) v); endinterface ================================================ FILE: tests/physmaster/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = EchoRequest EchoIndication PhysMemMasterRequest PhysMemMasterIndication BSVFILES = Echo.bsv PhysReq.bsv CPPFILES=daemon.cpp CPPFILES2=testecho.cpp CONNECTALFLAGS += --nohardware AUTOTOP= --portname IfcNames_PhysMemMasterIndication --portname IfcNames_PhysMemMasterRequest include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/physmaster/PhysReq.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import ConnectalMemTypes::*; typedef 6 MemTagSize; typedef 40 PhysAddrWidth; typedef 10 BurstLenSize; typedef 64 DataBusWidth; typedef struct { Bit#(addrWidth) addr; Bit#(BurstLenSize) burstLen; Bit#(MemTagSize) tag; } PhysMemRequest#(numeric type addrWidth) deriving (Bits); typedef struct { Bit#(dsz) data; Bit#(MemTagSize) tag; Bool last; } MemData#(numeric type dsz) deriving (Bits); interface PhysMemMasterRequest; method Action readReq(PhysMemRequest#(PhysAddrWidth) v); method Action writeReq(PhysMemRequest#(PhysAddrWidth) v); method Action writeData(MemData#(DataBusWidth) v); endinterface interface PhysMemMasterIndication; method Action readData(MemData#(DataBusWidth) v); method Action writeDone(Bit#(MemTagSize) v); endinterface ================================================ FILE: tests/physmaster/daemon.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "PhysMemMasterRequest.h" #include "PhysMemMasterIndication.h" PhysMemMasterIndicationProxy *sIndicationProxy; static int daemon_trace = 1; class PhysMemMasterRequest : public PhysMemMasterRequestWrapper { public: void readReq ( const PhysMemRequestL_PhysAddrWidth_P v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); //sIndicationProxy->heard(v); } void writeReq ( const PhysMemRequestL_PhysAddrWidth_P v ) { if (daemon_trace) fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); //sIndicationProxy->heard2(a, b); } void writeData ( const MemDataL_DataBusWidth_P v ) { fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); sleep(1); exit(1); } void disconnect (void) { fprintf(stderr, "daemon[%s:%d]\n", __FUNCTION__, __LINE__); sleep(1); exit(1); } PhysMemMasterRequest(unsigned int id, PortalTransportFunctions *item, void *param) : PhysMemMasterRequestWrapper(id, item, param) {} }; int main(int argc, const char **argv) { sIndicationProxy = new PhysMemMasterIndicationProxy(IfcNames_PhysMemMasterIndication, &transportSocketResp, NULL); PhysMemMasterRequest sRequest(IfcNames_PhysMemMasterRequest, &transportSocketResp, NULL); printf("[%s:%d] daemon sleeping...\n", __FUNCTION__, __LINE__); while(1) sleep(100); return 0; } ================================================ FILE: tests/physmaster/testecho.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "PhysMemMasterRequest.h" #include "PhysMemMasterIndication.h" PhysMemMasterRequestProxy *sRequestProxy; static sem_t sem_heard2; class PhysMemMasterIndication : public PhysMemMasterIndicationWrapper { public: void readData ( const MemDataL_DataBusWidth_P v ) { fprintf(stderr, "heard an s: %lld\n", (long long)v.data); //sRequestProxy->say2(v, 2*v); } void writeDone ( const uint8_t v ) { sem_post(&sem_heard2); //fprintf(stderr, "heard an s2: %ld %ld\n", a, b); } PhysMemMasterIndication(unsigned int id, PortalTransportFunctions *item, void *param) : PhysMemMasterIndicationWrapper(id, item, param) {} }; //sem_wait(&sem_heard2); int main(int argc, const char **argv) { PhysMemMasterIndication sIndication(IfcNames_PhysMemMasterIndication, &transportSocketInit, NULL); sRequestProxy = new PhysMemMasterRequestProxy(IfcNames_PhysMemMasterRequest, &transportSocketInit, NULL); int v = 42; fprintf(stderr, "Saying %d\n", v); //call_say(v); portal_disconnect(&sRequestProxy->pint); return 0; } ================================================ FILE: tests/qemuaccel/AccelIfcNames.bsv ================================================ typedef enum {AccelIfcNamesNone=0, PlatformAccelIfcNames_MemServerRequestS2H=1, PlatformAccelIfcNames_MMURequestS2H=2, PlatformAccelIfcNames_MemServerIndicationH2S=3, PlatformAccelIfcNames_MMUIndicationH2S=4, AccelIfcNames_SerialIndicationH2S=5, AccelIfcNames_SimpleRequestH2S=6, AccelIfcNames_BlockDevResponseH2S=7, AccelIfcNames_SerialRequestS2H=8, AccelIfcNames_SimpleRequestS2H=9, AccelIfcNames_BlockDevRequestS2H=10 } AccelIfcNames deriving (Eq,Bits); ================================================ FILE: tests/qemuaccel/AccelTop.bsv ================================================ `include "ConnectalProjectConfig.bsv" import ConnectalConfig::*; import Vector::*; import BuildVector::*; import Portal::*; import CtrlMux::*; import HostInterface::*; import Connectable::*; import MemReadEngine::*; import MemWriteEngine::*; import ConnectalMemTypes::*; import MemServer::*; import AccelIfcNames::*; `ifdef PinTypeInclude import `PinTypeInclude::*; `endif import SerialIndication::*; import Serial::*; import SimpleRequest::*; import Simple::*; import BlockDevResponse::*; import BlockDev::*; import SerialRequest::*; import SimpleRequest::*; import BlockDevRequest::*; interface Pins; interface SerialPort pins0; interface BlockDevClient pins1; endinterface `ifndef IMPORT_HOSTIF (* synthesize *) `endif module mkAccelTop `ifdef IMPORT_HOSTIF // no synthesis boundary #(HostInterface host) `else `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary #(Clock derivedClockIn, Reset derivedResetIn) `else // otherwise no params `endif `endif (ConnectalTop#(Pins)); Clock defaultClock <- exposeCurrentClock(); Reset defaultReset <- exposeCurrentReset(); `ifdef IMPORT_HOST_CLOCKS // enables synthesis boundary HostInterface host = (interface HostInterface; interface Clock derivedClock = derivedClockIn; interface Reset derivedReset = derivedResetIn; endinterface); `endif BlockDevRequestInput lBlockDevRequestInput <- mkBlockDevRequestInput; BlockDevResponseOutput lBlockDevResponseOutput <- mkBlockDevResponseOutput; SerialIndicationOutput lSerialIndicationOutput <- mkSerialIndicationOutput; SerialRequestInput lSerialRequestInput <- mkSerialRequestInput; SimpleRequestInput lSimpleRequestInput <- mkSimpleRequestInput; SimpleRequestOutput lSimpleRequestOutput <- mkSimpleRequestOutput; Serial lSerial <- mkSerial(lSerialIndicationOutput.ifc); Simple lSimple <- mkSimple(lSimpleRequestOutput.ifc); BlockDev lBlockDev <- mkBlockDev(lBlockDevResponseOutput.ifc); mkConnection(lBlockDevRequestInput.pipes, lBlockDev.request); mkConnection(lSerialRequestInput.pipes, lSerial.request); mkConnection(lSimpleRequestInput.pipes, lSimple.request); Vector#(6,StdPortal) portals; PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_0 <- mkPortalCtrlMemSlave(extend(pack(AccelIfcNames_SerialIndicationH2S)), lSerialIndicationOutput.portalIfc.intr); let memslave_0 <- mkMemMethodMuxOut(ctrlPort_0.memSlave,lSerialIndicationOutput.portalIfc.indications); portals[0] = (interface MemPortal; interface PhysMemSlave slave = memslave_0; interface ReadOnly interrupt = ctrlPort_0.interrupt; interface WriteOnly num_portals = ctrlPort_0.num_portals; endinterface); PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_1 <- mkPortalCtrlMemSlave(extend(pack(AccelIfcNames_SimpleRequestH2S)), lSimpleRequestOutput.portalIfc.intr); let memslave_1 <- mkMemMethodMuxOut(ctrlPort_1.memSlave,lSimpleRequestOutput.portalIfc.indications); portals[1] = (interface MemPortal; interface PhysMemSlave slave = memslave_1; interface ReadOnly interrupt = ctrlPort_1.interrupt; interface WriteOnly num_portals = ctrlPort_1.num_portals; endinterface); PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_2 <- mkPortalCtrlMemSlave(extend(pack(AccelIfcNames_BlockDevResponseH2S)), lBlockDevResponseOutput.portalIfc.intr); let memslave_2 <- mkMemMethodMuxOut(ctrlPort_2.memSlave,lBlockDevResponseOutput.portalIfc.indications); portals[2] = (interface MemPortal; interface PhysMemSlave slave = memslave_2; interface ReadOnly interrupt = ctrlPort_2.interrupt; interface WriteOnly num_portals = ctrlPort_2.num_portals; endinterface); PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_3 <- mkPortalCtrlMemSlave(extend(pack(AccelIfcNames_SerialRequestS2H)), lSerialRequestInput.portalIfc.intr); let memslave_3 <- mkMemMethodMuxIn(ctrlPort_3.memSlave,lSerialRequestInput.portalIfc.requests); portals[3] = (interface MemPortal; interface PhysMemSlave slave = memslave_3; interface ReadOnly interrupt = ctrlPort_3.interrupt; interface WriteOnly num_portals = ctrlPort_3.num_portals; endinterface); PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_4 <- mkPortalCtrlMemSlave(extend(pack(AccelIfcNames_SimpleRequestS2H)), lSimpleRequestInput.portalIfc.intr); let memslave_4 <- mkMemMethodMuxIn(ctrlPort_4.memSlave,lSimpleRequestInput.portalIfc.requests); portals[4] = (interface MemPortal; interface PhysMemSlave slave = memslave_4; interface ReadOnly interrupt = ctrlPort_4.interrupt; interface WriteOnly num_portals = ctrlPort_4.num_portals; endinterface); PortalCtrlMemSlave#(SlaveControlAddrWidth,SlaveDataBusWidth) ctrlPort_5 <- mkPortalCtrlMemSlave(extend(pack(AccelIfcNames_BlockDevRequestS2H)), lBlockDevRequestInput.portalIfc.intr); let memslave_5 <- mkMemMethodMuxIn(ctrlPort_5.memSlave,lBlockDevRequestInput.portalIfc.requests); portals[5] = (interface MemPortal; interface PhysMemSlave slave = memslave_5; interface ReadOnly interrupt = ctrlPort_5.interrupt; interface WriteOnly num_portals = ctrlPort_5.num_portals; endinterface); let ctrl_mux <- mkSlaveMux(portals); Vector#(NumWriteClients,MemWriteClient#(DataBusWidth)) nullWriters = replicate(null_mem_write_client()); Vector#(NumReadClients,MemReadClient#(DataBusWidth)) nullReaders = replicate(null_mem_read_client()); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface readers = take(nullReaders); interface writers = take(nullWriters); `ifdef TOP_SOURCES_PORTAL_CLOCK interface portalClockSource = None; `endif interface Pins pins; interface pins0 = lSerial.port; interface pins1 = lBlockDev.client; endinterface endmodule : mkAccelTop export mkAccelTop; export `PinTypeInclude::*; export Pins(..); ================================================ FILE: tests/qemuaccel/BlockDev.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. typedef enum { BlockDevRead, BlockDevWrite } BlockDevOp deriving (Bits,Eq,FShow); import BuildVector::*; import ClientServer::*; import FIFOF::*; import GetPut::*; import Vector::*; import ConnectalConfig::*; import ConnectalMemory::*; import ConnectalMemTypes::*; import MemReadEngine::*; import MemWriteEngine::*; import Pipe::*; interface PortPair#(type ifc1, type ifc2); interface ifc1 port1; interface ifc2 port2; endinterface function PortPair#(ifc1, ifc2) portPair(ifc1 p1, ifc2 p2); return (interface PortPair#(ifc1,ifc2); interface port1 = p1; interface port2 = p2; endinterface); endfunction interface BlockDevRequest; method Action transfer(BlockDevOp op, Bit#(32) dramaddr, Bit#(32) offset, Bit#(32) size, Bit#(32) tag); endinterface interface BlockDevResponse; method Action transferDone(Bit#(32) tag); endinterface typedef struct { BlockDevOp op; Bit#(32) dramaddr; Bit#(32) offset; Bit#(32) size; Bit#(32) tag; } BlockDevTransfer deriving (Bits,Eq,FShow); typedef Client#(BlockDevTransfer,Bit#(32)) BlockDevClient; interface BlockDev; interface BlockDevRequest request; interface BlockDevClient client; endinterface typedef 1 CmdQDepth; module mkBlockDev#(BlockDevResponse ind)(BlockDev); FIFOF#(BlockDevTransfer) requestFifo <- mkFIFOF(); FIFOF#(Bit#(32)) responseFifo <- mkFIFOF(); rule rl_response; let response <- toGet(responseFifo).get(); ind.transferDone(response); endrule interface BlockDevRequest request; method Action transfer(BlockDevOp op, Bit#(32) dramaddr, Bit#(32) offset, Bit#(32) size, Bit#(32) tag); requestFifo.enq(BlockDevTransfer { op: op, dramaddr: dramaddr, offset: offset, size: size, tag: tag }); endmethod endinterface interface Client client; interface Get request = toGet(requestFifo); interface Put response = toPut(responseFifo); endinterface endmodule ================================================ FILE: tests/qemuaccel/Devices.bsv ================================================ import BlockDev::*; import Serial::*; import Simple::*; interface DevicesPorts; interface SerialPort serial; interface Client#(BlockDevTransfer,Bit#(32)) blockDev; endinterface interface Devices; interface SimpleRequest simple; interface SerialPort serial; interface BlockDevPort blockDev; interface DevicesPorts ports; endinterface module mkDevices#(SimpleIndication simpleIndication, SerialIndication serialIndication, BlockDevResponse blockDevResponse)(Devices); let simple <- mksimple(simpleIndication); let serial <- mkSerial(serialIndication); let blockDev <- mkBlockDev(blockDevResponse); interface SimpleRequest simple= simple.request; interface SerialPort serial = serial.request; interface BlockDevPort blockDev = blockDev.request; interface DevicesPorts ports; interface SerialPort serial = serial.port; interface Client client = blockDev.client; endinterface endmodule ================================================ FILE: tests/qemuaccel/Makefile ================================================ CONNECTALDIR?=../.. INTERFACES = SimpleRequest SerialRequest SerialIndication BlockDevRequest BlockDevResponse S2H_INTERFACES = QemuAccelRequest:QemuAccel.request MemServerPortalRequest:QemuAccel.memServerPortalRequest SerialRequest:QemuAccel.uartRequest BlockDevResponse:QemuAccel.blockDevResponse H2S_INTERFACES = QemuAccel:QemuAccelIndication,MemServerPortalResponse,SerialIndication,BlockDevRequest #MEM_READ_INTERFACES = lQemuAccel.dmaReadClient #MEM_WRITE_INTERFACES = lQemuAccel.dmaWriteClient BSVFILES = $(CONNECTALDIR)/bsv/ConnectalConfig.bsv $(CONNECTALDIR)/examples/simple/Simple.bsv $(CONNECTALDIR)/bsv/MemServerPortal.bsv AccelIfcNames.bsv QemuAccelIfc.bsv Serial.bsv BlockDev.bsv CPPFILES = $(CONNECTALDIR)/lib/qemu/fpgadev.cpp CONNECTALFLAGS += --bsvpath $(CONNECTALDIR)/examples/simple CONNECTALFLAGS += --shared CONNECTALFLAGS += --cxxflags=-std=c++11 prebuild:: $(CONNECTALDIR)/scripts/topgen.py --project-dir . --filename 'AccelTop.bsv' --topname mkAccelTop --ifcnames 'AccelIfcNames' --wrapper SerialRequest:Serial.request --wrapper SimpleRequest:Simple.request --proxy Serial:SerialIndication --proxy Simple:SimpleRequest --interface pins:Serial.port --interface pins:BlockDev.client --wrapper BlockDevRequest:BlockDev.request --proxy BlockDev:BlockDevResponse --pintype 'SerialPort' --pintype BlockDevClient include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/qemuaccel/QemuAccel.bsv ================================================ import GetPut::*; import ClientServer::*; import MemServerPortal::*; import Pipe::*; import Portal::*; import Simple::*; import AccelTop::*; import QemuAccelIfc::*; import BlockDev::*; import Serial::*; interface QemuAccel; interface QemuAccelRequest request; interface MemServerPortalRequest memServerPortalRequest; interface SerialRequest uartRequest; interface BlockDevResponse blockDevResponse; endinterface module mkQemuAccel#(QemuAccelIndication ind, MemServerPortalResponse memServerPortalIndication, SerialIndication uartIndication, BlockDevRequest blockDevRequest)(QemuAccel); let accel <- AccelTop::mkAccelTop(); let physMemSlavePortal <- mkPhysMemSlavePortal(accel.slave, memServerPortalIndication); rule rl_rx; let ch <- toGet(accel.pins.pins0.out).get(); uartIndication.rx(ch); endrule rule rl_blockdev; let req <- accel.pins.pins1.request.get(); blockDevRequest.transfer(req.op, req.dramaddr, req.offset, req.size, req.tag); endrule interface MemServerPortalRequest memServerPortalRequest = physMemSlavePortal.request; interface QemuAccelRequest request; method Action start(); ind.started(); endmethod endinterface interface SerialRequest uartRequest; method Action tx(Bit#(8) ch); accel.pins.pins0.in.enq(ch); endmethod endinterface interface BlockDevResponse blockDevResponse; method Action transferDone(Bit#(32) tag); accel.pins.pins1.response.put(tag); endmethod endinterface endmodule ================================================ FILE: tests/qemuaccel/QemuAccelIfc.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface QemuAccelRequest; method Action start(); method Action reset(); method Action status(); method Action setupDma(Bit#(32) objId); endinterface interface QemuAccelIndication; method Action started(); endinterface ================================================ FILE: tests/qemuaccel/Serial.bsv ================================================ import GetPut::*; import FIFOF::*; import Pipe::*; interface SerialRequest; method Action tx(Bit#(8) c); endinterface interface SerialIndication; method Action rx(Bit#(8) c); endinterface interface SerialPort; interface PipeOut#(Bit#(8)) out; interface PipeIn#(Bit#(8)) in; endinterface interface Serial; interface SerialRequest request; interface SerialPort port; endinterface module mkSerial#(SerialIndication indication)(Serial); FIFOF#(Bit#(8)) infifo <- mkSizedFIFOF(16); FIFOF#(Bit#(8)) outfifo <- mkSizedFIFOF(16); rule rl_in; let ch <- toGet(infifo).get(); indication.rx(ch); endrule interface SerialRequest request; method Action tx(Bit#(8) c); //$display("%h", c); outfifo.enq(c); endmethod endinterface interface SerialPort port; interface PipeOut out = toPipeOut(outfifo); interface PipeIn in = toPipeIn(infifo); endinterface endmodule ================================================ FILE: tests/qemuaccel/qemuaccel.cpp ================================================ int main(int argc, const char **argv) { return 0; } ================================================ FILE: tests/rootport/AxiPcieRootPort.bsv ================================================ /* ../../generated/scripts/importbvi.py -I APRP -P APRP -r axi_aresetn -c axi_aclk_out -c axi_ctl_aclk_out -c REFCLK -o AxiPcieRootPort.bsv /home/jamey/miniitx100/miniitx100.srcs/sources_1/ip/axi_pcie_0/axi_pcie_0_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; (* always_ready, always_enabled *) interface AprpAxi; interface Clock aclk_out; interface Clock ctl_aclk_out; endinterface (* always_ready, always_enabled *) interface AprpInterrupt; method Bit#(1) out(); endinterface (* always_ready, always_enabled *) interface AprpIntx; method Bit#(1) msi_grant(); method Action msi_request(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AprpM_axi; method Bit#(32) araddr(); method Bit#(2) arburst(); method Bit#(4) arcache(); method Bit#(8) arlen(); method Bit#(1) arlock(); method Bit#(3) arprot(); method Action arready(Bit#(1) v); method Bit#(3) arsize(); method Bit#(1) arvalid(); method Bit#(32) awaddr(); method Bit#(2) awburst(); method Bit#(4) awcache(); method Bit#(8) awlen(); method Bit#(1) awlock(); method Bit#(3) awprot(); method Action awready(Bit#(1) v); method Bit#(3) awsize(); method Bit#(1) awvalid(); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(64) v); method Action rlast(Bit#(1) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action rvalid(Bit#(1) v); method Bit#(64) wdata(); method Bit#(1) wlast(); method Action wready(Bit#(1) v); method Bit#(8) wstrb(); method Bit#(1) wvalid(); endinterface (* always_ready, always_enabled *) interface AprpMmcm; method Bit#(1) lock(); endinterface (* always_ready, always_enabled *) interface AprpMsi; method Bit#(1) enable(); method Action vector_num(Bit#(5) v); method Bit#(3) vector_width(); endinterface (* always_ready, always_enabled *) interface AprpPci; method Action exp_rxn(Bit#(4) v); method Action exp_rxp(Bit#(4) v); method Bit#(4) exp_txn(); method Bit#(4) exp_txp(); endinterface (* always_ready, always_enabled *) interface AprpS_axi; method Action araddr(Bit#(32) v); method Action arburst(Bit#(2) v); method Action arid(Bit#(4) v); method Action arlen(Bit#(8) v); method Bit#(1) arready(); method Action arregion(Bit#(4) v); method Action arsize(Bit#(3) v); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(32) v); method Action awburst(Bit#(2) v); method Action awid(Bit#(4) v); method Action awlen(Bit#(8) v); method Bit#(1) awready(); method Action awregion(Bit#(4) v); method Action awsize(Bit#(3) v); method Action awvalid(Bit#(1) v); method Bit#(4) bid(); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(64) rdata(); method Bit#(4) rid(); method Bit#(1) rlast(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(64) v); method Action wlast(Bit#(1) v); method Bit#(1) wready(); method Action wstrb(Bit#(8) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AprpS_axi_ctl; method Action araddr(Bit#(32) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(32) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface APRP; interface AprpAxi axi; interface AprpInterrupt interrupt; interface AprpIntx intx; interface AprpM_axi m_axi; interface AprpMmcm mmcm; interface AprpMsi msi; interface AprpPci pci; interface AprpS_axi s_axi; interface AprpS_axi_ctl s_axi_ctl; endinterface import "BVI" axi_pcie_rp = module mkAPRP#(Clock refclk, Reset reset, Clock axi_aclk, Reset axi_aresetn, Clock axi_ctl_aclk, Reset axi_ctl_aresetn)(APRP); default_clock clk(); default_reset rst(); input_clock axi_aclk() = axi_aclk; input_clock axi_ctl_aclk() = axi_ctl_aclk; input_reset reset(axi_aresetn) = reset; input_reset axi_aresetn() clocked_by (axi_aclk) = axi_aresetn; input_reset axi_ctl_aresetn() clocked_by (axi_ctl_aclk) = axi_ctl_aresetn; input_clock refclk(REFCLK) = refclk; interface AprpAxi axi; output_clock aclk_out(axi_aclk_out); output_clock ctl_aclk_out(axi_ctl_aclk_out); endinterface interface AprpInterrupt interrupt; method interrupt_out out(); endinterface interface AprpIntx intx; method INTX_MSI_Grant msi_grant(); method msi_request(INTX_MSI_Request) enable((*inhigh*) EN_INTX_MSI_Request); endinterface interface AprpM_axi m_axi; method m_axi_araddr araddr(); method m_axi_arburst arburst(); method m_axi_arcache arcache(); method m_axi_arlen arlen(); method m_axi_arlock arlock(); method m_axi_arprot arprot(); method arready(m_axi_arready) enable((*inhigh*) EN_m_axi_arready); method m_axi_arsize arsize(); method m_axi_arvalid arvalid(); method m_axi_awaddr awaddr(); method m_axi_awburst awburst(); method m_axi_awcache awcache(); method m_axi_awlen awlen(); method m_axi_awlock awlock(); method m_axi_awprot awprot(); method awready(m_axi_awready) enable((*inhigh*) EN_m_axi_awready); method m_axi_awsize awsize(); method m_axi_awvalid awvalid(); method m_axi_bready bready(); method bresp(m_axi_bresp) enable((*inhigh*) EN_m_axi_bresp); method bvalid(m_axi_bvalid) enable((*inhigh*) EN_m_axi_bvalid); method rdata(m_axi_rdata) enable((*inhigh*) EN_m_axi_rdata); method rlast(m_axi_rlast) enable((*inhigh*) EN_m_axi_rlast); method m_axi_rready rready(); method rresp(m_axi_rresp) enable((*inhigh*) EN_m_axi_rresp); method rvalid(m_axi_rvalid) enable((*inhigh*) EN_m_axi_rvalid); method m_axi_wdata wdata(); method m_axi_wlast wlast(); method wready(m_axi_wready) enable((*inhigh*) EN_m_axi_wready); method m_axi_wstrb wstrb(); method m_axi_wvalid wvalid(); endinterface interface AprpMmcm mmcm; method mmcm_lock lock(); endinterface interface AprpMsi msi; method MSI_enable enable(); method vector_num(MSI_Vector_Num) enable((*inhigh*) EN_MSI_Vector_Num); method MSI_Vector_Width vector_width(); endinterface interface AprpPci pci; method exp_rxn(pci_exp_rxn) enable((*inhigh*) EN_pci_exp_rxn); method exp_rxp(pci_exp_rxp) enable((*inhigh*) EN_pci_exp_rxp); method pci_exp_txn exp_txn(); method pci_exp_txp exp_txp(); endinterface interface AprpS_axi s_axi; method araddr(s_axi_araddr) enable((*inhigh*) EN_s_axi_araddr) clocked_by(axi_aclk) reset_by (axi_aresetn); method arburst(s_axi_arburst) enable((*inhigh*) EN_s_axi_arburst) clocked_by(axi_aclk) reset_by (axi_aresetn); method arid(s_axi_arid) enable((*inhigh*) EN_s_axi_arid) clocked_by(axi_aclk) reset_by (axi_aresetn); method arlen(s_axi_arlen) enable((*inhigh*) EN_s_axi_arlen) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_arready arready() clocked_by(axi_aclk) reset_by (axi_aresetn); method arregion(s_axi_arregion) enable((*inhigh*) EN_s_axi_arregion) clocked_by(axi_aclk) reset_by (axi_aresetn); method arsize(s_axi_arsize) enable((*inhigh*) EN_s_axi_arsize) clocked_by(axi_aclk) reset_by (axi_aresetn); method arvalid(s_axi_arvalid) enable((*inhigh*) EN_s_axi_arvalid) clocked_by(axi_aclk) reset_by (axi_aresetn); method awaddr(s_axi_awaddr) enable((*inhigh*) EN_s_axi_awaddr) clocked_by(axi_aclk) reset_by (axi_aresetn); method awburst(s_axi_awburst) enable((*inhigh*) EN_s_axi_awburst) clocked_by(axi_aclk) reset_by (axi_aresetn); method awid(s_axi_awid) enable((*inhigh*) EN_s_axi_awid) clocked_by(axi_aclk) reset_by (axi_aresetn); method awlen(s_axi_awlen) enable((*inhigh*) EN_s_axi_awlen) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_awready awready() clocked_by(axi_aclk) reset_by (axi_aresetn); method awregion(s_axi_awregion) enable((*inhigh*) EN_s_axi_awregion) clocked_by(axi_aclk) reset_by (axi_aresetn); method awsize(s_axi_awsize) enable((*inhigh*) EN_s_axi_awsize) clocked_by(axi_aclk) reset_by (axi_aresetn); method awvalid(s_axi_awvalid) enable((*inhigh*) EN_s_axi_awvalid) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_bid bid() clocked_by(axi_aclk) reset_by (axi_aresetn); method bready(s_axi_bready) enable((*inhigh*) EN_s_axi_bready) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_bresp bresp() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_bvalid bvalid() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rdata rdata() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rid rid() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rlast rlast() clocked_by(axi_aclk) reset_by (axi_aresetn); method rready(s_axi_rready) enable((*inhigh*) EN_s_axi_rready) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rresp rresp() clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_rvalid rvalid() clocked_by(axi_aclk) reset_by (axi_aresetn); method wdata(s_axi_wdata) enable((*inhigh*) EN_s_axi_wdata) clocked_by(axi_aclk) reset_by (axi_aresetn); method wlast(s_axi_wlast) enable((*inhigh*) EN_s_axi_wlast) clocked_by(axi_aclk) reset_by (axi_aresetn); method s_axi_wready wready() clocked_by(axi_aclk) reset_by (axi_aresetn); method wstrb(s_axi_wstrb) enable((*inhigh*) EN_s_axi_wstrb) clocked_by(axi_aclk) reset_by (axi_aresetn); method wvalid(s_axi_wvalid) enable((*inhigh*) EN_s_axi_wvalid) clocked_by(axi_aclk) reset_by (axi_aresetn); endinterface interface AprpS_axi_ctl s_axi_ctl; method araddr(s_axi_ctl_araddr) enable((*inhigh*) EN_s_axi_ctl_araddr) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_arready arready() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method arvalid(s_axi_ctl_arvalid) enable((*inhigh*) EN_s_axi_ctl_arvalid) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method awaddr(s_axi_ctl_awaddr) enable((*inhigh*) EN_s_axi_ctl_awaddr) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_awready awready() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method awvalid(s_axi_ctl_awvalid) enable((*inhigh*) EN_s_axi_ctl_awvalid) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method bready(s_axi_ctl_bready) enable((*inhigh*) EN_s_axi_ctl_bready) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_bresp bresp() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_bvalid bvalid() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_rdata rdata() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method rready(s_axi_ctl_rready) enable((*inhigh*) EN_s_axi_ctl_rready) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_rresp rresp() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_rvalid rvalid() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method wdata(s_axi_ctl_wdata) enable((*inhigh*) EN_s_axi_ctl_wdata) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method s_axi_ctl_wready wready() clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method wstrb(s_axi_ctl_wstrb) enable((*inhigh*) EN_s_axi_ctl_wstrb) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); method wvalid(s_axi_ctl_wvalid) enable((*inhigh*) EN_s_axi_ctl_wvalid) clocked_by(axi_ctl_aclk) reset_by(axi_ctl_aresetn); endinterface schedule (interrupt.out, intx.msi_grant, intx.msi_request, m_axi.araddr, m_axi.arburst, m_axi.arcache, m_axi.arlen, m_axi.arlock, m_axi.arprot, m_axi.arready, m_axi.arsize, m_axi.arvalid, m_axi.awaddr, m_axi.awburst, m_axi.awcache, m_axi.awlen, m_axi.awlock, m_axi.awprot, m_axi.awready, m_axi.awsize, m_axi.awvalid, m_axi.bready, m_axi.bresp, m_axi.bvalid, m_axi.rdata, m_axi.rlast, m_axi.rready, m_axi.rresp, m_axi.rvalid, m_axi.wdata, m_axi.wlast, m_axi.wready, m_axi.wstrb, m_axi.wvalid, mmcm.lock, msi.enable, msi.vector_num, msi.vector_width, pci.exp_rxn, pci.exp_rxp, pci.exp_txn, pci.exp_txp, s_axi.araddr, s_axi.arburst, s_axi.arid, s_axi.arlen, s_axi.arready, s_axi.arregion, s_axi.arsize, s_axi.arvalid, s_axi.awaddr, s_axi.awburst, s_axi.awid, s_axi.awlen, s_axi.awready, s_axi.awregion, s_axi.awsize, s_axi.awvalid, s_axi.bid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rid, s_axi.rlast, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wlast, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axi_ctl.araddr, s_axi_ctl.arready, s_axi_ctl.arvalid, s_axi_ctl.awaddr, s_axi_ctl.awready, s_axi_ctl.awvalid, s_axi_ctl.bready, s_axi_ctl.bresp, s_axi_ctl.bvalid, s_axi_ctl.rdata, s_axi_ctl.rready, s_axi_ctl.rresp, s_axi_ctl.rvalid, s_axi_ctl.wdata, s_axi_ctl.wready, s_axi_ctl.wstrb, s_axi_ctl.wvalid) CF (interrupt.out, intx.msi_grant, intx.msi_request, m_axi.araddr, m_axi.arburst, m_axi.arcache, m_axi.arlen, m_axi.arlock, m_axi.arprot, m_axi.arready, m_axi.arsize, m_axi.arvalid, m_axi.awaddr, m_axi.awburst, m_axi.awcache, m_axi.awlen, m_axi.awlock, m_axi.awprot, m_axi.awready, m_axi.awsize, m_axi.awvalid, m_axi.bready, m_axi.bresp, m_axi.bvalid, m_axi.rdata, m_axi.rlast, m_axi.rready, m_axi.rresp, m_axi.rvalid, m_axi.wdata, m_axi.wlast, m_axi.wready, m_axi.wstrb, m_axi.wvalid, mmcm.lock, msi.enable, msi.vector_num, msi.vector_width, pci.exp_rxn, pci.exp_rxp, pci.exp_txn, pci.exp_txp, s_axi.araddr, s_axi.arburst, s_axi.arid, s_axi.arlen, s_axi.arready, s_axi.arregion, s_axi.arsize, s_axi.arvalid, s_axi.awaddr, s_axi.awburst, s_axi.awid, s_axi.awlen, s_axi.awready, s_axi.awregion, s_axi.awsize, s_axi.awvalid, s_axi.bid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rid, s_axi.rlast, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wlast, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axi_ctl.araddr, s_axi_ctl.arready, s_axi_ctl.arvalid, s_axi_ctl.awaddr, s_axi_ctl.awready, s_axi_ctl.awvalid, s_axi_ctl.bready, s_axi_ctl.bresp, s_axi_ctl.bvalid, s_axi_ctl.rdata, s_axi_ctl.rready, s_axi_ctl.rresp, s_axi_ctl.rvalid, s_axi_ctl.wdata, s_axi_ctl.wready, s_axi_ctl.wstrb, s_axi_ctl.wvalid); endmodule ================================================ FILE: tests/rootport/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = RootPortRequest:RootPort.request H2S_INTERFACES = RootPort:RootPortIndication,RootPortTrace:host MEM_READ_INTERFACES = lRootPort.dmaReadClient MEM_WRITE_INTERFACES = lRootPort.dmaWriteClient BSVFILES = RootPortIfc.bsv $(CONNECTALDIR)/bsv/ConnectalConfig.bsv CPPFILES= rootport.cpp PINOUT_FILE += rootport.json PIN_TYPE = RootPortPins PIN_TYPE_INCLUDE = RootPortPins AUTOTOP = --interface pins:RootPort.pins AUTOTOP += --portalclock=lRootPort.portalClockSource CONNECTALFLAGS += -D USE_ACP CONNECTALFLAGS += -D TOP_SOURCES_PORTAL_CLOCK --mainclockperiod=8 CONNECTALFLAGS += -D IMPORT_HOSTIF --bsvpath=../spikehw CONNECTALFLAGS += --xci=cores/$(BOARD)/axi_pcie_rp/axi_pcie_rp.xci CONNECTALFLAGS += --implconstraint=rootport.xdc include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/rootport/RootPort.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import BuildVector::*; import Clocks::*; import Connectable::*; import FIFOF::*; import GetPut::*; import Vector::*; import AxiBits::*; import ConnectalClocks::*; import ConnectalConfig::*; import DefaultValue::*; import HostInterface::*; import ConnectalMemTypes::*; import Pipe::*; import TraceMemClient::*; import XilinxCells::*; import AxiPcieRootPort::*; import RootPortIfc::*; import RootPortPins::*; `ifndef TOP_SOURCES_PORTAL_CLOCK import ConnectalBramFifo::*; `else import BRAMFIFO::*; module mkDualClockBramFIFOF#(Clock clock1, Reset reset1, Clock clock2, Reset reset2)(FIFOF#(a)) provisos (Bits#(a, asz), Add#(1, a__, asz)); FIFOF#(a) fifo <- mkSizedBRAMFIFOF(512, clocked_by clock1, reset_by reset1); return fifo; endmodule `endif interface RootPort; interface RootPortRequest request; interface RootPortTrace trace; interface RootPortPins pins; interface Vector#(1, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(1, MemWriteClient#(DataBusWidth)) dmaWriteClient; `ifdef TOP_SOURCES_PORTAL_CLOCK interface Clock portalClockSource; `endif endinterface module mkRootPort#(HostInterface host, RootPortIndication ind, RootPortTrace trace)(RootPort); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; let refclk_p <- mkB2C1(); let refclk_n <- mkB2C1(); let pcie_clk_100mhz_buf <- mkClockIBUFDS_GTE2( `ifdef ClockDefaultParam defaultValue, `endif True, refclk_p.c, refclk_n.c); `ifndef TOP_SOURCES_PORTAL_CLOCK let axiClockB2C <- mkB2C1(); let axiCtlClockB2C <- mkB2C1(); let axiClock = axiClockB2C.c; let axiCtlClock = axiCtlClockB2C.c; let axiReset <- mkSyncReset(10, reset, axiClock); let axiCtlReset <- mkSyncReset(10, reset, axiCtlClock); `else let axiClock = clock; let axiCtlClock = clock; let axiReset = reset; let axiCtlReset = reset; `endif let axiRootPort <- mkAPRP(pcie_clk_100mhz_buf, reset, axiClock, axiReset, axiCtlClock, axiCtlReset); `ifndef TOP_SOURCES_PORTAL_CLOCK let axiClockC2B <- mkC2B(axiRootPort.axi.aclk_out); let axiCtlClockC2B <- mkC2B(axiRootPort.axi.ctl_aclk_out); rule rl_connect_clocks; axiClockB2C.inputclock(axiClockC2B.o); axiCtlClockB2C.inputclock(axiClockC2B.o); endrule `endif FIFOF#(Bit#(32)) dfifoCtl <- mkFIFOF(); Axi4SlaveBits#(32,DataBusWidth,4,Empty) axiRootPortSlave = toAxi4SlaveBits(axiRootPort.s_axi); Axi4SlaveLiteBits#(32,32) axiRootPortSlaveCtl = toAxi4SlaveBits(axiRootPort.s_axi_ctl); PhysMemSlave#(32,DataBusWidth) axiRootPortMemSlave <- mkPhysMemSlave(axiRootPortSlave, clocked_by axiClock, reset_by axiReset); PhysMemSlave#(32,32) axiRootPortMemSlaveCtl <- mkPhysMemSlave(axiRootPortSlaveCtl, clocked_by axiCtlClock, reset_by axiCtlReset); FIFOF#(PhysMemRequest#(32,DataBusWidth)) araddrFifo <- mkDualClockBramFIFOF(clock, reset, axiClock, axiReset); FIFOF#(PhysMemRequest#(32,DataBusWidth)) awaddrFifo <- mkDualClockBramFIFOF(clock, reset, axiClock, axiReset); FIFOF#(MemData#(DataBusWidth)) rdataFifo <- mkDualClockBramFIFOF(axiClock, axiReset, clock, reset); FIFOF#(MemData#(DataBusWidth)) wdataFifo <- mkDualClockBramFIFOF(clock, reset, axiClock, axiReset); FIFOF#(Bit#(6)) doneFifo <- mkDualClockBramFIFOF(axiClock, axiReset, clock, reset); let araddrCnx <- mkConnection(toGet(araddrFifo), axiRootPortMemSlave.read_server.readReq); let awaddrCnx <- mkConnection(toGet(awaddrFifo), axiRootPortMemSlave.write_server.writeReq); let rdataCnx <- mkConnection(axiRootPortMemSlave.read_server.readData, toPut(rdataFifo)); let wdataCnx <- mkConnection(toGet(wdataFifo), axiRootPortMemSlave.write_server.writeData); let doneCnx <- mkConnection(axiRootPortMemSlave.write_server.writeDone, toPut(doneFifo)); rule rl_rdata; let rdata <- toGet(rdataFifo).get(); ind.readDone(rdata.data); endrule rule rl_writeDone; let tag <- toGet(doneFifo).get(); ind.writeDone(); endrule FIFOF#(PhysMemRequest#(32,32)) araddrFifoCtl <- mkDualClockBramFIFOF(clock, reset, axiCtlClock, axiCtlReset); FIFOF#(PhysMemRequest#(32,32)) awaddrFifoCtl <- mkDualClockBramFIFOF(clock, reset, axiCtlClock, axiCtlReset); FIFOF#(MemData#(32)) rdataFifoCtl <- mkDualClockBramFIFOF(axiCtlClock, axiCtlReset, clock, reset); FIFOF#(MemData#(32)) wdataFifoCtl <- mkDualClockBramFIFOF(clock, reset, axiCtlClock, axiCtlReset); FIFOF#(Bit#(6)) doneFifoCtl <- mkDualClockBramFIFOF(axiCtlClock, axiCtlReset, clock, reset); let araddrCtlCnx <- mkConnection(toGet(araddrFifoCtl), axiRootPortMemSlaveCtl.read_server.readReq); let awaddrCtlCnx <- mkConnection(toGet(awaddrFifoCtl), axiRootPortMemSlaveCtl.write_server.writeReq); let rdataCtlCnx <- mkConnection(axiRootPortMemSlaveCtl.read_server.readData, toPut(rdataFifoCtl)); let wdataCtlCnx <- mkConnection(toGet(wdataFifoCtl), axiRootPortMemSlaveCtl.write_server.writeData); let doneCtlCnx <- mkConnection(axiRootPortMemSlaveCtl.write_server.writeDone, toPut(doneFifoCtl)); rule rl_rdata_ctl; let rdata <- toGet(rdataFifoCtl).get(); ind.readDone(extend(rdata.data)); endrule rule rl_writeDone_ctl; let tag <- toGet(doneFifoCtl).get(); ind.writeDone(); endrule Axi4MasterBits#(32,DataBusWidth,MemTagSize,Empty) m_axi_mm = toAxi4MasterBits(axiRootPort.m_axi); let getObjId = (interface GetObjId; method SGLId objId(Bit#(32) addr); return extend(addr[31:24]); endmethod method Bit#(MemOffsetSize) addr(Bit#(32) axiAddr); return extend(axiAddr[23:0]); endmethod endinterface); let memReadClients <- mapM(mkMemReadClient(getObjId), vec(m_axi_mm)); let memWriteClients <- mapM(mkMemWriteClient(getObjId), vec(m_axi_mm)); FIFOF#(Tuple4#(DmaChannel,Bool,MemRequest,Bit#(32))) traceFifo <- mkDualClockBramFIFOF(clock, reset, clock, reset); FIFOF#(Tuple4#(DmaChannel,Bool,MemRequest,Bit#(32))) traceFifo0 <- mkFIFOF(); FIFOF#(Tuple4#(DmaChannel,Bool,MemRequest,Bit#(32))) traceFifo1 <- mkFIFOF(); PipeIn#(Tuple4#(DmaChannel,Bool,MemRequest,Bit#(32))) tracePipe = toPipeIn(traceFifo0); FIFOF#(Tuple4#(DmaChannel,Bool,MemData#(DataBusWidth),Bit#(32))) traceDataFifo <- mkDualClockBramFIFOF(clock, reset, clock, reset); FIFOF#(Tuple4#(DmaChannel,Bool,MemData#(DataBusWidth),Bit#(32))) traceDataFifo0 <- mkFIFOF(); FIFOF#(Tuple4#(DmaChannel,Bool,MemData#(DataBusWidth),Bit#(32))) traceDataFifo1 <- mkFIFOF(); PipeIn#(Tuple4#(DmaChannel,Bool,MemData#(DataBusWidth),Bit#(32))) traceDataPipe = toPipeIn(traceDataFifo0); let trace0Cnx <- mkConnection(toGet(traceFifo0), toPut(traceFifo)); let trace1Cnx <- mkConnection(toGet(traceFifo), toPut(traceFifo1)); rule rl_trace1; match { .chan, .write, .req, .timestamp } <- toGet(traceFifo1).get(); trace.traceDmaRequest(chan, write, truncate(req.sglId), extend(req.offset), extend(req.burstLen), extend(req.tag), timestamp); endrule let traceData0Cnx <- mkConnection(toGet(traceDataFifo0), toPut(traceDataFifo)); let traceData1Cnx <- mkConnection(toGet(traceDataFifo), toPut(traceDataFifo1)); rule rl_trace_data; match { .chan, .write, .md, .timestamp } <- toGet(traceDataFifo1).get(); trace.traceDmaData(chan, write, md.data, md.last, extend(md.tag), timestamp); endrule let traceReadClients <- mapM(uncurry(mkTraceReadClient(tracePipe,traceDataPipe)), zip(vec(DMA_TX), memReadClients)); let traceWriteClients <- mapM(uncurry(mkTraceWriteClient(tracePipe,traceDataPipe)), zip(vec(DMA_RX), memWriteClients)); interface RootPortRequest request; method Action status(); ind.status(axiRootPort.mmcm.lock()); endmethod method Action read32(Bit#(32) addr); araddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); endmethod method Action write32(Bit#(32) addr, Bit#(32) value); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); wdataFifo.enq(MemData {data: extend(value), tag: 0, last: True}); endmethod method Action read(Bit#(32) addr); araddrFifo.enq(PhysMemRequest { addr: addr, burstLen: fromInteger(valueOf(TDiv#(DataBusWidth,8))), tag: 0 }); endmethod method Action write(Bit#(32) addr, Bit#(DataBusWidth) value); awaddrFifo.enq(PhysMemRequest { addr: addr, burstLen: fromInteger(valueOf(TDiv#(DataBusWidth,8))), tag: 0 }); wdataFifo.enq(MemData {data: value, tag: 0, last: True}); endmethod method Action readCtl(Bit#(32) addr); araddrFifoCtl.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); endmethod method Action writeCtl(Bit#(32) addr, Bit#(DataBusWidth) value); awaddrFifoCtl.enq(PhysMemRequest { addr: addr, burstLen: 4, tag: 0 }); wdataFifoCtl.enq(MemData {data: truncate(value), tag: 0, last: True}); endmethod endinterface interface Clock portalClockSource = axiRootPort.axi.aclk_out; interface RootPortPins pins; interface deleteme_unused_clock = clock; interface pcie_sys_reset_n = reset; interface pcie = axiRootPort.pci; method Action pcie_refclk(Bit#(1) p, Bit#(1) n); refclk_p.inputclock(p); refclk_n.inputclock(n); endmethod endinterface interface Vector dmaReadClient = traceReadClients; interface Vector dmaWriteClient = traceWriteClients; endmodule instance ToAxi4SlaveBits#(Axi4SlaveBits#(32,DataBusWidth,4,Empty), AprpS_axi); function Axi4SlaveBits#(32,DataBusWidth,4,Empty) toAxi4SlaveBits(AprpS_axi s); return (interface Axi4SlaveBits#(32,DataBusWidth,4,Empty); method araddr = compose(s.araddr, extend); method arburst = s.arburst; //method arcache = s.arcache; method arid = s.arid; method arlen = s.arlen; //method arlock = s.arlock; //method arprot = s.arprot; //method arqos = s.arqos; method arready = s.arready; method arsize = s.arsize; method arvalid = s.arvalid; method awaddr = compose(s.awaddr, extend); method awburst = s.awburst; //method awcache = s.awcache; method awid = s.awid; method awlen = s.awlen; //method awlock = s.awlock; //method awprot = s.awprot; //method awqos = s.awqos; method awready = s.awready; method awsize = s.awsize; method awvalid = s.awvalid; method bid = s.bid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rid = s.rid; method rlast = s.rlast; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wlast = s.wlast; method wready = s.wready; method wvalid = s.wvalid; method wstrb = s.wstrb; endinterface); endfunction endinstance instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(32,32), AprpS_axi_ctl); function Axi4SlaveLiteBits#(32,32) toAxi4SlaveBits(AprpS_axi_ctl s); return (interface Axi4SlaveLiteBits#(32,32); method araddr = compose(s.araddr, extend); method arready = s.arready; method arvalid = s.arvalid; method awaddr = compose(s.awaddr, extend); method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance instance ToAxi4MasterBits#(Axi4MasterBits#(32,DataBusWidth,tagWidth,Empty), AprpM_axi); function Axi4MasterBits#(32,DataBusWidth,tagWidth,Empty) toAxi4MasterBits(AprpM_axi m); return (interface Axi4MasterBits#(32,DataBusWidth,tagWidth,Empty); method araddr = m.araddr; method arburst = m.arburst; method arcache = m.arcache; method arlen = m.arlen; method arlock = extend(m.arlock); method arready = m.arready; method arsize = m.arsize; method arvalid = m.arvalid; method Bit#(1) aresetn(); return 1; endmethod method Bit#(tagWidth) arid(); return 0; endmethod method arprot = m.arprot; method arqos = 0; method awaddr = m.awaddr; method awburst = m.awburst; method awcache = m.awcache; method Bit#(tagWidth) awid(); return 0; endmethod method awlen = m.awlen; method awlock = extend(m.awlock); method awprot = m.awprot; method awready = m.awready; method Bit#(4) awqos(); return 0; endmethod method awsize = m.awsize; method awvalid = m.awvalid; method Action bid(Bit#(tagWidth) v); endmethod method bready = m.bready; method bresp = m.bresp; method bvalid = m.bvalid; method rdata = m.rdata; method Action rid(Bit#(tagWidth) v); endmethod method rlast = m.rlast; method rready = m.rready; method rresp = m.rresp; method rvalid = m.rvalid; method wdata = m.wdata; method Bit#(tagWidth) wid(); return 0; endmethod method wlast = m.wlast; method wready = m.wready; method wstrb = m.wstrb; method wvalid = m.wvalid; interface extra = ?; endinterface); endfunction endinstance ================================================ FILE: tests/rootport/RootPortIfc.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; typedef enum { DMA_RX, DMA_TX, DMA_SG } DmaChannel deriving (Bits,Eq); interface RootPortRequest; method Action read32(Bit#(32) addr); method Action write32(Bit#(32) addr, Bit#(32) data); method Action read(Bit#(32) addr); method Action write(Bit#(32) addr, Bit#(DataBusWidth) data); method Action readCtl(Bit#(32) addr); method Action writeCtl(Bit#(32) addr, Bit#(DataBusWidth) data); method Action status(); endinterface interface RootPortIndication; method Action readDone(Bit#(DataBusWidth) data); method Action writeDone(); method Action status(Bit#(1) mmcm_lock); endinterface interface RootPortTrace; method Action traceDmaRequest(DmaChannel channel, Bool write, Bit#(16) objId, Bit#(DataBusWidth) offset, Bit#(16) burstLen, Bit#(8) tag, Bit#(32) timestamp); method Action traceDmaData(DmaChannel channel, Bool write, Bit#(DataBusWidth) data, Bool last, Bit#(8) tag, Bit#(32) timestamp); endinterface ================================================ FILE: tests/rootport/RootPortPins.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import AxiPcieRootPort::*; interface RootPortPins; interface AprpPci pcie; method Action pcie_refclk(Bit#(1) p, Bit#(1) n); interface Clock deleteme_unused_clock; interface Reset pcie_sys_reset_n; endinterface export RootPortPins(..); ================================================ FILE: tests/rootport/gencores.tcl ================================================ set ipdir {cores} set boardname {miniitx100} if {$boardname == {nfsume}} { set partname {xc7vx690tffg1761-2} set databuswidth 32 } if {$boardname == {miniitx100}} { set partname {xc7z100ffg900-2} set databuswidth 64 } puts "partname=$partname" create_project -name local_synthesized_ip -in_memory -part $partname if {$boardname == {nfsume}} { set_property board_part xilinx.com:vc709:part0:1.0 [current_project] } proc fpgamake_ipcore {core_name core_version ip_name params} { global ipdir boardname set generate_ip 0 if [file exists $ipdir/$boardname/$ip_name/$ip_name.xci] { } else { puts "no xci file $ip_name.xci" set generate_ip 1 } if [file exists $ipdir/$boardname/$ip_name/vivadoversion.txt] { gets [open $ipdir/$boardname/$ip_name/vivadoversion.txt r] generated_version set current_version [version -short] puts "core was generated by vivado $generated_version, currently running vivado $current_version" if {$current_version != $generated_version} { puts "vivado version does not match" set generate_ip 1 } } else { puts "no vivado version recorded" set generate_ip 1 } ## check requested core version and parameters if [file exists $ipdir/$boardname/$ip_name/coreversion.txt] { gets [open $ipdir/$boardname/$ip_name/coreversion.txt r] generated_version set current_version "$core_name $core_version $params" puts "Core generated: $generated_version" puts "Core requested: $current_version" if {$current_version != $generated_version} { puts "core version or params does not match" set generate_ip 1 } } else { puts "no core version recorded" set generate_ip 1 } if $generate_ip { file delete -force $ipdir/$boardname/$ip_name file mkdir $ipdir/$boardname create_ip -name $core_name -version $core_version -vendor xilinx.com -library ip -module_name $ip_name -dir $ipdir/$boardname if [llength $params] { set_property -dict $params [get_ips $ip_name] } report_property -file $ipdir/$boardname/$ip_name.properties.log [get_ips $ip_name] generate_target all [get_files $ipdir/$boardname/$ip_name/$ip_name.xci] set versionfd [open $ipdir/$boardname/$ip_name/vivadoversion.txt w] puts $versionfd [version -short] close $versionfd set corefd [open $ipdir/$boardname/$ip_name/coreversion.txt w] puts $corefd "$core_name $core_version $params" close $corefd } else { read_ip $ipdir/$boardname/$ip_name/$ip_name.xci } if [file exists $ipdir/$boardname/$ip_name/$ip_name.dcp] { } else { synth_ip [get_ips $ip_name] } } fpgamake_ipcore axi_pcie 2.7 axi_pcie_rp [list CONFIG.INCLUDE_RC {Root_Port_of_PCI_Express_Root_Complex} CONFIG.NO_OF_LANES {X4} CONFIG.BAR0_SCALE {Gigabytes} CONFIG.INCLUDE_BAROFFSET_REG {false} CONFIG.AXIBAR_0 {0x00000000} CONFIG.AXIBAR_HIGHADDR_0 {0xfFFFFFFF} CONFIG.AXIBAR2PCIEBAR_0 {0x00000000} CONFIG.BASEADDR {0x00000000} CONFIG.HIGHADDR {0xffffffff} CONFIG.XLNX_REF_BOARD {ZC706} CONFIG.shared_logic_in_core {true} CONFIG.MAX_LINK_SPEED {2.5_GT/s} CONFIG.DEVICE_ID {0x7022} CONFIG.BASE_CLASS_MENU {Bridge_device} CONFIG.SUB_CLASS_INTERFACE_MENU {InfiniBand_to_PCI_host_bridge} CONFIG.BAR0_SIZE {1} CONFIG.S_AXI_DATA_WIDTH {64} CONFIG.M_AXI_DATA_WIDTH {64} CONFIG.NUM_MSI_REQ {5} CONFIG.S_AXI_SUPPORTS_NARROW_BURST {true}] ================================================ FILE: tests/rootport/rootport.cpp ================================================ #include #include "portal.h" #include "dmaManager.h" #include "RootPortIndication.h" #include "RootPortRequest.h" #include "RootPortTrace.h" enum nvme_admin_opcode { nvme_identify = 0xe2 // 6? }; struct nvme_admin_cmd { uint8_t opcode; uint8_t flags; uint16_t cid; uint32_t nsid; uint32_t reserved0; uint32_t reserved1; uint64_t mptr; uint64_t prp1; uint64_t prp2; uint32_t cdw10; uint32_t cdw11; uint32_t cdw12; uint32_t cdw13; uint32_t cdw14; uint32_t cdw15; }; struct nvme_io_cmd { uint8_t opcode; uint8_t flags; uint16_t cid; uint32_t nsid; uint32_t reserved0; uint32_t reserved1; uint64_t mptr; uint64_t prp1; uint64_t prp2; uint32_t cdw10; uint32_t cdw11; uint32_t cdw12; uint32_t cdw13; uint32_t cdw14; uint32_t cdw15; }; class RootPortTrace : public RootPortTraceWrapper { public: void traceDmaRequest(const DmaChannel chan, const int write, const uint16_t objId, const uint64_t offset, const uint16_t burstLen, const uint8_t tag, const uint32_t timestamp) { fprintf(stderr, "%08x: traceDmaRequest chan=%d write=%d objId=%d offset=%08lx burstLen=%d tag=%x\n", timestamp, chan, write, objId, (long)offset, burstLen, tag); } void traceDmaData ( const DmaChannel chan, const int write, const uint64_t data, const int last, const uint8_t tag, const uint32_t timestamp ) { fprintf(stderr, "%08x: traceDmaData chan=%d write=%d data=%08llx last=%d tag=%x\n", timestamp, chan, write, (long long)data, last, tag); } RootPortTrace(int id, PortalPoller *poller = 0) : RootPortTraceWrapper(id, poller) { } }; class RootPortIndication : public RootPortIndicationWrapper { sem_t sem, wsem; public: uint64_t value; virtual void readDone ( const uint64_t data ) { //fprintf(stderr, "%s:%d data=%08llx\n", __FUNCTION__, __LINE__, (long long)data); value = data; sem_post(&sem); } virtual void writeDone ( ) { //fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__); sem_post(&wsem); } virtual void status ( const uint8_t mmcm_lock ) { fprintf(stderr, "%s:%d mmcm_lock=%d\n", __FUNCTION__, __LINE__, mmcm_lock); sem_post(&sem); } void wait() { sem_wait(&sem); } void waitwrite() { sem_wait(&wsem); } RootPortIndication(int id, PortalPoller *poller = 0) : RootPortIndicationWrapper(id, poller) { sem_init(&sem, 0, 0); sem_init(&wsem, 0, 0); } }; class DmaBuffer { const int size; int fd; char *buf; int ref; static DmaManager *mgr; static void initDmaManager(); public: // Allocates a portal memory object of specified size and maps it into user process DmaBuffer(int size); // Dereferences and deallocates the portal memory object // if destructor is not called, the object is automatically // unreferenced and freed when the process exits ~DmaBuffer(); // returns the address of the mapped buffer char *buffer() { return buf; } // returns the reference to the object // // Sends the address translation table to hardware MMU if necessary. uint32_t reference(); // Removes the address translation table from the hardware MMU void dereference(); // invalidate and optionally flush from the dcache void cacheFlush(int size=0, int flush=0); }; DmaManager *DmaBuffer::mgr; void DmaBuffer::initDmaManager() { if (!mgr) mgr = platformInit(); } DmaBuffer::DmaBuffer(int size) : size(size), ref(-1) { fd = portalAlloc(size, 1); buf = (char *)portalMmap(fd, size); } DmaBuffer::~DmaBuffer() { dereference(); portalMunmap(buf, size); close(fd); } uint32_t DmaBuffer::reference() { initDmaManager(); if (ref == -1) ref = mgr->reference(fd); return ref; } void DmaBuffer::dereference() { if (ref != -1 && mgr) mgr->dereference(ref); ref = -1; } void DmaBuffer::cacheFlush(int size, int flush) { if (size == 0) size = this->size; portalCacheFlush(fd, buf, size, flush); } class RootPort { RootPortRequestProxy device; RootPortIndication indication; RootPortTrace trace; public: DmaBuffer dummy; DmaBuffer transferBuffer; DmaBuffer adminSubmissionQueue; DmaBuffer adminCompletionQueue; DmaBuffer ioSubmissionQueue; DmaBuffer ioCompletionQueue; int transferBufferRef; int adminSubmissionQueueRef; int adminCompletionQueueRef; int ioSubmissionQueueRef; int ioCompletionQueueRef; RootPort() : device(IfcNames_RootPortRequestS2H) , indication(IfcNames_RootPortIndicationH2S) , trace(IfcNames_RootPortTraceH2S) , dummy(4096) , transferBuffer(10*4096) , adminSubmissionQueue(64*64) , adminCompletionQueue(4096) , ioSubmissionQueue(8192) , ioCompletionQueue(8192) { dummy.reference(); transferBufferRef = transferBuffer.reference(); adminSubmissionQueueRef = adminSubmissionQueue.reference(); adminCompletionQueueRef = adminCompletionQueue.reference(); fprintf(stderr, "adminSubmissionQueue %d\n", adminSubmissionQueue.reference()); fprintf(stderr, "adminCompletionQueue %d\n", adminCompletionQueue.reference()); ioSubmissionQueueRef = ioSubmissionQueue.reference(); ioCompletionQueueRef = ioCompletionQueue.reference(); fprintf(stderr, "ioSubmissionQueue %d\n", ioSubmissionQueue.reference()); fprintf(stderr, "ioCompletionQueue %d\n", ioCompletionQueue.reference()); device.status(); indication.wait(); } uint32_t readCtl(uint32_t addr); void writeCtl(uint32_t addr, uint32_t data); uint64_t read(uint32_t addr); void write(uint32_t addr, uint64_t data); uint32_t read32(uint32_t addr); void write32(uint32_t addr, uint32_t data); }; uint32_t RootPort::readCtl(uint32_t addr) { device.readCtl(addr); indication.wait(); return (uint32_t)indication.value; } void RootPort::writeCtl(uint32_t addr, uint32_t data) { device.writeCtl(addr, data); indication.waitwrite(); } uint64_t RootPort::read(uint32_t addr) { device.read(addr); indication.wait(); return indication.value; } void RootPort::write(uint32_t addr, uint64_t data) { device.write(addr, data); //indication.wait(); } uint32_t RootPort::read32(uint32_t addr) { device.read32(addr); indication.wait(); uint64_t v = indication.value; return (uint32_t)(v >> ((addr & 4) ? 32 : 0)); //return v; } void RootPort::write32(uint32_t addr, uint32_t data) { uint64_t v = data; //fixme byte enables //device.write(addr & ~7, v << ((addr & 4) ? 32 : 0)); device.write32(addr, v); //indication.wait(); } void memserverWrite(RootPort *rootPort) { // identify portals int numTiles = rootPort->read32(0x02200000 + 0x08); int numPortals = rootPort->read32(0x02200000 + 0x14); fprintf(stderr, "numTiles=%x numPortals=%x\n", numTiles, numPortals); for (int p = 0; p < numPortals; p++) { fprintf(stderr, "Platform Portal[%d].id=%x\n", p, rootPort->read32(0x02200000 + p*0x1000 + 0x10)); } numTiles = rootPort->read32(0x02200000 + 0x40000 + 0x08); numPortals = rootPort->read32(0x02200000 + 0x40000 + 0x14); fprintf(stderr, "numTiles=%x numPortals=%x\n", numTiles, numPortals); for (int p = 0; p < numPortals; p++) { fprintf(stderr, "Portal[%d].id=%x\n", p, rootPort->read32(0x02200000 + 0x40000 + p*0x1000 + 0x10)); } if (1) { // pause for vivado to connect fprintf(stderr, "type enter to continue:\n"); char line[100]; fgets(line, sizeof(line), stdin); } // start write test int pointer = 1; int numWords = 0x1000; int burstLen = 64; int numReqs = numWords / burstLen; int byteEnable = 0xff; rootPort->write32(0x02200000 + 0x41000 + 0x20, (pointer>>24)); rootPort->write32(0x02200000 + 0x41000 + 0x20, (numWords>>24)|(((unsigned long)pointer)<<8)); rootPort->write32(0x02200000 + 0x41000 + 0x20, (numReqs>>24)|(((unsigned long)numWords)<<8)); rootPort->write32(0x02200000 + 0x41000 + 0x20, (burstLen>>24)|(((unsigned long)numReqs)<<8)); rootPort->write32(0x02200000 + 0x41000 + 0x20, byteEnable|(((unsigned long)burstLen)<<8)); } void identify(RootPort *rootPort) { memset(rootPort->adminCompletionQueue.buffer(), 0xbf, 4096); fprintf(stderr, "sizeof(nvmd_id_cmd)=%d\n", sizeof(nvme_admin_cmd)); // write an identify command nvme_admin_cmd *cmd = (nvme_admin_cmd *)rootPort->adminSubmissionQueue.buffer(); memset(cmd, 0, 64); cmd->opcode = 6; //nvme_identify; cmd->cid = 22; cmd->nsid = 0; cmd->prp1 = (rootPort->transferBufferRef << 24) + 0; cmd->prp2 = (rootPort->transferBufferRef << 24) + 4096; cmd->cdw10 = 1; //rootPort->adminSubmissionQueue.cacheFlush(4096, 1); //rootPort->adminCompletionQueue.cacheFlush(4096, 0); // update submission queue tail rootPort->write32(0x1000, 1); //rootPort->write32(0x1000, 64); fprintf(stderr, "CTS %08x\n", rootPort->read32( 0x1c)); fprintf(stderr, "CMDSTATUS: %08x\n", rootPort->readCtl((1 << 20) + 0x4)); sleep(1); fprintf(stderr, "CTS %08x\n", rootPort->read32( 0x1c)); fprintf(stderr, "CMDSTATUS: %08x\n", rootPort->readCtl((1 << 20) + 0x4)); { int *buffer = (int *)rootPort->adminCompletionQueue.buffer(); for (int i = 0; i < 16; i++) { fprintf(stderr, "response[%02x]=%08x\n", i*4, buffer[i]); } int status = buffer[3]; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); } { char *cbuffer = (char *)(rootPort->transferBuffer.buffer() + 0); int *buffer = (int *)(rootPort->transferBuffer.buffer() + 0); for (int i = 0; i < 16; i++) { fprintf(stderr, "identity[%02x]=%08x\n", i*4, buffer[i]); } fprintf(stderr, "error log page entries %d\n", cbuffer[262]); fprintf(stderr, "host buffer preferred size %x\n", *(int *)&cbuffer[272]); fprintf(stderr, "host buffer min size %x\n", *(int *)&cbuffer[276]); fprintf(stderr, "nvm submission queue entry size %d\n", cbuffer[512]); fprintf(stderr, "nvm completion queue entry size %d\n", cbuffer[513]); fprintf(stderr, "nvm capacity: %08llx %08llx\n", *(long long *)&cbuffer[288], *(long long *)&cbuffer[280]); } } void allocIOQueues(RootPort *rootPort, int entry=0) { nvme_admin_cmd *cmd = 0; // create I/O completion queue cmd = (nvme_admin_cmd *)(rootPort->adminSubmissionQueue.buffer() + (entry+0)*64); memset(cmd, 0, 64); cmd->opcode = 5; //create I/O completion queue cmd->cid = 18; cmd->nsid = 0; cmd->prp1 = (rootPort->ioCompletionQueueRef << 24) + 0; cmd->cdw10 = ((8192 / 16 - 1) << 16) | 1; // size, completion queue 1 cmd->cdw11 = 1; // physically contiguous // create I/O submission queue cmd = (nvme_admin_cmd *)(rootPort->adminSubmissionQueue.buffer() + (entry+1)*64); memset(cmd, 0, 64); cmd->opcode = 1; //create I/O submission queue cmd->cid = 17; cmd->nsid = 0; cmd->prp1 = (rootPort->ioSubmissionQueueRef << 24) + 0; cmd->cdw10 = ((8192 / 64 - 1) << 16) + 1; // submission queue 1 cmd->cdw11 = (1 << 16) | 1; // completion queue 1, physically contiguous fprintf(stderr, "allocating IO submission queue\n"); // update submission queue tail rootPort->write32(0x1000, entry+2); sleep(1); { int *buffer = (int *)(rootPort->adminCompletionQueue.buffer() + (entry+0)*16); for (int i = 0; i < 16; i++) { fprintf(stderr, "response[%02x]=%08x\n", i*4, buffer[i]); } int status = buffer[3]; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); } { int *buffer = (int *)(rootPort->adminCompletionQueue.buffer() + (entry+1)*16); for (int i = 0; i < 16; i++) { fprintf(stderr, "response[%02x]=%08x\n", i*4, buffer[i]); } int status = buffer[3]; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); } { // let's do a read nvme_io_cmd *cmd = (nvme_io_cmd *)(rootPort->ioSubmissionQueue.buffer() + (entry+0)*64); memset(cmd, 0, 64); cmd->opcode = 2; // read cmd->cid = 42; cmd->nsid = 1; cmd->prp1 = (rootPort->transferBufferRef << 24) + 0; cmd->cdw10 = 0; // starting LBA.lower cmd->cdw11 = 0; // starting LBA.upper cmd->cdw12 = 7; // read 8 blocks fprintf(stderr, "enqueueing IO read request\n"); // update submission queue tail rootPort->write32(0x1000+(2*1*(4 << 0)), 1); sleep(1); { int *buffer = (int *)(rootPort->ioCompletionQueue.buffer() + (entry+0)*16); for (int i = 0; i < 16; i++) { fprintf(stderr, "response[%02x]=%08x\n", i*4, buffer[i]); } int status = buffer[3]; int more = (status >> 30) & 1; int sc = (status >> 17) & 0xff; int sct = (status >> 25) & 0x7; fprintf(stderr, "status=%08x more=%d sc=%x sct=%x\n", status, more, sc, sct); } { int *buffer = (int *)(rootPort->transferBuffer.buffer() + (entry+0)*16); for (int i = 0; i < 8*512/4; i++) { fprintf(stderr, "data read [%02x]=%08x\n", i*4, buffer[i]); } } } } int main(int argc, const char **argv) { RootPort rootPort; sleep(1); fprintf(stderr, "Enabling I/O and Memory, bus master, parity and SERR\n"); rootPort.writeCtl(0x004, 0x147); rootPort.readCtl(0x004); rootPort.readCtl(0x130); rootPort.readCtl(0x134); rootPort.readCtl(0x18); // required rootPort.writeCtl(0x18, 0x00070100); rootPort.readCtl(0x18); rootPort.writeCtl(0x10, 0xFFFFFFFF); rootPort.writeCtl(0x14, 0xFFFFFFFF); fprintf(stderr, "Root Port BAR0: %08x\n", rootPort.readCtl((0 << 20) + 0x10)); fprintf(stderr, "Root Port BAR1: %08x\n", rootPort.readCtl((0 << 20) + 0x14)); rootPort.writeCtl(0x10, 0x0); rootPort.writeCtl(0x14, 0x0); fprintf(stderr, "Enabling card I/O and Memory, bus master, parity and SERR\n"); rootPort.writeCtl((1 << 20) + 4, 0x147); fprintf(stderr, "reading config regs\n"); rootPort.readCtl((1 << 20) + 0); rootPort.readCtl((1 << 20) + 4); rootPort.readCtl((1 << 20) + 8); fprintf(stderr, "Card BAR0: %08x\n", rootPort.readCtl((1 << 20) + 0x10)); fprintf(stderr, "reading AXI BAR\n"); rootPort.readCtl(0x208); rootPort.readCtl(0x20C); rootPort.readCtl(0x210); fprintf(stderr, "writing card BAR0\n"); for (int i = 0; i < 6; i++) { rootPort.writeCtl((1 << 20) + 0x10 + 4*i, 0xffffffff); rootPort.readCtl((1 << 20) + 0x10 + 4*i); } rootPort.writeCtl((1 << 20) + 0x10, 0); rootPort.writeCtl((1 << 20) + 0x14, 0x0000); rootPort.writeCtl((1 << 20) + 0x18, 0x02200000); // BAR1 rootPort.writeCtl((1 << 20) + 0x1c, 0x00000000); rootPort.writeCtl((1 << 20) + 0x10+5*4, 0); // sata card fprintf(stderr, "reading card BARs\n"); for (int i = 0; i < 6; i++) { fprintf(stderr, "BAR%d: %08x\n", i, rootPort.readCtl((1 << 20) + 0x10 + 4*i)); } rootPort.readCtl((1 << 20) + 0x10); rootPort.readCtl((1 << 20) + 0x14); fprintf(stderr, "Enabling bridge\n"); rootPort.readCtl(0x148); rootPort.writeCtl(0x148, 1); rootPort.readCtl(0x148); rootPort.readCtl(0x140); rootPort.writeCtl(0x140, 0x00010000); rootPort.readCtl(0x140); if (1) { fprintf(stderr, "Reading card memory space BAR0\n"); for (int i = 0; i < 8; i++) fprintf(stderr, "BAR0[%02x]=%08x\n", i*4, rootPort.read32(0 + i*4)); } if (0) { fprintf(stderr, "Reading card memory space BAR2\n"); for (int i = 0; i < 8; i++) fprintf(stderr, "BAR1[%02x]=%08x\n", i*4, rootPort.read32(0x02200000 + i*4)); } fprintf(stderr, "CTS %08x\n", rootPort.read32( 0x1c)); rootPort.write32(0x1c, 0x10); // clear reset bit fprintf(stderr, "CTS %08x\n", rootPort.read32( 0x1c)); // disable rootPort.write32(0x14, 0); // reset rootPort.write32(0x20, 0x4e564d65); sleep(1); fprintf(stderr, "Reset reg %08x\n", rootPort.read32(0x20)); fprintf(stderr, "CTS %08x\n", rootPort.read32( 0x1c)); fprintf(stderr, "CMB size %08x\n", rootPort.read32(0x38)); fprintf(stderr, "CMB location %08x\n", rootPort.read32(0x3c)); uint64_t adminCompletionBaseAddress = rootPort.adminCompletionQueueRef << 24; uint64_t adminSubmissionBaseAddress = rootPort.adminSubmissionQueueRef << 24; fprintf(stderr, "Setting up Admin submission and completion queues %llx %llx\n", (long long)adminCompletionBaseAddress, (long long)adminSubmissionBaseAddress); rootPort.write(0x28, adminSubmissionBaseAddress); fprintf(stderr, "AdminSubmissionBaseAddress %08llx\n", (long long)rootPort.read(0x28)); rootPort.write(0x30, adminCompletionBaseAddress); fprintf(stderr, "AdminCompletionBaseAddress %08llx\n", (long long)rootPort.read(0x30)); rootPort.write32(0x24, 0x003f003f); fprintf(stderr, "register 0x20 %x\n", rootPort.read32(0x20)); fprintf(stderr, "CTS %08x\n", rootPort.read32( 0x1c)); // CC.enable rootPort.write32(0x14, 1); fprintf(stderr, "CTS %08x\n", rootPort.read32( 0x1c)); //identify(&rootPort); allocIOQueues(&rootPort, 0); fprintf(stderr, "CTS %08x\n", rootPort.read32( 0x1c)); return 0; } ================================================ FILE: tests/rootport/rootport.json ================================================ { "pcie_refclk_p": { "pcie": "sys_clk_p" }, "pcie_refclk_n": { "pcie": "sys_clk_n" }, "RST_N_pcie_sys_reset_n": { "pcie": "sys_reset_n" } } ================================================ FILE: tests/rootport/rootport.xdc ================================================ create_clock -name root_pci_refclk -period 10 [get_ports pcie_refclk_p] ================================================ FILE: tests/serialportal/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = SerialPortalRequest:SerialPortalTest.request EchoIndication:SerialPortalTest.echoIndication SimpleRequest:SerialPortalTest.simpleRequest H2S_INTERFACES = SerialPortalTest:SerialPortalIndication,EchoRequest,SimpleRequest INTERFACES = EchoRequest EchoIndication BSVFILES = SerialPortalIfc.bsv $(CONNECTALDIR)/examples/echo/Echo.bsv $(CONNECTALDIR)/examples/simple/Simple.bsv CPPFILES= serialportal.cpp CONNECTALFLAGS += -I $(CONNECTALDIR)/examples/simple PINOUT_FILE += rs232.json PIN_TYPE = SerialPortalPins PIN_TYPE_INCLUDE = SerialPortalIfc AUTOTOP = --interface pins:SerialPortalTest.pins include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/serialportal/SerialPortalIfc.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import RS232::*; interface SerialPortalRequest; method Action setDivisor(Bit#(16) d); endinterface interface SerialPortalIndication; method Action rx(Bit#(8) c); endinterface interface SerialPortalPins; interface RS232 uart; interface Clock deleteme_unused_clock; endinterface export RS232(..); export SerialPortalRequest(..); export SerialPortalIndication(..); export SerialPortalPins(..); ================================================ FILE: tests/serialportal/SerialPortalTest.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import BuildVector::*; import Clocks::*; import ClientServer::*; import Connectable::*; import Gearbox::*; import GetPut::*; import RS232::*; import Vector::*; import Pipe::*; import Portal::*; import SharedMemoryPortal::*; import SerialPortalIfc::*; import Echo::*; import EchoRequest::*; import EchoIndication::*; import Simple::*; import SimpleRequest::*; interface SerialPortalTest; interface SerialPortalRequest request; interface EchoIndication echoIndication; interface SimpleRequest simpleRequest; interface SerialPortalPins pins; endinterface module mkSerialPortalTest#(SerialPortalIndication indication, EchoRequest echoRequest, SimpleRequest simpleRequest)(SerialPortalTest); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); // 250MHz clock // 9600 baud: divisor=26042 // 115200 baud: divisor=134 Reg#(Bit#(16)) divisor <- mkReg(134); UART#(16) uart <- mkUART(8, EVEN, STOP_1, divisor); SerialPortalDemux#(3) serialEchoRequestDemux <- mkSerialPortalDemux(Method); // why the asymmetry? let echoRequestInput <- mkEchoRequestInput(); mkConnection(echoRequestInput.pipes, echoRequest); mkConnection(serialEchoRequestDemux.data, echoRequestInput.portalIfc.requests); SerialPortalDemux#(12) serialSimpleRequestDemux <- mkSerialPortalDemux(Method); // why the asymmetry? let simpleRequestInput <- mkSimpleRequestInput(); mkConnection(simpleRequestInput.pipes, simpleRequest); mkConnection(serialSimpleRequestDemux.data, simpleRequestInput.portalIfc.requests); SerialPortalDemux#(2) portalDemux <- mkSerialPortalDemux(Portal); mkConnection(portalDemux.data[0], serialEchoRequestDemux.inputPipe); mkConnection(portalDemux.data[1], serialSimpleRequestDemux.inputPipe); Gearbox#(1,4,Bit#(8)) tx_gb <- mk1toNGearbox(clock,reset,clock,reset); mkConnection(uart.tx, toPut(toPipeIn(tx_gb))); mkConnection(mapPipe(pack,toPipeOut(tx_gb)), portalDemux.inputPipe); let echoIndicationOutput <- mkEchoIndicationOutput; Vector#(2,PipeOut#(Bit#(32))) echoMethodPipes <- genWithM(mkFramedMessagePipe(0, echoIndicationOutput.portalIfc, getEchoIndicationMessageSize)); PipeOut#(Bit#(32)) serialEchoPortalPipe <- mkSerialPortalMux(echoMethodPipes); let simpleRequestOutput <- mkSimpleRequestOutput; Vector#(12,PipeOut#(Bit#(32))) simpleMethodPipes <- genWithM(mkFramedMessagePipe(1, simpleRequestOutput.portalIfc, getSimpleRequestMessageSize)); PipeOut#(Bit#(32)) serialSimplePortalPipe <- mkSerialPortalMux(simpleMethodPipes); PipeOut#(Bit#(32)) portalMux <- mkSerialPortalMux(vec(serialEchoPortalPipe, serialSimplePortalPipe)); Gearbox#(4,1,Bit#(8)) rx_gb <- mkNto1Gearbox(clock,reset,clock,reset); rule rl_rx_gb; let v <- toGet(portalMux).get(); rx_gb.enq(unpack(v)); endrule rule rl_rx; let char = rx_gb.first()[0]; rx_gb.deq(); uart.rx.put(char); indication.rx(char); endrule interface SerialPortalRequest request; method Action setDivisor(Bit#(16) d); divisor <= d; endmethod endinterface interface EchoIndication echoIndication = echoIndicationOutput.ifc; interface SimpleRequest simpleRequest = simpleRequestOutput.ifc; interface SerialPortalPins pins; interface uart = uart.rs232; interface deleteme_unused_clock = clock; endinterface endmodule ================================================ FILE: tests/serialportal/rs232.json ================================================ { "uart_SOUT": { "uart": "d_out" }, "uart_SIN": { "uart": "d_in" } } ================================================ FILE: tests/serialportal/serialportal.cpp ================================================ /* Copyright (c) 2016 Connectal Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include "portal.h" #include "SerialPortalIndication.h" #include "SerialPortalRequest.h" #include "EchoRequest.h" #include "EchoIndication.h" #include "SimpleRequest.h" #include #if 1 #define TEST_ASSERT(A) assert(A) #else #define TEST_ASSERT(A) {} #endif #define NUMBER_OF_TESTS 12 uint32_t v1a = 42; uint32_t v2a = 2; uint32_t v2b = 4; class Simple : public SimpleRequestWrapper { public: uint32_t cnt; uint32_t times; void incr_cnt(){ if (++cnt == NUMBER_OF_TESTS) exit(0); } void say1(uint32_t a) { fprintf(stderr, "received Simple.say1(%d)\n", a); TEST_ASSERT(a == v1a); incr_cnt(); } void say2(uint16_t a, uint16_t b) { fprintf(stderr, "received Simple.say2(%d %d)\n", a, b); TEST_ASSERT(a == v2a); TEST_ASSERT(b == v2b); incr_cnt(); } Simple(unsigned int id, PortalTransportFunctions *transport = 0, void *param = 0, PortalPoller *poller = 0) : SimpleRequestWrapper(id, transport, param, poller), cnt(0){} }; class SerialPortalIndication : public SerialPortalIndicationWrapper { public: void rx ( uint8_t c ) { fprintf(stderr, "rx=%x:%c\n", c, c); } SerialPortalIndication(unsigned int id) : SerialPortalIndicationWrapper(id) {} }; class EchoRequest : public EchoRequestWrapper { public: virtual void say(uint32_t v) { fprintf(stderr, "received EchoRequest.say: %x\n", v); } virtual void say2(uint16_t a, uint16_t b) { fprintf(stderr, "received EchoRequest.say2: %d %d\n", a, b); } virtual void setLeds ( const uint8_t v ) {} EchoRequest(unsigned int id) : EchoRequestWrapper(id) {} }; class EchoIndication : public EchoIndicationWrapper { public: virtual void heard ( const uint32_t v ) { fprintf(stderr, "EchoIndication.heard v=%x\n", v); } virtual void heard2 ( const uint16_t a, const uint16_t b ) { fprintf(stderr, "EchoIndication.heard2 a=%#x b=%#x\n", a, b); } EchoIndication(int id, PortalTransportFunctions *item = 0, void *param = 0, PortalPoller *poller = 0) : EchoIndicationWrapper(id, item, param, poller) { } }; int initSerial(const char *dev) { struct termios terminfo; int rc; int fd = open(dev, O_RDWR | O_NONBLOCK); tcflush(fd, TCIOFLUSH); tcgetattr(fd, &terminfo); terminfo.c_cflag = CS8 | CLOCAL | CREAD | PARENB; terminfo.c_cflag &= ~CRTSCTS; // needed for /dev/tty.SLAB_USBtoUART terminfo.c_iflag = IGNCR; terminfo.c_lflag &= ~(ICANON | ECHO | ISIG); cfsetspeed(&terminfo, B115200); rc = tcsetattr(fd, TCSANOW, &terminfo); if (rc != 0) fprintf(stderr, "tcsetattr rc=%d errno=%d\n", rc, errno); return fd; } int main(int argc, const char **argv) { SerialPortalIndication indication(IfcNames_SerialPortalIndicationH2S); EchoRequest echo(IfcNames_EchoRequestH2S); Simple simple(IfcNames_SimpleRequestH2S); SerialPortalRequestProxy *device = new SerialPortalRequestProxy(IfcNames_SerialPortalRequestS2H); EchoIndicationProxy *echoIndication = new EchoIndicationProxy(IfcNames_EchoIndicationS2H); SimpleRequestProxy *simpleRequest = new SimpleRequestProxy(IfcNames_SimpleRequestS2H); if (!argv[1]) { //realpath("/sys/class/tty/ttyUSB0/device/driver/"); fprintf(stderr, "usage: %s /dev/ttyUSBn\n", argv[0]); return -EINVAL; } int serial_fd = initSerial(argv[1]); PortalSharedParam paramSerial; paramSerial.serial.serial_fd = serial_fd; Portal *mcommon = new Portal(0, 0, sizeof(uint32_t), portal_serialmux_handler, NULL, &transportSerial, ¶mSerial, 0); PortalMuxParam param = {}; param.pint = &mcommon->pint; EchoRequestProxy echoSerial(0, &transportSerialMux, ¶m); SimpleRequestProxy simpleSerial(1, &transportSerialMux, ¶m); EchoIndication serialEchoIndication(0, &transportSerialMux, ¶m); Simple serialSimple(1, &transportSerialMux, ¶m); device->setDivisor(134); sleep(2); echoSerial.say(0x6789); echoSerial.say2(0x22, 0x23); sleep(2); simpleSerial.say1(v1a); simpleSerial.say2(v2a, v2b); sleep(2); echoIndication->heard2(0x68,0x47); echoIndication->heard(0x22); sleep(2); simpleRequest->say1(19); while (1) { // wait } } ================================================ FILE: tests/simmethodtime/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = SimmRequest:Simm.request H2S_INTERFACES = Simm:SimmIndication BSVFILES = Simm.bsv CPPFILES= test.cpp CONNECTALFLAGS += -lpapi include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/simmethodtime/Simm.bsv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; interface SimmIndication; method Action resp(Bit#(32) v); endinterface interface SimmRequest; method Action shortreq(Bit#(32) v); method Action longreq(Vector#(100, Bit#(32)) v); endinterface interface Simm; interface SimmRequest request; endinterface module mkSimm#(SimmIndication indication)(Simm); interface SimmRequest request; method Action shortreq(Bit#(32) v); endmethod method Action longreq(Vector#(100, Bit#(32)) v); endmethod endinterface endmodule ================================================ FILE: tests/simmethodtime/test.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "SimmRequest.h" #include "papi.h" #define NUM_EVENTS 4 static void perfinit(void) { static int once = 1; int event[NUM_EVENTS] = {PAPI_TOT_INS, PAPI_TOT_CYC, PAPI_BR_MSP, PAPI_L1_DCM }; if (once) { once = 0; /* Start counting events */ if (PAPI_start_counters(event, NUM_EVENTS) != PAPI_OK) { fprintf(stderr, "PAPI_start_counters - FAILED\n"); exit(1); } } } static void perfprint(long long *perfvalues, const char *name) { printf("%s: Total instructions: %6lld;", name, perfvalues[0]); printf("Total cycles: %6lld;", perfvalues[1]); //printf("Instr per cycle: %2.3f;", (double)perfvalues[0] / (double) perfvalues[1]); //printf("Branches mispredicted: %6lld;", perfvalues[2]); //printf("L1 Cache misses: %6lld;", perfvalues[3]); printf("\n"); } int main(int argc, const char **argv) { long long perfvalues1[NUM_EVENTS], perfvalues2[NUM_EVENTS]; bsvvector_Luint32_t_L100 testvec = {0}; SimmRequestProxy *req = new SimmRequestProxy(IfcNames_SimmRequestS2H); perfinit(); for (int i = 0; i < 10; i++) { if (PAPI_read_counters(perfvalues1, NUM_EVENTS) != PAPI_OK) { fprintf(stderr, "PAPI_read_counters - FAILED\n"); exit(1); } req->shortreq(1); if (PAPI_read_counters(perfvalues1, NUM_EVENTS) != PAPI_OK) { fprintf(stderr, "PAPI_read_counters - FAILED\n"); exit(1); } req->longreq(testvec); if (PAPI_read_counters(perfvalues2, NUM_EVENTS) != PAPI_OK) { fprintf(stderr, "PAPI_read_counters - FAILED\n"); exit(1); } perfprint(perfvalues1, "short"); perfprint(perfvalues2, "long"); } return 0; } ================================================ FILE: tests/simple_manual/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = SimpleRequest:Simple.request H2S_INTERFACES = Simple:SimpleRequest BSVFILES = Simple.bsv #original user program CPPFILES=testsimple.cpp CPPFILES=simple_manual.c CONNECTALFLAGS += -D NO_CPP_PORTAL_CODE include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/simple_manual/Simple.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. interface SimpleRequest; method Action say1(Bit#(32) v); method Action say2(Bit#(32) a, Bit#(32) b); endinterface interface Simple; interface SimpleRequest request; endinterface module mkSimple#(SimpleRequest indication)(Simple); let verbose = False; interface SimpleRequest request; method Action say1(Bit#(32) v); indication.say1(v); endmethod method Action say2(Bit#(32) a, Bit#(32) b); indication.say2(a,b); endmethod endinterface endmodule ================================================ FILE: tests/simple_manual/kernel/Makefile ================================================ # grep get_pcie_portal_descriptor /proc/kallsyms ###################### Flags for using KC705 ################### #BOARD=kc705 ###################### Flags for using VC707 ################### #BOARD=vc707 ###################### Flags for using zedboard ################## #BOARD=zedboard ###################### Flags for using Bluesim ################### BOARD=bluesim ###################### End of target h/w flags ################### ifeq ($(BOARD),bluesim) HARDWARE_FLAGS=-DBSIM endif export KROOT=/lib/modules/$(shell uname -r)/build CPPDIR=../../../cpp BOARDDIR=../$(BOARD)/jni DRIVERDIR=$(src)/../../../ CONNECTAL_MODULE_NAME:=connectaluser_$(USER) KBUILD_EXTRA_SYMBOLS := $(DRIVERDIR)/drivers/pcieportal/Module.symvers \ $(DRIVERDIR)/drivers/portalmem/Module.symvers $(CONNECTAL_MODULE_NAME)-y := ../simple_manual.o \ $(BOARDDIR)/SimpleIndication.o \ $(BOARDDIR)/SimpleRequest.o \ $(CPPDIR)/portal.o \ $(CPPDIR)/transportSocket.o \ $(CPPDIR)/kernel_module.o $(CONNECTAL_MODULE_NAME)-n := $(CPPDIR)/dmaManager.o obj-m := $(CONNECTAL_MODULE_NAME).o ccflags-y := -I$(src)/.. -I$(DRIVERDIR) -I$(src)/$(CPPDIR) -I$(src)/$(BOARDDIR) $(HARDWARE_FLAGS) default: $(MAKE) -C $(KROOT) M=$(PWD) modules clean: $(MAKE) -C $(KROOT) M=$(PWD) clean rm -f a.out bsim_relay socket_for_bluesim tmp.bluesim.makefile.pid CURRENTMOD=$(shell lsmod | grep $(CONNECTAL_MODULE_NAME)) run: host ifeq ($(BOARD),bluesim) @echo running bsim ../bluesim/bin/bsim& echo $$! >tmp.bluesim.makefile.pid else fpgajtag ../$(BOARD)/bin/mkTop.bin.gz endif ifneq ("$(CURRENTMOD)", "") sudo rmmod $(CONNECTAL_MODULE_NAME) #sudo rmmod bdbm_drv endif sudo modprobe pcieportal sudo modprobe portalmem sudo insmod $(CONNECTAL_MODULE_NAME).ko #sudo insmod bdbm_drv.ko ifeq ($(BOARD),bluesim) CONNECTAL_MODULE_NAME=$(CONNECTAL_MODULE_NAME) ./bsim_relay kill `cat tmp.bluesim.makefile.pid` #killall bluetcl endif sudo rmmod $(CONNECTAL_MODULE_NAME) #sudo rmmod bdbm_drv dmesg | tail -30 @rm -f tmp.bluesim.makefile.pid # # Target for making userspace bsim_relay program CINCL=../../.. HOSTSOURCES=$(CPPDIR)/bsim_relay.c $(CPPDIR)/sock_utils.c $(CPPDIR)/portalSocket.c $(CPPDIR)/portal.c host: $(HOSTSOURCES) ifeq ($(BOARD),bluesim) gcc -o bsim_relay -g -I$(CINCL)/cpp -I$(CINCL) -DNO_CPP_PORTAL_CODE -DNO_POLLER_SUPPORT $(HOSTSOURCES) -lpthread endif ================================================ FILE: tests/simple_manual/simple_manual.c ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "GeneratedTypes.h" static int v1a = 42; static int v2a = 2; static int v2b = 4; #define MAX_INDARRAY 2 static PortalInternal intarr[MAX_INDARRAY]; //static PORTAL_INDFUNC indfn[MAX_INDARRAY]; int SimpleIndicationWrapperheard1_cb ( struct PortalInternal *p, const uint32_t v ) { PORTAL_PRINTF("heard1(%d)\n", v); return 0; } int SimpleIndicationWrapperheard2_cb ( struct PortalInternal *p, const uint32_t a, const uint32_t b ) { PORTAL_PRINTF("heard2(%d %d)\n", a, b); return 0; } static void manual_event(void) { int i; for (i = 0; i < MAX_INDARRAY; i++) event_hardware(&intarr[i]); } SimpleRequestCb simple_cbTable = { portal_disconnect, SimpleIndicationWrapperheard1_cb, SimpleIndicationWrapperheard2_cb, }; int main(int argc, const char **argv) { init_portal_internal(&intarr[0], IfcNames_SimpleRequestS2H, DEFAULT_TILE, NULL, NULL, NULL, NULL, SimpleRequest_reqinfo); // portal 1 init_portal_internal(&intarr[1], IfcNames_SimpleRequestH2S, DEFAULT_TILE, SimpleRequest_handleMessage, &simple_cbTable, NULL, NULL, SimpleRequest_reqinfo); // portal 2 intarr[0].item->enableint(&intarr[0], 0); intarr[1].item->enableint(&intarr[1], 0); PORTAL_PRINTF("Main::calling say1(%d)\n", v1a); //device->say1(v1a); SimpleRequest_say1 (&intarr[0], v1a); manual_event(); PORTAL_PRINTF("Main::calling say2(%d, %d)\n", v2a,v2b); //device->say2(v2a,v2b); SimpleRequest_say2 (&intarr[0], v2a, v2b); manual_event(); return 0; } ================================================ FILE: tests/simple_manual/testsimple.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include "SimpleIndication.h" #include "SimpleRequest.h" int v1a = 42; int v2a = 2; int v2b = 4; class SimpleIndication : public SimpleIndicationWrapper { public: virtual void heard1(uint32_t a) { fprintf(stderr, "heard1(%d)\n", a); } virtual void heard2(uint32_t a, uint32_t b) { fprintf(stderr, "heard2(%d %d)\n", a, b); } SimpleIndication(unsigned int id) : SimpleIndicationWrapper(id) {} }; int main(int argc, const char **argv) { SimpleIndication *indication = new SimpleIndication(IfcNames_SimpleIndication); SimpleRequestProxy *device = new SimpleRequestProxy(IfcNames_SimpleRequest); fprintf(stderr, "Main::calling say1(%d)\n", v1a); device->say1(v1a); fprintf(stderr, "Main::calling say2(%d, %d)\n", v2a,v2b); device->say2(v2a,v2b); fprintf(stderr, "Main::about to go to sleep\n"); sleep(5); exit(0); } ================================================ FILE: tests/spi/ConnectalProjectConfig.bsv ================================================ `define ConnectalVersion 15.11.1 `define NumberOfMasters 1 `define PinType Empty `define PinTypeInclude Misc `define NumberOfUserTiles 1 `define SlaveDataBusWidth 32 `define SlaveControlAddrWidth 5 `define BurstLenSize 10 `define project_dir $(DTOP) `define MainClockPeriod 20 `define DerivedClockPeriod 10.000000 `define BsimHostInterface `define PhysAddrWidth 40 `define SIMULATION `define BOARD_bluesim ================================================ FILE: tests/spi/Makefile ================================================ CONNECTALDIR?=../.. run: spiTestBench ./spiTestBench gtkwave dump.vcd spitest.gtkw spiTestBench: $(CONNECTALDIR)/lib/bsv/ConnectalSpi.bsv mkdir -p obj bsc --show-schedule -sim -info-dir obj -bdir obj -p +:$(CONNECTALDIR)/lib/bsv:$(CONNECTALDIR)/bsv -g mkSpiTestBench -u $(CONNECTALDIR)/lib/bsv/ConnectalSpi.bsv bsc --show-schedule -sim -info-dir obj -bdir obj -e mkSpiTestBench -o spiTestBench clean: rm -rf spiTestBench* mkSpiTestBench.* model_mkSpiTestBench.* dump.vcd obj ================================================ FILE: tests/spi/spitest.gtkw ================================================ [*] [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI [*] Wed Apr 1 15:21:05 2015 [*] [dumpfile] "/scratch/jamey/connectal/tests/spi/dump.vcd" [dumpfile_mtime] "Wed Apr 1 15:19:07 2015" [dumpfile_size] 10945 [savefile] "/scratch/jamey/connectal/tests/spi/spitest.gtkw" [timestart] 0 [size] 1302 874 [pos] -1 -1 *-8.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] main. [sst_width] 224 [signals_width] 150 [sst_expanded] 1 [sst_vpaned_height] 248 @28 main.top.probeMiso$PROBE main.top.probeMosi$PROBE main.top.probeSelN$PROBE [pattern_trace] 1 [pattern_trace] 0 ================================================ FILE: tests/spikehw/AxiEthBufferBvi.bsv ================================================ /* ../../generated/scripts/importbvi.py -o AxiEthBufferBvi.bsv -I AxiEthBuffer -P AxiEthBuffer -c S_AXI_ACLK -r S_AXI_ARESETN -c AXI_STR_TXD_ACLK -r AXI_STR_TXD_ARESETN -c AXI_STR_TXC_ACLK -r AXI_STR_TXC_ARESETN -c AXI_STR_RXD_ACLK -r AXI_STR_RXD_ARESETN -c AXI_STR_RXS_ACLK -r AXI_STR_RXS_ARESETN -c rx_mac_aclk -r rx_reset -c tx_mac_aclk -r tx_reset -r PHY_RST_N -c GTX_CLK -n speed_is_10_100 -f S_AXI_2TEMAC -n RESET2PCSPMA -n RESET2TEMACn -f AXI_STR_RXD -f AXI_STR_RXS -f AXI_STR_TXC -f AXI_STR_TXD cores/nfsume/eth_buf/eth_buf_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import Vector::*; import AxiBits::*; import AxiStream::*; interface AxiEthBufferClocks; interface Clock axi_str_rxd_aclk; interface Clock axi_str_rxs_aclk; interface Clock axi_str_txc_aclk; interface Clock axi_str_txd_aclk; interface Clock gtx_clk; interface Clock rx_mac_aclk; interface Clock s_axi_aclk; interface Clock tx_mac_aclk; interface Reset axi_str_rxd_aresetn; interface Reset axi_str_rxs_aresetn; interface Reset axi_str_txc_aresetn; interface Reset axi_str_txd_aresetn; interface Reset rx_reset; interface Reset s_axi_aresetn; interface Reset tx_reset; endinterface (* always_ready, always_enabled *) interface AxiethbufferAxi_str_rxd; method Bit#(32) tdata(); method Bit#(4) tkeep(); method Bit#(1) tlast(); method Action tready(Bit#(1) v); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface AxiethbufferAxi_str_rxs; method Bit#(32) tdata(); method Bit#(4) tkeep(); method Bit#(1) tlast(); method Action tready(Bit#(1) v); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface AxiethbufferAxi_str_txc; method Action tdata(Bit#(32) v); method Action tkeep(Bit#(4) v); method Action tlast(Bit#(1) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AxiethbufferAxi_str_txd; method Action tdata(Bit#(32) v); method Action tkeep(Bit#(4) v); method Action tlast(Bit#(1) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AxiethbufferEmac; method Action client_autoneg_int(Bit#(1) v); method Action reset_done_int(Bit#(1) v); method Action rx_dcm_locked_int(Bit#(1) v); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface AxiethbufferMdc; method Action temac(Bit#(1) v); method Bit#(1) top(); endinterface (* always_ready, always_enabled *) interface AxiethbufferMdio; method Bit#(1) i_temac(); method Action i_top(Bit#(1) v); method Action o_pcspma(Bit#(1) v); method Action o_temac(Bit#(1) v); method Bit#(1) o_top(); method Action t_pcspma(Bit#(1) v); method Action t_temac(Bit#(1) v); method Bit#(1) t_top(); endinterface (* always_ready, always_enabled *) interface AxiethbufferPause; method Bit#(1) req(); method Bit#(16) val(); endinterface (* always_ready, always_enabled *) interface AxiethbufferPcspma; method Action status_vector(Bit#(16) v); endinterface (* always_ready, always_enabled *) interface AxiethbufferPhy; method Reset rst_n(); endinterface (* always_ready, always_enabled *) interface AxiethbufferRx; method Action axis_mac_tdata(Bit#(8) v); method Action axis_mac_tlast(Bit#(1) v); method Action axis_mac_tuser(Bit#(1) v); method Action axis_mac_tvalid(Bit#(1) v); method Action clk_enable_in(Bit#(1) v); method Action statistics_valid(Bit#(1) v); method Action statistics_vector(Bit#(28) v); endinterface (* always_ready, always_enabled *) interface AxiethbufferS_axi; method Action araddr(Bit#(18) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(18) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AxiethbufferS_axi_2temac; method Bit#(12) araddr(); method Action arready(Bit#(1) v); method Bit#(1) arvalid(); method Bit#(12) awaddr(); method Action awready(Bit#(1) v); method Bit#(1) awvalid(); method Bit#(1) bready(); method Action bresp(Bit#(2) v); method Action bvalid(Bit#(1) v); method Action rdata(Bit#(32) v); method Bit#(1) rready(); method Action rresp(Bit#(2) v); method Action rvalid(Bit#(1) v); method Bit#(32) wdata(); method Action wready(Bit#(1) v); method Bit#(1) wvalid(); endinterface (* always_ready, always_enabled *) interface AxiethbufferTx; method Bit#(8) axis_mac_tdata(); method Bit#(1) axis_mac_tlast(); method Action axis_mac_tready(Bit#(1) v); method Bit#(1) axis_mac_tuser(); method Bit#(1) axis_mac_tvalid(); method Bit#(9) ifg_delay(); endinterface (* always_ready, always_enabled *) interface AxiEthBuffer; interface AxiStreamMaster#(32) axi_str_rxd; interface AxiStreamMaster#(32) axi_str_rxs; interface AxiStreamSlave#(32) axi_str_txc; interface AxiStreamSlave#(32) axi_str_txd; interface AxiethbufferEmac emac; method Bit#(1) interrupt(); interface AxiethbufferMdc mdc; interface AxiethbufferMdio mdio; interface AxiethbufferPause pause; interface AxiethbufferPcspma pcspma; interface AxiethbufferPhy phy; method Bit#(1) reset2pcspma(); method Bit#(1) reset2temacn(); interface AxiethbufferRx rx; interface AxiethbufferS_axi_2temac s_axi_2temac; interface AxiethbufferS_axi s_axi; method Action speed_is_10_100(Bit#(1) v); interface AxiethbufferTx tx; endinterface import "BVI" eth_buf = module mkAxiEthBuffer#(AxiEthBufferClocks clks)(AxiEthBuffer); default_clock clk(); default_reset rst(); input_clock axi_str_rxd_aclk(AXI_STR_RXD_ACLK) = clks.axi_str_rxd_aclk; input_reset axi_str_rxd_aresetn(AXI_STR_RXD_ARESETN) = clks.axi_str_rxd_aresetn; input_clock axi_str_rxs_aclk(AXI_STR_RXS_ACLK) = clks.axi_str_rxs_aclk; input_reset axi_str_rxs_aresetn(AXI_STR_RXS_ARESETN) = clks.axi_str_rxs_aresetn; input_clock axi_str_txc_aclk(AXI_STR_TXC_ACLK) = clks.axi_str_txc_aclk; input_reset axi_str_txc_aresetn(AXI_STR_TXC_ARESETN) = clks.axi_str_txc_aresetn; input_clock axi_str_txd_aclk(AXI_STR_TXD_ACLK) = clks.axi_str_txd_aclk; input_reset axi_str_txd_aresetn(AXI_STR_TXD_ARESETN) = clks.axi_str_txd_aresetn; input_clock gtx_clk(GTX_CLK) = clks.gtx_clk; input_clock rx_mac_aclk(rx_mac_aclk) = clks.rx_mac_aclk; input_reset rx_reset(rx_reset) clocked_by (rx_mac_aclk) = clks.rx_reset; input_clock s_axi_aclk(S_AXI_ACLK) = clks.s_axi_aclk; input_reset s_axi_aresetn(S_AXI_ARESETN) clocked_by (s_axi_aclk) = clks.s_axi_aresetn; input_clock tx_mac_aclk(tx_mac_aclk) = clks.tx_mac_aclk; input_reset tx_reset(tx_reset) clocked_by (tx_mac_aclk) = clks.tx_reset; interface AxiStreamMaster axi_str_rxd; method AXI_STR_RXD_DATA tdata() clocked_by (axi_str_rxd_aclk) reset_by (axi_str_rxd_aresetn); method AXI_STR_RXD_KEEP tkeep() clocked_by (axi_str_rxd_aclk) reset_by (axi_str_rxd_aresetn); method AXI_STR_RXD_LAST tlast() clocked_by (axi_str_rxd_aclk) reset_by (axi_str_rxd_aresetn); method tready(AXI_STR_RXD_READY) clocked_by (axi_str_rxd_aclk) reset_by (axi_str_rxd_aresetn) enable((*inhigh*) EN_AXI_STR_RXD_READY); method AXI_STR_RXD_VALID tvalid() clocked_by (axi_str_rxd_aclk) reset_by (axi_str_rxd_aresetn); endinterface interface AxiStreamMaster axi_str_rxs; method AXI_STR_RXS_DATA tdata() clocked_by (axi_str_rxs_aclk) reset_by (axi_str_rxs_aresetn); method AXI_STR_RXS_KEEP tkeep() clocked_by (axi_str_rxs_aclk) reset_by (axi_str_rxs_aresetn); method AXI_STR_RXS_LAST tlast() clocked_by (axi_str_rxs_aclk) reset_by (axi_str_rxs_aresetn); method tready(AXI_STR_RXS_READY) clocked_by (axi_str_rxs_aclk) reset_by (axi_str_rxs_aresetn) enable((*inhigh*) EN_AXI_STR_RXS_READY); method AXI_STR_RXS_VALID tvalid() clocked_by (axi_str_rxs_aclk) reset_by (axi_str_rxs_aresetn); endinterface interface AxiStreamSlave axi_str_txc; method tdata(AXI_STR_TXC_TDATA) clocked_by (axi_str_txc_aclk) reset_by (axi_str_txc_aresetn) enable((*inhigh*) EN_AXI_STR_TXC_TDATA); method tkeep(AXI_STR_TXC_TKEEP) clocked_by (axi_str_txc_aclk) reset_by (axi_str_txc_aresetn) enable((*inhigh*) EN_AXI_STR_TXC_TKEEP); method tlast(AXI_STR_TXC_TLAST) clocked_by (axi_str_txc_aclk) reset_by (axi_str_txc_aresetn) enable((*inhigh*) EN_AXI_STR_TXC_TLAST); method AXI_STR_TXC_TREADY tready() clocked_by (axi_str_txc_aclk) reset_by (axi_str_txc_aresetn); method tvalid(AXI_STR_TXC_TVALID) clocked_by (axi_str_txc_aclk) reset_by (axi_str_txc_aresetn) enable((*inhigh*) EN_AXI_STR_TXC_TVALID); endinterface interface AxiStreamSlave axi_str_txd; method tdata(AXI_STR_TXD_TDATA) clocked_by (axi_str_txd_aclk) reset_by (axi_str_txd_aresetn) enable((*inhigh*) EN_AXI_STR_TXD_TDATA); method tkeep(AXI_STR_TXD_TKEEP) clocked_by (axi_str_txd_aclk) reset_by (axi_str_txd_aresetn) enable((*inhigh*) EN_AXI_STR_TXD_TKEEP); method tlast(AXI_STR_TXD_TLAST) clocked_by (axi_str_txd_aclk) reset_by (axi_str_txd_aresetn) enable((*inhigh*) EN_AXI_STR_TXD_TLAST); method AXI_STR_TXD_TREADY tready() clocked_by (axi_str_txd_aclk) reset_by (axi_str_txd_aresetn); method tvalid(AXI_STR_TXD_TVALID) clocked_by (axi_str_txd_aclk) reset_by (axi_str_txd_aresetn) enable((*inhigh*) EN_AXI_STR_TXD_TVALID); endinterface interface AxiethbufferEmac emac; method client_autoneg_int(EMAC_CLIENT_AUTONEG_INT) enable((*inhigh*) EN_EMAC_CLIENT_AUTONEG_INT); method reset_done_int(EMAC_RESET_DONE_INT) enable((*inhigh*) EN_EMAC_RESET_DONE_INT); method rx_dcm_locked_int(EMAC_RX_DCM_LOCKED_INT) enable((*inhigh*) EN_EMAC_RX_DCM_LOCKED_INT); endinterface method INTERRUPT interrupt(); interface AxiethbufferMdc mdc; method temac(mdc_temac) enable((*inhigh*) EN_mdc_temac); method mdc_top top(); endinterface interface AxiethbufferMdio mdio; method mdio_i_temac i_temac(); method i_top(mdio_i_top) enable((*inhigh*) EN_mdio_i_top); method o_pcspma(mdio_o_pcspma) enable((*inhigh*) EN_mdio_o_pcspma); method o_temac(mdio_o_temac) enable((*inhigh*) EN_mdio_o_temac); method mdio_o_top o_top(); method t_pcspma(mdio_t_pcspma) enable((*inhigh*) EN_mdio_t_pcspma); method t_temac(mdio_t_temac) enable((*inhigh*) EN_mdio_t_temac); method mdio_t_top t_top(); endinterface interface AxiethbufferPause pause; method pause_req req(); method pause_val val(); endinterface interface AxiethbufferPcspma pcspma; method status_vector(PCSPMA_STATUS_VECTOR) enable((*inhigh*) EN_PCSPMA_STATUS_VECTOR); endinterface interface AxiethbufferPhy phy; output_reset rst_n(PHY_RST_N); endinterface method RESET2PCSPMA reset2pcspma(); method RESET2TEMACn reset2temacn(); interface AxiethbufferRx rx; method axis_mac_tdata(rx_axis_mac_tdata) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_axis_mac_tdata); method axis_mac_tlast(rx_axis_mac_tlast) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_axis_mac_tlast); method axis_mac_tuser(rx_axis_mac_tuser) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_axis_mac_tuser); method axis_mac_tvalid(rx_axis_mac_tvalid) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_axis_mac_tvalid); method clk_enable_in(RX_CLK_ENABLE_IN) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_CLK_ENABLE_IN); method statistics_valid(rx_statistics_valid) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_statistics_valid); method statistics_vector(rx_statistics_vector) clocked_by (rx_mac_aclk) reset_by (rx_reset) enable((*inhigh*) EN_rx_statistics_vector); endinterface interface AxiethbufferS_axi_2temac s_axi_2temac; method S_AXI_2TEMAC_ARADDR araddr(); method arready(S_AXI_2TEMAC_ARREADY) enable((*inhigh*) EN_S_AXI_2TEMAC_ARREADY); method S_AXI_2TEMAC_ARVALID arvalid(); method S_AXI_2TEMAC_AWADDR awaddr(); method awready(S_AXI_2TEMAC_AWREADY) enable((*inhigh*) EN_S_AXI_2TEMAC_AWREADY); method S_AXI_2TEMAC_AWVALID awvalid(); method S_AXI_2TEMAC_BREADY bready(); method bresp(S_AXI_2TEMAC_BRESP) enable((*inhigh*) EN_S_AXI_2TEMAC_BRESP); method bvalid(S_AXI_2TEMAC_BVALID) enable((*inhigh*) EN_S_AXI_2TEMAC_BVALID); method rdata(S_AXI_2TEMAC_RDATA) enable((*inhigh*) EN_S_AXI_2TEMAC_RDATA); method S_AXI_2TEMAC_RREADY rready(); method rresp(S_AXI_2TEMAC_RRESP) enable((*inhigh*) EN_S_AXI_2TEMAC_RRESP); method rvalid(S_AXI_2TEMAC_RVALID) enable((*inhigh*) EN_S_AXI_2TEMAC_RVALID); method S_AXI_2TEMAC_WDATA wdata(); method wready(S_AXI_2TEMAC_WREADY) enable((*inhigh*) EN_S_AXI_2TEMAC_WREADY); method S_AXI_2TEMAC_WVALID wvalid(); endinterface interface AxiethbufferS_axi s_axi; method araddr(S_AXI_ARADDR) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_ARADDR); method S_AXI_ARREADY arready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method arvalid(S_AXI_ARVALID) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_ARVALID); method awaddr(S_AXI_AWADDR) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_AWADDR); method S_AXI_AWREADY awready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method awvalid(S_AXI_AWVALID) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_AWVALID); method bready(S_AXI_BREADY) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_BREADY); method S_AXI_BRESP bresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method S_AXI_BVALID bvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method S_AXI_RDATA rdata() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method rready(S_AXI_RREADY) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_RREADY); method S_AXI_RRESP rresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method S_AXI_RVALID rvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wdata(S_AXI_WDATA) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_WDATA); method S_AXI_WREADY wready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wstrb(S_AXI_WSTRB) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_WSTRB); method wvalid(S_AXI_WVALID) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_S_AXI_WVALID); endinterface method speed_is_10_100(speed_is_10_100) enable((*inhigh*) EN_speed_is_10_100); interface AxiethbufferTx tx; method tx_axis_mac_tdata axis_mac_tdata() clocked_by (tx_mac_aclk) reset_by (tx_reset); method tx_axis_mac_tlast axis_mac_tlast() clocked_by (tx_mac_aclk) reset_by (tx_reset); method axis_mac_tready(tx_axis_mac_tready) clocked_by (tx_mac_aclk) reset_by (tx_reset) enable((*inhigh*) EN_tx_axis_mac_tready); method tx_axis_mac_tuser axis_mac_tuser() clocked_by (tx_mac_aclk) reset_by (tx_reset); method tx_axis_mac_tvalid axis_mac_tvalid() clocked_by (tx_mac_aclk) reset_by (tx_reset); method tx_ifg_delay ifg_delay() clocked_by (tx_mac_aclk) reset_by (tx_reset); endinterface schedule (axi_str_rxd.tdata, axi_str_rxd.tkeep, axi_str_rxd.tlast, axi_str_rxd.tready, axi_str_rxd.tvalid, axi_str_rxs.tdata, axi_str_rxs.tkeep, axi_str_rxs.tlast, axi_str_rxs.tready, axi_str_rxs.tvalid, axi_str_txc.tdata, axi_str_txc.tkeep, axi_str_txc.tlast, axi_str_txc.tready, axi_str_txc.tvalid, axi_str_txd.tdata, axi_str_txd.tkeep, axi_str_txd.tlast, axi_str_txd.tready, axi_str_txd.tvalid, emac.client_autoneg_int, emac.reset_done_int, emac.rx_dcm_locked_int, interrupt, mdc.temac, mdc.top, mdio.i_temac, mdio.i_top, mdio.o_pcspma, mdio.o_temac, mdio.o_top, mdio.t_pcspma, mdio.t_temac, mdio.t_top, pause.req, pause.val, pcspma.status_vector, rx.axis_mac_tdata, rx.axis_mac_tlast, rx.axis_mac_tuser, rx.axis_mac_tvalid, rx.clk_enable_in, rx.statistics_valid, rx.statistics_vector, s_axi_2temac.araddr, s_axi_2temac.arready, s_axi_2temac.arvalid, s_axi_2temac.awaddr, s_axi_2temac.awready, s_axi_2temac.awvalid, s_axi_2temac.bready, s_axi_2temac.bresp, s_axi_2temac.bvalid, s_axi_2temac.rdata, s_axi_2temac.rready, s_axi_2temac.rresp, s_axi_2temac.rvalid, s_axi_2temac.wdata, s_axi_2temac.wready, s_axi_2temac.wvalid, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, speed_is_10_100, tx.axis_mac_tdata, tx.axis_mac_tlast, tx.axis_mac_tready, tx.axis_mac_tuser, tx.axis_mac_tvalid, tx.ifg_delay, reset2pcspma, reset2temacn) CF (axi_str_rxd.tdata, axi_str_rxd.tkeep, axi_str_rxd.tlast, axi_str_rxd.tready, axi_str_rxd.tvalid, axi_str_rxs.tdata, axi_str_rxs.tkeep, axi_str_rxs.tlast, axi_str_rxs.tready, axi_str_rxs.tvalid, axi_str_txc.tdata, axi_str_txc.tkeep, axi_str_txc.tlast, axi_str_txc.tready, axi_str_txc.tvalid, axi_str_txd.tdata, axi_str_txd.tkeep, axi_str_txd.tlast, axi_str_txd.tready, axi_str_txd.tvalid, emac.client_autoneg_int, emac.reset_done_int, emac.rx_dcm_locked_int, interrupt, mdc.temac, mdc.top, mdio.i_temac, mdio.i_top, mdio.o_pcspma, mdio.o_temac, mdio.o_top, mdio.t_pcspma, mdio.t_temac, mdio.t_top, pause.req, pause.val, pcspma.status_vector, rx.axis_mac_tdata, rx.axis_mac_tlast, rx.axis_mac_tuser, rx.axis_mac_tvalid, rx.clk_enable_in, rx.statistics_valid, rx.statistics_vector, s_axi_2temac.araddr, s_axi_2temac.arready, s_axi_2temac.arvalid, s_axi_2temac.awaddr, s_axi_2temac.awready, s_axi_2temac.awvalid, s_axi_2temac.bready, s_axi_2temac.bresp, s_axi_2temac.bvalid, s_axi_2temac.rdata, s_axi_2temac.rready, s_axi_2temac.rresp, s_axi_2temac.rvalid, s_axi_2temac.wdata, s_axi_2temac.wready, s_axi_2temac.wvalid, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, speed_is_10_100, tx.axis_mac_tdata, tx.axis_mac_tlast, tx.axis_mac_tready, tx.axis_mac_tuser, tx.axis_mac_tvalid, tx.ifg_delay, reset2pcspma, reset2temacn); endmodule instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(12,32), AxiethbufferS_axi); function Axi4SlaveLiteBits#(12,32) toAxi4SlaveBits(AxiethbufferS_axi s); return (interface Axi4SlaveLiteBits#(12,32); method araddr = compose(s.araddr, extend); method arready = s.arready; method arvalid = s.arvalid; method awaddr = compose(s.awaddr, extend); method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance ================================================ FILE: tests/spikehw/AxiEthSubsystem.bsv ================================================ // Copyright (c) 2016 Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `include "ConnectalProjectConfig.bsv" import FIFOF::*; import BRAMFIFO::*; import GetPut::*; import Clocks::*; import Connectable::*; import StmtFSM::*; `define PROBE_ME `ifdef PROBE_ME import Probe::*; `else interface Probe#(type a); method Action _write(a v); endinterface module mkProbe(Probe#(a)); method Action _write(a v); endmethod endmodule `endif import Vector::*; import AxiBits::*; import AxiStream::*; import AxiEthBufferBvi::*; import TriModeMacBvi::*; import GigEthPcsPmaBvi::*; import AxiEth1000BaseX::*; import SyncAxisFifo32x1024::*; import AxiDmaBvi::*; interface AxiEthSubsystem; interface AxidmabviMm2s mm2s_dma; interface AxidmabviS2mm s2mm_dma; interface AxidmabviM_axi_mm2s m_axi_mm2s; interface AxidmabviM_axi_s2mm m_axi_s2mm; interface AxidmabviM_axi_sg m_axi_sg; interface Axi4SlaveLiteBits#(10,32) s_axi_dma; interface TrimodemacS_axi s_axi_mac; interface TrimodemacMac mac; interface AxiethbviSfp sfp; interface AxiethbviMgt mgt; interface GigethpcspmabviSignal signal; interface GigethpcspmabviMmcm mmcm; endinterface instance Connectable#(TrimodemacGmii,GigethpcspmabviGmii); module mkConnection#(TrimodemacGmii mac, GigethpcspmabviGmii phy)(Empty); rule rx; mac.rx_dv(phy.rx_dv()); mac.rx_er(phy.rx_er()); mac.rxd(phy.rxd()); endrule rule tx; phy.tx_en(mac.tx_en()); phy.tx_er(mac.tx_er()); phy.txd(mac.txd()); endrule endmodule endinstance instance Connectable#(TrimodemacMdio,GigethpcspmabviMdio); module mkConnection#(TrimodemacMdio macMdio, GigethpcspmabviMdio phyMdio)(Empty); rule rl_mdio; macMdio.i(phyMdio.o()); phyMdio.i(macMdio.o()); endrule endmodule endinstance instance Connectable#(TriModeMac,GigEthPcsPma); module mkConnection#(TriModeMac mac, GigEthPcsPma phy)(Empty); let mdcCnx <- mkConnection(phy.mdc, mac.mdc); // should be a clock, but PHY is providing a clock to MAC and this would make a cycle let mdioCnx <- mkConnection(mac.mdio, phy.mdio); let gmiiCnx <- mkConnection(mac.gmii, phy.gmii); endmodule endinstance module mkStreamControlConnection#(AxiStreamMaster#(32) from, AxiStreamMaster#(32) cntrl, TrimodemacTx_axis_mac to, Clock fromClock, Reset fromReset, Clock toClock, Reset toReset)(Empty); let sfifo <- mkSyncAxisFifo32x1024(fromClock, fromReset, toClock, toReset); Reg#(Bit#(2)) phaseReg <- mkReg(0, clocked_by toClock, reset_by toReset); Probe#(Bit#(32)) fromControlDataProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(1)) fromControlValidProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(32)) fromDataProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(4)) fromKeepProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(1)) fromLastProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(8)) toDataProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(4)) toKeepProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(1)) toLastProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(1)) toValidProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(2)) phaseProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(4)) moreDataProbe <- mkProbe(clocked_by toClock, reset_by toReset); rule rl_control if (cntrl.tvalid() == 1); fromControlDataProbe <= cntrl.tdata(); fromControlValidProbe <= cntrl.tvalid(); endrule let fromCnx <- mkConnection(from, sfifo.s_axis); Wire#(Bool) doDeq <- mkDWire(False, clocked_by toClock, reset_by toReset); rule rl_expand if (to.tready() == 1 && sfifo.m_axis.tvalid() == 1); fromDataProbe <= sfifo.m_axis.tdata(); fromKeepProbe <= sfifo.m_axis.tkeep(); fromLastProbe <= sfifo.m_axis.tlast(); Vector#(4,Bit#(8)) data = unpack(sfifo.m_axis.tdata()); let keep = sfifo.m_axis.tkeep(); let last = sfifo.m_axis.tlast(); //match { .data, .keep, .last } = sfifo.first(); let phase = phaseReg; Bool lastPhase = (phaseReg == 3); Bit#(4) moreData = keep[3:phase+1]; if (!lastPhase) lastPhase = (moreData == 0); to.tdata(data[phase]); //to.tkeep(keep[phase]); to.tlast(pack(last == 1 && lastPhase)); toDataProbe <= data[phase]; toLastProbe <= pack(last == 1 && lastPhase); if (lastPhase) begin //sfifo.deq(); doDeq <= True; phase = 0; end else begin phase = phase + 1; end phaseReg <= phase; phaseProbe <= phase; moreDataProbe <= moreData; endrule rule rl_to_handshake; to.tvalid(sfifo.m_axis.tvalid()); toValidProbe <= sfifo.m_axis.tvalid(); sfifo.m_axis.tready(pack(doDeq)); endrule endmodule module mkStreamStatusConnection#(TrimodemacRx_axis_mac from, AxiStreamSlave#(32) to, AxiStreamSlave#(32) status, Clock fromClock, Reset fromReset, Clock toClock, Reset toReset)(Empty); Reg#(Bit#(16)) byteCountReg <- mkReg(0, clocked_by fromClock, reset_by fromReset); Reg#(Bit#(2)) phaseReg <- mkReg(0, clocked_by fromClock, reset_by fromReset); Vector#(4,Reg#(Bit#(8))) dataReg <- replicateM(mkReg(0), clocked_by fromClock, reset_by fromReset); Reg#(Bit#(4)) keepReg <- mkReg(0, clocked_by fromClock, reset_by fromReset); let sfifo <- mkSyncAxisFifo32x1024(fromClock, fromReset, toClock, toReset); let stsfifo <- mkSyncAxisFifo32x1024(fromClock, fromReset, toClock, toReset); Wire#(Bool) doEnq <- mkDWire(False, clocked_by fromClock, reset_by fromReset); Probe#(Bool) probeOverrun <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(1)) fromValidProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(8)) fromDataProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(1)) fromLastProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(32)) toDataProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(4)) toKeepProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(2)) phaseProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(1)) toReadyProbe <- mkProbe(clocked_by toClock, reset_by toReset); Probe#(Bit#(16)) byteCountProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); FIFOF#(Bit#(16)) lengthFifo <- mkFIFOF(clocked_by fromClock, reset_by fromReset); Wire#(Bit#(32)) statusDataWire <- mkDWire(0, clocked_by fromClock, reset_by fromReset); Wire#(Bit#(1)) statusLastWire <- mkDWire(0, clocked_by fromClock, reset_by fromReset); Wire#(Bit#(1)) statusValidWire <- mkDWire(0, clocked_by fromClock, reset_by fromReset); Probe#(Bit#(32)) statusDataProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(1)) statusLastProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); Probe#(Bit#(1)) statusValidProbe <- mkProbe(clocked_by fromClock, reset_by fromReset); let stsFsm <- mkAutoFSM((seq while (True) seq await (lengthFifo.notEmpty && stsfifo.s_axis.tready==1); action // status word statusDataWire <= 32'h80000000 | extend(lengthFifo.first); statusLastWire <= 0; statusValidWire <= 1; endaction await (stsfifo.s_axis.tready==1); action // app0 statusDataWire <= 0; statusLastWire <= 0; statusValidWire <= 1; endaction await (stsfifo.s_axis.tready==1); action // app1 statusDataWire <= 1; statusLastWire <= 0; statusValidWire <= 1; endaction await (stsfifo.s_axis.tready==1); action // app2 statusDataWire <= 2; statusLastWire <= 0; statusValidWire <= 1; endaction await (stsfifo.s_axis.tready==1); action // app3 statusDataWire <= 3; statusLastWire <= 0; statusValidWire <= 1; endaction await (stsfifo.s_axis.tready==1); action // app4 statusDataWire <= extend(lengthFifo.first); statusLastWire <= 0; statusValidWire <= 1; lengthFifo.deq(); endaction endseq // while endseq), clocked_by fromClock, reset_by fromReset); rule rl_status_handshake; if (statusValidWire == 1) begin statusValidProbe <= 1; statusDataProbe <= statusDataWire; statusLastProbe <= statusLastWire; end stsfifo.s_axis.tvalid(statusValidWire); stsfifo.s_axis.tdata(statusDataWire); stsfifo.s_axis.tlast(statusLastWire); stsfifo.s_axis.tkeep(maxBound); endrule rule rl_overrun if (from.tvalid() == 1 && sfifo.s_axis.tready() == 0); probeOverrun <= True; endrule rule rl_from_valid; fromValidProbe <= from.tvalid(); endrule rule rl_combine if (unpack(from.tvalid())); phaseProbe <= phaseReg; Bool last = unpack(from.tlast()); let byteCount = byteCountReg + 1; let phase = phaseReg; Vector#(4,Bit#(8)) data = readVReg(dataReg); let keep = keepReg; keep[phase] = 1; //from.tkeep(); data[phase] = from.tdata(); sfifo.s_axis.tdata(pack(data)); sfifo.s_axis.tkeep(keep); sfifo.s_axis.tlast(pack(last)); byteCountProbe <= byteCount; if (last || (phaseReg == 3)) begin toKeepProbe <= keep; toDataProbe <= pack(data); fromLastProbe <= pack(last); //from.tlast(); phase = 0; data = unpack(0); keep = 0; doEnq <= True; //sfifo.enq(tuple3(pack(data), keep, pack(last))); end else begin phase = phase + 1; end if (last) begin byteCount = 0; lengthFifo.enq(byteCount); end byteCountReg <= byteCount; phaseReg <= phase; writeVReg(dataReg, data); keepReg <= keep; fromDataProbe <= from.tdata(); endrule rule rl_from_handshake; //from.tready(pack(sfifo.s_axis.tready())); // scary -- no backpressure sfifo.s_axis.tvalid(pack(doEnq)); endrule rule rl_to_ready_probe; toReadyProbe <= to.tready(); endrule let toCnx <- mkConnection(sfifo.m_axis, to); let stsCnx <- mkConnection(stsfifo.m_axis, status); endmodule (* synthesize *) module mkAxiEthBvi#(Clock axis_clk, Clock ref_clk)(AxiEthSubsystem); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; // connect_bd_net -net eth_buf_RESET2PCSPMA [get_bd_pins eth_buf/RESET2PCSPMA] [get_bd_pins pcs_pma/reset] //FIXME // let resetToPcsPma <- mkReset(10, True, ref_clk); let pcs <- mkGigEthPcsPmaBvi(ref_clk, reset); // connect_bd_net -net pcs_pma_userclk2_out [get_bd_ports userclk2_out] [get_bd_pins eth_buf/GTX_CLK] [get_bd_pins eth_mac/gtx_clk] [get_bd_pins pcs_pma/userclk2_out] Clock gtx_clk = pcs.userclk2.out; let trimodemac <- mkTriModeMacBvi(gtx_clk, axis_clk, reset, reset, reset, reset); // connect_bd_intf_net -intf_net eth_mac_gmii [get_bd_intf_pins eth_mac/gmii] [get_bd_intf_pins pcs_pma/gmii_pcs_pma] let gmiiConnection <- mkConnection(trimodemac.gmii, pcs.gmii); // connect_bd_net -net eth_mac_mdc [get_bd_pins eth_mac/mdc] [get_bd_pins pcs_pma/mdc] rule rl_misc; pcs.mdc(trimodemac.mdc()); // actually a clock endrule // connect_bd_net -net eth_mac_mdio_o [get_bd_pins eth_mac/mdio_o] [get_bd_pins pcs_pma/mdio_i] // connect_bd_net -net pcs_pma_mdio_o [get_bd_pins eth_mac/mdio_i] [get_bd_pins pcs_pma/mdio_o] let mdioConnection <- mkConnection(trimodemac.mdio, pcs.mdio); // connect_bd_net -net reset_inv_Res [get_bd_pins eth_mac/glbl_rstn] [get_bd_pins eth_mac/rx_axi_rstn] [get_bd_pins eth_mac/tx_axi_rstn] [get_bd_pins reset_inv/Res] // ports: // connect_bd_intf_net -intf_net eth_mac_rx_statistics [get_bd_intf_ports rx_statistics] [get_bd_intf_pins eth_mac/rx_statistics] // connect_bd_intf_net -intf_net eth_mac_tx_statistics [get_bd_intf_ports tx_statistics] [get_bd_intf_pins eth_mac/tx_statistics] // connect_bd_intf_net -intf_net mgt_clk_1 [get_bd_intf_ports mgt_clk] [get_bd_intf_pins pcs_pma/gtrefclk_in] // connect_bd_intf_net -intf_net pcs_pma_sfp [get_bd_intf_ports sfp] [get_bd_intf_pins pcs_pma/sfp] // connect_bd_intf_net -intf_net s_axi_1 [get_bd_intf_ports s_axi] [get_bd_intf_pins eth_mac/s_axi] // connect_bd_intf_net -intf_net s_axis_pause_1 [get_bd_intf_ports s_axis_pause] [get_bd_intf_pins eth_mac/s_axis_pause] // connect_bd_intf_net -intf_net s_axis_tx_1 [get_bd_intf_ports s_axis_tx] [get_bd_intf_pins eth_mac/s_axis_tx] // connect_bd_net -net eth_mac_mac_irq [get_bd_ports mac_irq] [get_bd_pins eth_mac/mac_irq] // connect_bd_net -net eth_mac_rx_axis_filter_tuser [get_bd_ports rx_axis_filter_tuser] [get_bd_pins eth_mac/rx_axis_filter_tuser] // connect_bd_net -net eth_mac_rx_mac_aclk [get_bd_ports rx_mac_aclk] [get_bd_pins eth_mac/rx_mac_aclk] // connect_bd_net -net eth_mac_rx_reset [get_bd_ports rx_reset] [get_bd_pins eth_mac/rx_reset] // connect_bd_net -net eth_mac_tx_mac_aclk [get_bd_ports tx_mac_aclk] [get_bd_pins eth_mac/tx_mac_aclk] // connect_bd_net -net eth_mac_tx_reset [get_bd_ports tx_reset] [get_bd_pins eth_mac/tx_reset] // connect_bd_net -net glbl_rst_1 [get_bd_ports glbl_rst] [get_bd_pins pcs_pma/reset] [get_bd_pins reset_inv/Op1] // connect_bd_net -net pcs_pma_gt0_qplloutclk_out [get_bd_ports gt0_qplloutclk_out] [get_bd_pins pcs_pma/gt0_qplloutclk_out] // connect_bd_net -net pcs_pma_gt0_qplloutrefclk_out [get_bd_ports gt0_qplloutrefclk_out] [get_bd_pins pcs_pma/gt0_qplloutrefclk_out] // connect_bd_net -net pcs_pma_gtrefclk_bufg_out [get_bd_ports gtref_clk_buf_out] [get_bd_pins pcs_pma/gtrefclk_bufg_out] // connect_bd_net -net pcs_pma_gtrefclk_out [get_bd_ports gtref_clk_out] [get_bd_pins pcs_pma/gtrefclk_out] // connect_bd_net -net pcs_pma_mmcm_locked_out [get_bd_ports mmcm_locked_out] [get_bd_pins pcs_pma/mmcm_locked_out] // connect_bd_net -net pcs_pma_pma_reset_out [get_bd_ports pma_reset_out] [get_bd_pins pcs_pma/pma_reset_out] // connect_bd_net -net pcs_pma_rxuserclk2_out [get_bd_ports rxuserclk2_out] [get_bd_pins pcs_pma/rxuserclk2_out] // connect_bd_net -net pcs_pma_rxuserclk_out [get_bd_ports rxuserclk_out] [get_bd_pins pcs_pma/rxuserclk_out] // connect_bd_net -net pcs_pma_status_vector [get_bd_ports status_vector] [get_bd_pins pcs_pma/status_vector] // connect_bd_net -net pcs_pma_userclk2_out [get_bd_ports userclk2_out] [get_bd_pins eth_mac/gtx_clk] [get_bd_pins pcs_pma/userclk2_out] // connect_bd_net -net pcs_pma_userclk_out [get_bd_ports userclk_out] [get_bd_pins pcs_pma/userclk_out] // connect_bd_net -net ref_clk_1 [get_bd_ports ref_clk] [get_bd_pins pcs_pma/independent_clock_bufg] // connect_bd_intf_net -intf_net eth_mac_m_axis_rx [get_bd_intf_ports m_axis_rx] [get_bd_intf_pins eth_mac/m_axis_rx] // connect_bd_net -net s_axi_lite_clk_1 [get_bd_ports s_axi_lite_clk] [get_bd_pins eth_mac/s_axi_aclk] // connect_bd_net -net s_axi_lite_resetn_1 [get_bd_ports s_axi_lite_resetn] [get_bd_pins eth_mac/s_axi_resetn] // connect_bd_net -net signal_detect_1 [get_bd_ports signal_detect] [get_bd_pins pcs_pma/signal_detect] // connect_bd_net -net tx_ifg_delay_1 [get_bd_ports tx_ifg_delay] [get_bd_pins eth_mac/tx_ifg_delay] let axiDmaBvi <- mkAxiDmaBvi(clock,clock,clock,clock,reset); // packet data and status from the ethernet let rxResetInverted <- mkResetInverter(trimodemac.rx.reset, clocked_by trimodemac.rx.mac_aclk); let rxCnx <- mkStreamStatusConnection(trimodemac.rx_axis_mac, axiDmaBvi.s_axis_s2mm, axiDmaBvi.s_axis_s2mm_sts, trimodemac.rx.mac_aclk, rxResetInverted, clock, reset); //mkConnection(axiEthBvi.m_axis_rxs, axiDmaBvi.s_axis_s2mm_sts); // packet data and control to the ethernet let txResetInverted <- mkResetInverter(trimodemac.tx.reset, clocked_by trimodemac.tx.mac_aclk); let txCnx <- mkStreamControlConnection(axiDmaBvi.m_axis_mm2s, axiDmaBvi.m_axis_mm2s_cntrl, trimodemac.tx_axis_mac, clock, reset, trimodemac.tx.mac_aclk, txResetInverted); //mkConnection(axiDmaBvi.m_axis_mm2s_cntrl, axiEthBvi.s_axis_txc); interface mm2s_dma = axiDmaBvi.mm2s; interface s2mm_dma = axiDmaBvi.s2mm; interface m_axi_mm2s = axiDmaBvi.m_axi_mm2s; interface m_axi_s2mm = axiDmaBvi.m_axi_s2mm; interface m_axi_sg = axiDmaBvi.m_axi_sg; interface s_axi_dma = axiDmaBvi.s_axi_lite; interface s_axi_mac = trimodemac.s_axi; interface mac = trimodemac.mac; interface signal = pcs.signal; interface mmcm = pcs.mmcm; interface AxiethbviMgt mgt; method clk_clk_p = pcs.gtrefclk.p; method clk_clk_n = pcs.gtrefclk.n; endinterface interface AxiethbviSfp sfp; method txp = pcs.txp; method txn = pcs.txn; method rxp = pcs.rxp; method rxn = pcs.rxn; endinterface endmodule ================================================ FILE: tests/spikehw/AxiIic.bsv ================================================ /* /home/jamey/connectal.clean/generated/scripts/importbvi.py -P AxiIic -I AxiIic -c s_axi_aclk -r s_axi_aresetn -n iic2intc_irpt -o AxiIic.bsv cores/vc709/axi_iic_0/axi_iic_0_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import Vector::*; (* always_ready, always_enabled *) interface AxiiicS_axi; method Action araddr(Bit#(9) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(9) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AxiiicScl; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface AxiiicSda; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface AxiIic; method Bit#(8) gpo(); method Bit#(1) iic2intc_irpt(); interface AxiiicS_axi s_axi; interface AxiiicScl scl; interface AxiiicSda sda; endinterface import "BVI" axi_iic_0 = module mkAxiIicBvi#(Clock s_axi_aclk, Reset s_axi_aresetn)(AxiIic); default_clock clk(); default_reset rst(); input_clock s_axi_aclk(s_axi_aclk) = s_axi_aclk; input_reset s_axi_aresetn(s_axi_aresetn) = s_axi_aresetn; method gpo gpo(); method iic2intc_irpt iic2intc_irpt(); interface AxiiicS_axi s_axi; method araddr(s_axi_araddr) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_araddr); method s_axi_arready arready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method arvalid(s_axi_arvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_arvalid); method awaddr(s_axi_awaddr) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_awaddr); method s_axi_awready awready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method awvalid(s_axi_awvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_awvalid); method bready(s_axi_bready) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_bready); method s_axi_bresp bresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_bvalid bvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_rdata rdata() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method rready(s_axi_rready) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_rready); method s_axi_rresp rresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_rvalid rvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wdata(s_axi_wdata) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wdata); method s_axi_wready wready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wstrb(s_axi_wstrb) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wstrb); method wvalid(s_axi_wvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wvalid); endinterface interface AxiiicScl scl; method i(scl_i) enable((*inhigh*) EN_scl_i); method scl_o o(); method scl_t t(); endinterface interface AxiiicSda sda; method i(sda_i) enable((*inhigh*) EN_sda_i); method sda_o o(); method sda_t t(); endinterface schedule (gpo, iic2intc_irpt, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, scl.i, scl.o, scl.t, sda.i, sda.o, sda.t) CF (gpo, iic2intc_irpt, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, scl.i, scl.o, scl.t, sda.i, sda.o, sda.t); endmodule instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(9,32), AxiiicS_axi); function Axi4SlaveLiteBits#(9,32) toAxi4SlaveBits(AxiiicS_axi s); return (interface Axi4SlaveLiteBits#(9,32); method araddr = s.araddr; method arready = s.arready; method arvalid = s.arvalid; method awaddr = s.awaddr; method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance ================================================ FILE: tests/spikehw/AxiSpiBvi.bsv ================================================ /* ../../generated/scripts/importbvi.py -I AxiSpiBvi -P AxiSpi -c ext_spi_clk -c s_axi_aclk -r s_axi_aresetn -n ip2intc_irpt -o AxiSpiBvi.bsv cores/nfsume/axi_spi_0/axi_spi_0_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import Vector::*; import AxiBits::*; (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface AxispiIo; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface AxispiS_axi; method Action araddr(Bit#(7) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(7) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AxispiSck; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface AxispiSs; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface AxiSpiBvi; interface AxispiIo io0; interface AxispiIo io1; method Bit#(1) ip2intc_irpt(); interface AxispiS_axi s_axi; interface AxispiSck sck; interface AxispiSs ss; endinterface import "BVI" axi_spi_0 = module mkAxiSpiBvi#(Clock ext_spi_clk, Clock s_axi_aclk, Reset s_axi_aresetn)(AxiSpiBvi); default_clock clk(); default_reset rst(); input_clock ext_spi_clk(ext_spi_clk) = ext_spi_clk; input_clock s_axi_aclk(s_axi_aclk) = s_axi_aclk; input_reset s_axi_aresetn(s_axi_aresetn) = s_axi_aresetn; interface AxispiIo io0; method i(io0_i) enable((*inhigh*) EN_io0_i); method io0_o o(); method io0_t t(); endinterface interface AxispiIo io1; method i(io1_i) enable((*inhigh*) EN_io1_i); method io1_o o(); method io1_t t(); endinterface method ip2intc_irpt ip2intc_irpt(); interface AxispiS_axi s_axi; method araddr(s_axi_araddr) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_araddr); method s_axi_arready arready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method arvalid(s_axi_arvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_arvalid); method awaddr(s_axi_awaddr) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_awaddr); method s_axi_awready awready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method awvalid(s_axi_awvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_awvalid); method bready(s_axi_bready) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_bready); method s_axi_bresp bresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_bvalid bvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_rdata rdata() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method rready(s_axi_rready) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_rready); method s_axi_rresp rresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_rvalid rvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wdata(s_axi_wdata) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wdata); method s_axi_wready wready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wstrb(s_axi_wstrb) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wstrb); method wvalid(s_axi_wvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wvalid); endinterface interface AxispiSck sck; method i(sck_i) enable((*inhigh*) EN_sck_i); method sck_o o(); method sck_t t(); endinterface interface AxispiSs ss; method i(ss_i) enable((*inhigh*) EN_ss_i); method ss_o o(); method ss_t t(); endinterface schedule (io0.i, io0.o, io0.t, io1.i, io1.o, io1.t, ip2intc_irpt, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, sck.i, sck.o, sck.t, ss.i, ss.o, ss.t) CF (io0.i, io0.o, io0.t, io1.i, io1.o, io1.t, ip2intc_irpt, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, sck.i, sck.o, sck.t, ss.i, ss.o, ss.t); endmodule instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(7,32), AxispiS_axi); function Axi4SlaveLiteBits#(7,32) toAxi4SlaveBits(AxispiS_axi s); return (interface Axi4SlaveLiteBits#(7,32); method araddr = s.araddr; method arready = s.arready; method arvalid = s.arvalid; method awaddr = s.awaddr; method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance ================================================ FILE: tests/spikehw/AxiUart.bsv ================================================ /* /home/jamey/connectal.clean/generated/scripts/importbvi.py -P AxiUart -I AxiUart -c s_axi_aclk -r s_axi_aresetn -n ip2intc_irpt -n out1n -n out2n -o AxiUart.bsv cores/vc709/axi_uart16550_1/axi_uart16550_1_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import Vector::*; (* always_ready, always_enabled *) interface AxiuartS_axi; method Action araddr(Bit#(13) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(13) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wstrb(Bit#(4) v); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface AxiUart; method Bit#(1) baudoutn(); method Action ctsn(Bit#(1) v); method Action dcdn(Bit#(1) v); method Bit#(1) ddis(); method Action dsrn(Bit#(1) v); method Bit#(1) dtrn(); method Action freeze(Bit#(1) v); method Bit#(1) ip2intc_irpt(); method Bit#(1) out1n(); method Bit#(1) out2n(); method Action rin(Bit#(1) v); method Bit#(1) rtsn(); method Bit#(1) rxrdyn(); interface AxiuartS_axi s_axi; method Action sin(Bit#(1) v); method Bit#(1) sout(); method Bit#(1) txrdyn(); method Bit#(1) xout(); endinterface import "BVI" axi_uart16550_1 = module mkAxiUartBvi#(Clock s_axi_aclk, Reset s_axi_aresetn, Clock uartClk)(AxiUart); default_clock clk(); default_reset rst(); input_clock s_axi_aclk(s_axi_aclk) = s_axi_aclk; input_reset s_axi_aresetn(s_axi_aresetn) = s_axi_aresetn; input_clock xin(xin) = uartClk; method baudoutn baudoutn(); method ctsn(ctsn) enable((*inhigh*) EN_ctsn); method dcdn(dcdn) enable((*inhigh*) EN_dcdn); method ddis ddis(); method dsrn(dsrn) enable((*inhigh*) EN_dsrn); method dtrn dtrn(); method freeze(freeze) enable((*inhigh*) EN_freeze); method ip2intc_irpt ip2intc_irpt(); method out1n out1n(); method out2n out2n(); method rin(rin) enable((*inhigh*) EN_rin); method rtsn rtsn(); method rxrdyn rxrdyn(); interface AxiuartS_axi s_axi; method araddr(s_axi_araddr) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_araddr); method s_axi_arready arready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method arvalid(s_axi_arvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_arvalid); method awaddr(s_axi_awaddr) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_awaddr); method s_axi_awready awready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method awvalid(s_axi_awvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_awvalid); method bready(s_axi_bready) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_bready); method s_axi_bresp bresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_bvalid bvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_rdata rdata() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method rready(s_axi_rready) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_rready); method s_axi_rresp rresp() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method s_axi_rvalid rvalid() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wdata(s_axi_wdata) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wdata); method s_axi_wready wready() clocked_by (s_axi_aclk) reset_by (s_axi_aresetn); method wstrb(s_axi_wstrb) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wstrb); method wvalid(s_axi_wvalid) clocked_by (s_axi_aclk) reset_by (s_axi_aresetn) enable((*inhigh*) EN_s_axi_wvalid); endinterface method sin(sin) enable((*inhigh*) EN_sin); method sout sout(); method txrdyn txrdyn(); method xout xout(); schedule (baudoutn, ctsn, dcdn, ddis, dsrn, dtrn, freeze, ip2intc_irpt, out1n, out2n, rin, rtsn, rxrdyn, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, sin, sout, txrdyn, xout) CF (baudoutn, ctsn, dcdn, ddis, dsrn, dtrn, freeze, ip2intc_irpt, out1n, out2n, rin, rtsn, rxrdyn, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, sin, sout, txrdyn, xout); endmodule instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(12,32), AxiuartS_axi); function Axi4SlaveLiteBits#(12,32) toAxi4SlaveBits(AxiuartS_axi s); return (interface Axi4SlaveLiteBits#(12,32); method Action araddr(Bit#(12) addr); s.araddr(extend(addr)); endmethod method arready = s.arready; method arvalid = s.arvalid; method Action awaddr(Bit#(12) addr); s.awaddr(extend(addr)); endmethod method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance ================================================ FILE: tests/spikehw/GigEthPcsPmaBvi.bsv ================================================ /* /home/jamey/connectal.clean/generated/scripts/importbvi.py -o GigEthPcsPma.bsv -P GigEthPcsPmaBvi -I GigEthPcsPmaBvi -c gtrefclk_out -c userclk_out -c userclk2_out -c rxuserclk_out -c rxuserclk2_out -c independent_clock_bufg -r pma_reset_out -r reset -c gt0_qplloutclk_out -c gt0_qplloutrefclk_out ../FPGA/rtl/vc709/gig_ethernet_pcs_pma_0/gig_ethernet_pcs_pma_0_stub.v */ import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; (* always_ready, always_enabled *) interface GigethpcspmabviAn; method Action adv_config_val(Bit#(1) v); method Action adv_config_vector(Bit#(16) v); method Bit#(1) interrupt(); method Action restart_config(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviConfiguration; method Action valid(Bit#(1) v); method Action vector(Bit#(5) v); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviGmii; method Bit#(1) isolate(); method Bit#(1) rx_dv(); method Bit#(1) rx_er(); method Bit#(8) rxd(); method Action tx_en(Bit#(1) v); method Action tx_er(Bit#(1) v); method Action txd(Bit#(8) v); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviGt; interface Clock qplloutclk_out; interface Clock qplloutrefclk_out; endinterface (* always_ready, always_enabled *) interface GigethpcspmabviGtrefclk; method Action n(Bit#(1) v); interface Clock out; method Action p(Bit#(1) v); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface GigethpcspmabviMdio; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviMmcm; method Bit#(1) locked_out(); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviPma; method Reset reset_out(); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviRxuserclk; interface Clock out; endinterface (* always_ready, always_enabled *) interface GigethpcspmabviSignal; method Action detect(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviStatus; method Bit#(16) vector(); endinterface (* always_ready, always_enabled *) interface GigethpcspmabviUserclk; interface Clock out; endinterface (* always_ready, always_enabled *) interface GigEthPcsPmaBvi; interface GigethpcspmabviAn an; interface GigethpcspmabviConfiguration configuration; interface GigethpcspmabviGmii gmii; interface GigethpcspmabviGt gt0; interface GigethpcspmabviGtrefclk gtrefclk; method Action mdc(Bit#(1) v); interface GigethpcspmabviMdio mdio; interface GigethpcspmabviMmcm mmcm; interface GigethpcspmabviPma pma; method Bit#(1) resetdone(); method Action rxn(Bit#(1) v); method Action rxp(Bit#(1) v); interface GigethpcspmabviRxuserclk rxuserclk2; interface GigethpcspmabviRxuserclk rxuserclk; interface GigethpcspmabviSignal signal; interface GigethpcspmabviStatus status; method Bit#(1) txn(); method Bit#(1) txp(); interface GigethpcspmabviUserclk userclk2; interface GigethpcspmabviUserclk userclk; endinterface import "BVI" gig_ethernet_pcs_pma_0 = module mkGigEthPcsPmaBvi#(Clock independent_clock_bufg, Reset reset_n)(GigEthPcsPmaBvi); let invertedReset <- mkResetInverter(reset_n, clocked_by independent_clock_bufg); default_clock clk(); default_reset rst_n(); input_clock independent_clock_bufg(independent_clock_bufg) = independent_clock_bufg; input_reset reset(reset) clocked_by (independent_clock_bufg) = invertedReset; interface GigethpcspmabviAn an; method adv_config_val(an_adv_config_val) enable((*inhigh*) EN_an_adv_config_val); method adv_config_vector(an_adv_config_vector) enable((*inhigh*) EN_an_adv_config_vector); method an_interrupt interrupt(); method restart_config(an_restart_config) enable((*inhigh*) EN_an_restart_config); endinterface interface GigethpcspmabviConfiguration configuration; method valid(configuration_valid) enable((*inhigh*) EN_configuration_valid); method vector(configuration_vector) enable((*inhigh*) EN_configuration_vector); endinterface interface GigethpcspmabviGmii gmii; method gmii_isolate isolate(); method gmii_rx_dv rx_dv(); method gmii_rx_er rx_er(); method gmii_rxd rxd(); method tx_en(gmii_tx_en) enable((*inhigh*) EN_gmii_tx_en); method tx_er(gmii_tx_er) enable((*inhigh*) EN_gmii_tx_er); method txd(gmii_txd) enable((*inhigh*) EN_gmii_txd); endinterface interface GigethpcspmabviGt gt0; output_clock qplloutclk_out(gt0_qplloutclk_out); output_clock qplloutrefclk_out(gt0_qplloutrefclk_out); endinterface interface GigethpcspmabviGtrefclk gtrefclk; method n(gtrefclk_n) enable((*inhigh*) EN_gtrefclk_n); output_clock out(gtrefclk_out); method p(gtrefclk_p) enable((*inhigh*) EN_gtrefclk_p); endinterface method mdc(mdc) enable((*inhigh*) EN_mdc); interface GigethpcspmabviMdio mdio; method i(mdio_i) enable((*inhigh*) EN_mdio_i); method mdio_o o(); method mdio_t t(); endinterface interface GigethpcspmabviMmcm mmcm; method mmcm_locked_out locked_out(); endinterface interface GigethpcspmabviPma pma; output_reset reset_out(pma_reset_out); endinterface method resetdone resetdone(); method rxn(rxn) enable((*inhigh*) EN_rxn); method rxp(rxp) enable((*inhigh*) EN_rxp); interface GigethpcspmabviRxuserclk rxuserclk2; output_clock out(rxuserclk2_out); endinterface interface GigethpcspmabviRxuserclk rxuserclk; output_clock out(rxuserclk_out); endinterface interface GigethpcspmabviSignal signal; method detect(signal_detect) enable((*inhigh*) EN_signal_detect); endinterface interface GigethpcspmabviStatus status; method status_vector vector(); endinterface method txn txn(); method txp txp(); interface GigethpcspmabviUserclk userclk2; output_clock out(userclk2_out); endinterface interface GigethpcspmabviUserclk userclk; output_clock out(userclk_out); endinterface schedule (an.adv_config_val, an.adv_config_vector, an.interrupt, an.restart_config, configuration.valid, configuration.vector, gmii.isolate, gmii.rx_dv, gmii.rx_er, gmii.rxd, gmii.tx_en, gmii.tx_er, gmii.txd, gtrefclk.n, gtrefclk.p, mdc, mdio.i, mdio.o, mdio.t, mmcm.locked_out, resetdone, rxn, rxp, signal.detect, status.vector, txn, txp) CF (an.adv_config_val, an.adv_config_vector, an.interrupt, an.restart_config, configuration.valid, configuration.vector, gmii.isolate, gmii.rx_dv, gmii.rx_er, gmii.rxd, gmii.tx_en, gmii.tx_er, gmii.txd, gtrefclk.n, gtrefclk.p, mdc, mdio.i, mdio.o, mdio.t, mmcm.locked_out, resetdone, rxn, rxp, signal.detect, status.vector, txn, txp); endmodule (* always_ready, always_enabled *) interface GigEthPcsPmaPins; method Action rxn(Bit#(1) v); method Action rxp(Bit#(1) v); method Bit#(1) txn(); method Bit#(1) txp(); method Action gtrefclkp(Bit#(1) v); method Action gtrefclkn(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface GigEthPcsPmaTxPins; method Bit#(1) txn(); method Bit#(1) txp(); endinterface interface GigEthPcsPmaDebug; method Bit#(1) locked_out(); method Bit#(16) status(); method Bit#(1) resetdone(); endinterface interface GigEthPcsPma; method Action mdc(Bit#(1) v); interface GigethpcspmabviMdio mdio; interface GigethpcspmabviGmii gmii; interface GigEthPcsPmaPins pins; interface GigEthPcsPmaDebug debug; interface Clock gtrefclk; method Bit#(1) interrupt(); endinterface module mkGigEthPcsPma#(Clock independent_clock_bufg, Reset reset)(GigEthPcsPma); GigEthPcsPmaBvi bvi <- mkGigEthPcsPmaBvi(independent_clock_bufg, reset); rule rl_detect; bvi.signal.detect(1); endrule method mdc = bvi.mdc; interface mdio = bvi.mdio; interface gmii = bvi.gmii; interface gtrefclk = bvi.gtrefclk.out; interface GigEthPcsPmaPins pins; method rxn = bvi.rxn; method rxp = bvi.rxp; method txn = bvi.txn; method txp = bvi.txp; method gtrefclkp = bvi.gtrefclk.p; method gtrefclkn = bvi.gtrefclk.n; endinterface method interrupt = bvi.an.interrupt; interface GigEthPcsPmaDebug debug; method locked_out = bvi.mmcm.locked_out; method status = bvi.status.vector(); method resetdone = bvi.resetdone; endinterface endmodule ================================================ FILE: tests/spikehw/Makefile ================================================ INCLUDE_ETHERNET=1 SPIKE_DIR=/home/jamey/riscv-isa-sim CONNECTALDIR?=../.. S2H_INTERFACES = SpikeHwRequest:SpikeHw.request H2S_INTERFACES = SpikeHw:SpikeHwIndication:host MEM_READ_INTERFACES = lSpikeHw.dmaReadClient MEM_WRITE_INTERFACES = lSpikeHw.dmaWriteClient CONNECTALFLAGS+= -P mkConnectalTop CONNECTALFLAGS += --derivedclockperiod=67.81684027 RISCV_INCLUDES = -I$(SPIKE_DIR) -I$(SPIKE_DIR)/build CONNECTALFLAGS += $(RISCV_INCLUDES) --cxxflags=-std=c++11 BSVFILES = $(CONNECTALDIR)/bsv/MemTypes.bsv $(CONNECTALDIR)/bsv/ConnectalConfig.bsv SpikeHwIfc.bsv CPPFILES= spikehw.cpp ifeq ($(BOARD),miniitx100) CPPFILES += test-spikehw.cpp else CONNECTALFLAGS+= --shared endif # ifneq ($(BOARD),vc709) # CONNECTALFLAGS+= --verilog=i28f512p33.v # endif ifneq ($(BOARD),xsim) ifeq ($(BOARD),nfsume) PINOUT_FILE += nfsume.json else PINOUT_FILE += spikehw.json #PINOUT_FILE += rtscts.json #PINOUT_FILE += eth.json PINOUT_FILE += spikehw-$(BOARD).json ifneq ($(BOARD),miniitx100) PINOUT_FILE += i2c-standard.json endif # not minitx100 endif # not nfsume endif # not xsim ifeq ($(BOARD),vc707g2) CONNECTALFLAGS += -D IncludeFlash endif PIN_TYPE = SpikeHwPins PIN_TYPE_INCLUDE = SpikeHwPins AUTOTOP = --interface pins:SpikeHw.pins CONNECTALFLAGS+= -DDataBusWidth=32 ## ethernet uses the 200MHz SYS clock CONNECTALFLAGS += -D XILINX_SYS_CLK -D IMPORT_HOSTIF IPDIR=cores CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_intc_0/axi_intc_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_iic_0/axi_iic_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_spi_0/axi_spi_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_uart16550_1/axi_uart16550_1.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_dma_0/axi_dma_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/dual_clock_axis_fifo_32x1024/dual_clock_axis_fifo_32x1024.xci CONNECTALFLAGS += --constraint=spikehw.xdc --implconstraint=spikehw.xdc ##PREBUILD_DEPS = $(IPDIR)/$(BOARD)/axi_dma_0/axi_dma_0.xci $(IPDIR)/$(BOARD)/axi_intc_0/axi_intc_0.xci ifeq ($(INCLUDE_ETHERNET),1) #CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/axi_ethernet_1000basex/axi_ethernet_1000basex.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/tri_mode_ethernet_mac_0/tri_mode_ethernet_mac_0.xci CONNECTALFLAGS+= --xci=$(IPDIR)/$(BOARD)/gig_ethernet_pcs_pma_0/gig_ethernet_pcs_pma_0.xci CONNECTALFLAGS+= -D IncludeEthernet ##PREBUILD_DEPS += $(IPDIR)/$(BOARD)/axi_ethernet_0/axi_ethernet_0.xci endif prebuild:: $(PREBUILD_DEPS) ln -sf $(PWD)/bootromx4.hex $(BOARD) $(IPDIR)/$(BOARD)/axi_intc_0/axi_intc_0.xci: ../../scripts/connectal-synth-axidma.tcl cd $(BOARD); vivado -mode batch -source $(CONNECTALDIR)/scripts/connectal-synth-axiintc.tcl $(IPDIR)/$(BOARD)/axi_ethernet_0/axi_ethernet_0.xci: ../../scripts/connectal-synth-axieth.tcl cd $(BOARD); vivado -mode batch -source $(CONNECTALDIR)/scripts/connectal-synth-axieth.tcl $(IPDIR)/$(BOARD)/axi_dma_0/axi_dma_0.xci: ../../scripts/connectal-synth-axidma.tcl cd $(BOARD); vivado -mode batch -source $(CONNECTALDIR)/scripts/connectal-synth-axidma.tcl test-spikehw.o: test-spikehw.cpp spikehw.h g++ $(RISCV_INCLUDES) -std=c++11 -g -O -pthread -c -I. test-spikehw.cpp test-spikehw.%: test-spikehw.o #$(MAKE) build.$(*) g++ $(RISCV_INCLUDES) -g -O -pthread -o test-spikehw.$(*) test-spikehw.o $(*)/bin/connectal.so -lc include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/spikehw/README.md ================================================ Spike Hardware ============== This project provides hardware peripherals to spike, the RISC-V ISA simulator. TODO ---- * device tree partitioning of flash * added to riscv_spikehw_defconfig (DONE) * device tree entry for flash works (DONE) * device tree entry for partitions works (registers) * vmlinux partition (DONE) * root partition (DONE) * spikehw registering a flash device with spike (DONE) * restore console input (wtf) * copy vmlinux to flash (via /etc/init.d/rc) (DONE?) * pass address of vmlinux in flash to bbl (in riscy version of riscv-pk) * boot vmlinux from flash to login prompt (DONE) (AGAIN) * copy root fs image to flash (DONE) (AGAIN) * boot linux to command prompt using flash root filesystem (DONE) * change /etc/default/rcS ROOTFS_READ_ONLY=yes (DONE) * boot linux to command prompt using flash for vmlinux and root filesystem (almost done) * modify spike to use portalmem for dram so DMA from FPGA works (via register_mem_allocator) (DONE) * modify spike so devices can raise interrupts (IMPLEMENTED) * enable boot loader to pass command line to linux * modify spike to boot from boot ROM if no executable passed as an argument * copy bbl from boot ROM to DRAM (see code in tests/spikehw/boot/ ) * fix ioremap() so that all 128MB of flash can be mapped * switch to coreboot instead of bbl * ... Building SpikeHW ---------------- To get the sources: git clone git://github.com/cambridgehackers/fpgamake git clone git://github.com/cambridgehackers/buildcache git clone git://github.com/cambridgehackers/connectal I extended spike to enable devices to be registered from extlib's. git clone git://github.com/cambridgehackers/cambridgehackers/riscv-isa-sim cd connectal/tests/spikehw make build.vc707g2 test-spikehw.vc707g2 To test it, assuming connectal is installed: cd connectal/tests/spikehw ./test-spikehw.vc707g2 You should see output like the following: jamey@bdbm07:~/connectal/tests/spikehw$ ./test-spikehw.vc707g2 buffer /home/jamey/connectal/tests/spikehw/vc707g2/bin/connectal.so fpgajtag: elf input file, len 1459190 class 2 fpgajtag: unzip input file, len 1040655 fpgajtag: Digilent:Digilent Adept USB Device:210203860922; bcd:700 count 2/3 cortex -1 dcount 2 trail 0 STATUS 00500018 done 0 release_done 0 eos 10 startup_state 4 STATUS 00500018 done 0 release_done 0 eos 10 startup_state 4 STATUS 0002107a done 0 release_done 0 eos 10 startup_state 0 fpgajtag: Starting to send file fpgajtag: Done sending file fpgajtag: bypass already programmed ae STATUS 0002107a done 0 release_done 0 eos 10 startup_state 0 Running /usr/bin/pciescan.sh + PATH=/home/jamey/work/build/tools/bin:/home/jamey/work/vendor/android-ndk-r10e:/home/jamey/work/build/tools/bin:/home/jamey/work/vendor/android-ndk-r10e:/home/jamey/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/scratch/Xilinx/Vivado/2015.4/bin:/scratch/bluespec/Bluespec-2015.05.beta1/bin:/scratch/android-ndk-r10e:/home/jamey/bin:/sbin ++ lspci -d 1be7:c100 ++ sed -e 's/ .*//' + BLUEDEVICE=03:00.0 + '[' 03:00.0 '!=' '' ']' + sh -c 'echo 1 >/sys/bus/pci/devices/0000:03:00.0/remove' + sleep 1 + rmmod pcieportal + sleep 1 + sh -c 'echo 1 >/sys/bus/pci/rescan' + sleep 1 subprocess pid 16080 completed status=0 0 [initPortalHardwareOnce:256] fd 6 len 0 [checkSignature:154] read status from '/dev/connectal' was only 0 bytes long [dmaManagerOnce:44] axi eth status mmcm_locked=1 irq=0 intr sources=0 word 0000 of boot ROM 00001137 (expected 00001137) word 0004 of boot ROM 010000ef (expected 010000ef) word 0008 of boot ROM 20000513 (expected 20000513) word 000c of boot ROM 00050067 (expected 00050067) word 0010 of boot ROM 0000006f (expected 0000006f) word 0014 of boot ROM 040007b7 (expected 040007b7) word 0018 of boot ROM 40078793 (expected 40078793) word 001c of boot ROM fc0005b7 (expected fc0005b7) AXI Ethernet Identification 09000000 (expected 09000000) SpikeHw::writeFlash offset=55 value=98 Query flash 51.52.59 QRY (expected QRY) The last five lines are the actual test output. If the first word of the boot ROM is 0, then it is because bootromx4.hex is missing. Linux Kernel ------------ The corresponding RISC-V Linux kernel is available here: git clone git://github.com/cambridgehackers/cambridgehackers/riscv-linux-4.1.y linux cd linux ## configure the kernel make ARCH=riscv riscv64_spikehw_defconfig ## build the kernel make ARCH=riscv ## build the device tree .dtb files make ARCH=riscv dtbs BBL (in riscv-pk) ----------------- I modified BBL to load an ELF file from physical memory (DRAM, boot ROM, or NOR FLASH) when passed an address instead of a filename. git clone git://github.com/cambridgehackers/cambridgehackers/riscv-pk Using Spike HW with Spike ------------------------- Spike updated with register_device() available to extlibs: git clone git://github.com/cambridgehackers/cambridgehackers/riscv-isa-sim See also the pull request: https://github.com/riscv/riscv-isa-sim/pull/37 To connect spikehw to the hardware: spike -extlib=/path/to/vc707g2/bin/connectal.so -m64 ... ================================================ FILE: tests/spikehw/SpikeHw.bsv ================================================ import BuildVector::*; import Clocks::*; import Connectable::*; import GetPut::*; import FIFOF::*; import BRAM::*; import BRAMFIFO::*; import Probe::*; import StmtFSM::*; import TriState::*; import Vector::*; import XilinxCells::*; import Probe::*; import ConnectalXilinxCells::*; import ConnectalBramFifo::*; import ConnectalConfig::*; import GetPutWithClocks::*; import CtrlMux::*; import HostInterface::*; import ConnectalMemTypes::*; import Pipe::*; import AxiBits::*; import PhysMemSlaveFromBram::*; import TraceMemClient::*; import BpiFlash::*; import AxiIntcBvi::*; import AxiIic::*; import AxiSpiBvi::*; import AxiUart::*; `ifdef EthernetSgmii import AxiEthBvi::*; `else //import AxiEth1000BaseX::*; import AxiEthSubsystem::*; import TriModeMacBvi::*; import GigEthPcsPmaBvi::*; import AxiEthBufferBvi::*; import AxiEth1000BaseX::*; // for interfaces `endif import AxiDmaBvi::*; import SpikeHwPins::*; import SpikeHwIfc::*; `include "ConnectalProjectConfig.bsv" interface SpikeHw; interface SpikeHwRequest request; interface Vector#(2, MemReadClient#(DataBusWidth)) dmaReadClient; interface Vector#(2, MemWriteClient#(DataBusWidth)) dmaWriteClient; interface SpikeHwPins pins; endinterface typedef 65536 BootRomBytes; typedef TDiv#(BootRomBytes,4) BootRomEntries; module mkBramBootRom(Server#(BRAMRequest#(Bit#(TLog#(BootRomEntries)),Bit#(32)),Bit#(32))); BRAM_Configure cfg = defaultValue; cfg.memorySize = valueOf(BootRomEntries); // 128KB (32K x 4bytes) cfg.latency = 2; cfg.loadFormat = tagged Hex "bootromx4.hex"; BRAM1Port#(Bit#(TLog#(BootRomEntries)), Bit#(32)) bram <- mkBRAM1Server(cfg); return bram.portA; endmodule module mkSpikeHw#(HostInterface host, SpikeHwIndication ind)(SpikeHw); let clock <- exposeCurrentClock(); let reset <- exposeCurrentReset(); let newReset <- mkReset(10, True, clock); BUFRParams bufrParams = defaultValue; `ifndef BOARD_miniitx100 bufrParams.bufr_divide = "2"; Clock clk_125mhz <- mkClockBUFR(bufrParams, clocked_by clock); `endif bufrParams.bufr_divide = "4"; Clock uartClk <- mkClockBUFR(bufrParams, clocked_by host.derivedClock); let bootRom <- mkBramBootRom(); `ifdef IncludeFlash let bpiFlash <- mkBpiFlash(); `endif let axiIntcBvi <- mkAxiIntcBvi(clock, newReset.new_rst); let axiIicBvi <- mkAxiIicBvi(clock, newReset.new_rst); // let axiSpiBvi <- mkAxiSpiBvi(clock, clock, newReset.new_rst); let axiUartBvi <- mkAxiUartBvi(clock, newReset.new_rst, uartClk); `ifdef IncludeEthernet // let axiEthBvi <- mkAxiEthBvi(clock, host.tsys_clk_200mhz_buf, clock, // newReset.new_rst, newReset.new_rst, newReset.new_rst, newReset.new_rst, newReset.new_rst); let axiEthBvi <- AxiEthSubsystem::mkAxiEthBvi(clock, host.tsys_clk_200mhz_buf, reset_by newReset.new_rst); `endif Reg#(Bit#(32)) objId <- mkReg(0); Reg#(Bit#(1)) iicResetReg <- mkReg(0); Reg#(Bit#(1)) eth_los <- mkReg(0); let irqLevel <- mkReg(0); let intrLevel <- mkReg(0); function Bit#(16) intr(); Bit#(16) _intr = 0; _intr[0] = axiUartBvi.ip2intc_irpt(); _intr[1] = axiEthBvi.s2mm_dma.introut(); // rx _intr[2] = axiEthBvi.mm2s_dma.introut(); // tx `ifdef IncludeEthernet _intr[3] = axiEthBvi.mac.irq(); // _intr[4] = axiEthBvi.interrupt(); `endif _intr[5] = axiIicBvi.iic2intc_irpt(); // _intr[6] = axiSpiBvi.ip2intc_irpt(); return _intr; endfunction rule rl_intr; axiIntcBvi.intr(intr()); endrule FIFOF#(Tuple2#(Bit#(1),Bit#(16))) irqChangeFifo <- mkSizedFIFOF(8); rule rl_irq_levels_changed; let irq = axiIntcBvi.irq; let levels = intr(); if (irq != irqLevel) begin $display("irq changed irq=%h intr sources %h", irq, levels); irqLevel <= irq; intrLevel <= levels; irqChangeFifo.enq(tuple2(irq, levels)); end endrule rule rl_intr_indication; match { .irq, .levels } <- toGet(irqChangeFifo).get(); ind.irqChanged(irq, levels); endrule Reg#(Bit#(32)) cycles <- mkReg(0); Reg#(Bool) mmcm_lock <- mkReg(False); rule rl_cycles; cycles <= cycles+1; endrule FIFOF#(BRAMRequest#(Bit#(32),Bit#(32))) reqFifo <- mkSizedFIFOF(4); FIFOF#(Bit#(32)) dataFifo <- mkSizedFIFOF(16); Axi4MasterBits#(32,DataBusWidth,MemTagSize,Empty) m_axi_mm2s = toAxi4MasterBits(axiEthBvi.m_axi_mm2s); Axi4MasterBits#(32,DataBusWidth,MemTagSize,Empty) m_axi_s2mm = toAxi4MasterBits(axiEthBvi.m_axi_s2mm); Axi4MasterBits#(32,DataBusWidth,MemTagSize,Empty) m_axi_sg = toAxi4MasterBits(axiEthBvi.m_axi_sg); Axi4SlaveLiteBits#(12,32) axiUartSlaveLite = toAxi4SlaveBits(axiUartBvi.s_axi); PhysMemSlave#(12,32) axiUartMemSlave <- mkPhysMemSlave(axiUartSlaveLite); Axi4SlaveLiteBits#(9,32) axiIntcSlaveLite = toAxi4SlaveBits(axiIntcBvi.s_axi); PhysMemSlave#(12,32) axiIntcMemSlave <- mkPhysMemSlave(axiIntcSlaveLite); Axi4SlaveLiteBits#(9,32) axiIicSlaveLite = toAxi4SlaveBits(axiIicBvi.s_axi); PhysMemSlave#(12,32) axiIicMemSlave <- mkPhysMemSlave(axiIicSlaveLite); // Axi4SlaveLiteBits#(7,32) axiSpiSlaveLite = toAxi4SlaveBits(axiSpiBvi.s_axi); // PhysMemSlave#(12,32) axiSpiMemSlave <- mkPhysMemSlave(axiSpiSlaveLite); `ifdef IncludeEthernet PhysMemSlave#(12,32) axiDmaMemSlave <- mkPhysMemSlave(axiEthBvi.s_axi_dma); Axi4SlaveLiteBits#(12,32) axiEthSlaveLite = toAxi4SlaveBits(axiEthBvi.s_axi_mac); PhysMemSlave#(12,32) axiEthMemSlave <- mkPhysMemSlave(axiEthSlaveLite); PhysMemSlave#(20,32) deviceSlaveMux <- mkPhysMemSlaveMux(vec(axiUartMemSlave, axiIntcMemSlave, axiIicMemSlave, axiDmaMemSlave, axiEthMemSlave)); // , axiSpiMemSlave `else PhysMemSlave#(20,32) deviceSlaveMux <- mkPhysMemSlaveMux(vec(axiUartMemSlave, axiIntcMemSlave, axiIicMemSlave)); `endif PhysMemSlave#(20,32) bootRomMemSlave <- mkPhysMemSlaveFromBram(bootRom); PhysMemSlave#(21,32) memSlaveMux <- mkPhysMemSlaveMux(vec(bootRomMemSlave, deviceSlaveMux)); let memReadClients <- mapM(mkMemReadClient(objId), vec(m_axi_mm2s, m_axi_sg)); let memWriteClients <- mapM(mkMemWriteClient(objId), vec(m_axi_s2mm, m_axi_sg)); `ifdef IncludeFlash PhysMemSlave#(26,16) bpiFlashSlave <- mkPhysMemSlaveFromBram(bpiFlash.server); `endif FIFOF#(Bit#(32)) dfifo <- mkFIFOF(); FIFOF#(Bit#(32)) flashdfifo <- mkFIFOF(); `ifdef IncludeEthernet rule rl_axieth; axiEthBvi.signal.detect(1); // drive to 1 if not using optical transceiver, else use signal from transceiver endrule `endif rule rl_rdata; let rdata <- memSlaveMux.read_server.readData.get(); ind.readDone(rdata.data); endrule rule rl_wdata; let wdata <- toGet(dfifo).get(); memSlaveMux.write_server.writeData.put(MemData {data: wdata, tag: 0, last: True}); endrule rule rl_writeDone; let tag <- memSlaveMux.write_server.writeDone.get(); ind.writeDone(); endrule rule rl_bpiflash_rdata; `ifdef IncludeFlash let rdata <- bpiFlashSlave.read_server.readData.get(); ind.readFlashDone(extend(rdata.data)); `endif endrule rule rl_bpiflash_wdata; `ifdef IncludeFlash let wdata <- toGet(flashdfifo).get(); bpiFlashSlave.write_server.writeData.put(MemData {data: truncate(wdata), tag: 0, last: True}); `endif endrule rule rl_bpiflash_writeDone; `ifdef IncludeFlash let tag <- bpiFlashSlave.write_server.writeDone.get(); ind.writeFlashDone(); `endif endrule `ifndef BOARD_miniitx100 DiffClock sfp_rec_clk_buf <- mkClockOBUFDS(defaultValue, clocked_by clk_125mhz); `endif IOBUF sdaIOBuf <- mkIOBUF(axiIicBvi.sda.t, axiIicBvi.sda.o); IOBUF sclIOBuf <- mkIOBUF(axiIicBvi.scl.t, axiIicBvi.scl.o); // No probe for .o because they are tied to ground -- I2C operates open collector Probe#(Bit#(1)) sda_i_probe <- mkProbe(); Probe#(Bit#(1)) sda_t_probe <- mkProbe(); Probe#(Bit#(1)) scl_i_probe <- mkProbe(); Probe#(Bit#(1)) scl_t_probe <- mkProbe(); rule iic_o; sda_i_probe <= sdaIOBuf.o; sda_t_probe <= axiIicBvi.sda.t; scl_i_probe <= sclIOBuf.o; scl_t_probe <= axiIicBvi.scl.t; axiIicBvi.sda.i(sdaIOBuf.o); axiIicBvi.scl.i(sclIOBuf.o); endrule // IOBUF spiSckIOBuf <- mkIOBUF(axiSpiBvi.sck.t, axiSpiBvi.sck.o); // IOBUF spiSsIOBuf <- mkIOBUF(axiSpiBvi.ss.t, axiSpiBvi.ss.o); // IOBUF spiMosiIOBuf <- mkIOBUF(axiSpiBvi.io0.t, axiSpiBvi.io0.o); // IOBUF spiMisoIOBuf <- mkIOBUF(axiSpiBvi.io1.t, axiSpiBvi.io1.o); // rule spi_o; // axiSpiBvi.sck.i(spiSckIOBuf.o); // axiSpiBvi.ss.i(spiSsIOBuf.o); // axiSpiBvi.io0.i(spiMosiIOBuf.o); // axiSpiBvi.io1.i(spiMisoIOBuf.o); // endrule // Probe#(Bit#(1)) spi_sck_i_probe <- mkProbe(); // Probe#(Bit#(1)) spi_sck_o_probe <- mkProbe(); // Probe#(Bit#(1)) spi_sck_t_probe <- mkProbe(); // Probe#(Bit#(1)) spi_ss_i_probe <- mkProbe(); // Probe#(Bit#(1)) spi_ss_o_probe <- mkProbe(); // Probe#(Bit#(1)) spi_ss_t_probe <- mkProbe(); // Probe#(Bit#(1)) spi_miso_i_probe <- mkProbe(); // Probe#(Bit#(1)) spi_miso_o_probe <- mkProbe(); // Probe#(Bit#(1)) spi_miso_t_probe <- mkProbe(); // Probe#(Bit#(1)) spi_mosi_i_probe <- mkProbe(); // Probe#(Bit#(1)) spi_mosi_o_probe <- mkProbe(); // Probe#(Bit#(1)) spi_mosi_t_probe <- mkProbe(); // rule rl_spi_trace; // spi_sck_i_probe <= spiSckIOBuf.o; // spi_sck_o_probe <= axiSpiBvi.sck.o; // spi_sck_t_probe <= axiSpiBvi.sck.t; // spi_ss_i_probe <= spiSsIOBuf.o; // spi_ss_o_probe <= axiSpiBvi.ss.o; // spi_ss_t_probe <= axiSpiBvi.ss.t; // spi_miso_i_probe <= spiMisoIOBuf.o; // spi_miso_o_probe <= axiSpiBvi.io1.o; // spi_miso_t_probe <= axiSpiBvi.io1.t; // spi_mosi_i_probe <= spiMosiIOBuf.o; // spi_mosi_o_probe <= axiSpiBvi.io0.o; // spi_mosi_t_probe <= axiSpiBvi.io0.t; // endrule FIFOF#(Tuple3#(DmaChannel,Bool,MemRequest)) traceFifo <- mkDualClockBramFIFOF(clock, reset, clock, reset); FIFOF#(Tuple3#(DmaChannel,Bool,MemRequest)) traceFifo0 <- mkFIFOF(); FIFOF#(Tuple3#(DmaChannel,Bool,MemRequest)) traceFifo1 <- mkFIFOF(); PipeIn#(Tuple3#(DmaChannel,Bool,MemRequest)) tracePipe = toPipeIn(traceFifo0); FIFOF#(Tuple3#(DmaChannel,Bool,MemData#(DataBusWidth))) traceDataFifo <- mkDualClockBramFIFOF(clock, reset, clock, reset); FIFOF#(Tuple3#(DmaChannel,Bool,MemData#(DataBusWidth))) traceDataFifo0 <- mkFIFOF(); FIFOF#(Tuple3#(DmaChannel,Bool,MemData#(DataBusWidth))) traceDataFifo1 <- mkFIFOF(); PipeIn#(Tuple3#(DmaChannel,Bool,MemData#(DataBusWidth))) traceDataPipe = toPipeIn(traceDataFifo0); let trace0Cnx <- mkConnection(toGet(traceFifo0), toPut(traceFifo)); let trace1Cnx <- mkConnection(toGet(traceFifo), toPut(traceFifo1)); rule rl_trace1; match { .chan, .write, .req } <- toGet(traceFifo1).get(); ind.traceDmaRequest(chan, write, truncate(req.sglId), truncate(req.offset), extend(req.burstLen)); endrule let traceData0Cnx <- mkConnection(toGet(traceDataFifo0), toPut(traceDataFifo)); let traceData1Cnx <- mkConnection(toGet(traceDataFifo), toPut(traceDataFifo1)); rule rl_trace_data; match { .chan, .write, .md } <- toGet(traceDataFifo1).get(); ind.traceDmaData(chan, write, md.data, md.last); endrule let traceReadClients <- mapM(uncurry(mkTraceReadClient(tracePipe,traceDataPipe)), zip(vec(DMA_TX, DMA_SG), memReadClients)); let traceWriteClients <- mapM(uncurry(mkTraceWriteClient(tracePipe,traceDataPipe)), zip(vec(DMA_RX, DMA_SG), memWriteClients)); interface SpikeHwRequest request; method Action reset(); newReset.assertReset(); endmethod method Action setupDma(Bit#(32) memref); objId <= memref; endmethod method Action read(Bit#(32) addr); memSlaveMux.read_server.readReq.put(PhysMemRequest { addr: truncate(addr), burstLen: 4, tag: 0 }); endmethod method Action write(Bit#(32) addr, Bit#(32) value); memSlaveMux.write_server.writeReq.put(PhysMemRequest { addr: truncate(addr), burstLen: 4, tag: 0 }); dfifo.enq(value); endmethod method Action setFlashParameters(Bit#(16) cycles); `ifdef IncludeFlash bpiFlash.setParameters(cycles, False); `endif endmethod method Action readFlash(Bit#(32) addr); `ifdef IncludeFlash bpiFlashSlave.read_server.readReq.put(PhysMemRequest { addr: truncate(addr), burstLen: 2, tag: 0 }); `endif endmethod method Action writeFlash(Bit#(32) addr, Bit#(32) value); `ifdef IncludeFlash bpiFlashSlave.write_server.writeReq.put(PhysMemRequest { addr: truncate(addr), burstLen: 2, tag: 0 }); flashdfifo.enq(value); `endif endmethod method Action status(); ind.status( pack(newReset.isAsserted), `ifdef IncludeEthernet axiEthBvi.mmcm.locked_out(), eth_los, `else 0, eth_los, `endif axiIntcBvi.irq, intr()); endmethod method Action iicReset(Bit#(1) rst); iicResetReg <= rst; endmethod endinterface interface SpikeHwPins pins; `ifdef IncludeEthernet interface EthPins eth; interface AxiethbviMgt mgt = axiEthBvi.mgt; `ifdef EthernetSgmii interface AxiethbviSgmii sgmii = axiEthBvi.sgmii; `else interface AxiethbviSfp sfp = axiEthBvi.sfp; `endif method Bit#(1) tx_disable(); return 0; endmethod method Action rx_los(Bit#(1) v); eth_los <= v; endmethod endinterface `else interface EthPins eth; method Bit#(1) tx_disable(); return 0; endmethod method Action rx_los(Bit#(1) v); eth_los <= v; endmethod endinterface `endif `ifdef IncludeFlash interface flash = bpiFlash.flash; `endif interface SpikeUartPins uart; `ifndef BOARD_miniitx100 method tx = axiUartBvi.sout; method rx = axiUartBvi.sin; `endif `ifdef UART_HAX_RTS_CTS method rts = axiUartBvi.rtsn; method cts = axiUartBvi.ctsn; `endif endinterface interface SpikeIicPins iic; interface scl = sclIOBuf.io; interface sda = sdaIOBuf.io; method mux_reset = iicResetReg; endinterface // interface SpikeSpiPins spi; // interface sck = spiSckIOBuf.io; // interface ss = spiSsIOBuf.io; // interface miso = spiMisoIOBuf.io; // interface mosi = spiMosiIOBuf.io; // endinterface interface Clock deleteme_unused_clock = clock; interface Reset deleteme_unused_reset = reset; `ifndef BOARD_miniitx100 interface Clock sfp_rec_clk_p = sfp_rec_clk_buf.p; interface Clock sfp_rec_clk_n = sfp_rec_clk_buf.n; `endif endinterface interface Vector dmaReadClient = traceReadClients; interface Vector dmaWriteClient = traceWriteClients; endmodule ================================================ FILE: tests/spikehw/SpikeHwIfc.bsv ================================================ import BuildVector::*; import Clocks::*; import Connectable::*; import GetPut::*; import FIFOF::*; import BRAM::*; import Probe::*; import StmtFSM::*; import TriState::*; import Vector::*; import XilinxCells::*; import Probe::*; import ConnectalXilinxCells::*; import ConnectalConfig::*; import CtrlMux::*; import HostInterface::*; import ConnectalMemTypes::*; import Pipe::*; import AxiBits::*; import PhysMemSlaveFromBram::*; import BpiFlash::*; import AxiIntcBvi::*; import AxiIic::*; import AxiUart::*; `ifdef EthernetSgmii import AxiEthBvi::*; `else import AxiEth1000BaseX::*; `endif import AxiDmaBvi::*; import SpikeHwPins::*; `include "ConnectalProjectConfig.bsv" typedef enum { DMA_RX, DMA_TX, DMA_SG } DmaChannel deriving (Bits,Eq); interface SpikeHwRequest; method Action reset(); method Action setupDma(Bit#(32) memref); method Action status(); method Action read(Bit#(32) addr); method Action write(Bit#(32) addr, Bit#(32) value); method Action setFlashParameters(Bit#(16) cycles); method Action readFlash(Bit#(32) addr); method Action writeFlash(Bit#(32) addr, Bit#(32) value); method Action iicReset(Bit#(1) rst); endinterface interface SpikeHwIndication; method Action irqChanged(Bit#(1) newIrq, Bit#(16) intrSources); method Action readDone(Bit#(32) value); method Action writeDone(); method Action readFlashDone(Bit#(32) value); method Action writeFlashDone(); method Action resetDone(); method Action status(Bit#(1) reset_asserted, Bit#(1) mmcm_locked, Bit#(1) rx_los, Bit#(1) irq, Bit#(16) intrSources); method Action traceDmaRequest(DmaChannel channel, Bool write, Bit#(16) objId, Bit#(32) offset, Bit#(16) burstLen); method Action traceDmaData(DmaChannel channel, Bool write, Bit#(32) data, Bool last); endinterface ================================================ FILE: tests/spikehw/SpikeHwPins.bsv ================================================ `ifdef EthernetSgmii import AxiEthBvi::*; `else import AxiEth1000BaseX::*; `endif import BpiFlash::*; `include "ConnectalProjectConfig.bsv" interface EthPins; `ifdef IncludeEthernet `ifdef EthernetSgmii interface AxiethbviSgmii sgmii; `else interface AxiethbviSfp sfp; `endif interface AxiethbviMgt mgt; `endif method Bit#(1) tx_disable(); method Action rx_los(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface SpikeIicPins; interface Inout#(Bit#(1)) scl; interface Inout#(Bit#(1)) sda; method Bit#(1) mux_reset(); endinterface (* always_ready, always_enabled *) interface SpikeSpiPins; interface Inout#(Bit#(1)) miso; interface Inout#(Bit#(1)) mosi; interface Inout#(Bit#(1)) sck; interface Inout#(Bit#(1)) ss; endinterface (* always_ready, always_enabled *) interface SpikeUartPins; `ifndef BOARD_miniitx100 method Bit#(1) tx; method Action rx (Bit#(1) x); `endif `ifdef UART_HAX_RTS_CTS method Bit#(1) rts; method Action cts(Bit#(1) x); `endif endinterface (* always_ready, always_enabled *) interface SpikeHwPins; interface EthPins eth; interface SpikeUartPins uart; interface SpikeIicPins iic; interface SpikeSpiPins spi; `ifdef IncludeFlash interface BpiFlashPins flash; `endif interface Clock deleteme_unused_clock; interface Reset deleteme_unused_reset; `ifndef BOARD_miniitx100 interface Clock sfp_rec_clk_p; interface Clock sfp_rec_clk_n; `endif endinterface ================================================ FILE: tests/spikehw/SyncAxisFifo32x1024.bsv ================================================ /* ../../generated/scripts/importbvi.py -I SyncAxisFifo32x1024 -P SyncAxisFifo32x1024 -c m_aclk -c s_aclk -r s_aresetn -o SyncAxisFifo32x1024.bsv cores/nfsume/dual_clock_axis_fifo_32x1024/dual_clock_axis_fifo_32x1024_stub.v */ import Clocks::*; import ConnectalFIFO::*; import DefaultValue::*; import FIFOF::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import AxiStream::*; (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface Syncaxisfifo32x1024M_axis; method Bit#(32) tdata(); method Bit#(4) tkeep(); method Bit#(1) tlast(); method Action tready(Bit#(1) v); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface Syncaxisfifo32x1024S_axis; method Action tdata(Bit#(32) v); method Action tkeep(Bit#(4) v); method Action tlast(Bit#(1) v); method Bit#(1) tready(); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface SyncAxisFifo32x1024; interface AxiStreamMaster#(32) m_axis; interface AxiStreamSlave#(32) s_axis; endinterface import "BVI" dual_clock_axis_fifo_32x1024 = module mkSyncAxisFifo32x1024#(Clock s_aclk, Reset s_aresetn, Clock m_aclk, Reset m_aresetn)(SyncAxisFifo32x1024); default_clock clk(); default_reset rst(); input_clock m_aclk(m_aclk) = m_aclk; input_clock s_aclk(s_aclk) = s_aclk; input_reset s_aresetn(s_aresetn) clocked_by (s_aclk) = s_aresetn; input_reset m_aresetn_foo() clocked_by (m_aclk) = m_aresetn; interface AxiStreamMaster m_axis; method m_axis_tdata tdata() clocked_by (m_aclk) reset_by (m_aresetn_foo); method m_axis_tkeep tkeep() clocked_by (m_aclk) reset_by (m_aresetn_foo); method m_axis_tlast tlast() clocked_by (m_aclk) reset_by (m_aresetn_foo); method tready(m_axis_tready) enable((*inhigh*) EN_m_axis_tready) clocked_by (m_aclk) reset_by (m_aresetn_foo); method m_axis_tvalid tvalid() clocked_by (m_aclk) reset_by (m_aresetn_foo); endinterface interface AxiStreamSlave s_axis; method tdata(s_axis_tdata) enable((*inhigh*) EN_s_axis_tdata) clocked_by (s_aclk) reset_by (s_aresetn); method tkeep(s_axis_tkeep) enable((*inhigh*) EN_s_axis_tkeep) clocked_by (s_aclk) reset_by (s_aresetn); method tlast(s_axis_tlast) enable((*inhigh*) EN_s_axis_tlast) clocked_by (s_aclk) reset_by (s_aresetn); method s_axis_tready tready() clocked_by (s_aclk) reset_by (s_aresetn); method tvalid(s_axis_tvalid) enable((*inhigh*) EN_s_axis_tvalid) clocked_by (s_aclk) reset_by (s_aresetn); endinterface schedule (m_axis.tdata, m_axis.tkeep, m_axis.tlast, m_axis.tready, m_axis.tvalid, s_axis.tdata, s_axis.tkeep, s_axis.tlast, s_axis.tready, s_axis.tvalid) CF (m_axis.tdata, m_axis.tkeep, m_axis.tlast, m_axis.tready, m_axis.tvalid, s_axis.tdata, s_axis.tkeep, s_axis.tlast, s_axis.tready, s_axis.tvalid); endmodule module mkSyncAxisFifo32x1024FIFOF#(Clock fromClock, Reset fromReset, Clock toClock, Reset toReset)(FIFOF#(a)) provisos (Bits#(a, asz), Add#(asz, a__, 32)); let fromFIFOF <- mkCFFIFOF(clocked_by fromClock, reset_by fromReset); let syncFIFOF <- mkSyncAxisFifo32x1024(fromClock, fromReset, toClock, toReset); let toFIFOF <- mkCFFIFOF(clocked_by toClock, reset_by toReset); rule rl_from if (syncFIFOF.s_axis.tready() == 1); syncFIFOF.s_axis.tdata(extend(pack(fromFIFOF.first()))); fromFIFOF.deq(); endrule rule rl_from_handshake; syncFIFOF.s_axis.tvalid(pack(fromFIFOF.notEmpty())); syncFIFOF.s_axis.tkeep(maxBound); syncFIFOF.s_axis.tlast(1); endrule rule rl_to if (syncFIFOF.m_axis.tvalid() == 1); toFIFOF.enq(unpack(truncate(syncFIFOF.m_axis.tdata))); endrule rule rl_to_handshake; syncFIFOF.m_axis.tready(pack(toFIFOF.notFull())); endrule method notEmpty = toFIFOF.notEmpty; method first = toFIFOF.first; method deq = toFIFOF.deq; method enq = fromFIFOF.enq; method notFull = fromFIFOF.notFull; endmodule ================================================ FILE: tests/spikehw/TriModeMacBvi.bsv ================================================ /* /home/jamey/connectal.clean/generated/scripts/importbvi.py -o TriModeMacBvi.bsv -P TriModeMac -I TriModeMacBvi -c gtx_clk -r glbl_rstn -r rx_axi_rstn -r tx_axi_rstn -c rx_mac_aclk -r rx_reset -c tx_mac_aclk -r tx_reset -c s_axi_aclk -r s_axi_resetn -f rx_axis_mac -f tx_axis_mac -n speedis100 -n speedis10100 cores/nfsume/tri_mode_ethernet_mac_0/tri_mode_ethernet_mac_0_stub.v */ `include "ConnectalProjectConfig.bsv" import Clocks::*; import DefaultValue::*; import XilinxCells::*; import GetPut::*; import AxiBits::*; import AxiStream::*; (* always_ready, always_enabled *) interface TrimodemacGmii; method Action rx_dv(Bit#(1) v); method Action rx_er(Bit#(1) v); method Action rxd(Bit#(8) v); method Bit#(1) tx_en(); method Bit#(1) tx_er(); method Bit#(8) txd(); endinterface (* always_ready, always_enabled *) (* always_ready, always_enabled *) interface TrimodemacMac; method Bit#(1) irq(); endinterface (* always_ready, always_enabled *) interface TrimodemacMdio; method Action i(Bit#(1) v); method Bit#(1) o(); method Bit#(1) t(); endinterface (* always_ready, always_enabled *) interface TrimodemacPause; method Action req(Bit#(1) v); method Action val(Bit#(16) v); endinterface (* always_ready, always_enabled *) interface TrimodemacRx; method Bit#(5) axis_filter_tuser(); interface Clock mac_aclk; method Reset reset(); method Bit#(1) statistics_valid(); method Bit#(28) statistics_vector(); endinterface (* always_ready, always_enabled *) interface TrimodemacRx_axis_mac; method Bit#(8) tdata(); method Bit#(1) tlast(); method Bit#(1) tuser(); method Bit#(1) tvalid(); endinterface (* always_ready, always_enabled *) interface TrimodemacS_axi; method Action araddr(Bit#(12) v); method Bit#(1) arready(); method Action arvalid(Bit#(1) v); method Action awaddr(Bit#(12) v); method Bit#(1) awready(); method Action awvalid(Bit#(1) v); method Action bready(Bit#(1) v); method Bit#(2) bresp(); method Bit#(1) bvalid(); method Bit#(32) rdata(); method Action rready(Bit#(1) v); method Bit#(2) rresp(); method Bit#(1) rvalid(); method Action wdata(Bit#(32) v); method Bit#(1) wready(); method Action wvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface TrimodemacTx; method Action ifg_delay(Bit#(8) v); interface Clock mac_aclk; method Reset reset(); method Bit#(1) statistics_valid(); method Bit#(32) statistics_vector(); endinterface (* always_ready, always_enabled *) interface TrimodemacTx_axis_mac; method Action tdata(Bit#(8) v); method Action tlast(Bit#(1) v); method Bit#(1) tready(); method Action tuser(Bit#(1) v); method Action tvalid(Bit#(1) v); endinterface (* always_ready, always_enabled *) interface TriModeMac; interface TrimodemacGmii gmii; interface TrimodemacMac mac; method Bit#(1) mdc(); interface TrimodemacMdio mdio; interface TrimodemacPause pause; interface TrimodemacRx rx; interface TrimodemacRx_axis_mac rx_axis_mac; interface TrimodemacS_axi s_axi; method Bit#(1) speedis100(); method Bit#(1) speedis10100(); interface TrimodemacTx tx; interface TrimodemacTx_axis_mac tx_axis_mac; endinterface import "BVI" tri_mode_ethernet_mac_0 = module mkTriModeMacBvi#(Clock gtx_clk, Clock s_axi_aclk, Reset glbl_rstn, Reset rx_axi_rstn, Reset s_axi_resetn, Reset tx_axi_rstn)(TriModeMac); default_clock clk(); default_reset rst(); input_reset glbl_rstn(glbl_rstn) = glbl_rstn; input_clock gtx_clk(gtx_clk) = gtx_clk; input_reset rx_axi_rstn(rx_axi_rstn) = rx_axi_rstn; input_clock s_axi_aclk(s_axi_aclk) = s_axi_aclk; input_reset s_axi_resetn(s_axi_resetn) = s_axi_resetn; input_reset tx_axi_rstn(tx_axi_rstn) = tx_axi_rstn; interface TrimodemacGmii gmii; method rx_dv(gmii_rx_dv) enable((*inhigh*) EN_gmii_rx_dv); method rx_er(gmii_rx_er) enable((*inhigh*) EN_gmii_rx_er); method rxd(gmii_rxd) enable((*inhigh*) EN_gmii_rxd); method gmii_tx_en tx_en(); method gmii_tx_er tx_er(); method gmii_txd txd(); endinterface interface TrimodemacMac mac; method mac_irq irq() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); endinterface method mdc mdc(); interface TrimodemacMdio mdio; method i(mdio_i) enable((*inhigh*) EN_mdio_i); method mdio_o o(); method mdio_t t(); endinterface interface TrimodemacRx rx; output_clock mac_aclk(rx_mac_aclk); output_reset reset(rx_reset) clocked_by (rx_mac_aclk); method rx_axis_filter_tuser axis_filter_tuser() clocked_by (rx_mac_aclk) reset_by (rx_reset); method rx_statistics_valid statistics_valid() clocked_by (rx_mac_aclk) reset_by (rx_reset); method rx_statistics_vector statistics_vector() clocked_by (rx_mac_aclk) reset_by (rx_reset); endinterface interface TrimodemacRx_axis_mac rx_axis_mac; method rx_axis_mac_tdata tdata() clocked_by (rx_mac_aclk) reset_by (rx_reset); method rx_axis_mac_tlast tlast() clocked_by (rx_mac_aclk) reset_by (rx_reset); method rx_axis_mac_tuser tuser() clocked_by (rx_mac_aclk) reset_by (rx_reset); method rx_axis_mac_tvalid tvalid() clocked_by (rx_mac_aclk) reset_by (rx_reset); endinterface interface TrimodemacS_axi s_axi; method araddr(s_axi_araddr) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_araddr); method s_axi_arready arready() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method arvalid(s_axi_arvalid) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_arvalid); method awaddr(s_axi_awaddr) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_awaddr); method s_axi_awready awready() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method awvalid(s_axi_awvalid) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_awvalid); method bready(s_axi_bready) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_bready); method s_axi_bresp bresp() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method s_axi_bvalid bvalid() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method s_axi_rdata rdata() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method rready(s_axi_rready) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_rready); method s_axi_rresp rresp() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method s_axi_rvalid rvalid() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method wdata(s_axi_wdata) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_wdata); method s_axi_wready wready() clocked_by (s_axi_aclk) reset_by (s_axi_resetn); method wvalid(s_axi_wvalid) clocked_by (s_axi_aclk) reset_by (s_axi_resetn) enable((*inhigh*) EN_s_axi_wvalid); endinterface method speedis100 speedis100(); method speedis10100 speedis10100(); interface TrimodemacTx tx; output_clock mac_aclk(tx_mac_aclk); output_reset reset(tx_reset) clocked_by (tx_mac_aclk); method ifg_delay(tx_ifg_delay) enable((*inhigh*) EN_tx_ifg_delay) clocked_by (tx_mac_aclk) reset_by (tx_reset); method tx_statistics_valid statistics_valid() clocked_by (tx_mac_aclk) reset_by (tx_reset); method tx_statistics_vector statistics_vector() clocked_by (tx_mac_aclk) reset_by (tx_reset); endinterface interface TrimodemacTx_axis_mac tx_axis_mac; method tdata(tx_axis_mac_tdata) enable((*inhigh*) EN_tx_axis_mac_tdata) clocked_by (tx_mac_aclk) reset_by (tx_reset); method tlast(tx_axis_mac_tlast) enable((*inhigh*) EN_tx_axis_mac_tlast) clocked_by (tx_mac_aclk) reset_by (tx_reset); method tx_axis_mac_tready tready() clocked_by (tx_mac_aclk) reset_by (tx_reset); method tuser(tx_axis_mac_tuser) enable((*inhigh*) EN_tx_axis_mac_tuser) clocked_by (tx_mac_aclk) reset_by (tx_reset); method tvalid(tx_axis_mac_tvalid) enable((*inhigh*) EN_tx_axis_mac_tvalid) clocked_by (tx_mac_aclk) reset_by (tx_reset); endinterface interface TrimodemacPause pause; method req(pause_req) enable((*inhigh*) EN_pause_req) clocked_by (tx_mac_aclk) reset_by (tx_reset); method val(pause_val) enable((*inhigh*) EN_pause_val) clocked_by (tx_mac_aclk) reset_by (tx_reset); endinterface schedule (gmii.rx_dv, gmii.rx_er, gmii.rxd, gmii.tx_en, gmii.tx_er, gmii.txd, mac.irq, mdc, mdio.i, mdio.o, mdio.t, pause.req, pause.val, rx.axis_filter_tuser, rx.statistics_valid, rx.statistics_vector, rx_axis_mac.tdata, rx_axis_mac.tlast, rx_axis_mac.tuser, rx_axis_mac.tvalid, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wvalid, speedis100, speedis10100, tx.ifg_delay, tx.statistics_valid, tx.statistics_vector, tx_axis_mac.tdata, tx_axis_mac.tlast, tx_axis_mac.tready, tx_axis_mac.tuser, tx_axis_mac.tvalid) CF (gmii.rx_dv, gmii.rx_er, gmii.rxd, gmii.tx_en, gmii.tx_er, gmii.txd, mac.irq, mdc, mdio.i, mdio.o, mdio.t, pause.req, pause.val, rx.axis_filter_tuser, rx.statistics_valid, rx.statistics_vector, rx_axis_mac.tdata, rx_axis_mac.tlast, rx_axis_mac.tuser, rx_axis_mac.tvalid, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wvalid, speedis100, speedis10100, tx.ifg_delay, tx.statistics_valid, tx.statistics_vector, tx_axis_mac.tdata, tx_axis_mac.tlast, tx_axis_mac.tready, tx_axis_mac.tuser, tx_axis_mac.tvalid); endmodule `ifdef FLUTE import TLM3 :: *; import Axi4 :: *; import AxiDefines ::*; instance ToAxi4LRdWrSlave#(TrimodemacS_axi); function Axi4LRdWrSlave#(`SoC_PRM) toAxi4LRdWrSlave(TrimodemacS_axi s); return (interface Axi4LRdWrSlave#(`SoC_PRM); interface Axi4LRdSlave read; method Action arADDR(AxiAddr#(`SoC_PRM) addr); s.araddr(truncate(addr)); endmethod method arREADY = unpack(s.arready()); method Action arVALID(Bool v); s.arvalid(pack(v)); endmethod method rDATA = extend(s.rdata); method Action rREADY(Bool r); s.rready(pack(r)); endmethod method rRESP = unpack(s.rresp); method rVALID = unpack(s.rvalid); endinterface: read interface Axi4LWrSlave write; method Action awADDR(AxiAddr#(`SoC_PRM) addr); s.awaddr(truncate(addr)); endmethod method awREADY = unpack(s.awready); method Action awVALID(Bool v); s.awvalid(pack(v)); endmethod method Action bREADY(Bool r); s.bready(pack(r)); endmethod method bRESP = unpack(s.bresp); method bVALID = unpack(s.bvalid); method Action wDATA(AxiData#(`SoC_PRM) d); s.wdata(truncate(d)); endmethod method wREADY = unpack(s.wready); method Action wVALID(Bool v); s.wvalid(pack(v)); endmethod endinterface: write endinterface); endfunction endinstance interface TriModeMacMac; method Bit#(1) mdc(); interface TrimodemacMdio mdio; interface TrimodemacGmii gmii; interface Server #(SoC_Req, SoC_Rsp) bus_ifc; interface TrimodemacTx s_axis_tx; interface TrimodemacRx m_axis_rx; interface Clock mm2s_aclk; interface Clock s2mm_aclk; method Bit#(1) interrupt(); endinterface (* synthesize *) module mkTriModeMacMac#(Clock gtx_clock)(TriModeMacMac); let clock <- exposeCurrentClock; let reset <- exposeCurrentReset; let gtx_reset = reset; let axiEth <- mkTriModeMacBvi(gtx_clock, clock, reset, reset, reset, reset); Axi4LRdWrSlave#(`SoC_PRM) axiRdWrSlave = toAxi4LRdWrSlave(axiEth.s_axi); let tlmRecv <- mkTLMRecvFromAxi4LSlave(axiRdWrSlave); method mdc = axiEth.mdc; interface mdio = axiEth.mdio; interface bus_ifc = tlmRecv; interface gmii = axiEth.gmii; method interrupt = axiEth.mac.irq; interface s_axis_tx = axiEth.tx; interface m_axis_rx = axiEth.rx; interface mm2s_aclk = axiEth.rx.mac_aclk; interface s2mm_aclk = axiEth.tx.mac_aclk; endmodule `endif //FLUTE instance ToAxi4SlaveBits#(Axi4SlaveLiteBits#(12,32), TrimodemacS_axi); function Axi4SlaveLiteBits#(12,32) toAxi4SlaveBits(TrimodemacS_axi s); return (interface Axi4SlaveLiteBits#(12,32); method araddr = compose(s.araddr, extend); method arready = s.arready; method arvalid = s.arvalid; method awaddr = compose(s.awaddr, extend); method awready = s.awready; method awvalid = s.awvalid; method bready = s.bready; method bresp = s.bresp; method bvalid = s.bvalid; method rdata = s.rdata; method rready = s.rready; method rresp = s.rresp; method rvalid = s.rvalid; method wdata = s.wdata; method wready = s.wready; method Action wvalid(Bit#(1) v); s.wvalid(v); //s.wstrb(pack(replicate(v))); endmethod endinterface); endfunction endinstance ================================================ FILE: tests/spikehw/boot/Makefile ================================================ all: bootrom.bin bootrom.hex bootromx4.hex clean: rm -f *.o *.elf *.bin *.hex entry.o: entry.S riscv64-unknown-elf-gcc -O -c entry.S riscv64-unknown-elf-objdump -d -S entry.o > entry.dump copybbl.o: copybbl.c riscv64-unknown-elf-gcc -O -c copybbl.c copybbl.elf: entry.o copybbl.o bbl.o vmlinux.o Makefile riscv64-unknown-elf-ld -o copybbl.elf -Ttext 0x0000000 -Tdata 400 --entry=0000000 entry.o copybbl.o bbl.o riscv64-unknown-elf-objdump -D copybbl.elf | head -1000 > copybbl.dump bootrom.hex: copybbl.elf rm -f copybbl.hex #elf2hex 8 1048576 copybbl.elf > bootrom.hex elf2hex 8 524288 copybbl.elf > bootrom.hex #elf2hex 8 16384 copybbl.elf > bootrom.hex bootromx4.hex: copybbl.elf rm -f copybbl.hex #elf2hex 8 1048576 copybbl.elf > bootrom.hex elf2hex 4 16384 copybbl.elf > bootromx4.hex #elf2hex 8 16384 copybbl.elf > bootrom.hex bootrom.bin: copybbl.elf riscv64-unknown-elf-objcopy -O binary copybbl.elf bootrom.bin hexdump -C bootrom.bin > bootrom.txt bbl.o: bbl.elf Makefile riscv64-unknown-elf-objcopy -O binary bbl.elf bbl.bin riscv64-unknown-elf-objcopy -I binary -O elf64-littleriscv -B riscv bbl.bin bbl.o riscv64-unknown-elf-objdump -D bbl.elf > bbl.dump riscv64-unknown-elf-objdump -b binary -m riscv -D bbl.bin > bbl2.dump hexdump -C bbl.elf > bbl.txt hexdump -C bbl.bin > bbl2.txt LINUX_DIR = ../../../../linux vmlinux.o: $(LINUX_DIR)/vmlinux Makefile cp -f $(LINUX_DIR)/vmlinux vmlinux.elf riscv64-unknown-elf-objcopy -I binary -O elf64-littleriscv -B riscv vmlinux.elf vmlinux.o BBL_FILE = ../../../../riscv-pk/build/bbl bbl.elf: $(BBL_FILE) cp -fv $(BBL_FILE) bbl.elf bbl.hex: $(BBL_FILE) elf2hex 8 8192 $(BBL_FILE) > bbl.hex dump: copybbl.elf riscv64-unknown-elf-objdump -D copybbl.elf ================================================ FILE: tests/spikehw/boot/copybbl.c ================================================ #define DRAM_BASE 0 #define DRAM_SIZE 64*1024*1024 #define BOOT_SIZE 0x400 #define BBL_BASE (DRAM_SIZE+BOOT_SIZE) #define BBL_LEN (64*1024) int copybbl() { volatile long *src = (long *)BBL_BASE; volatile long *dst = (long*)(DRAM_BASE+0x100); int i; for (i = 0; i < BBL_LEN/sizeof(*dst); i++) *dst++ = *src++; } ================================================ FILE: tests/spikehw/boot/entry.S ================================================ entry: lui sp,1 jal copybbl li a0, 0x200 jr a0 stuck: j stuck copybbl: ================================================ FILE: tests/spikehw/bootromx4.hex ================================================ 00001137 010000ef 20000513 00050067 0000006f 040007b7 40078793 fc0005b7 04010637 40060613 0007b683 00b78733 d0d73023 00878793 fec798e3 00008067 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 34011173 04a13823 04b13c23 34202573 1a054863 2a0005b7 00a595bb 2005c063 05013503 05813583 34011173 30500073 00000013 00000013 00000013 00000013 34011173 04a13823 04b13c23 34202573 16054863 2a4005b7 00a595bb 1c05c063 30002573 0185151b 06054863 05013503 05813583 34011173 30500073 00000013 24d0206f 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 34011073 f0010113 04a13823 04b13c23 00d00513 1480006f 1c800513 30053073 f8dff06f 00000013 00000013 00000013 00000013 00000013 00000013 1d10206f 00000093 00000113 00000193 00000213 00000293 00000313 00000393 00000413 00000493 00000513 00000593 00000613 00000693 00000713 00000793 00000813 00000893 00000913 00000993 00000a13 00000a93 00000b13 00000b93 00000c13 00000c93 00000d13 00000d93 00000e13 00000e93 00000f13 00000f93 0000d117 d8310113 fffff2b7 00517133 ec010113 f1002573 00051663 34011073 6850206f 00009517 00850513 0010059b 00b5252f 00c51293 00510133 34011073 6650206f 00151513 00200593 02b51c63 08000513 34453073 02000593 30453073 3445a073 30002573 01000593 03857513 e2b51ae3 05013503 05813583 34011173 10000073 00051863 34447073 34416073 fd5ff06f 00400593 12b51663 00c00513 00113423 340110f3 00313c23 02413023 02513423 00009297 02613823 00251313 02713c23 006282b3 04813023 b102a283 04913423 00010593 06c13023 06d13423 06e13823 06f13c23 09013023 09113423 09213823 09313c23 0b413023 0b513423 0b613823 0b713c23 0d813023 0d913423 0da13823 0db13c23 0fc13023 0fd13423 0fe13823 0ff13c23 00113823 00013023 000280e7 00813083 01813183 02013203 02813283 03013303 03813383 04013403 04813483 05813583 06013603 06813683 07013703 07813783 08013803 08813883 09013903 09813983 0a013a03 0a813a83 0b013b03 0b813b83 0c013c03 0c813c83 0d013d03 0d813d83 0e013e03 0e813e83 0f013f03 0f813f83 00051863 05013503 01013103 10000073 05013503 01013103 30500073 78c0206f 0000a017 bbc00013 ff010113 00813023 00009417 3fc40413 00c42783 00113423 00079863 00008517 2e050513 68d000ef 050020ef 6d0020ef 0330000f 00100713 00009797 2a078793 00e7a023 04043783 34179073 10000073 00009717 28870713 00072783 fe078ee3 0330000f 00009797 3a078793 0407b783 34179073 10000073 fd010113 00913c23 01213823 01313423 00058913 00060993 00068493 12800613 00000593 02813023 02113423 00050413 35c020ef 02048863 100027f3 02813083 01343823 11243423 10f43023 01813483 02013403 01013903 00813983 03010113 00008067 00008517 25850513 5cd000ef fa010113 05213023 00050593 00050913 00000893 00000813 00000793 00000713 00000693 40000613 7db00513 04113c23 04813823 04913423 03313c23 03413823 03513423 03613023 01713c23 01813823 01913423 01a13023 2c8000ef 1c051c63 00093583 00008517 21850513 00100493 0bc010ef 00093783 00000413 00079663 0340006f 00070493 00341793 00f907b3 0087b603 00040593 00008517 1fc50513 08c010ef 00093783 0014041b 00148713 fcf4eae3 00008517 3e050513 070010ef 00093603 00100493 16c4f063 01093403 02d00793 00044703 14f71863 00144583 06d00c93 00048c13 00009b17 2bcb0b13 fffffbb7 07000d13 00009a97 2b4a8a93 07300993 00009a17 218a0a13 05958463 0cbcf463 0fa58663 0d359e63 069a3c23 001c069b 02069713 02075713 04c77c63 00371793 00f907b3 0087b403 02d00793 00044583 04f59063 00144583 00068c13 fd9590e3 00240513 330020ef 0e050263 01451793 0147d713 0aa77a63 001c069b 00093603 02069713 02075713 017b3023 fac768e3 020c1c13 020c5c13 05813083 003c1513 00a90533 40e60733 00e53423 05013403 00850513 04813483 04013903 03813983 03013a03 02813a83 02013b03 01813b83 01013c03 00813c83 00013d03 06010113 00008067 06300793 00f59c63 00100713 00009797 0a078793 00e7a023 f31ff06f 00008517 0b050513 3cd000ef 00240513 284020ef 0005051b 00aaa023 02050863 00093603 f09ff06f 00093603 00fb3023 efdff06f 00000c13 00048713 f55ff06f 00008517 04050513 058010ef 00144583 00008517 08050513 37d000ef bf010113 00053783 00009597 0c458593 00010713 40113423 40813023 00e5b823 40000713 00e5bc23 02078463 00050413 00853503 328000ef 00040513 c8dff0ef 40813083 40013403 41010113 00008067 00008517 05450513 321000ef fd010113 02813023 02051713 02059793 02113423 0330000f 02075713 0207d793 00200513 00010593 00010413 00013c23 00e13023 00f13423 00c13823 0900a0ef 00300513 0880a0ef fe050ce3 00a41e63 0330000f 02813083 01013503 02013403 03010113 00008067 00008517 00050513 779000ef fe010113 00050393 00058313 00113c23 00813823 00913423 00060293 00009597 e8058593 fff00513 0005a603 00009417 e7040413 fe061ae3 00050613 0cc4262f fe0614e3 00009497 a1848493 0330000f 00048613 00000593 00000513 0074b023 0064b423 0054b823 00d4bc23 02e4b023 02f4b423 0304b823 0314bc23 f11ff0ef 0004b503 0330000f 01813083 00042023 00813483 01013403 02010113 00008067 ff010113 00050593 00000893 00000813 00000793 00000713 00000693 00000613 05d00513 00113423 f39ff0ef 0000006f fb010113 03313423 01513c23 00050993 00060a93 01713423 01100613 00058b93 00008517 f1c50513 00008597 f0458593 04113423 03413023 01613823 01813023 00068b13 04813023 02913c23 03213823 4ed000ef 00008517 ee850513 01600613 00008597 ecc58593 4d5000ef 000b8713 000b0693 000a8613 00098593 00008517 ec850513 4b9000ef 00009797 d4c78793 0007b503 000b0693 000a8613 000b8593 464040ef 40000a13 000b8713 000b0693 000a8613 00098593 00008517 eb450513 47d000ef 000a8c1b 0b5a7263 000b0413 000a8493 000b8913 0240006f 40040413 00048613 00040593 00008517 ec450513 40090913 449000ef 049a7663 008985b3 40000613 00090513 c0048493 689010ef fc0506e3 00040593 00008517 e7c50513 40040413 419000ef 00048613 00040593 00008517 e7c50513 40090913 401000ef fa9a6ee3 bffa8793 00a7d793 00178713 00a79693 c00a8a93 400b0b13 00a71713 40da8ab3 01668b33 00eb8bb3 016985b3 000a8613 000b8513 55d010ef 00008517 e5850513 3b9000ef 04813083 000c0513 04013403 03813483 03013903 02813983 02013a03 01813a83 01013b03 00813b83 00013c03 05010113 00008067 f3010113 0c813023 00000613 00058413 00000593 0b313423 0b413023 0c113423 0a913c23 0b213823 09513c23 09613823 09713423 09813023 07913c23 07a13823 07b13423 00a13c23 00009997 bd098993 719010ef 00050a13 0009b023 74050a63 00008517 dc850513 319000ef 00000613 00000593 00008517 dcc50513 1bc040ef 00050793 00050593 00008517 de050513 00f9b023 2ed000ef 0009b703 fffff7b7 2af77263 000a0693 04700613 00008597 cc458593 00008517 e2c50513 2c5000ef 00000693 04000613 02010593 000a0513 d75ff0ef 00050493 04000613 00048593 00008517 d9850513 299000ef 02314683 02214603 02114583 00008517 da050513 281000ef 03f00793 2297de63 02012703 464c47b7 57f7879b 22f71663 00008797 68478793 02013703 0007b683 fff00793 0187d793 00f777b3 40d78733 00173713 00e42023 20d79e63 05815783 01843703 00379493 00679793 409784b3 1e976463 04013683 01043583 600a0463 00048613 000a0513 cd1ff0ef 1c954663 03813583 05815883 03800713 03f5d793 01142423 00e42223 01043503 00f42623 3a05d063 02043a83 fffa8a93 015ada93 001a8a93 015a9a93 03543023 64088c63 00050793 00000713 fff00b13 00100613 0100006f 0017071b 03878793 03175663 0007a683 fec698e3 0287b683 fe0684e3 0107b683 ff66f0e3 0017071b 00068b13 03878793 fd174ee3 3405dc63 015b5b13 02043a83 015b1b13 01613423 00813703 04b43023 40ea8ab3 3405da63 00008c37 012c0c1b 03543c23 01812823 fff88c1b fff00293 225c0863 01012703 000c0793 00379813 00679793 410787b3 02076713 00a78db3 00000913 00100d13 00028b13 00e12a23 0100006f fffc0c1b fc8d8d93 1f6c0c63 000da783 ffa798e3 028db783 fe0784e3 010db383 015384b3 009785b3 000017b7 fff78793 00f3fbb3 00b97463 00058913 00c42683 22069663 000b8463 000086b7 01012603 008db783 020db583 0009b703 41748cb3 00d666b3 417787b3 fff00613 00bb85b3 000c8513 66d000ef 04ac9c63 00000593 000b8613 279010ef 020db583 028db503 fff58593 017585b3 00c5d593 00158593 00c59593 417585b3 f4a5fce3 01412683 00b484b3 00000793 40b505b3 00000713 fff00613 00048513 619000ef f2a48ae3 00008517 b6c50513 035000ef 01813583 00008517 b6c50513 4c0000ef 00008717 44870713 00073703 fce79ce3 04c15483 01843783 00549493 fc97e4e3 03c16683 01043583 3c0a0c63 00048613 000a0513 ab1ff0ef fa9546e3 03812583 04c15883 02000713 01f5d79b 01142423 00e42223 01043803 00f42623 1805d863 02043a83 fffa8a93 015ada93 001a8a93 015a9a93 03543023 42088663 00080793 00000713 fff00513 00100613 0100006f 0017071b 02078793 03175663 0007a683 fec698e3 0147a683 fe0684e3 0087e683 fea6f0e3 0017071b 00068513 02078793 fd174ee3 00c55b13 00cb1b13 01613423 1605c663 03015703 00300793 34f70263 02059793 0207d793 00000a93 00813703 00fa87b3 04f43023 01570733 01200793 00e13423 03543c23 00f12823 1680006f 00000913 03843783 00813703 0009b503 fff7c793 012787b3 00c7d793 00178793 00c79793 05243423 02e43423 02f43823 361030ef 0c813083 0c013403 0b813483 0b013903 0a813983 0a013a03 09813a83 09013b03 08813b83 08013c03 07813c83 07013d03 06813d83 0d010113 00008067 41748cb3 000c8513 3e1000ef e4050ce3 008db683 020db603 2a0a0463 00048593 000a0513 941ff0ef 020da783 e2f54ce3 000b8613 00000593 000c8513 055010ef 020db783 028db603 00000593 00f48533 40f60633 03d010ef d3dff06f c80890e3 fffff7b7 00f13423 0200006f e80898e3 fffff637 00c13423 eddff06f 00cb5b13 00cb1b13 01613423 03015703 00300793 00000a93 20f70a63 00813783 015585b3 01200613 015787b3 04b43023 00f13423 03543c23 00c12823 ca1ff06f 01555b13 02043a83 015b1b13 01613423 00813603 02059793 0207d793 40ca8ab3 04f43023 e805d6e3 00008c37 012c0c1b 03543c23 01812823 fff88b1b fff00293 e85b0ae3 01012603 000b0793 00579793 02066613 01078c33 00000913 00100d93 00028d13 00c12a23 0100006f fffb0b1b fe0c0c13 e7ab02e3 000c2783 ffb798e3 014c2583 fe0584e3 008c2783 00001737 02059593 02079493 0204d493 fff7071b 0205d593 015484b3 00e7f7b3 02079b93 009585b3 020bdb93 00b97463 00058913 00c42683 08069a63 00078463 000086b7 01012603 004c6783 010c6583 0009b703 41748cb3 00d666b3 417787b3 fff00613 017585b3 000c8513 2c1000ef caac96e3 00000593 000b8613 6cc010ef 010c6583 014c6503 fff58593 017585b3 00c5d593 00158593 00c59593 417585b3 f4a5f0e3 01412683 00b484b3 00000793 40b505b3 00000713 fff00613 00048513 26d000ef f0a48ee3 c55ff06f 41748cb3 000c8513 1cd000ef c40502e3 004c6683 010c6603 080a0263 00048593 000a0513 f2cff0ef 010c2783 c2f542e3 000b8613 00000593 000c8513 640010ef 010c2603 014c2783 00000593 02061513 40c7863b 02055513 02061613 02065613 00950533 618010ef eadff06f 0009b503 00048613 3e1030ef c2dff06f 0009b503 00048613 3d1030ef 9fdff06f 02043a83 e29ff06f 02043a83 a8dff06f 0009b503 00048593 3b1030ef f81ff06f 0009b503 00048593 3a1030ef d5dff06f 01813503 00000613 00000593 27d030ef fffff7b7 00a9b023 b6f57ee3 00000693 04700613 00007597 59c58593 00007517 70450513 39c000ef 0009b503 00000693 04000613 02010593 351030ef 00050493 8d9ff06f ffe00737 00e13423 da1ff06f ffe00637 00c13423 a01ff06f fa010113 02810293 02b13423 00028593 00113c23 02c13823 02d13c23 04e13023 04f13423 05013823 05113c23 00513423 2e8000ef fff00513 dc0ff0ef 00064783 fb010113 04113423 04813023 02913c23 03213823 03313423 03413023 01513c23 01613823 01713423 2a078263 00100e13 00000713 00000293 00000813 02500493 01500413 00007e97 be8e8e93 00a00313 40ae0e33 fff00f93 02d00a13 00900f13 ffc00393 07800993 03000913 1e080063 f9d7879b 0ff7f893 1d146463 0ff7f793 00279793 01d787b3 0007a783 01d787b3 00078067 00100293 00160613 00064783 fc0796e3 0007079b 20b76463 00058663 00b50733 fe070fa3 04813083 00078513 04013403 03813483 03013903 02813983 02013a03 01813a83 01013b03 00813b83 05010113 00008067 1a028063 0006b883 00868693 1a08c063 0268c7b3 00100293 1c078263 0267c7b3 00128293 fe079ce3 fff2881b 02084863 00e807b3 00f507b3 00fe0ab3 00baf863 0268eab3 030a8a9b 01578023 fff8081b 0268c8b3 fff78793 fff810e3 00570733 00000813 00000293 f49ff06f 00170793 12b7f063 0006a803 00e50733 00868693 01070023 00000293 00078713 00000813 f21ff06f 0a029a63 0006ab03 00700b93 00868693 00e502b3 002b979b 00070813 00180813 00b87e63 40fb58b3 00f8f893 05788a9b 011f4463 03088a9b 01528023 ffc7879b 00128293 fc779ce3 00170713 00eb8733 00000293 00000813 ec5ff06f 0006b883 00e507b3 00868693 0008c803 02080063 00170713 00b77863 01078023 0018c803 00188893 00178793 fe0814e3 00000293 e8dff06f 00170793 00b7f663 00e50833 01280023 00270713 00b77663 00f507b3 01378023 0006bb03 00f00b93 00868693 f51ff06f 00007517 45450513 d79ff0ef 02978263 00170893 00b8fa63 00e50733 00f70023 00088713 e35ff06f 00088713 e2dff06f 00100813 e25ff06f 00078713 00000293 00000813 e15ff06f 0006a883 00868693 e608d4e3 00170793 411008b3 02b7f063 00e50733 01470023 00078713 e4dff06f 00e50733 00070023 e01ff06f 00078713 e39ff06f 00000813 e51ff06f 00000793 00000713 dd5ff06f ef010113 00058693 00050613 10000593 00010513 10113423 d0dff0ef 10000793 00a7f463 00078513 02051613 00010593 02065613 00008517 84850513 06d030ef 10813083 11010113 00008067 fa010113 02810293 02b13423 00028593 00113c23 02c13823 02d13c23 04e13023 04f13423 05013823 05113c23 00513423 f85ff0ef 01813083 06010113 00008067 fc010113 02913423 03213023 01313c23 01413823 01513423 01613023 02113c23 02813823 00050913 00053023 02050a93 00007a17 910a0a13 00400493 00007597 30458593 00000613 00007997 8d898993 02400b13 ffd4841b 02000693 00007517 2ec50513 f5dff0ef 00341793 00f98733 0014041b 00f907b3 00073583 0007b603 fc849ce3 0044849b 00a00693 00007517 2bc50513 f2dff0ef 01648c63 000ab603 000a3583 020a8a93 020a0a13 fa9ff06f 10093703 12092683 11093603 10893583 03813083 03013403 02813483 02013903 01813983 01013a03 00813a83 00013b03 00007517 27850513 04010113 ed5ff06f fb010113 02810293 02d13423 00028693 00113c23 02e13823 02f13c23 05013023 05113423 00513423 b81ff0ef 01813083 05010113 00008067 ff010113 00050593 00007517 25050513 00113423 b21ff0ef 00008697 f2868693 00008717 f1870713 0006b783 00073703 ff010113 00113423 00813023 04e78263 00008717 f0870713 00073403 00c79713 00001637 00870433 00178793 00040513 00000593 00f6b023 020010ef 00813083 00040513 00013403 01010113 00008067 00007517 2e850513 f79ff0ef fc010113 02813823 00008417 07440413 00043783 02913423 01313c23 02113c23 03213023 01413823 01513423 00050493 00058993 0a078263 01e00913 00a00a93 00c00a13 0124d433 1ff47413 00341413 00878433 00043503 00157793 06079063 08098e63 f29ff0ef 00c55513 00a51513 00156513 00a43023 00a55513 ff79091b 00c51793 fd4910e3 00c4d513 1ff57513 00351513 00a78533 03813083 03013403 02813483 02013903 01813983 01013a03 00813a83 04010113 00008067 01f57793 00fad7bb 0017f793 fa0798e3 00007517 23050513 ea1ff0ef eb5ff0ef 00008797 97478793 0007a703 00a43023 00050793 f40704e3 18051073 f41ff06f 00000513 f99ff06f fd010113 01313423 00c55993 00913c23 00c99493 01213823 00048513 00058913 00000593 02113423 02813023 01413023 ecdff0ef 00050c63 00053403 00050a13 00040663 00148793 0297f463 02813083 fff00513 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 00008717 e8870713 02073683 fcd4e8e3 06073703 fcf764e3 00147793 08079663 00a99993 01b9e793 00fa3023 101f8073 01043503 0e050663 00043683 00843603 01843783 00001737 00c68633 40960633 40d786b3 009686b3 08c76e63 00048593 400030ef 0ca05863 00001637 08c54e63 02042783 01043503 fff7879b 02f42023 06078e63 02442783 00b9e413 0027f713 00071463 0019e413 0047f793 00078463 00c46413 008a3023 03e91793 43f7d793 00a7f793 00497913 00178793 00090463 00c7e793 0087f433 f0f41ae3 101f8073 02813083 00000513 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 00070613 f65ff06f f80504e3 018030ef f81ff06f 00050793 40a6063b 00000593 00978533 571000ef f55ff06f 00001637 00000593 00048513 55d000ef f41ff06f 00007517 06c50513 cc5ff0ef fd010113 01213823 00b50933 02813023 01313423 02113423 00913c23 00050413 000019b7 05257463 00040513 00000593 d1dff0ef 00050493 01340433 02050663 00053783 0017f713 02078063 00071c63 0207a703 0107b683 fff7071b 02e7a023 02070663 0004b023 fd2460e3 101f8073 02813083 02013403 01813483 01013903 00813983 03010113 00008067 00068513 fc068ae3 745020ef 0004b023 fcdff06f 00b505b3 00050793 02a5e463 00008717 c9c70713 02073683 00000513 00d7ec63 06073503 00b535b3 0015c513 00008067 00000513 00008067 ff010113 00113423 00813023 00008717 b3470713 fff00693 00072783 00008417 b2440413 fe079ae3 00068793 0cf427af fe0794e3 0330000f d41ff0ef 0330000f 00813083 00042023 00013403 01010113 00008067 f9010113 05413023 fff58a13 03713423 00ca5a13 00068b93 0106f693 05213823 03513c23 01913c23 01a13823 06113423 06813023 04913c23 05313423 03613823 03813023 01b13423 00058913 00060a93 00070c93 00078d13 001a0a13 16068263 03451793 00050413 04078263 fff00513 06813083 06013403 05813483 05013903 04813983 04013a03 03813a83 03013b03 02813b83 02013c03 01813c83 01013d03 00813d83 07010113 00008067 00a587b3 faa7eee3 00008717 b6870713 02073683 fad566e3 06073703 faf762e3 00008b17 a18b0b13 000b3483 000a0a1b 16048663 0204a783 00001737 ff070713 00e48733 00078a63 02848493 f6e48ae3 0204a783 fe079ae3 000c8663 000c8513 579020ef 0084b023 0124b423 0194b823 01a4bc23 0344a023 0354a223 f40482e3 01240933 00040993 00001b37 01246a63 07c0006f 016989b3 009a3023 0329fc63 00100593 00098513 acdff0ef 00050a13 12050863 00053783 fc078ee3 00098513 000015b7 016989b3 d61ff0ef 009a3023 fd29e8e3 00007797 4f078793 0007a783 00040493 00078663 030b9793 0207d063 000019b7 000a8593 00048513 b7dff0ef 0e051663 013484b3 ff24e6e3 00040513 eb5ff06f 00008797 a5c78793 0607bb03 0507b483 00ca1c13 418b0b33 e89b6ae3 fffff9b7 013c0c33 00001db7 00000593 00048513 a31ff0ef 00050663 00053783 02079c63 009c0433 0084e863 0380006f 01340433 0284f863 00000593 00040513 a05ff0ef fe0506e3 00053783 fe0782e3 0084fa63 00040493 01b484b3 fa9b78e3 e31ff06f e20406e3 e89ff06f 00008997 8a498993 fff00693 0009a783 00008717 89470713 fe079ae3 00068793 0cf727af fe0794e3 0330000f 000b3783 02078663 0330000f 000b3483 0009a023 e59ff06f 00007517 cb050513 901ff0ef 00007517 cac50513 8f5ff0ef 909ff0ef 00008797 83c78793 00a7b023 fc9ff06f fe010113 03451793 00813823 00113c23 00913423 fea00413 06079063 00b507b3 fea00413 04a7ea63 00008717 93c70713 02073683 04d56263 06073703 02f76e63 00007797 7f478793 fff00693 0007a403 00007497 7e448493 fe041ae3 00068713 0ce4a72f fe0714e3 0330000f bb1ff0ef 0330000f 0004a023 01813083 00040513 00813483 01013403 02010113 00008067 fb010113 0026f813 02913c23 04113423 04813023 03213823 03313423 fea00493 02081263 04813083 00048513 04013403 03813483 03013903 02813983 05010113 00008067 fe0580e3 03479813 fc081ce3 00050913 0206f513 0a051063 00070513 00b13823 00c13423 00d13c23 00f13023 3e5020ef 00050993 ff700493 01013583 00813603 01813683 00013783 f8050ce3 00007417 71440413 fff00513 00042703 00007817 70480813 fe071ae3 00050713 0ce8272f fe0714e3 00098713 0330000f 00090513 bf5ff0ef 00008797 80c78793 0587b703 00e57463 04a7bc23 0330000f 00050493 00042023 f2098ee3 00098513 275020ef f31ff06f 00000993 f95ff06f fe010113 00913423 00007497 7cc48493 0484b783 01213023 00113c23 00813823 00078913 00f56863 0584b703 00050913 08a76663 0504b503 02051063 fff78513 00c55513 00150513 00c51513 00007797 78878793 04a7b823 fff90413 00c45413 00140413 00c41413 04a46e63 02856263 01813083 0484b823 00090513 01013403 00813483 00013903 02010113 00008067 00000793 00000713 03200693 fff00613 40a405b3 b15ff0ef 0504b783 fcf502e3 00007517 a7450513 e94ff0ef 00070913 f75ff06f 408505b3 00040513 9c1ff0ef 01813083 0484b823 00090513 01013403 00813483 00013903 02010113 00008067 ff010113 00113423 00813023 00007717 5a870713 fff00693 00072783 00007417 59840413 fe079ae3 00068793 0cf427af fe0794e3 0330000f ed9ff0ef 0330000f 00813083 00042023 00013403 01010113 00008067 fa800513 00008067 03451793 00078663 fea00513 00008067 fb010113 04813023 02913c23 03313423 04113423 03213823 03413023 01513c23 01613823 01713423 01813023 00050493 00060993 00007417 51440413 fff00693 00042783 00007717 50470713 fe079ae3 00068793 0cf727af fe0794e3 00b48933 0330000f 0f24f463 0000ac37 00009bb7 0029fa93 0049fb13 0a0c0c1b 880b8b9b 00001a37 01c0006f 0247a703 00e9e6b3 0ce69263 0337a223 014484b3 0b24f863 00000593 00048513 dd4ff0ef 06050263 00053783 04078e63 0017f713 fc0706e3 0007869b 020a8263 00dbd73b 00177713 08070263 c007f713 00b76713 000b1863 00e53023 fb5ff06f 060b0a63 00dc56bb 0016f693 06068063 c007f793 0017e713 060a9663 00c76713 00e53023 f8dff06f ff400513 0330000f 04813083 00042023 03813483 04013403 03013903 02813983 02013a03 01813a83 01013b03 00813b83 00013c03 05010113 00008067 00000513 fc5ff06f ff300513 fbdff06f c007f793 0017e713 00e53023 f31ff06f 00b7e713 00c76713 f95ff06f fff60613 00c65793 00178793 fc010113 00c79793 03213023 02113c23 02813823 02913423 01313c23 01413823 01513423 00a78933 04078c63 00050413 40a589b3 0026fa13 0046f493 00001ab7 00100593 00040513 cb0ff0ef 04050c63 008987b3 00c7d793 00a79793 00b7e713 000a1463 0017e713 00048463 00c76713 01076713 01540433 00e53023 fc8912e3 03813083 03013403 02813483 02013903 01813983 01013a03 00813a83 04010113 00008067 00006517 77050513 bc0ff0ef 00c55793 00c79793 00b505b3 00267613 00001737 00b7fa63 00061a63 0007a683 00e787b3 feb7eae3 00008067 0607a02f ff1ff06f 00007797 4a078793 0007a783 00007717 48c70713 00073683 00009717 ba770713 00c75713 00c7979b 00170713 02079793 00c71713 0207d793 00f707b3 00007617 3d460613 0146d713 00800593 02f63023 00b77463 00058713 00c71793 40f687b3 00007697 26068693 00e6b023 00007717 26470713 00f73023 04f63c23 06f63023 00008067 fc010113 01313c23 00007997 38498993 0289b683 0209b783 01413823 00007a17 3f8a0a13 000a3703 00d787b3 40f007b3 02113c23 02813823 02913423 03213023 01513423 01613023 000a0693 00f77463 00070793 0389b703 0309b483 00001b37 000b0613 00e484b3 ffe00737 00e7f7b3 00000593 00048513 00f6b023 310000ef 0289b603 01648433 00000593 fff64613 01e65613 00160a93 00ca9913 01690633 00040513 2e8000ef 20000693 415686b3 01240533 00c45793 00369693 00d506b3 00fa8633 00a79713 00176713 00178793 00e6b023 00868693 fec796e3 0289b783 0389b803 000a3703 002008b7 01078633 00e66663 0440006f 0289b783 410606b3 40f68733 0157d593 1ff5f693 01575793 00d787b3 00c65713 00379793 00a71713 00f407b3 01f76713 00e7b023 000a3783 01160633 fcf662e3 00009617 a0360613 0309b703 000017b7 00c65613 00f507b3 00160613 409787b3 00c61613 00e787b3 00c65613 02f9b823 02060863 20000693 40c686b3 00369693 009686b3 00000793 00a79713 01d76713 00178793 00e6b023 00868693 fef616e3 ff890913 01240433 00043783 06079663 00007797 09c78793 00c4d493 0007b783 00a49493 0014e493 00943023 04079c63 00007797 07478793 0007b023 00007797 23878793 0330000f 00a7b023 18051073 03813083 03013403 02813483 02013903 01813983 01013a03 00813a83 00013b03 04010113 00008067 00006517 53c50513 8ecff0ef 00006517 54050513 8e0ff0ef fe010113 00813823 00007417 15c40413 00042783 00113c23 00913423 00079e63 06043703 00100793 01f79793 00040693 0ce7e463 06e6b023 02043603 00700693 00000593 00000513 c1dff0ef 00007797 fd878793 0007b583 00007797 fbc78793 0007b603 00300693 00058513 00c61613 bf5ff0ef 00007797 17878793 0007b783 02000737 001004b7 00e7f863 00040737 000014b7 04e7fc63 06043503 00000793 00048593 40950533 00000713 03200693 00700613 c94ff0ef 00a484b3 fff00793 06a43423 06943823 02f50c63 828ff0ef 01813083 000017b7 00f50533 01013403 00813483 02010113 00008067 0117d493 00c49493 fa5ff06f 00078713 f39ff06f 00006517 44c50513 fd5fe0ef 00c5e7b3 00f567b3 0077f793 00c50633 02078263 00050793 02c57e63 00158593 fff5c703 00178793 fee78fa3 fec798e3 00008067 fec57ee3 00050793 00858593 ff85b703 00878793 fee7bc23 fec7e8e3 00008067 00008067 00c567b3 0077f793 02078263 00c50633 0ff5f593 00050793 04c57663 00178793 feb78fa3 fec79ce3 00008067 0ff5f593 00859793 00f5e5b3 01059793 00f5e5b3 02059793 00c50633 00f5e5b3 fcc57ee3 00050793 00878793 feb7bc23 fec7ece3 00008067 00008067 00800893 0ac8f863 00053283 0005b803 011507b3 01158733 fff00693 0702ec63 00100693 00587c63 06c0006f ff87b803 ff873683 06d86463 0706e863 ff860613 00878793 00870713 fec8e2e3 0005c883 00054803 00150793 00158713 fff00693 03186a63 00100693 0308e663 00c58633 0180006f 00170713 fff7c503 fff74683 00d56e63 02a6e263 00178793 fee614e3 00000693 00068513 00008067 fff00693 00068513 00008067 00100693 00068513 00008067 00000693 f8061ae3 fd9ff06f 00054783 00078e63 00050793 00178793 0007c703 fe071ce3 40a78533 00008067 00000513 00008067 00050793 00158593 fff5c703 00178793 fee78fa3 fe0718e3 00008067 00054783 02000713 00e79a63 00078713 00150513 00054783 fee78ce3 fd57871b 0fd77713 04070663 00054683 00000613 02068c63 00000793 00150513 fd06859b 00054683 00179713 00379793 00f707b3 00f587b3 fe0692e3 00078513 00060863 40f00533 00008067 00000513 00008067 00154683 fd37879b 0017b613 00150513 fa069ae3 00000793 fd1ff06f 00054783 02000713 00e79a63 00078713 00150513 00054783 fee78ce3 fd57871b 0fd77713 00000e93 00071863 fd37879b 0017be93 00150513 00054783 03000713 08e78463 00000693 00060293 00900893 00a00393 01900313 00c0006f 00e686b3 00054783 fd07871b 0ff77813 00078e63 025686b3 00150513 ff08f2e3 fbf7871b 0ff77713 00c3ce63 00058463 00a5b023 00068513 000e8463 40d00533 00008067 f9f7881b fc978e1b 0ff87813 fa97879b 00e36663 01c686b3 fa9ff06f fd0366e3 00f686b3 f9dff06f 00154783 07800693 02d78063 00e78663 00150513 f69ff06f 00254783 00800613 00250513 f59ff06f 00254783 01000613 00250513 f49ff06f 40500613 00005597 57458593 00006517 33c50513 3600206f 300026f3 34102773 000107b7 3007a2f3 00072603 3007b073 00028c63 00367793 00300813 03078863 fff00513 00008067 000017b7 ff878793 3007b073 34171073 00d7f733 30072073 34251073 fff00513 00008067 07c67793 00006817 91080813 010787b3 0007a283 00028067 ff010113 00113423 342025f3 34102673 00006517 08450513 f18fe0ef 00000793 781797f3 10078a63 ff010113 000016b7 fffff737 00d106b3 00e6f6b3 fc86b603 fff00713 00879313 01075713 0387d813 00e7f3b3 00113423 03835313 fc06b783 10060063 00007697 c2068693 0286b703 0386b583 00007697 c9868693 0006b283 00b705b3 00000693 00000513 00f00893 00b7e863 02078713 00577463 00f77a63 30002773 03077713 fd070713 0ce8e063 0007b703 00e80e63 00168693 0187b703 00078513 08d60e63 00070793 fc5ff06f 0087b703 fee312e3 0187b703 0077b823 06050063 00e53c23 00001737 00e106b3 fffff737 00e6f733 fd873683 fff60613 fcc73423 0007bc23 04068863 00f6bc23 00001737 00e106b3 fffff737 00e6f733 fcf73c23 344167f3 00813083 00000513 01010113 00008067 00000513 00008067 000016b7 00d105b3 fffff6b7 00d5f6b3 fce6b023 f95ff06f fcf73823 fb5ff06f 00006517 f7450513 dc8fe0ef 00006517 f5050513 dbcfe0ef 0885b783 fe010113 00700693 00813823 00113c23 00913423 00058413 0505b703 28f6e463 00005697 7e068693 00279793 00d787b3 0007a783 00d787b3 00078067 00100793 78079073 78079073 ff9ff06f 000017b7 00f10733 fffff7b7 00f777b3 fd07b783 22078c63 00001737 00e10733 fffff7b7 00f77733 fe470713 00000793 0cf727af 04f43823 341027f3 00478793 34179073 01813083 00000513 01013403 00813483 02010113 00008067 00007797 af078793 0007e683 fff00793 fcd774e3 000016b7 00d106b3 fffff7b7 00f6f6b3 fe06a783 40f707b3 00c79793 00d787b3 fe478793 00100693 0cd7a6af 00000793 f8069ae3 0330000f 78371073 f89ff06f 00000593 00000513 d9dff0ef 00001737 fffff7b7 00e10733 00f77733 fd073783 f60782e3 0187b683 fcd73823 f4069ce3 fc073c23 344176f3 0330000f fe472703 f40702e3 34416773 f3dff06f 00007697 9c068693 0286b783 0386b683 00d787b3 00f76c63 00007797 a3078793 0007b683 02070793 12d7ee63 300026f3 0306f693 fd068693 00f00613 ff200793 eed66ce3 00073583 00873783 01073603 1005b513 1007b693 00154513 0016c693 00d566b3 12069063 00100693 03069693 10d67a63 03859593 03079793 00f5e7b3 00c7e7b3 780796f3 fe069ee3 000016b7 fffff7b7 00d106b3 00f6f6b3 fc86b603 fc06b583 00000793 00160613 00b73c23 fce6b023 fcc6b423 e81ff06f 10100793 0ff77713 03079793 00f76733 780717f3 fe079ee3 00100493 781027f3 0387d713 02970063 fe078ae3 00000593 00000513 c69ff0ef 781027f3 0387d713 fe9714e3 00879793 0387d793 fe9790e3 00000793 78179073 00000793 e21ff06f 32171073 02000793 3447b7f3 08000793 3047a7f3 00000793 e05ff06f 000017b7 00f10733 fffff7b7 00f777b3 fe07a783 dedff06f 344177f3 0330000f dc5ff06f fa800793 dd9ff06f eee7f0e3 300026f3 0306f693 fd068693 00f00613 ff200793 dad66ee3 ec5ff06f fea00793 db1ff06f ff010113 00113423 00058813 34202573 341026f3 000017b7 00f10733 fffff7b7 00f777b3 ec078793 34079073 00500793 02f50463 02a7f063 00700793 00f50e63 00b00793 00f51863 00813083 01010113 cd9ff06f b5dff0ef 00006797 d2478793 00006597 da458593 00c0006f 00878793 feb7f2e3 0007a703 fee6eae3 0047a703 fee6f6e3 02083423 34171073 00813083 00000513 01010113 00008067 be010113 40113c23 2d1010ef 01010513 c6cfd0ef 00007797 80c78793 0007b783 02078863 00007797 80478793 0007a783 02078663 00a13423 b50ff0ef 00813503 e8cfd0ef 41813083 42010113 00008067 00006517 bb050513 9ecfe0ef 00006517 bcc50513 9e0fe0ef ff010113 000017b7 00f10733 fffff7b7 00f777b3 f00026f3 02d69593 00113423 fe07b023 fc07b023 fc07b423 fc07b823 fc07bc23 fea7a023 0e05dc63 0012f7b7 00050613 05678793 30079073 30002773 003e07b7 00f777b3 ffee0737 00e787b3 00020737 00e7e863 00006797 11c78793 0007a023 00000793 32179073 344477f3 304467f3 30002773 000037b7 00f777b3 0c078263 f0002773 00877713 00000793 02000693 0a070263 00000513 0037971b 00002597 00e585b3 fb4582e7 0017879b fed794e3 00000793 00379073 04060c63 00006797 6e078793 0007b703 00071663 0007b703 fe070ee3 0330000f 0007b783 18079073 000017b7 00f10733 fffff7b7 00f777b3 fe07a703 00006797 6b878793 0007a783 02f76463 10200073 10200073 ff9ff06f 00813083 01010113 e6dff06f 00006517 ab850513 8a4fe0ef 00813083 01010113 a38fd06f 00006517 ae050513 88cfe0ef 00006517 ab450513 d4cfe0ef fff00513 00008067 300023f3 34102873 00010337 300322f3 00082883 30033073 1a028663 00c8d69b 0f86f693 00d586b3 0006be03 00007737 00002637 07f7071b 4148d79b 00e8f733 0036051b 01c787b3 04a70663 000036b7 0036851b 08a70e63 00006537 0035051b 12a70063 0076851b 18a70063 0076061b 0ac70e63 000016b7 0036869b 20d70063 000056b7 0036869b fff00513 1cd70863 00008067 ffc7f713 00470693 300322f3 00072603 0006a503 30033073 0007879b 40f006bb 0036969b 0037979b 00d5173b 00f656bb 00d766b3 0012b293 16029863 0048d71b 0f877713 00e58733 00d73023 00480793 34179073 00000513 00008067 ff87f713 00870693 300322f3 00073603 0006b503 30033073 0007879b 40f006bb 0036969b 0037979b 00d51733 00f656b3 0012b293 00d766b3 fa5ff06f ffc7f613 00460513 300322f3 00062703 00052583 30033073 0007879b 40f0053b 0035151b 0037979b 00a5953b 00f757bb 00f56533 0c028e63 0048d71b 0f877713 00002797 00e787b3 d90782e7 3006a6f3 f65ff06f ffc7f713 00470693 300322f3 00076603 0006e503 30033073 0007879b 40f006bb 0036969b 0037979b 00d5173b 00f656bb 00d766b3 02069693 0012b293 0206d693 f0dff06f 000017b7 ff878793 3007b073 34181073 0077f7b3 3007a073 34251073 fff00513 00008067 ff87f613 00860513 300322f3 00063703 00053583 30033073 0007879b 40f0053b 0035151b 0037979b 00a59533 00f757b3 00f56533 02028063 0048d71b 0f877713 00002797 00e787b3 ed4782e7 3006a6f3 ea9ff06f 000017b7 ff878793 3007b073 34181073 0077f833 30082073 fff00513 00008067 300322f3 0007c603 0017c683 30033073 00869693 0012b293 00c6e6b3 e55ff06f 300322f3 0007c603 00178683 30033073 00869693 0012b293 00c6e6b3 e35ff06f 30002e73 34102673 00010337 300322f3 00062803 30033073 14028c63 00c8589b 0f88f893 00b888b3 0118551b 4198571b 0078569b 0008b783 0f857893 0057139b 02089e93 01f6f713 000076b7 00e3e733 020ede93 000023b7 07f6869b 01d585b3 00d876b3 0233881b 00f707b3 0005b503 0b068a63 00003737 0237059b 02b68c63 000015b7 0235859b 0cb68663 0277071b 00e68a63 0273839b fff00513 06768c63 00008067 000e8513 00002717 00a70733 cb8702e7 00010737 300722f3 00a78023 00855513 00a780a3 00855513 00a78123 00855513 00a781a3 00855513 00a78223 00855513 00a782a3 00855513 00a78323 00855513 00a783a3 30073073 0012b293 08029a63 00460793 34179073 00000513 00008067 00088513 00002717 00a70733 a48702e7 00010737 300722f3 00a78023 00855513 00a780a3 00855513 00a78123 00855513 00a781a3 30073073 0012b293 fb1ff06f 300322f3 00a78023 00855513 00a780a3 30033073 0012b293 f95ff06f 000017b7 ff878793 3007b073 34161073 01c7f7b3 3007a073 34251073 fff00513 00008067 000017b7 ff878793 3007b073 34161073 01c7f633 30062073 fff00513 00008067 00c6579b 0f87f793 00f587b3 0007b883 00007837 4146579b 011787b3 01067833 000028b7 07180863 000038b7 05181463 0077f893 0a089663 000105b7 3005a2f3 0007b503 3005b073 02028663 0046561b 0f867613 00002797 00c787b3 c58782e7 30082873 00470713 34171073 00000513 00008067 000017b7 ff878793 3007b073 34171073 00d7f6b3 3006a073 fff00513 00008067 0037f813 04081463 000105b7 3005a2f3 0007a503 3005b073 fc0284e3 0046561b 0005051b 0f867613 00002797 00c787b3 9f0782e7 000037b7 3007a7f3 00470713 34171073 00000513 00008067 ad1ff06f 00c6579b 0f87f893 011588b3 0008b883 4196579b 0076581b 01f87813 0057979b 0107e7b3 00007837 011787b3 01067833 000028b7 07180863 000038b7 05181463 0077f813 08081a63 0116551b 0f857513 00002617 00a60633 a78602e7 00010637 300622f3 00a7b023 30063073 0012b293 00029a63 00470713 34171073 00000513 00008067 000017b7 ff878793 3007b073 34171073 00d7f733 30072073 fff00513 00008067 0037f813 02081863 0116551b 0f857513 00002617 00a60633 814602e7 00010637 300622f3 00a7a023 30063073 0012b293 f9dff06f c91ff06f 00c6569b 0116579b 0f86f693 0f87f793 00d58533 00f586b3 fe0077b7 07f7879b 0006b883 020006b7 00f677b3 0336869b 00053803 06d78063 020046b7 0336869b 06d78c63 020056b7 0336869b 06d78a63 020066b7 0336869b 06d78c63 020076b7 0336869b 06d78263 020016b7 0336869b 06d78463 020036b7 0336869b 06d78a63 020026b7 0336869b fff00513 04d78c63 00008067 03180833 0046561b 0f867613 00c58633 01063023 00470713 34171073 00000513 00008067 03184833 fddff06f 03185833 fd5ff06f 03187833 fcdff06f 03186833 fc5ff06f 031818b3 00088813 fb9ff06f 031828b3 00088813 fadff06f 031838b3 00088813 fa1ff06f 00c6569b 0116579b 0f86f693 0f87f793 00d58533 00f586b3 fe0077b7 07f7879b 0006a883 020006b7 00f677b3 03b6869b 00052803 02d78e63 020046b7 0336869b 04d78a63 020056b7 0336869b 04d78863 020066b7 0336869b 04d78663 020076b7 0336869b fff00513 04d78263 00008067 0318083b 0046561b 0f867613 00c58633 01063023 00470713 34171073 00000513 00008067 0318483b fddff06f 0318583b fd5ff06f 0318683b fcdff06f 0318783b fc5ff06f 0146581b 00200793 08f80263 00300793 06f80263 00100793 00f80663 fff00513 00008067 000037b7 00f6f6b3 fff00513 04068063 001022f3 00c6579b 0077f693 00005897 ae088893 00269693 011686b3 0006a503 0f87f793 00f6569b 00f587b3 01150533 01f6f693 0007b783 00050067 00008067 000037b7 00f6f6b3 fff00513 fe0688e3 003022f3 fb1ff06f 000037b7 00f6f6b3 fff00513 fc068ce3 002022f3 f99ff06f 00068793 00200693 06d80063 00300693 06d80063 00100693 f6d810e3 00179073 0100006f 00068793 0057e7b3 fc069ce3 0046561b 0f867613 00c585b3 0055b023 00470713 34171073 00000513 00008067 fff7c793 0057f7b3 fd5ff06f fff6c793 0057f7b3 fc9ff06f 00279073 fc5ff06f 00379073 fbdff06f 000037b7 00f6f7b3 04078063 0196579b 00005817 a1480813 07c7f793 010787b3 0007a283 00202273 000077b7 00f67833 00f81463 00028067 00c6579b 0077f793 00400813 00f87663 fff00513 00008067 02079213 02025213 fddff06f 0196569b fe010113 0036f693 00113c23 00068e63 00100593 fff00513 08b68863 01813083 02010113 00008067 00c6551b 0116569b 0007859b 0f857513 00001797 00a787b3 488782e7 00050793 0f86f513 00001697 00a686b3 474682e7 00b545b3 00078513 00c13423 00e13023 059010ef 00813603 0046561b 0f867613 00001797 00c787b3 548782e7 000037b7 3007a7f3 00013703 00470713 34171073 01813083 00000513 02010113 00008067 00c6551b 0116569b 02079593 0f857513 00001797 00a787b3 608782e7 00050793 0f86f513 00001697 00a686b3 5f4682e7 00a5c5b3 00078513 00c13423 00e13023 7b1010ef 00813603 0046561b 0f867613 00001797 00c787b3 6c8782e7 000037b7 3007a7f3 00013703 f81ff06f 00000793 ee5ff06f 800007b7 eddff06f 0196579b fe010113 0037f793 00113c23 00078e63 00100693 fff00513 08d78663 01813083 02010113 00008067 00c6551b 0116569b 0f857513 00001797 00a787b3 364782e7 00050793 0f86f513 00001697 00a686b3 350682e7 00050593 00078513 00c13423 00e13023 335010ef 00813603 0046561b 0f867613 00001797 00c787b3 424782e7 000037b7 3007a7f3 00013703 00470713 34171073 01813083 00000513 02010113 00008067 00c6551b 0116569b 0f857513 00001797 00a787b3 4e8782e7 00050793 0f86f513 00001697 00a686b3 4d4682e7 00050593 00078513 00c13423 00e13023 320020ef 00813603 0046561b 0f867613 00001797 00c787b3 5a8782e7 000037b7 3007a7f3 00013703 f85ff06f 0196579b fe010113 0037f793 00113c23 00078e63 00100693 fff00513 08d78663 01813083 02010113 00008067 00c6551b 0116569b 0f857513 00001797 00a787b3 254782e7 00050793 0f86f513 00001697 00a686b3 240682e7 00050593 00078513 00c13423 00e13023 64c010ef 00813603 0046561b 0f867613 00001797 00c787b3 314782e7 000037b7 3007a7f3 00013703 00470713 34171073 01813083 00000513 02010113 00008067 00c6551b 0116569b 0f857513 00001797 00a787b3 3d8782e7 00050793 0f86f513 00001697 00a686b3 3c4682e7 00050593 00078513 00c13423 00e13023 5a5010ef 00813603 0046561b 0f867613 00001797 00c787b3 498782e7 000037b7 3007a7f3 00013703 f85ff06f 0146579b 01f7f793 fff00513 00078463 00008067 0196579b fe010113 0037f793 00813823 00913423 00113c23 00070413 00060493 02078063 00100693 04d78e63 01813083 01013403 00813483 02010113 00008067 00c6551b 0f857513 00001797 00a787b3 120782e7 2a9010ef 0044d61b 0f867613 00001797 00c787b3 208782e7 000037b7 3007a7f3 00440713 34171073 00000513 fadff06f 00c6551b 0f857513 00001797 00a787b3 2dc782e7 2e0020ef 0044d61b 0f867613 00001797 00c787b3 3c4782e7 000037b7 3007a7f3 fbdff06f 00c6551b 00757793 00200593 fff00693 00f5d663 00068513 00008067 0196559b 0035f593 08059463 0116581b 0f857513 00001697 00a686b3 07c682e7 00050593 01f5569b 0f887513 4017d81b 00001897 00a888b3 060882e7 01f5551b 00d876b3 00f547b3 80000537 00d7c7b3 fff54513 01f7979b 00a5f533 0046561b 00a7e533 0f867613 00001797 00c787b3 128782e7 000037b7 3007a7f3 00470713 34171073 00000693 00068513 00008067 00100813 f70592e3 0116589b 0f857513 00001597 00a585b3 1f0582e7 00050813 03f55593 0f88f513 0017d89b 00001317 00a30333 1d4302e7 03f55513 00b8f5b3 00f547b3 00b7c7b3 0016d693 03f79513 00d876b3 0046561b 00d56533 0f867613 00001797 00c787b3 2a0782e7 000037b7 3007a7f3 f79ff06f 00c6569b 0076f793 00100593 fff00513 00f5d463 00008067 fd010113 02813023 00060413 0196561b 00367613 00913c23 02113423 01213823 01313423 00070493 08061263 0114571b 0f86f513 00001697 00a686b3 f3c682e7 00050913 0f877513 00001717 00a70733 f28702e7 00050993 06079a63 00090513 00098593 640010ef 00051a63 0019979b ff000737 00f76463 00098913 0044561b 00090513 0f867613 00001797 00c787b3 fe8782e7 000037b7 3007a7f3 00448713 34171073 00000513 0080006f 02b60463 02813083 02013403 01813483 01013903 00813983 03010113 00008067 00090593 f95ff06f 0114571b 0f86f513 00001697 00a686b3 094682e7 00050913 00070513 0f857513 00090593 00001717 00a70733 078702e7 00050993 00079663 00090513 00098593 5dd010ef 00051c63 fff00793 00199713 03579793 00e7e463 00098913 0044561b 00090513 0f867613 00001797 00c787b3 134782e7 000037b7 3007a7f3 f4dff06f 0196579b fe010113 0146569b 0037f793 00113c23 01f6f693 fff00513 00079c63 00100793 06f68263 01813083 02010113 00008067 00100593 feb798e3 fe0696e3 00c6551b 00c13423 00e13023 0f857513 00001797 00a787b3 dcc782e7 0c5010ef 00813603 0046561b 0f867613 00001797 00c787b3 0b0782e7 000037b7 3007a7f3 00013703 0480006f 00c6551b 00c13423 00e13023 0f857513 00001797 00a787b3 f84782e7 13c020ef 00813603 0046561b 0f867613 00001797 00c787b3 e68782e7 000037b7 3007a7f3 00013703 00470713 34171073 00000513 f51ff06f fd010113 02813023 0196541b 00347413 00100793 02113423 00913c23 01213823 01313423 fff00513 0287f063 02813083 02013403 01813483 01013903 00813983 03010113 00008067 00c6569b 0f86f693 00070913 0146571b 00d585b3 01f77713 00060493 0005b683 0cf70463 0a070663 00200793 08f70063 00300793 faf718e3 00068513 02d030ef 04040463 0044d61b 0f867613 00001797 00c787b3 fac782e7 000037b7 3007a7f3 00490913 34191073 02813083 00000513 02013403 01813483 01013903 00813983 03010113 00008067 034020ef 0044d61b 0f867613 00001797 00c787b3 d64782e7 000037b7 3007a7f3 fb9ff06f 03f6d993 0406c263 00068513 7b0030ef f80982e3 fff00793 03f79793 00f54533 f75ff06f 0006879b 01f7d99b 00078693 fc07dce3 40f006bb fd1ff06f 02069693 0206d693 f49ff06f 40d006b3 fbdff06f fc010113 02813823 0146541b 01f47413 00300793 02113c23 02913423 03213023 01313c23 01413823 01513423 fff00513 0287d463 03813083 03013403 02813483 02013903 01813983 01013a03 00813a83 04010113 00008067 0196579b 0037f793 00070913 00058993 00060493 08078863 00100713 fce790e3 00c6551b 0f857513 00001797 00a787b3 d7c782e7 08054663 00100613 00020593 7f9010ef 00200793 0cf40a63 00300713 00050793 02e40463 00100793 0af40463 80000737 fff74713 0005079b 00070693 00a6f663 001867f3 00070793 00003737 30072773 0044d59b 0f85f593 00b985b3 00f5b023 00490713 34171073 00000513 f3dff06f 00c6551b 0f857513 00001797 00a787b3 af8782e7 5f0010ef f79ff06f fff00a93 03fa9a13 00100613 00020593 01454533 765010ef 00200793 04f40a63 00300793 06f40663 00100793 04f40a63 00100713 01f71713 40a007bb 00070693 f71ff06f fff00793 0207d793 00078713 00070693 00f577b3 f59ff06f fff00713 00175713 00050793 00070693 f45ff06f 000a0713 40a007b3 000a0693 f35ff06f 020ad713 00000693 00000793 f25ff06f 000a8713 00000693 00000793 f15ff06f fc010113 00c6579b 02913423 00200693 0077f493 02113c23 02813823 03213023 01313c23 01413823 01513423 fff00513 0296d463 03813083 03013403 02813483 02013903 01813983 01013a03 00813a83 04010113 00008067 0196569b 0036f693 00070993 00058913 00060413 06069263 0116571b 0f87f513 00001797 00a787b3 9cc782e7 00050a13 0f877513 00001797 00a787b3 9b8782e7 00100793 00050a93 06f49e63 000a8593 000a0513 038010ef 0044561b 0f867613 00c905b3 00a5b023 00498713 34171073 00000513 f69ff06f 00100713 f6e690e3 0116571b 0f87f513 00001797 00a787b3 b64782e7 00050a13 00070513 0f857513 00001797 00a787b3 b4c782e7 00050a93 02d49863 000a8593 000a0513 01d010ef f99ff06f 00050593 000a0513 711000ef f80494e3 f6050ce3 00100513 f7dff06f 00050593 000a0513 720010ef f60496e3 fc0502e3 00100513 f61ff06f fff077b7 07f7879b e00006b7 00f677b3 0536869b 00d78c63 e20006b7 0536869b fff00513 02d78e63 00008067 00c6551b 0f857513 00001797 00a787b3 8bc782e7 0046561b 0f867613 00c58633 00a63023 00470713 34171073 00000513 00008067 00c6551b 0f857513 00001797 00a787b3 a88782e7 fcdff06f 00c6579b 0f87f793 00f585b3 fff077b7 07f7879b f00006b7 00f677b3 0536869b 0005b583 00d78c63 f20006b7 0536869b fff00513 02d78c63 00008067 0046561b 0005851b 0f867613 00001797 00c787b3 930782e7 000037b7 3007a7f3 00470713 34171073 00000513 00008067 0046561b 00058513 0f867613 00001797 00c787b3 b00782e7 000037b7 3007a7f3 fd1ff06f 000037b7 fe010113 00f6f6b3 00113c23 00813823 00913423 02068a63 00202273 000077b7 00f676b3 0cf69463 00070493 00060413 00050813 0196579b 0037f793 02078263 00100693 0cd78263 01813083 fff00513 01013403 00813483 02010113 00008067 0116569b 0186579b 00c6551b 0f857513 00000617 00a60633 774602e7 00050593 0f86f513 00000697 00a686b3 760682e7 00050613 0f87f513 00000797 00a787b3 74c782e7 00050693 00080513 20c020ef 0044561b 0f867613 00001717 00c70733 82c702e7 000037b7 3007a7f3 00448713 34171073 01813083 00000513 01013403 00813483 02010113 00008067 00c6579b 0077f793 00400693 f4f6e8e3 02079213 02025213 f25ff06f 0116569b 0186579b 00c6551b 0f857513 00001617 00a60633 8cc602e7 00050593 0f86f513 00001697 00a686b3 8b8682e7 00050613 0f87f513 00001797 00a787b3 8a4782e7 00050693 00080513 4c4020ef 0044579b 0f87f793 00001717 00f70733 984702e7 000037b7 3007a7f3 f59ff06f 00000513 e81ff06f 00100513 e79ff06f 00300513 e71ff06f 00200513 e69ff06f 00050663 fff00513 00008067 00005797 e0c78793 0207b703 00005797 e8878793 0007b783 00e5b023 40e787b3 00f5b423 00008067 00004517 41450513 00200693 00005717 80870713 00c0006f 00850513 02e50463 00452783 fe079ae3 00450593 1605a7af 00079663 1ed5a62f fe061ae3 fc079ee3 00008067 00000513 00008067 00100713 00450513 06e527af 00078463 00008067 ff010113 00004517 2a850513 00113423 cedfc0ef fff00793 00450693 06f6a72f 00200793 00f70463 00008067 00052583 00000893 0330000f 00000813 00052223 00000793 00000713 00000693 00000613 03900513 d35fb06f ff010113 00813023 00113423 00004797 7c078793 00000413 08000693 0100006f 0014041b 00878793 02d40863 1607b72f 00071663 1ea7b62f fe061ae3 fe0712e3 f55ff0ef 00813083 00040513 00013403 01010113 00008067 00813083 fff00513 00013403 01010113 00008067 fe010113 00813823 00913423 00113c23 00000413 00300493 ec5ff0ef 00852023 0014041b f71ff0ef fe9418e3 01813083 01013403 00813483 02010113 00008067 07f00793 04a7ea63 00351513 00004797 71478793 00a78533 00053503 02051463 0380006f 00450593 1605a72f 00f71663 1ec5a82f fe081ae3 02071793 0207d793 02f68063 00452783 02079693 0206d693 0017861b fc0698e3 00000513 00008067 00008067 fd010113 00913c23 01213823 01313423 01413023 02113423 02813023 00050913 00058493 00060993 00068a13 e0dff0ef 06050263 00050413 00048513 d09fd0ef 00150693 00048613 00000893 00000813 000a0793 00098713 00090593 03800513 bc1fb0ef 00050493 04054863 02813083 00a42023 01813483 00040513 01013903 02013403 00813983 00013a03 03010113 00008067 02813083 ff400513 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 00040513 df1ff0ef 02813083 00048513 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 00060693 00058613 00050593 f9c00513 f0dff06f fe010113 00813823 00113c23 00913423 01213023 00050413 e8dff0ef 04050a63 00004797 5a478793 00341413 00050493 00878433 1604392f 00a91663 1e0437af fe079ae3 d71ff0ef 03249463 00048513 d65ff0ef 01813083 00000513 01013403 00813483 00013903 02010113 00008067 01813083 fff00513 01013403 00813483 00013903 02010113 00008067 fe010113 00813823 00913423 00058413 00060493 01213023 00048593 00050913 00200613 00040513 00113c23 e28fd0ef 00092583 00048693 00040613 00000893 00000813 00000793 00000713 03f00513 a4dfb0ef 01813083 0005051b 01013403 00813483 00013903 02010113 00008067 fd010113 02813023 00913c23 00058413 00060493 01313423 07e00613 00050993 00004597 f4058593 00004517 a1050513 02113423 01213823 00068913 ffcfc0ef 00048593 00040513 00200613 d98fd0ef 0009a583 00090713 00048693 00040613 00000893 00000813 00000793 04300513 9bdfb0ef 02813083 0005051b 02013403 01813483 01013903 00813983 03010113 00008067 fe010113 00813823 00913423 00058413 00060493 01213023 00048593 00050913 00100613 00040513 00113c23 d24fd0ef 00092583 00048693 00040613 00000893 00000813 00000793 00000713 04000513 949fb0ef 01813083 0005051b 01013403 00813483 00013903 02010113 00008067 fd010113 02813023 00913c23 00058413 00060493 01313423 00048593 00050993 00100613 00040513 02113423 01213823 00068913 cacfd0ef 0009a583 00090713 00048693 00040613 00000893 00000813 00000793 04400513 8d1fb0ef 02813083 0005051b 02013403 01813483 01013903 00813983 03010113 00008067 fe010113 00813823 00058413 00913423 00200613 00050493 08000593 00040513 00113c23 c40fd0ef 0004a583 00040613 00000893 00000813 00000793 00000713 00000693 05000513 865fb0ef 01813083 0005051b 01013403 00813483 02010113 00008067 00058613 00052583 ff010113 00000893 00000813 00000793 00000713 00000693 02e00513 00113423 821fb0ef 00813083 0005051b 01010113 00008067 00060693 00058613 00052583 ff010113 00000893 00000813 00000793 00000713 03e00513 00113423 fe4fb0ef 00813083 0005051b 01010113 00008067 e0000553 00028067 e0008553 00028067 e0010553 00028067 e0018553 00028067 e0020553 00028067 e0028553 00028067 e0030553 00028067 e0038553 00028067 e0040553 00028067 e0048553 00028067 e0050553 00028067 e0058553 00028067 e0060553 00028067 e0068553 00028067 e0070553 00028067 e0078553 00028067 e0080553 00028067 e0088553 00028067 e0090553 00028067 e0098553 00028067 e00a0553 00028067 e00a8553 00028067 e00b0553 00028067 e00b8553 00028067 e00c0553 00028067 e00c8553 00028067 e00d0553 00028067 e00d8553 00028067 e00e0553 00028067 e00e8553 00028067 e00f0553 00028067 e00f8553 00028067 f0050053 00028067 f00500d3 00028067 f0050153 00028067 f00501d3 00028067 f0050253 00028067 f00502d3 00028067 f0050353 00028067 f00503d3 00028067 f0050453 00028067 f00504d3 00028067 f0050553 00028067 f00505d3 00028067 f0050653 00028067 f00506d3 00028067 f0050753 00028067 f00507d3 00028067 f0050853 00028067 f00508d3 00028067 f0050953 00028067 f00509d3 00028067 f0050a53 00028067 f0050ad3 00028067 f0050b53 00028067 f0050bd3 00028067 f0050c53 00028067 f0050cd3 00028067 f0050d53 00028067 f0050dd3 00028067 f0050e53 00028067 f0050ed3 00028067 f0050f53 00028067 f0050fd3 00028067 e2000553 00028067 e2008553 00028067 e2010553 00028067 e2018553 00028067 e2020553 00028067 e2028553 00028067 e2030553 00028067 e2038553 00028067 e2040553 00028067 e2048553 00028067 e2050553 00028067 e2058553 00028067 e2060553 00028067 e2068553 00028067 e2070553 00028067 e2078553 00028067 e2080553 00028067 e2088553 00028067 e2090553 00028067 e2098553 00028067 e20a0553 00028067 e20a8553 00028067 e20b0553 00028067 e20b8553 00028067 e20c0553 00028067 e20c8553 00028067 e20d0553 00028067 e20d8553 00028067 e20e0553 00028067 e20e8553 00028067 e20f0553 00028067 e20f8553 00028067 f2050053 00028067 f20500d3 00028067 f2050153 00028067 f20501d3 00028067 f2050253 00028067 f20502d3 00028067 f2050353 00028067 f20503d3 00028067 f2050453 00028067 f20504d3 00028067 f2050553 00028067 f20505d3 00028067 f2050653 00028067 f20506d3 00028067 f2050753 00028067 f20507d3 00028067 f2050853 00028067 f20508d3 00028067 f2050953 00028067 f20509d3 00028067 f2050a53 00028067 f2050ad3 00028067 f2050b53 00028067 f2050bd3 00028067 f2050c53 00028067 f2050cd3 00028067 f2050d53 00028067 f2050dd3 00028067 f2050e53 00028067 f2050ed3 00028067 f2050f53 00028067 f2050fd3 00028067 01f5561b 0ff67613 01f5d79b 00002297 42828293 00f60463 00028067 00001297 15c28293 00028067 fc010113 02813823 00a5c733 0175541b 008007b7 fff7879b 02913423 01f7571b 0175d49b 0ff00693 0ff47413 03213023 01313c23 01413823 02113c23 00f57933 00d4f4b3 00f5fa33 0ff77993 10d40463 12d48c63 04049463 020a1a63 01246433 16041063 001867f3 03813083 fff00513 03013403 02813483 02013903 01813983 01013a03 04010113 00008067 000a0513 625010ef 0005049b 42055a13 02041e63 02091463 03813083 01f9951b 03013403 02813483 02013903 01813983 01013a03 04010113 00008067 00090513 5e9010ef 0005041b 42055913 00800537 00a96933 00aa67b3 0089171b 0087979b 409405bb 0079191b 0af77c63 07d5859b 02079793 02091913 0207d793 02f95733 0007061b 03f67693 00069e63 02071713 02075713 02f707b3 41278933 01203933 01266633 00098513 03813083 03013403 02813483 02013903 01813983 01013a03 04010113 5e50106f 02091c63 06848063 03813083 01f9971b 7f8009b7 0137053b 03013403 02813483 02013903 01813983 01013a03 04010113 00008067 f00a0ee3 03813083 03013403 02813483 02013903 01813983 01013a03 04010113 6900206f 07e5859b 0019591b f49ff06f ea0a06e3 fd1ff06f 001467f3 f99ff06f 0175579b 0ff7f793 0ff00713 02e78863 0175d79b 0ff7f793 0ff00713 04e78a63 00100793 00b50863 00b56533 0015151b 00153793 00078513 00008067 02951713 fc0708e3 0165579b 1ff7f793 1fe00713 02e78c63 0165d79b 1ff7f793 1fe00713 04e78063 00000793 00078513 00008067 02959793 fa0786e3 0165579b 1ff7f793 1fe00713 fce798e3 02a51713 fc0704e3 001867f3 00000793 00078513 00008067 02a59713 00000793 f80706e3 fe5ff06f 0175571b 0ff77713 0ff00693 00050793 02d70863 0175d71b 0ff77713 0ff00693 02d70a63 01f7d51b 0ff57713 01f5d69b 00000513 02d70e63 0407c663 00008067 02979713 fc0708e3 001867f3 00000513 00008067 02959713 fe0718e3 01f7d51b 0ff57713 01f5d69b 00000513 fcd716e3 fcb786e3 00b7b7b3 40e7853b 00a03533 00008067 00b7e7b3 0017951b 00a03533 00008067 0175571b 0ff77713 0ff00693 00050793 02d70863 0175d71b 0ff77713 0ff00693 06d70063 01f7d51b 0ff57713 01f5d69b 00000513 06d70463 0607cc63 00008067 02979713 fc0708e3 0167d71b 1ff77713 1fe00693 06d70663 0165d79b 1ff7f793 1fe00713 00000513 fce79ae3 02a59793 fc0786e3 001867f3 00000513 00008067 02959713 fa0700e3 0167d71b 1ff77713 1fe00693 fcd712e3 0280006f fab780e3 00b7b7b3 40e7853b 00a03533 00008067 00b7e7b3 0017951b 00a03533 00008067 02a79713 fa0718e3 f91ff06f fc010113 03213023 00a5c733 0175591b 008007b7 fff7879b 01313c23 01f7571b 0175d99b 0ff00693 0ff97913 02813823 02913423 01413823 02113c23 00f57a33 00d9f9b3 00f5f433 0ff77493 04d90863 0ad98463 02090863 0c099663 0a041c63 01f4951b 03813083 03013403 02813483 02013903 01813983 01013a03 04010113 00008067 fc0a0ee3 000a0513 251010ef 0005091b 42055a13 fc1ff06f 020a1e63 03298a63 0089e7b3 04079e63 001867f3 03813083 fff00513 03013403 02813483 02013903 01813983 01013a03 04010113 00008067 fc0408e3 03813083 03013403 02813483 02013903 01813983 01013a03 04010113 36c0206f 014967b3 fc041ee3 fa0786e3 01f4971b 7f8004b7 0097053b f55ff06f 00040513 1c5010ef 0005099b 42055413 008007b7 00fa6a33 00f46533 007a1a1b 0085151b 020a1a13 02051513 020a5a13 02055513 02aa0533 02000593 0139093b 69d010ef 0005061b 400007b7 f819059b 00f67663 f809059b 0016161b 00048513 03813083 03013403 02813483 02013903 01813983 01013a03 04010113 1cd0106f fd010113 02813023 0175541b 00913c23 0ff47493 00800437 fff4041b 0ff00713 02113423 01213823 00857433 0ee48063 10054263 02049863 00041e63 02813083 02013403 01813483 01013903 03010113 00008067 00040513 0f1010ef 0005049b 42055413 008007b7 00f46433 0084141b 00040593 00048513 7c1000ef f814891b 0025051b 4019591b 07f57713 00500793 07e9091b 04e7e863 00100793 0ca7f463 02051713 02075713 02e70733 00f4f4b3 0094543b 02041413 40e40733 02075063 fff5051b 02051793 0207d793 00179793 0017e793 00f70733 fe0744e3 00e03733 00e56533 569010ef 00050613 00090593 02813083 02013403 01813483 01013903 00000513 03010113 0c10106f 02041e63 f20556e3 001867f3 fff00513 02813083 02013403 01813483 01013903 03010113 00008067 0084e433 f00402e3 001867f3 fff00513 fd9ff06f 02813083 02013403 01813483 01013903 00000593 03010113 16c0206f 80000637 fff64613 f81ff06f fb010113 01f5579b 04813023 0175571b 0ff7f413 008007b7 fff7879b 0ff77713 0ff00693 04113423 00f577b3 04d70a63 02070a63 02079793 0207d793 03f41513 01d79793 3807071b 00f507b3 03471513 00a78533 04813083 04013403 05010113 00008067 03f41513 fe0786e3 00078513 768010ef fff5071b 42055793 fb9ff06f 02079263 04813083 7ff00793 03f41513 03479793 00f50533 04013403 05010113 00008067 00050593 02810513 01c020ef 02813783 00010513 00f13023 03013783 00f13423 03813783 00f13823 7e5010ef f85ff06f 03f55613 03f5d793 00002297 de828293 00f60463 00028067 00001297 b2028293 00028067 f9010113 06813023 fff00793 03455413 00c7d793 04913c23 05213823 00a5c4b3 0345d913 7ff00713 7ff47413 05313423 03513c23 06113423 05413023 00f579b3 00e97933 00f5fab3 03f4d493 10e40063 10e90c63 02091a63 000a9c63 01346433 1a041c63 001867f3 fff00513 0280006f 000a8513 6b0010ef 00b13423 00058a93 0005091b 00a13023 04041663 02099663 03f49513 06813083 06013403 05813483 05013903 04813983 04013a03 03813a83 07010113 00008067 00098513 668010ef 0005071b 00b13423 00058993 00a13023 00070413 00100a13 034a1a13 0149e9b3 014ae7b3 00b79a13 00b99793 4124043b 00a99993 0947fe63 3fd4041b 000a0613 00000593 00098513 3b9000ef 1ff57713 00200793 00050913 08e7f263 00090613 00040593 00048513 06813083 06013403 05813483 05013903 04813983 04013a03 03813a83 07010113 7580106f 02099063 0c890063 7ff00513 03f49493 03451513 00a48533 f31ff06f f20a84e3 06813083 06013403 05813483 05013903 04813983 04013a03 03813a83 07010113 71d0106f 3fe4041b 0019d993 f65ff06f 00050593 000a0513 4d1000ef 00050793 00b13c23 00058613 00050693 00000593 00098513 00f13823 259010ef 00058793 02b13423 02a13023 00050593 0207d663 00078513 000a0693 00000613 774000ef 00058793 02b13423 fff90913 02a13023 00050593 fc07cee3 00b03533 00a96933 f11ff06f e40a8ae3 f59ff06f 001467f3 f39ff06f 03455713 fff74713 03571793 02078c63 0345d793 fff7c793 03579713 06070663 00100793 00b50c63 fff00793 00b565b3 0017d793 00f5f7b3 0017b793 00078513 00008067 00c51713 fc0704e3 000017b7 fff78693 03355713 00d77733 ffe78793 04f70463 000017b7 fff78693 0335d713 00d77733 ffe78793 04f70463 00000793 00078513 00008067 00c59793 f8078ae3 000017b7 fff78693 03355713 00d77733 ffe78793 fcf710e3 00d51713 fa070ce3 001867f3 00000793 00078513 00008067 00d59713 00000793 f6070ae3 fe5ff06f 03455713 fff74713 03571693 00050793 02068663 0345d713 fff74713 03571693 02068863 03f7d713 03f5d693 00000513 02d70c63 0407c463 00008067 00c51713 fc070ae3 001867f3 00000513 00008067 00c59713 fe0718e3 03f7d713 03f5d693 00000513 fcd718e3 fcb788e3 00b7b7b3 40e7853b 00a03533 00008067 fff00513 00b7e7b3 00155513 00a7f7b3 00f03533 00008067 03455713 fff74713 03571693 00050793 02068663 0345d713 fff74713 03571693 06068663 03f7d713 03f5d693 00000513 08d70063 0807c863 00008067 00c51713 fc070ae3 00001737 fff70613 0337d693 00c6f6b3 ffe70713 08e68263 000017b7 fff78693 0335d713 00d77733 ffe78793 00000513 fcf712e3 00d59713 fa070ee3 001867f3 00000513 00008067 00c59713 f8070ae3 00001737 fff70613 0337d693 00c6f6b3 ffe70713 fae69ae3 0300006f f8b784e3 00b7b7b3 40e7853b 00a03533 00008067 fff00513 00b7e7b3 00155513 00a7f7b3 00f03533 00008067 00d79693 fa0690e3 f79ff06f fb010113 02913c23 fff00793 03455493 00c7d793 03213823 00a5c6b3 0345d913 7ff00713 7ff4f493 04813023 03313423 03413023 04113423 00f57a33 00e97933 00f5f433 03f6d993 04e48c63 0ae90863 02048863 0e091263 0c041263 03f99513 04813083 04013403 03813483 03013903 02813983 02013a03 05010113 00008067 fc0a0ee3 000a0513 230010ef 00b13423 00058a13 0005049b 00a13023 fb9ff06f 020a1e63 02990a63 008967b3 04079e63 001867f3 04813083 fff00513 04013403 03813483 03013903 02813983 02013a03 05010113 00008067 fc0408e3 04813083 04013403 03813483 03013903 02813983 02013a03 05010113 3450106f 0144e7b3 fc041ee3 fa0786e3 7ff00793 03f99513 03479793 00f50533 f49ff06f 00040513 198010ef 00b13423 00058413 0005059b 00a13023 00058913 00100793 03479793 00f465b3 00fa6533 00b59593 00a51513 0b9000ef 00a03633 fff00793 00b66633 0027d793 00b13c23 00a13823 012485bb 02c7e863 c005859b 00161613 00098513 04813083 04013403 03813483 03013903 02813983 02013a03 05010113 2980106f c015859b fd9ff06f fb010113 04813023 fff00713 03455413 00c75713 7ff47413 7ff00693 04113423 02913c23 03213823 00e57733 0cd40463 14054a63 02041c63 00071e63 04813083 04013403 03813483 03013903 05010113 00008067 00070513 0b8010ef 00b13423 00058713 0005041b 00a13023 00100913 03491913 01276933 01595593 0005859b 00040513 738000ef c014049b 00900713 00147413 4087073b 02051413 00e91933 02045413 02041613 00000593 00090513 5fc000ef 01e41413 00a40433 4014d49b 1ff47713 00500793 3fe4849b 04e7f863 00040613 00048593 04813083 04013403 03813483 03013903 00000513 05010113 19c0106f 0a071263 f40552e3 001867f3 fff00513 04813083 04013403 03813483 03013903 05010113 00008067 00040593 00040513 73c000ef 00050793 00b13c23 00058613 00050693 00000593 00090513 00f13823 4c4010ef 0180006f fff40413 00070513 00141693 03f45613 1ec000ef 00058713 02b13423 02a13023 00050593 fc074ee3 00a76533 00a03533 00a46433 f51ff06f 00e46433 ea040ae3 001867f3 fff00513 f71ff06f 04813083 04013403 03813483 03013903 00000593 05010113 0e50106f fc010113 02913423 fff00793 03455493 00c7d793 7ff4f493 7ff00713 02813823 02113c23 03f55413 00f577b3 02e48c63 00078513 01600593 3f4010ef 0005051b 00a4e7b3 06079463 01f4141b 03813083 00040513 02813483 03013403 04010113 00008067 01f4141b 7f800737 00e4043b fc078ee3 00050593 00810513 7cc010ef 00814403 800007b7 03813083 01f4141b fff7c793 00f46433 00040513 02813483 03013403 04010113 00008067 40000637 00c56633 c7f4859b 00040513 03813083 03013403 02813483 04010113 6cd0006f 03455813 fff00893 fd010113 00c8d793 7ff87813 02813023 00060713 00050413 02113423 00058693 00f57533 43300613 02080c63 00100793 03479793 4106063b 00f56533 02c04263 43e00793 0507dc63 001867f3 02813083 00088513 02013403 03010113 00008067 00000593 00d13423 00e13023 21c010ef 00b13c23 00a13823 00058613 00013703 00050593 00813683 03f45513 02813083 02013403 03010113 0ac0106f 40c005bb 00b515b3 02813083 03f45513 02013403 00000613 03010113 08c0106f 00d586b3 00c50633 ff010113 00b6b5b3 00068513 00b605b3 01010113 00008067 fd010113 01213823 01313423 0175591b 0175d99b 008007b7 fff7879b 0ff97913 0ff9f993 02813023 4139073b 00f57433 00f5f7b3 00913c23 01413023 0064149b 02113423 0067941b 00060a13 0ff00793 04071063 06f90e63 10090063 40000637 00c4043b 0094063b 00090593 000a0513 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 5590006f 06074463 0ef90e63 20000537 08098263 0085053b 00070593 0dc010ef 00050413 0084843b 200004b7 0094063b 400007b7 faf674e3 fff9091b 0016161b f9dff06f 0084e433 06040263 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 5f40106f 02f98863 20000537 00091463 00048513 0095053b 40e005bb 074010ef 00050493 00098913 f95ff06f 00040513 f7dff06f fa0418e3 01f6161b 7f800537 00a6053b 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 00b5053b 02813083 800005b7 fff5c593 00b57533 01f6161b 00a6053b 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 f40494e3 fa5ff06f fd010113 01213823 01313423 03455913 fff00693 0345d993 00c6d793 7ff97913 7ff9f993 02813023 4139073b 00f57433 00f5f7b3 00913c23 01413023 00941493 02113423 00979413 00060a13 7ff00793 04071263 08f90663 10090c63 00100613 03e61613 00c40433 00940633 00090593 000a0513 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 4fd0006f 06074a63 10f90663 00100513 03d51513 08098863 00850533 00070593 7d1000ef 00050413 00100613 00848433 fff00793 03d61493 00940633 0027d793 f8c7eee3 fff9091b 00161613 f91ff06f 0084e433 06040663 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 4900106f 02f98a63 00100513 03d51513 00091463 00048513 00950533 40e005bb 75d000ef 00050493 00098913 f89ff06f 00040513 f71ff06f fa0416e3 7ff00513 03f61613 03451513 00a60533 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 02813083 00b50533 0016d693 00d57533 03f61613 00a60533 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 f40492e3 fa9ff06f 00c56663 fff00513 00008067 fa010113 05213023 02065913 04813823 03313c23 fff00413 02091993 04113c23 04913423 03413823 03513423 02041413 0d356463 00058a93 00050a13 00040593 00060513 00060493 160000ef 00050793 00b13423 00058613 00050693 000a8593 000a0513 00f13023 6e9000ef 00058713 00b13c23 00a13823 00050593 02075c63 fff00a13 02049493 020a1a13 00070513 00048693 00090613 bf9ff0ef 00058713 00b13c23 01440433 00a13823 00050593 fc074ee3 02071713 0205d593 fff00513 00b765b3 02055513 0135f463 0325d533 05813083 00856533 04813483 05013403 04013903 03813983 03013a03 02813a83 06010113 00008067 03255433 02041413 f35ff06f 01b5d79b 00f7f793 00179793 00002717 bac70713 00157513 00f707b3 04050863 0007d503 00004737 0115d79b 00e7873b 40a7073b 02e5d7bb 00f7171b 0015d59b 00e7979b 00e7873b 02059793 02071513 0207d793 02055513 01f79793 02a7d7b3 0017559b 00b7853b 00008067 0207d683 0115d71b 000087b7 00f707bb 40d787bb 02f5d6bb ffff8737 00d787bb 000206b7 00d7f463 00f7971b fae5e8e3 4015d51b 00008067 fff00793 0207d793 02055713 0205d813 00f57533 00f5f5b3 02b70633 ff010113 00000693 02a807b3 00c787b3 02b50533 030705b3 00c7f663 00100693 02069693 02079713 00e50533 0207d793 00e53733 00d7e7b3 00b705b3 00b785b3 01010113 00008067 ffe5081b f9010113 01f6571b fff5079b 00183813 00058293 00e84833 05413023 01f6d89b 0175da1b 0017b793 01f5d59b 00800737 fff7071b 00b84833 06813023 0ff00593 0176d41b 04913c23 0117c7b3 0176549b 0ffa7a13 05213823 05313423 03513c23 03613823 03713423 06113423 00b47bb3 00e2f933 00b4f4b3 00e679b3 0ff7fb13 00e6f433 0ff87a93 10ba0663 14b48863 18bb8263 060a1863 04091a63 008be733 1a071463 1b6a8263 ffe2051b 00153513 40a0053b 800007b7 00f577b3 06813083 00078513 06013403 05813483 05013903 04813983 04013a03 03813a83 03013b03 02813b83 07010113 00008067 00090513 00d13423 710000ef 00813683 00050a1b 42055913 12048663 00800537 00a966b3 00a9e9b3 0076969b 0079999b 02069693 02099993 0206d693 0209d993 033689b3 fff00793 0037d793 009a04bb 1937f263 f824849b 100b9e63 10041463 01f00593 00098513 3c5000ef fff4849b 0005061b 00048593 000a8513 06813083 06013403 05813483 05013903 04813983 04013a03 03813a83 03013b03 02813b83 07010113 6f40006f 08090663 00060593 00028513 00d13423 7e5000ef 00813683 06813083 06013403 05813483 05013903 04813983 04013a03 03813a83 03013b03 02813b83 00068593 07010113 7b10006f 012a64b3 fa099ce3 02048263 01fa979b 7f800537 00a7853b 0ff00713 00050793 eceb90e3 fa0416e3 eb6a8ce3 001867f3 fff00513 f9dff06f 02040a63 00000513 f91ff06f 0b448663 0134e4b3 fe0480e3 fbdff06f e60986e3 00098513 5cc000ef 0005049b 42055993 ec5ff06f 00068793 e71ff06f 00040513 5b0000ef 00050b9b 42055413 00800737 00e46733 0067141b 417485bb 076a8463 02041413 0a05c063 08059663 408989b3 e20982e3 0c09c463 00098513 7d9000ef fff5079b 0009861b fdf5051b 40f484bb 00a6163b ea055ce3 40a005bb 00098513 265000ef 0005061b ea5ff06f f814849b 00199993 e7dff06f ec0996e3 0134e4b3 f55ff06f 04b05e63 02041513 1d9000ef 00a98533 02000593 22d000ef 0005061b 400007b7 e6f674e3 fff4849b 0016161b e5dff06f 00040513 1ad000ef 40a989b3 f79ff06f 00098513 40b005bb 199000ef 40a409b3 000b8493 000b0a93 f5dff06f 02000793 40b785bb 00098513 179000ef 0085063b 000b8493 fa9ff06f 001aca93 413009b3 f35ff06f 4015579b f6010113 00058313 0017f593 03f65793 00f5c5b3 03f35813 08913423 fff00793 03435493 00c7d793 0105c5b3 08813823 7ff00813 0346d413 03465293 03f6d893 00157713 7ff4f493 09213023 07313c23 07413823 07513423 07613023 05813823 01047a33 08113c23 05713c23 00f37b33 0102fc33 00f67933 01174ab3 00f6f433 0ff5f993 15048063 190c0463 1b0a0e63 08049063 040b1c63 008a67b3 1c079263 1d598063 fff00793 00200713 03f79793 00e20463 00000793 09813083 00078513 09013403 08813483 08013903 07813983 07013a03 06813a83 06013b03 05813b83 05013c03 0a010113 00008067 000b0513 00d13423 3f4000ef 00813683 0005079b 00b13c23 00058b13 00a13823 00078493 020c1263 f80902e3 00090513 3cc000ef 0005029b 00b13c23 00058913 00a13823 00028c13 00100b93 034b9513 00a965b3 00ab6533 00a59593 00a51513 aedff0ef fff00713 00375713 02b13423 00058b13 018484bb 02a13023 00050913 22b77c63 c024849b 100a1863 0e041863 001b1413 01203533 fff4849b 00a46633 00048593 00098513 09813083 09013403 08813483 08013903 07813983 07013a03 06813a83 06013b03 05813b83 05013c03 0a010113 4a40006f 080b0863 00060593 00030513 00d13423 499000ef 00813683 09813083 09013403 08813483 08013903 07813983 07013a03 06813a83 06013b03 05813b83 05013c03 00068593 0a010113 4610006f fa091ce3 0164e933 02090263 7ff00713 03471793 03f99513 00f50533 00050793 e8ea14e3 fa0414e3 e95980e3 001867f3 fff00513 f99ff06f 00040c63 00000513 f8dff06f 0c9c0663 012c6933 fbdff06f 00068793 e55ff06f 00040513 27c000ef 0005079b 00b13c23 00058413 00a13823 00078a13 00100793 03479793 00f467b3 00979413 4144863b 17598a63 08064863 12061663 00040613 00090593 00000693 000b0513 72c000ef 00a5e7b3 04b13423 00058413 00050913 04a13023 dc078ce3 0a05c463 00041863 00090413 fc04849b 00000913 00040513 421000ef fff5061b 40c484bb 16064863 00090593 00040513 680000ef 04b13423 00058413 04a13023 00050913 01203933 00896633 e71ff06f ea0914e3 012c6933 ef1ff06f 40c0063b 00090593 000b0513 500000ef 00050793 02b13423 00058613 00050693 00000593 00040513 02f13023 688000ef 04b13423 04a13023 00050913 00058413 000a0493 000a8993 f61ff06f 00050693 00058613 00000513 00000593 658000ef 04b13423 0019c993 04a13023 00050913 00058413 f35ff06f 00050593 000b8613 000b0513 5d0000ef 02b13423 00058b13 c014849b 02a13023 00050913 dadff06f 00040513 00000593 464000ef 00050793 02b13c23 00058613 00050693 00090593 000b0513 02f13823 5ec000ef 04b13423 00058413 04a13023 00050913 ecdff06f 06c05663 00040513 00000593 420000ef 00050793 00058613 02b13c23 00050693 00090593 000b0513 02f13823 ae8ff0ef 00a03433 04b13423 04a13023 00b46633 fff00793 0027d793 d2c7ece3 fff4849b 00161613 d2dff06f 00040513 40c005bb 54c000ef 00050413 ea1ff06f 00061c63 01640433 01203933 01246633 000a0493 fc1ff06f 000b0513 40c005bb 4c0000ef 00050b13 fddff06f fe010113 00113c23 00813823 00050413 20d000ef ff85051b 00100793 40a787bb 01813083 00a4143b 02079513 02041413 02055513 00856533 01013403 02010113 00008067 fe010113 00113c23 00813823 00050413 211000ef ff55059b 00100793 01813083 40b787bb 00f12023 00013503 00b415b3 01013403 02010113 00008067 fe010113 ffb27793 00813823 00913423 01213023 00113c23 00050493 00020913 04000413 02078863 00100793 00000413 02f20263 00153413 00300793 4087843b 4044043b 00143413 4080043b f8147413 07f4041b 0105969b 0106d69b 0fc00793 04d7d463 0a05c463 0fd00793 00f59663 00c4053b 02055c63 0012e7f3 01813083 01f4951b 7f800737 00e5073b 00143513 40a7053b 01013403 00813483 00013903 02010113 00008067 00c4053b 07f67613 fff00713 00060e63 0010e7f3 fc06061b 00193713 00163613 00c77733 fff74713 0075551b 00e577b3 01f4951b 00000713 02079263 01813083 00a787bb 00e7853b 01013403 00813483 00013903 02010113 00008067 0175971b fddff06f 00060513 40b005bb 28c000ef 07f57613 00060a63 001167f3 00000593 00a4053b f8dff06f 00a4053b fff00713 00000593 f95ff06f fe010113 ffb27793 00813823 00913423 01213023 00113c23 00050493 00020913 20000413 02078863 00100793 00000413 02f20263 00153413 00300793 4087843b 4044043b 00143413 4080043b c0147413 3ff4041b 0105969b 0106d69b 7fc00793 04d7d663 0a05c663 7fd00793 00f59663 00c40533 02055e63 0012e7f3 7ff00713 01813083 03f49513 03471713 00e50733 00143513 40a70533 01013403 00813483 00013903 02010113 00008067 00c40533 3ff67613 fff00713 00060e63 0010e7f3 e006061b 00193713 00163613 00c77733 fff74713 00a55413 00e477b3 03f49513 00000713 02079263 01813083 00a787b3 00e78533 01013403 00813483 00013903 02010113 00008067 03459713 fddff06f 00060513 40b005bb 1dc000ef 3ff57613 00060a63 001167f3 00000593 00a40533 f8dff06f 00a40533 fff00713 00000593 f95ff06f ffb6f793 02078863 00100793 00f68863 00153793 0027879b 06d78863 02051a63 00058513 02070463 02060263 0010e7f3 00008067 03f65793 fe0782e3 00158593 02059063 001867f3 fff00513 00008067 fc0588e3 001867f3 fff00513 ff1ff06f fff00793 0017d793 00f677b3 0017b793 0016b693 00d7f6b3 fff6c693 00b6f5b3 fa0500e3 fcdff06f 00c037b3 fadff06f 03f00793 ff010113 04c7f863 07f00793 00c7fc63 00b56533 00a03533 00000593 01010113 00008067 03f67613 00100793 00c797b3 fff78793 00a7f7b3 00b7e5b3 00b037b3 00c55533 00a7e533 00000593 01010113 00008067 40c007bb 02061613 02065613 03f7f793 00f516b3 00c5d733 00f597b3 00e6e733 00f037b3 00c555b3 01010113 00f76533 00008067 01f00793 00b7f663 00a03533 00008067 40b007bb 00f517bb 00f037b3 00b5553b 00a7e533 00008067 03f00793 ff010113 02c7f463 04000793 04f60063 00a037b3 00000613 00b035b3 00060513 00f5e5b3 01010113 00008067 40c007bb 00f517b3 00c55633 00b035b3 00060513 00f5e5b3 01010113 00008067 00050793 00000613 00b035b3 00060513 00f5e5b3 01010113 00008067 03f00793 00b7f663 00a03533 00008067 40b007bb 00f517b3 00f037b3 00b55533 00a7e533 00008067 02061793 0207d793 40c0063b 00f51733 ff010113 00c5d633 00f59533 01010113 00e665b3 00008067 0015579b 00157513 00a7e533 00008067 02059593 0205d593 00100793 00b797b3 fff78793 00a7f7b3 00f037b3 00b55533 00a7e533 00008067 40c50633 ff010113 00d5b7b3 40d58533 01010113 40f605b3 00008067 fd010113 02813023 01213823 01313423 0175591b 0175d99b 00800437 fff4041b 0ff97913 0ff9f993 00913c23 413907bb 008574b3 0085f433 01413023 02113423 00060a13 0074949b 0074141b 04f05e63 0ff00713 06e90e63 40000537 00099463 00040513 00078593 0085053b e5dff0ef 400007b7 00050413 00f4e4b3 4084863b fff9059b 000a0513 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 4cc0006f 08079063 0ff00793 0af90863 00091663 00100993 00098913 fa946ee3 0a84f863 00098913 0880006f 02048c63 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 33c0006f fe0410e3 00164513 01f5151b 7f8007b7 00f5053b 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 0ff00713 fce984e3 40000537 04090c63 40f005bb 0095053b d89ff0ef 400007b7 00050493 00f46433 00098913 001a4a13 4094063b f25ff06f 0084e433 f60418e3 001867f3 fff00513 f99ff06f ffe2051b 00153513 40a0053b 800007b7 00f57533 f81ff06f 00048513 fa9ff06f fd010113 01213823 01313423 03455913 fff00713 0345d993 02813023 7ff97913 00c75413 7ff9f993 00913c23 413907bb 008574b3 0085f433 01413023 02113423 00060a13 00a49493 00a41413 06f05263 7ff00713 0ae90863 00100513 03e51513 00099463 00040513 00078593 00850533 d59ff0ef 00100793 03e79793 00050413 00f4e4b3 40848633 fff9059b 000a0513 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 3d00006f 06079c63 7ff00793 0af90863 00091663 00100993 00098913 fa946ee3 0a84e863 fff00513 00200793 03f51513 00f20463 00000513 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 00008067 fe0480e3 02813083 02013403 01813483 01013903 00813983 00013a03 03010113 1b80006f 7ff00713 06e98063 00100513 03e51513 04090663 40f005bb 00950533 c85ff0ef 00100793 03e79793 00050493 00f46433 00098913 001a4a13 40940633 f25ff06f 0084e433 f8041ee3 001867f3 00070513 f6dff06f 00098913 fddff06f 00048513 fb5ff06f f6041ee3 00164513 7ff00793 03f51513 03479793 00f50533 f41ff06f 00050c63 00050613 00054a63 43c00593 00000513 2c00006f 00008067 ff010113 00100593 00113423 c59ff0ef 00813083 00050613 43d00593 00000513 01010113 8edff06f 00054503 fff00793 0017d793 03f51513 00f56533 00008067 0165d79b 1ff7f793 1fe00713 02e78263 000807b7 fff78793 01f5d59b 02979793 00b50023 00f53423 00053823 00008067 02a59793 fc078ee3 001867f3 fd5ff06f 000017b7 fff78713 0335d693 00e6f733 ffe78793 00f70e63 03f5d593 fffff7b7 00b50023 00f53423 00053823 00008067 00d59793 fe0782e3 001867f3 fffff7b7 03f5d593 00b50023 00f53423 00053823 00008067 0165579b 1ff7f793 1fe00713 02e78463 0165d79b 1ff7f793 1fe00713 00e79863 02a59793 00078463 001867f3 fff00513 00008067 02a51793 fc078ce3 001867f3 fedff06f 000017b7 fff78713 03355693 00e6f733 ffe78793 02f70863 000017b7 fff78693 0335d713 00d77733 ffe78793 00f71863 00d59793 00078463 001867f3 fff00513 00008067 00d51793 fc0788e3 001867f3 fedff06f 000107b7 00000693 00f57663 0105151b 01000693 010007b7 00f57663 0086869b 0085151b 0185579b 02079793 00001717 8a070713 0207d793 00f707b3 0007c503 00d5053b 00008067 fff00793 0207d793 04a7e863 0005079b 02000713 000106b7 00d7f663 0107071b 0107979b 010006b7 00d7f663 0087071b 0087979b 0187d79b 02079793 00001517 84850513 0207d793 00f507b3 0007c503 00e5053b 00008067 42055793 00000713 fb5ff06f fe010113 01213023 00050913 00060513 00813823 00913423 00060413 00058493 00113c23 f31ff0ef fff5061b 00600793 40c485bb 04c7d663 0105979b 0107d79b 0fc00713 02f74e63 01f9191b 00000793 00040463 0175979b ff85061b 01813083 00c4143b 0124043b 00f4053b 00813483 01013403 00013903 02010113 00008067 00c4163b 00090513 01813083 01013403 00813483 00013903 02010113 d1cff06f fe010113 01213023 00050913 00060513 00813823 00913423 00060413 00058493 00113c23 ed9ff0ef fff5061b 00900793 40c485bb 04c7d663 0105979b 0107d79b 7fc00713 02f74e63 03f91913 00000793 00040463 03459793 ff55061b 01813083 00c41433 01240433 00f40533 00813483 01013403 00013903 02010113 00008067 00c41633 00090513 01813083 01013403 00813483 00013903 02010113 dbcff06f ffff9528 ffff94bc ffff9614 ffff9614 ffff9614 ffff9614 ffff9614 ffff9614 ffff9614 ffff9468 ffff9614 ffff9614 ffff9614 ffff95e4 ffff9614 ffff9614 ffff95ac ffff9614 ffff9614 ffff9614 ffff9614 ffff9550 000089e0 00000000 00008a38 00000000 00008a40 00000000 00008a48 00000000 00008a50 00000000 00008a58 00000000 00008a60 00000000 00008a68 00000000 00008a70 00000000 00008a78 00000000 00008a80 00000000 00008a88 00000000 00008a90 00000000 00008a98 00000000 00008aa0 00000000 00008aa8 00000000 00008ab0 00000000 00008ab8 00000000 00008ac0 00000000 00008ac8 00000000 00008ad0 00000000 00008ad8 00000000 00008ae0 00000000 00008ae8 00000000 00008af0 00000000 00008af8 00000000 00008b00 00000000 00008b08 00000000 00008b10 00000000 00008b18 00000000 00008b20 00000000 00008b28 00000000 20202020 20202020 20202020 76762020 76767676 76767676 76767676 76767676 76767676 76767676 76767676 200a7676 20202020 20202020 20202020 20202020 76767620 76767676 76767676 76767676 76767676 76767676 76767676 72720a76 72727272 72727272 20727272 20202020 76762020 76767676 76767676 76767676 76767676 76767676 76767676 7272720a 72727272 72727272 72727272 20202072 76202020 76767676 76767676 76767676 76767676 76767676 0a767676 72727272 72727272 72727272 72727272 20207272 76762020 76767676 76767676 76767676 76767676 76767676 720a7676 72727272 72727272 72727272 72727272 20202072 76767620 76767676 76767676 76767676 76767676 76767676 72720a76 72727272 72727272 72727272 72727272 20202020 76767676 76767676 76767676 76767676 76767676 76767676 7272720a 72727272 72727272 72727272 20202072 76202020 76767676 76767676 76767676 76767676 76767676 0a202076 72727272 72727272 72727272 20202072 20202020 76767676 76767676 76767676 76767676 76767676 20207676 720a2020 20202072 20202020 20202020 20202020 76767620 76767676 76767676 76767676 76767676 20767676 20202020 72720a20 20202020 20202020 20202020 76767676 76767676 76767676 76767676 76767676 76767676 20202020 72722020 7272720a 20202072 76202020 76767676 76767676 76767676 76767676 76767676 76767676 20202076 72202020 0a727272 72727272 20207272 20202020 76767676 76767676 76767676 76767676 76767676 20207676 20202020 72727272 720a7272 72727272 20727272 20202020 76767620 76767676 76767676 76767676 20767676 20202020 72727220 72727272 72720a72 72727272 72727272 20202020 76762020 76767676 76767676 76767676 20202020 72722020 72727272 72727272 7272720a 72727272 72727272 20202072 76202020 76767676 76767676 20202076 72202020 72727272 72727272 0a727272 72727272 72727272 72727272 20207272 20202020 76767676 20207676 20202020 72727272 72727272 72727272 720a7272 72727272 72727272 72727272 20727272 20202020 20767620 20202020 72727220 72727272 72727272 72727272 72720a72 72727272 72727272 72727272 72727272 20202020 20202020 72722020 72727272 72727272 72727272 72727272 7272720a 72727272 72727272 72727272 72727272 20202072 72202020 72727272 72727272 72727272 72727272 0a727272 72727272 72727272 72727272 72727272 72727272 20207272 72727272 72727272 72727272 72727272 72727272 0a0a7272 20202020 49202020 5254534e 49544355 53204e4f 20535445 544e4157 204f5420 46204542 0a454552 00000000 00003280 000036d8 00003280 00003280 00003280 00003280 00003280 00003280 00003280 000037bc 00003280 00003280 00003898 00003280 00003994 00003280 00004a18 00004a20 00004a30 00004a28 00003b64 00003280 00003280 00003280 00003280 00003280 00003280 00003280 00003a48 00003280 00003280 00003280 ffffaa80 ffffaa04 ffffa948 ffffa8fc ffffa8a8 ffffa84c ffffa83c ffffaa64 ffffb4fc ffffb588 ffffb5ac ffffb5d4 ffffb4fc ffffb584 ffffb5a8 ffffb5e0 00003cd8 00003ce0 00003ce8 00003df8 00003fd8 000040fc 00003280 00003280 00004268 00003280 00003280 00003f08 00003280 00003280 00003280 00003280 00003280 00003280 00003280 00003280 00004640 00003280 00003280 00003280 00004488 00003280 00004344 00003280 00004794 00003280 0000480c 00003280 00220004 00b1005d 019f011d 02e00236 0468039c 06310545 0832072b 0a670946 08af0a2d 0629075a 0429051a 029e0356 01790200 00af0109 00340068 00020012 06060708 05050505 04040404 04040404 03030303 03030303 03030303 03030303 02020202 02020202 02020202 02020202 02020202 02020202 02020202 02020202 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 206c6262 276e6163 75722074 7375206e 62207265 72616e69 3b736569 79727420 69737520 7020676e 6e69206b 61657473 00000a64 00000000 276e6163 75722074 3233206e 7469622d 464c4520 206e6f20 622d3436 70207469 00000a6b 00000000 3d3d2072 00003020 20746f67 73677261 7261203a 253d6367 00000a64 00000000 67726120 64255b76 73253d5d 0000000a 65726e75 6e676f63 64657a69 74706f20 3a6e6f69 63256020 00000a27 00000000 20656874 2063252d 67616c66 71657220 65726975 20612073 7a6e6f6e 206f7265 75677261 746e656d 0000000a 00000000 6c6c6574 20656d20 74616877 464c4520 206f7420 64616f6c 00000a21 00000000 3d3d2070 006d2620 702f2e2e 6c652f6b 00632e66 00000000 253a7325 00000a64 656c6966 6572705f 61206461 3d726464 6e207825 2064253d 3d66666f 62207825 253d6675 00000a78 5f6d656d 61657270 64612064 253d7264 3d6e2078 6f206425 253d6666 75622078 78253d66 0000000a 6d73696d 68637461 20746120 2066666f 000a7825 00000000 5f6d656d 61657270 75622064 7a697366 65722065 6f206461 253d6666 3d6e2078 000a6425 00000000 5f6d656d 61657270 6f642064 000a656e 6e65706f 20676e69 696c6d76 0a78756e 00000000 00000000 6d6f682f 616a2f65 2f79656d 6b726f77 6f72702f 6d617267 696c2f73 2f78756e 696c6d76 0078756e 656c6966 0a702520 00000000 00000000 72646865 7a69735f 64253d65 7a697320 28666f65 34366865 64253d29 0000000a 34366865 6564692e 3d20746e 20632520 25206325 00000a63 6c6c6163 20676e69 696e6170 00000a63 6c756f63 74276e64 65706f20 4c45206e 72702046 6172676f 25203a6d 000a2173 253a7325 70252064 0000000a 00000000 20646162 0a746d66 00000000 00000000 0000207a 00000000 25207325 6325786c 00000000 00000000 25206370 7620786c 6c252061 6e692078 20206e73 20202020 20782520 25207273 000a786c 00000000 65737361 6f697472 6166206e 64656c69 7325203a 0000000a 00006172 00000000 00007073 00000000 00007067 00000000 00007074 00000000 00003074 00000000 00003174 00000000 00003274 00000000 00003073 00000000 00003173 00000000 00003061 00000000 00003161 00000000 00003261 00000000 00003361 00000000 00003461 00000000 00003561 00000000 00003661 00000000 00003761 00000000 00003273 00000000 00003373 00000000 00003473 00000000 00003573 00000000 00003673 00000000 00003773 00000000 00003873 00000000 00003973 00000000 00004173 00000000 00004273 00000000 00003374 00000000 00003474 00000000 00003574 00000000 00003674 00000000 7478656e 6572665f 61705f65 21206567 7266203d 705f6565 73656761 00000000 5f455450 4c424154 5b742845 5d786469 00000029 00000000 20746572 0030203e 00657470 00000000 61685f5f 656c646e 6761705f 61665f65 28746c75 70202c61 29746f72 203d3d20 00000030 00000000 6f645f5f 616d6d5f 75632870 6e657272 72622e74 6e202c6b 72627765 61705f6b 2d206567 72756320 746e6572 6b72622e 312d202c 414d202c 49465f50 7c444558 5f50414d 56495250 7c455441 5f50414d 4e4f4e41 554f4d59 30202c53 2930202c 203d3d20 72727563 2e746e65 006b7262 62732a21 74705f69 00000065 00000000 7478656e 6572665f 61705f65 3d206567 0030203d 00000000 72727563 2e746e65 63617473 6f625f6b 6d6f7474 203d2120 6e697528 72747074 2d29745f 00000031 6863616d 20656e69 65646f6d 6e75203a 646e6168 6c62616c 72742065 25207061 20402064 000a7025 66697468 6170203a 66206567 746c7561 0000000a 00000000 66697468 6f6e203a 63657220 0a64726f 00000000 00000000 6c756f63 6f6e2064 65642074 6d726574 20656e69 6f6d656d 63207972 63617061 0a797469 00000000 6c756f63 6f6e2064 65642074 6d726574 20656e69 626d756e 6f207265 61682066 0a737472 00000000 65707573 73697672 7320726f 6f707075 69207472 65722073 72697571 000a6465 64616572 7273635f 74736d28 73757461 20262029 4154534d 5f535554 00005346 20555046 20746f6e 6e756f66 72203b64 6d6f6365 656c6970 206b7020 68746977 736d2d20 2d74666f 616f6c66 00000a74 76657270 30203e20 00000000 00000000 702f2e2e 69662f6b 632e656c 00000000 00002b70 00002b74 00003298 0000329c 00003328 00003330 00003384 0000338c 000033c0 000033c8 00003414 0000341c 0000347c 00003484 000034e8 000034f0 00003508 00003510 00003534 00003538 000035e0 0000361c 00003650 0000366c 0000367c 00003688 00003718 0000371c 0000377c 00003780 00003820 00003824 00003884 00003888 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00002bcc 00002bcc 00002b60 00002bcc 00003288 00002bcc 00003524 00002bcc 00002bcc 00002d44 00002bcc 00002bcc 00002be8 0000301c 00002bcc 00002bcc ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 ffffffff 00000000 464c457f 00000002 464c457f 00000001 3a434347 4e472820 35202955 302e322e 00000000 00000001 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000893 00000073 00008067 00000013 fffff517 0d052503 00008067 00000013 a18fa06f 00000013 00000013 00000013 00100893 00000073 00008067 00000013 00200893 00000073 00008067 00000013 00300893 00000073 00008067 00000013 00400893 00000073 00008067 00000013 00500893 00000073 00008067 00000013 00989537 6805051b 00008067 00000013 00600893 00000073 00000013 00000013 00700893 00000073 00008067 00050893 00058513 00060593 00000073 00008067 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000013 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ================================================ FILE: tests/spikehw/eth.json ================================================ { "eth_sfp_rxp_v": { "sfp1": "rxp" }, "eth_sfp_rxn_v": { "sfp1": "rxn" }, "eth_sfp_txp": { "sfp1": "txp" }, "eth_sfp_txn": { "sfp1": "txn" } } ================================================ FILE: tests/spikehw/flash.json ================================================ { "flash_data_0": { "bpi_flash": "data[0]" }, "flash_data_1": { "bpi_flash": "data[1]" }, "flash_data_2": { "bpi_flash": "data[2]" }, "flash_data_3": { "bpi_flash": "data[3]" }, "flash_data_4": { "bpi_flash": "data[4]" }, "flash_data_5": { "bpi_flash": "data[5]" }, "flash_data_6": { "bpi_flash": "data[6]" }, "flash_data_7": { "bpi_flash": "data[7]" }, "flash_data_8": { "bpi_flash": "data[8]" }, "flash_data_9": { "bpi_flash": "data[9]" }, "flash_data_10": { "bpi_flash": "data[10]" }, "flash_data_11": { "bpi_flash": "data[11]" }, "flash_data_12": { "bpi_flash": "data[12]" }, "flash_data_13": { "bpi_flash": "data[13]" }, "flash_data_14": { "bpi_flash": "data[14]" }, "flash_data_15": { "bpi_flash": "data[15]" }, "flash_addr[0]": { "bpi_flash": "addr[0]" }, "flash_addr[1]": { "bpi_flash": "addr[1]" }, "flash_addr[2]": { "bpi_flash": "addr[2]" }, "flash_addr[3]": { "bpi_flash": "addr[3]" }, "flash_addr[4]": { "bpi_flash": "addr[4]" }, "flash_addr[5]": { "bpi_flash": "addr[5]" }, "flash_addr[6]": { "bpi_flash": "addr[6]" }, "flash_addr[7]": { "bpi_flash": "addr[7]" }, "flash_addr[8]": { "bpi_flash": "addr[8]" }, "flash_addr[9]": { "bpi_flash": "addr[9]" }, "flash_addr[10]": { "bpi_flash": "addr[10]" }, "flash_addr[11]": { "bpi_flash": "addr[11]" }, "flash_addr[12]": { "bpi_flash": "addr[12]" }, "flash_addr[13]": { "bpi_flash": "addr[13]" }, "flash_addr[14]": { "bpi_flash": "addr[14]" }, "flash_addr[15]": { "bpi_flash": "addr[15]" }, "flash_addr[16]": { "bpi_flash": "addr[16]" }, "flash_addr[17]": { "bpi_flash": "addr[17]" }, "flash_addr[18]": { "bpi_flash": "addr[18]" }, "flash_addr[19]": { "bpi_flash": "addr[19]" }, "flash_addr[20]": { "bpi_flash": "addr[20]" }, "flash_addr[21]": { "bpi_flash": "addr[21]" }, "flash_addr[22]": { "bpi_flash": "addr[22]" }, "flash_addr[23]": { "bpi_flash": "addr[23]" }, "flash_addr[24]": { "bpi_flash": "addr[24]" }, "flash_addr[25]": { "bpi_flash": "addr[25]" }, "flash_oe_b": { "bpi_flash": "oe_b" }, "flash_ce_b": { "bpi_flash": "ce_b" }, "flash_adv_b": { "bpi_flash": "adv_b" }, "flash_we_b": { "bpi_flash": "we_b" }, "flash_wait_in_b": { "bpi_flash": "wait_in_b" } } ================================================ FILE: tests/spikehw/gencores.tcl ================================================ set ipdir {cores} set boardname {nfsume} #set boardname {miniitx100} if {$boardname == {nfsume}} { set partname {xc7vx690tffg1761-2} set databuswidth 32 } if {$boardname == {miniitx100}} { set partname {xc7z100ffg900-2} set databuswidth 64 } file mkdir $ipdir/$boardname create_project -name local_synthesized_ip -in_memory -part $partname set_property board_part xilinx.com:vc709:part0:1.0 [current_project] proc fpgamake_ipcore {core_name core_version ip_name params} { global ipdir boardname set generate_ip 0 if [file exists $ipdir/$boardname/$ip_name/$ip_name.xci] { } else { puts "no xci file $ip_name.xci" set generate_ip 1 } if [file exists $ipdir/$boardname/$ip_name/vivadoversion.txt] { gets [open $ipdir/$boardname/$ip_name/vivadoversion.txt r] generated_version set current_version [version -short] puts "core was generated by vivado $generated_version, currently running vivado $current_version" if {$current_version != $generated_version} { puts "vivado version does not match" set generate_ip 1 } } else { puts "no vivado version recorded" set generate_ip 1 } ## check requested core version and parameters if [file exists $ipdir/$boardname/$ip_name/coreversion.txt] { gets [open $ipdir/$boardname/$ip_name/coreversion.txt r] generated_version set current_version "$core_name $core_version $params" puts "Core generated: $generated_version" puts "Core requested: $current_version" if {$current_version != $generated_version} { puts "core version or params does not match" set generate_ip 1 } } else { puts "no core version recorded" set generate_ip 1 } if $generate_ip { file delete -force $ipdir/$boardname/$ip_name file mkdir $ipdir/$boardname create_ip -name $core_name -version $core_version -vendor xilinx.com -library ip -module_name $ip_name -dir $ipdir/$boardname if [llength $params] { set_property -dict $params [get_ips $ip_name] } report_property -file $ipdir/$boardname/$ip_name.properties.log [get_ips $ip_name] generate_target all [get_files $ipdir/$boardname/$ip_name/$ip_name.xci] set versionfd [open $ipdir/$boardname/$ip_name/vivadoversion.txt w] puts $versionfd [version -short] close $versionfd set corefd [open $ipdir/$boardname/$ip_name/coreversion.txt w] puts $corefd "$core_name $core_version $params" close $corefd } else { read_ip $ipdir/$boardname/$ip_name/$ip_name.xci } if [file exists $ipdir/$boardname/$ip_name/$ip_name.dcp] { } else { synth_ip [get_ips $ip_name] } } if {[version -short] == "2014.2"} { fpgamake_ipcore axi_ethernet_buffer 2.0 eth_buf [ list CONFIG.C_AVB {0} CONFIG.C_PHYADDR {1} CONFIG.C_PHY_TYPE {5} CONFIG.C_STATS {1} CONFIG.C_TYPE {1} CONFIG.ENABLE_LVDS {0} CONFIG.HAS_SGMII {true} CONFIG.MCAST_EXTEND {false} CONFIG.RXCSUM {None} CONFIG.RXMEM {4k} CONFIG.RXVLAN_STRP {false} CONFIG.RXVLAN_TAG {false} CONFIG.RXVLAN_TRAN {false} CONFIG.SIMULATION_MODE {false} CONFIG.TXCSUM {None} CONFIG.TXMEM {4k} CONFIG.TXVLAN_STRP {false} CONFIG.TXVLAN_TAG {false} CONFIG.TXVLAN_TRAN {false} CONFIG.USE_BOARD_FLOW {true} ] } fpgamake_ipcore axi_uart16550 2.0 axi_uart16550_1 [list CONFIG.USE_BOARD_FLOW {true} CONFIG.UART_BOARD_INTERFACE {rs232_uart} CONFIG.C_HAS_EXTERNAL_XIN {1} CONFIG.C_HAS_EXTERNAL_RCLK {0} CONFIG.C_EXTERNAL_XIN_CLK_HZ_d {3.686400} CONFIG.C_EXTERNAL_XIN_CLK_HZ {3686400}] if {[version -short] == "2014.2"} { fpgamake_ipcore axi_intc 4.1 axi_intc_0 [list CONFIG.C_NUM_INTR_INPUTS {16} CONFIG.C_NUM_SW_INTR {0} CONFIG.C_HAS_ILR {1}] } else { fpgamake_ipcore axi_intc 4.1 axi_intc_0 [list CONFIG.C_NUM_INTR_INPUTS {16} CONFIG.C_NUM_SW_INTR {0} CONFIG.C_HAS_ILR {1} CONFIG.C_S_AXI_ACLK_FREQ_MHZ {250}] } fpgamake_ipcore fifo_generator 13.0 dual_clock_axis_fifo_32x1024 [list CONFIG.INTERFACE_TYPE {AXI_STREAM} CONFIG.Clock_Type_AXI {Independent_Clock} CONFIG.TDATA_NUM_BYTES {4} CONFIG.TUSER_WIDTH {0} CONFIG.Enable_TLAST {true} CONFIG.HAS_TKEEP {true} CONFIG.FIFO_Application_Type_axis {Data_FIFO} CONFIG.Reset_Type {Asynchronous_Reset} CONFIG.Full_Flags_Reset_Value {1} CONFIG.TSTRB_WIDTH {4} CONFIG.TKEEP_WIDTH {4} CONFIG.FIFO_Implementation_wach {Independent_Clocks_Distributed_RAM} CONFIG.Full_Threshold_Assert_Value_wach {15} CONFIG.Empty_Threshold_Assert_Value_wach {13} CONFIG.FIFO_Implementation_wdch {Independent_Clocks_Block_RAM} CONFIG.Empty_Threshold_Assert_Value_wdch {1021} CONFIG.FIFO_Implementation_wrch {Independent_Clocks_Distributed_RAM} CONFIG.Full_Threshold_Assert_Value_wrch {15} CONFIG.Empty_Threshold_Assert_Value_wrch {13} CONFIG.FIFO_Implementation_rach {Independent_Clocks_Distributed_RAM} CONFIG.Full_Threshold_Assert_Value_rach {15} CONFIG.Empty_Threshold_Assert_Value_rach {13} CONFIG.FIFO_Implementation_rdch {Independent_Clocks_Block_RAM} CONFIG.Empty_Threshold_Assert_Value_rdch {1021} CONFIG.FIFO_Implementation_axis {Independent_Clocks_Block_RAM} CONFIG.Empty_Threshold_Assert_Value_axis {1021}] fpgamake_ipcore axi_dma 7.1 axi_dma_0 [list CONFIG.c_sg_include_stscntrl_strm {1} CONFIG.c_m_axi_mm2s_data_width $databuswidth CONFIG.c_m_axi_s2mm_data_width $databuswidth CONFIG.c_mm2s_burst_size {8} CONFIG.c_s2mm_burst_size {8} CONFIG.c_include_mm2s_dre {1} CONFIG.c_sg_use_stsapp_length {1} CONFIG.c_include_s2mm_dre {1}] fpgamake_ipcore axi_iic 2.0 axi_iic_0 [list CONFIG.AXI_ACLK_FREQ_MHZ {250} CONFIG.C_GPO_WIDTH {8}] fpgamake_ipcore axi_quad_spi 3.2 axi_spi_0 [list CONFIG.C_USE_STARTUP {0} CONFIG.C_SPI_MODE {0} CONFIG.C_XIP_MODE {0} CONFIG.C_USE_STARTUP_INT {0} CONFIG.C_SCK_RATIO {16} CONFIG.C_FIFO_DEPTH {16} CONFIG.C_TYPE_OF_AXI4_INTERFACE {0}] ## does not exist with vivado 2014.2 if {[version -short] > "2014.2"} { fpgamake_ipcore axi_ethernet 7.0 axi_ethernet_1000basex [list CONFIG.ETHERNET_BOARD_INTERFACE {sfp1} CONFIG.processor_mode {true} CONFIG.DIFFCLK_BOARD_INTERFACE {sfp_mgt_clk} CONFIG.axiliteclkrate {250.0} CONFIG.PHY_TYPE {1000BaseX}] fpgamake_ipcore tri_mode_ethernet_mac 9.0 tri_mode_ethernet_mac_0 [list CONFIG.Physical_Interface {Internal} CONFIG.MAC_Speed {1000_Mbps} CONFIG.SupportLevel {1}] ## 2014.2: 14.2 ## 2015.4: 15.1 fpgamake_ipcore gig_ethernet_pcs_pma 15.1 gig_ethernet_pcs_pma_0 [list CONFIG.USE_BOARD_FLOW {true} CONFIG.Management_Interface {true} CONFIG.ETHERNET_BOARD_INTERFACE {sfp1} CONFIG.DIFFCLK_BOARD_INTERFACE {sfp_mgt_clk} CONFIG.Standard {1000BASEX} CONFIG.SupportLevel {Include_Shared_Logic_in_Core}] } else { ## 2014.2: 8.2 ## 2015.4: 9.0 fpgamake_ipcore tri_mode_ethernet_mac 8.2 tri_mode_ethernet_mac_0 [list CONFIG.Physical_Interface {Internal} CONFIG.MAC_Speed {1000_Mbps} CONFIG.SupportLevel {1}] ## 2014.2: 14.2 ## 2015.4: 15.1 fpgamake_ipcore gig_ethernet_pcs_pma 14.2 gig_ethernet_pcs_pma_0 [list CONFIG.USE_BOARD_FLOW {true} CONFIG.Management_Interface {true} CONFIG.ETHERNET_BOARD_INTERFACE {sfp1} CONFIG.DIFFCLK_BOARD_INTERFACE {sfp_mgt_clk} CONFIG.Standard {1000BASEX} CONFIG.SupportLevel {Include_Shared_Logic_in_Core}] } if {[version -short] > "2014.2"} { fpgamake_ipcore mig_7series 2.1 ddr3_v2_1 [list CONFIG.XML_INPUT_FILE [pwd]/mig_a.prj CONFIG.RESET_BOARD_INTERFACE {Custom} CONFIG.MIG_DONT_TOUCH_PARAM {Custom} CONFIG.BOARD_MIG_PARAM {Custom}] } ================================================ FILE: tests/spikehw/geneth.tcl ================================================ set ipdir {cores} set boardname {nfsume} #set boardname {miniitx100} if {$boardname == {nfsume}} { set partname {xc7vx690tffg1761-2} set databuswidth 32 } if {$boardname == {miniitx100}} { set partname {xc7z100ffg900-2} set databuswidth 64 } file mkdir $ipdir/$boardname create_project -name local_synthesized_ip -in_memory -part $partname set_property board_part xilinx.com:vc709:part0:1.0 [current_project] ################################################################ # This is a generated script based on design: bd_0 # # Though there are limitations about the generated script, # the main purpose of this utility is to make learning # IP Integrator Tcl commands easier. ################################################################ ################################################################ # START ################################################################ # To test this script, run the following commands from Vivado Tcl console: # source bd_0_script.tcl # If you do not already have a project created, # you can create a project using the following command: # create_project project_1 myproj -part xc7vx690tffg1761-2 # set_property BOARD_PART xilinx.com:vc709:part0:1.0 [current_project] # CHECKING IF PROJECT EXISTS if { [get_projects -quiet] eq "" } { puts "ERROR: Please open or create a project!" return 1 } # CHANGE DESIGN NAME HERE set design_name bd_0 # This script was generated for a remote BD. set str_bd_folder /home/jamey/connectal.clean/tests/spikehw/cores/nfsume/foo_eth set str_bd_filepath ${str_bd_folder}/${design_name}/${design_name}.bd # Check if remote design exists on disk if { [file exists $str_bd_filepath ] == 1 } { puts "ERROR: The remote BD file path <$str_bd_filepath> already exists!\n" puts "INFO: Please modify the variable to another path or modify the variable ." return 1 } # Check if design exists in memory set list_existing_designs [get_bd_designs -quiet $design_name] if { $list_existing_designs ne "" } { puts "ERROR: The design <$design_name> already exists in this project!" puts "ERROR: Will not create the remote BD <$design_name> at the folder <$str_bd_folder>.\n" puts "INFO: Please modify the variable ." return 1 } # Check if design exists on disk within project set list_existing_designs [get_files */${design_name}.bd] if { $list_existing_designs ne "" } { puts "ERROR: The design <$design_name> already exists in this project at location:" puts " $list_existing_designs" puts "ERROR: Will not create the remote BD <$design_name> at the folder <$str_bd_folder>.\n" puts "INFO: Please modify the variable ." return 1 } # Now can create the remote BD create_bd_design -dir $str_bd_folder $design_name current_bd_design $design_name ################################################################## # DESIGN PROCs ################################################################## # Procedure to create entire design; Provide argument to make # procedure reusable. If parentCell is "", will use root. proc create_root_design { parentCell } { if { $parentCell eq "" } { set parentCell [get_bd_cells /] } # Get object for parentCell set parentObj [get_bd_cells $parentCell] if { $parentObj == "" } { puts "ERROR: Unable to find parent cell <$parentCell>!" return } # Make sure parentObj is hier blk set parentType [get_property TYPE $parentObj] if { $parentType ne "hier" } { puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." return } # Save current instance; Restore later set oldCurInst [current_bd_instance .] # Set parent object as current current_bd_instance $parentObj # Create interface ports set m_axis_rxd [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_rxd ] set m_axis_rxs [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_rxs ] set mgt_clk [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 mgt_clk ] set_property -dict [ list \ CONFIG.BOARD.ASSOCIATED_PARAM {DIFFCLK_BOARD_INTERFACE} \ ] $mgt_clk set s_axi [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi ] set_property -dict [ list \ CONFIG.PROTOCOL {AXI4LITE} \ ] $s_axi set s_axis_txc [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 s_axis_txc ] set s_axis_txd [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 s_axis_txd ] set sfp [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:sfp_rtl:1.0 sfp ] set_property -dict [ list \ CONFIG.BOARD.ASSOCIATED_PARAM {ETHERNET_BOARD_INTERFACE} \ ] $sfp # Create ports set axi_rxd_arstn [ create_bd_port -dir I -type rst axi_rxd_arstn ] set_property -dict [ list \ CONFIG.POLARITY {ACTIVE_LOW} \ ] $axi_rxd_arstn set axi_rxs_arstn [ create_bd_port -dir I -type rst axi_rxs_arstn ] set_property -dict [ list \ CONFIG.POLARITY {ACTIVE_LOW} \ ] $axi_rxs_arstn set axi_txc_arstn [ create_bd_port -dir I -type rst axi_txc_arstn ] set_property -dict [ list \ CONFIG.POLARITY {ACTIVE_LOW} \ ] $axi_txc_arstn set axi_txd_arstn [ create_bd_port -dir I -type rst axi_txd_arstn ] set_property -dict [ list \ CONFIG.POLARITY {ACTIVE_LOW} \ ] $axi_txd_arstn set axis_clk [ create_bd_port -dir I -type clk axis_clk ] set gt0_qplloutclk_out [ create_bd_port -dir O -type clk gt0_qplloutclk_out ] set gt0_qplloutrefclk_out [ create_bd_port -dir O -type clk gt0_qplloutrefclk_out ] set gtref_clk_buf_out [ create_bd_port -dir O -type clk gtref_clk_buf_out ] set_property -dict [ list \ CONFIG.FREQ_HZ {125000000} \ ] $gtref_clk_buf_out set gtref_clk_out [ create_bd_port -dir O -type clk gtref_clk_out ] set_property -dict [ list \ CONFIG.FREQ_HZ {125000000} \ ] $gtref_clk_out set interrupt [ create_bd_port -dir O -type intr interrupt ] set_property -dict [ list \ CONFIG.SENSITIVITY {LEVEL_HIGH} \ ] $interrupt set mac_irq [ create_bd_port -dir O -type intr mac_irq ] set_property -dict [ list \ CONFIG.SENSITIVITY {EDGE_RISING} \ ] $mac_irq set mmcm_locked_out [ create_bd_port -dir O mmcm_locked_out ] set pma_reset_out [ create_bd_port -dir O -type rst pma_reset_out ] set_property -dict [ list \ CONFIG.POLARITY {ACTIVE_HIGH} \ ] $pma_reset_out set ref_clk [ create_bd_port -dir I -type clk ref_clk ] set rxuserclk2_out [ create_bd_port -dir O -type clk rxuserclk2_out ] set_property -dict [ list \ CONFIG.FREQ_HZ {62500000} \ ] $rxuserclk2_out set rxuserclk_out [ create_bd_port -dir O -type clk rxuserclk_out ] set_property -dict [ list \ CONFIG.FREQ_HZ {62500000} \ ] $rxuserclk_out set s_axi_lite_clk [ create_bd_port -dir I -type clk s_axi_lite_clk ] set s_axi_lite_resetn [ create_bd_port -dir I -type rst s_axi_lite_resetn ] set_property -dict [ list \ CONFIG.POLARITY {ACTIVE_LOW} \ ] $s_axi_lite_resetn set signal_detect [ create_bd_port -dir I signal_detect ] set userclk2_out [ create_bd_port -dir O -type clk userclk2_out ] set_property -dict [ list \ CONFIG.FREQ_HZ {125000000} \ ] $userclk2_out set userclk_out [ create_bd_port -dir O -type clk userclk_out ] set_property -dict [ list \ CONFIG.FREQ_HZ {62500000} \ ] $userclk_out # Create instance: eth_buf, and set properties set eth_buf [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_ethernet_buffer:2.0 eth_buf ] set_property -dict [ list \ CONFIG.C_AVB {0} \ CONFIG.C_PHYADDR {1} \ CONFIG.C_PHY_TYPE {5} \ CONFIG.C_STATS {1} \ CONFIG.C_TYPE {1} \ CONFIG.ENABLE_LVDS {0} \ CONFIG.HAS_SGMII {true} \ CONFIG.MCAST_EXTEND {false} \ CONFIG.RXCSUM {None} \ CONFIG.RXMEM {4k} \ CONFIG.RXVLAN_STRP {false} \ CONFIG.RXVLAN_TAG {false} \ CONFIG.RXVLAN_TRAN {false} \ CONFIG.SIMULATION_MODE {false} \ CONFIG.TXCSUM {None} \ CONFIG.TXMEM {4k} \ CONFIG.TXVLAN_STRP {false} \ CONFIG.TXVLAN_TAG {false} \ CONFIG.TXVLAN_TRAN {false} \ CONFIG.USE_BOARD_FLOW {true} \ CONFIG.enable_1588 {0} \ ] $eth_buf # Create instance: eth_mac, and set properties set eth_mac [ create_bd_cell -type ip -vlnv xilinx.com:ip:tri_mode_ethernet_mac:9.0 eth_mac ] set_property -dict [ list \ CONFIG.Data_Rate {1_Gbps} \ CONFIG.ETHERNET_BOARD_INTERFACE {Custom} \ CONFIG.Enable_1588 {false} \ CONFIG.Enable_1588_1step {false} \ CONFIG.Enable_AVB {false} \ CONFIG.Enable_MDIO {true} \ CONFIG.Enable_Priority_Flow_Control {false} \ CONFIG.Frame_Filter {true} \ CONFIG.Half_Duplex {false} \ CONFIG.MAC_Speed {1000_Mbps} \ CONFIG.MDIO_BOARD_INTERFACE {Custom} \ CONFIG.Make_MDIO_External {false} \ CONFIG.Management_Interface {true} \ CONFIG.Number_of_Table_Entries {4} \ CONFIG.Physical_Interface {Internal} \ CONFIG.RX_Inband_TS_Enable {false} \ CONFIG.Statistics_Counters {true} \ CONFIG.Statistics_Reset {false} \ CONFIG.Statistics_Width {64bit} \ CONFIG.SupportLevel {0} \ CONFIG.TX_Inband_CF_Enable {false} \ CONFIG.Timer_Format {Time_of_day} \ CONFIG.USE_BOARD_FLOW {false} \ ] $eth_mac # Create instance: pcs_pma, and set properties set pcs_pma [ create_bd_cell -type ip -vlnv xilinx.com:ip:gig_ethernet_pcs_pma:15.1 pcs_pma ] set_property -dict [ list \ CONFIG.Auto_Negotiation {true} \ CONFIG.C_PHYADDR {1} \ CONFIG.DIFFCLK_BOARD_INTERFACE {sfp_mgt_clk} \ CONFIG.DrpClkRate {50.0} \ CONFIG.ETHERNET_BOARD_INTERFACE {sfp1} \ CONFIG.EXAMPLE_SIMULATION {0} \ CONFIG.Enable_1588 {false} \ CONFIG.Ext_Management_Interface {false} \ CONFIG.LvdsRefClk {125} \ CONFIG.MDIO_BOARD_INTERFACE {Custom} \ CONFIG.Management_Interface {true} \ CONFIG.MaxDataRate {1G} \ CONFIG.Physical_Interface {Transceiver} \ CONFIG.RefClkRate {125} \ CONFIG.SGMII_Mode {10_100_1000} \ CONFIG.SGMII_PHY_Mode {false} \ CONFIG.Standard {1000BASEX} \ CONFIG.SupportLevel {Include_Shared_Logic_in_Core} \ CONFIG.Timer_Format {Time_of_day} \ CONFIG.TransceiverControl {false} \ CONFIG.USE_BOARD_FLOW {true} \ ] $pcs_pma # Create interface connections connect_bd_intf_net -intf_net eth_buf_AXI_STR_RXD [get_bd_intf_ports m_axis_rxd] [get_bd_intf_pins eth_buf/AXI_STR_RXD] connect_bd_intf_net -intf_net eth_buf_AXI_STR_RXS [get_bd_intf_ports m_axis_rxs] [get_bd_intf_pins eth_buf/AXI_STR_RXS] connect_bd_intf_net -intf_net eth_buf_S_AXI_2TEMAC [get_bd_intf_pins eth_buf/S_AXI_2TEMAC] [get_bd_intf_pins eth_mac/s_axi] connect_bd_intf_net -intf_net eth_buf_TX_AXIS_MAC [get_bd_intf_pins eth_buf/TX_AXIS_MAC] [get_bd_intf_pins eth_mac/s_axis_tx] connect_bd_intf_net -intf_net eth_mac_gmii [get_bd_intf_pins eth_mac/gmii] [get_bd_intf_pins pcs_pma/gmii_pcs_pma] connect_bd_intf_net -intf_net eth_mac_m_axis_rx [get_bd_intf_pins eth_buf/RX_AXIS_MAC] [get_bd_intf_pins eth_mac/m_axis_rx] connect_bd_intf_net -intf_net mgt_clk_1 [get_bd_intf_ports mgt_clk] [get_bd_intf_pins pcs_pma/gtrefclk_in] connect_bd_intf_net -intf_net pcs_pma_sfp [get_bd_intf_ports sfp] [get_bd_intf_pins pcs_pma/sfp] connect_bd_intf_net -intf_net s_axi_1 [get_bd_intf_ports s_axi] [get_bd_intf_pins eth_buf/S_AXI] connect_bd_intf_net -intf_net s_axis_txc_1 [get_bd_intf_ports s_axis_txc] [get_bd_intf_pins eth_buf/AXI_STR_TXC] connect_bd_intf_net -intf_net s_axis_txd_1 [get_bd_intf_ports s_axis_txd] [get_bd_intf_pins eth_buf/AXI_STR_TXD] # Create port connections connect_bd_net -net axi_rxd_arstn_1 [get_bd_ports axi_rxd_arstn] [get_bd_pins eth_buf/AXI_STR_RXD_ARESETN] connect_bd_net -net axi_rxs_arstn_1 [get_bd_ports axi_rxs_arstn] [get_bd_pins eth_buf/AXI_STR_RXS_ARESETN] connect_bd_net -net axi_txc_arstn_1 [get_bd_ports axi_txc_arstn] [get_bd_pins eth_buf/AXI_STR_TXC_ARESETN] connect_bd_net -net axi_txd_arstn_1 [get_bd_ports axi_txd_arstn] [get_bd_pins eth_buf/AXI_STR_TXD_ARESETN] connect_bd_net -net axis_clk_1 [get_bd_ports axis_clk] [get_bd_pins eth_buf/AXI_STR_RXD_ACLK] [get_bd_pins eth_buf/AXI_STR_RXS_ACLK] [get_bd_pins eth_buf/AXI_STR_TXC_ACLK] [get_bd_pins eth_buf/AXI_STR_TXD_ACLK] connect_bd_net -net eth_buf_INTERRUPT [get_bd_ports interrupt] [get_bd_pins eth_buf/INTERRUPT] connect_bd_net -net eth_buf_RESET2PCSPMA [get_bd_pins eth_buf/RESET2PCSPMA] [get_bd_pins pcs_pma/reset] connect_bd_net -net eth_buf_RESET2TEMACn [get_bd_pins eth_buf/RESET2TEMACn] [get_bd_pins eth_mac/glbl_rstn] [get_bd_pins eth_mac/rx_axi_rstn] [get_bd_pins eth_mac/tx_axi_rstn] connect_bd_net -net eth_buf_pause_req [get_bd_pins eth_buf/pause_req] [get_bd_pins eth_mac/pause_req] connect_bd_net -net eth_buf_pause_val [get_bd_pins eth_buf/pause_val] [get_bd_pins eth_mac/pause_val] connect_bd_net -net eth_buf_tx_ifg_delay [get_bd_pins eth_buf/tx_ifg_delay] [get_bd_pins eth_mac/tx_ifg_delay] connect_bd_net -net eth_mac_mac_irq [get_bd_ports mac_irq] [get_bd_pins eth_mac/mac_irq] connect_bd_net -net eth_mac_mdc [get_bd_pins eth_mac/mdc] [get_bd_pins pcs_pma/mdc] connect_bd_net -net eth_mac_mdio_o [get_bd_pins eth_mac/mdio_o] [get_bd_pins pcs_pma/mdio_i] connect_bd_net -net eth_mac_rx_mac_aclk [get_bd_pins eth_buf/rx_mac_aclk] [get_bd_pins eth_mac/rx_mac_aclk] connect_bd_net -net eth_mac_rx_reset [get_bd_pins eth_buf/rx_reset] [get_bd_pins eth_mac/rx_reset] connect_bd_net -net eth_mac_rx_statistics_valid [get_bd_pins eth_buf/rx_statistics_valid] [get_bd_pins eth_mac/rx_statistics_valid] connect_bd_net -net eth_mac_rx_statistics_vector [get_bd_pins eth_buf/rx_statistics_vector] [get_bd_pins eth_mac/rx_statistics_vector] connect_bd_net -net eth_mac_speedis10100 [get_bd_pins eth_buf/speed_is_10_100] [get_bd_pins eth_mac/speedis10100] connect_bd_net -net eth_mac_tx_mac_aclk [get_bd_pins eth_buf/tx_mac_aclk] [get_bd_pins eth_mac/tx_mac_aclk] connect_bd_net -net eth_mac_tx_reset [get_bd_pins eth_buf/tx_reset] [get_bd_pins eth_mac/tx_reset] connect_bd_net -net pcs_pma_an_interrupt [get_bd_pins eth_buf/EMAC_CLIENT_AUTONEG_INT] [get_bd_pins pcs_pma/an_interrupt] connect_bd_net -net pcs_pma_gt0_qplloutclk_out [get_bd_ports gt0_qplloutclk_out] [get_bd_pins pcs_pma/gt0_qplloutclk_out] connect_bd_net -net pcs_pma_gt0_qplloutrefclk_out [get_bd_ports gt0_qplloutrefclk_out] [get_bd_pins pcs_pma/gt0_qplloutrefclk_out] connect_bd_net -net pcs_pma_gtrefclk_bufg_out [get_bd_ports gtref_clk_buf_out] [get_bd_pins pcs_pma/gtrefclk_bufg_out] connect_bd_net -net pcs_pma_gtrefclk_out [get_bd_ports gtref_clk_out] [get_bd_pins pcs_pma/gtrefclk_out] connect_bd_net -net pcs_pma_mdio_o [get_bd_pins eth_mac/mdio_i] [get_bd_pins pcs_pma/mdio_o] connect_bd_net -net pcs_pma_mmcm_locked_out [get_bd_ports mmcm_locked_out] [get_bd_pins eth_buf/EMAC_RX_DCM_LOCKED_INT] [get_bd_pins pcs_pma/mmcm_locked_out] connect_bd_net -net pcs_pma_pma_reset_out [get_bd_ports pma_reset_out] [get_bd_pins pcs_pma/pma_reset_out] connect_bd_net -net pcs_pma_resetdone [get_bd_pins eth_buf/EMAC_RESET_DONE_INT] [get_bd_pins pcs_pma/resetdone] connect_bd_net -net pcs_pma_rxuserclk2_out [get_bd_ports rxuserclk2_out] [get_bd_pins pcs_pma/rxuserclk2_out] connect_bd_net -net pcs_pma_rxuserclk_out [get_bd_ports rxuserclk_out] [get_bd_pins pcs_pma/rxuserclk_out] connect_bd_net -net pcs_pma_status_vector [get_bd_pins eth_buf/PCSPMA_STATUS_VECTOR] [get_bd_pins pcs_pma/status_vector] connect_bd_net -net pcs_pma_userclk2_out [get_bd_ports userclk2_out] [get_bd_pins eth_buf/GTX_CLK] [get_bd_pins eth_mac/gtx_clk] [get_bd_pins pcs_pma/userclk2_out] connect_bd_net -net pcs_pma_userclk_out [get_bd_ports userclk_out] [get_bd_pins pcs_pma/userclk_out] connect_bd_net -net ref_clk_1 [get_bd_ports ref_clk] [get_bd_pins pcs_pma/independent_clock_bufg] connect_bd_net -net s_axi_lite_clk_1 [get_bd_ports s_axi_lite_clk] [get_bd_pins eth_buf/S_AXI_ACLK] [get_bd_pins eth_mac/s_axi_aclk] connect_bd_net -net s_axi_lite_resetn_1 [get_bd_ports s_axi_lite_resetn] [get_bd_pins eth_buf/S_AXI_ARESETN] [get_bd_pins eth_mac/s_axi_resetn] connect_bd_net -net signal_detect_1 [get_bd_ports signal_detect] [get_bd_pins pcs_pma/signal_detect] # Create address segments create_bd_addr_seg -range 0x20000 -offset 0x0 [get_bd_addr_spaces eth_buf/S_AXI_2TEMAC] [get_bd_addr_segs eth_mac/s_axi/Reg] SEG_eth_mac_Reg create_bd_addr_seg -range 0x40000 -offset 0x0 [get_bd_addr_spaces s_axi] [get_bd_addr_segs eth_buf/S_AXI/Reg] SEG_eth_buf_REG # Restore current instance current_bd_instance $oldCurInst save_bd_design # generate_target -force synthesis [get_ips] } # End of create_root_design() ################################################################## # MAIN FLOW ################################################################## create_root_design "" make_wrapper -import -top [get_files $str_bd_filepath] ================================================ FILE: tests/spikehw/i2c-standard.json ================================================ { "iic_gpo": { "pins": "si5324_rst_n" }, "iic_sda": { "iic_main": "sda" }, "iic_scl": { "iic_main": "scl" } } ================================================ FILE: tests/spikehw/nfsume.json ================================================ { "eth_sgmii_rxp_v": { "sfp1": "rxp" }, "eth_sgmii_rxn_v": { "sfp1": "rxn" }, "eth_sgmii_txp": { "sfp1": "txp" }, "eth_sgmii_txn": { "sfp1": "txn" }, "eth_sfp_rxp_v": { "sfp1": "rxp" }, "eth_sfp_rxn_v": { "sfp1": "rxn" }, "eth_sfp_txp": { "sfp1": "txp" }, "eth_sfp_txn": { "sfp1": "txn" }, "eth_rx_los_v": { "sfp1": "rx_los" }, "eth_tx_disable": { "sfp1": "tx_disable" }, "uart_tx": { "uart": "d_out" }, "uart_rx_x": { "uart": "d_in" }, "uart_rts": { "uart": "rts" }, "uart_cts_x": { "uart": "cts" }, "iic_sda": { "i2c_main": "sda" }, "iic_scl": { "i2c_main": "scl" }, "iic_mux_reset": { "i2c_main": "mux_reset" }, "spi_sck": { "sdio": "clk" }, "spi_ss": { "sdio": "d3" }, "spi_mosi": { "sdio": "cmd" }, "spi_miso": { "sdio": "d0" }, "eth_mgt_clk_clk_p_v": { "pins": "si5324_clk_p", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "eth_mgt_clk_clk_n_v": { "pins": "si5324_clk_n", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "INPUT" }, "CLK_sfp_rec_clk_p": { "pins": "sfp_rec_clk_p", "IOSTANDARD": "DIFF_HSTL_II_18", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" }, "CLK_sfp_rec_clk_n": { "pins": "sfp_rec_clk_n", "IOSTANDARD": "DIFF_HSTL_II_18", "DIFF_TERM": "TRUE", "PIO_DIRECTION": "OUTPUT" } } ================================================ FILE: tests/spikehw/program.tcl ================================================ open_hw connect_hw_server open_hw_target current_hw_device [lindex [get_hw_devices] 0] set_property PROBES.FILE {/home/jamey/connectal.clean/tests/spikehw/debug.ltx} [lindex [get_hw_devices] 0] set_property PROGRAM.FILE {/home/jamey/connectal.clean/tests/spikehw/debug.bit} [lindex [get_hw_devices] 0] program_hw_devices [lindex [get_hw_devices] 0] quit ================================================ FILE: tests/spikehw/rtscts.json ================================================ { "uart_rts": { "uart": "rts" }, "uart_cts_x": { "uart": "cts" } } ================================================ FILE: tests/spikehw/spikehw-miniitx100.json ================================================ { "eth_rx_los_v": { "sfp1": "rx_los" }, "eth_tx_disable": { "sfp1": "tx_disable" }, "iic_sda": { "sfp1": "mod_def2", "PIO_DIRECTION": "BIDIR" }, "iic_scl": { "sfp1": "mod_def1", "PIO_DIRECTION": "BIDIR" }, "iic_mux_reset": { "sfp1": "mod_def0", "PIO_DIRECTION": "OUTPUT", "comment": "not connected" } } ================================================ FILE: tests/spikehw/spikehw-vc707g2.json ================================================ { "eth_mgt_clk_clk_p_v": { "pins": "sgmii_clk_p" }, "eth_mgt_clk_clk_n_v": { "pins": "sgmii_clk_n" } } ================================================ FILE: tests/spikehw/spikehw-vc709.json ================================================ { "eth_mgt_clk_clk_p_v": { "pins": "si5324_clk_p" }, "eth_mgt_clk_clk_n_v": { "pins": "si5324_clk_n" } } ================================================ FILE: tests/spikehw/spikehw.cpp ================================================ #include #include #include #include #include #include #include #include #include "dmaManager.h" #include "spikehw.h" #ifdef REGISTER_SPIKE_DEVICES #include #include #include #endif int verbose = 0; class SpikeHwIndication : public SpikeHwIndicationWrapper { sem_t sem; public: int irq; uint32_t buf[16]; IrqCallback irqCallback; void traceDmaRequest(DmaChannel chan, int write, uint16_t objId, uint32_t offset, uint16_t burstLen) { fprintf(stderr, "traceDmaRequest chan=%d write=%d objId=%d offset=%08x burstLen=%d\n", chan, write, objId, offset, burstLen); } void traceDmaData ( const DmaChannel chan, const int write, const uint32_t data, const int last ) { fprintf(stderr, "traceDmaData chan=%d write=%d data=%08x last=%d\n", chan, write, data, last); } void irqChanged( const uint8_t irq, const uint16_t intrSources ) { if (intrSources & 0xe) fprintf(stderr, "iic intr=%d %04x\n", irq, intrSources); if (verbose) fprintf(stderr, "SpikeHw::irqChanged %d intr sources %x\n", irq, intrSources); this->irq = irq; if (irqCallback) irqCallback(irq); } virtual void resetDone() { fprintf(stderr, "reset done\n"); sem_post(&sem); } virtual void status ( const uint8_t reset_asserted, const uint8_t mmcm_locked, const uint8_t rx_los, const uint8_t irq, const uint16_t intrSources ) { fprintf(stderr, "spikehw status reset_asserted=%d mmcm_locked=%d rx_los=%d irq=%d intr sources=%x\n", reset_asserted, mmcm_locked, rx_los, irq, intrSources); sem_post(&sem); } void wait() { struct timespec timeout; timeout.tv_sec = 1000; timeout.tv_nsec = 0; if (0) { for (int tries = 0; tries < 10; tries++) { int status = sem_timedwait(&sem, &timeout); if (status != 0 && errno == ETIMEDOUT) { if (tries > 5) fprintf(stderr, "%s:%d: try %d timed out waiting for response status=%d errno=%d\n", __FILE__, __LINE__, tries, status, errno); } else { break; } } } else { sem_wait(&sem); } } void readDone ( const uint32_t value ) { buf[0] = value; if (verbose) fprintf(stderr, "readDone value=%08x\n", value); sem_post(&sem); } void writeDone ( ) { if (verbose) fprintf(stderr, "writeDone\n"); sem_post(&sem); } void readFlashDone ( const uint32_t value ) { buf[0] = value; if (verbose) fprintf(stderr, "readFlashDone value=%08x\n", value); sem_post(&sem); } void writeFlashDone ( ) { if (verbose) fprintf(stderr, "writeFlashDone\n"); sem_post(&sem); } SpikeHwIndication(unsigned int id, IrqCallback callback=0) : SpikeHwIndicationWrapper(id), irq(0), irqCallback(callback) { sem_init(&sem, 0, 0); } }; SpikeHwRequestProxy *request; SpikeHwIndication *indication; SpikeHw::SpikeHw(IrqCallback callback) : request(0), indication(0), dmaManager(0), didReset(false), mainMemFd(0) { request = new SpikeHwRequestProxy(IfcNames_SpikeHwRequestS2H); indication = new SpikeHwIndication(IfcNames_SpikeHwIndicationH2S, callback); dmaManager = platformInit(); request->reset(); request->setFlashParameters(100); request->iicReset(0); // de-assert reset } SpikeHw::~SpikeHw() { //delete request; //delete indication; request = 0; indication = 0; } void SpikeHw::maybeReset() { if (0) if (!didReset) { fprintf(stderr, "resetting flash\n"); request->reset(); indication->wait(); //request->setParameters(50, 0); fprintf(stderr, "done resetting flash\n"); didReset = true; } } void SpikeHw::status() { request->status(); indication->wait(); } void SpikeHw::setupDma(uint32_t memfd) { int memref = dmaManager->reference(memfd); fprintf(stderr, "SpikeHw::setupDma memfd=%d memref=%d\n", memfd, memref); request->setupDma(memref); } void SpikeHw::read(unsigned long offset, uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "SpikeHw::read offset=%lx\n", offset); request->read(offset); indication->wait(); if (verbose) fprintf(stderr, "SpikeHw::read offset=%lx value=%x\n", offset, *(uint32_t *)indication->buf); memcpy(buf, indication->buf, 4); } void SpikeHw::write(unsigned long offset, const uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "SpikeHw::write offset=%lx value=%x\n", offset, *(uint32_t *)buf); request->write(offset, *(uint32_t *)buf); indication->wait(); //request->status(); //indication->wait(); } uint32_t SpikeHw::read(unsigned long offset) { maybeReset(); if (verbose) fprintf(stderr, "SpikeHw::read offset=%08lx\n", offset); request->read(offset); indication->wait(); if (verbose) fprintf(stderr, "SpikeHw::read done value=%x\n", *(uint32_t *)indication->buf); return *(uint32_t *)indication->buf; } void SpikeHw::write(unsigned long offset, const uint32_t value) { maybeReset(); if (verbose) fprintf(stderr, "SpikeHw::write offset=%08lx value=%x\n", offset, value); request->write(offset, value); indication->wait(); if (verbose) fprintf(stderr, "SpikeHw::write done\n"); } void SpikeHw::setFlashParameters(unsigned long cycles) { request->setFlashParameters(cycles); } void SpikeHw::readFlash(unsigned long offset, uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "SpikeHw::readFlash offset=%lx\n", offset); request->readFlash(offset); indication->wait(); if (verbose) fprintf(stderr, "SpikeHw::readFlash offset=%lx value=%x\n", offset, *(uint32_t *)indication->buf); memcpy(buf, indication->buf, 4); } void SpikeHw::writeFlash(unsigned long offset, const uint8_t *buf) { maybeReset(); if (verbose) fprintf(stderr, "SpikeHw::writeFlash offset=%lx value=%x\n", offset, *(uint32_t *)buf); request->writeFlash(offset, *(uint32_t *)buf); indication->wait(); } bool SpikeHw::hasInterrupt() { return indication->irq; } void SpikeHw::clearInterrupt() { indication->irq = 0; } char *SpikeHw::allocate_mem(size_t memsz) { int memfd = portalAlloc(memsz, 1); if (memfd < 0) return 0; char *buf = (char *)portalMmap(memfd, memsz); if (buf == MAP_FAILED) { close(memfd); return 0; } fprintf(stderr, "SpikeHw::allocate_mem memsz=%lx memfd=%d buf=%p\n", memsz, memfd, buf); if (!mainMemFd) { setupDma(memfd); mainMemFd = memfd; fprintf(stderr, "SpikeHw::allocate_mem mainMemFd=%d\n", memfd); } return buf; } SpikeHw *spikeHw; #ifdef REGISTER_SPIKE_DEVICES class spikehw_device_t : public abstract_device_t { public: spikehw_device_t(); bool has_interrupt(); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); static abstract_device_t *make_device(); }; spikehw_device_t::spikehw_device_t() { if (!spikeHw) spikeHw = new SpikeHw(); } bool spikehw_device_t::has_interrupt() { if (spikeHw->hasInterrupt()) { spikeHw->clearInterrupt(); return true; } return false; } bool spikehw_device_t::load(reg_t addr, size_t len, uint8_t* bytes) { spikeHw->read(addr, bytes); // always reads 4 bytes return true; } bool spikehw_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) { spikeHw->write(addr, bytes); return true; } abstract_device_t *spikehw_device_t::make_device() { std::cerr << "make_device called" << std::endl; return new spikehw_device_t(); } class spikeflash_device_t : public abstract_device_t { public: spikeflash_device_t(); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); static abstract_device_t *make_device(); }; spikeflash_device_t::spikeflash_device_t() { if (!spikeHw) spikeHw = new SpikeHw(); } bool spikeflash_device_t::load(reg_t addr, size_t len, uint8_t* bytes) { if (addr & 1 && len != 1) fprintf(stderr, "spikeflash::load addr=%08lx len=%ld\n", addr, len); if (addr & 1) { uint8_t data[2]; spikeHw->readFlash(addr, data); // always reads 4 bytes bytes[0] = data[1]; if (len > 1) return false; else return true; } while (len) { spikeHw->readFlash(addr, bytes); // always reads 4 bytes if (len < 2) break; addr += 2; bytes += 2; len -= 2; } return true; } bool spikeflash_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) { //fprintf(stderr, "spikeflash::store addr=%08lx len=%ld bytes=%02x\n", addr, len, *(uint16_t *)bytes); if (len != 2) return false; spikeHw->writeFlash(addr, bytes); return true; } abstract_device_t *spikeflash_device_t::make_device() { std::cerr << "spikeflash_device_t::make_device called" << std::endl; return new spikeflash_device_t(); } class devicetree_device_t : public abstract_device_t { public: devicetree_device_t(); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); static abstract_device_t *make_device(); private: const char *dtb; size_t dtbsz; }; devicetree_device_t::devicetree_device_t() { int fd = open("devicetree.dtb", O_RDONLY); if (fd > 0) { struct stat statbuf; int status = fstat(fd, &statbuf); fprintf(stderr, "fstat status %d size %ld\n", status, statbuf.st_size); if (status == 0) { dtb = (const char *)mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); dtbsz = statbuf.st_size; fprintf(stderr, "mapped dtb at %p (%ld bytes)\n", dtb, dtbsz); } close(fd); } else { fprintf(stderr, "Could not open devicetree.dtb\n"); } } bool devicetree_device_t::load(reg_t addr, size_t len, uint8_t* bytes) { if (dtb && dtb != MAP_FAILED) { if ((addr < dtbsz) && (bytes != 0)) { memcpy(bytes, dtb + addr, len); return true; } } return false; } bool devicetree_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) { return true; } abstract_device_t *devicetree_device_t::make_device() { std::cerr << "devicetree_device_t::make_device called" << std::endl; return new devicetree_device_t(); } //REGISTER_MEM_ALLOCATOR(SpikeHw::allocate_mem); REGISTER_DEVICE(devicetree, 0x04080000, devicetree_device_t::make_device); REGISTER_DEVICE(spikehw, 0x04100000, spikehw_device_t::make_device); REGISTER_DEVICE(spikeflash, 0x08000000, spikeflash_device_t::make_device); #endif #ifndef REGISTER_SPIKE_DEVICES extern "C" { struct FpgaOps { uint64_t (*read)(uint64_t addr); void (*write)(uint64_t addr, uint64_t value); void (*close)(); void *(*alloc_mem)(size_t size); }; uint64_t fpga_read(uint64_t addr) { uint64_t val = spikeHw->read(0x100000 + addr); return val; } void fpga_write(uint64_t addr, uint64_t value) { spikeHw->write(0x100000 + addr, value); } void fpga_close() { } void *fpga_alloc_mem(size_t size) { return (void *)spikeHw->allocate_mem(size);; } void *fpgadev_init(void (*irqCallback)(int irq)) { fprintf(stderr, "connectal.so init called\n"); if (!spikeHw) spikeHw = new SpikeHw(irqCallback); struct FpgaOps *ops = (struct FpgaOps *)malloc(sizeof(struct FpgaOps)); ops->read = fpga_read; ops->write = fpga_write; ops->close = fpga_close; ops->alloc_mem = fpga_alloc_mem; return ops; } } #endif ================================================ FILE: tests/spikehw/spikehw.h ================================================ #ifndef SPIKEHW_H #define SPIKEHW_H #include class SpikeHwRequestProxy; class SpikeHwIndication; class DmaManager; typedef void (*IrqCallback)(int irq); class SpikeHw { public: SpikeHw(IrqCallback callback=0); ~SpikeHw(); int irq ( const uint8_t newLevel ); void status(); void read(unsigned long offset, uint8_t *buf); void write(unsigned long offset, const uint8_t *buf); uint32_t read(unsigned long offset); void write(unsigned long offset, const uint32_t value); void setFlashParameters(unsigned long cycles); void readFlash(unsigned long offset, uint8_t *buf); void writeFlash(unsigned long offset, const uint8_t *buf); bool hasInterrupt(); void clearInterrupt(); char *allocate_mem(size_t memsz); private: void setupDma( uint32_t memfd ); SpikeHwRequestProxy *request; SpikeHwIndication *indication; DmaManager *dmaManager; bool didReset; int mainMemFd; void maybeReset(); }; #endif ================================================ FILE: tests/spikehw/spikehw.json ================================================ { "eth_sfp_rxp_v": { "sfp1": "rxp" }, "eth_sfp_rxn_v": { "sfp1": "rxn" }, "eth_sfp_txp": { "sfp1": "txp" }, "eth_sfp_txn": { "sfp1": "txn" }, "flash_data_0": { "bpi_flash": "data[0]" }, "flash_data_1": { "bpi_flash": "data[1]" }, "flash_data_2": { "bpi_flash": "data[2]" }, "flash_data_3": { "bpi_flash": "data[3]" }, "flash_data_4": { "bpi_flash": "data[4]" }, "flash_data_5": { "bpi_flash": "data[5]" }, "flash_data_6": { "bpi_flash": "data[6]" }, "flash_data_7": { "bpi_flash": "data[7]" }, "flash_data_8": { "bpi_flash": "data[8]" }, "flash_data_9": { "bpi_flash": "data[9]" }, "flash_data_10": { "bpi_flash": "data[10]" }, "flash_data_11": { "bpi_flash": "data[11]" }, "flash_data_12": { "bpi_flash": "data[12]" }, "flash_data_13": { "bpi_flash": "data[13]" }, "flash_data_14": { "bpi_flash": "data[14]" }, "flash_data_15": { "bpi_flash": "data[15]" }, "flash_addr[0]": { "bpi_flash": "addr[0]" }, "flash_addr[1]": { "bpi_flash": "addr[1]" }, "flash_addr[2]": { "bpi_flash": "addr[2]" }, "flash_addr[3]": { "bpi_flash": "addr[3]" }, "flash_addr[4]": { "bpi_flash": "addr[4]" }, "flash_addr[5]": { "bpi_flash": "addr[5]" }, "flash_addr[6]": { "bpi_flash": "addr[6]" }, "flash_addr[7]": { "bpi_flash": "addr[7]" }, "flash_addr[8]": { "bpi_flash": "addr[8]" }, "flash_addr[9]": { "bpi_flash": "addr[9]" }, "flash_addr[10]": { "bpi_flash": "addr[10]" }, "flash_addr[11]": { "bpi_flash": "addr[11]" }, "flash_addr[12]": { "bpi_flash": "addr[12]" }, "flash_addr[13]": { "bpi_flash": "addr[13]" }, "flash_addr[14]": { "bpi_flash": "addr[14]" }, "flash_addr[15]": { "bpi_flash": "addr[15]" }, "flash_addr[16]": { "bpi_flash": "addr[16]" }, "flash_addr[17]": { "bpi_flash": "addr[17]" }, "flash_addr[18]": { "bpi_flash": "addr[18]" }, "flash_addr[19]": { "bpi_flash": "addr[19]" }, "flash_addr[20]": { "bpi_flash": "addr[20]" }, "flash_addr[21]": { "bpi_flash": "addr[21]" }, "flash_addr[22]": { "bpi_flash": "addr[22]" }, "flash_addr[23]": { "bpi_flash": "addr[23]" }, "flash_addr[24]": { "bpi_flash": "addr[24]" }, "flash_addr[25]": { "bpi_flash": "addr[25]" }, "flash_oe_b": { "bpi_flash": "oe_b" }, "flash_ce_b": { "bpi_flash": "ce_b" }, "flash_adv_b": { "bpi_flash": "adv_b" }, "flash_we_b": { "bpi_flash": "we_b" }, "flash_wait_in_b": { "bpi_flash": "wait_in_b" }, "uart_tx": { "uart": "d_out" }, "uart_rx_x": { "uart": "d_in" }, "uart_rts": { "uart": "rts" }, "uart_cts_x": { "uart": "cts" }, "iic_gpo": { "pins": "si5324_rst_n" }, "iic_sda": { "iic_main": "sda" }, "iic_scl": { "iic_main": "scl" } } ================================================ FILE: tests/spikehw/spikehw.xdc ================================================ create_clock -name eth_mgt_clk_clk -period 8.000 [get_ports eth_mgt_clk_clk_p_v] ================================================ FILE: tests/spikehw/test-spikehw.cpp ================================================ #include #include "spikehw.h" #ifdef REGISTER_SPIKE_DEVICES #include #include #include #include #include #endif static SpikeHw *spikeHw; #ifdef REGISTER_SPIKE_DEVICES // spike stubs std::map>& devices() { static std::map> v; return v; } void register_device(reg_t addr, std::function f) { } void register_mem_allocator(std::function f) { } #endif const char *regnames[] = { "CR", "SR", "TX_FIFO", "RX_FIFO", "ADR", "TX_FIFO_OCY", "RX_FIFO_OCY", "TBA", "RX_FIFO_DEPTH", "GPO" }; static void dumpI2cRegs() { fprintf(stderr, "------------------------------------------------------------\n"); fprintf(stderr, "I2C GIE %04x\n", spikeHw->read(0x10301c)); fprintf(stderr, "I2C ISR %04x\n", spikeHw->read(0x103020)); fprintf(stderr, "I2C IER %04x\n", spikeHw->read(0x103028)); for (int i = 0; i < 10; i++) fprintf(stderr, "I2C REG%d %s %04x\n", i, regnames[i], spikeHw->read(0x103100 + 4*i)); fprintf(stderr, "------------------------------------------------------------\n"); } int main(int argc, const char **argv) { spikeHw = new SpikeHw(); // not needed yet //spikeHw->setupDma(memfd); // query mmcm and interrupt status spikeHw->status(); fprintf(stderr, "boot rom[0] %x\n", spikeHw->read(0)); fprintf(stderr, "scratch register %x\n", spikeHw->read(0x10001c)); spikeHw->write(0x10001c, 0x22); fprintf(stderr, "scratch register %x\n", spikeHw->read(0x10001c)); fprintf(stderr, "scratch register %x\n", spikeHw->read(0x10001c)); fprintf(stderr, "scratch register %x\n", spikeHw->read(0x10001c)); fprintf(stderr, "scratch register %x\n", spikeHw->read(0x10001c)); spikeHw->read(0x100000); spikeHw->write(0x100000, 'h'); spikeHw->write(0x103040, 0xa); // SOFTR dumpI2cRegs(); // let's read i2c 0x50 spikeHw->write(0x103108, 0x100 | (0x56 << 1) | 1); // TX_FIFO spikeHw->write(0x103120, 1); // RX_FIFO_DEPTH spikeHw->write(0x103100, 5); // CR enable spikeHw->write(0x103108, (uint32_t)1); // TX_FIFO spikeHw->write(0x103108, 0x200 | 2); // TX_FIFO fprintf(stderr, "I2C RX_FIFO_OCY %04x\n", spikeHw->read(0x103118)); dumpI2cRegs(); dumpI2cRegs(); dumpI2cRegs(); dumpI2cRegs(); return 0; // let's write 1 to 0x50 spikeHw->write(0x103108, 0x100 | (0x56 << 1) | 0); // TX_FIFO spikeHw->write(0x103100, 5); // CR enable spikeHw->write(0x103108, 0x200 | 1); // TX_FIFO dumpI2cRegs(); // let's read i2c 0x50 spikeHw->write(0x103108, 0x100 | (0x56 << 1) | 1); // TX_FIFO spikeHw->write(0x103120, 2); // RX_FIFO_DEPTH spikeHw->write(0x103100, 5); // CR enable spikeHw->write(0x103108, 0x200 | 1); // TX_FIFO fprintf(stderr, "I2C RX_FIFO_OCY %04x\n", spikeHw->read(0x103118)); dumpI2cRegs(); return 0; // read boot rom uint32_t word = 0; uint32_t expected[] = { 0x00001137, 0x010000ef, 0x20000513, 0x00050067, 0x0000006f, 0x040007b7, 0x40078793, 0xfc0005b7 }; for (int i = 0; i < 8; i++){ spikeHw->read(0x000000 + i*4, (uint8_t *)&word); fprintf(stderr, "word %04x of boot ROM %08x (expected %08x)\n", i*4, word, expected[i]); } // read ethernet identification register uint32_t id; spikeHw->read(0x180000 + 0x4f8, (uint8_t *)&id); fprintf(stderr, "AXI Ethernet Identification %08x (expected %08x)\n", id, 0x09000000); // put flash in query mode spikeHw->setFlashParameters(50); // divides clock by 50 uint32_t values[4] = { 0x98 }; spikeHw->writeFlash(0x00aa, (uint8_t *)&values[0]); spikeHw->readFlash(0x0020, (uint8_t *)&values[1]); spikeHw->readFlash(0x0022, (uint8_t *)&values[2]); spikeHw->readFlash(0x0024, (uint8_t *)&values[3]); fprintf(stderr, "Query flash %02x.%02x.%02x %c%c%c (expected QRY)\n", values[1], values[2], values[3], values[1], values[2], values[3]); return 0; } ================================================ FILE: tests/spikehw/trace.tcl ================================================ open_hw connect_hw_server open_hw_target current_hw_device [lindex [get_hw_devices] 0] set_property PROBES.FILE {/home/jamey/connectal.clean/tests/spikehw/debug.ltx} [lindex [get_hw_devices] 0] set_property PROGRAM.FILE {/home/jamey/connectal.clean/tests/spikehw/debug.bit} [lindex [get_hw_devices] 0] refresh_hw_device [lindex [get_hw_devices] 0] set_property TRIGGER_COMPARE_VALUE eq1'h0 [get_hw_probes tile_0_lSpikeHw_sda_t_probe_PROBE -of_objects [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}]] set_property CONTROL.TRIGGER_MODE BASIC_ONLY [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}] set_property CONTROL.TRIGGER_POSITION 1000 [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}] #set_property CONTROL.DATA_DEPTH 131072 [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}] run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}] wait_on_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}] upload_hw_ila_data [get_hw_ilas -of_objects [get_hw_devices xc7vx690t_0] -filter {CELL_NAME=~"u_ila_0"}] write_hw_ila_data -force debug.vcd -vcd_file [current_hw_ila_data] ================================================ FILE: tests/test_pmod/Controller.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Leds::*; interface PmodPins; method Bit#(8) pmod(); endinterface interface PmodControllerRequest; method Action rst(Bit#(32) v); endinterface interface PmodControllerIndication; method Action rst(Bit#(32) v); endinterface interface Controller; interface PmodControllerRequest req; interface PmodPins pins; interface LEDS leds; endinterface module mkController#(PmodControllerIndication ind)(Controller); Reg#(Bit#(8)) data_reg <- mkReg(0); Reg#(Bit#(8)) leds_reg <- mkReg(0); Reg#(Bool) rst_reg <- mkReg(False); rule count; if (rst_reg) begin rst_reg <= False; data_reg <= 0; leds_reg <= data_reg; end else begin data_reg <= data_reg+1; end endrule interface PmodControllerRequest req; method Action rst(Bit#(32) v); rst_reg <= True; ind.rst(v); endmethod endinterface interface PmodPins pins; method Bit#(8) pmod() = data_reg._read; endinterface interface LEDS leds; method Bit#(LedsWidth) leds() = truncate(leds_reg); endinterface endmodule ================================================ FILE: tests/test_pmod/Makefile ================================================ CONNECTALDIR ?= ../.. INTERFACES = PmodControllerRequest PmodControllerIndication BSVFILES = Controller.bsv Top.bsv CPPFILES= testpmod.cpp PIN_TYPE = PmodPins PIN_TYPE_INCLUDE = Controller CONNECTALFLAGS = -C $(BOARD)/sources/pinout-$(BOARD).xdc PIN_BINDING ?= -b pmod:pmoda gentarget:: $(BOARD)/sources/pinout-$(BOARD).xdc $(BOARD)/sources/pinout-$(BOARD).xdc: pinout.json $(CONNECTALDIR)/boardinfo/$(BOARD).json mkdir -p $(BOARD)/sources $(CONNECTALDIR)/scripts/generate-constraints.py $(PIN_BINDING) -o $(BOARD)/sources/pinout-$(BOARD).xdc --boardfile $(CONNECTALDIR)/boardinfo/$(BOARD).json --pinoutfile pinout.json include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/test_pmod/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import CtrlMux::*; import Portal::*; import ConnectalMemTypes::*; import ConnectalConfig::*; import PmodControllerRequest::*; import PmodControllerIndication::*; import Controller::*; typedef enum {IfcNames_ControllerRequest, IfcNames_ControllerIndication} IfcNames deriving (Eq,Bits); module mkConnectalTop(ConnectalTop); PmodControllerIndicationProxy cp <- mkPmodControllerIndicationProxy(IfcNames_ControllerIndication); Controller controller <- mkController(cp.ifc); PmodControllerRequestWrapper cw <- mkPmodControllerRequestWrapper(IfcNames_ControllerRequest, controller.req); Vector#(2,StdPortal) portals; portals[0] = cp.portalIfc; portals[1] = cw.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; interface pins = controller.pins; endmodule : mkConnectalTop export Controller::*; export mkConnectalTop; ================================================ FILE: tests/test_pmod/pinout.json ================================================ { "pmod[0]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J1" }, "pmod[1]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J2" }, "pmod[2]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J3" }, "pmod[3]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J4" }, "pmod[4]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J7" }, "pmod[5]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J8" }, "pmod[6]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J9" }, "pmod[7]" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J10" } } ================================================ FILE: tests/test_pmod/testpmod.cpp ================================================ #include #include #include #include #include #include "PmodControllerRequest.h" #include "PmodControllerIndication.h" #include "GeneratedTypes.h" class PmodControllerIndication : public PmodControllerIndicationWrapper { public: PmodControllerIndication(int id) : PmodControllerIndicationWrapper(id) {} virtual void rst ( const uint32_t v ) { fprintf(stderr, "PmodControllerIndication::rst(%08x)\n", v); } }; int main(int argc, const char **argv) { PmodControllerIndication *ind = new PmodControllerIndication(IfcNames_ControllerIndication); PmodControllerRequestProxy *device = new PmodControllerRequestProxy(IfcNames_ControllerRequest); for(int i = 0; i < 10; i++) { device->rst(i); sleep(1); } } ================================================ FILE: tests/test_sdio1/Makefile ================================================ CONNECTALDIR ?= ../.. INTERFACES = SDIORequest SDIOResponse BSVFILES = Top.bsv SDIO.bsv CPPFILES= test_sdio1.cpp CONNECTALFLAGS += -D PS7EXTENDED -D IMPORT_HOSTIF PIN_TYPE = TestSDIO1Pins PIN_TYPE_INCLUDE = SDIO PINOUT_FILE = pinout.json PIN_BINDINGS = pmod:pmodd include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/test_sdio1/SDIO.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import ConnectalXilinxCells::*; import PPS7LIB::*; import FrequencyCounter::*; import ConnectalClocks::*; import XilinxCells::*; import Clocks::*; (* always_ready, always_enabled *) interface SDIOPins; method Bit#(1) clk; interface Inout#(Bit#(1)) cmd; interface Inout#(Bit#(1)) d0; interface Inout#(Bit#(1)) d1; interface Inout#(Bit#(1)) d2; interface Inout#(Bit#(1)) d3; method Action cdn(Bit#(1) v); method Action wp(Bit#(1) v); endinterface interface SDIORequest; method Action cnt_cycle_req(Bit#(32) v); method Action set_spew_en(Bit#(1) v); method Action toggle_cd(Bit#(32) v); endinterface interface SDIOResponse; method Action cnt_cycle_resp(Bit#(32) v); method Action emio_sample(Bit#(32) v); endinterface interface Controller; interface SDIOPins pins; interface SDIORequest req; endinterface module mkController#(SDIOResponse ind, Pps7Emiosdio sdio)(Controller); B2C1 b2c <- mkB2C1(); Clock sdio_clk <- mkClockBUFG(clocked_by b2c.c); rule tx_sdio_clk; b2c.inputclock(sdio.clk); endrule Reset def_rst <- exposeCurrentReset(); Reset sdio_rst <- mkAsyncReset(2, def_rst, sdio_clk); FrequencyCounter fc <- mkFrequencyCounter(sdio_clk, sdio_rst); Reg#(Bit#(1)) spew_en <- mkReg(0); let cmdb <- mkIOBUF(sdio.cmdtn, sdio.cmdo); let d0b <- mkIOBUF(sdio.datatn[0], sdio.datao[0]); let d1b <- mkIOBUF(sdio.datatn[1], sdio.datao[1]); let d2b <- mkIOBUF(sdio.datatn[2], sdio.datao[2]); let d3b <- mkIOBUF(sdio.datatn[3], sdio.datao[3]); Reg#(Bit#(32)) toggle_cd_reg <- mkReg(0); Bit#(4) db_o = {d3b.o,d2b.o,d1b.o,d0b.o}; Bit#(1) cmdb_o = cmdb.o; (* fire_when_enabled, no_implicit_conditions *) rule xxx; sdio.cmdi(cmdb_o); sdio.datai(db_o); sdio.clkfb(sdio.clk); endrule rule emio_sample_rule if (spew_en == 1); ind.emio_sample({0, db_o, sdio.datatn, sdio.datao, cmdb_o, sdio.cmdtn, sdio.cmdo, sdio.clk}); endrule rule cnt_cycle_resp_rule; let v <- fc.elapsedCycles; ind.cnt_cycle_resp(v); endrule rule decr_toggle_cd_reg (toggle_cd_reg > 0); toggle_cd_reg <= toggle_cd_reg-1; endrule interface SDIORequest req; method Action cnt_cycle_req(Bit#(32) v); fc.start(v); endmethod method Action set_spew_en(Bit#(1) v); spew_en <= v; endmethod method Action toggle_cd(Bit#(32) v); toggle_cd_reg <= v; endmethod endinterface interface SDIOPins pins; method Bit#(1) clk = sdio.clk; interface cmd = cmdb.io; interface d0 = d0b.io; interface d1 = d1b.io; interface d2 = d2b.io; interface d3 = d3b.io; method Action cdn(Bit#(1) v) = sdio.cdn((toggle_cd_reg > 0) ? ~v : v); method Action wp(Bit#(1) v) = sdio.wp(v); endinterface endmodule ================================================ FILE: tests/test_sdio1/Top.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import HostInterface::*; import Vector::*; import CtrlMux::*; import Portal::*; import ConnectalMemTypes::*; import SDIORequest::*; import SDIOResponse::*; import SDIO::*; import Leds::*; import PS7LIB::*; typedef enum {IfcNames_ControllerRequest, IfcNames_ControllerResponse} IfcNames deriving (Eq,Bits); interface TestSDIO1Pins; interface SDIOPins sdio; interface LEDS leds; endinterface module mkConnectalTop#(HostInterface host)(ConnectalTop); SDIOResponseProxy cp <- mkSDIOResponseProxy(IfcNames_ControllerResponse); Controller controller <- mkController(cp.ifc, host.ps7.emiosdio1); SDIORequestWrapper cw <- mkSDIORequestWrapper(IfcNames_ControllerRequest, controller.req); Vector#(2,StdPortal) portals; portals[0] = cp.portalIfc; portals[1] = cw.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; interface TestSDIO1Pins pins; interface sdio = controller.pins; interface leds = ?; endinterface endmodule : mkConnectalTop export TestSDIO1Pins; export mkConnectalTop; ================================================ FILE: tests/test_sdio1/pinout.json ================================================ { "sdio_clk" : { "PIO_DIRECTION": "OUTPUT", "pmod" : "J4" }, "sdio_cdn_v" : { "PIO_DIRECTION": "INPUT", "pmod" : "J9" }, "sdio_wp_v" : { "PIO_DIRECTION": "INPUT", "pmod" : "J10" }, "sdio_cmd" : { "PIO_DIRECTION": "BIDIR", "pmod" : "J2" }, "sdio_d0" : { "PIO_DIRECTION": "BIDIR", "pmod" : "J3" }, "sdio_d1" : { "PIO_DIRECTION": "BIDIR", "pmod" : "J7" }, "sdio_d2" : { "PIO_DIRECTION": "BIDIR", "pmod" : "J8" }, "sdio_d3" : { "PIO_DIRECTION": "BIDIR", "pmod" : "J1" }, "leds_leds[0]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L0" }, "leds_leds[1]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L1" }, "leds_leds[2]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L2" }, "leds_leds[3]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L3" }, "leds_leds[4]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L4" }, "leds_leds[5]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L5" }, "leds_leds[6]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L6" }, "leds_leds[7]" : { "PIO_DIRECTION": "OUTPUT", "leds" : "L7" } } ================================================ FILE: tests/test_sdio1/test_sdio1.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include "SDIORequest.h" #include "SDIOResponse.h" uint32_t bit_sel(uint32_t lsb, uint32_t msb, uint32_t v) { return (v >> lsb) & ~(~0 << (msb-lsb+1)); } class SDIOResponse : public SDIOResponseWrapper { public: virtual void read_resp(uint8_t v){ fprintf(stderr, "read_resp cd:%d wp:%d\n", (v&2)>>1, v&1); } virtual void emio_sample(uint32_t v){ int clk = bit_sel(0,0,v); int cmdo = bit_sel(1,1,v); int cmdtn = bit_sel(2,2,v); int cmdi = bit_sel(3,3,v); int datao = bit_sel(4,7,v); int datatn = bit_sel(8,11,v); int datai = bit_sel(12,15,v); fprintf(stderr, "emio_sample(%08x): datai:%X datatn:%X datao:%X cmdi:%X, cmdtn:%X, cmdo:%X, clk:%X\n", v, datai, datatn, datao, cmdi, cmdtn, cmdo, clk); } virtual void cnt_cycle_resp(uint32_t v){ fprintf(stderr, "cnt_cycle_resp %d\n", v); } SDIOResponse(unsigned int id) : SDIOResponseWrapper(id){} }; int main(int argc, const char **argv) { SDIORequestProxy *device = new SDIORequestProxy(IfcNames_ControllerRequest); SDIOResponse *ind = new SDIOResponse(IfcNames_ControllerResponse); //sleep(2); // device->toggle_cd(1000); // device->set_spew_en(1); // while(true){ // device->cnt_cycle_req(100); // sleep(2); // } } ================================================ FILE: tests/test_spi0/Makefile ================================================ CONNECTALDIR ?= ../.. INTERFACES = SPIRequest SPIResponse BSVFILES = Top.bsv SPI.bsv CPPFILES= test_spi0.cpp CONNECTALFLAGS += -D PS7EXTENDED -D IMPORT_HOSTIF include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/test_spi0/SPI.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import Vector::*; import ConnectalXilinxCells::*; import PPS7LIB::*; import FrequencyCounter::*; import ConnectalClocks::*; import XilinxCells::*; import Clocks::*; import BRAMFIFO::*; import FIFOF::*; typedef struct { Bit#(1) mo; Bit#(1) motn; Bit#(3) sson; Bit#(1) ssntn; Bit#(1) sclko; Bit#(1) sclktn; Bit#(16) cnt; } Spew deriving (Eq,Bits); typedef struct { Bit#(1) clk_sel; Bit#(32) clk_cnt; } CycleReq deriving (Eq,Bits); interface SPIRequest; method Action cnt_cycle_req(CycleReq v); method Action set_spew_en(Bit#(32) v); method Action set_clk_inv(Bit#(1) v); method Action set_spew_src(Bit#(1) v); endinterface interface SPIResponse; method Action cnt_cycle_resp(Bit#(32) v); method Action emio_sample(Spew v); method Action spi_word(Bit#(32) v); endinterface interface Controller; interface SPIRequest req; endinterface module mkController#(SPIResponse ind, Pps7Emiospi spi)(Controller); B2C1 sclko_b2c <- mkB2C1(); Clock def_clk <- exposeCurrentClock; Clock spi_clk <- mkClockBUFG(clocked_by sclko_b2c.c); Reset spi_rst <- mkAsyncResetFromCR(2, spi_clk); Reg#(Bit#(32)) shift_reg <- mkReg(0, clocked_by spi_clk, reset_by spi_rst); Reg#(Bit#(5)) spi_cnt_reg <- mkReg(0, clocked_by spi_clk, reset_by spi_rst); ReadOnly#(Bit#(1)) mo_sync <- mkNullCrossingWire(spi_clk, spi.mo); ReadOnly#(Bit#(1)) motn_sync <- mkNullCrossingWire(spi_clk, spi.motn); ReadOnly#(Bit#(3)) sson_sync <- mkNullCrossingWire(spi_clk, spi.sson); ReadOnly#(Bit#(1)) ssntn_sync <- mkNullCrossingWire(spi_clk, spi.ssntn); ReadOnly#(Bit#(1)) sclko_sync <- mkNullCrossingWire(spi_clk, spi.sclko); ReadOnly#(Bit#(1)) sclktn_sync <- mkNullCrossingWire(spi_clk, spi.sclktn); ReadOnly#(Bit#(1)) miso_sync <- mkNullCrossingWire(def_clk, shift_reg[31]); Reg#(Bit#(1)) spew_src <- mkReg(0); Reg#(Bit#(1)) clk_inv <- mkReg(0); Reg#(Bit#(16)) def_cnt_reg <- mkReg(0); Reg#(Bit#(32)) spew_en <- mkReg(0); Reg#(Bit#(32)) spew_cyc <- mkReg(0); FrequencyCounter spi_clk_fc <- mkFrequencyCounter(spi_clk, spi_rst); SyncFIFOIfc#(Bit#(32)) req_fifo <- mkSyncFIFOToCC(2, spi_clk, spi_rst); SyncFIFOIfc#(Spew) spew_fifo <- mkSyncBRAMFIFOToCC(128, spi_clk, spi_rst); (* fire_when_enabled *) rule connect_to_ps7; sclko_b2c.inputclock(clk_inv ^ spi.sclko); spi.mi(miso_sync); spi.sclki(0); spi.si(0); spi.ssin(1); endrule (* fire_when_enabled *) rule def_cnt_rule if (~spi.sclktn==1 && ~spi.motn==1); def_cnt_reg <= def_cnt_reg+1; endrule rule mosi_rule if (sson_sync[0] == 0); shift_reg <= {shift_reg[30:0],mo_sync}; spi_cnt_reg <= spi_cnt_reg+1; if (spi_cnt_reg == 0) req_fifo.enq(shift_reg); endrule rule cnt_cycle_resp_rule_a; let v <- spi_clk_fc.elapsedCycles; ind.cnt_cycle_resp(v); endrule rule drain_req_fifo; ind.spi_word(req_fifo.first); req_fifo.deq; endrule rule emio_sample_rule_a; spew_fifo.enq(Spew{mo:mo_sync, motn:motn_sync, sson:sson_sync, ssntn:ssntn_sync, sclko:sclko_sync, sclktn:sclktn_sync, cnt:extend(spi_cnt_reg)}); endrule rule emio_sample_rule_b if (spew_en > 0); if (spew_cyc+1 == spew_en) begin spew_cyc <= 0; if (spew_src == 1) begin ind.emio_sample(Spew{mo:spi.mo, motn:spi.motn, sson:spi.sson, ssntn:spi.ssntn, sclko:spi.sclko, sclktn:spi.sclktn, cnt:def_cnt_reg}); end else begin ind.emio_sample(spew_fifo.first); spew_fifo.deq; end end else begin spew_cyc <= spew_cyc+1; end endrule interface SPIRequest req; method Action cnt_cycle_req(CycleReq v); spi_clk_fc.start(v.clk_cnt); endmethod method Action set_spew_en(Bit#(32) v); spew_en <= v; endmethod method Action set_clk_inv(Bit#(1) v); clk_inv <= v; endmethod method Action set_spew_src(Bit#(1) v); spew_src <= v; endmethod endinterface endmodule ================================================ FILE: tests/test_spi0/Top.bsv ================================================ // Copyright (c) 2015 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import ConnectalConfig::*; import HostInterface::*; import Vector::*; import CtrlMux::*; import Portal::*; import ConnectalMemTypes::*; import Leds::*; import PS7LIB::*; import SPI::*; import SPIRequest::*; import SPIResponse::*; typedef enum {IfcNames_ControllerRequest, IfcNames_ControllerResponse} IfcNames deriving (Eq,Bits); module mkConnectalTop#(HostInterface host)(ConnectalTop); SPIResponseProxy cp <- mkSPIResponseProxy(IfcNames_ControllerResponse); Controller controller <- mkController(cp.ifc, host.ps7.emiospi0); SPIRequestWrapper cw <- mkSPIRequestWrapper(IfcNames_ControllerRequest, controller.req); Vector#(2,StdPortal) portals; portals[0] = cp.portalIfc; portals[1] = cw.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = nil; endmodule : mkConnectalTop export mkConnectalTop; ================================================ FILE: tests/test_spi0/foo.cpp ================================================ #include "ImageCapture.h" #include #include #include #include #include #include #include #include #include #include #include "i2chdmi.h" #include "i2ccamera.h" #include "/usr/include/linux/spi/spidev.h" #define SPIDEVICENAME "/dev/spidev2.0" static ImageCapture *device = 0; #define DECL(A) \ static sem_t sem_ ## A; \ static unsigned long cv_ ## A; DECL(iserdes_control) DECL(decoder_control) DECL(crc_control) DECL(crc_status) DECL(remapper_control) DECL(triggen_control) DECL(clock_gen_locked) #define RXFN(A) \ virtual void A ## _value ( unsigned long v ){ \ cv_ ## A = v; \ sem_post(&sem_ ## A); \ } #define GETFN(A) \ static unsigned long read_ ## A (void) \ { \ device->get_ ## A(); \ sem_wait(&sem_ ## A); \ return cv_ ## A; \ } class TestImageCaptureIndications : public ImageCaptureIndications { void spi_trace_sample_count_value(long unsigned int) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); } void spi_trace_sample_value(long long unsigned int) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); } void spi_control_value(long unsigned int) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); } void spi_rxfifo_value(long unsigned int) { printf("[%s:%d]\n", __FUNCTION__, __LINE__); } RXFN(iserdes_control) RXFN(decoder_control) RXFN(crc_control) RXFN(crc_status) RXFN(remapper_control) RXFN(triggen_control) RXFN(clock_gen_locked) void putFailed(unsigned long v){ fprintf(stderr, "putFailed: %x\n", v); exit(1); } void debugind(long unsigned int v) { printf("[%s:%d] valu %lx\n", __FUNCTION__, __LINE__, v); } }; static void init_local_semaphores(void) { sem_init(&sem_iserdes_control, 0, 0); sem_init(&sem_decoder_control, 0, 0); sem_init(&sem_crc_control, 0, 0); sem_init(&sem_remapper_control, 0, 0); sem_init(&sem_triggen_control, 0, 0); sem_init(&sem_crc_status, 0, 0); sem_init(&sem_clock_gen_locked, 0, 0); } GETFN(iserdes_control) GETFN(decoder_control) GETFN(crc_control) GETFN(crc_status) GETFN(remapper_control) GETFN(triggen_control) GETFN(clock_gen_locked) //#define VITA_ISERDES_CONTROL_REG 0x0010 #define VITA_ISERDES_RESET_BIT 0x0001 #define VITA_ISERDES_AUTO_ALIGN_BIT 0x0002 #define VITA_ISERDES_ALIGN_START_BIT 0x0004 #define VITA_ISERDES_FIFO_ENABLE_BIT 0x0008 //#define VITA_DECODER_CONTROL_REG 0x0020 #define VITA_DECODER_RESET_BIT 0x0001 #define VITA_DECODER_ENABLE_BIT 0x0002 //#define VITA_CRC_CONTROL_REG 0x0070 #define VITA_CRC_RESET_BIT 0x0001 #define VITA_CRC_INITVALUE_BIT 0x0002 //#define VITA_CRC_STATUS_REG 0x0074 static uint32_t uManualTap; static struct { // Sync Channel Decoder status uint32_t cntBlackLines; uint32_t cntImageLines; uint32_t cntBlackPixels; uint32_t cntImagePixels; uint32_t cntFrames; uint32_t cntWindows; uint32_t cntStartLines; uint32_t cntEndLines; uint32_t cntClocks; uint32_t crcStatus; } vita_status_t2; #define VITA_SPI_SEQ1_QTY 8 /* Table 6. enable clock management register upload - part 1 */ static uint16_t vita_spi_seq1[VITA_SPI_SEQ1_QTY][3] = { // Enable Clock Management - Part 1 // V1/SN/SE 10-bit mode with PLL { 2, 0xFFFF, 0}, // Monochrome Sensor // { 2, 0xFFFF, 0x0001}, // Color Sensor { 32, 0xFFFF, 0x2004}, // Configure clock management { 20, 0xFFFF, 0}, // Configure clock management { 17, 0xFFFF, 0x2113}, // Configure PLL { 26, 0xFFFF, 0x2280}, // Configure PLL lock detector { 27, 0xFFFF, 0x3D2D}, // Configure PLL lock detector { 8, 0xFFFF, 0}, // Release PLL soft reset { 16, 0xFFFF, 0x0003} // Enable PLL }; #define VITA_SPI_SEQ3_QTY 3 /* Table 7. enable clock management register upload - part 2 */ static uint16_t vita_spi_seq3[VITA_SPI_SEQ3_QTY][3] = { // Enable Clock Management - Part 2 // V1/SN/SE 10-bit mode with PLL { 9, 0xFFFF, 0}, // Release clock generator soft reset { 32, 0xFFFF, 0x2006}, // Enable logic clock { 34, 0xFFFF, 0x0001} // Enable logic blocks }; #define VITA_SPI_SEQ4_QTY 17 /* Table 8. required register upload */ static uint16_t vita_spi_seq4[VITA_SPI_SEQ4_QTY][3] = { // Required Register Upload // V1/SN/SE 10-bit mode with PLL { 41, 0xFFFF, 0}, // Configure image core {129, 0x2000, 0}, // [13] 10-bit mode { 65, 0xFFFF, 0x288B}, // Configure CP biasing { 66, 0xFFFF, 0x53C6}, // Configure AFE biasing { 67, 0xFFFF, 0x0344}, // Configure MUX biasing { 68, 0xFFFF, 0x0085}, // Configure LVDS biasing { 70, 0xFFFF, 0x4888}, // Configure reserved register { 81, 0xFFFF, 0x86A1}, // Configure reserved register {128, 0xFFFF, 0x460F}, // Configure calibration {176, 0xFFFF, 0x00F5}, // Configure AEC {180, 0xFFFF, 0x00FD}, // Configure AEC {181, 0xFFFF, 0x0144}, // Configure AEC {194, 0xFFFF, 0x0404}, // Configure sequencer {218, 0xFFFF, 0x160B}, // Configure sequencer {224, 0xFFFF, 0x3E13}, // Configure sequencer {391, 0xFFFF, 0x1010}, // Configure sequencer {456, 0xFFFF, 0x0386} // Configure sequencer }; #define VITA_SPI_SEQ5_QTY 7 /* Table 9. soft power up register uploads for mode dependent registers */ static uint16_t vita_spi_seq5[VITA_SPI_SEQ5_QTY][3] = { // Soft Power-Up // V1/SN/SE 10-bit mode with PLL { 32, 0xFFFF, 0x2007}, // Enable analog clock distribution { 10, 0xFFFF, 0}, // Release soft reset state { 64, 0xFFFF, 0x0001}, // Enable biasing block { 72, 0xFFFF, 0x0203}, // Enable charge pump { 40, 0xFFFF, 0x0003}, // Enable column multiplexer { 48, 0xFFFF, 0x0001}, // Enable AFE {112, 0xFFFF, 0x0007} // Enable LVDS transmitters }; //#define VITA_SPI_SEQ6_QTY 1 #define VITA_SPI_SEQ6_QTY 2 /* Table 10. enable sequencer register upload */ static uint16_t vita_spi_seq6[VITA_SPI_SEQ6_QTY][3] = { // {192, 0x0001, 0x0001} // [0] Enable Sequencer #if defined(TRIGGERED_MASTER_MODE) {192, 0x0051, 0x0011}, // [0] Enable Sequencer // [4] triggered_mode = on // [6] xsm_delay_enable = off {193, 0xFF00, 0} // [15:8] xsm_delay = 0x00 #elif defined(STRETCH_VITA_HTIMING) {192, 0x3841, 0x3841}, // {192, 0x0041, 0x0041}, // [0] Enable Sequencer // [6] xsm_delay_enable = on {193, 0xFF00, 0x0400} // [15:8] xsm_delay = 0x04 #else {192, 0x0001, 0x0001}, // [0] Enable Sequencer // [6] xsm_delay_enable = off {193, 0xFF00, 0} // [15:8] xsm_delay = 0x00 #endif }; #define VITA_AUTOEXP_ON_QTY 1 static uint16_t vita_autoexp_on_seq[VITA_AUTOEXP_ON_QTY][3] = { // Auto-Exposure ON {160, 0x0001, 0x0001} // [4] Auto Exposure enable }; #define VITA_ROI0_CROP_1080P_QTY 2 static uint16_t vita_roi0_crop_1080p_seq[VITA_ROI0_CROP_1080P_QTY][3] = { // Crop ROI0 from 1920x1200 to 1920x1080 // R257[10:0] y_start = 60 (0x3C) // R258[10:0] y_end = 60+1080 = 1140 (0x474) {257, 0xFFFF, 0x003C}, {258, 0xFFFF, 0x0474} }; #define VITA_MULT_TIMER_LINE_RESOLUTION_QTY 1 static uint16_t vita_mult_timer_line_resolution_seq[VITA_MULT_TIMER_LINE_RESOLUTION_QTY][3] = { // R199[15:0] mult_timer = (1920+88+44+148)/4 = 2200/4 = 550 (0x0226) //199, 0xFFFF, 0x0226 // R199[15:0] mult_timer = (1920+88+44+132)/4 = 2184/4 = 546 (0x0222) {199, 0xFFFF, 0x0222} }; /************************ SPI ******************************/ static int spidevicefd; static uint8_t spimode = 0; static uint8_t spibits = 8; static uint32_t speed = 50000; static uint16_t delay = 100; static uint16_t zynq_spi(uint32_t addr, uint32_t data) { unsigned int ii; uint8_t tx[sizeof(uint32_t)], rx[sizeof(uint32_t)]; uint32_t retval = 0; static struct spi_ioc_transfer tr; uint32_t command = addr << 23 | (data << 6); //printf("[%s:%d] addr %x data %x command %x\n", __FUNCTION__, __LINE__, addr, data, command); for (ii = 0; ii < sizeof(uint32_t); ii++) { tx[3-ii] = command; command >>= 8; } tr.tx_buf = (unsigned long)tx; tr.rx_buf = (unsigned long)rx; tr.len = sizeof(tx); tr.delay_usecs = delay; tr.speed_hz = speed; tr.bits_per_word = spibits; if (ioctl(spidevicefd, SPI_IOC_MESSAGE(1), &tr) < 1) printf("can't send spi message\n"); for (ii = 0; ii < sizeof(uint32_t); ii++) retval = retval << 8 | rx[ii]; return (retval >> 5) & 0xffff; } static uint16_t vita_spi_read(uint32_t uAddr) { return zynq_spi(uAddr, 0); } static int vita_spi_write(uint32_t uAddr, uint16_t uData) { zynq_spi(uAddr, 0x10000 | uData); return 0; } /****************************************************************************** * This function performs a sequence of SPI write transactions. ******************************************************************************/ static void vita_spi_write_sequence(uint16_t pConfig[][3], uint32_t uLength) { uint16_t uData; int i; for ( i = 0; i < (int)uLength; i++) { if ( pConfig[i][1] != 0xFFFF) { uData = vita_spi_read(pConfig[i][0]) & ~pConfig[i][1]; printf( "\t 0x%04X\n\r", pConfig[i][1]); } } for ( i = 0; i < (int)uLength; i++) { if ( pConfig[i][1] == 0xFFFF) uData = pConfig[i][2]; else { uData = vita_spi_read(pConfig[i][0]) & ~pConfig[i][1]; uData |= pConfig[i][2]; } vita_spi_write(pConfig[i][0], uData); usleep(100); // 100 usec } } static int fmc_imageon_vita_receiver_get_status(void) { sleep(1); //vita_status_t2.cntBlackLines = vita_reg_read(VITA_DECODER_CNT_BLACK_LINES_REG); //vita_status_t2.cntImageLines = vita_reg_read(VITA_DECODER_CNT_IMAGE_LINES_REG); //vita_status_t2.cntBlackPixels = vita_reg_read(VITA_DECODER_CNT_BLACK_PIXELS_REG); //vita_status_t2.cntImagePixels = vita_reg_read(VITA_DECODER_CNT_IMAGE_PIXELS_REG); //vita_status_t2.cntFrames = vita_reg_read(VITA_DECODER_CNT_FRAMES_REG); //vita_status_t2.cntWindows = vita_reg_read(VITA_DECODER_CNT_WINDOWS_REG); //vita_status_t2.cntStartLines = vita_reg_read(VITA_DECODER_CNT_START_LINES_REG); //vita_status_t2.cntEndLines = vita_reg_read(VITA_DECODER_CNT_END_LINES_REG); //vita_status_t2.cntClocks = vita_reg_read(VITA_DECODER_CNT_CLOCKS_REG); //vita_status_t2.crcStatus = read_crc_status(); return 0; } static struct { const char *pName; uint32_t VActiveVideo; uint32_t VFrontPorch; uint32_t VSyncWidth; uint32_t VBackPorch; uint32_t VSyncPolarity; uint32_t HActiveVideo; uint32_t HFrontPorch; uint32_t HSyncWidth; uint32_t HBackPorch; uint32_t HSyncPolarity; } vres = { "1080P", 1080, 4, 5, 36, 1, 1920, 88, 44, 148, 1 // VIDEO_RESOLUTION_1080P }; static void fmc_imageon_demo_enable_ipipe( void) { // VITA-2000 Initialization printf( "FMC-IMAGEON VITA Initialization ...\n\r"); uint16_t uData; uint32_t uStatus; int timeout; uint32_t h_active = 1920; uint32_t h_fporch = 88; uint32_t h_syncwidth = 44; #if defined(STRETCH_VITA_HTIMING) uint32_t h_bporch = 148; #else uint32_t h_bporch = 132; #endif uint32_t h_syncpol = 1; //v_active = 1080; uint32_t v_active = 1080+1; uint32_t v_fporch = 4; uint32_t v_syncwidth = 5; //v_bporch = 36; uint32_t v_bporch = 300; uint32_t v_syncpol = 1; // Horizontal settings device->set_syncgen_delay(((1920+88+44+148)>>2)*6); // approx. 6 lines of delay device->set_syncgen_hactive(h_active); device->set_syncgen_hfporch(h_fporch); device->set_syncgen_hsync((h_syncpol)<<15 | (h_syncwidth)<<0); device->set_syncgen_hbporch(h_bporch); // Vertical settings device->set_syncgen_vactive(v_active); device->set_syncgen_vfporch(v_fporch); device->set_syncgen_vsync ((v_syncpol)<<15 | (v_syncwidth)<<0); device->set_syncgen_vbporch(v_bporch); printf( "VITA ISERDES - Setting Training Sequence to 0x03A6\n\r"); device->set_serdes_training(0x03A6); printf( "VITA ISERDES - Setting Manual Tap to 0x%08X\n\r", uManualTap); device->set_serdes_manual_tap(uManualTap); device->set_decoder_startoddeven(0); device->set_decoder_code_ls(0x00AA); device->set_decoder_code_le(0x012A); device->set_decoder_code_fs(0x02AA); device->set_decoder_code_fe(0x032A); device->set_decoder_code_bl(0x0015); device->set_decoder_code_img(0x0035); device->set_decoder_code_tr(0x03A6); device->set_decoder_code_crc(0x0059); printf( "VITA REMAPPER - Configuring for image lines in normal mode\n\r"); device->set_remapper_control( 1); uint32_t uControl = read_remapper_control(); printf( "VITA REMAPPER - Control = 0x%08X\n\r", uControl); device->set_iserdes_control( VITA_ISERDES_RESET_BIT); device->set_decoder_control( VITA_DECODER_RESET_BIT); device->set_crc_control( VITA_CRC_INITVALUE_BIT | VITA_CRC_RESET_BIT); usleep(10); // 10 usec #if 0 printf("VITA SPI Sequence 0 - Assert RESET_N pin\n\r"); device->set_spi_control( VITA_VITA_RESET_BIT); #endif usleep(10); // 10 usec printf( "VITA ISERDES - Releasing Reset\n\r"); device->set_iserdes_control( 0); printf( "VITA DECODER - Releasing Reset\n\r"); device->set_decoder_control( 0); printf( "VITA CRC - Releasing Reset\n\r"); device->set_crc_control( VITA_CRC_INITVALUE_BIT); sleep(1); // 1 sec (time to get clocks to lock) #if 0 printf("VITA SPI Sequence 0 - Releasing RESET_N pin\n\r"); device->set_spi_control( 0); #endif usleep(20); // 20 usec uData = vita_spi_read(0); printf("[%s:%d] %x\n", __FUNCTION__, __LINE__, uData); switch ( uData) { case 0: printf( "\tVITA Sensor absent\n\r"); break; case 0x560D: printf( "\tVITA-1300 Sensor detected\n\r"); break; case 0x5614: printf( "\tVITA-2000 Sensor detected\n\r"); break; case 0x5632: printf( "\tVITA-5000 Sensor detected\n\r"); break; case 0x56FA: printf( "\tVITA-25K Sensor detected\n\r"); break; default: printf( "\tERROR: Unknown CHIP_ID !!!\n\r"); break; } if ( uData != 0x5614) { printf( "\tERROR: Absent or unsupported VITA sensor !!!\n\r"); return; } printf("VITA SPI Sequence 1 - Enable Clock Management - Part 1\n\r"); vita_spi_write_sequence(vita_spi_seq1, VITA_SPI_SEQ1_QTY); { uint16_t uLock = 0; printf("VITA SPI Sequence 2 - Verify PLL Lock Indicator\n\r"); timeout = 10; while ( !(uLock) && --timeout) { usleep(100000); uLock = vita_spi_read(24); } if ( !timeout) { printf( "\tERROR: Timed Out while waiting for PLL lock to assert !!!\n\r"); return; } } printf("VITA SPI Sequence 3 - Enable Clock Management - Part 2\n\r"); vita_spi_write_sequence(vita_spi_seq3, VITA_SPI_SEQ3_QTY); printf("VITA SPI Sequence 4 - Required Register Upload\n\r"); vita_spi_write_sequence(vita_spi_seq4, VITA_SPI_SEQ4_QTY); printf("VITA SPI Sequence 5 - Soft Power-Up\n\r"); vita_spi_write_sequence(vita_spi_seq5, VITA_SPI_SEQ5_QTY); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); timeout = 9; while ( !(uStatus & 0x0100) && --timeout) { uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); usleep(1); } if ( !timeout) { printf( "\tTimed Out !!!\n\r"); return; } printf( "VITA ISERDES - Align Start\n\r"); device->set_iserdes_control( VITA_ISERDES_ALIGN_START_BIT); printf( "VITA ISERDES - Waiting for ALIGN_BUSY to assert\n\r"); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); timeout = 9; while ( !(uStatus & 0x0200) && --timeout) { uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); usleep(1); } if ( !timeout) { printf( "\tTimed Out !!!\n\r"); return; } device->set_iserdes_control( 0); printf( "VITA ISERDES - Waiting for ALIGN_BUSY to de-assert\n\r"); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); timeout = 9; while ( (uStatus & 0x0200) && --timeout) { uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); usleep(1); } if ( !timeout) printf( "\tTimed Out !!!\n\r"); uStatus = read_iserdes_control(); printf( "VITA ISERDES - Status = 0x%08X\n\r", uStatus); printf("VITA SPI Sequence - Crop ROI0 to 1920x1080\n\r"); vita_spi_write_sequence(vita_roi0_crop_1080p_seq, VITA_ROI0_CROP_1080P_QTY); printf("VITA SPI Sequence - Set mult_timer to line resolution\n\r"); vita_spi_write_sequence(vita_mult_timer_line_resolution_seq, VITA_MULT_TIMER_LINE_RESOLUTION_QTY); printf("VITA SPI Sequence - Set auto-exposure to ON\n\r"); vita_spi_write_sequence(vita_autoexp_on_seq, VITA_AUTOEXP_ON_QTY); printf("VITA SPI Sequence 6 - Enable Sequencer\n\r"); vita_spi_write_sequence(vita_spi_seq6, VITA_SPI_SEQ6_QTY); device->set_iserdes_control( VITA_ISERDES_FIFO_ENABLE_BIT); device->set_decoder_control(VITA_DECODER_ENABLE_BIT); uControl = read_decoder_control(); printf( "VITA DECODER - Control = 0x%08X\n\r", uControl); uStatus = read_crc_status(); printf( "VITA CRC - Status = 0x%08X\n\r", uStatus); usleep(100); uStatus = read_crc_status(); printf( "VITA CRC - Status = 0x%08X\n\r", uStatus); sleep(1); printf( "VITA 1080P60 - Disable Sequencer\n\r"); vita_spi_write(192, 0); usleep(100); // 100 usec printf( "VITA 1080P60 - Adjust line spacing in VITA\n\r"); vita_spi_write(193, 0x0400); usleep(100); // 100 usec vita_spi_write(192, 0x0040); usleep(100); // 100 usec printf( "VITA 1080P60 - Tolerate 6 lines of jitter (required for programmable exposure)\n\r"); device->set_syncgen_delay(0x0CE4); printf( "VITA 1080P60 - Adjust line spacing in sync generator\n\r"); device->set_syncgen_hactive(0x0780); device->set_syncgen_hfporch(0x0058); device->set_syncgen_hsync(0x802C); device->set_syncgen_hbporch(0x0094); printf( "VITA 1080P60 - Adjust frame spacing in VITA\n\r"); vita_spi_write(199, 0x0001); usleep(100); // 100 usec vita_spi_write(200, 0); usleep(100); // 100 usec vita_spi_write(194, 0); usleep(100); // 100 usec printf( "VITA 1080P60 - Adjust frame spacing in sync generator\n\r"); device->set_syncgen_vactive (0x0438); device->set_syncgen_vfporch (0x0004); device->set_syncgen_vsync(0x8005); device->set_syncgen_vbporch(0x0024); printf( "VITA 1080P60 - Crop ROI0 from 1920x1200 to 1920x1080\n\r"); vita_spi_write(257, 0x003C); usleep(100); // 100 usec vita_spi_write(258, 0x0474); usleep(100); // 100 usec printf( "VITA 1080P60 - Disable auto-exposure\n\r"); vita_spi_write(160, 0x0010); usleep(100); // 100 usec printf( "VITA 1080P60 - Enable trig generator\n\r"); uint32_t trigDutyCycle = 90; // exposure time is 90% of frame time (ie. 15msec) uint32_t vitaTrigGenDefaultFreq = (((1920+88+44+148)*(1080+4+5+36))>>2) - 2; device->set_trigger_default_freq(vitaTrigGenDefaultFreq); device->set_trigger_cnt_trigger0high((vitaTrigGenDefaultFreq * (100-trigDutyCycle))/100); // negative polarity device->set_trigger_cnt_trigger0low(1); device->set_triggen_control(0x31000011); // invert trigger[2:0], internal trigger, enable trigger[0], update triggen_cnt registers device->set_triggen_control(0x30000011); // invert trigger[2:0], internal trigger, enable trigger[0] printf("VITA 1080P60 - Exposure related settings\n\r"); vita_spi_write(194, 0x0400); vita_spi_write(0x29, 0x0700); uint16_t vspi_data = vita_spi_read(192) | 0x0071; usleep(100); // 100 usec vita_spi_write(192, vspi_data); usleep(100); // 100 usec fmc_imageon_vita_receiver_get_status(); uint32_t lastframes = vita_status_t2.cntFrames; fmc_imageon_vita_receiver_get_status(); printf("VITA Status = \n\r"); printf("\tImage Width = %d\n\r", vita_status_t2.cntImagePixels * 4); printf("\tImage Height = %d\n\r", vita_status_t2.cntImageLines); printf("\tFrame Rate = %d frames/sec\n\r", vita_status_t2.cntFrames - lastframes); printf("Initializing iPipe cores ... done!\r\n"); usleep(10000); } static void fmc_imageon_demo_init(int argc, const char **argv) { int ret; printf("[%s:%d]\n", __FUNCTION__, __LINE__); //ret = fmc_iic_axi_init(uBaseAddr_IIC_FmcImageon); //fmc_iic_axi_GpoWrite(uBaseAddr_IIC_FmcImageon, fmc_iic_axi_GpoRead(uBaseAddr_IIC_FmcImageon) | 2); device->set_host_oe(1); printf("[%s:%d]\n", __FUNCTION__, __LINE__); spidevicefd = open(SPIDEVICENAME, O_RDWR); if (spidevicefd < 0 || ioctl(spidevicefd, SPI_IOC_WR_MODE, &spimode) == -1 || ioctl(spidevicefd, SPI_IOC_RD_MODE, &spimode) == -1 || ioctl(spidevicefd, SPI_IOC_WR_BITS_PER_WORD, &spibits) == -1 || ioctl(spidevicefd, SPI_IOC_RD_BITS_PER_WORD, &spibits) == -1 || ioctl(spidevicefd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1 || ioctl(spidevicefd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) printf("Error: cannot open SPI device\n"); device->set_iic_reset(0); device->set_iic_reset(1); init_i2c_camera(); init_i2c_hdmi(); //init_vclk(); // Reset DCMs /* puts the DCM_0 PCORE into reset */ //fmc_iic_axi_GpoWrite(uBaseAddr_IIC_FmcImageon, fmc_iic_axi_GpoRead(uBaseAddr_IIC_FmcImageon) | 4); device->set_clock_gen_reset(1); printf("[%s:%d]\n", __FUNCTION__, __LINE__); usleep(200000); /* releases the DCM_0 PCORE from reset */ //fmc_iic_axi_GpoWrite(uBaseAddr_IIC_FmcImageon, fmc_iic_axi_GpoRead(uBaseAddr_IIC_FmcImageon) & ~4); device->set_clock_gen_reset(0); printf("[%s:%d]\n", __FUNCTION__, __LINE__); usleep(500000); printf("[%s:%d]\n", __FUNCTION__, __LINE__); printf("[%s:%d] locked %ld\n", __FUNCTION__, __LINE__, read_clock_gen_locked()); // FMC-IMAGEON VITA Receiver Initialization printf( "FMC-IMAGEON VITA Receiver Initialization ...\n\r"); uManualTap = 25; device->set_spi_timing((100/10)); fmc_imageon_demo_enable_ipipe(); } static void *pthread_worker(void *ptr) { portalExec(NULL); return NULL; } int main(int argc, const char **argv) { pthread_t threaddata; init_local_semaphores(); device = ImageCapture::createImageCapture("fpga0", new TestImageCaptureIndications); int rc = pthread_create(&threaddata, NULL, &pthread_worker, (void *)device); fmc_imageon_demo_init(argc, argv); usleep(200000); while (getchar() != EOF) { device->set_debugreq(1); device->get_debugind(); printf("[%s:%d] iserdes %lx\n", __FUNCTION__, __LINE__, read_iserdes_control()); printf("[%s:%d] decode %lx\n", __FUNCTION__, __LINE__, read_decoder_control()); printf("[%s:%d] crccontrol %lx\n", __FUNCTION__, __LINE__, read_crc_control()); printf("[%s:%d] crcstatus %lx\n", __FUNCTION__, __LINE__, read_crc_status()); printf("[%s:%d] remapper %lx\n", __FUNCTION__, __LINE__, read_remapper_control()); printf("[%s:%d] triggen %lx\n", __FUNCTION__, __LINE__, read_triggen_control()); static int regids[] = {24, 97, 186, 0}; int i; for (i = 0; regids[i]; i++) printf("[%s:%d] spi %d. %x\n", __FUNCTION__, __LINE__, regids[i], vita_spi_read(regids[i])); } return 0; } ================================================ FILE: tests/test_spi0/test_spi0.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include #include "linux/spi/spidev.h" #include "SPIRequest.h" #include "SPIResponse.h" #define SPIDEVICENAME "/dev/spidev2.0" static int spidevicefd; static uint8_t spimode = 0; static uint8_t spibits = 8; static uint32_t speed = 16666666; static uint16_t delay = 100; uint32_t bit_sel(uint32_t lsb, uint32_t msb, uint32_t v) { return (v >> lsb) & ~(~0 << (msb-lsb+1)); } class SPIResponse : public SPIResponseWrapper { public: virtual void read_resp(uint8_t v){ fprintf(stderr, "read_resp cd:%d wp:%d\n", (v&2)>>1, v&1); } virtual void emio_sample(const Spew v){ fprintf(stderr, "emio_sample{mo:%d, motn:%d, sson:%d, ssntn:%d, sclko:%d, sclktn:%d, cnt:%d}\n", v.mo, v.motn, v.sson, v.ssntn, v.sclko, v.sclktn, v.cnt); } virtual void cnt_cycle_resp(uint32_t v){ fprintf(stderr, "cnt_cycle_resp %d\n", v); } virtual void spi_word(uint32_t v){ fprintf(stderr, "spi_word %08x\n", v); } SPIResponse(unsigned int id) : SPIResponseWrapper(id){} }; int main(int argc, const char **argv) { SPIRequestProxy *device = new SPIRequestProxy(IfcNames_ControllerRequest); SPIResponse ind(IfcNames_ControllerResponse); uint8_t iter = 1; device->set_clk_inv(0); device->set_spew_en(0); device->set_spew_src(0); spidevicefd = open(SPIDEVICENAME, O_RDWR); if (spidevicefd < 0){ printf("Error: cannot open SPI device\n"); goto finish; } else if (ioctl(spidevicefd, SPI_IOC_WR_MODE, &spimode) == -1 || ioctl(spidevicefd, SPI_IOC_RD_MODE, &spimode) == -1 || ioctl(spidevicefd, SPI_IOC_WR_BITS_PER_WORD, &spibits) == -1 || ioctl(spidevicefd, SPI_IOC_RD_BITS_PER_WORD, &spibits) == -1 || ioctl(spidevicefd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1 || ioctl(spidevicefd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1){ printf("Error: cannot configure SPI device\n"); goto finish; } else { printf("Successfully opened spi %x\n", spidevicefd); } while(iter < 4){ uint8_t tx[sizeof(uint32_t)], rx[sizeof(uint32_t)]; for(unsigned int i = 0; i < sizeof(uint32_t); i++) tx[i] = 1; struct spi_ioc_transfer tr; tr.tx_buf = (unsigned long)tx; tr.rx_buf = (unsigned long)rx; tr.len = sizeof(tx); tr.delay_usecs = delay; tr.speed_hz = speed; tr.bits_per_word = spibits; { struct CycleReq cr; cr.clk_sel = 0; cr.clk_cnt = 10000; device->cnt_cycle_req(cr); } if (ioctl(spidevicefd, SPI_IOC_MESSAGE(1), &tr) < 1) printf("can't send spi message\n"); else printf("successfully sent spi message\n"); iter++; sleep(1); } finish: if (spidevicefd >= 0) close(spidevicefd); return 0; } ================================================ FILE: tests/testfpmul/Makefile ================================================ CONNECTALDIR?=../.. MMDIR=../../examples/matmul TESTCPPFILES= testfpmul.cpp BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib CONNECTALFLAGS = -D J_VALUE=2 -D K_VALUE=2 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testfpmul/Top.bsv ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import ConnectalConfig::*; import Vector::*; import FIFO::*; import Connectable::*; import Portal::*; import CtrlMux::*; import ConnectalMemTypes::*; import FpMulIndication::*; import FpMulRequest::*; import RbmTypes::*; import FpMacTb::*; module mkConnectalTop(ConnectalTop); FpMulIndicationProxy ind <- mkFpMulIndicationProxy(IfcNames_FpMulIndicationPortal); FpMulRequest req <- mkFpMulRequest(ind.ifc); FpMulRequestWrapper reqW <- mkFpMulRequestWrapper(IfcNames_FpMulRequestPortal,req); Vector#(2,StdPortal) portals; portals[0] = ind.portalIfc; portals[1] = reqW.portalIfc; let ctrl_mux <- mkSlaveMux(portals); interface interrupt = getInterruptVector(portals); interface slave = ctrl_mux; interface masters = replicate(?); endmodule : mkConnectalTop ================================================ FILE: tests/testfpmul/testfpmul.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include #include #include #include #include #include //////////////////////////////////////////// // class RbmRequestProxy; class MmRequestProxy; class SigmoidRequestProxy; class TimerRequestProxy; class SigmoidIndication; RbmRequestProxy *rbmdevice = 0; MmRequestProxy *mmdevice = 0; SigmoidIndication *sigmoidindication = 0; SigmoidRequestProxy *sigmoiddevice = 0; TimerRequestProxy *timerdevice = 0; // //////////////////////////////////////////// class FpMulIndication : public FpMulIndicationWrapper { public: virtual void mul_resp(uint32_t v) { fprintf(stderr, "res: %d\n", v); exit(0); } FpMulIndication(unsigned int id) : FpMulIndicationWrapper(id) {} }; int main(int argc, const char **argv) { unsigned int srcGen = 0; fprintf(stderr, "%s %s\n", __DATE__, __TIME__); FpMulRequestProxy *dev = new FpMulRequestProxy(IfcNames_FpMulRequestPortal); FpMulIndication *ind = new FpMulIndication(IfcNames_FpMulIndicationPortal); dev->mul_req(0,0); while(1); } ================================================ FILE: tests/testldstrex/Makefile ================================================ CONNECTALDIR?=../.. TOOLCHAIN ?= /afs/csail.mit.edu/group/csg/tools/tools_lx86/android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.6 CPPFILES= testldstrex.cpp CONNECTALFLAGS += -I $(TOOLCHAIN)/include -I $(TOOLCHAIN)/libs/armeabi-v7a/include include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testldstrex/testldstrex.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //#include //#include //#include //#include //#include //#include //#include //#include //#include // frexp(), fabs() //#include //#include //#include #include #include "portal.h" #define CV_XADD __gnu_cxx::__exchange_and_add int main(int argc, const char **argv) { int totalsize = 4096; int fd = portalAlloc(totalsize, 0); if (fd < 0) { fprintf(stderr, "memory alloc failed\n"); exit(-1); } fprintf(stderr, "allocated %d bytes, fd=%d\n", totalsize, fd); int *mem = (int*)portalMmap(fd, totalsize); *mem = 1; fprintf(stderr, "Before CV_XADD: mem=%p *mem=%d\n", mem, *mem); CV_XADD(mem, -1); fprintf(stderr, "Before CV_XADD: *mem=%d\n", *mem); exit(0); } ================================================ FILE: tests/testmm16.16.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=16 -D K_VALUE=16 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm16.16.4/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=16 -D K_VALUE=16 -D N_VALUE=4 -D DataBusWidth=128 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm2.4.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=2 -D K_VALUE=4 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm2.4.2/zc706_floorplan.xdc ================================================ create_pblock mmtile_0 resize_pblock mmtile_0 -add {SLICE_X92Y150:SLICE_X96Y250 SLICE_X97Y150:SLICE_X161Y250 DSP48_X4Y62:DSP48_X6Y99 RAMB18_X5Y62:RAMB18_X7Y99 RAMB36_X5Y31:RAMB36_X7Y49} add_cells_to_pblock mmtile_0 [get_cells [list top_mm_dmaMMF_dmaMMF_mmTiles_0]] -clear_locs set_property CONTAIN_ROUTING true [get_pblocks mmtile_0] set_property HD.PARTPIN_RANGE {SLICE_X92Y150:SLICE_X96Y250} [get_pins top_mm_dmaMMF_dmaMMF_mmTiles_0/*] create_pblock mmtile_1 resize_pblock mmtile_1 -add {SLICE_X92Y52:SLICE_X96Y151 SLICE_X97Y52:SLICE_X159Y151 DSP48_X4Y22:DSP48_X6Y59 RAMB18_X4Y22:RAMB18_X7Y59 RAMB36_X4Y11:RAMB36_X7Y29} add_cells_to_pblock mmtile_1 [get_cells [list top_mm_dmaMMF_dmaMMF_mmTiles_1]] -clear_locs set_property CONTAIN_ROUTING true [get_pblocks mmtile_1] set_property HD.PARTPIN_RANGE {SLICE_X92Y52:SLICE_X96Y151} [get_pins top_mm_dmaMMF_dmaMMF_mmTiles_1/*] ================================================ FILE: tests/testmm32.16.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES=$(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=32 -D K_VALUE=16 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm32.32.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=32 -D K_VALUE=32 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm4.2.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=4 -D K_VALUE=2 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm4.4.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=4 -D K_VALUE=4 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm4.4.4/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=4 -D K_VALUE=4 -D N_VALUE=4 -D DataBusWidth=128 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm8.8.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=8 -D K_VALUE=8 -D N_VALUE=2 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm8.8.2/zc706_floorplan.xdc ================================================ create_pblock mmtile_0 resize_pblock [get_pblocks mmtile_0] -add {SLICE_X56Y154:SLICE_X163Y274} resize_pblock [get_pblocks mmtile_0] -add {DSP48_X4Y62:DSP48_X6Y109} resize_pblock [get_pblocks mmtile_0] -add {RAMB18_X4Y62:RAMB18_X7Y109} resize_pblock [get_pblocks mmtile_0] -add {RAMB36_X4Y31:RAMB36_X7Y54} add_cells_to_pblock mmtile_0 [get_cells [list top_mm_dmaMMF_dmaMMF_mmTiles_0]] -clear_locs set_property CONTAIN_ROUTING true [get_pblocks mmtile_0] set_property HD.PARTPIN_RANGE {SLICE_X56Y154:SLICE_X60Y274} [get_pins top_mm_dmaMMF_dmaMMF_mmTiles_0/*] create_pblock mmtile_1 resize_pblock [get_pblocks mmtile_1] -add {SLICE_X56Y6:SLICE_X159Y151} resize_pblock [get_pblocks mmtile_1] -add {DSP48_X4Y4:DSP48_X6Y59} resize_pblock [get_pblocks mmtile_1] -add {RAMB18_X4Y4:RAMB18_X7Y59} resize_pblock [get_pblocks mmtile_1] -add {RAMB36_X4Y2:RAMB36_X7Y29} add_cells_to_pblock mmtile_1 [get_cells [list top_mm_dmaMMF_dmaMMF_mmTiles_1]] -clear_locs set_property CONTAIN_ROUTING true [get_pblocks mmtile_1] set_property HD.PARTPIN_RANGE {SLICE_X56Y6:SLICE_X60Y151} [get_pins top_mm_dmaMMF_dmaMMF_mmTiles_1/*] ================================================ FILE: tests/testmm8.8.4/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=8 -D K_VALUE=8 -D N_VALUE=4 -D DataBusWidth=128 include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm_cuda_perf/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib CUDA_PERF_TEST = 1 MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(MMDIR)/testmm.cpp CONNECTALFLAGS = -D J_VALUE=8 -D K_VALUE=8 -D N_VALUE=2 CONNECTALFLAGS += -D CUDA_PERF_TEST=$(CUDA_PERF_TEST) include $(MMDIR)/Makefile.mm include $(MMDIR)/Makefile.mmif include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testmm_cuda_perf/Readme.md ================================================ Running on vangogh: 1) download opencv 2.4.9 to /scratch/opencv-cuda/ http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.9/opencv-2.4.9.zip 2) install it using the following commands (I used cmake version 2.8.11.2): cd opencv-2.9.4 mkdir install cmake -G 'Unix Makefiles' -D WITH_CUDA=ON -D CMAKE_BUILD_TYPE=DEBUG -D BUILD_SHARED_LIBS=NO -D WITH_CUBLAS=YES -D CMAKE_INSTALL_PREFIX=./install . make -j 8 make install 3) nm -A *.a | c++filt | grep -w T ================================================ FILE: tests/testmm_cuda_perf/cuda_opencv_example/Makefile ================================================ NVCC = /usr/local/cuda-5.5/bin/nvcc default: cuda_opencv_example main.o: main.cu $(NVCC) -I/usr/local/cuda-5.5/targets/x86_64-linux/include/ -I/scratch/opencv-cuda/opencv-2.4.9/install/include -c main.cu cuda_opencv_example: main.o main.cpp g++ -I/usr/local/cuda-5.5/targets/x86_64-linux/include/ -I/scratch/opencv-cuda/opencv-2.4.9/install/include -o cuda_opencv_example main.o main.cpp \ -L/scratch/opencv-cuda/opencv-2.4.9/install/lib -L/usr/local/cuda-5.5/lib64 \ -lcuda -lopencv_core -lopencv_gpu -lcudart -lopencv_core run: LD_LIBRARY_PATH=/usr/local/cuda-5.5/lib64 ./cuda_opencv_example clean: rm -f main.o cuda_opencv_example ================================================ FILE: tests/testmm_cuda_perf/cuda_opencv_example/main.cpp ================================================ /* Copyright (c) 2014 Quanta Research Cambridge, Inc * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include using std::cout; using std::endl; void convert_to_gray(const cv::Mat& input, cv::Mat& output); void map_sigmoid(const cv::Mat& input, cv::Mat& output); float sigmoid(float x); #define SIGMOID #ifdef SIGMOID int main() { int A = 128; int B = 128; srand(A*B); cv::Mat input(A,B,CV_32F); cv::Mat output(A,B,CV_32F); for(int a = 0; a < A; a++) for(int b = 0; b < B; b++) input.at(a,b) = (float)(rand() % 10); fprintf(stderr, "about to call kernel\n"); map_sigmoid(input,output); fprintf(stderr, "successfully called kernel\n"); bool match = true; float epsilon = 0.00001; for(int a = 0; a < A; a++) { for(int b = 0; b < B; b++) { float ref = sigmoid(input.at(a,b)); float gpuv = output.at(a,b); float err = fabs(ref - gpuv);//ref; bool eq = (epsilon > err); match &= eq; if (!eq) fprintf(stderr, "(%d,%d) %f %f\n", a,b,ref,gpuv); } } return !match; } #else // SIGMOID int main() { std::string imagePath = "image.jpg"; //Read input image from the disk cv::Mat input = cv::Mat::zeros(100,100,CV_LOAD_IMAGE_COLOR); //cv::imread(imagePath,CV_LOAD_IMAGE_COLOR); if(input.empty()) { std::cout<<"Image Not Found!"< #include #include #include #include #include using std::cout; using std::endl; static inline void _safe_cuda_call(cudaError err, const char* msg, const char* file_name, const int line_number) { if(err!=cudaSuccess) { fprintf(stderr,"%s\n\nFile: %s\n\nLine Number: %d\n\nReason: %s\n",msg,file_name,line_number,cudaGetErrorString(err)); std::cin.get(); exit(EXIT_FAILURE); } } #define SAFE_CALL(call,msg) _safe_cuda_call((call),(msg),__FILE__,__LINE__) __global__ void bgr_to_gray_kernel( unsigned char* input, unsigned char* output, int width, int height, int colorWidthStep, int grayWidthStep) { //2D Index of current thread const int xIndex = blockIdx.x * blockDim.x + threadIdx.x; const int yIndex = blockIdx.y * blockDim.y + threadIdx.y; //Only valid threads perform memory I/O if((xIndex(gray); } } void convert_to_gray(const cv::Mat& input, cv::Mat& output) { //Calculate total number of bytes of input and output image const int colorBytes = input.step * input.rows; const int grayBytes = output.step * output.rows; unsigned char *d_input, *d_output; //Allocate device memory SAFE_CALL(cudaMalloc(&d_input,colorBytes),"CUDA Malloc Failed"); SAFE_CALL(cudaMalloc(&d_output,grayBytes),"CUDA Malloc Failed"); //Copy data from OpenCV input image to device memory SAFE_CALL(cudaMemcpy(d_input,input.ptr(),colorBytes,cudaMemcpyHostToDevice),"CUDA Memcpy Host To Device Failed"); //Specify a reasonable block size const dim3 block(16,16); //Calculate grid size to cover the whole image const dim3 grid((input.cols + block.x - 1)/block.x, (input.rows + block.y - 1)/block.y); //Launch the color conversion kernel bgr_to_gray_kernel<<>>(d_input,d_output,input.cols,input.rows,input.step,output.step); //Synchronize to check for any kernel launch errors SAFE_CALL(cudaDeviceSynchronize(),"Kernel Launch Failed"); //Copy back data from destination device meory to OpenCV output image SAFE_CALL(cudaMemcpy(output.ptr(),d_output,grayBytes,cudaMemcpyDeviceToHost),"CUDA Memcpy Host To Device Failed"); //Free the device memory SAFE_CALL(cudaFree(d_input),"CUDA Free Failed"); SAFE_CALL(cudaFree(d_output),"CUDA Free Failed"); } #define SIGMOID(x) ((x < -8.0) ? -8.0 : ((x > 8.0) ? 8.0 : (1 / (1 + expf(-x))))) float sigmoid(float x) { return SIGMOID(x); } __global__ void ssigmoid( float* input, float* output, int width, int height) { //2D Index of current thread const int xIndex = blockIdx.x * blockDim.x + threadIdx.x; const int yIndex = blockIdx.y * blockDim.y + threadIdx.y; //Only valid threads perform memory I/O if((xIndex(&d_input,inputBytes),"CUDA Malloc Failed"); SAFE_CALL(cudaMalloc(&d_output,outputBytes),"CUDA Malloc Failed"); //Copy data from OpenCV input image to device memory SAFE_CALL(cudaMemcpy(d_input,input.ptr(),inputBytes,cudaMemcpyHostToDevice),"CUDA Memcpy Host To Device Failed"); //Specify a reasonable block size const dim3 block(16,16); //Calculate grid size to cover the whole image const dim3 grid((input.cols + block.x - 1)/block.x, (input.rows + block.y - 1)/block.y); //Launch the input conversion kernel ssigmoid<<>>(d_input,d_output,input.cols,input.rows); //Synchronize to check for any kernel launch errors SAFE_CALL(cudaDeviceSynchronize(),"Kernel Launch Failed"); //Copy back data from destination device meory to OpenCV output image SAFE_CALL(cudaMemcpy(output.ptr(),d_output,outputBytes,cudaMemcpyDeviceToHost),"CUDA Memcpy Host To Device Failed"); //Free the device memory SAFE_CALL(cudaFree(d_input),"CUDA Free Failed"); SAFE_CALL(cudaFree(d_output),"CUDA Free Failed"); } ================================================ FILE: tests/testmm_cuda_perf/run_exe ================================================ #!/bin/bash set -x LD_LIBRARY_PATH=/usr/local/cuda-5.5/lib64 ./bin/bsim_exe ================================================ FILE: tests/testmm_cuda_perf/synth-ip.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" connectal_synth_ip floating_point 7.0 fp_add [list CONFIG.Axi_Optimize_Goal {Performance} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] connectal_synth_ip floating_point 7.0 fp_mul [list CONFIG.Operation_Type {Multiply} CONFIG.Axi_Optimize_Goal {Resources} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] ================================================ FILE: tests/testmm_cuda_perf/zc706_floorplan.xdc ================================================ create_pblock mmtile_0 resize_pblock mmtile_0 -add {SLICE_X92Y150:SLICE_X96Y250 SLICE_X97Y150:SLICE_X161Y250 DSP48_X4Y62:DSP48_X6Y99 RAMB18_X5Y62:RAMB18_X7Y99 RAMB36_X5Y31:RAMB36_X7Y49} add_cells_to_pblock mmtile_0 [get_cells [list top_mm_dmaMMF_dmaMMF_mmTiles_0]] -clear_locs set_property CONTAIN_ROUTING true [get_pblocks mmtile_0] set_property HD.PARTPIN_RANGE {SLICE_X92Y150:SLICE_X96Y250} [get_pins top_mm_dmaMMF_dmaMMF_mmTiles_0/*] create_pblock mmtile_1 resize_pblock mmtile_1 -add {SLICE_X92Y52:SLICE_X96Y151 SLICE_X97Y52:SLICE_X159Y151 DSP48_X4Y22:DSP48_X6Y59 RAMB18_X4Y22:RAMB18_X7Y59 RAMB36_X4Y11:RAMB36_X7Y29} add_cells_to_pblock mmtile_1 [get_cells [list top_mm_dmaMMF_dmaMMF_mmTiles_1]] -clear_locs set_property CONTAIN_ROUTING true [get_pblocks mmtile_1] set_property HD.PARTPIN_RANGE {SLICE_X92Y52:SLICE_X96Y151} [get_pins top_mm_dmaMMF_dmaMMF_mmTiles_1/*] ================================================ FILE: tests/testrbm16.16.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(RBMDIR)/testrbm.cpp CONNECTALFLAGS = -D J_VALUE=16 -D K_VALUE=16 -D N_VALUE=2 -D DataBusWidth=64 include $(MMDIR)/Makefile.mm include $(RBMDIR)/Makefile.rbm include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testrbm16.16.2/synth-ip.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" connectal_synth_ip floating_point 7.0 fp_add [list CONFIG.Axi_Optimize_Goal {Performance} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] connectal_synth_ip floating_point 7.0 fp_mul [list CONFIG.Operation_Type {Multiply} CONFIG.Axi_Optimize_Goal {Resources} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] ================================================ FILE: tests/testrbm8.8.2/Makefile ================================================ CONNECTALDIR?=../.. BSCFLAGS=-aggressive-conditions -show-schedule -keep-fires -p +:../paclib MMDIR=$(CONNECTALDIR)/examples/matmul RBMDIR=$(CONNECTALDIR)/examples/rbm TESTCPPFILES= $(RBMDIR)/testrbm.cpp CONNECTALFLAGS = -D J_VALUE=8 -D K_VALUE=8 -D N_VALUE=2 -D DataBusWidth=64 include $(MMDIR)/Makefile.mm include $(RBMDIR)/Makefile.rbm include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/testrbm8.8.2/synth-ip.tcl ================================================ source "board.tcl" source "$connectaldir/scripts/connectal-synth-ip.tcl" connectal_synth_ip floating_point 7.0 fp_add [list CONFIG.Axi_Optimize_Goal {Performance} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] connectal_synth_ip floating_point 7.0 fp_mul [list CONFIG.Operation_Type {Multiply} CONFIG.Axi_Optimize_Goal {Resources} CONFIG.Maximum_Latency {false} CONFIG.Has_ARESETN {true}] ================================================ FILE: tests/yuv/Makefile ================================================ CONNECTALDIR?=../.. S2H_INTERFACES = YuvRequest:YuvIF.request H2S_INTERFACES = YuvIF:YuvIndication BSVFILES = YuvIF.bsv CPPFILES= testyuv.cpp include $(CONNECTALDIR)/Makefile.connectal ================================================ FILE: tests/yuv/YuvIF.bsv ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. import GetPut::*; import HDMI::*; import Vector::*; import Arith::*; import YUV::*; interface YuvRequest; method Action toRgb(Bit#(8) r, Bit#(8) g, Bit#(8) b); method Action toYuv(Bit#(8) r, Bit#(8) g, Bit#(8) b); method Action toYyuv(Bit#(8) r, Bit#(8) g, Bit#(8) b); endinterface interface YuvIndication; method Action rgb(Bit#(8) y, Bit#(8) u, Bit#(8) v); method Action yuv(Bit#(8) y, Bit#(8) u, Bit#(8) v); method Action yyuv(Bit#(8) yy, Bit#(8) uv); endinterface interface YuvIF; interface YuvRequest request; endinterface module mkYuvIF#(YuvIndication indication)(YuvIF); let rgb888ToYyuv <- mkRgb888ToYyuv(); Wire#(VideoData#(Rgb888)) yyuvInputWire <- mkDWire(unpack(0)); Wire#(VideoData#(Rgb888)) stage0Reg <- mkDWire(unpack(0)); Reg#(VideoData#(Yuv444Intermediates)) stage1Reg <- mkReg(unpack(0)); Reg#(VideoData#(Vector#(2,Vector#(3,Bit#(16))))) stage2Reg <- mkReg(unpack(0)); Reg#(VideoData#(Yuv444)) stage3Reg <- mkReg(unpack(0)); Reg#(VideoData#(Yyuv)) stage4Reg <- mkReg(unpack(0)); Reg#(Bool) evenOddPixelReg <- mkReg(False); rule stage1_rule; let previous = stage0Reg; let pixel = previous.pixel; stage1Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: (previous.de != 0) ? rgbToYuvIntermediates(pixel) : unpack(0) }; endrule rule stage2_rule; let previous = stage1Reg; Vector#(4, Vector#(3, Bit#(16))) vprev = previous.pixel; Vector#(2, Vector#(3, Bit#(16))) vnext; vnext[0] = vadd(vprev[0], vprev[1]); vnext[1] = vadd(vprev[2], vprev[3]); stage2Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: (previous.de != 0) ? vnext : unpack(0) }; endrule rule stage3_rule; let previous = stage2Reg; Vector#(2, Vector#(3, Bit#(16))) vprev = previous.pixel; Yuv444 pixel = yuv444FromVector(vrshift(vadd(vprev[0], vprev[1]), 8)); stage3Reg <= VideoData { vsync: previous.vsync, hsync: previous.hsync, de: previous.de, pixel: (previous.de != 0) ? pixel : unpack(0) }; endrule rule yuv_rule; let v = stage3Reg; if (v.de == 1) indication.yuv(v.pixel.y, v.pixel.u, v.pixel.v); endrule rule yyuv_input_rule; rgb888ToYyuv.rgb888.put(yyuvInputWire); endrule rule yyuv_rule; let v <- rgb888ToYyuv.yyuv.get(); if (v.de == 1) indication.yyuv(v.pixel.yy, v.pixel.uv); endrule interface YuvRequest request; method Action toRgb(Bit#(8) r, Bit#(8) g, Bit#(8) b); indication.rgb(r, g, b); endmethod method Action toYuv(Bit#(8) r, Bit#(8) g, Bit#(8) b); stage0Reg <= VideoData { de: 1, vsync: 0, hsync: 0, pixel: Rgb888 { r:r, g:g, b:b } }; endmethod method Action toYyuv(Bit#(8) r, Bit#(8) g, Bit#(8) b); yyuvInputWire <= VideoData { de: 1, vsync: 0, hsync: 0, pixel: Rgb888 { r:r, g:g, b:b } }; endmethod endinterface endmodule ================================================ FILE: tests/yuv/testyuv.cpp ================================================ // Copyright (c) 2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include "YuvIndication.h" #include "YuvRequest.h" #include "GeneratedTypes.h" struct rgb { unsigned char r; unsigned char g; unsigned char b; int operator==(const struct rgb &o) { return r == o.r && g == o.g && b == o.b; } }; struct yuv { unsigned char y; unsigned char u; unsigned char v; int operator==(const struct yuv &o) { return y == o.y && u == o.u && v == o.v; } }; struct rgb expected_rgb; struct yuv expected_yuv; static int numTests = 0; class YuvIndication : public YuvIndicationWrapper { public: int cnt; void incr_cnt(){ if (++cnt >= numTests) exit(0); } void rgb(uint8_t r, uint8_t g, uint8_t b) { fprintf(stderr, "rgb(%d,%d,%d)\n", r, g, b); struct rgb answer = {r, g, b}; assert(expected_rgb == answer); incr_cnt(); } void yuv(uint8_t y, uint8_t u, uint8_t v) { fprintf(stderr, "yuv(%d,%d,%d)\n", y, u, v); struct yuv answer = {y,u,v}; assert(expected_yuv == answer); incr_cnt(); } void yyuv(uint8_t yy, uint8_t uv) { fprintf(stderr, "yyuv(%d,%d)\n", yy, uv); // assert(a == v1a); incr_cnt(); } YuvIndication(unsigned int id) : YuvIndicationWrapper(id), cnt(0){} }; struct yuv rgbtoyuv(unsigned short r, unsigned short g, unsigned short b) { unsigned char y = ( 77*r + 150*g + 29*b + 0) >> 8; unsigned char u = (-43*r - 85*g + 128*b + 128) >> 8; unsigned char v = (128*r - 107*g - 21*b + 128) >> 8; fprintf(stderr, "rgb %d,%d,%d -> yuv %d,%d,%d\n", r, g, b, y, u, v); struct yuv yuvret; yuvret.y = y; yuvret.u = u; yuvret.v = v; return yuvret; } int main(int argc, const char **argv) { YuvIndication indication(IfcNames_YuvIndicationH2S); YuvRequestProxy *device = new YuvRequestProxy(IfcNames_YuvRequestS2H); struct rgb tests[] = { { 0, 0, 0 }, { 1, 2, 3 }, { 128, 0, 0 }, { 0, 128, 0 }, { 0, 0, 128 }, { 255, 0, 0 }, { 0, 255, 0 }, { 0, 0, 255 }, { 255, 255, 255 }, }; numTests++; for (unsigned int i = 0; i < sizeof(tests)/sizeof(struct rgb); i++) { expected_rgb = tests[i]; expected_yuv = rgbtoyuv(tests[i].r, tests[i].g, tests[i].b); numTests++; device->toRgb(tests[i].r, tests[i].g, tests[i].b); numTests++; device->toYuv(tests[i].r, tests[i].g, tests[i].b); numTests++; device->toYyuv(tests[i].r, tests[i].g, tests[i].b); sleep(1); } expected_rgb = tests[0]; device->toRgb(tests[0].r, tests[0].g, tests[0].b); // now we're done fprintf(stderr, "Main::about to go to sleep\n"); while(true){sleep(2);} } ================================================ FILE: verilog/CONNECTNET.v ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. module CONNECTNET(IN, OUT); output OUT; input IN; assign OUT = IN; endmodule ================================================ FILE: verilog/CONNECTNET2.v ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. module CONNECTNET2(OUT1, OUT2, IN1, IN2); output OUT1; output OUT2; input IN1; input IN2; assign OUT1 = IN1; assign OUT2 = IN2; endmodule ================================================ FILE: verilog/FpgaReset.v ================================================ // Copyright (c) 2000-2012 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 29455 $ // $Date: 2012-08-27 22:02:09 +0000 (Mon, 27 Aug 2012) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif // Exposes FPGA GSR reset module FpgaReset ( CLK, OUT_RST ); parameter RSTDELAY = 1 ; // Width of reset shift reg input CLK ; output OUT_RST ; reg [RSTDELAY:0] reset_hold ; wire [RSTDELAY+1:0] next_reset = {reset_hold, ~ `BSV_RESET_VALUE} ; assign OUT_RST = reset_hold[RSTDELAY] ; always @( posedge CLK ) // reset is read synchronous with clock begin reset_hold <= `BSV_ASSIGNMENT_DELAY next_reset[RSTDELAY:0]; end // always @ ( posedge CLK ) `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS // synopsys translate_off initial begin #0 ; // initialize to reset reset_hold = {(RSTDELAY + 1) {`BSV_RESET_VALUE }} ; end // synopsys translate_on `endif // BSV_NO_INITIAL_BLOCKS endmodule // PositiveReset ================================================ FILE: verilog/GenBIBUF.v ================================================ // Copyright (c) 2013-2014 Quanta Research Cambridge, Inc. // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. module GenBIBUF(IO, PAD); parameter SIZE = 1; inout [SIZE-1:0]IO; inout [SIZE-1:0]PAD; genvar i; generate for(i = 0; i < SIZE; i = i + 1) begin BIBUF(.PAD(PAD[i]), .IO(IO[i])); end endgenerate endmodule ================================================ FILE: verilog/LinkInverter.v ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module LinkInverter(CLK, RST, put, EN_put, RDY_put, get, EN_get, RDY_get, modReady, inverseReady ); parameter DATA_WIDTH = 1; input CLK; input RST; output [DATA_WIDTH-1 : 0] get; input [DATA_WIDTH-1 : 0] put; input EN_get; input EN_put; output RDY_get; output RDY_put; output modReady; output inverseReady; // will this work? assign get = put; assign RDY_get = 1; assign RDY_put = 1; assign modReady = EN_get; assign inverseReady = EN_put; endmodule // LinkInverter ================================================ FILE: verilog/PositiveReset.v ================================================ // Copyright (c) 2000-2012 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 29455 $ // $Date: 2012-08-27 22:02:09 +0000 (Mon, 27 Aug 2012) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif // A synchronization module for resets. Output resets are held for // RSTDELAY+1 cycles, RSTDELAY >= 0. Both assertion and deassertions is // synchronized to the clock. module PositiveReset ( IN_RST, CLK, OUT_RST ); parameter RSTDELAY = 1 ; // Width of reset shift reg input CLK ; input IN_RST ; output OUT_RST ; (* ASYNC_REG = "true" *) reg reset_meta ; reg [RSTDELAY:1] reset_hold ; wire [RSTDELAY+1:0] next_reset = {reset_hold, reset_meta, 1'b0} ; assign OUT_RST = reset_hold[RSTDELAY] ; always @( posedge CLK ) // reset is read synchronous with clock begin if (IN_RST == `BSV_RESET_VALUE) begin reset_meta <= 1; end else begin reset_meta <= 0; end if (reset_meta == 1) begin reset_hold <= `BSV_ASSIGNMENT_DELAY -1 ; end else begin reset_hold <= `BSV_ASSIGNMENT_DELAY next_reset[RSTDELAY:1]; end end // always @ ( posedge CLK ) `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS // synopsys translate_off initial begin #0 ; // initialize out of reset forcing the designer to do one reset_hold = 0 ; end // synopsys translate_on `endif // BSV_NO_INITIAL_BLOCKS endmodule // PositiveReset ================================================ FILE: verilog/PutInverter.v ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module PutInverter(CLK, RST, put, EN_put, RDY_put, get, EN_get, RDY_get ); parameter DATA_WIDTH = 1; input CLK; input RST; output [DATA_WIDTH-1 : 0] get; input [DATA_WIDTH-1 : 0] put; input EN_get; input EN_put; output RDY_get; output RDY_put; // will this work? assign get = put; assign RDY_get = EN_put; assign RDY_put = EN_get; endmodule // PutInverter ================================================ FILE: verilog/SyncFIFO.v ================================================ // Copyright (c) 2000-2012 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 33367 $ // $Date: 2014-02-18 17:46:14 +0000 (Tue, 18 Feb 2014) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif `ifdef BSV_RESET_FIFO_HEAD `define BSV_RESET_EDGE_HEAD or `BSV_RESET_EDGE dRST `else `define BSV_RESET_EDGE_HEAD `endif // A clock synchronization FIFO where the enqueue and dequeue sides are in // different clock domains. // There are no restrictions w.r.t. clock frequencies // The depth of the FIFO must be a power of 2 (2,4,8,...) since the // indexing uses a Gray code counter. // FULL and EMPTY signal are pessimistic, that is, they are asserted // immediately when the FIFO becomes FULL or EMPTY, but their deassertion // is delayed due to synchronization latency. module SyncFIFO( sCLK, sRST, dCLK, sENQ, sD_IN, sFULL_N, dDEQ, dD_OUT, dEMPTY_N ) ; parameter dataWidth = 1 ; parameter depth = 2 ; // minimum 2 parameter indxWidth = 1 ; // minimum 1 // input clock domain ports input sCLK ; input sRST ; input sENQ ; input [dataWidth -1 : 0] sD_IN ; output sFULL_N ; // destination clock domain ports input dCLK ; input dDEQ ; output dEMPTY_N ; output [dataWidth -1 : 0] dD_OUT ; // constants for bit masking of the gray code wire [indxWidth : 0] msbset = ~({(indxWidth + 1){1'b1}} >> 1) ; wire [indxWidth - 1 : 0] msb2set = ~({(indxWidth + 0){1'b1}} >> 1) ; wire [indxWidth : 0] msb12set = msbset | {1'b0, msb2set} ; // 'b11000... // FIFO Memory (* ASYNC_REG = "TRUE" *) reg [dataWidth -1 : 0] fifoMem [0: depth -1 ] ; (* ASYNC_REG = "TRUE" *) reg [dataWidth -1 : 0] dDoutReg ; // Enqueue Pointer support reg [indxWidth +1 : 0] sGEnqPtr, sGEnqPtr1 ; // Flops reg sNotFullReg ; wire sNextNotFull, sFutureNotFull ; // Dequeue Pointer support reg [indxWidth+1 : 0] dGDeqPtr, dGDeqPtr1 ; // Flops reg dNotEmptyReg ; wire dNextNotEmpty; // Reset generation wire dRST ; // flops to sychronize enqueue and dequeue point across domains (* ASYNC_REG = "TRUE" *) reg [indxWidth : 0] dSyncReg1, dEnqPtr ; (* ASYNC_REG = "TRUE" *) reg [indxWidth : 0] sSyncReg1, sDeqPtr ; wire [indxWidth - 1 :0] sEnqPtrIndx, dDeqPtrIndx ; // Resets assign dRST = sRST ; // Outputs assign dD_OUT = dDoutReg ; assign dEMPTY_N = dNotEmptyReg ; assign sFULL_N = sNotFullReg ; // Indexes are truncated from the Gray counter with parity assign sEnqPtrIndx = sGEnqPtr[indxWidth-1:0]; assign dDeqPtrIndx = dGDeqPtr[indxWidth-1:0]; // Fifo memory write always @(posedge sCLK) begin if ( sENQ ) fifoMem[sEnqPtrIndx] <= `BSV_ASSIGNMENT_DELAY sD_IN ; end // always @ (posedge sCLK) //////////////////////////////////////////////////////////////////////// // Enqueue Pointer and increment logic assign sNextNotFull = (sGEnqPtr [indxWidth+1:1] ^ msb12set) != sDeqPtr ; assign sFutureNotFull = (sGEnqPtr1[indxWidth+1:1] ^ msb12set) != sDeqPtr ; always @(posedge sCLK or `BSV_RESET_EDGE sRST) begin if (sRST == `BSV_RESET_VALUE) begin sGEnqPtr <= `BSV_ASSIGNMENT_DELAY {(indxWidth +2 ) {1'b0}} ; sGEnqPtr1 <= `BSV_ASSIGNMENT_DELAY { {indxWidth {1'b0}}, 2'b11} ; sNotFullReg <= `BSV_ASSIGNMENT_DELAY 1'b0 ; // Mark as full during reset to avoid spurious loads end // if (sRST == `BSV_RESET_VALUE) else begin if ( sENQ ) begin sGEnqPtr1 <= `BSV_ASSIGNMENT_DELAY incrGrayP( sGEnqPtr1 ) ; sGEnqPtr <= `BSV_ASSIGNMENT_DELAY sGEnqPtr1 ; sNotFullReg <= `BSV_ASSIGNMENT_DELAY sFutureNotFull ; end // if ( sENQ ) else begin sNotFullReg <= `BSV_ASSIGNMENT_DELAY sNextNotFull ; end // else: !if( sENQ ) end // else: !if(sRST == `BSV_RESET_VALUE) end // always @ (posedge sCLK or `BSV_RESET_EDGE sRST) // Enqueue pointer synchronizer to dCLK always @(posedge dCLK or `BSV_RESET_EDGE dRST) begin if (dRST == `BSV_RESET_VALUE) begin dSyncReg1 <= `BSV_ASSIGNMENT_DELAY {(indxWidth + 1) {1'b0}} ; dEnqPtr <= `BSV_ASSIGNMENT_DELAY {(indxWidth + 1) {1'b0}} ; end // if (dRST == `BSV_RESET_VALUE) else begin dSyncReg1 <= `BSV_ASSIGNMENT_DELAY sGEnqPtr[indxWidth+1:1] ; // Clock domain crossing dEnqPtr <= `BSV_ASSIGNMENT_DELAY dSyncReg1 ; end // else: !if(dRST == `BSV_RESET_VALUE) end // always @ (posedge dCLK or `BSV_RESET_EDGE dRST) //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // Enqueue Pointer and increment logic assign dNextNotEmpty = dGDeqPtr[indxWidth+1:1] != dEnqPtr ; always @(posedge dCLK or `BSV_RESET_EDGE dRST) begin if (dRST == `BSV_RESET_VALUE) begin dGDeqPtr <= `BSV_ASSIGNMENT_DELAY {(indxWidth + 2) {1'b0}} ; dGDeqPtr1 <= `BSV_ASSIGNMENT_DELAY {{indxWidth {1'b0}}, 2'b11 } ; dNotEmptyReg <= `BSV_ASSIGNMENT_DELAY 1'b0 ; end // if (dRST == `BSV_RESET_VALUE) else begin if ((!dNotEmptyReg || dDEQ) && dNextNotEmpty) begin dGDeqPtr <= `BSV_ASSIGNMENT_DELAY dGDeqPtr1 ; dGDeqPtr1 <= `BSV_ASSIGNMENT_DELAY incrGrayP( dGDeqPtr1 ); dNotEmptyReg <= `BSV_ASSIGNMENT_DELAY 1'b1; end else if (dDEQ && !dNextNotEmpty) begin dNotEmptyReg <= `BSV_ASSIGNMENT_DELAY 1'b0; end end // else: !if(dRST == `BSV_RESET_VALUE) end // always @ (posedge dCLK or `BSV_RESET_EDGE dRST) always @(posedge dCLK `BSV_RESET_EDGE_HEAD) begin `ifdef BSV_RESET_FIFO_HEAD if (dRST == `BSV_RESET_VALUE) begin dDoutReg <= `BSV_ASSIGNMENT_DELAY {dataWidth {1'b0}} ; end // if (dRST == `BSV_RESET_VALUE) else `endif begin if ((!dNotEmptyReg || dDEQ) && dNextNotEmpty) begin dDoutReg <= `BSV_ASSIGNMENT_DELAY fifoMem[dDeqPtrIndx] ; end end end // Dequeue pointer synchronized to sCLK always @(posedge sCLK or `BSV_RESET_EDGE sRST) begin if (sRST == `BSV_RESET_VALUE) begin sSyncReg1 <= `BSV_ASSIGNMENT_DELAY {(indxWidth + 1) {1'b0}} ; sDeqPtr <= `BSV_ASSIGNMENT_DELAY {(indxWidth + 1) {1'b0}} ; // When reset mark as not empty end // if (sRST == `BSV_RESET_VALUE) else begin sSyncReg1 <= `BSV_ASSIGNMENT_DELAY dGDeqPtr[indxWidth+1:1] ; // clock domain crossing sDeqPtr <= `BSV_ASSIGNMENT_DELAY sSyncReg1 ; end // else: !if(sRST == `BSV_RESET_VALUE) end // always @ (posedge sCLK or `BSV_RESET_EDGE sRST) //////////////////////////////////////////////////////////////////////// `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS // synopsys translate_off initial begin : initBlock integer i ; // initialize the FIFO memory with aa's for (i = 0; i < depth; i = i + 1) begin fifoMem[i] = {((dataWidth + 1)/2){2'b10}} ; end dDoutReg = {((dataWidth + 1)/2){2'b10}} ; // initialize the pointer sGEnqPtr = {((indxWidth + 2)/2){2'b10}} ; sGEnqPtr1 = sGEnqPtr ; sNotFullReg = 1'b0 ; dGDeqPtr = sGEnqPtr ; dGDeqPtr1 = sGEnqPtr ; dNotEmptyReg = 1'b0; // initialize other registers sSyncReg1 = sGEnqPtr ; sDeqPtr = sGEnqPtr ; dSyncReg1 = sGEnqPtr ; dEnqPtr = sGEnqPtr ; end // block: initBlock // synopsys translate_on // synopsys translate_off initial begin : parameter_assertions integer ok ; integer i, expDepth ; ok = 1; expDepth = 1 ; // calculate x = 2 ** (indxWidth - 1) for( i = 0 ; i < indxWidth ; i = i + 1 ) begin expDepth = expDepth * 2 ; end // for ( i = 0 ; i < indxWidth ; i = i + 1 ) if ( expDepth != depth ) begin ok = 0; $display ( "ERROR SyncFiFO.v: index size and depth do not match;" ) ; $display ( "\tdepth must equal 2 ** index size. expected %0d", expDepth ); end #0 if ( ok == 0 ) $finish ; end // initial begin // synopsys translate_on `endif // BSV_NO_INITIAL_BLOCKS function [indxWidth+1:0] incrGrayP ; input [indxWidth+1:0] grayPin; begin: incrGrayPBlock reg [indxWidth :0] g; reg p ; reg [indxWidth :0] i; g = grayPin[indxWidth+1:1]; p = grayPin[0]; i = incrGray (g,p); incrGrayP = {i,~p}; end endfunction function [indxWidth:0] incrGray ; input [indxWidth:0] grayin; input parity ; begin: incrGrayBlock integer i; reg [indxWidth: 0] tempshift; reg [indxWidth: 0] flips; flips[0] = ! parity ; for ( i = 1 ; i < indxWidth ; i = i+1 ) begin tempshift = grayin << (2 + indxWidth - i ) ; flips[i] = parity & grayin[i-1] & ~(| tempshift ) ; end tempshift = grayin << 2 ; flips[indxWidth] = parity & ~(| tempshift ) ; incrGray = flips ^ grayin ; end endfunction endmodule // FIFOSync `ifdef testBluespec module testSyncFIFO() ; parameter dsize = 8; parameter fifodepth = 32; parameter fifoidx = 5; wire sCLK, dCLK, dRST ; wire sENQ, dDEQ; wire sFULL_N, dEMPTY_N ; wire [dsize -1:0] sDIN, dDOUT ; reg [dsize -1:0] sCNT, dCNT ; reg sRST, sCLR ; ClockGen#(15,14,10) sc( sCLK ); ClockGen#(11,12,2600) dc( dCLK ); initial begin sCNT = 0; dCNT = 0; sCLR = 1'b0 ; sRST = `BSV_RESET_VALUE ; $display( "running test" ) ; $dumpfile("SyncFIFO.vcd"); $dumpvars(5,testSyncFIFO) ; $dumpon ; #200 ; sRST = !`BSV_RESET_VALUE ; #100000 $finish ; end // initial begin initial begin #50000 ; @(posedge sCLK ) ; sCLR <= `BSV_ASSIGNMENT_DELAY 1'b1 ; @(posedge sCLK ) ; sCLR <= `BSV_ASSIGNMENT_DELAY 1'b0 ; end SyncFIFO #(dsize,fifodepth,fifoidx) dut( sCLK, sRST, dCLK, sENQ, sDIN, sFULL_N, // sCLR, dDEQ, dDOUT, dEMPTY_N ); assign sDIN = sCNT ; assign sENQ = sFULL_N ; always @(posedge sCLK) begin if (sENQ ) begin sCNT <= `BSV_ASSIGNMENT_DELAY sCNT + 1; end end // always @ (posedge sCLK) assign dDEQ = dEMPTY_N ; always @(posedge dCLK) begin if (dDEQ ) begin $display( "dequeing %d", dDOUT ) ; end end // always @ (posedge dCLK) endmodule // testSyncFIFO `endif ================================================ FILE: verilog/SyncFIFO1.v ================================================ // Copyright (c) 2000-2012 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 29441 $ // $Date: 2012-08-27 21:58:03 +0000 (Mon, 27 Aug 2012) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif // A clock synchronization FIFO where the enqueue and dequeue sides are in // different clock domains. // The depth of the FIFO is strictly 1 element. Implementation uses only // 1 register to minimize hardware // There are no restrictions w.r.t. clock frequencies // FULL and EMPTY signal are pessimistic, that is, they are asserted // immediately when the FIFO becomes FULL or EMPTY, but their deassertion // is delayed due to synchronization latency. module SyncFIFO1( sCLK, sRST, dCLK, sENQ, sD_IN, sFULL_N, dDEQ, dD_OUT, dEMPTY_N ) ; parameter dataWidth = 1 ; // input clock domain ports input sCLK ; input sRST ; input sENQ ; input [dataWidth -1 : 0] sD_IN ; output sFULL_N ; // destination clock domain ports input dCLK ; input dDEQ ; output dEMPTY_N ; output [dataWidth -1 : 0] dD_OUT ; // FIFO DATA (* ASYNC_REG = "TRUE" *) reg [dataWidth -1 : 0] syncFIFO1Data ; // Reset generation wire dRST = sRST; // sCLK registers reg sEnqToggle, sDeqToggle, sSyncReg1; // dCLK registers reg dEnqToggle, dDeqToggle, dSyncReg1; // output assignment assign dD_OUT = syncFIFO1Data; assign dEMPTY_N = dEnqToggle != dDeqToggle; assign sFULL_N = sEnqToggle == sDeqToggle; always @(posedge sCLK or `BSV_RESET_EDGE sRST) begin if (sRST == `BSV_RESET_VALUE) begin syncFIFO1Data <= `BSV_ASSIGNMENT_DELAY {dataWidth {1'b0}}; sEnqToggle <= `BSV_ASSIGNMENT_DELAY 1'b0; sSyncReg1 <= `BSV_ASSIGNMENT_DELAY 1'b0; sDeqToggle <= `BSV_ASSIGNMENT_DELAY 1'b1; // FIFO marked as full during reset end else begin if (sENQ && (sEnqToggle == sDeqToggle)) begin syncFIFO1Data <= `BSV_ASSIGNMENT_DELAY sD_IN; sEnqToggle <= `BSV_ASSIGNMENT_DELAY ! sEnqToggle; end sSyncReg1 <= `BSV_ASSIGNMENT_DELAY dDeqToggle; // clock domain crossing sDeqToggle <= `BSV_ASSIGNMENT_DELAY sSyncReg1; end end always @(posedge dCLK or `BSV_RESET_EDGE dRST) begin if (dRST == `BSV_RESET_VALUE) begin dEnqToggle <= `BSV_ASSIGNMENT_DELAY 1'b0; dSyncReg1 <= `BSV_ASSIGNMENT_DELAY 1'b0; dDeqToggle <= `BSV_ASSIGNMENT_DELAY 1'b0; end else begin if (dDEQ && (dEnqToggle != dDeqToggle)) begin dDeqToggle <= `BSV_ASSIGNMENT_DELAY ! dDeqToggle; end dSyncReg1 <= `BSV_ASSIGNMENT_DELAY sEnqToggle; // clock domain crossing dEnqToggle <= `BSV_ASSIGNMENT_DELAY dSyncReg1; end end `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS // synopsys translate_off initial begin : initBlock syncFIFO1Data = {((dataWidth + 1)/2){2'b10}} ; sEnqToggle = 1'b0; sDeqToggle = 1'b0; sSyncReg1 = 1'b0; dEnqToggle = 1'b0; dDeqToggle = 1'b0; dSyncReg1 = 1'b0; end // synopsys translate_on `endif // !`ifdef BSV_NO_INITIAL_BLOCKS // synopsys translate_off always@(posedge sCLK) begin: error_checks1 reg enqerror ; enqerror = 0; if (sRST == ! `BSV_RESET_VALUE) begin if ( sENQ && (sEnqToggle != sDeqToggle)) begin enqerror = 1; $display( "Warning: SyncFIFO1: %m -- Enqueuing to a full fifo" ) ; end end end always@(posedge dCLK) begin: error_checks2 reg deqerror ; deqerror = 0; if (dRST == ! `BSV_RESET_VALUE) begin if ( dDEQ && (dEnqToggle == dDeqToggle)) begin deqerror = 1; $display( "Warning: SyncFIFO1: %m -- Dequeuing from an empty full fifo" ) ; end end end // block: error_checks // synopsys translate_on endmodule ================================================ FILE: verilog/SyncReset.v ================================================ // Copyright (c) 2000-2012 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 29455 $ // $Date: 2012-08-27 22:02:09 +0000 (Mon, 27 Aug 2012) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif // A synchronization module for resets. Output resets are held for // RSTDELAY+1 cycles, RSTDELAY >= 0. Both assertion and deassertions is // synchronized to the clock. module SyncReset ( IN_RST, CLK, OUT_RST ); parameter RSTDELAY = 1 ; // Width of reset shift reg input CLK ; input IN_RST ; output OUT_RST ; (* ASYNC_REG = "TRUE" *) reg reset_meta; reg [RSTDELAY:1] reset_hold ; wire [RSTDELAY+1:0] next_reset = {reset_hold, reset_meta, ~ `BSV_RESET_VALUE}; assign OUT_RST = reset_hold[RSTDELAY] ; always @( posedge CLK ) // reset is read synchronous with clock begin if (IN_RST == `BSV_RESET_VALUE) begin reset_meta <= `BSV_ASSIGNMENT_DELAY `BSV_RESET_VALUE ; end else begin reset_meta <= `BSV_ASSIGNMENT_DELAY ~ `BSV_RESET_VALUE ; end if (reset_meta == `BSV_RESET_VALUE) begin reset_hold <= `BSV_ASSIGNMENT_DELAY {(RSTDELAY) {`BSV_RESET_VALUE}} ; end else begin reset_hold <= `BSV_ASSIGNMENT_DELAY next_reset[RSTDELAY:1]; end end // always @ ( posedge CLK ) `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS // synopsys translate_off initial begin #0 ; // initialize out of reset forcing the designer to do one reset_hold = {(RSTDELAY + 1) {~ `BSV_RESET_VALUE }} ; end // synopsys translate_on `endif // BSV_NO_INITIAL_BLOCKS endmodule // SyncReset ================================================ FILE: verilog/XsimDmaReadWrite.sv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //`timescale 1ns / 1ps `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module XsimDmaReadWrite(input CLK, input CLK_GATE, input RST, input en_init, input [31:0] init_id, input [31:0] init_handle, input [31:0] init_size, input en_initfd, input [31:0] initfd_id, input [31:0] initfd_fd, input en_idreturn, input [31:0] idreturn_id, output rdy_readrequest, input en_readrequest, input [31:0] readrequest_addr, input [31:0] readrequest_handle, input en_readresponse, output rdy_readresponse, output [31:0] readresponse_data, input en_write32, input [31:0] write32_addr, input [31:0] write32_handle, input [31:0] write32_data, input [3:0] write32_byteenable ); reg readresponse_valid_reg; reg [31:0] readresponse_data_reg; import "DPI-C" function void simDma_init(input int id, input int handle, input int size); import "DPI-C" function void simDma_initfd(input int id, input int fd); import "DPI-C" function void simDma_idreturn(input int aid); import "DPI-C" function void write_simDma32(input int handle, input int addr, input int data, input int byteenable); import "DPI-C" function int read_simDma32(input int handle, input int addr); assign rdy_readresponse = readresponse_valid_reg; assign rdy_readrequest = !readresponse_valid_reg || en_readresponse; assign readresponse_data = readresponse_data_reg; always @(posedge CLK) begin if (RST == `BSV_RESET_VALUE) begin readresponse_data_reg <= 32'haaaaaaaa; readresponse_valid_reg <= 0; end else begin if (en_init == 1) simDma_init(init_id, init_handle, init_size); if (en_initfd == 1) simDma_initfd(initfd_id, initfd_fd); if (en_idreturn == 1) simDma_idreturn(idreturn_id); //if (en_readresponse) $display("xsimtop.readresponse data=%h", readresponse_data_reg); if (en_readrequest == 1) begin readresponse_data_reg <= read_simDma32(readrequest_handle, readrequest_addr); //$display("xsimtop.readrequest handle=%h addr=%h", readrequest_handle, readrequest_addr); readresponse_valid_reg <= 1; end else if (en_readresponse) begin readresponse_valid_reg <= 0; readresponse_data_reg <= 32'hbbbbbbbb; end if (en_write32 == 1) write_simDma32(write32_handle, write32_addr, write32_data, write32_byteenable); end // else: !if(RST == BSV_RESET_VALUE) end // always @ (posedge CLK) endmodule ================================================ FILE: verilog/XsimFinish.sv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //`timescale 1ns / 1ps `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif ================================================ FILE: verilog/XsimLink.sv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //`timescale 1ns / 1ps `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module XsimLink #(parameter DATAWIDTH=32) ( input RST, input CLK, input CLK_GATE, input start_listening, input en_start, input [31:0] start_linknumber, input [DATAWIDTH-1:0] tx_enq_v, input en_rx_deq, input en_tx_enq, output [DATAWIDTH-1:0] rx_first, output rdy_rx_first, output rdy_rx_deq, output rdy_tx_enq, output tx_not_full, output rx_not_empty, output link_up ); reg [31:0] linknumber_reg; reg started; reg listeningreg; reg link_up_reg; reg rx_valid; reg tx_valid; reg [DATAWIDTH-1:0] rx_reg; reg [DATAWIDTH-1:0] tx_reg; int rx_val; longint rx_val64; import "DPI-C" function int bsimLinkUp(input int linknumber, input bit listening); import "DPI-C" function void bsimLinkOpen(input int linknumber, input bit listening); import "DPI-C" function int bsimLinkCanReceive(input int linknumber, input bit listening); import "DPI-C" function int bsimLinkCanTransmit(input int linknumber, input bit listening); import "DPI-C" function int bsimLinkReceive32(input int linknumber, input bit listening); import "DPI-C" function void bsimLinkTransmit32(input int linknumber, input bit listening, input int val); import "DPI-C" function longint bsimLinkReceive64(input int linknumber, input bit listening); import "DPI-C" function void bsimLinkTransmit64(input int linknumber, input bit listening, input longint val); assign rx_first = rx_reg; assign rdy_rx_first = rx_valid && started; assign rdy_rx_deq = rx_valid && started; assign rdy_tx_enq = !tx_valid && started; assign tx_not_full = !tx_valid; assign rx_not_empty = rx_valid; assign link_up = link_up_reg; always @(posedge CLK) begin if (RST == `BSV_RESET_VALUE) begin started <= 0; linknumber_reg <= 0; link_up_reg <= 0; listeningreg <= 0; rx_valid <= 0; tx_valid <= 0; rx_reg <= 32'haaaaaaaa; tx_reg <= 32'haaaaaaaa; end else begin if (en_start == 1 && started == 0) begin //$display("start linknumber=%d listening=%d", start_linknumber, start_listening); bsimLinkOpen(start_linknumber, start_listening); linknumber_reg <= start_linknumber; listeningreg <= start_listening; started <= 1; end if (started && !rx_valid && bsimLinkCanReceive(linknumber_reg, listeningreg)) begin if (DATAWIDTH == 32) begin rx_val = bsimLinkReceive32(linknumber_reg, listeningreg); rx_reg <= rx_val; end else begin rx_val64 = bsimLinkReceive64(linknumber_reg, listeningreg); rx_reg <= rx_val64; end rx_valid <= 1; //$display("link %d.%d received %d %h", linknumber_reg, listeningreg, rx_valid, rx_val); end if (started && tx_valid && bsimLinkCanTransmit(linknumber_reg, listeningreg)) begin //$display("link %d.%d transmitting %d %h", linknumber_reg, listeningreg, tx_valid, tx_reg); if (DATAWIDTH == 32) bsimLinkTransmit32(linknumber_reg, listeningreg, tx_reg); else bsimLinkTransmit64(linknumber_reg, listeningreg, tx_reg); tx_valid <= 0; end if (started && en_rx_deq) begin rx_valid <= 0; //$display("%d.%d rx_deq %d %h", linknumber_reg, listeningreg, rx_valid, rx_reg); end if (started && en_tx_enq && !tx_valid) begin tx_valid <= 1; tx_reg <= tx_enq_v; //$display("%d.%d tx_enq %h", linknumber_reg, listeningreg, tx_enq_v); end link_up_reg <= bsimLinkUp(linknumber_reg, listeningreg); end end endmodule ================================================ FILE: verilog/XsimSink.sv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //`timescale 1ns / 1ps `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module XsimSink(input CLK, input CLK_GATE, input RST, input [31:0] portal, output RDY_beat, input EN_beat, output [31:0] beat); reg valid_reg; reg [31:0] beat_reg; import "DPI-C" function longint dpi_msgSink_beat(input int portal); assign RDY_beat = valid_reg; assign beat = beat_reg; always @(posedge CLK) begin if (RST == `BSV_RESET_VALUE) begin valid_reg <= 0; beat_reg <= 32'haaaaaaaa; end else if (EN_beat == 1 || valid_reg == 0) begin `ifndef BOARD_cvc automatic longint v = dpi_msgSink_beat(portal); valid_reg <= v[32]; beat_reg <= v[31:0]; `else { valid_reg, beat_reg } <= dpi_msgSink_beat(portal); `endif end end endmodule ================================================ FILE: verilog/XsimSource.sv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //`timescale 1ns / 1ps `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif module XsimSource( input CLK, input CLK_GATE, input RST, input [31:0] portal, input en_beat, input [31:0] beat); import "DPI-C" function void dpi_msgSource_beat(input int portal, input int beat); always @(posedge CLK) begin if (en_beat) dpi_msgSource_beat(portal, beat); end endmodule ================================================ FILE: verilog/altera/BRAM1.v ================================================ // Copyright (c) 2000-2011 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision$ // $Date$ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif // Single-Ported BRAM module BRAM1(CLK, EN, WE, ADDR, DI, DO ); parameter PIPELINED = 0; parameter ADDR_WIDTH = 1; parameter DATA_WIDTH = 1; parameter MEMSIZE = 1; input CLK; input EN; input WE; input [ADDR_WIDTH-1:0] ADDR; input [DATA_WIDTH-1:0] DI; output [DATA_WIDTH-1:0] DO; wire REN = EN & !WE; wire WEN = EN & WE; altsyncram #( .width_a (DATA_WIDTH), .widthad_a (ADDR_WIDTH), .numwords_a (MEMSIZE), .outdata_reg_a ((PIPELINED) ? "CLOCK0" : "UNREGISTERED"), .address_aclr_a ("NONE"), .outdata_aclr_a ("NONE"), .indata_aclr_a ("NONE"), .wrcontrol_aclr_a ("NONE"), .byteena_aclr_a ("NONE"), .width_byteena_a (1), .width_b (1),// .widthad_b (1),// .numwords_b (0),// .rdcontrol_reg_b ("CLOCK1"),// .address_reg_b ("CLOCK1"),// .outdata_reg_b ("UNREGISTERED"),// .outdata_aclr_b ("NONE"),// .rdcontrol_aclr_b ("NONE"),// .indata_reg_b ("CLOCK1"),// .wrcontrol_wraddress_reg_b ("CLOCK1"),// .byteena_reg_b ("CLOCK1"),// .indata_aclr_b ("NONE"),// .wrcontrol_aclr_b ("NONE"),// .address_aclr_b ("NONE"),// .byteena_aclr_b ("NONE"),// .width_byteena_b (1),// .clock_enable_input_a ("BYPASS"), .clock_enable_output_a ("BYPASS"), .clock_enable_input_b ("NORMAL"),// .clock_enable_output_b ("NORMAL"),// .clock_enable_core_a ("USE_INPUT_CLKEN"),// .clock_enable_core_b ("USE_INPUT_CLKEN"),// .read_during_write_mode_port_a ("NEW_DATA_NO_NBE_READ"), .read_during_write_mode_port_b ("NEW_DATA_NO_NBE_READ"), .enable_ecc ("FALSE"),// .width_eccstatus (3),// .ecc_pipeline_stage_enabled ("FALSE"),// .operation_mode ("SINGLE_PORT"), .byte_size (8),// .read_during_write_mode_mixed_ports ("DONT_CARE"),// .ram_block_type ("AUTO"),// .init_file ("UNUSED"),// .init_file_layout ("UNUSED"),// .maximum_depth (MEMSIZE), // number of elements in memory .intended_device_family ("Stratix"),// .lpm_hint ("ENABLE_RUNTIME_MOD=NO"), .lpm_type ("altsyncram"),// .implement_in_les ("OFF"), // .power_up_uninitialized ("FALSE") ) RAM ( .wren_a (WEN), .rden_a (REN), .data_a (DI), .address_a (ADDR), .clock0 (CLK), .clocken0 (1'b1), .clocken1 (1'b1), .aclr0 (1'b0), .byteena_a (1'b1), .addressstall_a (1'b0), .q_a (DO), .wren_b (1'b0), .rden_b (1'b1), .data_b (1'b1), .address_b (1'b1), .clock1 (1'b1), .clocken2 (1'b1), .clocken3 (1'b1), .aclr1 (1'b0), .byteena_b (1'b1), .addressstall_b (1'b0), .q_b (), .eccstatus () ); endmodule // BRAM1 ================================================ FILE: verilog/altera/BRAM1BE.v ================================================ // Copyright (c) 2000-2011 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 31023 $ // $Date: 2013-04-15 16:20:17 +0000 (Mon, 15 Apr 2013) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif // Single-Ported BRAM with byte enables module BRAM1BE(CLK, EN, WE, ADDR, DI, DO ); parameter PIPELINED = 0; parameter ADDR_WIDTH = 1; parameter DATA_WIDTH = 1; parameter CHUNKSIZE = 1; parameter WE_WIDTH = 1; parameter MEMSIZE = 1; input CLK; input EN; input [WE_WIDTH-1:0] WE; input [ADDR_WIDTH-1:0] ADDR; input [DATA_WIDTH-1:0] DI; output [DATA_WIDTH-1:0] DO; reg [DATA_WIDTH-1:0] RAM[0:MEMSIZE-1]; reg [DATA_WIDTH-1:0] DO_R; reg [DATA_WIDTH-1:0] DO_R2; `ifdef BSV_NO_INITIAL_BLOCKS `else // synopsys translate_off initial begin : init_block integer i; for (i = 0; i < MEMSIZE; i = i + 1) begin RAM[i] = { ((DATA_WIDTH+1)/2) { 2'b10 } }; end DO_R = { ((DATA_WIDTH+1)/2) { 2'b10 } }; DO_R2 = { ((DATA_WIDTH+1)/2) { 2'b10 } }; end // synopsys translate_on `endif // !`ifdef BSV_NO_INITIAL_BLOCKS // iverilog does not support the full verilog-2001 language. This fixes that for simulation. `ifdef __ICARUS__ reg [DATA_WIDTH-1:0] MASK, IMASK; reg [DATA_WIDTH-1:0] DATA; wire [DATA_WIDTH-1:0] DATAwr; assign DATAwr = RAM[ADDR] ; always @(WE or DI or DATAwr) begin : combo1 integer j; MASK = 0; IMASK = 0; for(j = WE_WIDTH-1; j >= 0; j = j - 1) begin if (WE[j]) MASK = (MASK << 8) | { { DATA_WIDTH-CHUNKSIZE { 1'b0 } }, { CHUNKSIZE { 1'b1 } } }; else MASK = (MASK << 8); end IMASK = ~MASK; DATA = (DATAwr & IMASK) | (DI & MASK); end always @(posedge CLK) begin if (EN) begin if (WE) begin RAM[ADDR] <= `BSV_ASSIGNMENT_DELAY DATA; DO_R <= `BSV_ASSIGNMENT_DELAY DATA; end else begin DO_R <= `BSV_ASSIGNMENT_DELAY RAM[ADDR]; end end end `else generate genvar i; for(i = 0; i < WE_WIDTH; i = i + 1) begin: porta_we always @(posedge CLK) begin if (EN) begin if (WE[i]) begin RAM[ADDR][((i+1)*CHUNKSIZE)-1 : i*CHUNKSIZE] <= `BSV_ASSIGNMENT_DELAY DI[((i+1)*CHUNKSIZE)-1 : i*CHUNKSIZE]; DO_R[((i+1)*CHUNKSIZE)-1 : i*CHUNKSIZE] <= `BSV_ASSIGNMENT_DELAY DI[((i+1)*CHUNKSIZE)-1 : i*CHUNKSIZE]; end else begin DO_R[((i+1)*CHUNKSIZE)-1 : i*CHUNKSIZE] <= `BSV_ASSIGNMENT_DELAY RAM[ADDR][((i+1)*CHUNKSIZE)-1 : i*CHUNKSIZE]; end end end end endgenerate `endif // !`ifdef __ICARUS__ // Output driver always @(posedge CLK) begin DO_R2 <= `BSV_ASSIGNMENT_DELAY DO_R; end assign DO = (PIPELINED) ? DO_R2 : DO_R; endmodule // BRAM1BE ================================================ FILE: verilog/altera/BRAM2.v ================================================ // Copyright (c) 2000-2009 Bluespec, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // $Revision: 24080 $ // $Date: 2011-05-18 19:32:52 +0000 (Wed, 18 May 2011) $ `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY `endif // Dual-Ported BRAM (READ FIRST) module BRAM2(CLKA, ENA, WEA, ADDRA, DIA, DOA, CLKB, ENB, WEB, ADDRB, DIB, DOB ); parameter PIPELINED = 0; parameter ADDR_WIDTH = 1; parameter DATA_WIDTH = 1; parameter MEMSIZE = 1; input CLKA; input ENA; input WEA; input [ADDR_WIDTH-1:0] ADDRA; input [DATA_WIDTH-1:0] DIA; output [DATA_WIDTH-1:0] DOA; input CLKB; input ENB; input WEB; input [ADDR_WIDTH-1:0] ADDRB; input [DATA_WIDTH-1:0] DIB; output [DATA_WIDTH-1:0] DOB; reg [DATA_WIDTH-1:0] RAM[0:MEMSIZE-1] /* synthesis syn_ramstyle="no_rw_check" */ ; reg [DATA_WIDTH-1:0] DOA_R; reg [DATA_WIDTH-1:0] DOB_R; reg [DATA_WIDTH-1:0] DOA_D1_R; reg [DATA_WIDTH-1:0] DOB_D1_R; `ifdef BSV_NO_INITIAL_BLOCKS `else // synopsys translate_off integer i; initial begin : init_block for (i = 0; i < MEMSIZE; i = i + 1) begin RAM[i] = { ((DATA_WIDTH+1)/2) { 2'b10 } }; end DOA_R = { ((DATA_WIDTH+1)/2) { 2'b10 } }; DOB_R = { ((DATA_WIDTH+1)/2) { 2'b10 } }; DOA_D1_R = { ((DATA_WIDTH+1)/2) { 2'b10 } }; DOB_D1_R = { ((DATA_WIDTH+1)/2) { 2'b10 } }; end // synopsys translate_on `endif // !`ifdef BSV_NO_INITIAL_BLOCKS always @(posedge CLKA) begin DOA_R <= `BSV_ASSIGNMENT_DELAY RAM[ADDRA]; if (ENA) begin if (WEA) begin RAM[ADDRA] <= `BSV_ASSIGNMENT_DELAY DIA; end end end always @(posedge CLKB) begin DOB_R <= `BSV_ASSIGNMENT_DELAY RAM[ADDRB]; if (ENB) begin if (WEB) begin RAM[ADDRB] <= `BSV_ASSIGNMENT_DELAY DIB; end end end // Pipeline always @(posedge CLKA) DOA_D1_R <= DOA_R; always @(posedge CLKB) DOB_D1_R <= DOB_R; // Output drivers assign DOA = (PIPELINED) ? DOA_D1_R : DOA_R; assign DOB = (PIPELINED) ? DOB_D1_R : DOB_R; endmodule // BRAM2 ================================================ FILE: verilog/altera/siv_gen2x8/siv_gen2x8.v ================================================ // megafunction wizard: %IP Compiler for PCI Express v14.0% // GENERATION: XML // ============================================================ // Megafunction Name(s): // ============================================================ //Legal Notice: (C)2015 Altera Corporation. All rights reserved. Your //use of Altera Corporation's design tools, logic functions and other //software and tools, and its AMPP partner logic functions, and any //output files any of the foregoing (including device programming or //simulation files), and any associated documentation or information are //expressly subject to the terms and conditions of the Altera Program //License Subscription Agreement or other applicable license agreement, //including, without limitation, that your use is for the sole purpose //of programming logic devices manufactured by Altera and sold by Altera //or its authorized distributors. Please refer to the applicable //agreement for further details. // ========================================================= // IP Compiler for PCI Express Wizard Data // =============================== // DO NOT EDIT FOLLOWING DATA // @Altera, IP Toolbench@ // Warning: If you modify this section, IP Compiler for PCI Express Wizard may not be able to reproduce your chosen configuration. // // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // Retrieval info: // ========================================================= ================================================ FILE: verilog/awsf1.sv ================================================ `include "ConnectalProjectConfig.bsv" module awsf1( `include "cl_ports.vh" ); //`include "cl_common_defines.vh" // CL Defines for all examples `include "cl_id_defines.vh" // Defines for ID0 and ID1 (PCI ID's) assign cl_sh_id0 = `CL_SH_ID0; assign cl_sh_id1 = `CL_SH_ID1; //Put module name of the CL design here. This is used to instantiate in top.sv `define CL_NAME awsf1 //Highly recommeneded. For lib FIFO block, uses less async reset (take advantage of // FPGA flop init capability). This will help with routing resources. `define FPGA_LESS_RST `define SH_SDA // Not sure what that does //uncomment below to make SH and CL async `define SH_CL_ASYNC `include "unused_flr_template.inc" `ifndef AWSF1_DDR_A `include "unused_ddr_a_b_d_template.inc" `endif // AWSF1_DDR_A `include "unused_ddr_c_template.inc" //`include "unused_pcim_template.inc" `ifndef AWSF1_DMA_PCIS `include "unused_dma_pcis_template.inc" `endif `include "unused_cl_sda_template.inc" `include "unused_sh_bar1_template.inc" //`include "unused_apppf_irq_template.inc" //`include "unused_sh_ocl_template.inc" `ifdef AWSF1_DDR_A localparam DDR_A_PRESENT=1; // DDR B and D are not used, disable them `ifdef AWSF1_DDR_B localparam DDR_B_PRESENT=1; `else localparam DDR_B_PRESENT=0; `endif localparam DDR_D_PRESENT=0; // localparam DDR_SCRB_MAX_ADDR = 64'h3FFFFFFFF; //16GB // localparam DDR_SCRB_BURST_LEN_MINUS1 = 15; //---------------------------- // Internal signals //---------------------------- //axi_bus_t lcl_cl_sh_ddra(); //axi_bus_t lcl_cl_sh_ddrb(); //axi_bus_t lcl_cl_sh_ddrd(); //axi_bus_t sh_cl_dma_pcis_bus(); //axi_bus_t sh_cl_dma_pcis_q(); // //axi_bus_t cl_sh_pcim_bus(); //axi_bus_t cl_sh_ddr_bus(); //axi_bus_t sda_cl_bus(); //axi_bus_t sh_ocl_bus(); //cfg_bus_t pcim_tst_cfg_bus(); //cfg_bus_t ddra_tst_cfg_bus(); //cfg_bus_t ddrb_tst_cfg_bus(); //cfg_bus_t ddrc_tst_cfg_bus(); //cfg_bus_t ddrd_tst_cfg_bus(); //cfg_bus_t int_tst_cfg_bus(); // scrb_bus_t ddra_scrb_bus(); // scrb_bus_t ddrb_scrb_bus(); // scrb_bus_t ddrc_scrb_bus(); // scrb_bus_t ddrd_scrb_bus(); logic clk; (* dont_touch = "true" *) logic pipe_rst_n; logic pre_sync_rst_n; (* dont_touch = "true" *) logic sync_rst_n; //logic sh_cl_flr_assert_q; //logic [3:0] all_ddr_scrb_done; logic [3:0] all_ddr_is_ready; logic [2:0] lcl_sh_cl_ddr_is_ready; //logic dbg_scrb_en; //logic [2:0] dbg_scrb_mem_sel; //---------------------------- // End Internal signals //---------------------------- assign clk = clk_main_a0; //reset synchronizer lib_pipe #(.WIDTH(1), .STAGES(4)) PIPE_RST_N (.clk(clk), .rst_n(1'b1), .in_bus(rst_main_n), .out_bus(pipe_rst_n)); always_ff @(negedge pipe_rst_n or posedge clk) if (!pipe_rst_n) begin pre_sync_rst_n <= 0; sync_rst_n <= 0; end else begin pre_sync_rst_n <= 1; sync_rst_n <= pre_sync_rst_n; end //----------------------------------------- // DDR controller instantiation //----------------------------------------- logic [7:0] sh_ddr_stat_addr_q[2:0]; logic [2:0] sh_ddr_stat_wr_q; logic [2:0] sh_ddr_stat_rd_q; logic [31:0] sh_ddr_stat_wdata_q[2:0]; logic [2:0] ddr_sh_stat_ack_q; logic [31:0] ddr_sh_stat_rdata_q[2:0]; logic [7:0] ddr_sh_stat_int_q[2:0]; localparam NUM_CFG_STGS_CL_DDR_ATG = 8; localparam NUM_CFG_STGS_SH_DDR_ATG = 4; lib_pipe #(.WIDTH(1+1+8+32), .STAGES(NUM_CFG_STGS_CL_DDR_ATG)) PIPE_DDR_STAT0 (.clk(clk), .rst_n(sync_rst_n), .in_bus({sh_ddr_stat_wr0, sh_ddr_stat_rd0, sh_ddr_stat_addr0, sh_ddr_stat_wdata0}), .out_bus({sh_ddr_stat_wr_q[0], sh_ddr_stat_rd_q[0], sh_ddr_stat_addr_q[0], sh_ddr_stat_wdata_q[0]}) ); lib_pipe #(.WIDTH(1+8+32), .STAGES(NUM_CFG_STGS_CL_DDR_ATG)) PIPE_DDR_STAT_ACK0 (.clk(clk), .rst_n(sync_rst_n), .in_bus({ddr_sh_stat_ack_q[0], ddr_sh_stat_int_q[0], ddr_sh_stat_rdata_q[0]}), .out_bus({ddr_sh_stat_ack0, ddr_sh_stat_int0, ddr_sh_stat_rdata0}) ); // tie DRAM B to 0 //lib_pipe #(.WIDTH(1+1+8+32), .STAGES(NUM_CFG_STGS_CL_DDR_ATG)) PIPE_DDR_STAT1 (.clk(clk), .rst_n(sync_rst_n), // .in_bus({sh_ddr_stat_wr1, sh_ddr_stat_rd1, sh_ddr_stat_addr1, sh_ddr_stat_wdata1}), // .out_bus({sh_ddr_stat_wr_q[1], sh_ddr_stat_rd_q[1], sh_ddr_stat_addr_q[1], sh_ddr_stat_wdata_q[1]}) // ); //lib_pipe #(.WIDTH(1+8+32), .STAGES(NUM_CFG_STGS_CL_DDR_ATG)) PIPE_DDR_STAT_ACK1 (.clk(clk), .rst_n(sync_rst_n), // .in_bus({ddr_sh_stat_ack_q[1], ddr_sh_stat_int_q[1], ddr_sh_stat_rdata_q[1]}), // .out_bus({ddr_sh_stat_ack1, ddr_sh_stat_int1, ddr_sh_stat_rdata1}) // ); assign {sh_ddr_stat_wr_q[ 1], sh_ddr_stat_rd_q[ 1], sh_ddr_stat_addr_q[ 1], sh_ddr_stat_wdata_q[1]} = '0; assign ddr_sh_stat_ack1 = 1'b1; // Needed in order not to hang the interface assign {ddr_sh_stat_int1, ddr_sh_stat_rddata1} = '0; // tie DRAM D to 0 //lib_pipe #(.WIDTH(1+1+8+32), .STAGES(NUM_CFG_STGS_CL_DDR_ATG)) PIPE_DDR_STAT2 (.clk(clk), .rst_n(sync_rst_n), // .in_bus({sh_ddr_stat_wr2, sh_ddr_stat_rd2, sh_ddr_stat_addr2, sh_ddr_stat_wdata2}), // .out_bus({sh_ddr_stat_wr_q[2], sh_ddr_stat_rd_q[2], sh_ddr_stat_addr_q[2], sh_ddr_stat_wdata_q[2]}) // ); //lib_pipe #(.WIDTH(1+8+32), .STAGES(NUM_CFG_STGS_CL_DDR_ATG)) PIPE_DDR_STAT_ACK2 (.clk(clk), .rst_n(sync_rst_n), // .in_bus({ddr_sh_stat_ack_q[2], ddr_sh_stat_int_q[2], ddr_sh_stat_rdata_q[2]}), // .out_bus({ddr_sh_stat_ack2, ddr_sh_stat_int2, ddr_sh_stat_rdata2}) // ); assign {sh_ddr_stat_wr_q[ 2], sh_ddr_stat_rd_q[ 2], sh_ddr_stat_addr_q[ 2], sh_ddr_stat_wdata_q[2]} = '0; assign ddr_sh_stat_ack2 = 1'b1; // Needed in order not to hang the interface assign {ddr_sh_stat_int2, ddr_sh_stat_rddata2} = '0; //convert to 2D logic [15:0] cl_sh_ddr_awid_2d[2:0]; logic [63:0] cl_sh_ddr_awaddr_2d[2:0]; logic [7:0] cl_sh_ddr_awlen_2d[2:0]; logic [2:0] cl_sh_ddr_awsize_2d[2:0]; logic [1:0] cl_sh_ddr_awburst_2d[2:0]; logic cl_sh_ddr_awvalid_2d [2:0]; logic [2:0] sh_cl_ddr_awready_2d; logic [15:0] cl_sh_ddr_wid_2d[2:0]; logic [511:0] cl_sh_ddr_wdata_2d[2:0]; logic [63:0] cl_sh_ddr_wstrb_2d[2:0]; logic [2:0] cl_sh_ddr_wlast_2d; logic [2:0] cl_sh_ddr_wvalid_2d; logic [2:0] sh_cl_ddr_wready_2d; logic [15:0] sh_cl_ddr_bid_2d[2:0]; logic [1:0] sh_cl_ddr_bresp_2d[2:0]; logic [2:0] sh_cl_ddr_bvalid_2d; logic [2:0] cl_sh_ddr_bready_2d; logic [15:0] cl_sh_ddr_arid_2d[2:0]; logic [63:0] cl_sh_ddr_araddr_2d[2:0]; logic [7:0] cl_sh_ddr_arlen_2d[2:0]; logic [2:0] cl_sh_ddr_arsize_2d[2:0]; logic [1:0] cl_sh_ddr_arburst_2d[2:0]; logic [2:0] cl_sh_ddr_arvalid_2d; logic [2:0] sh_cl_ddr_arready_2d; logic [15:0] sh_cl_ddr_rid_2d[2:0]; logic [511:0] sh_cl_ddr_rdata_2d[2:0]; logic [1:0] sh_cl_ddr_rresp_2d[2:0]; logic [2:0] sh_cl_ddr_rlast_2d; logic [2:0] sh_cl_ddr_rvalid_2d; logic [2:0] cl_sh_ddr_rready_2d; // tie DRAM B to 0 assign {cl_sh_ddr_awid_2d[ 1], cl_sh_ddr_awaddr_2d[ 1], cl_sh_ddr_awlen_2d[ 1], cl_sh_ddr_awsize_2d[ 1], cl_sh_ddr_awvalid_2d[1], cl_sh_ddr_wid_2d[ 1], cl_sh_ddr_wdata_2d[ 1], cl_sh_ddr_wstrb_2d[ 1], cl_sh_ddr_wlast_2d[ 1], cl_sh_ddr_wvalid_2d[ 1], cl_sh_ddr_bready_2d[ 1], cl_sh_ddr_arid_2d[ 1], cl_sh_ddr_araddr_2d[ 1], cl_sh_ddr_arlen_2d[ 1], cl_sh_ddr_arsize_2d[ 1], cl_sh_ddr_arvalid_2d[1], cl_sh_ddr_rready_2d[ 1]} = '0; // tie DRAM D to 0 assign {cl_sh_ddr_awid_2d[ 2], cl_sh_ddr_awaddr_2d[ 2], cl_sh_ddr_awlen_2d[ 2], cl_sh_ddr_awsize_2d[ 2], cl_sh_ddr_awvalid_2d[2], cl_sh_ddr_wid_2d[ 2], cl_sh_ddr_wdata_2d[ 2], cl_sh_ddr_wstrb_2d[ 2], cl_sh_ddr_wlast_2d[ 2], cl_sh_ddr_wvalid_2d[ 2], cl_sh_ddr_bready_2d[ 2], cl_sh_ddr_arid_2d[ 2], cl_sh_ddr_araddr_2d[ 2], cl_sh_ddr_arlen_2d[ 2], cl_sh_ddr_arsize_2d[ 2], cl_sh_ddr_arvalid_2d[2], cl_sh_ddr_rready_2d[ 2]} = '0; assign cl_sh_pcim_araddr[63:40] = 24'd0; assign cl_sh_pcim_awaddr[63:40] = 24'd0; (* dont_touch = "true" *) logic sh_ddr_sync_rst_n; lib_pipe #(.WIDTH(1), .STAGES(4)) SH_DDR_SLC_RST_N (.clk(clk), .rst_n(1'b1), .in_bus(sync_rst_n), .out_bus(sh_ddr_sync_rst_n)); sh_ddr #( .DDR_A_PRESENT(DDR_A_PRESENT), .DDR_B_PRESENT(DDR_B_PRESENT), .DDR_D_PRESENT(DDR_D_PRESENT) ) SH_DDR ( .clk(clk), .rst_n(sh_ddr_sync_rst_n), .stat_clk(clk), .stat_rst_n(sh_ddr_sync_rst_n), .CLK_300M_DIMM0_DP(CLK_300M_DIMM0_DP), .CLK_300M_DIMM0_DN(CLK_300M_DIMM0_DN), .M_A_ACT_N(M_A_ACT_N), .M_A_MA(M_A_MA), .M_A_BA(M_A_BA), .M_A_BG(M_A_BG), .M_A_CKE(M_A_CKE), .M_A_ODT(M_A_ODT), .M_A_CS_N(M_A_CS_N), .M_A_CLK_DN(M_A_CLK_DN), .M_A_CLK_DP(M_A_CLK_DP), .M_A_PAR(M_A_PAR), .M_A_DQ(M_A_DQ), .M_A_ECC(M_A_ECC), .M_A_DQS_DP(M_A_DQS_DP), .M_A_DQS_DN(M_A_DQS_DN), .cl_RST_DIMM_A_N(cl_RST_DIMM_A_N), .CLK_300M_DIMM1_DP(CLK_300M_DIMM1_DP), .CLK_300M_DIMM1_DN(CLK_300M_DIMM1_DN), .M_B_ACT_N(M_B_ACT_N), .M_B_MA(M_B_MA), .M_B_BA(M_B_BA), .M_B_BG(M_B_BG), .M_B_CKE(M_B_CKE), .M_B_ODT(M_B_ODT), .M_B_CS_N(M_B_CS_N), .M_B_CLK_DN(M_B_CLK_DN), .M_B_CLK_DP(M_B_CLK_DP), .M_B_PAR(M_B_PAR), .M_B_DQ(M_B_DQ), .M_B_ECC(M_B_ECC), .M_B_DQS_DP(M_B_DQS_DP), .M_B_DQS_DN(M_B_DQS_DN), .cl_RST_DIMM_B_N(cl_RST_DIMM_B_N), .CLK_300M_DIMM3_DP(CLK_300M_DIMM3_DP), .CLK_300M_DIMM3_DN(CLK_300M_DIMM3_DN), .M_D_ACT_N(M_D_ACT_N), .M_D_MA(M_D_MA), .M_D_BA(M_D_BA), .M_D_BG(M_D_BG), .M_D_CKE(M_D_CKE), .M_D_ODT(M_D_ODT), .M_D_CS_N(M_D_CS_N), .M_D_CLK_DN(M_D_CLK_DN), .M_D_CLK_DP(M_D_CLK_DP), .M_D_PAR(M_D_PAR), .M_D_DQ(M_D_DQ), .M_D_ECC(M_D_ECC), .M_D_DQS_DP(M_D_DQS_DP), .M_D_DQS_DN(M_D_DQS_DN), .cl_RST_DIMM_D_N(cl_RST_DIMM_D_N), //------------------------------------------------------ // DDR-4 Interface from CL (AXI-4) //------------------------------------------------------ .cl_sh_ddr_awid(cl_sh_ddr_awid_2d), .cl_sh_ddr_awaddr(cl_sh_ddr_awaddr_2d), .cl_sh_ddr_awlen(cl_sh_ddr_awlen_2d), .cl_sh_ddr_awsize(cl_sh_ddr_awsize_2d), .cl_sh_ddr_awburst(cl_sh_ddr_awburst_2d), .cl_sh_ddr_awvalid(cl_sh_ddr_awvalid_2d), .sh_cl_ddr_awready(sh_cl_ddr_awready_2d), .cl_sh_ddr_wid(cl_sh_ddr_wid_2d), .cl_sh_ddr_wdata(cl_sh_ddr_wdata_2d), .cl_sh_ddr_wstrb(cl_sh_ddr_wstrb_2d), .cl_sh_ddr_wlast(cl_sh_ddr_wlast_2d), .cl_sh_ddr_wvalid(cl_sh_ddr_wvalid_2d), .sh_cl_ddr_wready(sh_cl_ddr_wready_2d), .sh_cl_ddr_bid(sh_cl_ddr_bid_2d), .sh_cl_ddr_bresp(sh_cl_ddr_bresp_2d), .sh_cl_ddr_bvalid(sh_cl_ddr_bvalid_2d), .cl_sh_ddr_bready(cl_sh_ddr_bready_2d), .cl_sh_ddr_arid(cl_sh_ddr_arid_2d), .cl_sh_ddr_araddr(cl_sh_ddr_araddr_2d), .cl_sh_ddr_arlen(cl_sh_ddr_arlen_2d), .cl_sh_ddr_arsize(cl_sh_ddr_arsize_2d), .cl_sh_ddr_arburst(cl_sh_ddr_arburst_2d), .cl_sh_ddr_arvalid(cl_sh_ddr_arvalid_2d), .sh_cl_ddr_arready(sh_cl_ddr_arready_2d), .sh_cl_ddr_rid(sh_cl_ddr_rid_2d), .sh_cl_ddr_rdata(sh_cl_ddr_rdata_2d), .sh_cl_ddr_rresp(sh_cl_ddr_rresp_2d), .sh_cl_ddr_rlast(sh_cl_ddr_rlast_2d), .sh_cl_ddr_rvalid(sh_cl_ddr_rvalid_2d), .cl_sh_ddr_rready(cl_sh_ddr_rready_2d), .sh_cl_ddr_is_ready(lcl_sh_cl_ddr_is_ready), .sh_ddr_stat_addr0 (sh_ddr_stat_addr_q[0]) , .sh_ddr_stat_wr0 (sh_ddr_stat_wr_q[0] ) , .sh_ddr_stat_rd0 (sh_ddr_stat_rd_q[0] ) , .sh_ddr_stat_wdata0 (sh_ddr_stat_wdata_q[0] ) , .ddr_sh_stat_ack0 (ddr_sh_stat_ack_q[0] ) , .ddr_sh_stat_rdata0 (ddr_sh_stat_rdata_q[0] ), .ddr_sh_stat_int0 (ddr_sh_stat_int_q[0] ), .sh_ddr_stat_addr1 (sh_ddr_stat_addr_q[1]) , .sh_ddr_stat_wr1 (sh_ddr_stat_wr_q[1] ) , .sh_ddr_stat_rd1 (sh_ddr_stat_rd_q[1] ) , .sh_ddr_stat_wdata1 (sh_ddr_stat_wdata_q[1] ) , .ddr_sh_stat_ack1 (ddr_sh_stat_ack_q[1] ) , .ddr_sh_stat_rdata1 (ddr_sh_stat_rdata_q[1] ), .ddr_sh_stat_int1 (ddr_sh_stat_int_q[1] ), .sh_ddr_stat_addr2 (sh_ddr_stat_addr_q[2]) , .sh_ddr_stat_wr2 (sh_ddr_stat_wr_q[2] ) , .sh_ddr_stat_rd2 (sh_ddr_stat_rd_q[2] ) , .sh_ddr_stat_wdata2 (sh_ddr_stat_wdata_q[2] ) , .ddr_sh_stat_ack2 (ddr_sh_stat_ack_q[2] ) , .ddr_sh_stat_rdata2 (ddr_sh_stat_rdata_q[2] ), .ddr_sh_stat_int2 (ddr_sh_stat_int_q[2] ) ); //----------------------------------------- // DDR controller instantiation //----------------------------------------- `endif // AWSF1_DDR_A `ifdef AWSF1_CL_DEBUG_BRIDGE ila_connectal_1 cl_ila_slave ( .clk (clk_main_a0), .probe0 (sh_ocl_awvalid), .probe1 (sh_ocl_awaddr), .probe2 (ocl_sh_awready), .probe3 (sh_ocl_arvalid), .probe4 (sh_ocl_araddr), .probe5 (ocl_sh_arready), .probe6 (sh_ocl_wvalid), .probe7 (sh_ocl_wdata), .probe8 (ocl_sh_wready), .probe9 (ocl_sh_rvalid), .probe10 (ocl_sh_rdata), .probe11 (sh_ocl_rready), .probe12 (cl_sh_apppf_irq_req), .probe13 (sh_cl_apppf_irq_ack) ); `ifndef AWSF1_DMA_PCIS ila_connectal_2 cl_ila_master ( .clk (clk_main_a0), .probe0 (cl_sh_pcim_awvalid), .probe1 (cl_sh_pcim_awaddr), .probe2 (sh_cl_pcim_awready), .probe3 (cl_sh_pcim_arvalid), .probe4 (cl_sh_pcim_araddr), .probe5 (sh_cl_pcim_arready), .probe6 (cl_sh_pcim_wvalid), .probe7 (cl_sh_pcim_wdata), .probe8 (sh_cl_pcim_wready), .probe9 (sh_cl_pcim_rvalid), .probe10 (sh_cl_pcim_rdata), .probe11 (cl_sh_pcim_rready), .probe12(cl_sh_pcim_wstrb), .probe13 (cl_sh_pcim_aruser), .probe14 (cl_sh_pcim_awuser), .probe15 (cl_sh_pcim_arlen), .probe16 (cl_sh_pcim_awlen), .probe17 (cl_sh_pcim_arid), .probe18 (cl_sh_pcim_awid), .probe19 (cl_sh_pcim_arsize), .probe20 (cl_sh_pcim_awsize), .probe21 (sh_cl_pcim_bid), .probe22 (sh_cl_pcim_bresp), .probe23 (cl_sh_pcim_bready), .probe24 (sh_cl_pcim_bvalid) ); `else wire [159:0] pc_status; wire pc_asserted; ila_connectal_3 cl_ila_pcis ( .clk (clk_main_a0), .probe0 (sh_cl_dma_pcis_awvalid), .probe1 (sh_cl_dma_pcis_awaddr), .probe2 (cl_sh_dma_pcis_awready), .probe3 (sh_cl_dma_pcis_arvalid), .probe4 (sh_cl_dma_pcis_araddr), .probe5 (cl_sh_dma_pcis_arready), .probe6 (sh_cl_dma_pcis_wvalid), .probe7 (sh_cl_dma_pcis_wdata), .probe8 (cl_sh_dma_pcis_wready), .probe9 (cl_sh_dma_pcis_rvalid), .probe10 (cl_sh_dma_pcis_rdata), .probe11 (sh_cl_dma_pcis_rready), .probe12(sh_cl_dma_pcis_wstrb), .probe13 (sh_cl_dma_pcis_aruser), .probe14 ({sh_cl_dma_pcis_wlast, cl_sh_dma_pcis_rid, cl_sh_dma_pcis_rresp, cl_sh_dma_pcis_rlast, pc_asserted}), .probe15 (sh_cl_dma_pcis_arlen), .probe16 (sh_cl_dma_pcis_awlen), .probe17 (sh_cl_dma_pcis_arid), .probe18 (sh_cl_dma_pcis_awid), .probe19 (sh_cl_dma_pcis_arsize), .probe20 (sh_cl_dma_pcis_awsize), .probe21 (cl_sh_dma_pcis_bid), .probe22 (cl_sh_dma_pcis_bresp), .probe23 (sh_cl_dma_pcis_bready), .probe24 (cl_sh_dma_pcis_bvalid), .probe25 (pc_status) ); `endif `ifdef AWSF1_DDR_A ila_connectal_2 cl_ila_mem ( .clk (clk_main_a0), .probe0 (cl_sh_ddr_awvalid_2d[0]), .probe1 (cl_sh_ddr_awaddr_2d[0]), // 64 .probe2 (sh_cl_ddr_awready_2d[0]), .probe3 (cl_sh_ddr_arvalid_2d[0]), .probe4 (cl_sh_ddr_araddr_2d[0]), // 64 .probe5 (sh_cl_ddr_arready_2d[0]), .probe6 (cl_sh_ddr_wvalid_2d[0]), .probe7 (cl_sh_ddr_wdata_2d[0]), // 512 .probe8 (sh_cl_ddr_wready_2d[0]), .probe9 (sh_cl_ddr_rvalid_2d[0]), .probe10 (sh_cl_ddr_rdata_2d[0]), // 512 .probe11 (cl_sh_ddr_rready_2d[0]), .probe12 (cl_sh_ddr_wstrb_2d[0]), // 64 .probe13 (cl_sh_pcim_aruser), // 19 .probe14 (cl_sh_pcim_awuser), // 19 .probe15 (cl_sh_ddr_arlen_2d[0]), // 8 .probe16 (cl_sh_ddr_awlen_2d[0]), // 8 .probe17 (cl_sh_ddr_arsize_2d[0]), // 3 .probe18 (cl_sh_ddr_awsize_2d[0]), // 3 .probe19 (cl_sh_ddr_awid_2d[0]), // 16 .probe20 (cl_sh_ddr_arid_2d[0]), // 16 .probe21 (sh_cl_ddr_bid_2d[0]), // 16 .probe22 (sh_cl_ddr_bresp_2d[0]), // 2 .probe23 (cl_sh_ddr_bready_2d[0]), .probe24 (sh_cl_ddr_bvalid_2d[0]) ); `endif `ifdef AWSF1_DDR_B ila_connectal_2 cl_ila_mem ( .clk (clk_main_a0), .probe0 (cl_sh_ddr_awvalid_2d[1]), .probe1 (cl_sh_ddr_awaddr_2d[1]), // 64 .probe2 (sh_cl_ddr_awready_2d[1]), .probe3 (cl_sh_ddr_arvalid_2d[1]), .probe4 (cl_sh_ddr_araddr_2d[1]), // 64 .probe5 (sh_cl_ddr_arready_2d[1]), .probe6 (cl_sh_ddr_wvalid_2d[1]), .probe7 (cl_sh_ddr_wdata_2d[1]), // 512 .probe8 (sh_cl_ddr_wready_2d[1]), .probe9 (sh_cl_ddr_rvalid_2d[1]), .probe10 (sh_cl_ddr_rdata_2d[1]), // 512 .probe11 (cl_sh_ddr_rready_2d[1]), .probe12 (cl_sh_ddr_wstrb_2d[1]), // 64 .probe13 (0), // 19 .probe14 (0), // 19 .probe15 (cl_sh_ddr_arlen_2d[1]), // 8 .probe16 (cl_sh_ddr_awlen_2d[1]), // 8 .probe17 (cl_sh_ddr_arsize_2d[1]), // 3 .probe18 (cl_sh_ddr_awsize_2d[1]), // 3 .probe19 (cl_sh_ddr_awid_2d[1]), // 16 .probe20 (cl_sh_ddr_arid_2d[1]), // 16 .probe21 (sh_cl_ddr_bid_2d[1]), // 16 .probe22 (sh_cl_ddr_bresp_2d[1]), // 2 .probe23 (cl_sh_ddr_bready_2d[1]), .probe24 (sh_cl_ddr_bvalid_2d[1]) ); `endif // Debug Bridge cl_debug_bridge CL_DEBUG_BRIDGE ( .clk(clk_main_a0), .S_BSCAN_drck(drck), .S_BSCAN_shift(shift), .S_BSCAN_tdi(tdi), .S_BSCAN_update(update), .S_BSCAN_sel(sel), .S_BSCAN_tdo(tdo), .S_BSCAN_tms(tms), .S_BSCAN_tck(tck), .S_BSCAN_runtest(runtest), .S_BSCAN_reset(reset), .S_BSCAN_capture(capture), .S_BSCAN_bscanid_en(bscanid_en) ); `endif // AWSF1_CL_DEBUG_BRIDGE assign cl_sh_pcim_awuser = 0; assign cl_sh_pcim_aruser = 0; mkAwsF1Top awsF1Top( .clk_main_a0(clk_main_a0), //Main clock. This is the clock for all of the interfaces to the SH .clk_extra_a1(clk_extra_a1), //Extra clock A1 (phase aligned to "A" clock group) .clk_extra_a2(clk_extra_a2), //Extra clock A2 (phase aligned to "A" clock group) .clk_extra_a3(clk_extra_a3), //Extra clock A3 (phase aligned to "A" clock group) .clk_extra_b0(clk_extra_b0), //Extra clock B0 (phase aligned to "B" clock group) .clk_extra_b1(clk_extra_b1), //Extra clock B1 (phase aligned to "B" clock group) .clk_extra_c0(clk_extra_c0), //Extra clock C0 (phase aligned to "B" clock group) .clk_extra_c1(clk_extra_c1), //Extra clock C1 (phase aligned to "B" clock group) .kernel_rst_n(kernel_rst_n), //Kernel reset (for SDA platform) .rst_main_n(rst_main_n), //Reset sync to main clock. .sh_cl_flr_assert(sh_cl_flr_assert), //Function level reset assertion. Level signal that indicates PCIe function level reset is asserted // remove import "unused_flr_template.inc" if the flr_done signal is needed //.cl_sh_flr_done(cl_sh_flr_done), //Function level reset done indication. Must be asserted by CL when done processing functional .cl_sh_status0(cl_sh_status0), //Functionality TBD .cl_sh_status1(cl_sh_status1), //Functionality TBD //.cl_sh_id0(cl_sh_id0), //.cl_sh_id1(cl_sh_id1), .sh_cl_ctl0(sh_cl_ctl0), //Functionality TBD .sh_cl_ctl1(sh_cl_ctl1), //Functionality TBD .sh_cl_status_vdip(sh_cl_status_vdip), //Virtual DIP switches. Controlled through FPGA management PF and tools. .cl_sh_status_vled(cl_sh_status_vled), //Virtual LEDs, monitored through FPGA management PF and tools .sh_cl_pwr_state(sh_cl_pwr_state), //Power state, 2'b00: Normal, 2'b11: Critical .interrupt_apppf_irq_req(cl_sh_apppf_irq_req), .interrupt_apppf_irq_ack_ack(sh_cl_apppf_irq_ack), //------------------------------------------------------------------------------------------ // AXI-L maps to any inbound PCIe access through ManagementPF BAR4 for developer's use // If the CL is created through Xilinx’s SDAccel, then this configuration bus // would be connected automatically to SDAccel generic logic (SmartConnect, APM etc) //------------------------------------------------------------------------------------------ .ocl_awvalid_v(sh_ocl_awvalid), .ocl_awaddr_v(sh_ocl_awaddr), .ocl_awready(ocl_sh_awready), //Write data .ocl_wvalid_v(sh_ocl_wvalid), .ocl_wdata_v(sh_ocl_wdata), //.(sh_ocl_wstrb), .ocl_wready(ocl_sh_wready), //Write response .ocl_bvalid(ocl_sh_bvalid), .ocl_bresp(ocl_sh_bresp), .ocl_bready_v(sh_ocl_bready), //Read address .ocl_arvalid_v(sh_ocl_arvalid), .ocl_araddr_v(sh_ocl_araddr), .ocl_arready(ocl_sh_arready), //Read data/response .ocl_rvalid(ocl_sh_rvalid), .ocl_rdata(ocl_sh_rdata), .ocl_rresp(ocl_sh_rresp), .ocl_rready_v(sh_ocl_rready), // DDR 3 through connectal AXI `ifdef AWSF1_DDR_A .pins_araddr(cl_sh_ddr_araddr_2d[0]), .pins_arid(cl_sh_ddr_arid_2d[0]), .pins_arlen(cl_sh_ddr_arlen_2d[0]), .pins_arready(sh_cl_ddr_arready_2d[0]), .pins_arsize(cl_sh_ddr_arsize_2d[0]), .pins_arburst(cl_sh_ddr_arburst_2d[0]), .pins_arvalid(cl_sh_ddr_arvalid_2d[0]), .pins_awaddr(cl_sh_ddr_awaddr_2d[0]), .pins_awid(cl_sh_ddr_awid_2d[0]), .pins_awlen(cl_sh_ddr_awlen_2d[0]), .pins_awready(sh_cl_ddr_awready_2d[0]), .pins_awsize(cl_sh_ddr_awsize_2d[0]), .pins_awburst(cl_sh_ddr_awburst_2d[0]), .pins_awvalid(cl_sh_ddr_awvalid_2d[0]), //.pins_awlock(), .pins_bid(sh_cl_ddr_bid_2d[0]), .pins_bready(cl_sh_ddr_bready_2d[0]), .pins_bresp(sh_cl_ddr_bresp_2d[0]), .pins_bvalid(sh_cl_ddr_bvalid_2d[0]), .pins_rdata(sh_cl_ddr_rdata_2d[0]), .pins_rid(sh_cl_ddr_rid_2d[0]), .pins_rlast(sh_cl_ddr_rlast_2d[0]), .pins_rready(cl_sh_ddr_rready_2d[0]), .pins_rresp(sh_cl_ddr_rresp_2d[0]), .pins_rvalid(sh_cl_ddr_rvalid_2d[0]), .pins_wdata(cl_sh_ddr_wdata_2d[0]), //.pins_wid(cl_sh_ddr_wid_2d[0]), .pins_wlast(cl_sh_ddr_wlast_2d[0]), .pins_wready(sh_cl_ddr_wready_2d[0]), .pins_wstrb(cl_sh_ddr_wstrb_2d[0]), .pins_wvalid(cl_sh_ddr_wvalid_2d[0]), `endif // AWSF1_DDR_A `ifdef AWSF1_DDR_B .pins_ddr_b_araddr(cl_sh_ddr_araddr_2d[1]), .pins_ddr_b_arid(cl_sh_ddr_arid_2d[1]), .pins_ddr_b_arlen(cl_sh_ddr_arlen_2d[1]), .pins_ddr_b_arready(sh_cl_ddr_arready_2d[1]), .pins_ddr_b_arsize(cl_sh_ddr_arsize_2d[1]), .pins_ddr_b_arburst(cl_sh_ddr_arburst_2d[1]), .pins_ddr_b_arvalid(cl_sh_ddr_arvalid_2d[1]), .pins_ddr_b_awaddr(cl_sh_ddr_awaddr_2d[1]), .pins_ddr_b_awid(cl_sh_ddr_awid_2d[1]), .pins_ddr_b_awlen(cl_sh_ddr_awlen_2d[1]), .pins_ddr_b_awready(sh_cl_ddr_awready_2d[1]), .pins_ddr_b_awsize(cl_sh_ddr_awsize_2d[1]), .pins_ddr_b_awburst(cl_sh_ddr_awburst_2d[1]), .pins_ddr_b_awvalid(cl_sh_ddr_awvalid_2d[1]), //.pins_ddr_b_awlock(), .pins_ddr_b_bid(sh_cl_ddr_bid_2d[1]), .pins_ddr_b_bready(cl_sh_ddr_bready_2d[1]), .pins_ddr_b_bresp(sh_cl_ddr_bresp_2d[1]), .pins_ddr_b_bvalid(sh_cl_ddr_bvalid_2d[1]), .pins_ddr_b_rdata(sh_cl_ddr_rdata_2d[1]), .pins_ddr_b_rid(sh_cl_ddr_rid_2d[1]), .pins_ddr_b_rlast(sh_cl_ddr_rlast_2d[1]), .pins_ddr_b_rready(cl_sh_ddr_rready_2d[1]), .pins_ddr_b_rresp(sh_cl_ddr_rresp_2d[1]), .pins_ddr_b_rvalid(sh_cl_ddr_rvalid_2d[1]), .pins_ddr_b_wdata(cl_sh_ddr_wdata_2d[1]), //.pins_ddr_b_wid(cl_sh_ddr_wid_2d[1]), .pins_ddr_b_wlast(cl_sh_ddr_wlast_2d[1]), .pins_ddr_b_wready(sh_cl_ddr_wready_2d[1]), .pins_ddr_b_wstrb(cl_sh_ddr_wstrb_2d[1]), .pins_ddr_b_wvalid(cl_sh_ddr_wvalid_2d[1]), `endif // AWSF1_DDR_B // DDR3 END `ifdef AWSF1_DMA_PCIS .pins_pcis_araddr(sh_cl_dma_pcis_araddr[39:0]), .pins_pcis_arburst(1), .pins_pcis_arcache(0), .pins_pcis_arid(sh_cl_dma_pcis_arid), .pins_pcis_arlen(sh_cl_dma_pcis_arlen), .pins_pcis_arlock(0), .pins_pcis_arprot(0), .pins_pcis_arqos(0), .pins_pcis_arready(cl_sh_dma_pcis_arready), .pins_pcis_arsize(sh_cl_dma_pcis_arsize), .pins_pcis_arvalid(sh_cl_dma_pcis_arvalid), .pins_pcis_awaddr(sh_cl_dma_pcis_awaddr[39:0]), .pins_pcis_awburst(1), .pins_pcis_awcache(0), .pins_pcis_awid(sh_cl_dma_pcis_awid), .pins_pcis_awlen(sh_cl_dma_pcis_awlen), .pins_pcis_awlock(0), .pins_pcis_awprot(0), .pins_pcis_awqos(0), .pins_pcis_awready(cl_sh_dma_pcis_awready), .pins_pcis_awsize(sh_cl_dma_pcis_awsize), .pins_pcis_awvalid(sh_cl_dma_pcis_awvalid), .pins_pcis_bid(cl_sh_dma_pcis_bid), .pins_pcis_bready(sh_cl_dma_pcis_bready), .pins_pcis_bresp(cl_sh_dma_pcis_bresp), .pins_pcis_bvalid(cl_sh_dma_pcis_bvalid), .pins_pcis_rdata(cl_sh_dma_pcis_rdata), .pins_pcis_rid(cl_sh_dma_pcis_rid), .pins_pcis_rlast(cl_sh_dma_pcis_rlast), .pins_pcis_rready(sh_cl_dma_pcis_rready), .pins_pcis_rresp(cl_sh_dma_pcis_rresp), .pins_pcis_rvalid(cl_sh_dma_pcis_rvalid), .pins_pcis_wdata(sh_cl_dma_pcis_wdata), .pins_pcis_wlast(sh_cl_dma_pcis_wlast), .pins_pcis_wready(cl_sh_dma_pcis_wready), .pins_pcis_wstrb(sh_cl_dma_pcis_wstrb), .pins_pcis_wvalid(sh_cl_dma_pcis_wvalid), `endif .pcim_araddr(cl_sh_pcim_araddr[39:0]), //.pcim_arburst(pcim_arburst), //.pcim_arcache(pcim_arcache), //.pcim_aresetn(pcim_aresetn), .pcim_arid(cl_sh_pcim_arid), .pcim_arlen(cl_sh_pcim_arlen), //.pcim_arlock(pcim_arlock), //.pcim_arprot(pcim_arprot), //.pcim_arqos(pcim_arqos), .pcim_arready_v(sh_cl_pcim_arready), .pcim_arsize(cl_sh_pcim_arsize), .pcim_arvalid(cl_sh_pcim_arvalid), //RESERVED: .pcim_extra_aruser(cl_sh_pcim_aruser), .pcim_awaddr(cl_sh_pcim_awaddr[39:0]), //.pcim_awburst(pcim_awburst), //.pcim_awcache(pcim_awcache), .pcim_awid(cl_sh_pcim_awid), .pcim_awlen(cl_sh_pcim_awlen), //.pcim_awlock(pcim_awlock), //.pcim_awprot(pcim_awprot), //.pcim_awqos(pcim_awqos), .pcim_awready_v(sh_cl_pcim_awready), .pcim_awsize(cl_sh_pcim_awsize), .pcim_awvalid(cl_sh_pcim_awvalid), //RESERVED: .pcim_extra_awuser(cl_sh_pcim_awuser), .pcim_bid_v(sh_cl_pcim_bid), .pcim_bready(cl_sh_pcim_bready), .pcim_bresp_v(sh_cl_pcim_bresp), .pcim_bvalid_v(sh_cl_pcim_bvalid), .pcim_rdata_v(sh_cl_pcim_rdata), .pcim_rid_v(sh_cl_pcim_rid), .pcim_rlast_v(sh_cl_pcim_rlast), .pcim_rready(cl_sh_pcim_rready), .pcim_rresp_v(sh_cl_pcim_rresp), .pcim_rvalid_v(sh_cl_pcim_rvalid), .pcim_wdata(cl_sh_pcim_wdata), //.pcim_wid(cl_sh_pcim_wid), // No longer part of AXI4 spec .pcim_wlast(cl_sh_pcim_wlast), .pcim_wready_v(sh_cl_pcim_wready), .pcim_wstrb(cl_sh_pcim_wstrb), .pcim_wvalid(cl_sh_pcim_wvalid) ); `ifdef AWSF1_CL_DEBUG_BRIDGE `ifdef AWSF1_DMA_PCIS `ifdef AWSF1_AXI_PROTOCOL_CHECKER axi_protocol_checker_0 axi_protocol_checker_i ( .pc_status(pc_status), // output wire [159 : 0] pc_status .pc_asserted(pc_asserted), // output wire pc_asserted .aclk(clk_main_a0), // input wire aclk .aresetn(rst_main_n), // input wire aresetn .pc_axi_awid(sh_cl_dma_pcis_awid), // input wire [5 : 0] pc_axi_awid .pc_axi_awaddr(sh_cl_dma_pcis_awaddr), // input wire [63 : 0] pc_axi_awaddr .pc_axi_awlen(sh_cl_dma_pcis_awlen), // input wire [7 : 0] pc_axi_awlen .pc_axi_awsize(sh_cl_dma_pcis_awsize), // input wire [2 : 0] pc_axi_awsize .pc_axi_awburst(1), // input wire [1 : 0] pc_axi_awburst .pc_axi_awlock(0), // input wire [0 : 0] pc_axi_awlock .pc_axi_awcache(0), // input wire [3 : 0] pc_axi_awcache .pc_axi_awprot(0), // input wire [2 : 0] pc_axi_awprot .pc_axi_awqos(0), // input wire [3 : 0] pc_axi_awqos .pc_axi_awregion(0), // input wire [3 : 0] pc_axi_awregion .pc_axi_awvalid(sh_cl_dma_pcis_awvalid), // input wire pc_axi_awvalid .pc_axi_awready(cl_sh_dma_pcis_awready), // input wire pc_axi_awready .pc_axi_wlast(sh_cl_dma_pcis_wlast), // input wire pc_axi_wlast .pc_axi_wdata(sh_cl_dma_pcis_wdata), // input wire [511 : 0] pc_axi_wdata .pc_axi_wstrb(sh_cl_dma_pcis_wstrb), // input wire [63 : 0] pc_axi_wstrb .pc_axi_wvalid(sh_cl_dma_pcis_wvalid), // input wire pc_axi_wvalid .pc_axi_wready(cl_sh_dma_pcis_wready), // input wire pc_axi_wready .pc_axi_bid(cl_sh_dma_pcis_bid), // input wire [5 : 0] pc_axi_bid .pc_axi_bresp(cl_sh_dma_pcis_bresp), // input wire [1 : 0] pc_axi_bresp .pc_axi_bvalid(cl_sh_dma_pcis_bvalid), // input wire pc_axi_bvalid .pc_axi_bready(sh_cl_dma_pcis_bready), // input wire pc_axi_bready .pc_axi_arid(sh_cl_dma_pcis_arid), // input wire [5 : 0] pc_axi_arid .pc_axi_araddr(sh_cl_dma_pcis_araddr), // input wire [63 : 0] pc_axi_araddr .pc_axi_arlen(sh_cl_dma_pcis_arlen), // input wire [7 : 0] pc_axi_arlen .pc_axi_arsize(sh_cl_dma_pcis_arsize), // input wire [2 : 0] pc_axi_arsize .pc_axi_arburst(1), // input wire [1 : 0] pc_axi_arburst .pc_axi_arlock(0), // input wire [0 : 0] pc_axi_arlock .pc_axi_arcache(0), // input wire [3 : 0] pc_axi_arcache .pc_axi_arprot(0), // input wire [2 : 0] pc_axi_arprot .pc_axi_arqos(0), // input wire [3 : 0] pc_axi_arqos .pc_axi_arregion(0), // input wire [3 : 0] pc_axi_arregion .pc_axi_arvalid(sh_cl_dma_pcis_arvalid), // input wire pc_axi_arvalid .pc_axi_arready(cl_sh_dma_pcis_arready), // input wire pc_axi_arready .pc_axi_rid(cl_sh_dma_pcis_rid), // input wire [5 : 0] pc_axi_rid .pc_axi_rlast(cl_sh_dma_pcis_rlast), // input wire pc_axi_rlast .pc_axi_rdata(cl_sh_dma_pcis_rdata), // input wire [511 : 0] pc_axi_rdata .pc_axi_rresp(cl_sh_dma_pcis_rresp), // input wire [1 : 0] pc_axi_rresp .pc_axi_rvalid(cl_sh_dma_pcis_rvalid), // input wire pc_axi_rvalid .pc_axi_rready(sh_cl_dma_pcis_rready) // input wire pc_axi_rready ); `endif // AWSF1_AXI_PROTOCOL_CHECKER `endif // `ifdef AWSF1_DMA_PCIS `endif // `ifdef AWSF1_CL_DEBUG_BRIDGE endmodule ================================================ FILE: verilog/cl_id_defines.vh ================================================ // Amazon FPGA Hardware Development Kit // // Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Amazon Software License (the "License"). You may not use // this file except in compliance with the License. A copy of the License is // located at // // http://aws.amazon.com/asl/ // // or in the "license" file accompanying this file. This file is distributed on // an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or // implied. See the License for the specific language governing permissions and // limitations under the License. // CL_SH_ID0 // - PCIe Vendor/Device ID Values // 31:16: PCIe Device ID // 15: 0: PCIe Vendor ID // - A Vendor ID value of 0x8086 is not valid. // - If using a Vendor ID value of 0x1D0F (Amazon) then valid // values for Device ID's are in the range of 0xF000 - 0xF0FF. // - A Vendor/Device ID of 0 (zero) is not valid. `define CL_SH_ID0 32'hF000_1D0F // CL_SH_ID1 // - PCIe Subsystem/Subsystem Vendor ID Values // 31:16: PCIe Subsystem ID // 15: 0: PCIe Subsystem Vendor ID // - A PCIe Subsystem/Subsystem Vendor ID of 0 (zero) is not valid `define CL_SH_ID1 32'h1D51_FEDD ================================================ FILE: verilog/xsimtop.sv ================================================ // Copyright (c) 2015 The Connectal Project // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. `timescale 1ns / 1ps `ifdef BSV_POSITIVE_RESET `define BSV_RESET_VALUE 1'b1 `define BSV_RESET_EDGE posedge `else `define BSV_RESET_VALUE 1'b0 `define BSV_RESET_EDGE negedge `endif `ifndef MainClockPeriod `define MainClockPeriod 4 `endif `ifndef DerivedClockPeriod `define DerivedClockPeriod 4 `endif `define XSIM module xsimtop( `ifndef XSIM CLK, DERIVED_CLK, sys_clk `endif ); `ifndef XSIM input CLK; input DERIVED_CLK; input sys_clk; `else reg CLK; reg DERIVED_CLK; reg sys_clk; `endif reg RST_N; reg DERIVED_RST_N; reg [31:0] count; reg [31:0] count_derived; reg finish; import "DPI-C" function void dpi_init(input int unused); import "DPI-C" function bit dpi_cycle(input int returns); // unused non-zero if verilog should $finish(). `ifdef __ATOMICC__ VsimTop connectalTop(.CLK(CLK), .nRST(RST_N), .CLK_derivedClock(DERIVED_CLK), .nRST_derivedReset(DERIVED_RST_N), .CLK_sys_clk(sys_clk)); `else mkXsimTop connectalTop(.CLK(CLK), .RST_N(RST_N), .CLK_derivedClock(DERIVED_CLK), .RST_N_derivedReset(DERIVED_RST_N), .CLK_sys_clk(sys_clk)); `endif initial begin `ifdef XSIM CLK = 1'b0; DERIVED_CLK = 1'b0; sys_clk = 1'b0; `endif RST_N = `BSV_RESET_VALUE; DERIVED_RST_N = `BSV_RESET_VALUE; count = 0; count_derived = 0; finish = 1'b0; dpi_init(0); end `ifdef XSIM always begin #(`MainClockPeriod/2) CLK = !CLK; end always begin #(`DerivedClockPeriod/2) DERIVED_CLK = !DERIVED_CLK; end always begin #2.5 sys_clk = !sys_clk; end `endif always @(posedge CLK) begin count <= count + 1; finish <= dpi_cycle(0); if (finish) begin $display("simulator calling $finish"); $finish(); end end always @(`BSV_RESET_EDGE CLK) begin if (count == 20) begin RST_N <= !`BSV_RESET_VALUE; end end always @(`BSV_RESET_EDGE DERIVED_CLK) begin count_derived <= count_derived + 1; if (count_derived == 20) begin DERIVED_RST_N <= !`BSV_RESET_VALUE; end end endmodule