├── .github └── workflows │ └── regression-tests.yml ├── .gitignore ├── AUTHORS ├── COPYING ├── README.md ├── example ├── ATLYS │ └── fpga │ │ ├── Makefile │ │ ├── common │ │ └── xilinx.mk │ │ ├── fpga.ucf │ │ ├── fpga │ │ └── Makefile │ │ ├── lib │ │ └── uart │ │ └── rtl │ │ ├── debounce_switch.v │ │ ├── fpga.v │ │ ├── fpga_core.v │ │ ├── sync_reset.v │ │ └── sync_signal.v ├── Arty │ └── fpga │ │ ├── Makefile │ │ ├── common │ │ └── vivado.mk │ │ ├── fpga.xdc │ │ ├── fpga │ │ └── Makefile │ │ ├── lib │ │ └── uart │ │ └── rtl │ │ ├── debounce_switch.v │ │ ├── fpga.v │ │ ├── fpga_core.v │ │ ├── sync_reset.v │ │ └── sync_signal.v ├── ML605 │ └── fpga │ │ ├── Makefile │ │ ├── common │ │ └── xilinx.mk │ │ ├── fpga.ucf │ │ ├── fpga │ │ └── Makefile │ │ ├── lib │ │ └── uart │ │ └── rtl │ │ ├── debounce_switch.v │ │ ├── fpga.v │ │ ├── fpga_core.v │ │ ├── sync_reset.v │ │ └── sync_signal.v ├── NexysVideo │ └── fpga │ │ ├── Makefile │ │ ├── common │ │ └── vivado.mk │ │ ├── fpga.xdc │ │ ├── fpga │ │ └── Makefile │ │ ├── lib │ │ └── uart │ │ └── rtl │ │ ├── debounce_switch.v │ │ ├── fpga.v │ │ ├── fpga_core.v │ │ ├── sync_reset.v │ │ └── sync_signal.v └── VCU108 │ └── fpga │ ├── Makefile │ ├── common │ └── vivado.mk │ ├── fpga.xdc │ ├── fpga │ └── Makefile │ ├── lib │ └── uart │ └── rtl │ ├── debounce_switch.v │ ├── fpga.v │ ├── fpga_core.v │ ├── sync_reset.v │ └── sync_signal.v ├── rtl ├── uart.v ├── uart_rx.v └── uart_tx.v ├── tb ├── axis_ep.py ├── test_uart_rx.py ├── test_uart_rx.v ├── test_uart_tx.py ├── test_uart_tx.v ├── uart_ep.py ├── uart_rx │ ├── Makefile │ └── test_uart_rx.py └── uart_tx │ ├── Makefile │ └── test_uart_tx.py └── tox.ini /.github/workflows/regression-tests.yml: -------------------------------------------------------------------------------- 1 | name: Regression Tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: Python ${{matrix.python-version}} 8 | runs-on: ubuntu-22.04 9 | 10 | strategy: 11 | matrix: 12 | python-version: ["3.10"] 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: Set up Python ${{ matrix.python-version }} 18 | uses: actions/setup-python@v4 19 | with: 20 | python-version: ${{ matrix.python-version }} 21 | 22 | - name: Install Icarus Verilog 23 | run: | 24 | sudo apt install -y --no-install-recommends iverilog 25 | 26 | - name: Install Python dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install tox tox-gh-actions 30 | 31 | - name: Test with tox 32 | run: tox -- -n auto --verbose 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.lxt 3 | *.kate-swp 4 | *.pyc 5 | *.vvp 6 | 7 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alex Forencich 2 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2017 Alex Forencich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Verilog UART Readme 2 | 3 | [![Build Status](https://github.com/alexforencich/verilog-uart/workflows/Regression%20Tests/badge.svg?branch=master)](https://github.com/alexforencich/verilog-uart/actions/) 4 | 5 | For more information and updates: http://alexforencich.com/wiki/en/verilog/uart/start 6 | 7 | GitHub repository: https://github.com/alexforencich/verilog-uart 8 | 9 | ## Deprecation Notice 10 | 11 | This repository is superseded by https://github.com/fpganinja/taxi. All new features and bug fixes will be applied there, and commercial support is also available. As a result, this repo is deprecated and will not receive any future maintenance or support. 12 | 13 | ## Introduction 14 | 15 | This is a basic UART to AXI Stream IP core, written in Verilog with cocotb 16 | testbenches. 17 | 18 | ## Documentation 19 | 20 | The main code for the core exists in the rtl subdirectory. The uart_rx.v and 21 | uart_tx.v files are the actual implementation, uart.v simply instantiates both 22 | modules and makes a couple of internal connections. 23 | 24 | The UART transmitter and receiver both use a single transmit or receive pin. 25 | The modules take one parameter, DATA_WIDTH, that specifies the width of both 26 | the data bus and the length of the actual data words communicated. The 27 | default value is 8 for an 8 bit interface. The prescale input determines the 28 | data rate - it should be set to Fclk / (baud * 8). This is an input instead 29 | of a parameter so it can be changed at run time, though it is not buffered 30 | internally so care should be used to avoid corrupt data. The main interface 31 | to the user design is an AXI4-Stream interface that consists of the tdata, 32 | tvalid, and tready signals. tready flows in the opposite direction. tdata 33 | is considered valid when tvalid is high. The destination will accept data 34 | only when tready is high. Data is transferred from the source to the 35 | destination only when both tvalid and tready are high, otherwise the bus is 36 | stalled. 37 | 38 | Both interfaces also present a 'busy' signal that is high when an operation is 39 | taking place. The receiver also presents overrun error and frame error strobe 40 | outputs. If the data word currently in the tdata output register is not read 41 | before another word is received, then a single cycle pulse will be emitted 42 | from overrun_error and the word is discarded. If the receiver does not get a 43 | stop bit of the right level, then a single pulse will be emitted from the 44 | frame_error output and the received word will be discarded. 45 | 46 | ### Source Files 47 | 48 | rtl/uart.v : Wrapper for complete UART 49 | rtl/uart_rx.v : UART receiver implementation 50 | rtl/uart_tx.v : UART transmitter implementation 51 | 52 | ### AXI Stream Interface Example 53 | 54 | two byte transfer with sink pause after each byte 55 | 56 | __ __ __ __ __ __ __ __ __ 57 | clk __/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__ 58 | _____ _________________ 59 | tdata XXXXXXXXX_D0__X_D1______________XXXXXXXXXXXXXXXXXXXXXXXX 60 | _______________________ 61 | tvalid ________/ \_______________________ 62 | ______________ _____ ___________ 63 | tready \___________/ \___________/ 64 | 65 | 66 | ## Testing 67 | 68 | Running the included testbenches requires [cocotb](https://github.com/cocotb/cocotb), [cocotbext-axi](https://github.com/alexforencich/cocotbext-axi), and [Icarus Verilog](http://iverilog.icarus.com/). The testbenches can be run with pytest directly (requires [cocotb-test](https://github.com/themperek/cocotb-test)), pytest via tox, or via cocotb makefiles. 69 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/Makefile: -------------------------------------------------------------------------------- 1 | # Targets 2 | TARGETS:= 3 | 4 | # Subdirectories 5 | SUBDIRS = fpga 6 | SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) 7 | 8 | # Rules 9 | .PHONY: all 10 | all: $(SUBDIRS) $(TARGETS) 11 | 12 | .PHONY: $(SUBDIRS) 13 | $(SUBDIRS): 14 | cd $@ && $(MAKE) 15 | 16 | .PHONY: $(SUBDIRS_CLEAN) 17 | $(SUBDIRS_CLEAN): 18 | cd $(@:.clean=) && $(MAKE) clean 19 | 20 | .PHONY: clean 21 | clean: $(SUBDIRS_CLEAN) 22 | -rm -rf $(TARGETS) 23 | 24 | program: 25 | #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit 26 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/common/xilinx.mk: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Author: Lane Brooks/Keith Fife 3 | # Date: 04/28/2006 4 | # License: GPL 5 | # Desc: This is a Makefile intended to take a verilog rtl design 6 | # through the Xilinx ISE tools to generate configuration files for 7 | # Xilinx FPGAs. This file is generic and just a template. As such 8 | # all design specific options such as synthesis files, fpga part type, 9 | # prom part type, etc should be set in the top Makefile prior to 10 | # including this file. Alternatively, all parameters can be passed 11 | # in from the command line as well. 12 | # 13 | ############################################################################## 14 | # 15 | # Parameter: 16 | # SYN_FILES - Space seperated list of files to be synthesized 17 | # PART - FPGA part (see Xilinx documentation) 18 | # PROM - PROM part 19 | # NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. 20 | # UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf 21 | # 22 | # 23 | # Example Calling Makefile: 24 | # 25 | # SYN_FILES = fpga.v fifo.v clks.v 26 | # PART = xc3s1000 27 | # FPGA_TOP = fpga 28 | # PROM = xc18v04 29 | # NGC_PATH = ipLib1 ipLib2 30 | # FPGA_ARCH = spartan6 31 | # SPI_PROM_SIZE = (in bytes) 32 | # include xilinx.mk 33 | ############################################################################# 34 | # 35 | # Command Line Example: 36 | # make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga 37 | # 38 | ############################################################################## 39 | # 40 | # Required Setup: 41 | # 42 | # %.ucf - user constraint file. Needed by ngdbuild 43 | # 44 | # Optional Files: 45 | # %.xcf - user constraint file. Needed by xst. 46 | # %.ut - File for pin states needed by bitgen 47 | 48 | 49 | .PHONY: clean bit prom fpga spi 50 | 51 | 52 | # Mark the intermediate files as PRECIOUS to prevent make from 53 | # deleting them (see make manual section 10.4). 54 | .PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v 55 | 56 | # include the local Makefile for project for any project specific targets 57 | CONFIG ?= config.mk 58 | -include ../$(CONFIG) 59 | 60 | SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) 61 | INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) 62 | INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) 63 | NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) 64 | 65 | ifdef UCF_FILES 66 | UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) 67 | else 68 | UCF_FILES_REL = $(FPGA_TOP).ucf 69 | endif 70 | 71 | 72 | 73 | fpga: $(FPGA_TOP).bit 74 | 75 | mcs: $(FPGA_TOP).mcs 76 | 77 | prom: $(FPGA_TOP).spi 78 | 79 | spi: $(FPGA_TOP).spi 80 | 81 | fpgasim: $(FPGA_TOP)_sim.v 82 | 83 | 84 | ########################### XST TEMPLATES ############################ 85 | # There are 2 files that XST uses for synthesis that we auto generate. 86 | # The first is a project file which is just a list of all the verilog 87 | # files. The second is the src file which passes XST all the options. 88 | # See XST user manual for XST options. 89 | %.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) 90 | rm -rf xst $*.prj $*.xst defines.v 91 | touch defines.v 92 | mkdir -p xst/tmp 93 | for x in $(DEFS); do echo '`define' $$x >> defines.v; done 94 | echo verilog work defines.v > $*.prj 95 | for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done 96 | @echo "set -tmpdir ./xst/tmp" >> $*.xst 97 | @echo "set -xsthdpdir ./xst" >> $*.xst 98 | @echo "run" >> $*.xst 99 | @echo "-ifn $*.prj" >> $*.xst 100 | @echo "-ifmt mixed" >> $*.xst 101 | @echo "-top $*" >> $*.xst 102 | @echo "-ofn $*" >> $*.xst 103 | @echo "-ofmt NGC" >> $*.xst 104 | @echo "-opt_mode Speed" >> $*.xst 105 | @echo "-opt_level 1" >> $*.xst 106 | # @echo "-verilog2001 YES" >> $*.xst 107 | @echo "-keep_hierarchy NO" >> $*.xst 108 | @echo "-p $(FPGA_PART)" >> $*.xst 109 | xst -ifn $*.xst -ofn $*.log 110 | 111 | 112 | ########################### ISE TRANSLATE ############################ 113 | # ngdbuild will automatically use a ucf called %.ucf if one is found. 114 | # We setup the dependancy such that %.ucf file is required. If any 115 | # pre-compiled ncd files are needed, set the NGC_PATH variable as a space 116 | # seperated list of directories that include the pre-compiled ngc files. 117 | %.ngd: %.ngc $(UCF_FILES_REL) 118 | ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ 119 | 120 | 121 | ########################### ISE MAP ################################### 122 | ifeq ($(FPGA_ARCH),spartan6) 123 | MAP_OPTS= -register_duplication on -timing -xe n 124 | else 125 | MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b 126 | endif 127 | 128 | %_map.ncd: %.ngd 129 | map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf 130 | 131 | # map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf 132 | 133 | 134 | ########################### ISE PnR ################################### 135 | %.ncd: %_map.ncd 136 | par -w -ol high $< $@ $*.pcf 137 | 138 | # par -w -ol std -t 1 $< $@ $*.pcf 139 | 140 | 141 | ##################### ISE Static Timing Analysis ##################### 142 | %.twr: %.ncd 143 | -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf 144 | 145 | %_sim.v: %.ncd 146 | netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ 147 | 148 | # netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v 149 | 150 | 151 | ########################### ISE Bitgen ############################# 152 | %.bit: %.twr 153 | bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit 154 | mkdir -p rev 155 | EXT=bit; COUNT=100; \ 156 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 157 | do let COUNT=COUNT+1; done; \ 158 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 159 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 160 | 161 | 162 | ########################### ISE Promgen ############################# 163 | %.mcs: %.bit 164 | promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< 165 | # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) 166 | mkdir -p rev 167 | EXT=mcs; COUNT=100; \ 168 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 169 | do let COUNT=COUNT+1; done; \ 170 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 171 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 172 | 173 | 174 | %.spi: %.mcs 175 | objcopy -I ihex -O binary $< $@ 176 | EXT=spi; COUNT=100; \ 177 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 178 | do let COUNT=COUNT+1; done; \ 179 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 180 | 181 | 182 | tmpclean: 183 | -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml 184 | 185 | clean: tmpclean 186 | -rm -rf *.bit *.mcs 187 | 188 | # clean everything 189 | distclean: clean 190 | -rm -rf rev 191 | 192 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/fpga.ucf: -------------------------------------------------------------------------------- 1 | # User Constraints File for the Digilent Atlys board, rev C 2 | 3 | CONFIG PART = xc6slx45-2csg324; 4 | 5 | # 100MHz Clock: I/O Bank 1 6 | NET "clk" LOC = "L15" | IOSTANDARD=LVCMOS33; # IO_L42P_GCLK7_M1UDM (GCLK) 7 | NET "clk" TNM_NET = "sys_clk_pin"; 8 | TIMESPEC "TS_sys_clk_pin" = PERIOD "sys_clk_pin" 100000 kHz; 9 | 10 | # Light Emitting Diodes (not used) 11 | NET "led<0>" LOC = "U18" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L52N_M1DQ15 (LD0) 12 | NET "led<1>" LOC = "M14" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L53P (LD1) 13 | NET "led<2>" LOC = "N14" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L53N_VREF (LD2) 14 | NET "led<3>" LOC = "L14" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L61P (LD3) 15 | NET "led<4>" LOC = "M13" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L61N (LD4) 16 | NET "led<5>" LOC = "D4" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; # Bank = 0, IO_L1P_HSWAPEN_0 (HSWAP/LD5) 17 | NET "led<6>" LOC = "P16" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 1, IO_L74N_DOUT_BUSY_1 (LD6) 18 | NET "led<7>" LOC = "N12" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; # Bank = 2, IO_L13P_M1_2 (M1/LD7) 19 | 20 | # Reset Button: I/O Bank 2 (not used) 21 | NET "reset_n" LOC = "T15" | IOSTANDARD=LVCMOS33; # IO_L1N_M0_CMPMISO_2 (M0/RESET) 22 | 23 | # Push Buttons: I/O Bank 3 (not used) 24 | NET "btnu" LOC = "N4"; # IO_L1P (BTNU) 25 | NET "btnl" LOC = "P4"; # IO_L2P (BTNL) 26 | NET "btnd" LOC = "P3"; # IO_L2N (BTND) 27 | NET "btnr" LOC = "F6"; # IO_L55P_M3A13 (BTNR) 28 | NET "btnc" LOC = "F5"; # IO_L55N_M3A14 (BTNC) 29 | 30 | # Toggle Switches (not used) 31 | NET "sw<0>" LOC = "A10"; # Bank = 0, IO_L37N_GCLK12 (SW0) 32 | NET "sw<1>" LOC = "D14"; # Bank = 0, IO_L65P_SCP3 (SW1) 33 | NET "sw<2>" LOC = "C14"; # Bank = 0, IO_L65N_SCP2 (SW2) 34 | NET "sw<3>" LOC = "P15"; # Bank = 1, IO_L74P_AWAKE_1 (SW3) 35 | NET "sw<4>" LOC = "P12"; # Bank = 2, IO_L13N_D10 (SW4) 36 | NET "sw<5>" LOC = "R5"; # Bank = 2, IO_L48P_D7 (SW5) 37 | NET "sw<6>" LOC = "T5"; # Bank = 2, IO_L48N_RDWR_B_VREF_2 (SW6) 38 | NET "sw<7>" LOC = "E4"; # Bank = 3, IO_L54P_M3RESET (SW7) 39 | 40 | # Marvell M88E1111 Tri-Mode Ethernet PHY (1000BASE-T): I/O Bank 1 41 | # Interrupt, Reset, MDIO 42 | #NET "phy_int_n" LOC = "L16" | IOSTANDARD=LVCMOS25; # IO_L42N_GCLK6_TRDY1_M1LDM (E-INT) 43 | NET "phy_reset_n" LOC = "G13" | IOSTANDARD=LVCMOS25; # IO_L32N_A16_M1A9 (E-RESET) 44 | #NET "phy_mdc" LOC = "F16" | IOSTANDARD=LVCMOS25; # IO_L1N_A24_VREF (E-MDC) 45 | #NET "phy_mdio" LOC = "N17" | IOSTANDARD=LVCMOS25; # IO_L48P_HDC_M1DQ8 (E-MDIO) 46 | # GMII Transmit 47 | NET "phy_gtx_clk" LOC = "L12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L40P_GCLK11_M1A5 (E-GTXCLK) 48 | NET "phy_txd<0>" LOC = "H16" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37N_A6_M1A1 (E-TXD0) 49 | NET "phy_txd<1>" LOC = "H13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L36P_A9_M1BA0 (E-TXD1) 50 | NET "phy_txd<2>" LOC = "K14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39N_M1ODT (E-TXD2) 51 | NET "phy_txd<3>" LOC = "K13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34N_A12_M1BA2 (E-TXD3) 52 | NET "phy_txd<4>" LOC = "J13" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L39P_M1A3 (E-TXD4) 53 | NET "phy_txd<5>" LOC = "G14" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L30N_A20_M1A11 (E-TXD5) 54 | NET "phy_txd<6>" LOC = "H12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L32P_A17_M1A8 (E-TXD6) 55 | NET "phy_txd<7>" LOC = "K12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L34P_A13_M1WE (E-TXD7) 56 | NET "phy_tx_en" LOC = "H15" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L37P_A7_M1A0 (E-TXEN) 57 | NET "phy_tx_er" LOC = "G18" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # IO_L38N_A4_M1CLKN (E-TXER) 58 | # GMII Receive (not used) 59 | NET "phy_rx_clk" LOC = "K15" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # IO_L41P_GCLK9_IRDY1_M1RASN (E-RXCLK) 60 | NET "phy_rxd<0>" LOC = "G16" | IOSTANDARD=LVCMOS25; # IO_L38P_A5_M1CLK (E-RXD0) 61 | NET "phy_rxd<1>" LOC = "H14" | IOSTANDARD=LVCMOS25; # IO_L36N_A8_M1BA1 (E-RXD1) 62 | NET "phy_rxd<2>" LOC = "E16" | IOSTANDARD=LVCMOS25; # IO_L33P_A15_M1A10 (E-RXD2) 63 | NET "phy_rxd<3>" LOC = "F15" | IOSTANDARD=LVCMOS25; # IO_L1P_A25 (E-RXD3) 64 | NET "phy_rxd<4>" LOC = "F14" | IOSTANDARD=LVCMOS25; # IO_L30P_A21_M1RESET (E-RXD4) 65 | NET "phy_rxd<5>" LOC = "E18" | IOSTANDARD=LVCMOS25; # IO_L33N_A14_M1A4 (E-RXD5) 66 | NET "phy_rxd<6>" LOC = "D18" | IOSTANDARD=LVCMOS25; # IO_L31N_A18_M1A12 (E-RXD6) 67 | NET "phy_rxd<7>" LOC = "D17" | IOSTANDARD=LVCMOS25; # IO_L31P_A19_M1CKE (E-RXD7) 68 | NET "phy_rx_dv" LOC = "F17" | IOSTANDARD=LVCMOS25; # IO_L35P_A11_M1A7 (E-RXDV) 69 | NET "phy_rx_er" LOC = "F18" | IOSTANDARD=LVCMOS25; # IO_L35N_A10_M1A2 (E-RXER) 70 | 71 | # Timing constraints for Ethernet PHY 72 | TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; 73 | # WARNING: Receiving Ethernet frames will not work without these constraints. 74 | # WARNING: Meeting these constraints will require instantiating an IODELAY2 primitive. 75 | #INST "phy_rxd" TNM = IN_GMII; 76 | #INST "phy_rx_er" TNM = IN_GMII; 77 | #INST "phy_rx_dv" TNM = IN_GMII; 78 | #TIMEGRP "IN_GMII" OFFSET = IN 2.4 ns VALID 2.8 ns BEFORE "phy_rx_clk125"; 79 | 80 | # PMOD Connector (FPGA Bank 2) 81 | # 82 | # FPGA | Atlys 83 | # ------------------------------------ 84 | # T3 | IO_L62N_D6 | JA1 (TOP) 85 | # R3 | IO_L62P_D5 | JA2 (TOP) 86 | # P6 | IO_L64N_D9 | JA3 (TOP) 87 | # N5 | IO_L64P_D8 | JA4 (TOP) 88 | # | GND | JA5 (TOP) 89 | # | Vcc | JA6 (TOP) 90 | # V9 | IO_L32N_GCLK28 | JA7 (BOTTOM) 91 | # T9 | IO_L32P_GCLK29 | JA8 (BOTTOM) 92 | # V4 | IO_L63N | JA9 (BOTTOM) 93 | # T4 | IO_L63P | JA10 (BOTTOM) 94 | # | GND | JA11 (BOTTOM) 95 | # | Vcc | JA12 (BOTTOM) 96 | # 97 | #NET "ready<1>" LOC = "T3" | IOSTANDARD=LVCMOS33 | PULLDOWN; 98 | #NET "trigger<1>" LOC = "V9" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; 99 | #NET "spi_mosi<1>" LOC = "R3" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; 100 | #NET "spi_cs_n<1>" LOC = "T9" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; 101 | #NET "spi_clk<1>" LOC = "P6" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; 102 | #NET "spi_gnd<1>" LOC = "V4" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; 103 | 104 | # VHDCI Connector (FPGA Bank 2) 105 | # Note: Channnel 1 connects to P signals, Channel 2 to N signals 106 | # 107 | # FPGA | Atlys | VmodMIB 108 | # ----------------------------------------------------------------------------- 109 | # U16 | IO_L2P_CMPCLK | EXP-IO1_P | JC.1 | JC-CLK_P | JC8 (BOTTOM) 110 | # U15 | *IO_L5P | EXP-IO2_P | JC.3 | JC-D0_P | JC2 (TOP) 111 | # U13 | IO_L14P_D11 | EXP-IO3_P | JC.4 | JC-D1_P | JC10 (BOTTOM) 112 | # M11 | *IO_L15P | EXP-IO4_P | JC.6 | JC-D2_P | JC4 (TOP) 113 | # R11 | IO_L16P | EXP-IO5_P | JC.7 | JA-D0_P | JA2 (TOP) 114 | # T12 | *IO_L19P | EXP-IO6_P | JC.9 | JA-D1_P | JA10 (BOTTOM) 115 | # N10 | *IO_L20P | EXP-IO7_P | JC.10 | JA-D2_P | JA4 (TOP) 116 | # M10 | *IO_L22P | EXP-IO8_P | JC.12 | JB-D0_P | JB2 (TOP) 117 | # U11 | IO_L23P | EXP-IO9_P | JC.13 | JB-D1_P | JB10 (BOTTOM) 118 | # R10 | IO_L29P_GCLK3 | EXP-IO10_P | JC.15 | JA-CLK_P | JA8 (BOTTOM) 119 | # U10 | IO_L30P_GCLK1_D13 | EXP-IO11_P | JC.20 | JB-CLK_P | JB8 (BOTTOM) 120 | # R8 | IO_L31P_GCLK31_D14 | EXP-IO12_P | JC.22 | JB-D2_P | JB4 (TOP) 121 | # M8 | *IO_L40P | EXP-IO13_P | JC.23 | JE8 | JE8 (BOTTOM) 122 | # U8 | IO_L41P | EXP-IO14_P | JC.25 | JE2 | JE2 (TOP) 123 | # U7 | IO_L43P | EXP-IO15_P | JC.26 | JE10 | JE10 (BOTTOM) 124 | # N7 | *IO_L44P | EXP-IO16_P | JC.28 | JE4 | JE4 (TOP) 125 | # T6 | IO_L45P | EXP-IO17_P | JC.29 | JD-CLK_P | JD8 (BOTTOM) 126 | # R7 | IO_L46P | EXP-IO18_P | JC.31 | JD-D0_P | JD2 (TOP) 127 | # N6 | *IO_L47P | EXP-IO19_P | JC.32 | JD-D1_P | JD10 (BOTTOM) 128 | # U5 | IO_49P_D3 | EXP-IO20_P | JC.34 | JD-D2_P | JD4 (TOP) 129 | # V16 | IO_L2N_CMPMOSI | EXP-IO1_N | JC.35 | JC-CLK_N | JC7 (BOTTOM) 130 | # V15 | *IO_L5N | EXP-IO2_N | JC.37 | JC-D0_N | JC1 (TOP) 131 | # V13 | IO_L14N_D12 | EXP-IO3_N | JC.38 | JC-D1_N | JC9 (BOTTOM) 132 | # N11 | *IO_L15N | EXP-IO4_N | JC.40 | JC-D2_N | JC3 (TOP) 133 | # T11 | IO_L16N_VREF | EXP-IO5_N | JC.41 | JA-D0_N | JA1 (TOP) 134 | # V12 | *IO_L19N | EXP-IO6_N | JC.43 | JA-D1_N | JA9 (BOTTOM) 135 | # P11 | *IO_L20N | EXP-IO7_N | JC.44 | JA-D2_N | JA3 (TOP) 136 | # N9 | *IO_L22N | EXP-IO8_N | JC.46 | JB-D0_N | JB1 (TOP) 137 | # V11 | IO_L23N | EXP-IO9_N | JC.47 | JB-D1_N | JB9 (BOTTOM) 138 | # T10 | IO_L29N_GCLK2 | EXP-IO10_N | JC.49 | JA-CLK_N | JA7 (BOTTOM) 139 | # V10 | IO_L30N_GCLK0_USERCCLK | EXP-IO11_N | JC.54 | JB-CLK_N | JB7 (BOTTOM) 140 | # T8 | IO_L31N_GCLK30_D15 | EXP-IO12_N | JC.56 | JB-D2_N | JB3 (TOP) 141 | # N8 | *IO_L40N | EXP-IO13_N | JC.57 | JE7 | JE7 (BOTTOM) 142 | # V8 | IO_L41N_VREF | EXP-IO14_N | JC.59 | JE1 | JE1 (TOP) 143 | # V7 | IO_L43N | EXP-IO15_N | JC.60 | JE9 | JE9 (BOTTOM) 144 | # P8 | *IO_L44N | EXP-IO16_N | JC.62 | JE3 | JE3 (TOP) 145 | # V6 | IO_L45N | EXP-IO17_N | JC.63 | JD-CLK_N | JD7 (BOTTOM) 146 | # T7 | IO_L46N | EXP-IO18_N | JC.65 | JD-D0_N | JD1 (TOP) 147 | # P7 | *IO_L47N | EXP-IO19_N | JC.66 | JD-D1_N | JD9 (BOTTOM) 148 | # V5 | IO_49N_D4 | EXP-IO20_N | JC.68 | JD-D2_N | JD3 (TOP) 149 | 150 | #NET "" LOC = "U16" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO1_P 151 | #NET "" LOC = "U15" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO2_P 152 | #NET "" LOC = "U13" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO3_P 153 | #NET "" LOC = "M11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO4_P 154 | #NET "" LOC = "R11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO5_P 155 | #NET "" LOC = "T12" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO6_P 156 | #NET "" LOC = "N10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO7_P 157 | #NET "" LOC = "M10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO8_P 158 | #NET "" LOC = "U11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO9_P 159 | #NET "" LOC = "R10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO10_P 160 | #NET "" LOC = "U10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO11_P 161 | #NET "" LOC = "R8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO12_P 162 | #NET "" LOC = "M8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO13_P 163 | #NET "" LOC = "U8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO14_P 164 | #NET "" LOC = "U7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO15_P 165 | #NET "" LOC = "N7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO16_P 166 | #NET "" LOC = "T6" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO17_P 167 | #NET "" LOC = "R7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO18_P 168 | #NET "" LOC = "N6" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO19_P 169 | #NET "" LOC = "U5" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO20_P 170 | #NET "" LOC = "V16" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO1_N 171 | #NET "" LOC = "V15" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO2_N 172 | #NET "" LOC = "V13" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO3_N 173 | #NET "" LOC = "N11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO4_N 174 | #NET "" LOC = "T11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=8; # EXP-IO5_N 175 | #NET "" LOC = "V12" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO6_N 176 | #NET "" LOC = "P11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO7_N 177 | #NET "" LOC = "N9" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO8_N 178 | #NET "" LOC = "V11" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO9_N 179 | #NET "" LOC = "T10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO10_N 180 | #NET "" LOC = "V10" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO11_N 181 | #NET "" LOC = "T8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO12_N 182 | #NET "" LOC = "N8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO13_N 183 | #NET "" LOC = "V8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO14_N 184 | #NET "" LOC = "V7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO15_N 185 | #NET "" LOC = "P8" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO16_N 186 | #NET "" LOC = "V6" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO17_N 187 | #NET "" LOC = "T7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO18_N 188 | #NET "" LOC = "P7" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO19_N 189 | #NET "" LOC = "V5" | IOSTANDARD=LVCMOS33 | SLEW=FAST | DRIVE=2; # EXP-IO20_N 190 | 191 | # Exar UART: I/O Bank 0 192 | NET "uart_rxd" LOC = "A16" | IOSTANDARD=LVCMOS33; # IO_L66N_SCP0 (USBB-RXD) 193 | NET "uart_txd" LOC = "B16" | IOSTANDARD=LVCMOS33; # IO_L66P_SCP1 (USBB-TXD) 194 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/fpga/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # FPGA settings 3 | FPGA_PART = xc6slx45-2csg324 4 | FPGA_TOP = fpga 5 | FPGA_ARCH = spartan6 6 | 7 | # PROM settings 8 | #PROM = xc18v04 9 | #SPI_PROM_SIZE = (in bytes) 10 | 11 | # Files for synthesis 12 | SYN_FILES = rtl/fpga.v 13 | SYN_FILES += rtl/fpga_core.v 14 | SYN_FILES += rtl/debounce_switch.v 15 | SYN_FILES += rtl/sync_reset.v 16 | SYN_FILES += rtl/sync_signal.v 17 | SYN_FILES += lib/uart/rtl/uart.v 18 | SYN_FILES += lib/uart/rtl/uart_rx.v 19 | SYN_FILES += lib/uart/rtl/uart_tx.v 20 | #SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v 21 | 22 | # UCF files 23 | UCF_FILES = fpga.ucf 24 | 25 | # NGC paths for ngdbuild 26 | #NGC_PATHS = coregen/dcm_i100_o125 27 | 28 | # Bitgen options 29 | BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 30 | 31 | include ../common/xilinx.mk 32 | 33 | program: $(FPGA_TOP).bit 34 | djtgcfg prog -d Atlys --index 0 --file $(FPGA_TOP).bit 35 | 36 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/lib/uart: -------------------------------------------------------------------------------- 1 | ../../../../ -------------------------------------------------------------------------------- /example/ATLYS/fpga/rtl/debounce_switch.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes switch and button inputs with a slow sampled shift register 31 | */ 32 | module debounce_switch #( 33 | parameter WIDTH=1, // width of the input and output signals 34 | parameter N=3, // length of shift register 35 | parameter RATE=125000 // clock division factor 36 | )( 37 | input wire clk, 38 | input wire rst, 39 | input wire [WIDTH-1:0] in, 40 | output wire [WIDTH-1:0] out 41 | ); 42 | 43 | reg [23:0] cnt_reg = 24'd0; 44 | 45 | reg [N-1:0] debounce_reg[WIDTH-1:0]; 46 | 47 | reg [WIDTH-1:0] state; 48 | 49 | /* 50 | * The synchronized output is the state register 51 | */ 52 | assign out = state; 53 | 54 | integer k; 55 | 56 | always @(posedge clk or posedge rst) begin 57 | if (rst) begin 58 | cnt_reg <= 0; 59 | state <= 0; 60 | 61 | for (k = 0; k < WIDTH; k = k + 1) begin 62 | debounce_reg[k] <= 0; 63 | end 64 | end else begin 65 | if (cnt_reg < RATE) begin 66 | cnt_reg <= cnt_reg + 24'd1; 67 | end else begin 68 | cnt_reg <= 24'd0; 69 | end 70 | 71 | if (cnt_reg == 24'd0) begin 72 | for (k = 0; k < WIDTH; k = k + 1) begin 73 | debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; 74 | end 75 | end 76 | 77 | for (k = 0; k < WIDTH; k = k + 1) begin 78 | if (|debounce_reg[k] == 0) begin 79 | state[k] <= 0; 80 | end else if (&debounce_reg[k] == 1) begin 81 | state[k] <= 1; 82 | end else begin 83 | state[k] <= state[k]; 84 | end 85 | end 86 | end 87 | end 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/rtl/fpga.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA top-level module 31 | */ 32 | module fpga ( 33 | /* 34 | * Clock: 100MHz 35 | * Reset: Push button, active low 36 | */ 37 | input wire clk, 38 | input wire reset_n, 39 | /* 40 | * GPIO 41 | */ 42 | input wire btnu, 43 | input wire btnl, 44 | input wire btnd, 45 | input wire btnr, 46 | input wire btnc, 47 | input wire [7:0] sw, 48 | output wire [7:0] led, 49 | /* 50 | * Ethernet: 1000BASE-T GMII 51 | */ 52 | input wire phy_rx_clk, 53 | input wire [7:0] phy_rxd, 54 | input wire phy_rx_dv, 55 | input wire phy_rx_er, 56 | output wire phy_gtx_clk, 57 | output wire [7:0] phy_txd, 58 | output wire phy_tx_en, 59 | output wire phy_tx_er, 60 | output wire phy_reset_n, 61 | /* 62 | * UART: 500000 bps, 8N1 63 | */ 64 | input wire uart_rxd, 65 | output wire uart_txd 66 | ); 67 | 68 | // Clock and reset 69 | 70 | wire clk_ibufg; 71 | wire clk_bufg; 72 | wire clk_dcm_out; 73 | 74 | // Internal 125 MHz clock 75 | wire clk_int; 76 | wire rst_int; 77 | 78 | wire dcm_rst; 79 | wire [7:0] dcm_status; 80 | wire dcm_locked; 81 | wire dcm_clkfx_stopped = dcm_status[2]; 82 | 83 | assign dcm_rst = ~reset_n | (dcm_clkfx_stopped & ~dcm_locked); 84 | 85 | IBUFG 86 | clk_ibufg_inst( 87 | .I(clk), 88 | .O(clk_ibufg) 89 | ); 90 | 91 | DCM_SP #( 92 | .CLKIN_PERIOD(10), 93 | .CLK_FEEDBACK("NONE"), 94 | .CLKDV_DIVIDE(2.0), 95 | .CLKFX_MULTIPLY(5.0), 96 | .CLKFX_DIVIDE(4.0), 97 | .PHASE_SHIFT(0), 98 | .CLKOUT_PHASE_SHIFT("NONE"), 99 | .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), 100 | .STARTUP_WAIT("FALSE"), 101 | .CLKIN_DIVIDE_BY_2("FALSE") 102 | ) 103 | clk_dcm_inst ( 104 | .CLKIN(clk_ibufg), 105 | .CLKFB(1'b0), 106 | .RST(dcm_rst), 107 | .PSEN(1'b0), 108 | .PSINCDEC(1'b0), 109 | .PSCLK(1'b0), 110 | .CLK0(), 111 | .CLK90(), 112 | .CLK180(), 113 | .CLK270(), 114 | .CLK2X(), 115 | .CLK2X180(), 116 | .CLKDV(), 117 | .CLKFX(clk_dcm_out), 118 | .CLKFX180(), 119 | .STATUS(dcm_status), 120 | .LOCKED(dcm_locked), 121 | .PSDONE() 122 | ); 123 | 124 | BUFG 125 | clk_bufg_inst ( 126 | .I(clk_dcm_out), 127 | .O(clk_int) 128 | ); 129 | 130 | sync_reset #( 131 | .N(4) 132 | ) 133 | sync_reset_inst ( 134 | .clk(clk_int), 135 | .rst(~dcm_locked), 136 | .sync_reset_out(rst_int) 137 | ); 138 | 139 | // GPIO 140 | wire btnu_int; 141 | wire btnl_int; 142 | wire btnd_int; 143 | wire btnr_int; 144 | wire btnc_int; 145 | wire [7:0] sw_int; 146 | 147 | debounce_switch #( 148 | .WIDTH(13), 149 | .N(4), 150 | .RATE(125000) 151 | ) 152 | debounce_switch_inst ( 153 | .clk(clk_int), 154 | .rst(rst_int), 155 | .in({btnu, 156 | btnl, 157 | btnd, 158 | btnr, 159 | btnc, 160 | sw}), 161 | .out({btnu_int, 162 | btnl_int, 163 | btnd_int, 164 | btnr_int, 165 | btnc_int, 166 | sw_int}) 167 | ); 168 | 169 | sync_signal #( 170 | .WIDTH(1), 171 | .N(2) 172 | ) 173 | sync_signal_inst ( 174 | .clk(clk_int), 175 | .in({uart_rxd}), 176 | .out({uart_rxd_int}) 177 | ); 178 | 179 | fpga_core 180 | core_inst ( 181 | /* 182 | * Clock: 125MHz 183 | * Synchronous reset 184 | */ 185 | .clk(clk_int), 186 | .rst(rst_int), 187 | /* 188 | * GPIO 189 | */ 190 | .btnu(btnu_int), 191 | .btnl(btnl_int), 192 | .btnd(btnd_int), 193 | .btnr(btnr_int), 194 | .btnc(btnc_int), 195 | .sw(sw_int), 196 | .led(led), 197 | /* 198 | * Ethernet: 1000BASE-T GMII 199 | */ 200 | .phy_rx_clk(phy_rx_clk), 201 | .phy_rxd(phy_rxd), 202 | .phy_rx_dv(phy_rx_dv), 203 | .phy_rx_er(phy_rx_er), 204 | .phy_gtx_clk(phy_gtx_clk), 205 | .phy_txd(phy_txd), 206 | .phy_tx_en(phy_tx_en), 207 | .phy_tx_er(phy_tx_er), 208 | .phy_reset_n(phy_reset_n), 209 | /* 210 | * UART: 115200 bps, 8N1 211 | */ 212 | .uart_rxd(uart_rxd_int), 213 | .uart_txd(uart_txd) 214 | ); 215 | 216 | endmodule 217 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/rtl/fpga_core.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | module fpga_core ( 30 | /* 31 | * Clock: 125MHz 32 | * Synchronous reset 33 | */ 34 | input wire clk, 35 | input wire rst, 36 | /* 37 | * GPIO 38 | */ 39 | input wire btnu, 40 | input wire btnl, 41 | input wire btnd, 42 | input wire btnr, 43 | input wire btnc, 44 | input wire [7:0] sw, 45 | output wire [7:0] led, 46 | /* 47 | * Ethernet: 1000BASE-T GMII 48 | */ 49 | input wire phy_rx_clk, 50 | input wire [7:0] phy_rxd, 51 | input wire phy_rx_dv, 52 | input wire phy_rx_er, 53 | output wire phy_gtx_clk, 54 | output wire [7:0] phy_txd, 55 | output wire phy_tx_en, 56 | output wire phy_tx_er, 57 | output wire phy_reset_n, 58 | /* 59 | * UART: 115200 bps, 8N1 60 | */ 61 | input wire uart_rxd, 62 | output wire uart_txd 63 | ); 64 | 65 | reg [7:0] uart_tx_axis_tdata; 66 | reg uart_tx_axis_tvalid; 67 | wire uart_tx_axis_tready; 68 | 69 | wire [7:0] uart_rx_axis_tdata; 70 | wire uart_rx_axis_tvalid; 71 | reg uart_rx_axis_tready; 72 | 73 | uart 74 | uart_inst ( 75 | .clk(clk), 76 | .rst(rst), 77 | // AXI input 78 | .s_axis_tdata(uart_tx_axis_tdata), 79 | .s_axis_tvalid(uart_tx_axis_tvalid), 80 | .s_axis_tready(uart_tx_axis_tready), 81 | // AXI output 82 | .m_axis_tdata(uart_rx_axis_tdata), 83 | .m_axis_tvalid(uart_rx_axis_tvalid), 84 | .m_axis_tready(uart_rx_axis_tready), 85 | // uart 86 | .rxd(uart_rxd), 87 | .txd(uart_txd), 88 | // status 89 | .tx_busy(), 90 | .rx_busy(), 91 | .rx_overrun_error(), 92 | .rx_frame_error(), 93 | // configuration 94 | .prescale(125000000/(9600*8)) 95 | ); 96 | 97 | //assign led = sw; 98 | assign led = uart_tx_axis_tdata; 99 | assign phy_reset_n = ~rst; 100 | 101 | assign phy_gtx_clk = 1'b0; 102 | assign phy_txd = 8'd0; 103 | assign phy_tx_en = 1'b0; 104 | assign phy_tx_er = 1'b0; 105 | 106 | always @(posedge clk or posedge rst) begin 107 | if (rst) begin 108 | uart_tx_axis_tdata <= 0; 109 | uart_tx_axis_tvalid <= 0; 110 | uart_rx_axis_tready <= 0; 111 | end else begin 112 | if (uart_tx_axis_tvalid) begin 113 | // attempting to transmit a byte 114 | // so can't receive one at the moment 115 | uart_rx_axis_tready <= 0; 116 | // if it has been received, then clear the valid flag 117 | if (uart_tx_axis_tready) begin 118 | uart_tx_axis_tvalid <= 0; 119 | end 120 | end else begin 121 | // ready to receive byte 122 | uart_rx_axis_tready <= 1; 123 | if (uart_rx_axis_tvalid) begin 124 | // got one, so make sure it gets the correct ready signal 125 | // (either clear it if it was set or set it if we just got a 126 | // byte out of waiting for the transmitter to send one) 127 | uart_rx_axis_tready <= ~uart_rx_axis_tready; 128 | // send byte back out 129 | uart_tx_axis_tdata <= uart_rx_axis_tdata; 130 | uart_tx_axis_tvalid <= 1; 131 | end 132 | end 133 | end 134 | end 135 | 136 | endmodule 137 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an active-high asynchronous reset signal to a given clock by 31 | * using a pipeline of N registers. 32 | */ 33 | module sync_reset #( 34 | parameter N=2 // depth of synchronizer 35 | )( 36 | input wire clk, 37 | input wire rst, 38 | output wire sync_reset_out 39 | ); 40 | 41 | reg [N-1:0] sync_reg = {N{1'b1}}; 42 | 43 | assign sync_reset_out = sync_reg[N-1]; 44 | 45 | always @(posedge clk or posedge rst) begin 46 | if (rst) 47 | sync_reg <= {N{1'b1}}; 48 | else 49 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /example/ATLYS/fpga/rtl/sync_signal.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an asyncronous signal to a given clock by using a pipeline of 31 | * two registers. 32 | */ 33 | module sync_signal #( 34 | parameter WIDTH=1, // width of the input and output signals 35 | parameter N=2 // depth of synchronizer 36 | )( 37 | input wire clk, 38 | input wire [WIDTH-1:0] in, 39 | output wire [WIDTH-1:0] out 40 | ); 41 | 42 | reg [WIDTH-1:0] sync_reg[N-1:0]; 43 | 44 | /* 45 | * The synchronized output is the last register in the pipeline. 46 | */ 47 | assign out = sync_reg[N-1]; 48 | 49 | integer k; 50 | 51 | always @(posedge clk) begin 52 | sync_reg[0] <= in; 53 | for (k = 1; k < N; k = k + 1) begin 54 | sync_reg[k] <= sync_reg[k-1]; 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /example/Arty/fpga/Makefile: -------------------------------------------------------------------------------- 1 | # Targets 2 | TARGETS:= 3 | 4 | # Subdirectories 5 | SUBDIRS = fpga 6 | SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) 7 | 8 | # Rules 9 | .PHONY: all 10 | all: $(SUBDIRS) $(TARGETS) 11 | 12 | .PHONY: $(SUBDIRS) 13 | $(SUBDIRS): 14 | cd $@ && $(MAKE) 15 | 16 | .PHONY: $(SUBDIRS_CLEAN) 17 | $(SUBDIRS_CLEAN): 18 | cd $(@:.clean=) && $(MAKE) clean 19 | 20 | .PHONY: clean 21 | clean: $(SUBDIRS_CLEAN) 22 | -rm -rf $(TARGETS) 23 | 24 | program: 25 | #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit 26 | -------------------------------------------------------------------------------- /example/Arty/fpga/common/vivado.mk: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | # 3 | # Xilinx Vivado FPGA Makefile 4 | # 5 | # Copyright (c) 2016 Alex Forencich 6 | # 7 | ################################################################### 8 | # 9 | # Parameters: 10 | # FPGA_TOP - Top module name 11 | # FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) 12 | # FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) 13 | # SYN_FILES - space-separated list of source files 14 | # INC_FILES - space-separated list of include files 15 | # XDC_FILES - space-separated list of timing constraint files 16 | # XCI_FILES - space-separated list of IP XCI files 17 | # 18 | # Example: 19 | # 20 | # FPGA_TOP = fpga 21 | # FPGA_FAMILY = VirtexUltrascale 22 | # FPGA_DEVICE = xcvu095-ffva2104-2-e 23 | # SYN_FILES = rtl/fpga.v 24 | # XDC_FILES = fpga.xdc 25 | # XCI_FILES = ip/pcspma.xci 26 | # include ../common/vivado.mk 27 | # 28 | ################################################################### 29 | 30 | # phony targets 31 | .PHONY: clean fpga 32 | 33 | # prevent make from deleting intermediate files and reports 34 | .PRECIOUS: %.xpr %.bit 35 | .SECONDARY: 36 | 37 | CONFIG ?= config.mk 38 | -include ../$(CONFIG) 39 | 40 | SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) 41 | INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) 42 | XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) 43 | 44 | ifdef XDC_FILES 45 | XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) 46 | else 47 | XDC_FILES_REL = $(FPGA_TOP).xdc 48 | endif 49 | 50 | ################################################################### 51 | # Main Targets 52 | # 53 | # all: build everything 54 | # clean: remove output files and project files 55 | ################################################################### 56 | 57 | all: fpga 58 | 59 | fpga: $(FPGA_TOP).bit 60 | 61 | tmpclean: 62 | -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v 63 | -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl 64 | 65 | clean: tmpclean 66 | -rm -rf *.bit program.tcl 67 | 68 | distclean: clean 69 | -rm -rf rev 70 | 71 | ################################################################### 72 | # Target implementations 73 | ################################################################### 74 | 75 | # Vivado project file 76 | %.xpr: Makefile $(XCI_FILES_REL) 77 | rm -rf defines.v 78 | touch defines.v 79 | for x in $(DEFS); do echo '`define' $$x >> defines.v; done 80 | echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl 81 | echo "add_files -fileset sources_1 defines.v" >> create_project.tcl 82 | for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done 83 | for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done 84 | for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done 85 | echo "exit" >> create_project.tcl 86 | vivado -mode batch -source create_project.tcl 87 | 88 | # synthesis run 89 | %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) 90 | echo "open_project $*.xpr" > run_synth.tcl 91 | echo "reset_run synth_1" >> run_synth.tcl 92 | echo "launch_runs synth_1" >> run_synth.tcl 93 | echo "wait_on_run synth_1" >> run_synth.tcl 94 | echo "exit" >> run_synth.tcl 95 | vivado -mode batch -source run_synth.tcl 96 | 97 | # implementation run 98 | %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp 99 | echo "open_project $*.xpr" > run_impl.tcl 100 | echo "reset_run impl_1" >> run_impl.tcl 101 | echo "launch_runs impl_1" >> run_impl.tcl 102 | echo "wait_on_run impl_1" >> run_impl.tcl 103 | echo "exit" >> run_impl.tcl 104 | vivado -mode batch -source run_impl.tcl 105 | 106 | # bit file 107 | %.bit: %.runs/impl_1/%_routed.dcp 108 | echo "open_project $*.xpr" > generate_bit.tcl 109 | echo "open_run impl_1" >> generate_bit.tcl 110 | echo "write_bitstream -force $*.bit" >> generate_bit.tcl 111 | echo "exit" >> generate_bit.tcl 112 | vivado -mode batch -source generate_bit.tcl 113 | mkdir -p rev 114 | EXT=bit; COUNT=100; \ 115 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 116 | do let COUNT=COUNT+1; done; \ 117 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 118 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 119 | -------------------------------------------------------------------------------- /example/Arty/fpga/fpga.xdc: -------------------------------------------------------------------------------- 1 | # XDC constraints for the Digilent Arty board 2 | # part: xc7a35t-csg324-1 3 | 4 | # General configuration 5 | set_property CFGBVS VCCO [current_design] 6 | set_property CONFIG_VOLTAGE 3.3 [current_design] 7 | set_property BITSTREAM.GENERAL.COMPRESS true [current_design] 8 | 9 | # 100 MHz clock 10 | set_property -dict {LOC E3 IOSTANDARD LVCMOS33} [get_ports clk] 11 | create_clock -period 10.000 -name clk [get_ports clk] 12 | 13 | # LEDs 14 | set_property -dict {LOC G6 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led0_r] 15 | set_property -dict {LOC F6 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led0_g] 16 | set_property -dict {LOC E1 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led0_b] 17 | set_property -dict {LOC G3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led1_r] 18 | set_property -dict {LOC J4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led1_g] 19 | set_property -dict {LOC G4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led1_b] 20 | set_property -dict {LOC J3 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led2_r] 21 | set_property -dict {LOC J2 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led2_g] 22 | set_property -dict {LOC H4 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led2_b] 23 | set_property -dict {LOC K1 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led3_r] 24 | set_property -dict {LOC H6 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led3_g] 25 | set_property -dict {LOC K2 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led3_b] 26 | set_property -dict {LOC H5 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led4] 27 | set_property -dict {LOC J5 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led5] 28 | set_property -dict {LOC T9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led6] 29 | set_property -dict {LOC T10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led7] 30 | 31 | # Reset button 32 | set_property -dict {LOC C2 IOSTANDARD LVCMOS33} [get_ports reset_n] 33 | 34 | # Push buttons 35 | set_property -dict {LOC D9 IOSTANDARD LVCMOS33} [get_ports {btn[0]}] 36 | set_property -dict {LOC C9 IOSTANDARD LVCMOS33} [get_ports {btn[1]}] 37 | set_property -dict {LOC B9 IOSTANDARD LVCMOS33} [get_ports {btn[2]}] 38 | set_property -dict {LOC B8 IOSTANDARD LVCMOS33} [get_ports {btn[3]}] 39 | 40 | # Toggle switches 41 | set_property -dict {LOC A8 IOSTANDARD LVCMOS33} [get_ports {sw[0]}] 42 | set_property -dict {LOC C11 IOSTANDARD LVCMOS33} [get_ports {sw[1]}] 43 | set_property -dict {LOC C10 IOSTANDARD LVCMOS33} [get_ports {sw[2]}] 44 | set_property -dict {LOC A10 IOSTANDARD LVCMOS33} [get_ports {sw[3]}] 45 | 46 | # UART 47 | set_property -dict {LOC D10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports uart_txd] 48 | set_property -dict {LOC A9 IOSTANDARD LVCMOS33} [get_ports uart_rxd] 49 | 50 | # Ethernet MII PHY 51 | #set_property -dict {LOC F15 IOSTANDARD LVCMOS33} [get_ports phy_rx_clk] 52 | #set_property -dict {LOC D18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[0]}] 53 | #set_property -dict {LOC E17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[1]}] 54 | #set_property -dict {LOC E18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[2]}] 55 | #set_property -dict {LOC G17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[3]}] 56 | #set_property -dict {LOC G16 IOSTANDARD LVCMOS33} [get_ports phy_rx_dv] 57 | #set_property -dict {LOC C17 IOSTANDARD LVCMOS33} [get_ports phy_rx_er] 58 | #set_property -dict {LOC H16 IOSTANDARD LVCMOS33} [get_ports phy_tx_clk] 59 | #set_property -dict {LOC H14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[0]}] 60 | #set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[1]}] 61 | #set_property -dict {LOC J13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[2]}] 62 | #set_property -dict {LOC H17 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[3]}] 63 | #set_property -dict {LOC H15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports phy_tx_en] 64 | #set_property -dict {LOC D17 IOSTANDARD LVCMOS33} [get_ports phy_col] 65 | #set_property -dict {LOC G14 IOSTANDARD LVCMOS33} [get_ports phy_crs] 66 | #set_property -dict {LOC G18 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_ref_clk] 67 | #set_property -dict {LOC C16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_reset_n] 68 | #set_property -dict {LOC K13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_mdio] 69 | #set_property -dict {LOC F16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_mdc] 70 | 71 | #create_clock -period 40.000 -name phy_rx_clk [get_ports phy_rx_clk] 72 | #create_clock -period 40.000 -name phy_tx_clk [get_ports phy_tx_clk] 73 | 74 | -------------------------------------------------------------------------------- /example/Arty/fpga/fpga/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # FPGA settings 3 | FPGA_PART = xc7a35t-csg324-1 4 | FPGA_TOP = fpga 5 | FPGA_ARCH = artix7 6 | 7 | # Files for synthesis 8 | SYN_FILES = rtl/fpga.v 9 | SYN_FILES += rtl/fpga_core.v 10 | SYN_FILES += rtl/debounce_switch.v 11 | SYN_FILES += rtl/sync_reset.v 12 | SYN_FILES += rtl/sync_signal.v 13 | SYN_FILES += lib/uart/rtl/uart.v 14 | SYN_FILES += lib/uart/rtl/uart_rx.v 15 | SYN_FILES += lib/uart/rtl/uart_tx.v 16 | 17 | # XDC files 18 | XDC_FILES = fpga.xdc 19 | 20 | include ../common/vivado.mk 21 | 22 | program: $(FPGA_TOP).bit 23 | echo "open_hw" > program.tcl 24 | echo "connect_hw_server" >> program.tcl 25 | echo "open_hw_target" >> program.tcl 26 | echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl 27 | echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl 28 | echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl 29 | echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl 30 | echo "exit" >> program.tcl 31 | vivado -mode batch -source program.tcl 32 | 33 | -------------------------------------------------------------------------------- /example/Arty/fpga/lib/uart: -------------------------------------------------------------------------------- 1 | ../../../../ -------------------------------------------------------------------------------- /example/Arty/fpga/rtl/debounce_switch.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes switch and button inputs with a slow sampled shift register 31 | */ 32 | module debounce_switch #( 33 | parameter WIDTH=1, // width of the input and output signals 34 | parameter N=3, // length of shift register 35 | parameter RATE=125000 // clock division factor 36 | )( 37 | input wire clk, 38 | input wire rst, 39 | input wire [WIDTH-1:0] in, 40 | output wire [WIDTH-1:0] out 41 | ); 42 | 43 | reg [23:0] cnt_reg = 24'd0; 44 | 45 | reg [N-1:0] debounce_reg[WIDTH-1:0]; 46 | 47 | reg [WIDTH-1:0] state; 48 | 49 | /* 50 | * The synchronized output is the state register 51 | */ 52 | assign out = state; 53 | 54 | integer k; 55 | 56 | always @(posedge clk or posedge rst) begin 57 | if (rst) begin 58 | cnt_reg <= 0; 59 | state <= 0; 60 | 61 | for (k = 0; k < WIDTH; k = k + 1) begin 62 | debounce_reg[k] <= 0; 63 | end 64 | end else begin 65 | if (cnt_reg < RATE) begin 66 | cnt_reg <= cnt_reg + 24'd1; 67 | end else begin 68 | cnt_reg <= 24'd0; 69 | end 70 | 71 | if (cnt_reg == 24'd0) begin 72 | for (k = 0; k < WIDTH; k = k + 1) begin 73 | debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; 74 | end 75 | end 76 | 77 | for (k = 0; k < WIDTH; k = k + 1) begin 78 | if (|debounce_reg[k] == 0) begin 79 | state[k] <= 0; 80 | end else if (&debounce_reg[k] == 1) begin 81 | state[k] <= 1; 82 | end else begin 83 | state[k] <= state[k]; 84 | end 85 | end 86 | end 87 | end 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /example/Arty/fpga/rtl/fpga.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA top-level module 31 | */ 32 | module fpga ( 33 | /* 34 | * Clock: 100MHz 35 | * Reset: Push button, active low 36 | */ 37 | input wire clk, 38 | input wire reset_n, 39 | 40 | /* 41 | * GPIO 42 | */ 43 | input wire [3:0] sw, 44 | input wire [3:0] btn, 45 | output wire led0_r, 46 | output wire led0_g, 47 | output wire led0_b, 48 | output wire led1_r, 49 | output wire led1_g, 50 | output wire led1_b, 51 | output wire led2_r, 52 | output wire led2_g, 53 | output wire led2_b, 54 | output wire led3_r, 55 | output wire led3_g, 56 | output wire led3_b, 57 | output wire led4, 58 | output wire led5, 59 | output wire led6, 60 | output wire led7, 61 | 62 | /* 63 | * UART: 500000 bps, 8N1 64 | */ 65 | input wire uart_rxd, 66 | output wire uart_txd 67 | ); 68 | 69 | // Clock and reset 70 | 71 | wire clk_ibufg; 72 | wire clk_bufg; 73 | wire clk_mmcm_out; 74 | 75 | // Internal 125 MHz clock 76 | wire clk_int; 77 | wire rst_int; 78 | 79 | wire mmcm_rst = ~reset_n; 80 | wire mmcm_locked; 81 | wire mmcm_clkfb; 82 | 83 | IBUFG 84 | clk_ibufg_inst( 85 | .I(clk), 86 | .O(clk_ibufg) 87 | ); 88 | 89 | // MMCM instance 90 | // 100 MHz in, 125 MHz out 91 | // PFD range: 10 MHz to 550 MHz 92 | // VCO range: 600 MHz to 1200 MHz 93 | // M = 10, D = 1 sets Fvco = 1000 MHz (in range) 94 | // Divide by 8 to get output frequency of 125 MHz 95 | // 1000 / 5 = 200 MHz 96 | MMCME2_BASE #( 97 | .BANDWIDTH("OPTIMIZED"), 98 | .CLKOUT0_DIVIDE_F(8), 99 | .CLKOUT0_DUTY_CYCLE(0.5), 100 | .CLKOUT0_PHASE(0), 101 | .CLKOUT1_DIVIDE(1), 102 | .CLKOUT1_DUTY_CYCLE(0.5), 103 | .CLKOUT1_PHASE(0), 104 | .CLKOUT2_DIVIDE(1), 105 | .CLKOUT2_DUTY_CYCLE(0.5), 106 | .CLKOUT2_PHASE(0), 107 | .CLKOUT3_DIVIDE(1), 108 | .CLKOUT3_DUTY_CYCLE(0.5), 109 | .CLKOUT3_PHASE(0), 110 | .CLKOUT4_DIVIDE(1), 111 | .CLKOUT4_DUTY_CYCLE(0.5), 112 | .CLKOUT4_PHASE(0), 113 | .CLKOUT5_DIVIDE(1), 114 | .CLKOUT5_DUTY_CYCLE(0.5), 115 | .CLKOUT5_PHASE(0), 116 | .CLKOUT6_DIVIDE(1), 117 | .CLKOUT6_DUTY_CYCLE(0.5), 118 | .CLKOUT6_PHASE(0), 119 | .CLKFBOUT_MULT_F(10), 120 | .CLKFBOUT_PHASE(0), 121 | .DIVCLK_DIVIDE(1), 122 | .REF_JITTER1(0.010), 123 | .CLKIN1_PERIOD(10.0), 124 | .STARTUP_WAIT("FALSE"), 125 | .CLKOUT4_CASCADE("FALSE") 126 | ) 127 | clk_mmcm_inst ( 128 | .CLKIN1(clk_ibufg), 129 | .CLKFBIN(mmcm_clkfb), 130 | .RST(mmcm_rst), 131 | .PWRDWN(1'b0), 132 | .CLKOUT0(clk_mmcm_out), 133 | .CLKOUT0B(), 134 | .CLKOUT1(), 135 | .CLKOUT1B(), 136 | .CLKOUT2(), 137 | .CLKOUT2B(), 138 | .CLKOUT3(), 139 | .CLKOUT3B(), 140 | .CLKOUT4(), 141 | .CLKOUT5(), 142 | .CLKOUT6(), 143 | .CLKFBOUT(mmcm_clkfb), 144 | .CLKFBOUTB(), 145 | .LOCKED(mmcm_locked) 146 | ); 147 | 148 | BUFG 149 | clk_bufg_inst ( 150 | .I(clk_mmcm_out), 151 | .O(clk_int) 152 | ); 153 | 154 | sync_reset #( 155 | .N(4) 156 | ) 157 | sync_reset_inst ( 158 | .clk(clk_int), 159 | .rst(~mmcm_locked), 160 | .sync_reset_out(rst_int) 161 | ); 162 | 163 | // GPIO 164 | wire [3:0] btn_int; 165 | wire [3:0] sw_int; 166 | 167 | debounce_switch #( 168 | .WIDTH(8), 169 | .N(4), 170 | .RATE(125000) 171 | ) 172 | debounce_switch_inst ( 173 | .clk(clk_int), 174 | .rst(rst_int), 175 | .in({btn, 176 | sw}), 177 | .out({btn_int, 178 | sw_int}) 179 | ); 180 | 181 | sync_signal #( 182 | .WIDTH(1), 183 | .N(2) 184 | ) 185 | sync_signal_inst ( 186 | .clk(clk_int), 187 | .in({uart_rxd}), 188 | .out({uart_rxd_int}) 189 | ); 190 | 191 | fpga_core 192 | core_inst ( 193 | /* 194 | * Clock: 125MHz 195 | * Synchronous reset 196 | */ 197 | .clk(clk_int), 198 | .rst(rst_int), 199 | /* 200 | * GPIO 201 | */ 202 | .btn(btn_int), 203 | .sw(sw_int), 204 | .led0_r(led0_r), 205 | .led0_g(led0_g), 206 | .led0_b(led0_b), 207 | .led1_r(led1_r), 208 | .led1_g(led1_g), 209 | .led1_b(led1_b), 210 | .led2_r(led2_r), 211 | .led2_g(led2_g), 212 | .led2_b(led2_b), 213 | .led3_r(led3_r), 214 | .led3_g(led3_g), 215 | .led3_b(led3_b), 216 | .led4(led4), 217 | .led5(led5), 218 | .led6(led6), 219 | .led7(led7), 220 | /* 221 | * UART: 115200 bps, 8N1 222 | */ 223 | .uart_rxd(uart_rxd_int), 224 | .uart_txd(uart_txd) 225 | ); 226 | 227 | endmodule 228 | -------------------------------------------------------------------------------- /example/Arty/fpga/rtl/fpga_core.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA core logic 31 | */ 32 | module fpga_core # 33 | ( 34 | parameter TARGET = "XILINX" 35 | ) 36 | ( 37 | /* 38 | * Clock: 125MHz 39 | * Synchronous reset 40 | */ 41 | input wire clk, 42 | input wire rst, 43 | 44 | /* 45 | * GPIO 46 | */ 47 | input wire [3:0] btn, 48 | input wire [3:0] sw, 49 | output wire led0_r, 50 | output wire led0_g, 51 | output wire led0_b, 52 | output wire led1_r, 53 | output wire led1_g, 54 | output wire led1_b, 55 | output wire led2_r, 56 | output wire led2_g, 57 | output wire led2_b, 58 | output wire led3_r, 59 | output wire led3_g, 60 | output wire led3_b, 61 | output wire led4, 62 | output wire led5, 63 | output wire led6, 64 | output wire led7, 65 | 66 | /* 67 | * UART: 115200 bps, 8N1 68 | */ 69 | input wire uart_rxd, 70 | output wire uart_txd 71 | ); 72 | 73 | reg [7:0] uart_tx_axis_tdata; 74 | reg uart_tx_axis_tvalid; 75 | wire uart_tx_axis_tready; 76 | 77 | wire [7:0] uart_rx_axis_tdata; 78 | wire uart_rx_axis_tvalid; 79 | reg uart_rx_axis_tready; 80 | 81 | uart 82 | uart_inst ( 83 | .clk(clk), 84 | .rst(rst), 85 | // AXI input 86 | .s_axis_tdata(uart_tx_axis_tdata), 87 | .s_axis_tvalid(uart_tx_axis_tvalid), 88 | .s_axis_tready(uart_tx_axis_tready), 89 | // AXI output 90 | .m_axis_tdata(uart_rx_axis_tdata), 91 | .m_axis_tvalid(uart_rx_axis_tvalid), 92 | .m_axis_tready(uart_rx_axis_tready), 93 | // uart 94 | .rxd(uart_rxd), 95 | .txd(uart_txd), 96 | // status 97 | .tx_busy(), 98 | .rx_busy(), 99 | .rx_overrun_error(), 100 | .rx_frame_error(), 101 | // configuration 102 | .prescale(125000000/(9600*8)) 103 | ); 104 | 105 | //assign led = sw; 106 | assign {led7, led6, led5, led4, led3_g, led2_g, led1_g, led0_g} = uart_tx_axis_tdata; 107 | 108 | always @(posedge clk or posedge rst) begin 109 | if (rst) begin 110 | uart_tx_axis_tdata <= 0; 111 | uart_tx_axis_tvalid <= 0; 112 | uart_rx_axis_tready <= 0; 113 | end else begin 114 | if (uart_tx_axis_tvalid) begin 115 | // attempting to transmit a byte 116 | // so can't receive one at the moment 117 | uart_rx_axis_tready <= 0; 118 | // if it has been received, then clear the valid flag 119 | if (uart_tx_axis_tready) begin 120 | uart_tx_axis_tvalid <= 0; 121 | end 122 | end else begin 123 | // ready to receive byte 124 | uart_rx_axis_tready <= 1; 125 | if (uart_rx_axis_tvalid) begin 126 | // got one, so make sure it gets the correct ready signal 127 | // (either clear it if it was set or set it if we just got a 128 | // byte out of waiting for the transmitter to send one) 129 | uart_rx_axis_tready <= ~uart_rx_axis_tready; 130 | // send byte back out 131 | uart_tx_axis_tdata <= uart_rx_axis_tdata; 132 | uart_tx_axis_tvalid <= 1; 133 | end 134 | end 135 | end 136 | end 137 | 138 | endmodule 139 | -------------------------------------------------------------------------------- /example/Arty/fpga/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an active-high asynchronous reset signal to a given clock by 31 | * using a pipeline of N registers. 32 | */ 33 | module sync_reset #( 34 | parameter N=2 // depth of synchronizer 35 | )( 36 | input wire clk, 37 | input wire rst, 38 | output wire sync_reset_out 39 | ); 40 | 41 | reg [N-1:0] sync_reg = {N{1'b1}}; 42 | 43 | assign sync_reset_out = sync_reg[N-1]; 44 | 45 | always @(posedge clk or posedge rst) begin 46 | if (rst) 47 | sync_reg <= {N{1'b1}}; 48 | else 49 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /example/Arty/fpga/rtl/sync_signal.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an asyncronous signal to a given clock by using a pipeline of 31 | * two registers. 32 | */ 33 | module sync_signal #( 34 | parameter WIDTH=1, // width of the input and output signals 35 | parameter N=2 // depth of synchronizer 36 | )( 37 | input wire clk, 38 | input wire [WIDTH-1:0] in, 39 | output wire [WIDTH-1:0] out 40 | ); 41 | 42 | reg [WIDTH-1:0] sync_reg[N-1:0]; 43 | 44 | /* 45 | * The synchronized output is the last register in the pipeline. 46 | */ 47 | assign out = sync_reg[N-1]; 48 | 49 | integer k; 50 | 51 | always @(posedge clk) begin 52 | sync_reg[0] <= in; 53 | for (k = 1; k < N; k = k + 1) begin 54 | sync_reg[k] <= sync_reg[k-1]; 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /example/ML605/fpga/Makefile: -------------------------------------------------------------------------------- 1 | # Targets 2 | TARGETS:= 3 | 4 | # Subdirectories 5 | SUBDIRS = fpga 6 | SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) 7 | 8 | # Rules 9 | .PHONY: all 10 | all: $(SUBDIRS) $(TARGETS) 11 | 12 | .PHONY: $(SUBDIRS) 13 | $(SUBDIRS): 14 | cd $@ && $(MAKE) 15 | 16 | .PHONY: $(SUBDIRS_CLEAN) 17 | $(SUBDIRS_CLEAN): 18 | cd $(@:.clean=) && $(MAKE) clean 19 | 20 | .PHONY: clean 21 | clean: $(SUBDIRS_CLEAN) 22 | -rm -rf $(TARGETS) 23 | 24 | program: 25 | #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit 26 | -------------------------------------------------------------------------------- /example/ML605/fpga/common/xilinx.mk: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Author: Lane Brooks/Keith Fife 3 | # Date: 04/28/2006 4 | # License: GPL 5 | # Desc: This is a Makefile intended to take a verilog rtl design 6 | # through the Xilinx ISE tools to generate configuration files for 7 | # Xilinx FPGAs. This file is generic and just a template. As such 8 | # all design specific options such as synthesis files, fpga part type, 9 | # prom part type, etc should be set in the top Makefile prior to 10 | # including this file. Alternatively, all parameters can be passed 11 | # in from the command line as well. 12 | # 13 | ############################################################################## 14 | # 15 | # Parameter: 16 | # SYN_FILES - Space seperated list of files to be synthesized 17 | # PART - FPGA part (see Xilinx documentation) 18 | # PROM - PROM part 19 | # NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. 20 | # UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf 21 | # 22 | # 23 | # Example Calling Makefile: 24 | # 25 | # SYN_FILES = fpga.v fifo.v clks.v 26 | # PART = xc3s1000 27 | # FPGA_TOP = fpga 28 | # PROM = xc18v04 29 | # NGC_PATH = ipLib1 ipLib2 30 | # FPGA_ARCH = spartan6 31 | # SPI_PROM_SIZE = (in bytes) 32 | # include xilinx.mk 33 | ############################################################################# 34 | # 35 | # Command Line Example: 36 | # make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga 37 | # 38 | ############################################################################## 39 | # 40 | # Required Setup: 41 | # 42 | # %.ucf - user constraint file. Needed by ngdbuild 43 | # 44 | # Optional Files: 45 | # %.xcf - user constraint file. Needed by xst. 46 | # %.ut - File for pin states needed by bitgen 47 | 48 | 49 | .PHONY: clean bit prom fpga spi 50 | 51 | 52 | # Mark the intermediate files as PRECIOUS to prevent make from 53 | # deleting them (see make manual section 10.4). 54 | .PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v 55 | 56 | # include the local Makefile for project for any project specific targets 57 | CONFIG ?= config.mk 58 | -include ../$(CONFIG) 59 | 60 | SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) 61 | INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) 62 | INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) 63 | NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) 64 | 65 | ifdef UCF_FILES 66 | UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) 67 | else 68 | UCF_FILES_REL = $(FPGA_TOP).ucf 69 | endif 70 | 71 | 72 | 73 | fpga: $(FPGA_TOP).bit 74 | 75 | mcs: $(FPGA_TOP).mcs 76 | 77 | prom: $(FPGA_TOP).spi 78 | 79 | spi: $(FPGA_TOP).spi 80 | 81 | fpgasim: $(FPGA_TOP)_sim.v 82 | 83 | 84 | ########################### XST TEMPLATES ############################ 85 | # There are 2 files that XST uses for synthesis that we auto generate. 86 | # The first is a project file which is just a list of all the verilog 87 | # files. The second is the src file which passes XST all the options. 88 | # See XST user manual for XST options. 89 | %.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) 90 | rm -rf xst $*.prj $*.xst defines.v 91 | touch defines.v 92 | mkdir -p xst/tmp 93 | for x in $(DEFS); do echo '`define' $$x >> defines.v; done 94 | echo verilog work defines.v > $*.prj 95 | for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done 96 | @echo "set -tmpdir ./xst/tmp" >> $*.xst 97 | @echo "set -xsthdpdir ./xst" >> $*.xst 98 | @echo "run" >> $*.xst 99 | @echo "-ifn $*.prj" >> $*.xst 100 | @echo "-ifmt mixed" >> $*.xst 101 | @echo "-top $*" >> $*.xst 102 | @echo "-ofn $*" >> $*.xst 103 | @echo "-ofmt NGC" >> $*.xst 104 | @echo "-opt_mode Speed" >> $*.xst 105 | @echo "-opt_level 1" >> $*.xst 106 | # @echo "-verilog2001 YES" >> $*.xst 107 | @echo "-keep_hierarchy NO" >> $*.xst 108 | @echo "-p $(FPGA_PART)" >> $*.xst 109 | xst -ifn $*.xst -ofn $*.log 110 | 111 | 112 | ########################### ISE TRANSLATE ############################ 113 | # ngdbuild will automatically use a ucf called %.ucf if one is found. 114 | # We setup the dependancy such that %.ucf file is required. If any 115 | # pre-compiled ncd files are needed, set the NGC_PATH variable as a space 116 | # seperated list of directories that include the pre-compiled ngc files. 117 | %.ngd: %.ngc $(UCF_FILES_REL) 118 | ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ 119 | 120 | 121 | ########################### ISE MAP ################################### 122 | ifeq ($(FPGA_ARCH),spartan6) 123 | MAP_OPTS= -register_duplication on -timing -xe n 124 | else 125 | MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b 126 | endif 127 | 128 | %_map.ncd: %.ngd 129 | map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf 130 | 131 | # map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf 132 | 133 | 134 | ########################### ISE PnR ################################### 135 | %.ncd: %_map.ncd 136 | par -w -ol high $< $@ $*.pcf 137 | 138 | # par -w -ol std -t 1 $< $@ $*.pcf 139 | 140 | 141 | ##################### ISE Static Timing Analysis ##################### 142 | %.twr: %.ncd 143 | -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf 144 | 145 | %_sim.v: %.ncd 146 | netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ 147 | 148 | # netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v 149 | 150 | 151 | ########################### ISE Bitgen ############################# 152 | %.bit: %.twr 153 | bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit 154 | mkdir -p rev 155 | EXT=bit; COUNT=100; \ 156 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 157 | do let COUNT=COUNT+1; done; \ 158 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 159 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 160 | 161 | 162 | ########################### ISE Promgen ############################# 163 | %.mcs: %.bit 164 | promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< 165 | # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) 166 | mkdir -p rev 167 | EXT=mcs; COUNT=100; \ 168 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 169 | do let COUNT=COUNT+1; done; \ 170 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 171 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 172 | 173 | 174 | %.spi: %.mcs 175 | objcopy -I ihex -O binary $< $@ 176 | EXT=spi; COUNT=100; \ 177 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 178 | do let COUNT=COUNT+1; done; \ 179 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 180 | 181 | 182 | tmpclean: 183 | -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml 184 | 185 | clean: tmpclean 186 | -rm -rf *.bit *.mcs 187 | 188 | # clean everything 189 | distclean: clean 190 | -rm -rf rev 191 | 192 | -------------------------------------------------------------------------------- /example/ML605/fpga/fpga.ucf: -------------------------------------------------------------------------------- 1 | # User Constraints File for the Xilinx ML605 board, rev C 2 | 3 | CONFIG PART = xc6vlx130t-1ff1156; 4 | 5 | # 200MHz clock 6 | NET "sys_clk_p" LOC = "J9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0P_GC_34 (GCLK) 7 | NET "sys_clk_n" LOC = "H9" | IOSTANDARD=LVDS_25; # Bank = 34, IO_L0N_GC_34 (GCLK) 8 | NET "sys_clk_p" TNM_NET = "sys_clk_pin"; 9 | TIMESPEC "TS_sys_clk_pin" = PERIOD "sys_clk_pin" 200000 kHz; 10 | 11 | # Light Emitting Diodes 12 | NET "ledu" LOC = "AH27" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0P_23 (DS20) 13 | NET "ledl" LOC = "AD21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0N_22 (DS17) 14 | NET "ledd" LOC = "AH28" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L0N_23 (DS18) 15 | NET "ledr" LOC = "AE21" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 22, IO_L0P_22 (DS19) 16 | NET "ledc" LOC = "AP24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 23, IO_L19N_23 (DS16) 17 | 18 | NET "led<0>" LOC = "AC22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L19P_24 (DS12) 19 | NET "led<1>" LOC = "AC24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L18N_24 (DS11) 20 | NET "led<2>" LOC = "AE22" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17N_VRP_24 (DS9) 21 | NET "led<3>" LOC = "AE23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L17P_VRN_24 (DS10) 22 | NET "led<4>" LOC = "AB23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L16N_CSO_B_24 (DS15) 23 | NET "led<5>" LOC = "AG23" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L15N_RS1_24 (DS14) 24 | NET "led<6>" LOC = "AE24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11N_SRCC_24 (DS22) 25 | NET "led<7>" LOC = "AD24" | IOSTANDARD=LVCMOS25 | SLEW=QUIETIO | DRIVE=2; # Bank = 24, IO_L11P_SRCC_24 (DS21) 26 | 27 | # Reset Button: I/O Bank 2 28 | NET "reset" LOC = "H10" | IOSTANDARD=LVCMOS15; # Bank = 35, IO_L6P_SM3P_35 (SW10) 29 | 30 | # Push Buttons: I/O Bank 3 31 | NET "btnu" LOC = "A19" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15N_26 (SW5) 32 | NET "btnl" LOC = "H17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3P_36 (SW8) 33 | NET "btnd" LOC = "A18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L15P_26 (SW6) 34 | NET "btnr" LOC = "G17" | IOSTANDARD=LVCMOS15; # Bank = 36, IO_L3N_36 (SW7) 35 | NET "btnc" LOC = "G26" | IOSTANDARD=LVCMOS15; # Bank = 25, IO_L6P_25 (SW9) 36 | 37 | # Toggle Switches 38 | NET "sw<0>" LOC = "D22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19N_26 (SW1.1) 39 | NET "sw<1>" LOC = "C22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L19P_26 (SW1.2) 40 | NET "sw<2>" LOC = "L21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18N_26 (SW1.3) 41 | NET "sw<3>" LOC = "L20" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L18P_26 (SW1.4) 42 | NET "sw<4>" LOC = "C18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17N_26 (SW1.5) 43 | NET "sw<5>" LOC = "B18" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L17P_26 (SW1.6) 44 | NET "sw<6>" LOC = "K22" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16N_26 (SW1.7) 45 | NET "sw<7>" LOC = "K21" | IOSTANDARD=LVCMOS15; # Bank = 26, IO_L16P_26 (SW1.8) 46 | 47 | # Marvell M88E1111 Tri-Mode Ethernet PHY (1000BASE-T) 48 | # Interrupt, Reset, MDIO 49 | #NET "phy_int_n" LOC = "AH14" | IOSTANDARD=LVCMOS25; # (E-INT) 50 | NET "phy_reset_n" LOC = "AH13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L18P_33 (E-RESET) 51 | #NET "phy_mdc" LOC = "AP14" | IOSTANDARD=LVCMOS25; # (E-MDC) 52 | #NET "phy_mdio" LOC = "AN14" | IOSTANDARD=LVCMOS25; # (E-MDIO) 53 | # GMII Transmit 54 | NET "phy_gtx_clk" LOC = "AH12" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L16N_33 (E-GTXCLK) 55 | NET "phy_txd<0>" LOC = "AM11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7N_33 (E-TXD0) 56 | NET "phy_txd<1>" LOC = "AL11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L7P_33 (E-TXD1) 57 | NET "phy_txd<2>" LOC = "AG10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6N_33 (E-TXD2) 58 | NET "phy_txd<3>" LOC = "AG11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L6P_33 (E-TXD3) 59 | NET "phy_txd<4>" LOC = "AL10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5N_33 (E-TXD4) 60 | NET "phy_txd<5>" LOC = "AM10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L5P_33 (E-TXD5) 61 | NET "phy_txd<6>" LOC = "AE11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4N_VREF_33 (E-TXD6) 62 | NET "phy_txd<7>" LOC = "AF11" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L4P_33 (E-TXD7) 63 | NET "phy_tx_en" LOC = "AJ10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8P_SRCC_33 (E-TXEN) 64 | NET "phy_tx_er" LOC = "AH10" | IOSTANDARD=LVCMOS25 | SLEW = FAST; # Bank = 33, IO_L8N_SRCC_33 (E-TXER) 65 | # GMII Receive 66 | NET "phy_rx_clk" LOC = "AP11" | IOSTANDARD=LVCMOS25 | TNM_NET = "clk_rx_local"; # (E-RXCLK) 67 | NET "phy_rxd<0>" LOC = "AN13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15P_33 (E-RXD0) 68 | NET "phy_rxd<1>" LOC = "AF14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14N_VREF_33 (E-RXD1) 69 | NET "phy_rxd<2>" LOC = "AE14" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L14P_33 (E-RXD2) 70 | NET "phy_rxd<3>" LOC = "AN12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13N_33 (E-RXD3) 71 | NET "phy_rxd<4>" LOC = "AM12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L13P_33 (E-RXD4) 72 | NET "phy_rxd<5>" LOC = "AD11" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L10N_MRCC_33 (E-RXD5) 73 | NET "phy_rxd<6>" LOC = "AC12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9N_MRCC_33 (E-RXD6) 74 | NET "phy_rxd<7>" LOC = "AC13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L9P_MRCC_33 (E-RXD7) 75 | NET "phy_rx_dv" LOC = "AM13" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L15N_33 (E-RXDV) 76 | NET "phy_rx_er" LOC = "AG12" | IOSTANDARD=LVCMOS25; # Bank = 33, IO_L16P_33 (E-RXER) 77 | 78 | # Timing constraints for Ethernet PHY 79 | TIMESPEC "TS_rx_clk_root" = PERIOD "clk_rx_local" 8000 ps HIGH 50 %; 80 | 81 | # Silicon Labs CP2103 82 | NET "uart_rxd" LOC = "J25" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9P_MRCC_24 (U24.24) 83 | NET "uart_txd" LOC = "J24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L9N_MRCC_24 (U24.25) 84 | NET "uart_rts" LOC = "T23" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8N_SRCC_24 (U24.23) 85 | NET "uart_cts" LOC = "T24" | IOSTANDARD=LVCMOS25; # Bank = 24, IO_L8P_SRCC_24 (U24.22) 86 | -------------------------------------------------------------------------------- /example/ML605/fpga/fpga/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # FPGA settings 3 | FPGA_PART = xc6vlx130t-1ff1156 4 | FPGA_TOP = fpga 5 | FPGA_ARCH = spartan6 6 | 7 | # PROM settings 8 | #PROM = xc18v04 9 | #SPI_PROM_SIZE = (in bytes) 10 | 11 | # Files for synthesis 12 | SYN_FILES = rtl/fpga.v 13 | SYN_FILES += rtl/fpga_core.v 14 | SYN_FILES += rtl/debounce_switch.v 15 | SYN_FILES += rtl/sync_reset.v 16 | SYN_FILES += rtl/sync_signal.v 17 | SYN_FILES += lib/uart/rtl/uart.v 18 | SYN_FILES += lib/uart/rtl/uart_rx.v 19 | SYN_FILES += lib/uart/rtl/uart_tx.v 20 | 21 | # UCF files 22 | UCF_FILES = fpga.ucf 23 | 24 | # NGC paths for ngdbuild 25 | #NGC_PATHS = coregen/dcm_i100_o125 26 | 27 | # Bitgen options 28 | BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 29 | 30 | include ../common/xilinx.mk 31 | 32 | program: $(FPGA_TOP).bit 33 | echo "setmode -bscan" > program.cmd 34 | echo "setcable -p auto" >> program.cmd 35 | echo "identify" >> program.cmd 36 | echo "assignfile -p 2 -file $(FPGA_TOP).bit" >> program.cmd 37 | echo "program -p 2" >> program.cmd 38 | echo "quit" >> program.cmd 39 | impact -batch program.cmd 40 | 41 | -------------------------------------------------------------------------------- /example/ML605/fpga/lib/uart: -------------------------------------------------------------------------------- 1 | ../../../../ -------------------------------------------------------------------------------- /example/ML605/fpga/rtl/debounce_switch.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes switch and button inputs with a slow sampled shift register 31 | */ 32 | module debounce_switch #( 33 | parameter WIDTH=1, // width of the input and output signals 34 | parameter N=3, // length of shift register 35 | parameter RATE=125000 // clock division factor 36 | )( 37 | input wire clk, 38 | input wire rst, 39 | input wire [WIDTH-1:0] in, 40 | output wire [WIDTH-1:0] out 41 | ); 42 | 43 | reg [23:0] cnt_reg = 24'd0; 44 | 45 | reg [N-1:0] debounce_reg[WIDTH-1:0]; 46 | 47 | reg [WIDTH-1:0] state; 48 | 49 | /* 50 | * The synchronized output is the state register 51 | */ 52 | assign out = state; 53 | 54 | integer k; 55 | 56 | always @(posedge clk or posedge rst) begin 57 | if (rst) begin 58 | cnt_reg <= 0; 59 | state <= 0; 60 | 61 | for (k = 0; k < WIDTH; k = k + 1) begin 62 | debounce_reg[k] <= 0; 63 | end 64 | end else begin 65 | if (cnt_reg < RATE) begin 66 | cnt_reg <= cnt_reg + 24'd1; 67 | end else begin 68 | cnt_reg <= 24'd0; 69 | end 70 | 71 | if (cnt_reg == 24'd0) begin 72 | for (k = 0; k < WIDTH; k = k + 1) begin 73 | debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; 74 | end 75 | end 76 | 77 | for (k = 0; k < WIDTH; k = k + 1) begin 78 | if (|debounce_reg[k] == 0) begin 79 | state[k] <= 0; 80 | end else if (&debounce_reg[k] == 1) begin 81 | state[k] <= 1; 82 | end else begin 83 | state[k] <= state[k]; 84 | end 85 | end 86 | end 87 | end 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /example/ML605/fpga/rtl/fpga.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA top-level module 31 | */ 32 | module fpga ( 33 | /* 34 | * Clock: 200MHz 35 | * Reset: Push button, active high 36 | */ 37 | input wire sys_clk_p, 38 | input wire sys_clk_n, 39 | input wire reset, 40 | /* 41 | * GPIO 42 | */ 43 | input wire btnu, 44 | input wire btnl, 45 | input wire btnd, 46 | input wire btnr, 47 | input wire btnc, 48 | input wire [7:0] sw, 49 | output wire ledu, 50 | output wire ledl, 51 | output wire ledd, 52 | output wire ledr, 53 | output wire ledc, 54 | output wire [7:0] led, 55 | /* 56 | * Ethernet: 1000BASE-T GMII 57 | */ 58 | input wire phy_rx_clk, 59 | input wire [7:0] phy_rxd, 60 | input wire phy_rx_dv, 61 | input wire phy_rx_er, 62 | output wire phy_gtx_clk, 63 | output wire [7:0] phy_txd, 64 | output wire phy_tx_en, 65 | output wire phy_tx_er, 66 | output wire phy_reset_n, 67 | /* 68 | * Silicon Labs CP2103 USB UART 69 | */ 70 | output wire uart_rxd, 71 | input wire uart_txd, 72 | input wire uart_rts, 73 | output wire uart_cts 74 | ); 75 | 76 | // Clock and reset 77 | 78 | wire sys_clk_ibufg; 79 | wire sys_clk_bufg; 80 | wire clk_125mhz_mmcm_out; 81 | 82 | // Internal 125 MHz clock 83 | wire clk_125mhz_int; 84 | wire rst_125mhz_int; 85 | 86 | wire mmcm_rst = reset; 87 | wire mmcm_locked; 88 | wire mmcm_clkfb; 89 | 90 | IBUFGDS 91 | clk_ibufgds_inst( 92 | .I(sys_clk_p), 93 | .IB(sys_clk_n), 94 | .O(sys_clk_ibufg) 95 | ); 96 | 97 | // MMCM instance 98 | // 200 MHz in, 125 MHz out 99 | // PFD range: 10 MHz to 450 MHz 100 | // VCO range: 600 MHz to 1200 MHz 101 | // M = 5, D = 1 sets Fvco = 1000 MHz (in range) 102 | // Divide by 8 to get output frequency of 125 MHz 103 | MMCM_BASE #( 104 | .BANDWIDTH("OPTIMIZED"), 105 | .CLKOUT0_DIVIDE_F(8), 106 | .CLKOUT0_DUTY_CYCLE(0.5), 107 | .CLKOUT0_PHASE(0), 108 | .CLKOUT1_DIVIDE(1), 109 | .CLKOUT1_DUTY_CYCLE(0.5), 110 | .CLKOUT1_PHASE(0), 111 | .CLKOUT2_DIVIDE(1), 112 | .CLKOUT2_DUTY_CYCLE(0.5), 113 | .CLKOUT2_PHASE(0), 114 | .CLKOUT3_DIVIDE(1), 115 | .CLKOUT3_DUTY_CYCLE(0.5), 116 | .CLKOUT3_PHASE(0), 117 | .CLKOUT4_DIVIDE(1), 118 | .CLKOUT4_DUTY_CYCLE(0.5), 119 | .CLKOUT4_PHASE(0), 120 | .CLKOUT5_DIVIDE(1), 121 | .CLKOUT5_DUTY_CYCLE(0.5), 122 | .CLKOUT5_PHASE(0), 123 | .CLKOUT6_DIVIDE(1), 124 | .CLKOUT6_DUTY_CYCLE(0.5), 125 | .CLKOUT6_PHASE(0), 126 | .CLKFBOUT_MULT_F(5), 127 | .CLKFBOUT_PHASE(0), 128 | .DIVCLK_DIVIDE(1), 129 | .REF_JITTER1(0.100), 130 | .CLKIN1_PERIOD(5.0), 131 | .STARTUP_WAIT("FALSE"), 132 | .CLKOUT4_CASCADE("FALSE") 133 | ) 134 | clk_mmcm_inst ( 135 | .CLKIN1(sys_clk_ibufg), 136 | .CLKFBIN(mmcm_clkfb), 137 | .RST(mmcm_rst), 138 | .PWRDWN(1'b0), 139 | .CLKOUT0(clk_125mhz_mmcm_out), 140 | .CLKOUT0B(), 141 | .CLKOUT1(), 142 | .CLKOUT1B(), 143 | .CLKOUT2(), 144 | .CLKOUT2B(), 145 | .CLKOUT3(), 146 | .CLKOUT3B(), 147 | .CLKOUT4(), 148 | .CLKOUT5(), 149 | .CLKOUT6(), 150 | .CLKFBOUT(mmcm_clkfb), 151 | .CLKFBOUTB(), 152 | .LOCKED(mmcm_locked) 153 | ); 154 | 155 | BUFG 156 | clk_125mhz_bufg_inst ( 157 | .I(clk_125mhz_mmcm_out), 158 | .O(clk_125mhz_int) 159 | ); 160 | 161 | sync_reset #( 162 | .N(4) 163 | ) 164 | sync_reset_125mhz_inst ( 165 | .clk(clk_125mhz_int), 166 | .rst(~mmcm_locked), 167 | .sync_reset_out(rst_125mhz_int) 168 | ); 169 | 170 | // GPIO 171 | wire btnu_int; 172 | wire btnl_int; 173 | wire btnd_int; 174 | wire btnr_int; 175 | wire btnc_int; 176 | wire [7:0] sw_int; 177 | 178 | wire ledu_int; 179 | wire ledl_int; 180 | wire ledd_int; 181 | wire ledr_int; 182 | wire ledc_int; 183 | wire [7:0] led_int; 184 | 185 | wire uart_rxd_int; 186 | wire uart_txd_int; 187 | wire uart_rts_int; 188 | wire uart_cts_int; 189 | 190 | debounce_switch #( 191 | .WIDTH(13), 192 | .N(4), 193 | .RATE(125000) 194 | ) 195 | debounce_switch_inst ( 196 | .clk(clk_125mhz_int), 197 | .rst(rst_125mhz_int), 198 | .in({btnu, 199 | btnl, 200 | btnd, 201 | btnr, 202 | btnc, 203 | sw}), 204 | .out({btnu_int, 205 | btnl_int, 206 | btnd_int, 207 | btnr_int, 208 | btnc_int, 209 | sw_int}) 210 | ); 211 | 212 | sync_signal #( 213 | .WIDTH(2), 214 | .N(2) 215 | ) 216 | sync_signal_inst ( 217 | .clk(clk_125mhz_int), 218 | .in({uart_txd, 219 | uart_rts}), 220 | .out({uart_txd_int, 221 | uart_rts_int}) 222 | ); 223 | 224 | assign ledu = ledu_int; 225 | assign ledl = ledl_int; 226 | assign ledd = ledd_int; 227 | assign ledr = ledr_int; 228 | assign ledc = ledc_int; 229 | assign led = led_int; 230 | 231 | assign uart_rxd = uart_rxd_int; 232 | assign uart_cts = uart_cts_int; 233 | 234 | fpga_core 235 | core_inst ( 236 | /* 237 | * Clock: 125MHz 238 | * Synchronous reset 239 | */ 240 | .clk_125mhz(clk_125mhz_int), 241 | .rst_125mhz(rst_125mhz_int), 242 | /* 243 | * GPIO 244 | */ 245 | .btnu(btnu_int), 246 | .btnl(btnl_int), 247 | .btnd(btnd_int), 248 | .btnr(btnr_int), 249 | .btnc(btnc_int), 250 | .sw(sw_int), 251 | .ledu(ledu_int), 252 | .ledl(ledl_int), 253 | .ledd(ledd_int), 254 | .ledr(ledr_int), 255 | .ledc(ledc_int), 256 | .led(led_int), 257 | /* 258 | * Ethernet: 1000BASE-T GMII 259 | */ 260 | .phy_rx_clk(phy_rx_clk), 261 | .phy_rxd(phy_rxd), 262 | .phy_rx_dv(phy_rx_dv), 263 | .phy_rx_er(phy_rx_er), 264 | .phy_gtx_clk(phy_gtx_clk), 265 | .phy_txd(phy_txd), 266 | .phy_tx_en(phy_tx_en), 267 | .phy_tx_er(phy_tx_er), 268 | .phy_reset_n(phy_reset_n), 269 | /* 270 | * UART: 115200 bps, 8N1 271 | */ 272 | .uart_rxd(uart_rxd_int), 273 | .uart_txd(uart_txd_int), 274 | .uart_rts(uart_rts_int), 275 | .uart_cts(uart_cts_int) 276 | ); 277 | 278 | endmodule 279 | -------------------------------------------------------------------------------- /example/ML605/fpga/rtl/fpga_core.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA core logic 31 | */ 32 | module fpga_core ( 33 | /* 34 | * Clock: 125MHz 35 | * Synchronous reset 36 | */ 37 | input wire clk_125mhz, 38 | input wire rst_125mhz, 39 | 40 | /* 41 | * GPIO 42 | */ 43 | input wire btnu, 44 | input wire btnl, 45 | input wire btnd, 46 | input wire btnr, 47 | input wire btnc, 48 | input wire [7:0] sw, 49 | output wire ledu, 50 | output wire ledl, 51 | output wire ledd, 52 | output wire ledr, 53 | output wire ledc, 54 | output wire [7:0] led, 55 | 56 | /* 57 | * Ethernet: 1000BASE-T GMII 58 | */ 59 | input wire phy_rx_clk, 60 | input wire [7:0] phy_rxd, 61 | input wire phy_rx_dv, 62 | input wire phy_rx_er, 63 | output wire phy_gtx_clk, 64 | output wire [7:0] phy_txd, 65 | output wire phy_tx_en, 66 | output wire phy_tx_er, 67 | output wire phy_reset_n, 68 | 69 | /* 70 | * Silicon Labs CP2103 USB UART 71 | */ 72 | output wire uart_rxd, 73 | input wire uart_txd, 74 | input wire uart_rts, 75 | output wire uart_cts 76 | ); 77 | 78 | reg [7:0] uart_tx_axis_tdata; 79 | reg uart_tx_axis_tvalid; 80 | wire uart_tx_axis_tready; 81 | 82 | wire [7:0] uart_rx_axis_tdata; 83 | wire uart_rx_axis_tvalid; 84 | reg uart_rx_axis_tready; 85 | 86 | uart 87 | uart_inst ( 88 | .clk(clk_125mhz), 89 | .rst(rst_125mhz), 90 | // AXI input 91 | .s_axis_tdata(uart_tx_axis_tdata), 92 | .s_axis_tvalid(uart_tx_axis_tvalid), 93 | .s_axis_tready(uart_tx_axis_tready), 94 | // AXI output 95 | .m_axis_tdata(uart_rx_axis_tdata), 96 | .m_axis_tvalid(uart_rx_axis_tvalid), 97 | .m_axis_tready(uart_rx_axis_tready), 98 | // uart 99 | .rxd(uart_txd), 100 | .txd(uart_rxd), 101 | // status 102 | .tx_busy(), 103 | .rx_busy(), 104 | .rx_overrun_error(), 105 | .rx_frame_error(), 106 | // configuration 107 | .prescale(125000000/(9600*8)) 108 | ); 109 | 110 | //assign led = sw; 111 | assign led = uart_tx_axis_tdata; 112 | assign phy_reset_n = ~rst_125mhz; 113 | 114 | assign phy_gtx_clk = 1'b0; 115 | assign phy_txd = 8'd0; 116 | assign phy_tx_en = 1'b0; 117 | assign phy_tx_er = 1'b0; 118 | 119 | always @(posedge clk_125mhz or posedge rst_125mhz) begin 120 | if (rst_125mhz) begin 121 | uart_tx_axis_tdata <= 0; 122 | uart_tx_axis_tvalid <= 0; 123 | uart_rx_axis_tready <= 0; 124 | end else begin 125 | if (uart_tx_axis_tvalid) begin 126 | // attempting to transmit a byte 127 | // so can't receive one at the moment 128 | uart_rx_axis_tready <= 0; 129 | // if it has been received, then clear the valid flag 130 | if (uart_tx_axis_tready) begin 131 | uart_tx_axis_tvalid <= 0; 132 | end 133 | end else begin 134 | // ready to receive byte 135 | uart_rx_axis_tready <= 1; 136 | if (uart_rx_axis_tvalid) begin 137 | // got one, so make sure it gets the correct ready signal 138 | // (either clear it if it was set or set it if we just got a 139 | // byte out of waiting for the transmitter to send one) 140 | uart_rx_axis_tready <= ~uart_rx_axis_tready; 141 | // send byte back out 142 | uart_tx_axis_tdata <= uart_rx_axis_tdata; 143 | uart_tx_axis_tvalid <= 1; 144 | end 145 | end 146 | end 147 | end 148 | 149 | endmodule 150 | -------------------------------------------------------------------------------- /example/ML605/fpga/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an active-high asynchronous reset signal to a given clock by 31 | * using a pipeline of N registers. 32 | */ 33 | module sync_reset #( 34 | parameter N=2 // depth of synchronizer 35 | )( 36 | input wire clk, 37 | input wire rst, 38 | output wire sync_reset_out 39 | ); 40 | 41 | reg [N-1:0] sync_reg = {N{1'b1}}; 42 | 43 | assign sync_reset_out = sync_reg[N-1]; 44 | 45 | always @(posedge clk or posedge rst) begin 46 | if (rst) 47 | sync_reg <= {N{1'b1}}; 48 | else 49 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /example/ML605/fpga/rtl/sync_signal.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an asyncronous signal to a given clock by using a pipeline of 31 | * two registers. 32 | */ 33 | module sync_signal #( 34 | parameter WIDTH=1, // width of the input and output signals 35 | parameter N=2 // depth of synchronizer 36 | )( 37 | input wire clk, 38 | input wire [WIDTH-1:0] in, 39 | output wire [WIDTH-1:0] out 40 | ); 41 | 42 | reg [WIDTH-1:0] sync_reg[N-1:0]; 43 | 44 | /* 45 | * The synchronized output is the last register in the pipeline. 46 | */ 47 | assign out = sync_reg[N-1]; 48 | 49 | integer k; 50 | 51 | always @(posedge clk) begin 52 | sync_reg[0] <= in; 53 | for (k = 1; k < N; k = k + 1) begin 54 | sync_reg[k] <= sync_reg[k-1]; 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/Makefile: -------------------------------------------------------------------------------- 1 | # Targets 2 | TARGETS:= 3 | 4 | # Subdirectories 5 | SUBDIRS = fpga 6 | SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) 7 | 8 | # Rules 9 | .PHONY: all 10 | all: $(SUBDIRS) $(TARGETS) 11 | 12 | .PHONY: $(SUBDIRS) 13 | $(SUBDIRS): 14 | cd $@ && $(MAKE) 15 | 16 | .PHONY: $(SUBDIRS_CLEAN) 17 | $(SUBDIRS_CLEAN): 18 | cd $(@:.clean=) && $(MAKE) clean 19 | 20 | .PHONY: clean 21 | clean: $(SUBDIRS_CLEAN) 22 | -rm -rf $(TARGETS) 23 | 24 | program: 25 | #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit 26 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/common/vivado.mk: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | # 3 | # Xilinx Vivado FPGA Makefile 4 | # 5 | # Copyright (c) 2016 Alex Forencich 6 | # 7 | ################################################################### 8 | # 9 | # Parameters: 10 | # FPGA_TOP - Top module name 11 | # FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) 12 | # FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) 13 | # SYN_FILES - space-separated list of source files 14 | # INC_FILES - space-separated list of include files 15 | # XDC_FILES - space-separated list of timing constraint files 16 | # XCI_FILES - space-separated list of IP XCI files 17 | # 18 | # Example: 19 | # 20 | # FPGA_TOP = fpga 21 | # FPGA_FAMILY = VirtexUltrascale 22 | # FPGA_DEVICE = xcvu095-ffva2104-2-e 23 | # SYN_FILES = rtl/fpga.v 24 | # XDC_FILES = fpga.xdc 25 | # XCI_FILES = ip/pcspma.xci 26 | # include ../common/vivado.mk 27 | # 28 | ################################################################### 29 | 30 | # phony targets 31 | .PHONY: clean fpga 32 | 33 | # prevent make from deleting intermediate files and reports 34 | .PRECIOUS: %.xpr %.bit 35 | .SECONDARY: 36 | 37 | CONFIG ?= config.mk 38 | -include ../$(CONFIG) 39 | 40 | SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) 41 | INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) 42 | XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) 43 | 44 | ifdef XDC_FILES 45 | XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) 46 | else 47 | XDC_FILES_REL = $(FPGA_TOP).xdc 48 | endif 49 | 50 | ################################################################### 51 | # Main Targets 52 | # 53 | # all: build everything 54 | # clean: remove output files and project files 55 | ################################################################### 56 | 57 | all: fpga 58 | 59 | fpga: $(FPGA_TOP).bit 60 | 61 | tmpclean: 62 | -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v 63 | -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl 64 | 65 | clean: tmpclean 66 | -rm -rf *.bit program.tcl 67 | 68 | distclean: clean 69 | -rm -rf rev 70 | 71 | ################################################################### 72 | # Target implementations 73 | ################################################################### 74 | 75 | # Vivado project file 76 | %.xpr: Makefile $(XCI_FILES_REL) 77 | rm -rf defines.v 78 | touch defines.v 79 | for x in $(DEFS); do echo '`define' $$x >> defines.v; done 80 | echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl 81 | echo "add_files -fileset sources_1 defines.v" >> create_project.tcl 82 | for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done 83 | for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done 84 | for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done 85 | echo "exit" >> create_project.tcl 86 | vivado -mode batch -source create_project.tcl 87 | 88 | # synthesis run 89 | %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) 90 | echo "open_project $*.xpr" > run_synth.tcl 91 | echo "reset_run synth_1" >> run_synth.tcl 92 | echo "launch_runs synth_1" >> run_synth.tcl 93 | echo "wait_on_run synth_1" >> run_synth.tcl 94 | echo "exit" >> run_synth.tcl 95 | vivado -mode batch -source run_synth.tcl 96 | 97 | # implementation run 98 | %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp 99 | echo "open_project $*.xpr" > run_impl.tcl 100 | echo "reset_run impl_1" >> run_impl.tcl 101 | echo "launch_runs impl_1" >> run_impl.tcl 102 | echo "wait_on_run impl_1" >> run_impl.tcl 103 | echo "exit" >> run_impl.tcl 104 | vivado -mode batch -source run_impl.tcl 105 | 106 | # bit file 107 | %.bit: %.runs/impl_1/%_routed.dcp 108 | echo "open_project $*.xpr" > generate_bit.tcl 109 | echo "open_run impl_1" >> generate_bit.tcl 110 | echo "write_bitstream -force $*.bit" >> generate_bit.tcl 111 | echo "exit" >> generate_bit.tcl 112 | vivado -mode batch -source generate_bit.tcl 113 | mkdir -p rev 114 | EXT=bit; COUNT=100; \ 115 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 116 | do let COUNT=COUNT+1; done; \ 117 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 118 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 119 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/fpga.xdc: -------------------------------------------------------------------------------- 1 | # XDC constraints for the Digilent Nexys Video board 2 | # part: xc7a200tsbg484-1 3 | 4 | # General configuration 5 | set_property CFGBVS VCCO [current_design] 6 | set_property CONFIG_VOLTAGE 3.3 [current_design] 7 | 8 | # 100 MHz clock 9 | set_property -dict {LOC R4 IOSTANDARD LVCMOS33} [get_ports clk] 10 | create_clock -name clk -period 10.000 [get_ports clk] 11 | 12 | # LEDs 13 | set_property -dict {LOC T14 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[0]] 14 | set_property -dict {LOC T15 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[1]] 15 | set_property -dict {LOC T16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[2]] 16 | set_property -dict {LOC U16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[3]] 17 | set_property -dict {LOC V15 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[4]] 18 | set_property -dict {LOC W16 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[5]] 19 | set_property -dict {LOC W15 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[6]] 20 | set_property -dict {LOC Y13 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports led[7]] 21 | 22 | # Reset button 23 | set_property -dict {LOC G4 IOSTANDARD LVCMOS15} [get_ports reset_n] 24 | 25 | # Push buttons 26 | set_property -dict {LOC F15 IOSTANDARD LVCMOS12} [get_ports btnu] 27 | set_property -dict {LOC C22 IOSTANDARD LVCMOS12} [get_ports btnl] 28 | set_property -dict {LOC D22 IOSTANDARD LVCMOS12} [get_ports btnd] 29 | set_property -dict {LOC D14 IOSTANDARD LVCMOS12} [get_ports btnr] 30 | set_property -dict {LOC B22 IOSTANDARD LVCMOS12} [get_ports btnc] 31 | 32 | # Toggle switches 33 | set_property -dict {LOC E22 IOSTANDARD LVCMOS12} [get_ports sw[0]] 34 | set_property -dict {LOC F21 IOSTANDARD LVCMOS12} [get_ports sw[1]] 35 | set_property -dict {LOC G21 IOSTANDARD LVCMOS12} [get_ports sw[2]] 36 | set_property -dict {LOC G22 IOSTANDARD LVCMOS12} [get_ports sw[3]] 37 | set_property -dict {LOC H17 IOSTANDARD LVCMOS12} [get_ports sw[4]] 38 | set_property -dict {LOC J16 IOSTANDARD LVCMOS12} [get_ports sw[5]] 39 | set_property -dict {LOC K13 IOSTANDARD LVCMOS12} [get_ports sw[6]] 40 | set_property -dict {LOC M17 IOSTANDARD LVCMOS12} [get_ports sw[7]] 41 | 42 | # UART 43 | set_property -dict {LOC AA19 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports uart_txd] 44 | set_property -dict {LOC V18 IOSTANDARD LVCMOS33} [get_ports uart_rxd] 45 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/fpga/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # FPGA settings 3 | FPGA_PART = xc7a200t-sbg484-1 4 | FPGA_TOP = fpga 5 | FPGA_ARCH = artix7 6 | 7 | # Files for synthesis 8 | SYN_FILES = rtl/fpga.v 9 | SYN_FILES += rtl/fpga_core.v 10 | SYN_FILES += rtl/debounce_switch.v 11 | SYN_FILES += rtl/sync_reset.v 12 | SYN_FILES += rtl/sync_signal.v 13 | SYN_FILES += lib/uart/rtl/uart.v 14 | SYN_FILES += lib/uart/rtl/uart_rx.v 15 | SYN_FILES += lib/uart/rtl/uart_tx.v 16 | 17 | # XDC files 18 | XDC_FILES = fpga.xdc 19 | 20 | include ../common/vivado.mk 21 | 22 | program: $(FPGA_TOP).bit 23 | djtgcfg prog -d NexysVideo --index 0 --file $(FPGA_TOP).bit 24 | 25 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/lib/uart: -------------------------------------------------------------------------------- 1 | ../../../../ -------------------------------------------------------------------------------- /example/NexysVideo/fpga/rtl/debounce_switch.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes switch and button inputs with a slow sampled shift register 31 | */ 32 | module debounce_switch #( 33 | parameter WIDTH=1, // width of the input and output signals 34 | parameter N=3, // length of shift register 35 | parameter RATE=125000 // clock division factor 36 | )( 37 | input wire clk, 38 | input wire rst, 39 | input wire [WIDTH-1:0] in, 40 | output wire [WIDTH-1:0] out 41 | ); 42 | 43 | reg [23:0] cnt_reg = 24'd0; 44 | 45 | reg [N-1:0] debounce_reg[WIDTH-1:0]; 46 | 47 | reg [WIDTH-1:0] state; 48 | 49 | /* 50 | * The synchronized output is the state register 51 | */ 52 | assign out = state; 53 | 54 | integer k; 55 | 56 | always @(posedge clk or posedge rst) begin 57 | if (rst) begin 58 | cnt_reg <= 0; 59 | state <= 0; 60 | 61 | for (k = 0; k < WIDTH; k = k + 1) begin 62 | debounce_reg[k] <= 0; 63 | end 64 | end else begin 65 | if (cnt_reg < RATE) begin 66 | cnt_reg <= cnt_reg + 24'd1; 67 | end else begin 68 | cnt_reg <= 24'd0; 69 | end 70 | 71 | if (cnt_reg == 24'd0) begin 72 | for (k = 0; k < WIDTH; k = k + 1) begin 73 | debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; 74 | end 75 | end 76 | 77 | for (k = 0; k < WIDTH; k = k + 1) begin 78 | if (|debounce_reg[k] == 0) begin 79 | state[k] <= 0; 80 | end else if (&debounce_reg[k] == 1) begin 81 | state[k] <= 1; 82 | end else begin 83 | state[k] <= state[k]; 84 | end 85 | end 86 | end 87 | end 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/rtl/fpga.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA top-level module 31 | */ 32 | module fpga ( 33 | /* 34 | * Clock: 100MHz 35 | * Reset: Push button, active low 36 | */ 37 | input wire clk, 38 | input wire reset_n, 39 | /* 40 | * GPIO 41 | */ 42 | input wire btnu, 43 | input wire btnl, 44 | input wire btnd, 45 | input wire btnr, 46 | input wire btnc, 47 | input wire [7:0] sw, 48 | output wire [7:0] led, 49 | /* 50 | * UART: 9600 bps, 8N1 51 | */ 52 | input wire uart_rxd, 53 | output wire uart_txd 54 | ); 55 | 56 | // Clock and reset 57 | 58 | wire clk_ibufg; 59 | wire clk_bufg; 60 | wire clk_mmcm_out; 61 | 62 | // Internal 125 MHz clock 63 | wire clk_int; 64 | wire rst_int; 65 | 66 | wire mmcm_rst = ~reset_n; 67 | wire mmcm_locked; 68 | wire mmcm_clkfb; 69 | 70 | IBUFG 71 | clk_ibufg_inst( 72 | .I(clk), 73 | .O(clk_ibufg) 74 | ); 75 | 76 | // MMCM instance 77 | // 100 MHz in, 125 MHz out 78 | // PFD range: 10 MHz to 550 MHz 79 | // VCO range: 600 MHz to 1200 MHz 80 | // M = 10, D = 1 sets Fvco = 1000 MHz (in range) 81 | // Divide by 8 to get output frequency of 125 MHz 82 | MMCME2_BASE #( 83 | .BANDWIDTH("OPTIMIZED"), 84 | .CLKOUT0_DIVIDE_F(8), 85 | .CLKOUT0_DUTY_CYCLE(0.5), 86 | .CLKOUT0_PHASE(0), 87 | .CLKOUT1_DIVIDE(1), 88 | .CLKOUT1_DUTY_CYCLE(0.5), 89 | .CLKOUT1_PHASE(0), 90 | .CLKOUT2_DIVIDE(5), 91 | .CLKOUT2_DUTY_CYCLE(0.5), 92 | .CLKOUT2_PHASE(0), 93 | .CLKOUT3_DIVIDE(1), 94 | .CLKOUT3_DUTY_CYCLE(0.5), 95 | .CLKOUT3_PHASE(0), 96 | .CLKOUT4_DIVIDE(1), 97 | .CLKOUT4_DUTY_CYCLE(0.5), 98 | .CLKOUT4_PHASE(0), 99 | .CLKOUT5_DIVIDE(1), 100 | .CLKOUT5_DUTY_CYCLE(0.5), 101 | .CLKOUT5_PHASE(0), 102 | .CLKOUT6_DIVIDE(1), 103 | .CLKOUT6_DUTY_CYCLE(0.5), 104 | .CLKOUT6_PHASE(0), 105 | .CLKFBOUT_MULT_F(10), 106 | .CLKFBOUT_PHASE(0), 107 | .DIVCLK_DIVIDE(1), 108 | .REF_JITTER1(0.010), 109 | .CLKIN1_PERIOD(10.0), 110 | .STARTUP_WAIT("FALSE"), 111 | .CLKOUT4_CASCADE("FALSE") 112 | ) 113 | clk_mmcm_inst ( 114 | .CLKIN1(clk_ibufg), 115 | .CLKFBIN(mmcm_clkfb), 116 | .RST(mmcm_rst), 117 | .PWRDWN(1'b0), 118 | .CLKOUT0(clk_mmcm_out), 119 | .CLKOUT0B(), 120 | .CLKOUT1(), 121 | .CLKOUT1B(), 122 | .CLKOUT2(), 123 | .CLKOUT2B(), 124 | .CLKOUT3(), 125 | .CLKOUT3B(), 126 | .CLKOUT4(), 127 | .CLKOUT5(), 128 | .CLKOUT6(), 129 | .CLKFBOUT(mmcm_clkfb), 130 | .CLKFBOUTB(), 131 | .LOCKED(mmcm_locked) 132 | ); 133 | 134 | BUFG 135 | clk_bufg_inst ( 136 | .I(clk_mmcm_out), 137 | .O(clk_int) 138 | ); 139 | 140 | sync_reset #( 141 | .N(4) 142 | ) 143 | sync_reset_inst ( 144 | .clk(clk_int), 145 | .rst(~mmcm_locked), 146 | .sync_reset_out(rst_int) 147 | ); 148 | 149 | // GPIO 150 | wire btnu_int; 151 | wire btnl_int; 152 | wire btnd_int; 153 | wire btnr_int; 154 | wire btnc_int; 155 | wire [7:0] sw_int; 156 | 157 | debounce_switch #( 158 | .WIDTH(13), 159 | .N(4), 160 | .RATE(125000) 161 | ) 162 | debounce_switch_inst ( 163 | .clk(clk_int), 164 | .rst(rst_int), 165 | .in({btnu, 166 | btnl, 167 | btnd, 168 | btnr, 169 | btnc, 170 | sw}), 171 | .out({btnu_int, 172 | btnl_int, 173 | btnd_int, 174 | btnr_int, 175 | btnc_int, 176 | sw_int}) 177 | ); 178 | 179 | sync_signal #( 180 | .WIDTH(1), 181 | .N(2) 182 | ) 183 | sync_signal_inst ( 184 | .clk(clk_int), 185 | .in({uart_rxd}), 186 | .out({uart_rxd_int}) 187 | ); 188 | 189 | fpga_core 190 | core_inst ( 191 | /* 192 | * Clock: 125MHz 193 | * Synchronous reset 194 | */ 195 | .clk(clk_int), 196 | .rst(rst_int), 197 | /* 198 | * GPIO 199 | */ 200 | .btnu(btnu_int), 201 | .btnl(btnl_int), 202 | .btnd(btnd_int), 203 | .btnr(btnr_int), 204 | .btnc(btnc_int), 205 | .sw(sw_int), 206 | .led(led), 207 | /* 208 | * UART: 9600 bps, 8N1 209 | */ 210 | .uart_rxd(uart_rxd_int), 211 | .uart_txd(uart_txd) 212 | ); 213 | 214 | endmodule 215 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/rtl/fpga_core.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | module fpga_core ( 30 | /* 31 | * Clock: 125MHz 32 | * Synchronous reset 33 | */ 34 | input wire clk, 35 | input wire rst, 36 | /* 37 | * GPIO 38 | */ 39 | input wire btnu, 40 | input wire btnl, 41 | input wire btnd, 42 | input wire btnr, 43 | input wire btnc, 44 | input wire [7:0] sw, 45 | output wire [7:0] led, 46 | /* 47 | * UART: 9600 bps, 8N1 48 | */ 49 | input wire uart_rxd, 50 | output wire uart_txd 51 | ); 52 | 53 | reg [7:0] uart_tx_axis_tdata; 54 | reg uart_tx_axis_tvalid; 55 | wire uart_tx_axis_tready; 56 | 57 | wire [7:0] uart_rx_axis_tdata; 58 | wire uart_rx_axis_tvalid; 59 | reg uart_rx_axis_tready; 60 | 61 | uart 62 | uart_inst ( 63 | .clk(clk), 64 | .rst(rst), 65 | // AXI input 66 | .s_axis_tdata(uart_tx_axis_tdata), 67 | .s_axis_tvalid(uart_tx_axis_tvalid), 68 | .s_axis_tready(uart_tx_axis_tready), 69 | // AXI output 70 | .m_axis_tdata(uart_rx_axis_tdata), 71 | .m_axis_tvalid(uart_rx_axis_tvalid), 72 | .m_axis_tready(uart_rx_axis_tready), 73 | // uart 74 | .rxd(uart_rxd), 75 | .txd(uart_txd), 76 | // status 77 | .tx_busy(), 78 | .rx_busy(), 79 | .rx_overrun_error(), 80 | .rx_frame_error(), 81 | // configuration 82 | .prescale(125000000/(9600*8)) 83 | ); 84 | 85 | //assign led = sw; 86 | assign led = uart_tx_axis_tdata; 87 | 88 | always @(posedge clk or posedge rst) begin 89 | if (rst) begin 90 | uart_tx_axis_tdata <= 0; 91 | uart_tx_axis_tvalid <= 0; 92 | uart_rx_axis_tready <= 0; 93 | end else begin 94 | if (uart_tx_axis_tvalid) begin 95 | // attempting to transmit a byte 96 | // so can't receive one at the moment 97 | uart_rx_axis_tready <= 0; 98 | // if it has been received, then clear the valid flag 99 | if (uart_tx_axis_tready) begin 100 | uart_tx_axis_tvalid <= 0; 101 | end 102 | end else begin 103 | // ready to receive byte 104 | uart_rx_axis_tready <= 1; 105 | if (uart_rx_axis_tvalid) begin 106 | // got one, so make sure it gets the correct ready signal 107 | // (either clear it if it was set or set it if we just got a 108 | // byte out of waiting for the transmitter to send one) 109 | uart_rx_axis_tready <= ~uart_rx_axis_tready; 110 | // send byte back out 111 | uart_tx_axis_tdata <= uart_rx_axis_tdata; 112 | uart_tx_axis_tvalid <= 1; 113 | end 114 | end 115 | end 116 | end 117 | 118 | endmodule 119 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an active-high asynchronous reset signal to a given clock by 31 | * using a pipeline of N registers. 32 | */ 33 | module sync_reset #( 34 | parameter N=2 // depth of synchronizer 35 | )( 36 | input wire clk, 37 | input wire rst, 38 | output wire sync_reset_out 39 | ); 40 | 41 | reg [N-1:0] sync_reg = {N{1'b1}}; 42 | 43 | assign sync_reset_out = sync_reg[N-1]; 44 | 45 | always @(posedge clk or posedge rst) begin 46 | if (rst) 47 | sync_reg <= {N{1'b1}}; 48 | else 49 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /example/NexysVideo/fpga/rtl/sync_signal.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an asyncronous signal to a given clock by using a pipeline of 31 | * two registers. 32 | */ 33 | module sync_signal #( 34 | parameter WIDTH=1, // width of the input and output signals 35 | parameter N=2 // depth of synchronizer 36 | )( 37 | input wire clk, 38 | input wire [WIDTH-1:0] in, 39 | output wire [WIDTH-1:0] out 40 | ); 41 | 42 | reg [WIDTH-1:0] sync_reg[N-1:0]; 43 | 44 | /* 45 | * The synchronized output is the last register in the pipeline. 46 | */ 47 | assign out = sync_reg[N-1]; 48 | 49 | integer k; 50 | 51 | always @(posedge clk) begin 52 | sync_reg[0] <= in; 53 | for (k = 1; k < N; k = k + 1) begin 54 | sync_reg[k] <= sync_reg[k-1]; 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /example/VCU108/fpga/Makefile: -------------------------------------------------------------------------------- 1 | # Targets 2 | TARGETS:= 3 | 4 | # Subdirectories 5 | SUBDIRS = fpga 6 | SUBDIRS_CLEAN = $(patsubst %,%.clean,$(SUBDIRS)) 7 | 8 | # Rules 9 | .PHONY: all 10 | all: $(SUBDIRS) $(TARGETS) 11 | 12 | .PHONY: $(SUBDIRS) 13 | $(SUBDIRS): 14 | cd $@ && $(MAKE) 15 | 16 | .PHONY: $(SUBDIRS_CLEAN) 17 | $(SUBDIRS_CLEAN): 18 | cd $(@:.clean=) && $(MAKE) clean 19 | 20 | .PHONY: clean 21 | clean: $(SUBDIRS_CLEAN) 22 | -rm -rf $(TARGETS) 23 | 24 | program: 25 | #djtgcfg prog -d Atlys --index 0 --file fpga/fpga.bit 26 | -------------------------------------------------------------------------------- /example/VCU108/fpga/common/vivado.mk: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | # 3 | # Xilinx Vivado FPGA Makefile 4 | # 5 | # Copyright (c) 2016 Alex Forencich 6 | # 7 | ################################################################### 8 | # 9 | # Parameters: 10 | # FPGA_TOP - Top module name 11 | # FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale) 12 | # FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e) 13 | # SYN_FILES - space-separated list of source files 14 | # INC_FILES - space-separated list of include files 15 | # XDC_FILES - space-separated list of timing constraint files 16 | # XCI_FILES - space-separated list of IP XCI files 17 | # 18 | # Example: 19 | # 20 | # FPGA_TOP = fpga 21 | # FPGA_FAMILY = VirtexUltrascale 22 | # FPGA_DEVICE = xcvu095-ffva2104-2-e 23 | # SYN_FILES = rtl/fpga.v 24 | # XDC_FILES = fpga.xdc 25 | # XCI_FILES = ip/pcspma.xci 26 | # include ../common/vivado.mk 27 | # 28 | ################################################################### 29 | 30 | # phony targets 31 | .PHONY: clean fpga 32 | 33 | # prevent make from deleting intermediate files and reports 34 | .PRECIOUS: %.xpr %.bit 35 | .SECONDARY: 36 | 37 | CONFIG ?= config.mk 38 | -include ../$(CONFIG) 39 | 40 | SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) 41 | INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) 42 | XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) 43 | 44 | ifdef XDC_FILES 45 | XDC_FILES_REL = $(patsubst %, ../%, $(XDC_FILES)) 46 | else 47 | XDC_FILES_REL = $(FPGA_TOP).xdc 48 | endif 49 | 50 | ################################################################### 51 | # Main Targets 52 | # 53 | # all: build everything 54 | # clean: remove output files and project files 55 | ################################################################### 56 | 57 | all: fpga 58 | 59 | fpga: $(FPGA_TOP).bit 60 | 61 | tmpclean: 62 | -rm -rf *.log *.jou *.cache *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v 63 | -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl 64 | 65 | clean: tmpclean 66 | -rm -rf *.bit program.tcl 67 | 68 | distclean: clean 69 | -rm -rf rev 70 | 71 | ################################################################### 72 | # Target implementations 73 | ################################################################### 74 | 75 | # Vivado project file 76 | %.xpr: Makefile $(XCI_FILES_REL) 77 | rm -rf defines.v 78 | touch defines.v 79 | for x in $(DEFS); do echo '`define' $$x >> defines.v; done 80 | echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl 81 | echo "add_files -fileset sources_1 defines.v" >> create_project.tcl 82 | for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done 83 | for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done 84 | for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done 85 | echo "exit" >> create_project.tcl 86 | vivado -mode batch -source create_project.tcl 87 | 88 | # synthesis run 89 | %.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) 90 | echo "open_project $*.xpr" > run_synth.tcl 91 | echo "reset_run synth_1" >> run_synth.tcl 92 | echo "launch_runs synth_1" >> run_synth.tcl 93 | echo "wait_on_run synth_1" >> run_synth.tcl 94 | echo "exit" >> run_synth.tcl 95 | vivado -mode batch -source run_synth.tcl 96 | 97 | # implementation run 98 | %.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp 99 | echo "open_project $*.xpr" > run_impl.tcl 100 | echo "reset_run impl_1" >> run_impl.tcl 101 | echo "launch_runs impl_1" >> run_impl.tcl 102 | echo "wait_on_run impl_1" >> run_impl.tcl 103 | echo "exit" >> run_impl.tcl 104 | vivado -mode batch -source run_impl.tcl 105 | 106 | # bit file 107 | %.bit: %.runs/impl_1/%_routed.dcp 108 | echo "open_project $*.xpr" > generate_bit.tcl 109 | echo "open_run impl_1" >> generate_bit.tcl 110 | echo "write_bitstream -force $*.bit" >> generate_bit.tcl 111 | echo "exit" >> generate_bit.tcl 112 | vivado -mode batch -source generate_bit.tcl 113 | mkdir -p rev 114 | EXT=bit; COUNT=100; \ 115 | while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ 116 | do let COUNT=COUNT+1; done; \ 117 | cp $@ rev/$*_rev$$COUNT.$$EXT; \ 118 | echo "Output: rev/$*_rev$$COUNT.$$EXT"; 119 | -------------------------------------------------------------------------------- /example/VCU108/fpga/fpga.xdc: -------------------------------------------------------------------------------- 1 | # XDC constraints for the Xilinx VCU108 board 2 | # part: xcvu095-ffva2104-2-e 3 | 4 | # General configuration 5 | set_property CFGBVS GND [current_design] 6 | set_property CONFIG_VOLTAGE 1.8 [current_design] 7 | 8 | # System clocks 9 | # 300 MHz 10 | #set_property -dict {LOC G31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_p] 11 | #set_property -dict {LOC F31 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_1_n] 12 | #create_clock -period 3.333 -name clk_300_mhz_1 [get_ports clk_300mhz_1_p] 13 | #set_clock_groups -asynchronous -group clk_300mhz_1 14 | 15 | #set_property -dict {LOC G22 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_p] 16 | #set_property -dict {LOC G21 IOSTANDARD DIFF_SSTL12} [get_ports clk_300mhz_2_n] 17 | #create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p] 18 | #set_clock_groups -asynchronous -group clk_300mhz_2 19 | 20 | # 125 MHz 21 | set_property -dict {LOC BC9 IOSTANDARD LVDS} [get_ports clk_125mhz_p] 22 | set_property -dict {LOC BC8 IOSTANDARD LVDS} [get_ports clk_125mhz_n] 23 | create_clock -period 8.000 -name clk_125mhz [get_ports clk_125mhz_p] 24 | set_clock_groups -asynchronous -group clk_125mhz 25 | 26 | # 90 MHz 27 | #set_property -dict {LOC AL20 IOSTANDARD LVCMOS18} [get_ports clk_90mhz] 28 | #create_clock -period 11.111 -name clk_90mhz [get_ports clk_90mhz] 29 | #set_clock_groups -asynchronous -group clk_90mhz 30 | 31 | # LEDs 32 | set_property -dict {LOC AT32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}] 33 | set_property -dict {LOC AV34 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}] 34 | set_property -dict {LOC AY30 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}] 35 | set_property -dict {LOC BB32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[3]}] 36 | set_property -dict {LOC BF32 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[4]}] 37 | set_property -dict {LOC AV36 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[5]}] 38 | set_property -dict {LOC AY35 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[6]}] 39 | set_property -dict {LOC BA37 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[7]}] 40 | 41 | # Reset button 42 | set_property -dict {LOC E36 IOSTANDARD LVCMOS12} [get_ports reset] 43 | 44 | # Push buttons 45 | set_property -dict {LOC E34 IOSTANDARD LVCMOS12} [get_ports btnu] 46 | set_property -dict {LOC M22 IOSTANDARD LVCMOS12} [get_ports btnl] 47 | set_property -dict {LOC D9 IOSTANDARD LVCMOS12} [get_ports btnd] 48 | set_property -dict {LOC A10 IOSTANDARD LVCMOS12} [get_ports btnr] 49 | set_property -dict {LOC AW27 IOSTANDARD LVCMOS12} [get_ports btnc] 50 | 51 | # DIP switches 52 | set_property -dict {LOC BC40 IOSTANDARD LVCMOS12} [get_ports {sw[0]}] 53 | set_property -dict {LOC L19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}] 54 | set_property -dict {LOC C37 IOSTANDARD LVCMOS12} [get_ports {sw[2]}] 55 | set_property -dict {LOC C38 IOSTANDARD LVCMOS12} [get_ports {sw[3]}] 56 | 57 | # UART 58 | set_property -dict {LOC BE24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] 59 | set_property -dict {LOC BC24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] 60 | set_property -dict {LOC BF24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_rts] 61 | set_property -dict {LOC BD22 IOSTANDARD LVCMOS18} [get_ports uart_cts] 62 | -------------------------------------------------------------------------------- /example/VCU108/fpga/fpga/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # FPGA settings 3 | FPGA_PART = xcvu095-ffva2104-2-e 4 | FPGA_TOP = fpga 5 | FPGA_ARCH = VirtexUltrascale 6 | 7 | # Files for synthesis 8 | SYN_FILES = rtl/fpga.v 9 | SYN_FILES += rtl/fpga_core.v 10 | SYN_FILES += rtl/debounce_switch.v 11 | SYN_FILES += rtl/sync_reset.v 12 | SYN_FILES += rtl/sync_signal.v 13 | SYN_FILES += lib/uart/rtl/uart.v 14 | SYN_FILES += lib/uart/rtl/uart_rx.v 15 | SYN_FILES += lib/uart/rtl/uart_tx.v 16 | 17 | # XDC files 18 | XDC_FILES = fpga.xdc 19 | 20 | include ../common/vivado.mk 21 | 22 | program: $(FPGA_TOP).bit 23 | echo "open_hw" > program.tcl 24 | echo "connect_hw_server" >> program.tcl 25 | echo "open_hw_target" >> program.tcl 26 | echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl 27 | echo "refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]" >> program.tcl 28 | echo "set_property PROGRAM.FILE {$(FPGA_TOP).bit} [lindex [get_hw_devices] 0]" >> program.tcl 29 | echo "program_hw_devices [lindex [get_hw_devices] 0]" >> program.tcl 30 | echo "exit" >> program.tcl 31 | vivado -mode batch -source program.tcl 32 | 33 | -------------------------------------------------------------------------------- /example/VCU108/fpga/lib/uart: -------------------------------------------------------------------------------- 1 | ../../../../ -------------------------------------------------------------------------------- /example/VCU108/fpga/rtl/debounce_switch.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes switch and button inputs with a slow sampled shift register 31 | */ 32 | module debounce_switch #( 33 | parameter WIDTH=1, // width of the input and output signals 34 | parameter N=3, // length of shift register 35 | parameter RATE=125000 // clock division factor 36 | )( 37 | input wire clk, 38 | input wire rst, 39 | input wire [WIDTH-1:0] in, 40 | output wire [WIDTH-1:0] out 41 | ); 42 | 43 | reg [23:0] cnt_reg = 24'd0; 44 | 45 | reg [N-1:0] debounce_reg[WIDTH-1:0]; 46 | 47 | reg [WIDTH-1:0] state; 48 | 49 | /* 50 | * The synchronized output is the state register 51 | */ 52 | assign out = state; 53 | 54 | integer k; 55 | 56 | always @(posedge clk or posedge rst) begin 57 | if (rst) begin 58 | cnt_reg <= 0; 59 | state <= 0; 60 | 61 | for (k = 0; k < WIDTH; k = k + 1) begin 62 | debounce_reg[k] <= 0; 63 | end 64 | end else begin 65 | if (cnt_reg < RATE) begin 66 | cnt_reg <= cnt_reg + 24'd1; 67 | end else begin 68 | cnt_reg <= 24'd0; 69 | end 70 | 71 | if (cnt_reg == 24'd0) begin 72 | for (k = 0; k < WIDTH; k = k + 1) begin 73 | debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; 74 | end 75 | end 76 | 77 | for (k = 0; k < WIDTH; k = k + 1) begin 78 | if (|debounce_reg[k] == 0) begin 79 | state[k] <= 0; 80 | end else if (&debounce_reg[k] == 1) begin 81 | state[k] <= 1; 82 | end else begin 83 | state[k] <= state[k]; 84 | end 85 | end 86 | end 87 | end 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /example/VCU108/fpga/rtl/fpga.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * FPGA top-level module 31 | */ 32 | module fpga ( 33 | /* 34 | * Clock: 125MHz LVDS 35 | * Reset: Push button, active low 36 | */ 37 | input wire clk_125mhz_p, 38 | input wire clk_125mhz_n, 39 | input wire reset, 40 | 41 | /* 42 | * GPIO 43 | */ 44 | input wire btnu, 45 | input wire btnl, 46 | input wire btnd, 47 | input wire btnr, 48 | input wire btnc, 49 | input wire [3:0] sw, 50 | output wire [7:0] led, 51 | 52 | /* 53 | * UART: 500000 bps, 8N1 54 | */ 55 | input wire uart_rxd, 56 | output wire uart_txd, 57 | output wire uart_rts, 58 | input wire uart_cts 59 | ); 60 | 61 | // Clock and reset 62 | 63 | wire clk_125mhz_ibufg; 64 | wire clk_125mhz_mmcm_out; 65 | 66 | // Internal 125 MHz clock 67 | wire clk_125mhz_int; 68 | wire rst_125mhz_int; 69 | 70 | wire mmcm_rst = reset; 71 | wire mmcm_locked; 72 | wire mmcm_clkfb; 73 | 74 | IBUFGDS #( 75 | .DIFF_TERM("FALSE"), 76 | .IBUF_LOW_PWR("FALSE") 77 | ) 78 | clk_125mhz_ibufg_inst ( 79 | .O (clk_125mhz_ibufg), 80 | .I (clk_125mhz_p), 81 | .IB (clk_125mhz_n) 82 | ); 83 | 84 | // MMCM instance 85 | // 125 MHz in, 125 MHz out 86 | // PFD range: 10 MHz to 500 MHz 87 | // VCO range: 600 MHz to 1440 MHz 88 | // M = 5, D = 1 sets Fvco = 625 MHz (in range) 89 | // Divide by 5 to get output frequency of 125 MHz 90 | MMCME3_BASE #( 91 | .BANDWIDTH("OPTIMIZED"), 92 | .CLKOUT0_DIVIDE_F(5), 93 | .CLKOUT0_DUTY_CYCLE(0.5), 94 | .CLKOUT0_PHASE(0), 95 | .CLKOUT1_DIVIDE(1), 96 | .CLKOUT1_DUTY_CYCLE(0.5), 97 | .CLKOUT1_PHASE(0), 98 | .CLKOUT2_DIVIDE(1), 99 | .CLKOUT2_DUTY_CYCLE(0.5), 100 | .CLKOUT2_PHASE(0), 101 | .CLKOUT3_DIVIDE(1), 102 | .CLKOUT3_DUTY_CYCLE(0.5), 103 | .CLKOUT3_PHASE(0), 104 | .CLKOUT4_DIVIDE(1), 105 | .CLKOUT4_DUTY_CYCLE(0.5), 106 | .CLKOUT4_PHASE(0), 107 | .CLKOUT5_DIVIDE(1), 108 | .CLKOUT5_DUTY_CYCLE(0.5), 109 | .CLKOUT5_PHASE(0), 110 | .CLKOUT6_DIVIDE(1), 111 | .CLKOUT6_DUTY_CYCLE(0.5), 112 | .CLKOUT6_PHASE(0), 113 | .CLKFBOUT_MULT_F(5), 114 | .CLKFBOUT_PHASE(0), 115 | .DIVCLK_DIVIDE(1), 116 | .REF_JITTER1(0.010), 117 | .CLKIN1_PERIOD(8.0), 118 | .STARTUP_WAIT("FALSE"), 119 | .CLKOUT4_CASCADE("FALSE") 120 | ) 121 | clk_mmcm_inst ( 122 | .CLKIN1(clk_125mhz_ibufg), 123 | .CLKFBIN(mmcm_clkfb), 124 | .RST(mmcm_rst), 125 | .PWRDWN(1'b0), 126 | .CLKOUT0(clk_125mhz_mmcm_out), 127 | .CLKOUT0B(), 128 | .CLKOUT1(), 129 | .CLKOUT1B(), 130 | .CLKOUT2(), 131 | .CLKOUT2B(), 132 | .CLKOUT3(), 133 | .CLKOUT3B(), 134 | .CLKOUT4(), 135 | .CLKOUT5(), 136 | .CLKOUT6(), 137 | .CLKFBOUT(mmcm_clkfb), 138 | .CLKFBOUTB(), 139 | .LOCKED(mmcm_locked) 140 | ); 141 | 142 | BUFG 143 | clk_125mhz_bufg_inst ( 144 | .I(clk_125mhz_mmcm_out), 145 | .O(clk_125mhz_int) 146 | ); 147 | 148 | sync_reset #( 149 | .N(4) 150 | ) 151 | sync_reset_125mhz_inst ( 152 | .clk(clk_125mhz_int), 153 | .rst(~mmcm_locked), 154 | .sync_reset_out(rst_125mhz_int) 155 | ); 156 | 157 | // GPIO 158 | wire btnu_int; 159 | wire btnl_int; 160 | wire btnd_int; 161 | wire btnr_int; 162 | wire btnc_int; 163 | wire [7:0] sw_int; 164 | 165 | debounce_switch #( 166 | .WIDTH(13), 167 | .N(4), 168 | .RATE(125000) 169 | ) 170 | debounce_switch_inst ( 171 | .clk(clk_125mhz_int), 172 | .rst(rst_125mhz_int), 173 | .in({btnu, 174 | btnl, 175 | btnd, 176 | btnr, 177 | btnc, 178 | sw}), 179 | .out({btnu_int, 180 | btnl_int, 181 | btnd_int, 182 | btnr_int, 183 | btnc_int, 184 | sw_int}) 185 | ); 186 | 187 | wire uart_rxd_int; 188 | wire uart_cts_int; 189 | 190 | sync_signal #( 191 | .WIDTH(2), 192 | .N(2) 193 | ) 194 | sync_signal_inst ( 195 | .clk(clk_125mhz_int), 196 | .in({uart_rxd, uart_cts}), 197 | .out({uart_rxd_int,uart_cts_int}) 198 | ); 199 | 200 | fpga_core 201 | core_inst ( 202 | /* 203 | * Clock: 125MHz 204 | * Synchronous reset 205 | */ 206 | .clk(clk_125mhz_int), 207 | .rst(rst_125mhz_int), 208 | /* 209 | * GPIO 210 | */ 211 | .btnu(btnu_int), 212 | .btnl(btnl_int), 213 | .btnd(btnd_int), 214 | .btnr(btnr_int), 215 | .btnc(btnc_int), 216 | .sw(sw_int), 217 | .led(led), 218 | /* 219 | * UART: 9600 bps, 8N1 220 | */ 221 | .uart_rxd(uart_rxd_int), 222 | .uart_txd(uart_txd), 223 | .uart_rts(uart_rts), 224 | .uart_cts(uart_cts_int) 225 | ); 226 | 227 | endmodule 228 | -------------------------------------------------------------------------------- /example/VCU108/fpga/rtl/fpga_core.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | module fpga_core ( 30 | /* 31 | * Clock: 125MHz 32 | * Synchronous reset 33 | */ 34 | input wire clk, 35 | input wire rst, 36 | /* 37 | * GPIO 38 | */ 39 | input wire btnu, 40 | input wire btnl, 41 | input wire btnd, 42 | input wire btnr, 43 | input wire btnc, 44 | input wire [7:0] sw, 45 | output wire [7:0] led, 46 | /* 47 | * UART: 9600 bps, 8N1 48 | */ 49 | input wire uart_rxd, 50 | output wire uart_txd, 51 | output wire uart_rts, 52 | input wire uart_cts 53 | ); 54 | 55 | reg [7:0] uart_tx_axis_tdata; 56 | reg uart_tx_axis_tvalid; 57 | wire uart_tx_axis_tready; 58 | 59 | wire [7:0] uart_rx_axis_tdata; 60 | wire uart_rx_axis_tvalid; 61 | reg uart_rx_axis_tready; 62 | 63 | assign uart_rts = 1'b1; 64 | 65 | uart 66 | uart_inst ( 67 | .clk(clk), 68 | .rst(rst), 69 | // AXI input 70 | .s_axis_tdata(uart_tx_axis_tdata), 71 | .s_axis_tvalid(uart_tx_axis_tvalid), 72 | .s_axis_tready(uart_tx_axis_tready), 73 | // AXI output 74 | .m_axis_tdata(uart_rx_axis_tdata), 75 | .m_axis_tvalid(uart_rx_axis_tvalid), 76 | .m_axis_tready(uart_rx_axis_tready), 77 | // uart 78 | .rxd(uart_rxd), 79 | .txd(uart_txd), 80 | // status 81 | .tx_busy(), 82 | .rx_busy(), 83 | .rx_overrun_error(), 84 | .rx_frame_error(), 85 | // configuration 86 | .prescale(125000000/(9600*8)) 87 | ); 88 | 89 | //assign led = sw; 90 | assign led = uart_tx_axis_tdata; 91 | 92 | always @(posedge clk or posedge rst) begin 93 | if (rst) begin 94 | uart_tx_axis_tdata <= 0; 95 | uart_tx_axis_tvalid <= 0; 96 | uart_rx_axis_tready <= 0; 97 | end else begin 98 | if (uart_tx_axis_tvalid) begin 99 | // attempting to transmit a byte 100 | // so can't receive one at the moment 101 | uart_rx_axis_tready <= 0; 102 | // if it has been received, then clear the valid flag 103 | if (uart_tx_axis_tready) begin 104 | uart_tx_axis_tvalid <= 0; 105 | end 106 | end else begin 107 | // ready to receive byte 108 | uart_rx_axis_tready <= 1; 109 | if (uart_rx_axis_tvalid) begin 110 | // got one, so make sure it gets the correct ready signal 111 | // (either clear it if it was set or set it if we just got a 112 | // byte out of waiting for the transmitter to send one) 113 | uart_rx_axis_tready <= ~uart_rx_axis_tready; 114 | // send byte back out 115 | uart_tx_axis_tdata <= uart_rx_axis_tdata; 116 | uart_tx_axis_tvalid <= 1; 117 | end 118 | end 119 | end 120 | end 121 | 122 | endmodule 123 | -------------------------------------------------------------------------------- /example/VCU108/fpga/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an active-high asynchronous reset signal to a given clock by 31 | * using a pipeline of N registers. 32 | */ 33 | module sync_reset #( 34 | parameter N=2 // depth of synchronizer 35 | )( 36 | input wire clk, 37 | input wire rst, 38 | output wire sync_reset_out 39 | ); 40 | 41 | reg [N-1:0] sync_reg = {N{1'b1}}; 42 | 43 | assign sync_reset_out = sync_reg[N-1]; 44 | 45 | always @(posedge clk or posedge rst) begin 46 | if (rst) 47 | sync_reg <= {N{1'b1}}; 48 | else 49 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /example/VCU108/fpga/rtl/sync_signal.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an asyncronous signal to a given clock by using a pipeline of 31 | * two registers. 32 | */ 33 | module sync_signal #( 34 | parameter WIDTH=1, // width of the input and output signals 35 | parameter N=2 // depth of synchronizer 36 | )( 37 | input wire clk, 38 | input wire [WIDTH-1:0] in, 39 | output wire [WIDTH-1:0] out 40 | ); 41 | 42 | reg [WIDTH-1:0] sync_reg[N-1:0]; 43 | 44 | /* 45 | * The synchronized output is the last register in the pipeline. 46 | */ 47 | assign out = sync_reg[N-1]; 48 | 49 | integer k; 50 | 51 | always @(posedge clk) begin 52 | sync_reg[0] <= in; 53 | for (k = 1; k < N; k = k + 1) begin 54 | sync_reg[k] <= sync_reg[k-1]; 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /rtl/uart.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * AXI4-Stream UART 31 | */ 32 | module uart # 33 | ( 34 | parameter DATA_WIDTH = 8 35 | ) 36 | ( 37 | input wire clk, 38 | input wire rst, 39 | 40 | /* 41 | * AXI input 42 | */ 43 | input wire [DATA_WIDTH-1:0] s_axis_tdata, 44 | input wire s_axis_tvalid, 45 | output wire s_axis_tready, 46 | 47 | /* 48 | * AXI output 49 | */ 50 | output wire [DATA_WIDTH-1:0] m_axis_tdata, 51 | output wire m_axis_tvalid, 52 | input wire m_axis_tready, 53 | 54 | /* 55 | * UART interface 56 | */ 57 | input wire rxd, 58 | output wire txd, 59 | 60 | /* 61 | * Status 62 | */ 63 | output wire tx_busy, 64 | output wire rx_busy, 65 | output wire rx_overrun_error, 66 | output wire rx_frame_error, 67 | 68 | /* 69 | * Configuration 70 | */ 71 | input wire [15:0] prescale 72 | 73 | ); 74 | 75 | uart_tx #( 76 | .DATA_WIDTH(DATA_WIDTH) 77 | ) 78 | uart_tx_inst ( 79 | .clk(clk), 80 | .rst(rst), 81 | // axi input 82 | .s_axis_tdata(s_axis_tdata), 83 | .s_axis_tvalid(s_axis_tvalid), 84 | .s_axis_tready(s_axis_tready), 85 | // output 86 | .txd(txd), 87 | // status 88 | .busy(tx_busy), 89 | // configuration 90 | .prescale(prescale) 91 | ); 92 | 93 | uart_rx #( 94 | .DATA_WIDTH(DATA_WIDTH) 95 | ) 96 | uart_rx_inst ( 97 | .clk(clk), 98 | .rst(rst), 99 | // axi output 100 | .m_axis_tdata(m_axis_tdata), 101 | .m_axis_tvalid(m_axis_tvalid), 102 | .m_axis_tready(m_axis_tready), 103 | // input 104 | .rxd(rxd), 105 | // status 106 | .busy(rx_busy), 107 | .overrun_error(rx_overrun_error), 108 | .frame_error(rx_frame_error), 109 | // configuration 110 | .prescale(prescale) 111 | ); 112 | 113 | endmodule 114 | -------------------------------------------------------------------------------- /rtl/uart_rx.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * AXI4-Stream UART 31 | */ 32 | module uart_rx # 33 | ( 34 | parameter DATA_WIDTH = 8 35 | ) 36 | ( 37 | input wire clk, 38 | input wire rst, 39 | 40 | /* 41 | * AXI output 42 | */ 43 | output wire [DATA_WIDTH-1:0] m_axis_tdata, 44 | output wire m_axis_tvalid, 45 | input wire m_axis_tready, 46 | 47 | /* 48 | * UART interface 49 | */ 50 | input wire rxd, 51 | 52 | /* 53 | * Status 54 | */ 55 | output wire busy, 56 | output wire overrun_error, 57 | output wire frame_error, 58 | 59 | /* 60 | * Configuration 61 | */ 62 | input wire [15:0] prescale 63 | 64 | ); 65 | 66 | reg [DATA_WIDTH-1:0] m_axis_tdata_reg = 0; 67 | reg m_axis_tvalid_reg = 0; 68 | 69 | reg rxd_reg = 1; 70 | 71 | reg busy_reg = 0; 72 | reg overrun_error_reg = 0; 73 | reg frame_error_reg = 0; 74 | 75 | reg [DATA_WIDTH-1:0] data_reg = 0; 76 | reg [18:0] prescale_reg = 0; 77 | reg [3:0] bit_cnt = 0; 78 | 79 | assign m_axis_tdata = m_axis_tdata_reg; 80 | assign m_axis_tvalid = m_axis_tvalid_reg; 81 | 82 | assign busy = busy_reg; 83 | assign overrun_error = overrun_error_reg; 84 | assign frame_error = frame_error_reg; 85 | 86 | always @(posedge clk) begin 87 | if (rst) begin 88 | m_axis_tdata_reg <= 0; 89 | m_axis_tvalid_reg <= 0; 90 | rxd_reg <= 1; 91 | prescale_reg <= 0; 92 | bit_cnt <= 0; 93 | busy_reg <= 0; 94 | overrun_error_reg <= 0; 95 | frame_error_reg <= 0; 96 | end else begin 97 | rxd_reg <= rxd; 98 | overrun_error_reg <= 0; 99 | frame_error_reg <= 0; 100 | 101 | if (m_axis_tvalid && m_axis_tready) begin 102 | m_axis_tvalid_reg <= 0; 103 | end 104 | 105 | if (prescale_reg > 0) begin 106 | prescale_reg <= prescale_reg - 1; 107 | end else if (bit_cnt > 0) begin 108 | if (bit_cnt > DATA_WIDTH+1) begin 109 | if (!rxd_reg) begin 110 | bit_cnt <= bit_cnt - 1; 111 | prescale_reg <= (prescale << 3)-1; 112 | end else begin 113 | bit_cnt <= 0; 114 | prescale_reg <= 0; 115 | end 116 | end else if (bit_cnt > 1) begin 117 | bit_cnt <= bit_cnt - 1; 118 | prescale_reg <= (prescale << 3)-1; 119 | data_reg <= {rxd_reg, data_reg[DATA_WIDTH-1:1]}; 120 | end else if (bit_cnt == 1) begin 121 | bit_cnt <= bit_cnt - 1; 122 | if (rxd_reg) begin 123 | m_axis_tdata_reg <= data_reg; 124 | m_axis_tvalid_reg <= 1; 125 | overrun_error_reg <= m_axis_tvalid_reg; 126 | end else begin 127 | frame_error_reg <= 1; 128 | end 129 | end 130 | end else begin 131 | busy_reg <= 0; 132 | if (!rxd_reg) begin 133 | prescale_reg <= (prescale << 2)-2; 134 | bit_cnt <= DATA_WIDTH+2; 135 | data_reg <= 0; 136 | busy_reg <= 1; 137 | end 138 | end 139 | end 140 | end 141 | 142 | endmodule 143 | -------------------------------------------------------------------------------- /rtl/uart_tx.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * AXI4-Stream UART 31 | */ 32 | module uart_tx # 33 | ( 34 | parameter DATA_WIDTH = 8 35 | ) 36 | ( 37 | input wire clk, 38 | input wire rst, 39 | 40 | /* 41 | * AXI input 42 | */ 43 | input wire [DATA_WIDTH-1:0] s_axis_tdata, 44 | input wire s_axis_tvalid, 45 | output wire s_axis_tready, 46 | 47 | /* 48 | * UART interface 49 | */ 50 | output wire txd, 51 | 52 | /* 53 | * Status 54 | */ 55 | output wire busy, 56 | 57 | /* 58 | * Configuration 59 | */ 60 | input wire [15:0] prescale 61 | ); 62 | 63 | reg s_axis_tready_reg = 0; 64 | 65 | reg txd_reg = 1; 66 | 67 | reg busy_reg = 0; 68 | 69 | reg [DATA_WIDTH:0] data_reg = 0; 70 | reg [18:0] prescale_reg = 0; 71 | reg [3:0] bit_cnt = 0; 72 | 73 | assign s_axis_tready = s_axis_tready_reg; 74 | assign txd = txd_reg; 75 | 76 | assign busy = busy_reg; 77 | 78 | always @(posedge clk) begin 79 | if (rst) begin 80 | s_axis_tready_reg <= 0; 81 | txd_reg <= 1; 82 | prescale_reg <= 0; 83 | bit_cnt <= 0; 84 | busy_reg <= 0; 85 | end else begin 86 | if (prescale_reg > 0) begin 87 | s_axis_tready_reg <= 0; 88 | prescale_reg <= prescale_reg - 1; 89 | end else if (bit_cnt == 0) begin 90 | s_axis_tready_reg <= 1; 91 | busy_reg <= 0; 92 | 93 | if (s_axis_tvalid) begin 94 | s_axis_tready_reg <= !s_axis_tready_reg; 95 | prescale_reg <= (prescale << 3)-1; 96 | bit_cnt <= DATA_WIDTH+1; 97 | data_reg <= {1'b1, s_axis_tdata}; 98 | txd_reg <= 0; 99 | busy_reg <= 1; 100 | end 101 | end else begin 102 | if (bit_cnt > 1) begin 103 | bit_cnt <= bit_cnt - 1; 104 | prescale_reg <= (prescale << 3)-1; 105 | {data_reg, txd_reg} <= {1'b0, data_reg}; 106 | end else if (bit_cnt == 1) begin 107 | bit_cnt <= bit_cnt - 1; 108 | prescale_reg <= (prescale << 3); 109 | txd_reg <= 1; 110 | end 111 | end 112 | end 113 | end 114 | 115 | endmodule 116 | -------------------------------------------------------------------------------- /tb/axis_ep.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Copyright (c) 2014-2018 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | """ 24 | 25 | from myhdl import * 26 | 27 | skip_asserts = False 28 | 29 | class AXIStreamFrame(object): 30 | def __init__(self, data=b'', keep=None, id=None, dest=None, user=None, last_cycle_user=None): 31 | self.B = 0 32 | self.N = 8 33 | self.M = 1 34 | self.WL = 8 35 | self.data = b'' 36 | self.keep = None 37 | self.id = 0 38 | self.dest = 0 39 | self.user = None 40 | self.last_cycle_user = None 41 | 42 | if type(data) in (bytes, bytearray): 43 | self.data = bytearray(data) 44 | self.keep = keep 45 | self.id = id 46 | self.dest = dest 47 | self.user = user 48 | self.last_cycle_user = last_cycle_user 49 | elif type(data) is AXIStreamFrame: 50 | self.N = data.N 51 | self.WL = data.WL 52 | if type(data.data) is bytearray: 53 | self.data = bytearray(data.data) 54 | else: 55 | self.data = list(data.data) 56 | if data.keep is not None: 57 | self.keep = list(data.keep) 58 | if data.id is not None: 59 | if type(data.id) in (int, bool): 60 | self.id = data.id 61 | else: 62 | self.id = list(data.id) 63 | if data.dest is not None: 64 | if type(data.dest) in (int, bool): 65 | self.dest = data.dest 66 | else: 67 | self.dest = list(data.dest) 68 | if data.user is not None: 69 | if type(data.user) in (int, bool): 70 | self.user = data.user 71 | else: 72 | self.user = list(data.user) 73 | self.last_cycle_user = data.last_cycle_user 74 | else: 75 | self.data = list(data) 76 | self.keep = keep 77 | self.id = id 78 | self.dest = dest 79 | self.user = user 80 | self.last_cycle_user = last_cycle_user 81 | 82 | def build(self): 83 | if self.data is None: 84 | return 85 | 86 | f = list(self.data) 87 | tdata = [] 88 | tkeep = [] 89 | tid = [] 90 | tdest = [] 91 | tuser = [] 92 | i = 0 93 | 94 | while len(f) > 0: 95 | if self.B == 0: 96 | data = 0 97 | keep = 0 98 | for j in range(self.M): 99 | data = data | (f.pop(0) << (j*self.WL)) 100 | keep = keep | (1 << j) 101 | if len(f) == 0: break 102 | tdata.append(data) 103 | 104 | if self.keep is None: 105 | tkeep.append(keep) 106 | else: 107 | tkeep.append(self.keep[i]) 108 | else: 109 | # multiple tdata signals 110 | data = 0 111 | tdata.append(f.pop(0)) 112 | tkeep.append(0) 113 | 114 | if self.id is None: 115 | tid.append(0) 116 | elif type(self.id) is int: 117 | tid.append(self.id) 118 | else: 119 | tid.append(self.id[i]) 120 | 121 | if self.dest is None: 122 | tdest.append(0) 123 | elif type(self.dest) is int: 124 | tdest.append(self.dest) 125 | else: 126 | tdest.append(self.dest[i]) 127 | 128 | if self.user is None: 129 | tuser.append(0) 130 | elif type(self.user) is int: 131 | tuser.append(self.user) 132 | else: 133 | tuser.append(self.user[i]) 134 | i += 1 135 | 136 | if self.last_cycle_user: 137 | tuser[-1] = self.last_cycle_user 138 | 139 | return tdata, tkeep, tid, tdest, tuser 140 | 141 | def parse(self, tdata, tkeep, tid, tdest, tuser): 142 | if tdata is None or tkeep is None or tuser is None: 143 | return 144 | if len(tdata) != len(tkeep) or len(tdata) != len(tid) or len(tdata) != len(tdest) or len(tdata) != len(tuser): 145 | raise Exception("Invalid data") 146 | 147 | self.data = [] 148 | self.keep = [] 149 | self.id = [] 150 | self.dest = [] 151 | self.user = [] 152 | 153 | if self.B == 0: 154 | mask = 2**self.WL-1 155 | 156 | for i in range(len(tdata)): 157 | for j in range(self.M): 158 | if tkeep[i] & (1 << j): 159 | self.data.append((tdata[i] >> (j*self.WL)) & mask) 160 | self.keep.append(tkeep[i]) 161 | self.id.append(tid[i]) 162 | self.dest.append(tdest[i]) 163 | self.user.append(tuser[i]) 164 | else: 165 | for i in range(len(tdata)): 166 | self.data.append(tdata[i]) 167 | self.keep.append(tkeep[i]) 168 | self.id.append(tid[i]) 169 | self.dest.append(tdest[i]) 170 | self.user.append(tuser[i]) 171 | 172 | if self.WL == 8: 173 | self.data = bytearray(self.data) 174 | 175 | self.last_cycle_user = self.user[-1] 176 | 177 | def __eq__(self, other): 178 | if not isinstance(other, AXIStreamFrame): 179 | return False 180 | if self.data != other.data: 181 | return False 182 | if self.keep is not None and other.keep is not None: 183 | if self.keep != other.keep: 184 | return False 185 | if self.id is not None and other.id is not None: 186 | if type(self.id) in (int, bool) and type(other.id) is list: 187 | for k in other.id: 188 | if self.id != k: 189 | return False 190 | elif type(other.id) in (int, bool) and type(self.id) is list: 191 | for k in self.id: 192 | if other.id != k: 193 | return False 194 | elif self.id != other.id: 195 | return False 196 | if self.dest is not None and other.dest is not None: 197 | if type(self.dest) in (int, bool) and type(other.dest) is list: 198 | for k in other.dest: 199 | if self.dest != k: 200 | return False 201 | elif type(other.dest) in (int, bool) and type(self.dest) is list: 202 | for k in self.dest: 203 | if other.dest != k: 204 | return False 205 | elif self.dest != other.dest: 206 | return False 207 | if self.last_cycle_user is not None and other.last_cycle_user is not None: 208 | if self.last_cycle_user != other.last_cycle_user: 209 | return False 210 | if self.user is not None and other.user is not None: 211 | if type(self.user) in (int, bool) and type(other.user) is list: 212 | for k in other.user[:-1]: 213 | if self.user != k: 214 | return False 215 | elif type(other.user) in (int, bool) and type(self.user) is list: 216 | for k in self.user[:-1]: 217 | if other.user != k: 218 | return False 219 | elif self.user != other.user: 220 | return False 221 | else: 222 | if self.user is not None and other.user is not None: 223 | if type(self.user) in (int, bool) and type(other.user) is list: 224 | for k in other.user: 225 | if self.user != k: 226 | return False 227 | elif type(other.user) in (int, bool) and type(self.user) is list: 228 | for k in self.user: 229 | if other.user != k: 230 | return False 231 | elif self.user != other.user: 232 | return False 233 | return True 234 | 235 | def __repr__(self): 236 | return ( 237 | ('AXIStreamFrame(data=%s, ' % repr(self.data)) + 238 | ('keep=%s, ' % repr(self.keep)) + 239 | ('id=%s, ' % repr(self.id)) + 240 | ('dest=%s, ' % repr(self.dest)) + 241 | ('user=%s, ' % repr(self.user)) + 242 | ('last_cycle_user=%s)' % repr(self.last_cycle_user)) 243 | ) 244 | 245 | def __iter__(self): 246 | return self.data.__iter__() 247 | 248 | 249 | class AXIStreamSource(object): 250 | def __init__(self): 251 | self.has_logic = False 252 | self.queue = [] 253 | 254 | def send(self, frame): 255 | self.queue.append(AXIStreamFrame(frame)) 256 | 257 | def write(self, data): 258 | self.send(data) 259 | 260 | def count(self): 261 | return len(self.queue) 262 | 263 | def empty(self): 264 | return self.count() == 0 265 | 266 | def create_logic(self, 267 | clk, 268 | rst, 269 | tdata=None, 270 | tkeep=Signal(bool(True)), 271 | tvalid=Signal(bool(False)), 272 | tready=Signal(bool(True)), 273 | tlast=Signal(bool(False)), 274 | tid=Signal(intbv(0)), 275 | tdest=Signal(intbv(0)), 276 | tuser=Signal(intbv(0)), 277 | pause=0, 278 | name=None 279 | ): 280 | 281 | assert not self.has_logic 282 | 283 | self.has_logic = True 284 | 285 | tready_int = Signal(bool(False)) 286 | tvalid_int = Signal(bool(False)) 287 | 288 | @always_comb 289 | def pause_logic(): 290 | tready_int.next = tready and not pause 291 | tvalid.next = tvalid_int and not pause 292 | 293 | @instance 294 | def logic(): 295 | frame = AXIStreamFrame() 296 | data = [] 297 | keep = [] 298 | id = [] 299 | dest = [] 300 | user = [] 301 | B = 0 302 | N = len(tdata) 303 | M = len(tkeep) 304 | WL = int((len(tdata)+M-1)/M) 305 | 306 | if type(tdata) is list or type(tdata) is tuple: 307 | # multiple tdata signals 308 | B = len(tdata) 309 | N = [len(b) for b in tdata] 310 | M = 1 311 | WL = [1]*B 312 | 313 | while True: 314 | yield clk.posedge, rst.posedge 315 | 316 | if rst: 317 | if B > 0: 318 | for s in tdata: 319 | s.next = 0 320 | else: 321 | tdata.next = 0 322 | tkeep.next = 0 323 | tid.next = 0 324 | tdest.next = 0 325 | tuser.next = False 326 | tvalid_int.next = False 327 | tlast.next = False 328 | else: 329 | if tready_int and tvalid: 330 | if len(data) > 0: 331 | if B > 0: 332 | l = data.pop(0) 333 | for i in range(B): 334 | tdata[i].next = l[i] 335 | else: 336 | tdata.next = data.pop(0) 337 | tkeep.next = keep.pop(0) 338 | tid.next = id.pop(0) 339 | tdest.next = dest.pop(0) 340 | tuser.next = user.pop(0) 341 | tvalid_int.next = True 342 | tlast.next = len(data) == 0 343 | else: 344 | tvalid_int.next = False 345 | tlast.next = False 346 | if (tlast and tready_int and tvalid) or not tvalid_int: 347 | if len(self.queue) > 0: 348 | frame = self.queue.pop(0) 349 | frame.B = B 350 | frame.N = N 351 | frame.M = M 352 | frame.WL = WL 353 | data, keep, id, dest, user = frame.build() 354 | if name is not None: 355 | print("[%s] Sending frame %s" % (name, repr(frame))) 356 | if B > 0: 357 | l = data.pop(0) 358 | for i in range(B): 359 | tdata[i].next = l[i] 360 | else: 361 | tdata.next = data.pop(0) 362 | tkeep.next = keep.pop(0) 363 | tid.next = id.pop(0) 364 | tdest.next = dest.pop(0) 365 | tuser.next = user.pop(0) 366 | tvalid_int.next = True 367 | tlast.next = len(data) == 0 368 | 369 | return instances() 370 | 371 | 372 | class AXIStreamSink(object): 373 | def __init__(self): 374 | self.has_logic = False 375 | self.queue = [] 376 | self.read_queue = [] 377 | 378 | def recv(self): 379 | if len(self.queue) > 0: 380 | return self.queue.pop(0) 381 | return None 382 | 383 | def read(self, count=-1): 384 | while len(self.queue) > 0: 385 | self.read_queue.extend(self.queue.pop(0).data) 386 | if count < 0: 387 | count = len(self.read_queue) 388 | data = self.read_queue[:count] 389 | del self.read_queue[:count] 390 | return data 391 | 392 | def count(self): 393 | return len(self.queue) 394 | 395 | def empty(self): 396 | return self.count() == 0 397 | 398 | def create_logic(self, 399 | clk, 400 | rst, 401 | tdata=None, 402 | tkeep=Signal(bool(True)), 403 | tvalid=Signal(bool(False)), 404 | tready=Signal(bool(True)), 405 | tlast=Signal(bool(True)), 406 | tid=Signal(intbv(0)), 407 | tdest=Signal(intbv(0)), 408 | tuser=Signal(intbv(0)), 409 | pause=0, 410 | name=None 411 | ): 412 | 413 | assert not self.has_logic 414 | 415 | self.has_logic = True 416 | 417 | tready_int = Signal(bool(False)) 418 | tvalid_int = Signal(bool(False)) 419 | 420 | @always_comb 421 | def pause_logic(): 422 | tready.next = tready_int and not pause 423 | tvalid_int.next = tvalid and not pause 424 | 425 | @instance 426 | def logic(): 427 | frame = AXIStreamFrame() 428 | data = [] 429 | keep = [] 430 | id = [] 431 | dest = [] 432 | user = [] 433 | B = 0 434 | N = len(tdata) 435 | M = len(tkeep) 436 | WL = int((len(tdata)+M-1)/M) 437 | first = True 438 | 439 | if type(tdata) is list or type(tdata) is tuple: 440 | # multiple tdata signals 441 | B = len(tdata) 442 | N = [len(b) for b in tdata] 443 | M = 1 444 | WL = [1]*B 445 | 446 | while True: 447 | yield clk.posedge, rst.posedge 448 | 449 | if rst: 450 | tready_int.next = False 451 | frame = AXIStreamFrame() 452 | data = [] 453 | keep = [] 454 | id = [] 455 | dest = [] 456 | user = [] 457 | first = True 458 | else: 459 | tready_int.next = True 460 | 461 | if tvalid_int: 462 | 463 | if not skip_asserts: 464 | # zero tkeep not allowed 465 | assert int(tkeep) != 0 466 | # tkeep must be contiguous 467 | # i.e. 0b00011110 allowed, but 0b00011010 not allowed 468 | b = int(tkeep) 469 | while b & 1 == 0: 470 | b = b >> 1 471 | while b & 1 == 1: 472 | b = b >> 1 473 | assert b == 0 474 | # tkeep must not have gaps across cycles 475 | if not first: 476 | # not first cycle; lowest bit must be set 477 | assert int(tkeep) & 1 478 | if not tlast: 479 | # not last cycle; highest bit must be set 480 | assert int(tkeep) & (1 << len(tkeep)-1) 481 | 482 | if B > 0: 483 | l = [] 484 | for i in range(B): 485 | l.append(int(tdata[i])) 486 | data.append(l) 487 | else: 488 | data.append(int(tdata)) 489 | keep.append(int(tkeep)) 490 | id.append(int(tid)) 491 | dest.append(int(tdest)) 492 | user.append(int(tuser)) 493 | first = False 494 | if tlast: 495 | frame.B = B 496 | frame.N = N 497 | frame.M = M 498 | frame.WL = WL 499 | frame.parse(data, keep, id, dest, user) 500 | self.queue.append(frame) 501 | if name is not None: 502 | print("[%s] Got frame %s" % (name, repr(frame))) 503 | frame = AXIStreamFrame() 504 | data = [] 505 | keep = [] 506 | id = [] 507 | dest = [] 508 | user = [] 509 | first = True 510 | 511 | return instances() 512 | 513 | -------------------------------------------------------------------------------- /tb/test_uart_rx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | Copyright (c) 2014-2017 Alex Forencich 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | """ 25 | 26 | from myhdl import * 27 | import os 28 | 29 | import axis_ep 30 | import uart_ep 31 | 32 | module = 'uart_rx' 33 | testbench = 'test_%s' % module 34 | 35 | srcs = [] 36 | 37 | srcs.append("../rtl/%s.v" % module) 38 | srcs.append("%s.v" % testbench) 39 | 40 | src = ' '.join(srcs) 41 | 42 | build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) 43 | 44 | def bench(): 45 | 46 | # Inputs 47 | clk = Signal(bool(0)) 48 | rst = Signal(bool(0)) 49 | current_test = Signal(intbv(0)[8:]) 50 | 51 | m_axis_tready = Signal(bool(0)) 52 | rxd = Signal(bool(1)) 53 | prescale = Signal(intbv(0)[16:]) 54 | 55 | # Outputs 56 | m_axis_tdata = Signal(intbv(0)[8:]) 57 | m_axis_tvalid = Signal(bool(0)) 58 | 59 | busy = Signal(bool(0)) 60 | overrun_error = Signal(bool(0)) 61 | frame_error = Signal(bool(0)) 62 | 63 | # sources and sinks 64 | sink_pause = Signal(bool(0)) 65 | 66 | source = uart_ep.UARTSource() 67 | 68 | source_logic = source.create_logic( 69 | clk, 70 | rst, 71 | txd=rxd, 72 | prescale=prescale, 73 | name='source' 74 | ) 75 | 76 | sink = axis_ep.AXIStreamSink() 77 | 78 | sink_logic = sink.create_logic( 79 | clk, 80 | rst, 81 | tdata=m_axis_tdata, 82 | tvalid=m_axis_tvalid, 83 | tready=m_axis_tready, 84 | pause=sink_pause, 85 | name='sink' 86 | ) 87 | 88 | # DUT 89 | if os.system(build_cmd): 90 | raise Exception("Error running build command") 91 | 92 | dut = Cosimulation( 93 | "vvp -m myhdl %s.vvp -lxt2" % testbench, 94 | clk=clk, 95 | rst=rst, 96 | current_test=current_test, 97 | 98 | m_axis_tdata=m_axis_tdata, 99 | m_axis_tvalid=m_axis_tvalid, 100 | m_axis_tready=m_axis_tready, 101 | 102 | rxd=rxd, 103 | 104 | busy=busy, 105 | overrun_error=overrun_error, 106 | frame_error=frame_error, 107 | 108 | prescale=prescale 109 | ) 110 | 111 | @always(delay(4)) 112 | def clkgen(): 113 | clk.next = not clk 114 | 115 | @instance 116 | def check(): 117 | yield delay(100) 118 | yield clk.posedge 119 | rst.next = 1 120 | yield clk.posedge 121 | rst.next = 0 122 | yield clk.posedge 123 | yield delay(100) 124 | yield clk.posedge 125 | 126 | yield clk.posedge 127 | 128 | yield clk.posedge 129 | 130 | prescale.next = 1; 131 | 132 | yield clk.posedge 133 | 134 | yield clk.posedge 135 | print("test 1: walk") 136 | current_test.next = 1 137 | 138 | source.write(b'\x00\x01\x02\x04\x08\x10\x20\x40\x80') 139 | yield clk.posedge 140 | 141 | yield delay(5000) 142 | 143 | yield delay(1000) 144 | 145 | yield clk.posedge 146 | 147 | rx_data = bytearray(sink.read()) 148 | print(rx_data) 149 | assert rx_data == b'\x00\x01\x02\x04\x08\x10\x20\x40\x80' 150 | 151 | yield clk.posedge 152 | print("test 2: walk 2") 153 | current_test.next = 2 154 | 155 | source.write(b'\x00\x01\x03\x07\x0F\x1F\x3F\x7F\xFF') 156 | yield clk.posedge 157 | 158 | yield delay(5000) 159 | 160 | yield delay(1000) 161 | 162 | yield clk.posedge 163 | 164 | rx_data = bytearray(sink.read()) 165 | print(rx_data) 166 | assert rx_data == b'\x00\x01\x03\x07\x0F\x1F\x3F\x7F\xFF' 167 | 168 | yield delay(100) 169 | 170 | raise StopSimulation 171 | 172 | return instances() 173 | 174 | def test_bench(): 175 | os.chdir(os.path.dirname(os.path.abspath(__file__))) 176 | sim = Simulation(bench()) 177 | sim.run() 178 | 179 | if __name__ == '__main__': 180 | print("Running test...") 181 | test_bench() 182 | 183 | -------------------------------------------------------------------------------- /tb/test_uart_rx.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | module test_uart_rx; 30 | 31 | // Inputs 32 | reg clk = 0; 33 | reg rst = 0; 34 | reg [7:0] current_test = 0; 35 | 36 | reg m_axis_tready = 0; 37 | reg rxd = 1; 38 | reg [15:0] prescale = 0; 39 | 40 | // Outputs 41 | wire [7:0] m_axis_tdata; 42 | wire m_axis_tvalid; 43 | 44 | wire busy; 45 | wire overrun_error; 46 | wire frame_error; 47 | 48 | initial begin 49 | // myhdl integration 50 | $from_myhdl(clk, 51 | rst, 52 | current_test, 53 | m_axis_tready, 54 | rxd, 55 | prescale); 56 | $to_myhdl(m_axis_tdata, 57 | m_axis_tvalid, 58 | busy, 59 | overrun_error, 60 | frame_error); 61 | 62 | // dump file 63 | $dumpfile("test_uart_rx.lxt"); 64 | $dumpvars(0, test_uart_rx); 65 | end 66 | 67 | uart_rx #( 68 | .DATA_WIDTH(8) 69 | ) 70 | UUT ( 71 | .clk(clk), 72 | .rst(rst), 73 | // axi output 74 | .m_axis_tdata(m_axis_tdata), 75 | .m_axis_tvalid(m_axis_tvalid), 76 | .m_axis_tready(m_axis_tready), 77 | // input 78 | .rxd(rxd), 79 | // status 80 | .busy(busy), 81 | .overrun_error(overrun_error), 82 | .frame_error(frame_error), 83 | // configuration 84 | .prescale(prescale) 85 | ); 86 | 87 | endmodule 88 | -------------------------------------------------------------------------------- /tb/test_uart_tx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | Copyright (c) 2014-2017 Alex Forencich 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | """ 25 | 26 | from myhdl import * 27 | import os 28 | 29 | import axis_ep 30 | import uart_ep 31 | 32 | module = 'uart_tx' 33 | testbench = 'test_%s' % module 34 | 35 | srcs = [] 36 | 37 | srcs.append("../rtl/%s.v" % module) 38 | srcs.append("%s.v" % testbench) 39 | 40 | src = ' '.join(srcs) 41 | 42 | build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) 43 | 44 | def bench(): 45 | 46 | # Inputs 47 | clk = Signal(bool(0)) 48 | rst = Signal(bool(0)) 49 | current_test = Signal(intbv(0)[8:]) 50 | 51 | s_axis_tdata = Signal(intbv(0)[8:]) 52 | s_axis_tvalid = Signal(bool(0)) 53 | s_axis_tlast = Signal(bool(0)) 54 | prescale = Signal(intbv(0)[16:]) 55 | 56 | # Outputs 57 | s_axis_tready = Signal(bool(0)) 58 | txd = Signal(bool(1)) 59 | 60 | busy = Signal(bool(0)) 61 | 62 | # sources and sinks 63 | source_pause = Signal(bool(0)) 64 | 65 | source = axis_ep.AXIStreamSource() 66 | 67 | source_logic = source.create_logic( 68 | clk, 69 | rst, 70 | tdata=s_axis_tdata, 71 | tvalid=s_axis_tvalid, 72 | tready=s_axis_tready, 73 | pause=source_pause, 74 | name='source' 75 | ) 76 | 77 | sink = uart_ep.UARTSink() 78 | 79 | sink_logic = sink.create_logic( 80 | clk, 81 | rst, 82 | rxd=txd, 83 | prescale=prescale, 84 | name='sink' 85 | ) 86 | 87 | # DUT 88 | if os.system(build_cmd): 89 | raise Exception("Error running build command") 90 | 91 | dut = Cosimulation( 92 | "vvp -m myhdl %s.vvp -lxt2" % testbench, 93 | clk=clk, 94 | rst=rst, 95 | current_test=current_test, 96 | 97 | s_axis_tdata=s_axis_tdata, 98 | s_axis_tvalid=s_axis_tvalid, 99 | s_axis_tready=s_axis_tready, 100 | 101 | txd=txd, 102 | 103 | busy=busy, 104 | 105 | prescale=prescale 106 | ) 107 | 108 | @always(delay(4)) 109 | def clkgen(): 110 | clk.next = not clk 111 | 112 | @instance 113 | def check(): 114 | yield delay(100) 115 | yield clk.posedge 116 | rst.next = 1 117 | yield clk.posedge 118 | rst.next = 0 119 | yield clk.posedge 120 | yield delay(100) 121 | yield clk.posedge 122 | 123 | yield clk.posedge 124 | 125 | yield clk.posedge 126 | 127 | prescale.next = 1; 128 | 129 | yield clk.posedge 130 | 131 | yield clk.posedge 132 | print("test 1: walk") 133 | current_test.next = 1 134 | 135 | source.write(b'\x00\x01\x02\x04\x08\x10\x20\x40\x80') 136 | yield clk.posedge 137 | 138 | yield s_axis_tvalid.negedge 139 | 140 | yield delay(1000) 141 | 142 | yield clk.posedge 143 | 144 | rx_data = bytearray(sink.read()) 145 | print(rx_data) 146 | assert rx_data == b'\x00\x01\x02\x04\x08\x10\x20\x40\x80' 147 | 148 | yield clk.posedge 149 | print("test 2: walk 2") 150 | current_test.next = 2 151 | 152 | source.write(b'\x00\x01\x03\x07\x0F\x1F\x3F\x7F\xFF') 153 | yield clk.posedge 154 | 155 | yield s_axis_tvalid.negedge 156 | 157 | yield delay(1000) 158 | 159 | yield clk.posedge 160 | 161 | rx_data = bytearray(sink.read()) 162 | print(rx_data) 163 | assert rx_data == b'\x00\x01\x03\x07\x0F\x1F\x3F\x7F\xFF' 164 | 165 | yield delay(100) 166 | 167 | raise StopSimulation 168 | 169 | return instances() 170 | 171 | def test_bench(): 172 | os.chdir(os.path.dirname(os.path.abspath(__file__))) 173 | sim = Simulation(bench()) 174 | sim.run() 175 | 176 | if __name__ == '__main__': 177 | print("Running test...") 178 | test_bench() 179 | 180 | -------------------------------------------------------------------------------- /tb/test_uart_tx.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | module test_uart_tx; 30 | 31 | // Inputs 32 | reg clk = 0; 33 | reg rst = 0; 34 | reg [7:0] current_test = 0; 35 | 36 | reg [7:0] s_axis_tdata = 8'd0; 37 | reg s_axis_tvalid = 1'b0; 38 | reg [15:0] prescale = 0; 39 | 40 | // Outputs 41 | wire s_axis_tready; 42 | wire txd; 43 | 44 | wire busy; 45 | 46 | initial begin 47 | // myhdl integration 48 | $from_myhdl(clk, 49 | rst, 50 | current_test, 51 | s_axis_tdata, 52 | s_axis_tvalid, 53 | prescale); 54 | $to_myhdl(s_axis_tready, 55 | txd, 56 | busy); 57 | 58 | // dump file 59 | $dumpfile("test_uart_tx.lxt"); 60 | $dumpvars(0, test_uart_tx); 61 | end 62 | 63 | uart_tx #( 64 | .DATA_WIDTH(8) 65 | ) 66 | UUT ( 67 | .clk(clk), 68 | .rst(rst), 69 | // axi input 70 | .s_axis_tdata(s_axis_tdata), 71 | .s_axis_tvalid(s_axis_tvalid), 72 | .s_axis_tready(s_axis_tready), 73 | // output 74 | .txd(txd), 75 | // status 76 | .busy(busy), 77 | // configuration 78 | .prescale(prescale) 79 | ); 80 | 81 | endmodule 82 | -------------------------------------------------------------------------------- /tb/uart_ep.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Copyright (c) 2014-2017 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | """ 24 | 25 | from myhdl import * 26 | 27 | class UARTSource(object): 28 | def __init__(self): 29 | self.has_logic = False 30 | self.queue = [] 31 | 32 | def write(self, data): 33 | self.queue.extend(data) 34 | 35 | def count(self): 36 | return len(self.queue) 37 | 38 | def empty(self): 39 | return self.count() == 0 40 | 41 | def create_logic(self, 42 | clk, 43 | rst, 44 | txd=None, 45 | width=8, 46 | prescale=2, 47 | name=None 48 | ): 49 | 50 | assert not self.has_logic 51 | 52 | self.has_logic = True 53 | 54 | @instance 55 | def logic(): 56 | frame = [] 57 | temp_data = 0 58 | prescale_cnt = 0 59 | bit_cnt = 0 60 | 61 | while True: 62 | yield clk.posedge, rst.posedge 63 | 64 | if rst: 65 | txd.next = 1 66 | prescale_cnt = 0 67 | bit_cnt = 0 68 | else: 69 | if prescale_cnt > 0: 70 | prescale_cnt = prescale_cnt-1 71 | elif bit_cnt > 0: 72 | bit_cnt = bit_cnt-1 73 | prescale_cnt = (prescale << 3) - 1 74 | if bit_cnt > 0: 75 | txd.next = temp_data & 1 != 0 76 | temp_data = temp_data >> 1 77 | else: 78 | txd.next = 1 79 | elif len(self.queue) > 0: 80 | temp_data = self.queue.pop(0) 81 | if name is not None: 82 | print("[%s] Sending data byte %d" % (name, temp_data)) 83 | prescale_cnt = (prescale << 3) - 1 84 | bit_cnt = width+1 85 | txd.next = 0 86 | 87 | return instances() 88 | 89 | 90 | class UARTSink(object): 91 | def __init__(self): 92 | self.has_logic = False 93 | self.queue = [] 94 | 95 | def read(self, count=-1): 96 | if count < 0: 97 | count = len(self.queue) 98 | data = self.queue[:count] 99 | del self.queue[:count] 100 | return data 101 | 102 | def count(self): 103 | return len(self.queue) 104 | 105 | def empty(self): 106 | return self.count() == 0 107 | 108 | def create_logic(self, 109 | clk, rst, 110 | rxd=None, 111 | width=8, 112 | prescale=2, 113 | name=None 114 | ): 115 | 116 | assert not self.has_logic 117 | 118 | self.has_logic = True 119 | 120 | @instance 121 | def logic(): 122 | frame = [] 123 | temp_data = 0 124 | prescale_cnt = 0 125 | bit_cnt = 0 126 | 127 | while True: 128 | yield clk.posedge, rst.posedge 129 | 130 | if rst: 131 | frame = [] 132 | prescale_cnt = 0 133 | bit_cnt = 0 134 | else: 135 | if prescale_cnt > 0: 136 | prescale_cnt = prescale_cnt-1 137 | elif bit_cnt > 0: 138 | bit_cnt = bit_cnt-1 139 | prescale_cnt = (prescale << 3) - 1 140 | if bit_cnt == width+1: 141 | if rxd: 142 | if name is not None: 143 | print("[%s] Bad start bit" % name) 144 | prescale_cnt = 0 145 | bit_cnt = 0 146 | elif bit_cnt > 0: 147 | temp_data = temp_data | (rxd << (width-bit_cnt)) 148 | else: 149 | prescale_cnt = 0 150 | if rxd: 151 | if name is not None: 152 | print("[%s] Got data byte %d" % (name, temp_data)) 153 | self.queue.append(temp_data) 154 | else: 155 | if name is not None: 156 | print("[%s] Bad stop bit" % name) 157 | elif rxd == 0: 158 | prescale_cnt = (prescale << 2) - 2 159 | bit_cnt = width+2 160 | temp_data = 0 161 | 162 | return instances() 163 | 164 | -------------------------------------------------------------------------------- /tb/uart_rx/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Alex Forencich 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | # THE SOFTWARE. 20 | 21 | TOPLEVEL_LANG = verilog 22 | 23 | SIM ?= icarus 24 | WAVES ?= 0 25 | 26 | COCOTB_HDL_TIMEUNIT = 1ns 27 | COCOTB_HDL_TIMEPRECISION = 1ns 28 | 29 | DUT = uart_rx 30 | TOPLEVEL = $(DUT) 31 | MODULE = test_$(DUT) 32 | VERILOG_SOURCES += ../../rtl/$(DUT).v 33 | 34 | # module parameters 35 | export PARAM_DATA_WIDTH ?= 8 36 | 37 | ifeq ($(SIM), icarus) 38 | PLUSARGS += -fst 39 | 40 | COMPILE_ARGS += -P $(TOPLEVEL).DATA_WIDTH=$(PARAM_DATA_WIDTH) 41 | 42 | ifeq ($(WAVES), 1) 43 | VERILOG_SOURCES += iverilog_dump.v 44 | COMPILE_ARGS += -s iverilog_dump 45 | endif 46 | else ifeq ($(SIM), verilator) 47 | COMPILE_ARGS += -Wno-WIDTH 48 | 49 | COMPILE_ARGS += -GDATA_WIDTH=$(PARAM_DATA_WIDTH) 50 | 51 | ifeq ($(WAVES), 1) 52 | COMPILE_ARGS += --trace-fst 53 | endif 54 | endif 55 | 56 | include $(shell cocotb-config --makefiles)/Makefile.sim 57 | 58 | iverilog_dump.v: 59 | echo 'module iverilog_dump();' > $@ 60 | echo 'initial begin' >> $@ 61 | echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ 62 | echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ 63 | echo 'end' >> $@ 64 | echo 'endmodule' >> $@ 65 | 66 | clean:: 67 | @rm -rf iverilog_dump.v 68 | @rm -rf dump.fst $(TOPLEVEL).fst 69 | -------------------------------------------------------------------------------- /tb/uart_rx/test_uart_rx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | Copyright (c) 2020 Alex Forencich 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | """ 25 | 26 | import itertools 27 | import logging 28 | import os 29 | 30 | import cocotb_test.simulator 31 | 32 | import cocotb 33 | from cocotb.clock import Clock 34 | from cocotb.triggers import RisingEdge, Timer 35 | from cocotb.regression import TestFactory 36 | 37 | from cocotbext.axi import AxiStreamSink, AxiStreamBus 38 | from cocotbext.uart import UartSource 39 | 40 | 41 | class TB: 42 | def __init__(self, dut, baud=3e6): 43 | self.dut = dut 44 | 45 | self.log = logging.getLogger("cocotb.tb") 46 | self.log.setLevel(logging.DEBUG) 47 | 48 | cocotb.start_soon(Clock(dut.clk, 8, units="ns").start()) 49 | 50 | self.source = UartSource(dut.rxd, baud=baud, bits=len(dut.m_axis_tdata), stop_bits=1) 51 | 52 | self.sink = AxiStreamSink(AxiStreamBus.from_prefix(dut, "m_axis"), dut.clk, dut.rst) 53 | 54 | dut.prescale.setimmediatevalue(int(1/8e-9/baud/8)) 55 | 56 | async def reset(self): 57 | self.dut.rst.setimmediatevalue(0) 58 | await RisingEdge(self.dut.clk) 59 | await RisingEdge(self.dut.clk) 60 | self.dut.rst.value = 1 61 | await RisingEdge(self.dut.clk) 62 | await RisingEdge(self.dut.clk) 63 | self.dut.rst.value = 0 64 | await RisingEdge(self.dut.clk) 65 | await RisingEdge(self.dut.clk) 66 | 67 | 68 | async def run_test(dut, payload_lengths=None, payload_data=None): 69 | 70 | tb = TB(dut) 71 | 72 | await tb.reset() 73 | 74 | for test_data in [payload_data(x) for x in payload_lengths()]: 75 | 76 | await tb.source.write(test_data) 77 | 78 | rx_data = bytearray() 79 | 80 | while len(rx_data) < len(test_data): 81 | rx_data.extend(await tb.sink.read()) 82 | 83 | tb.log.info("Read data: %s", rx_data) 84 | 85 | assert tb.sink.empty() 86 | 87 | await Timer(2, 'us') 88 | 89 | await RisingEdge(dut.clk) 90 | await RisingEdge(dut.clk) 91 | 92 | 93 | def prbs31(state=0x7fffffff): 94 | while True: 95 | for i in range(8): 96 | if bool(state & 0x08000000) ^ bool(state & 0x40000000): 97 | state = ((state & 0x3fffffff) << 1) | 1 98 | else: 99 | state = (state & 0x3fffffff) << 1 100 | yield state & 0xff 101 | 102 | 103 | def size_list(): 104 | return list(range(1, 16)) + [128] 105 | 106 | 107 | def incrementing_payload(length): 108 | return bytearray(itertools.islice(itertools.cycle(range(256)), length)) 109 | 110 | 111 | def prbs_payload(length): 112 | gen = prbs31() 113 | return bytearray([next(gen) for x in range(length)]) 114 | 115 | 116 | if cocotb.SIM_NAME: 117 | 118 | factory = TestFactory(run_test) 119 | factory.add_option("payload_lengths", [size_list]) 120 | factory.add_option("payload_data", [incrementing_payload, prbs_payload]) 121 | factory.generate_tests() 122 | 123 | 124 | # cocotb-test 125 | 126 | tests_dir = os.path.abspath(os.path.dirname(__file__)) 127 | rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) 128 | 129 | 130 | def test_uart_rx(request): 131 | dut = "uart_rx" 132 | module = os.path.splitext(os.path.basename(__file__))[0] 133 | toplevel = dut 134 | 135 | verilog_sources = [ 136 | os.path.join(rtl_dir, f"{dut}.v"), 137 | ] 138 | 139 | parameters = {} 140 | 141 | parameters['DATA_WIDTH'] = 8 142 | 143 | extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} 144 | 145 | sim_build = os.path.join(tests_dir, "sim_build", 146 | request.node.name.replace('[', '-').replace(']', '')) 147 | 148 | cocotb_test.simulator.run( 149 | python_search=[tests_dir], 150 | verilog_sources=verilog_sources, 151 | toplevel=toplevel, 152 | module=module, 153 | parameters=parameters, 154 | sim_build=sim_build, 155 | extra_env=extra_env, 156 | ) 157 | -------------------------------------------------------------------------------- /tb/uart_tx/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Alex Forencich 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | # THE SOFTWARE. 20 | 21 | TOPLEVEL_LANG = verilog 22 | 23 | SIM ?= icarus 24 | WAVES ?= 0 25 | 26 | COCOTB_HDL_TIMEUNIT = 1ns 27 | COCOTB_HDL_TIMEPRECISION = 1ns 28 | 29 | DUT = uart_tx 30 | TOPLEVEL = $(DUT) 31 | MODULE = test_$(DUT) 32 | VERILOG_SOURCES += ../../rtl/$(DUT).v 33 | 34 | # module parameters 35 | export PARAM_DATA_WIDTH ?= 8 36 | 37 | ifeq ($(SIM), icarus) 38 | PLUSARGS += -fst 39 | 40 | COMPILE_ARGS += -P $(TOPLEVEL).DATA_WIDTH=$(PARAM_DATA_WIDTH) 41 | 42 | ifeq ($(WAVES), 1) 43 | VERILOG_SOURCES += iverilog_dump.v 44 | COMPILE_ARGS += -s iverilog_dump 45 | endif 46 | else ifeq ($(SIM), verilator) 47 | COMPILE_ARGS += -Wno-WIDTH 48 | 49 | COMPILE_ARGS += -GDATA_WIDTH=$(PARAM_DATA_WIDTH) 50 | 51 | ifeq ($(WAVES), 1) 52 | COMPILE_ARGS += --trace-fst 53 | endif 54 | endif 55 | 56 | include $(shell cocotb-config --makefiles)/Makefile.sim 57 | 58 | iverilog_dump.v: 59 | echo 'module iverilog_dump();' > $@ 60 | echo 'initial begin' >> $@ 61 | echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ 62 | echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ 63 | echo 'end' >> $@ 64 | echo 'endmodule' >> $@ 65 | 66 | clean:: 67 | @rm -rf iverilog_dump.v 68 | @rm -rf dump.fst $(TOPLEVEL).fst 69 | -------------------------------------------------------------------------------- /tb/uart_tx/test_uart_tx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | Copyright (c) 2020 Alex Forencich 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | """ 25 | 26 | import itertools 27 | import logging 28 | import os 29 | 30 | import cocotb_test.simulator 31 | 32 | import cocotb 33 | from cocotb.clock import Clock 34 | from cocotb.triggers import RisingEdge, Timer 35 | from cocotb.regression import TestFactory 36 | 37 | from cocotbext.axi import AxiStreamSource, AxiStreamBus 38 | from cocotbext.uart import UartSink 39 | 40 | 41 | class TB: 42 | def __init__(self, dut, baud=3e6): 43 | self.dut = dut 44 | 45 | self.log = logging.getLogger("cocotb.tb") 46 | self.log.setLevel(logging.DEBUG) 47 | 48 | cocotb.start_soon(Clock(dut.clk, 8, units="ns").start()) 49 | 50 | self.source = AxiStreamSource(AxiStreamBus.from_prefix(dut, "s_axis"), dut.clk, dut.rst) 51 | 52 | self.sink = UartSink(dut.txd, baud=baud, bits=len(dut.s_axis_tdata), stop_bits=1) 53 | 54 | dut.prescale.setimmediatevalue(int(1/8e-9/baud/8)) 55 | 56 | async def reset(self): 57 | self.dut.rst.setimmediatevalue(0) 58 | await RisingEdge(self.dut.clk) 59 | await RisingEdge(self.dut.clk) 60 | self.dut.rst.value = 1 61 | await RisingEdge(self.dut.clk) 62 | await RisingEdge(self.dut.clk) 63 | self.dut.rst.value = 0 64 | await RisingEdge(self.dut.clk) 65 | await RisingEdge(self.dut.clk) 66 | 67 | 68 | async def run_test(dut, payload_lengths=None, payload_data=None): 69 | 70 | tb = TB(dut) 71 | 72 | await tb.reset() 73 | 74 | for test_data in [payload_data(x) for x in payload_lengths()]: 75 | 76 | await tb.source.write(test_data) 77 | 78 | rx_data = bytearray() 79 | 80 | while len(rx_data) < len(test_data): 81 | rx_data.extend(await tb.sink.read()) 82 | 83 | tb.log.info("Read data: %s", rx_data) 84 | 85 | assert tb.sink.empty() 86 | 87 | await Timer(2, 'us') 88 | 89 | await RisingEdge(dut.clk) 90 | await RisingEdge(dut.clk) 91 | 92 | 93 | def prbs31(state=0x7fffffff): 94 | while True: 95 | for i in range(8): 96 | if bool(state & 0x08000000) ^ bool(state & 0x40000000): 97 | state = ((state & 0x3fffffff) << 1) | 1 98 | else: 99 | state = (state & 0x3fffffff) << 1 100 | yield state & 0xff 101 | 102 | 103 | def size_list(): 104 | return list(range(1, 16)) + [128] 105 | 106 | 107 | def incrementing_payload(length): 108 | return bytearray(itertools.islice(itertools.cycle(range(256)), length)) 109 | 110 | 111 | def prbs_payload(length): 112 | gen = prbs31() 113 | return bytearray([next(gen) for x in range(length)]) 114 | 115 | 116 | if cocotb.SIM_NAME: 117 | 118 | factory = TestFactory(run_test) 119 | factory.add_option("payload_lengths", [size_list]) 120 | factory.add_option("payload_data", [incrementing_payload, prbs_payload]) 121 | factory.generate_tests() 122 | 123 | 124 | # cocotb-test 125 | 126 | tests_dir = os.path.abspath(os.path.dirname(__file__)) 127 | rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) 128 | 129 | 130 | def test_uart_tx(request): 131 | dut = "uart_tx" 132 | module = os.path.splitext(os.path.basename(__file__))[0] 133 | toplevel = dut 134 | 135 | verilog_sources = [ 136 | os.path.join(rtl_dir, f"{dut}.v"), 137 | ] 138 | 139 | parameters = {} 140 | 141 | parameters['DATA_WIDTH'] = 8 142 | 143 | extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} 144 | 145 | sim_build = os.path.join(tests_dir, "sim_build", 146 | request.node.name.replace('[', '-').replace(']', '')) 147 | 148 | cocotb_test.simulator.run( 149 | python_search=[tests_dir], 150 | verilog_sources=verilog_sources, 151 | toplevel=toplevel, 152 | module=module, 153 | parameters=parameters, 154 | sim_build=sim_build, 155 | extra_env=extra_env, 156 | ) 157 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # tox configuration 2 | [tox] 3 | envlist = py3 4 | skipsdist = True 5 | minversion = 3.2.0 6 | requires = virtualenv >= 16.1 7 | 8 | [gh-actions] 9 | python = 10 | 3.10: py3 11 | 12 | [testenv] 13 | deps = 14 | pytest == 7.2.1 15 | pytest-xdist == 3.1.0 16 | cocotb == 1.7.2 17 | cocotb-bus == 0.2.1 18 | cocotb-test == 0.2.4 19 | cocotbext-axi == 0.1.20 20 | cocotbext-uart == 0.1.2 21 | 22 | commands = 23 | pytest {posargs:-n auto --verbose} 24 | 25 | # pytest configuration 26 | [pytest] 27 | testpaths = 28 | tb 29 | addopts = 30 | --ignore-glob=tb/test_*.py 31 | --import-mode importlib 32 | --------------------------------------------------------------------------------