├── .github
└── FUNDING.yml
├── .gitignore
├── .scalafmt.conf
├── .vscode
└── settings.json
├── Readme.md
├── blinky
├── .gitignore
├── .scalafix.conf
├── .scalafmt.conf
├── .travis.yml
├── LICENSE
├── Makefile
├── Makefile.boards
├── README.md
├── build.sbt
├── build.sc
├── chiselblinky.core
├── constraints
│ ├── arty_a7.xdc
│ ├── de1_soc_revF.sdc
│ ├── de1_soc_revF.tcl
│ ├── ecp5-evn.lpf
│ ├── ecp5-ulx3s.lpf
│ ├── fomu-pvt1.lpf
│ ├── nexys4ddr.xdc
│ ├── orange-crab.lpf
│ ├── polarfire_evaluation.pdc
│ ├── qmtech-kintex7.xdc
│ ├── qmtech-zyjzgw.xdc
│ ├── qomu.pcf
│ ├── storey_peak_stratixV.sdc
│ └── storey_peak_stratixV.tcl
├── openocd
│ ├── LFE5U-25F.cfg
│ ├── LFE5U-45F.cfg
│ ├── LFE5U-85F.cfg
│ ├── LFE5UM-25F.cfg
│ ├── LFE5UM-45F.cfg
│ ├── LFE5UM-85F.cfg
│ ├── LFE5UM5G-25F.cfg
│ ├── LFE5UM5G-45F.cfg
│ ├── LFE5UM5G-85F.cfg
│ ├── digilent-hs1.cfg
│ ├── ecp5-evn.cfg
│ ├── ft231x.cfg
│ ├── olimex-arm-usb-tiny-h.cfg
│ └── xilinx-xc7.cfg
├── proginfo
│ ├── artix7-template.txt
│ ├── boardconfig.yaml
│ ├── dfu-util.txt
│ ├── proginfo.py
│ ├── qmtech_k325t-template.txt
│ └── ulx3s-template.txt
├── project
│ ├── build.properties
│ └── plugins.sbt
├── scripts
│ └── mill
└── src
│ ├── main
│ ├── resources
│ │ ├── pll_artya7-35t.v
│ │ ├── pll_de1_soc_revF.v
│ │ ├── pll_evn.v
│ │ ├── pll_nexys4ddr.v
│ │ ├── pll_orange-crab.v
│ │ ├── pll_polarfireeval.v
│ │ ├── pll_qmtech_k325t.v
│ │ ├── pll_qomu.v
│ │ ├── pll_storey_peak_stratixV.v
│ │ └── pll_ulx3s.v
│ └── scala
│ │ ├── BlackBoxPLL.scala
│ │ ├── Blinky.scala
│ │ └── Toplevel.scala
│ └── test
│ └── scala
│ └── BlinkySpec.scala
├── blockram
├── .gitignore
├── .scalafmt.conf
├── Makefile
├── build.sbt
├── project
│ ├── build.properties
│ ├── metals.sbt
│ └── plugins.sbt
├── sample.hex
└── src
│ └── main
│ └── scala
│ └── utils
│ ├── DualportRAM.scala
│ ├── MultiMemory.scala
│ ├── SingleportRAM.scala
│ └── SubByteMemory.scala
├── fomublink
├── .gitignore
├── .scalafix.conf
├── .scalafmt.conf
├── .vscode
│ └── settings.json
├── Makefile
├── Readme.md
├── build.sc
├── constraints
│ └── fomu-pvt.pcf
├── fomublink.core
├── post-instructions.txt
├── scripts
│ └── mill
└── src
│ └── main
│ └── scala
│ ├── Blinky.scala
│ ├── ICE40ledDrvBlackBox.scala
│ └── ICE40pllBlackbox.scala
└── pdf
├── Chisel3-CheatSheet.pdf
├── Chisel3-Documentation.pdf
├── Digital Design with Chisel - Martin Schoeberl.pdf
└── UCB-Chisel-Tutorial.pdf
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: carlosedp
4 | patreon: carlosedp
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .metals
2 | .ammonite
3 | .vscode
--------------------------------------------------------------------------------
/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = "2.7.5"
2 | maxColumn = 120
3 | align.preset = most
4 | align.multiline = false
5 | continuationIndent.defnSite = 2
6 | assumeStandardLibraryStripMargin = true
7 | docstrings = JavaDoc
8 | lineEndings = preserve
9 | includeCurlyBraceInSelectChains = false
10 | danglingParentheses.preset = true
11 | optIn.annotationNewlines = true
12 | newlines.alwaysBeforeMultilineDef = false
13 |
14 | rewrite.rules = [RedundantBraces]
15 |
16 | rewrite.redundantBraces.generalExpressions = false
17 | rewriteTokens = {
18 | "⇒": "=>"
19 | "→": "->"
20 | "←": "<-"
21 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.watcherExclude": {
3 | "**/target": true
4 | }
5 | }
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Chisel Playground
2 |
3 | The objective of this repo is to hold examples of synthesizable applications written
4 | in [Chisel](https://www.chisel-lang.org/) for learning purposes.
5 |
6 | ## Projects
7 |
8 | * [Blinky](/blinky) - A blink application that can be synthesizable on multiple FPGA boards by using FuseSoc. Can be used as base for new projects.
9 | * [Fomublink](/fomublink) - A port from [Fomu](https://tomu.im/fomu.html) blink application that can be synthesizable for Foum ICE40 FPGA.
10 |
11 | ## Books and Learning Material
12 |
13 | I've collected some documentation to help learn Chisel:
14 |
15 | * Chisel Book - Downloaded from [Martin's page](https://github.com/schoeberl/chisel-book) - [PDF](/pdf/Digital%20Design%20with%20Chisel%20-%20Martin%20Schoeberl.pdf)
16 | * Chisel Cheat Sheet - [PDF](/pdf/Chisel3-CheatSheet.pdf)
17 | * Chisel 3 Documentation - PDF Generated from [Chisel Wiki](https://github.com/chipsalliance/chisel3/wiki) - [PDF](/pdf/Chisel3-Documentation.pdf)
18 | * UCB Chisel Tutorial - PDF Generated from [Wiki](https://github.com/ucb-bar/chisel-tutorial/wiki) - [PDF](/pdf/UCB-Chisel-Tutorial.pdf)
--------------------------------------------------------------------------------
/blinky/.gitignore:
--------------------------------------------------------------------------------
1 | out/
2 | target/
3 | project/target
4 | project/project
5 | docs/generated
6 | docs-target/
7 | /*.fir
8 | /*.v
9 | /*.anno.json
10 | /*.swp
11 | /*~
12 | .addons-dont-touch
13 | /lib/
14 | /test_lib/
15 | /testbuild/
16 | obj_dir
17 | test_run_dir
18 | generated
19 | .metals
20 | .bloop
21 | .bsp
22 | .vscode
23 |
--------------------------------------------------------------------------------
/blinky/.scalafix.conf:
--------------------------------------------------------------------------------
1 | rules = [
2 | RemoveUnused,
3 | DisableSyntax,
4 | LeakingImplicitClassVal,
5 | NoAutoTupling,
6 | NoValInForComprehension,
7 | OrganizeImports,
8 | ProcedureSyntax,
9 | ]
10 |
11 | OrganizeImports {
12 | groupedImports = Merge
13 | }
14 |
15 | RemoveUnused {
16 | imports = false // handled by OrganizeImports
17 | }
--------------------------------------------------------------------------------
/blinky/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = "2.7.5"
2 | maxColumn = 120
3 | align.preset = most
4 | align.multiline = false
5 | continuationIndent.defnSite = 2
6 | assumeStandardLibraryStripMargin = true
7 | docstrings = JavaDoc
8 | lineEndings = preserve
9 | includeCurlyBraceInSelectChains = false
10 | danglingParentheses.preset = true
11 | optIn.annotationNewlines = true
12 | newlines.alwaysBeforeMultilineDef = false
13 |
14 | rewrite.rules = [RedundantBraces]
15 |
16 | rewrite.redundantBraces.generalExpressions = false
17 | rewriteTokens = {
18 | "⇒": "=>"
19 | "→": "->"
20 | "←": "<-"
21 | }
--------------------------------------------------------------------------------
/blinky/.travis.yml:
--------------------------------------------------------------------------------
1 | language: minimal
2 | install: skip
3 |
4 | services: docker
5 |
6 | before_install: docker pull verilator/verilator:latest
7 |
8 | script:
9 | # Unset the VERILATOR variable so the container won't fail when running inside another container in Travis
10 | docker run --rm -t -v `pwd`:/build -w /build --entrypoint /bin/bash verilator/verilator:latest -c "apt update && apt install -y default-jre-headless python3-pexpect curl && make VERILATOR= check"
11 |
--------------------------------------------------------------------------------
/blinky/LICENSE:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 |
4 |
5 | The MIT License (MIT)
6 |
7 | Copyright (c) 2021 Carlos Eduardo de Paula (carlosedp@gmail.com)
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in
17 | all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/blinky/Makefile:
--------------------------------------------------------------------------------
1 | # Define board parameters
2 | include Makefile.boards
3 | SHELL = bash
4 |
5 | # Project name and toplevel
6 | project = toplevel
7 | toplevel = Toplevel
8 |
9 | # Use Docker images
10 | DOCKER=docker
11 |
12 | PWD = $(shell pwd)
13 | USBDEVICE ?= /dev/bus/usb
14 | DOCKERARGS = run --rm -v $(PWD):/src -w /src
15 | VERILATORARGS = run --name verilator --hostname verilator --rm -it --entrypoint= -v $(PWD):/work -w /work
16 |
17 | ifeq ($(DOCKER),docker)
18 | YOSYS = $(DOCKER) $(DOCKERARGS) hdlc/yosys yosys
19 | NEXTPNR = $(DOCKER) $(DOCKERARGS) hdlc/nextpnr nextpnr-$(FPGA)
20 | ECPPACK = $(DOCKER) $(DOCKERARGS) hdlc/prjtrellis ecppack
21 | ICEPACK = $(DOCKER) $(DOCKERARGS) hdlc/icestorm icepack
22 | OPENOCD_DEF = $(DOCKER) $(DOCKERARGS) --privileged --device $(USBDEVICE):/dev/bus/usb hdlc/prog openocd
23 | VERILATOR = $(DOCKER) $(VERILATORARGS) hdlc/verilator
24 | else
25 | YOSYS = yosys
26 | NEXTPNR = nextpnr-$(FPGA)
27 | ECPPACK = ecppack
28 | ICEPACK = icepack
29 | OPENOCD_DEF = openocd
30 | OPENOCD_ULX3S = openocd
31 | VERILATOR = verilator
32 | endif
33 |
34 | scala_files = $(wildcard src/main/scala/*scala)
35 | generated_files = generated
36 | verilog_files = $(generated_files)/*.v
37 |
38 | # Targets
39 | chisel: $(verilog_files) ## Generates Verilog code from Chisel sources using Mill
40 | $(verilog_files): $(scala_files) check-board-vars clean
41 | scripts/mill $(project).run -board ${BOARD} -td $(generated_files)
42 |
43 | chisel-sbt: ## Generates Verilog code from Chisel sources using SBT
44 | sbt "run -board ${BOARD} -td $(generated_files)"
45 |
46 | chisel_tests:
47 | scripts/mill $(project).test
48 |
49 | check: chisel_tests ## Run Chisel tests
50 |
51 | fmt:
52 | scripts/mill all $(project).{reformat,fix}
53 |
54 | synth: check-board-vars $(project).bit ## Synthesizes for target BOARD with "make BOARD=board synth"
55 |
56 | check-board-vars:
57 | @test -n "$(BOARD)" || (echo "Set BOARD variable to a board from:" ; echo -n " "; cat Makefile.boards|grep BOARD| cut -d ',' -f 2 |tr -s ')\n' ', ' | sed 's/, $$/\n/'; echo "Eg. make chisel BOARD=polarfireeval"; echo; exit 1)
58 |
59 | $(project).json: $(verilog_files)
60 | $(YOSYS) -p "read_verilog -sv $^; synth_$(FPGA) -json $(generated_files)/$@ -top $(toplevel)"
61 |
62 | $(project).config: $(project).json $(LPF)
63 | $(NEXTPNR) --json $(generated_files)/$< --lpf $(LPF) --textcfg $(generated_files)/$@ $(NEXTPNR_FLAGS) --package $(PACKAGE)
64 |
65 | $(project).bit: $(project).config
66 | $(PACK) --svf $(generated_files)/$(project).svf $(generated_files)/$< $(generated_files)/$@
67 |
68 | $(project).svf: $(project).bit
69 |
70 | prog: check-board-vars $(project).svf ## Programs target BOARD with "make BOARD=board prog"
71 | $(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $(generated_files)/$(project).svf; exit"
72 |
73 | clean: ## Clean all generated files
74 | @./scripts/mill clean
75 | @rm -rf obj_dir test_run_dir target
76 | @rm -rf $(generated_files)
77 | @rm -rf out
78 | @rm -f $(project)
79 |
80 | help:
81 | @echo "Makefile targets:"
82 | @echo ""
83 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = "[:##]"}; {printf "\033[36m%-20s\033[0m %s\n", $$2, $$5}'
84 | @echo ""
85 | @echo "Supported boards:"
86 | @echo ""
87 | @grep -E 'BOARD|##' Makefile.boards |sed 's/.*BOARD)\,\(.*\))/\1/' | sed -n 'N;s/\n/ /;p' | awk -F"[ \t]*##" '{printf "\033[36m%-15s\033[0m - %s\n", $$1, $$2}'
88 |
89 | .PHONY: chisel clean prog help
90 | .PRECIOUS: $(project).json $(project).config $(project).bit
91 | .DEFAULT_GOAL := help
92 |
--------------------------------------------------------------------------------
/blinky/Makefile.boards:
--------------------------------------------------------------------------------
1 | // code: language=makefile tabSize=4
2 |
3 | ifeq ($(BOARD),evn)
4 | ## ECP5-EVN
5 | FPGA=ecp5
6 | PACK=$(ECPPACK)
7 | LPF=constraints/ecp5-evn.lpf
8 | PLL=pll/pll_ehxplll.v
9 | PACKAGE=CABGA381
10 | NEXTPNR_FLAGS=--um5g-85k --freq 12
11 | OPENOCD=$(OPENOCD_DEF)
12 | OPENOCD_JTAG_CONFIG=openocd/ecp5-evn.cfg
13 | OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
14 | else ifeq ($(BOARD),ulx3s)
15 | ## Radiona ULX3S with ECP5-85F
16 | FPGA=ecp5
17 | PACK=$(ECPPACK)
18 | LPF=constraints/ecp5-ulx3s.lpf
19 | PLL=pll/pll_ehxplll_25MHz.v
20 | PACKAGE=CABGA381
21 | NEXTPNR_FLAGS=--85k --freq 25
22 | OPENOCD=$(OPENOCD_ULX3S)
23 | OPENOCD_JTAG_CONFIG=openocd/ft231x.cfg
24 | OPENOCD_DEVICE_CONFIG=openocd/LFE5U-85F.cfg
25 | else ifeq ($(BOARD),orangecrab)
26 | ## OrangeCrab with ECP85
27 | FPGA=ecp5
28 | PACK=$(ECPPACK)
29 | LPF=constraints/orange-crab.lpf
30 | PLL=pll/pll_bypass.v
31 | PACKAGE=CSFBGA285
32 | NEXTPNR_FLAGS=--um5g-85k --freq 50
33 | OPENOCD=$(OPENOCD_DEF)
34 | OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
35 | OPENOCD_DEVICE_CONFIG=openocd/LFE5UM5G-85F.cfg
36 | else ifeq ($(BOARD),colorlight)
37 | ## Colorlight 5A-75B
38 | FPGA=ecp5
39 | PACK=$(ECPPACK)
40 | LPF=constraints/colorlight_5A-75B.lpf
41 | PLL=pll/pll_ehxplll_25MHz.v
42 | PACKAGE=CABGA256
43 | NEXTPNR_FLAGS=--25k --freq 25
44 | OPENOCD=$(OPENOCD_DEF)
45 | OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
46 | OPENOCD_DEVICE_CONFIG=openocd/LFE5U-25F.cfg
47 | else ifeq ($(BOARD),fomu)
48 | ## Fomu PVT1 - Test
49 | FPGA=ice40
50 | PACK=$(ICEPACK)
51 | LPF=constraints/fomu-pvt1.lpf
52 | PACKAGE=uwg30
53 | NEXTPNR_FLAGS=--up5k
54 | # TODO - Define parameters below
55 | OPENOCD=$(OPENOCD_DEF)
56 | OPENOCD_JTAG_CONFIG=openocd/olimex-arm-usb-tiny-h.cfg
57 | OPENOCD_DEVICE_CONFIG=openocd/LFE5U-25F.cfg
58 | else
59 | endif
--------------------------------------------------------------------------------
/blinky/README.md:
--------------------------------------------------------------------------------
1 | # Chisel Blinky
2 |
3 | This is a simple Blinky project to demonstrate Chisel functionality with build scripts
4 | and tooling to be able to synth on FPGA boards.
5 |
6 | The Chisel sources uses a `-board` parameter to define which board is used and generate the proper PLL and build. To support this, an utility module was created.
7 |
8 | The project also have a visual test spec that indicates the "blink" behavior that can be run with `./scripts/mill toplevel.test.testOne BlinkySpec`.
9 |
10 | ## Building
11 |
12 | The project provides two building methods. The first and recommended is using [Fusesoc](https://github.com/olofk/fusesoc), a package manager that handles all board backend files and configuration. It also makes adding support to new boards and vendors much easier.
13 |
14 | A second method is using the built-in Makefile that provides support for some boards.
15 |
16 | ### Fusesoc build and generation
17 |
18 | To install Fusesoc (requires Python3 and pip3):
19 |
20 | ```sh
21 | pip3 install --upgrade --user fusesoc
22 | ```
23 |
24 | Check if it's working:
25 |
26 | ```sh
27 | $ fusesoc --version
28 | 1.12.0
29 | ```
30 |
31 | If the terminal reports an error about the command not being found check that the directory `~/.local/bin` is in your command search path (`export PATH=~/.local/bin:$PATH`).
32 |
33 | Fusesoc allows multiple boards from different vendors to be supported by the project. It uses chisel-generator to generate Verilog from Scala sources and calls the correct board EDA backend to create it's project files.
34 |
35 | For example, to generate the programming files for the **ULX3s** based on ECP5:
36 |
37 | ```sh
38 | mkdir fusesoc-chiselblinky && cd fusesoc-chiselblinky
39 |
40 | fusesoc library add fusesoc-cores https://github.com/fusesoc/fusesoc-cores
41 |
42 | # Since Blinky is not a standalone repo (but a folder in an umbrella repo)
43 | # We clone it locally and add the library as a local dir.
44 | git clone https://github.com/carlosedp/chisel-playground
45 | fusesoc library add chiselblinky $(pwd)/chisel-playground/blinky
46 |
47 | fusesoc run --target=ulx3s-85 carlosedp:demo:chiselblinky:0
48 | ...
49 | ...
50 | # Output bitstream will be on build/carlosedp_demo_chiselblinky_0/ulx3s-85-trellis
51 | ❯ ll build/carlosedp_demo_chiselblinky_0/ulx3s-85-trellis
52 | total 2.7M
53 | -rw-r--r-- 1 cdepaula staff 774 Apr 7 18:53 carlosedp_demo_chiselblinky_0.eda.yml
54 | -rw-r--r-- 1 cdepaula staff 545 Apr 7 18:53 carlosedp_demo_chiselblinky_0.tcl
55 | -rw-r--r-- 1 cdepaula staff 435 Apr 7 18:53 carlosedp_demo_chiselblinky_0.mk
56 | -rw-r--r-- 1 cdepaula staff 608 Apr 7 18:53 Makefile
57 | -rw-r--r-- 1 cdepaula staff 9.5K Apr 7 18:53 carlosedp_demo_chiselblinky_0.blif
58 | -rw-r--r-- 1 cdepaula staff 655K Apr 7 18:53 carlosedp_demo_chiselblinky_0.json
59 | -rw-r--r-- 1 cdepaula staff 44K Apr 7 18:53 carlosedp_demo_chiselblinky_0.edif
60 | -rw-r--r-- 1 cdepaula staff 45K Apr 7 18:53 yosys.log
61 | -rw-r--r-- 1 cdepaula staff 8.7K Apr 7 18:53 next.log
62 | -rw-r--r-- 1 cdepaula staff 1.9M Apr 7 18:53 carlosedp_demo_chiselblinky_0.bit
63 | ```
64 |
65 | Just program it to your FPGA with `OpenOCD` or in ULX3S case, [`ujprog`](https://github.com/f32c/tools/tree/master/ujprog)
66 |
67 | And for the **Microchip Polarfire** evaluation board, just change the target:
68 |
69 | ```sh
70 | fusesoc run --target=polarfireeval_es carlosedp:demo:chiselblinky:0
71 | ```
72 |
73 | ### Building on containers
74 |
75 | The standard build process uses locally installed tools like Java (for Chisel generation)Yosys, NextPNR, Vivado and others. Fusesoc also supports building the complete workflow by using containers thru a command launcher.
76 |
77 | To use it:
78 |
79 | ```sh
80 | # Download the command wrapper
81 | wget https://gist.github.com/carlosedp/c0e29d55e48309a48961f2e3939acfe9/raw/bfeb1cfe2e188c1d5ced0b09aabc9902fdfda6aa/runme.py
82 | chmod +x runme.py
83 |
84 | # Run fusesoc with the wrapper as an environment var
85 | EDALIZE_LAUNCHER=$(realpath ./runme.py) fusesoc run --target=ulx3s-85 carlosedp:demo:chiselblinky:0
86 |
87 | #The output files will be on the local ./build dir like before
88 | ```
89 |
90 | Here's a demo of it:
91 |
92 | [](https://asciinema.org/a/405850)
93 |
94 | ### Adding support to new boards
95 |
96 | Support for new boards can be added in the `chiselblinky.core` file.
97 |
98 | Three sections are required:
99 |
100 | #### Fileset
101 |
102 | Filesets lists the dependency files specific for each board that must be copied to the output project dir and used by EDA.
103 |
104 | ```yaml
105 | polarfireeval:
106 | files:
107 | - constraints/polarfire_evaluation.pdc: { file_type: PDC }
108 | # or for boards that contain programming files
109 | artya7-35t:
110 | files:
111 | - constraints/arty_a7.xdc: { file_type: xdc }
112 | - openocd/digilent-hs1.cfg: { file_type: user }
113 | - openocd/xilinx-xc7.cfg: { file_type: user }
114 | - proginfo/artix7-template.txt: { file_type: user }
115 | ```
116 |
117 | #### Generate
118 |
119 | The generator section contains the Chisel generator parameters. It has the arguments to be passed to Chisel (the board in this example), the project name and the output files created by the generator to be used by the EDA. Since they all inherit from the Chisel standard generator, it's a matter of using the `*baseparam` tag as:
120 |
121 | ```yaml
122 | polarfireeval:
123 | generator: chisel
124 | parameters:
125 | <<: *baseparam
126 | extraargs: "-board polarfireeval"
127 |
128 | # or if board doesn't use an inverse-reset (pulled down) switch
129 | qomu:
130 | generator: chisel
131 | parameters:
132 | <<: *baseparam
133 | extraargs: "-board qomu -invreset false"
134 | ```
135 |
136 | #### Target
137 |
138 | Finally the target section has the board information to be passed to the EDA tools. Parameters like the package/die or extra parameters to synthesis or PnR. This is highly dependent of the EDA backend. It's name is the one passed on the `--target=` param on FuseSoc. It also references the fileset and generate configs. Must contain the `base` fileset.
139 |
140 | ```yaml
141 | polarfireeval_es:
142 | default_tool: libero
143 | description: Microsemi Polarfire Evaluation Kit (ES)
144 | filesets: [base, polarfireeval]
145 | generate: [polarfireeval]
146 | tools:
147 | libero:
148 | family: PolarFire
149 | die: MPF300TS_ES
150 | package: FCG1152
151 | toplevel: Toplevel
152 | ```
153 |
154 | To add support to additional boards, create these sections (or reuse similar ones). More details can be found on [Edalize docs](https://github.com/olofk/edalize/) or using [Corescore](https://github.com/olofk/corescore) and [Blinky](https://github.com/fusesoc/blinky) as examples.
155 |
156 | ### Makefile build and generation
157 |
158 | The Makefiles support synthesis on some FPGAs using the Open Source toolchain based on yosys/nextpnr. This is deprecated might be removed in the future.
159 |
160 |
161 | Click to expand
162 |
163 | At the moment the tools support Lattice ECP5 FPGAs. The build process can use Docker images, so no software other than Docker needs to be installed. If you prefer Podman you can use that too, just adjust it in `Makefile`, `DOCKER=podman`. If the variable is undefined, build proceeds with locally installed tools.
164 |
165 | ### Building and programming the FPGA
166 |
167 | The `Makefile` currently supports the following FPGA boards by defining the `BOARD` parameter on make:
168 |
169 | * Lattice [ECP5 Evaluation Board](http://www.latticesemi.com/ecp5-evaluation) - `evn`
170 | * Radiona [ULX3S](https://radiona.org/ulx3s/) - `ulx3s`
171 | * Greg Davill [Orangecrab](https://github.com/gregdavill/OrangeCrab) - `orangecrab`
172 | * Q3k [Colorlight](https://github.com/q3k/chubby75/tree/master/5a-75b) - `colorlight`
173 |
174 | For example, to build for the ULX3S Board, run:
175 |
176 | ```sh
177 | make BOARD=ulx3s synth`
178 | ```
179 |
180 | After this command, all files will be generated in the `generated` output dir.
181 |
182 | To program your FPGA:
183 |
184 | ```sh
185 | make BOARD=ulx3s prog
186 |
187 | # or if your USB device has a different path, pass it on USBDEVICE, like:
188 |
189 | make BOARD=ulx3s USBDEVICE=/dev/tty.usbserial-120001 prog
190 | ```
191 |
192 | Programming using OpenOCD on Docker does not work on Docker Desktop for Mac/Windows since the container is run in a Linux VM and can not see the physical devices connected to the Host. In this case you need OpenOCD installed locally.
193 |
194 | For the ULX3S board, the current OpenOCD does not support ft232 protocol so to program it, download [ujprog](https://github.com/emard/ulx3s-bin/tree/master/usb-jtag) for your platform and program using `./ujprog chiselwatt.bit` or to persist in the flash, `./ujprog -j FLASH chiselwatt.bit`.
195 |
196 |
197 |
--------------------------------------------------------------------------------
/blinky/build.sbt:
--------------------------------------------------------------------------------
1 | // See README.md for license details.
2 |
3 | lazy val blinky = (project in file("."))
4 | .settings(
5 | organization := "com.carlosedp",
6 | name := "chisel-blinky",
7 | version := "0.0.1",
8 | scalaVersion := "2.13.8",
9 | semanticdbEnabled := true,
10 | semanticdbVersion := scalafixSemanticdb.revision,
11 | maxErrors := 3
12 | )
13 |
14 | // Library default versions
15 | val defaultVersions = Map(
16 | "chisel3" -> "3.5.1",
17 | "chisel-iotesters" -> "1.5.3",
18 | "chiseltest" -> "0.5.1",
19 | "scalatest" -> "3.2.11",
20 | "organize-imports" -> "0.5.0",
21 | "scalautils" -> "0.9.0"
22 | )
23 | // Import libraries
24 | libraryDependencies ++= Seq("chisel3", "chisel-iotesters", "chiseltest").map { dep: String =>
25 | "edu.berkeley.cs" %% dep % sys.props
26 | .getOrElse(dep + "Version", defaultVersions(dep))
27 | }
28 | libraryDependencies += "org.scalatest" %% "scalatest" % defaultVersions("scalatest")
29 | libraryDependencies += "com.carlosedp" %% "scalautils" % defaultVersions("scalautils")
30 | ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % defaultVersions("organize-imports")
31 |
32 | // Aliases
33 | addCommandAlias("com", "all compile test:compile")
34 | addCommandAlias("rel", "reload")
35 | addCommandAlias("fix", "all compile:scalafix test:scalafix")
36 | addCommandAlias("fmt", "all scalafmtSbt scalafmtAll")
37 |
38 | resolvers ++= Seq(
39 | Resolver.sonatypeRepo("snapshots"),
40 | Resolver.sonatypeRepo("releases")
41 | )
42 |
43 | addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % defaultVersions("chisel3") cross CrossVersion.full)
44 |
45 | scalacOptions ++= Seq(
46 | "-unchecked",
47 | "-deprecation",
48 | "-language:reflectiveCalls",
49 | "-feature",
50 | "-Xcheckinit",
51 | "-Xfatal-warnings",
52 | "-Ywarn-dead-code",
53 | "-Ywarn-unused"
54 | )
55 |
--------------------------------------------------------------------------------
/blinky/build.sc:
--------------------------------------------------------------------------------
1 | import mill._
2 | import mill.scalalib._
3 | import scalafmt._
4 | import coursier.MavenRepository
5 | import $ivy.`com.goyeau::mill-scalafix:0.2.2`
6 | import com.goyeau.mill.scalafix._
7 |
8 | def mainClass = Some("Toplevel")
9 |
10 | val defaultVersions = Map(
11 | "scala" -> "2.13.8",
12 | "chisel3" -> "3.5.1",
13 | "chisel-iotesters" -> "1.5.3",
14 | "chiseltest" -> "0.5.1",
15 | "scalatest" -> "3.2.11",
16 | "organize-imports" -> "0.6.0",
17 | "scalautils" -> "0.9.0",
18 | "semanticdb-scalac" -> "4.4.35"
19 | )
20 |
21 | trait HasChisel3 extends ScalaModule {
22 | override def ivyDeps = super.ivyDeps() ++ Agg(
23 | ivy"edu.berkeley.cs::chisel3:${defaultVersions("chisel3")}",
24 | ivy"com.carlosedp::scalautils:${defaultVersions("scalautils")}"
25 | )
26 | override def scalacPluginIvyDeps = super.scalacPluginIvyDeps() ++ Agg(
27 | ivy"edu.berkeley.cs:::chisel3-plugin:${defaultVersions("chisel3")}"
28 | )
29 | }
30 |
31 | trait HasChiselTests extends CrossSbtModule {
32 | object test extends Tests {
33 | override def ivyDeps = super.ivyDeps() ++ Agg(
34 | ivy"org.scalatest::scalatest:${defaultVersions("scalatest")}",
35 | ivy"edu.berkeley.cs::chisel-iotesters:${defaultVersions("chisel-iotesters")}",
36 | ivy"edu.berkeley.cs::chiseltest:${defaultVersions("chiseltest")}"
37 | )
38 | def repositories = super.repositories ++ Seq(
39 | MavenRepository("https://oss.sonatype.org/content/repositories/snapshots")
40 | )
41 | def testFrameworks = Seq("org.scalatest.tools.Framework")
42 |
43 | def testOne(args: String*) = T.command {
44 | super.runMain("org.scalatest.run", args: _*)
45 | }
46 | }
47 | }
48 |
49 | trait CodeQuality extends ScalafixModule with ScalafmtModule {
50 | def scalafixIvyDeps = Agg(ivy"com.github.liancheng::organize-imports:${defaultVersions("organize-imports")}")
51 | // Override semanticdb version due to unavailable 4.4.10 for Scala 2.12.14.
52 | override def scalacPluginIvyDeps =
53 | super.scalacPluginIvyDeps() ++ Agg(ivy"org.scalameta:::semanticdb-scalac:${defaultVersions("semanticdb-scalac")}")
54 | }
55 |
56 | trait Aliases extends Module {
57 | def fmt() = T.command {
58 | toplevel.reformat()
59 | toplevel.fix()
60 | }
61 | }
62 |
63 | trait ScalacOptions extends ScalaModule {
64 | override def scalacOptions = T {
65 | super.scalacOptions() ++ Seq(
66 | "-unchecked",
67 | "-deprecation",
68 | "-language:reflectiveCalls",
69 | "-feature",
70 | "-Xcheckinit",
71 | "-Xfatal-warnings",
72 | "-Ywarn-dead-code",
73 | "-Ywarn-unused"
74 | )
75 | }
76 | }
77 |
78 | object toplevel
79 | extends CrossSbtModule
80 | with HasChisel3
81 | with HasChiselTests
82 | with CodeQuality
83 | with Aliases
84 | with ScalacOptions {
85 | override def millSourcePath = super.millSourcePath
86 | def crossScalaVersion = defaultVersions("scala")
87 | }
88 |
--------------------------------------------------------------------------------
/blinky/chiselblinky.core:
--------------------------------------------------------------------------------
1 | CAPI=2:
2 |
3 | name: carlosedp:demo:chiselblinky:0
4 | description: A blinky demo written in Chisel HDL
5 |
6 | filesets:
7 | proginfo:
8 | files:
9 | - proginfo/proginfo.py : {file_type : user, copyto : proginfo.py}
10 | - proginfo/boardconfig.yaml : {file_type : user, copyto : boardconfig.yaml}
11 |
12 | base:
13 | depend: ["fusesoc:utils:generators"]
14 |
15 | polarfireeval:
16 | files:
17 | - constraints/polarfire_evaluation.pdc: { file_type: PDC }
18 |
19 | ulx3s-85:
20 | files:
21 | - constraints/ecp5-ulx3s.lpf: { file_type: LPF }
22 | - openocd/ft231x.cfg: { file_type: user }
23 | - openocd/LFE5U-85F.cfg: { file_type: user }
24 | - proginfo/ulx3s-template.txt: { file_type: user }
25 |
26 | artya7-35t:
27 | files:
28 | - constraints/arty_a7.xdc: { file_type: xdc }
29 | - openocd/digilent-hs1.cfg: { file_type: user }
30 | - openocd/xilinx-xc7.cfg: { file_type: user }
31 | - proginfo/artix7-template.txt: { file_type: user }
32 |
33 | nexys4ddr:
34 | files:
35 | - constraints/nexys4ddr.xdc: { file_type: xdc }
36 | - openocd/digilent-hs1.cfg: { file_type: user }
37 | - openocd/xilinx-xc7.cfg: { file_type: user }
38 |
39 | orange-crab:
40 | files:
41 | - constraints/orange-crab.lpf: { file_type: LPF }
42 | - proginfo/dfu-util.txt: { file_type: user }
43 |
44 | de1_soc_revF:
45 | files:
46 | - constraints/de1_soc_revF.sdc: { file_type: SDC }
47 | - constraints/de1_soc_revF.tcl: { file_type: tclSource }
48 |
49 | storey_peak_stratixV:
50 | files:
51 | - constraints/storey_peak_stratixV.sdc: { file_type: SDC }
52 | - constraints/storey_peak_stratixV.tcl: { file_type: tclSource }
53 |
54 | qomu:
55 | files:
56 | - constraints/qomu.pcf: { file_type: PCF }
57 | - proginfo/qomu-qf-template.txt: { file_type: user }
58 |
59 | qmtech_k325t:
60 | files:
61 | - constraints/qmtech-kintex7.xdc: { file_type: XDC }
62 | - proginfo/qmtech_k325t-template.txt: { file_type: user }
63 |
64 | qmtech_k325t_zyjzgw:
65 | files:
66 | - constraints/qmtech-zyjzgw.xdc: { file_type: XDC }
67 | - proginfo/qmtech_k325t-template.txt: { file_type: user }
68 |
69 | generate:
70 |
71 | default-chisel:
72 | generator: chisel
73 | parameters: &baseparam
74 | extraargs: "-board bypass"
75 | chiselproject: toplevel
76 | copy_core: true
77 | output:
78 | files:
79 | - generated/Toplevel.v: { file_type: verilogSource }
80 | - generated/PLL.v: { file_type: verilogSource }
81 |
82 |
83 | polarfireeval:
84 | generator: chisel
85 | parameters:
86 | <<: *baseparam
87 | extraargs: "-board polarfireeval"
88 |
89 | ulx3s:
90 | generator: chisel
91 | parameters:
92 | <<: *baseparam
93 | extraargs: "-board ulx3s"
94 |
95 | artya7-35t:
96 | generator: chisel
97 | parameters:
98 | <<: *baseparam
99 | extraargs: "-board artya7-35t --target:fpga --emission-options=disableMemRandomization,disableRegisterRandomization"
100 |
101 | nexys4ddr:
102 | generator: chisel
103 | parameters:
104 | <<: *baseparam
105 | extraargs: "-board nexys4ddr -invreset false"
106 |
107 | orange-crab:
108 | generator: chisel
109 | parameters:
110 | <<: *baseparam
111 | extraargs: "-board orange-crab"
112 |
113 | de1_soc_revF:
114 | generator: chisel
115 | parameters:
116 | <<: *baseparam
117 | extraargs: "-board de1_soc_revF"
118 |
119 | storey_peak_stratixV:
120 | generator: chisel
121 | parameters:
122 | <<: *baseparam
123 | extraargs: "-board storey_peak_stratixV"
124 |
125 | qomu:
126 | generator: chisel
127 | parameters:
128 | <<: *baseparam
129 | extraargs: "-board qomu -invreset false"
130 |
131 | qmtech_k325t:
132 | generator: chisel
133 | parameters:
134 | <<: *baseparam
135 | extraargs: "-board qmtech_k325t -invreset true"
136 |
137 | targets:
138 | polarfireeval_es:
139 | default_tool: libero
140 | description: Microsemi Polarfire Evaluation Kit (ES)
141 | filesets: [base, polarfireeval]
142 | generate: [polarfireeval]
143 | tools:
144 | libero:
145 | family: PolarFire
146 | die: MPF300TS_ES
147 | package: FCG1152
148 | toplevel: Toplevel
149 |
150 | ulx3s-85:
151 | default_tool: trellis
152 | description: ULX3S 85k version
153 | filesets: [base, ulx3s-85, proginfo]
154 | generate: [ulx3s]
155 | hooks:
156 | post_run: [ulx3s-85f]
157 | tools:
158 | diamond:
159 | part: LFE5U-85F-6BG381C
160 | trellis:
161 | nextpnr_options: [--package, CABGA381, --85k]
162 | yosys_synth_options: [-abc9, -nowidelut]
163 | toplevel: Toplevel
164 |
165 | artya7-35t:
166 | default_tool : vivado
167 | description: Digilent ArtyA7-35T Board
168 | filesets : [base, artya7-35t]
169 | generate: [artya7-35t]
170 | tools:
171 | vivado:
172 | part : xc7a35ticsg324-1L
173 | toplevel : Toplevel
174 |
175 | nexys4ddr:
176 | default_tool : vivado
177 | description: Digilent Nexys 4 DDR (and Nexys A7) board
178 | filesets : [base, nexys4ddr]
179 | generate: [nexys4ddr]
180 | tools:
181 | vivado:
182 | part : xc7a100tcsg324-1
183 | toplevel : Toplevel
184 |
185 | artya7-35t-oss:
186 | default_tool : symbiflow
187 | description: Digilent ArtyA7-35T Board using Symbiflow OSS Toolchain
188 | filesets : [base, artya7-35t, proginfo]
189 | generate: [artya7-35t]
190 | hooks:
191 | post_run: [artya7-35t]
192 | tools:
193 | symbiflow:
194 | part : xc7a35t
195 | package: csg324-1
196 | vendor: xilinx
197 | pnr: vtr
198 | toplevel : Toplevel
199 |
200 | orange-crab:
201 | default_tool: trellis
202 | description: GsD orangecrab version 0.2
203 | filesets: [base, orange-crab, proginfo]
204 | generate: [orange-crab]
205 | hooks:
206 | post_run: [dfu-util]
207 | tools:
208 | trellis:
209 | nextpnr_options : [--package, CSFBGA285, --25k]
210 | toplevel: Toplevel
211 |
212 | de1_soc_revF:
213 | default_tool : quartus
214 | description: Altera Cyclone V DE1_SoC board, revision F
215 | filesets : [base, de1_soc_revF]
216 | generate : [de1_soc_revF]
217 | tools:
218 | quartus:
219 | family : Cyclone V
220 | device : 5CSEMA5F31C6
221 | board_device_index : 2
222 | toplevel: Toplevel
223 |
224 | storey_peak_stratixV:
225 | default_tool : quartus
226 | description: Microsoft Storey Peak (Catapult) Stratix V FPGA Accelerator
227 | filesets : [base, storey_peak_stratixV]
228 | generate : [storey_peak_stratixV]
229 | tools:
230 | quartus:
231 | family : Stratix V
232 | device : 5SGSMD5K1F40C2
233 | toplevel: Toplevel
234 |
235 | qomu:
236 | default_tool : symbiflow
237 | description: Qomu, a Quicklogic EOS S3 board using Symbiflow OSS Toolchain
238 | filesets : [base, qomu, proginfo]
239 | generate: [qomu]
240 | tools:
241 | symbiflow:
242 | part : ql-eos-s3
243 | package: WR42
244 | vendor: quicklogic
245 | pnr: vtr
246 | toolchain_prefix: ql-
247 | toplevel : Toplevel
248 |
249 | qmtech_k325t: &qmtech_k325t
250 | default_tool : xray
251 | description: QMTech Kintex 7 K325T Board using Project X-Ray OSS Toolchain
252 | filesets : [base, qmtech_k325t, proginfo]
253 | generate: [qmtech_k325t]
254 | hooks:
255 | post_run: [qmtech_k325t]
256 | tools:
257 | xray:
258 | part : xc7k325t
259 | package: ffg676-1
260 | yosys_synth_options: [-abc9, -flatten]
261 | nextpnr_options: [--verbose, --debug]
262 | toplevel : Toplevel
263 |
264 | qmtech_k325t_zyjzgw:
265 | <<: *qmtech_k325t
266 | description: QMTech Kintex 7 K325T ZYJZGW Board using Project X-Ray OSS Toolchain
267 | filesets : [base, qmtech_k325t_zyjzgw, proginfo]
268 |
269 | scripts:
270 | artya7-35t:
271 | cmd : [python3, proginfo.py, artya7-35t]
272 | dfu-util:
273 | cmd : [python3, proginfo.py, dfu-util]
274 | ulx3s-85f:
275 | cmd : [python3, proginfo.py, ulx3s-85f]
276 | qmtech_k325t:
277 | cmd : [python3, proginfo.py, qmtech_k325t]
278 |
--------------------------------------------------------------------------------
/blinky/constraints/arty_a7.xdc:
--------------------------------------------------------------------------------
1 | # Clock pin
2 | set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports {clock}]
3 |
4 | # LEDs
5 | set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports {io_led0}]
6 | set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports {io_led1}]
7 | set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports {io_led2}]
8 |
9 | # Switches
10 | set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { reset }]
11 |
12 | # Clock constraints
13 | create_clock -period 10.0 [get_ports {clock}]
14 |
--------------------------------------------------------------------------------
/blinky/constraints/de1_soc_revF.sdc:
--------------------------------------------------------------------------------
1 | # Main system clock (50 Mhz)
2 | create_clock -name "clk" -period 20.000ns [get_ports {clk}]
3 |
4 | # Automatically constrain PLL and other generated clocks
5 | derive_pll_clocks -create_base_clocks
6 |
7 | # Automatically calculate clock uncertainty to jitter and other effects.
8 | derive_clock_uncertainty
9 |
--------------------------------------------------------------------------------
/blinky/constraints/de1_soc_revF.tcl:
--------------------------------------------------------------------------------
1 | # Clock
2 | set_location_assignment PIN_AF14 -to clock
3 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clock
4 |
5 | # Reset
6 | set_location_assignment PIN_AA14 -to reset
7 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to reset
8 |
9 | # LEDs
10 | set_location_assignment PIN_V16 -to io_led0
11 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to io_led0
12 | set_location_assignment PIN_W16 -to io_led1
13 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to io_led1
14 | set_location_assignment PIN_V17 -to io_led2
15 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to io_led2
--------------------------------------------------------------------------------
/blinky/constraints/ecp5-evn.lpf:
--------------------------------------------------------------------------------
1 | LOCATE COMP "clock" SITE "A10";
2 | IOBUF PORT "clock" IO_TYPE=LVCMOS33;
3 |
4 | LOCATE COMP "reset" SITE "P4";
5 | IOBUF PORT "reset" IO_TYPE=LVCMOS33;
6 |
7 | LOCATE COMP "io_tx" SITE "P3";
8 | LOCATE COMP "io_rx" SITE "P2";
9 |
10 | IOBUF PORT "io_tx" IO_TYPE=LVCMOS33;
11 | IOBUF PORT "io_rx" IO_TYPE=LVCMOS33;
12 |
13 | LOCATE COMP "io_led0" SITE "A13";
14 | LOCATE COMP "io_led1" SITE "A12";
15 | LOCATE COMP "io_led2" SITE "B19";
16 |
17 | IOBUF PORT "io_led0" IO_TYPE=LVCMOS25;
18 | IOBUF PORT "io_led1" IO_TYPE=LVCMOS25;
19 | IOBUF PORT "io_led2" IO_TYPE=LVCMOS25;
20 |
--------------------------------------------------------------------------------
/blinky/constraints/ecp5-ulx3s.lpf:
--------------------------------------------------------------------------------
1 | LOCATE COMP "clock" SITE "G2";
2 | IOBUF PORT "clock" PULLMODE=NONE IO_TYPE=LVCMOS33;
3 | FREQUENCY PORT "clock" 25 MHZ;
4 |
5 | LOCATE COMP "reset" SITE "D6";
6 | IOBUF PORT "reset" PULLMODE=UP IO_TYPE=LVCMOS33;
7 |
8 | LOCATE COMP "io_tx" SITE "L4";
9 | LOCATE COMP "io_rx" SITE "M1";
10 |
11 | IOBUF PORT "io_tx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
12 | IOBUF PORT "io_rx" PULLMODE=UP IO_TYPE=LVCMOS33;
13 |
14 | LOCATE COMP "io_led7" SITE "H3";
15 | LOCATE COMP "io_led6" SITE "E1";
16 | LOCATE COMP "io_led5" SITE "E2";
17 | LOCATE COMP "io_led4" SITE "D1";
18 | LOCATE COMP "io_led3" SITE "D2";
19 | LOCATE COMP "io_led2" SITE "C1";
20 | LOCATE COMP "io_led1" SITE "C2";
21 | LOCATE COMP "io_led0" SITE "B2";
22 | IOBUF PORT "io_led0" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
23 | IOBUF PORT "io_led1" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
24 | IOBUF PORT "io_led2" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
25 | IOBUF PORT "io_led3" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
26 | IOBUF PORT "io_led4" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
27 | IOBUF PORT "io_led5" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
28 | IOBUF PORT "io_led6" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
29 | IOBUF PORT "io_led7" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
--------------------------------------------------------------------------------
/blinky/constraints/fomu-pvt1.lpf:
--------------------------------------------------------------------------------
1 | set_io clock F4
2 |
3 | set_io io_led0 A5
4 | set_io io_led1 B5
5 | set_io io_led2 C5
6 |
7 | set_io reset E4
8 | set_io touch_2 D5
9 | set_io touch_3 E5
10 | set_io touch_4 F5
11 |
12 | set_io pmod_1 E4
13 | set_io pmod_2 D5
14 | set_io pmod_3 E5
15 | set_io pmod_4 F5
16 | set_io pmoda_1 E4
17 | set_io pmoda_2 D5
18 | set_io pmoda_3 E5
19 | set_io pmoda_4 F5
20 | set_io user_1 E4
21 | set_io user_2 D5
22 | set_io user_3 E5
23 | set_io user_4 F5
24 | set_io spi_mosi F1
25 | set_io spi_miso E1
26 | set_io spi_clk D1
27 | set_io spi_io2 F2
28 | set_io spi_io3 B1
29 | set_io spi_cs C1
30 | set_io usb_dn A2
31 | set_io usb_dp A1
32 | set_io usb_dp_pu A4
33 |
--------------------------------------------------------------------------------
/blinky/constraints/nexys4ddr.xdc:
--------------------------------------------------------------------------------
1 | # Clock pin
2 | set_property PACKAGE_PIN E3 [get_ports {clock}]
3 | set_property IOSTANDARD LVCMOS33 [get_ports {clock}]
4 | create_clock -period 10.0 [get_ports {clock}]
5 |
6 | # LEDs
7 | set_property PACKAGE_PIN H17 [get_ports {io_led0}]
8 | set_property PACKAGE_PIN K15 [get_ports {io_led1}]
9 | set_property PACKAGE_PIN J13 [get_ports {io_led2}]
10 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led0}]
11 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led1}]
12 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led2}]
13 |
14 | # Center button assigned to reset
15 | set_property PACKAGE_PIN N17 [get_ports { reset }]
16 | set_property IOSTANDARD LVCMOS33 [get_ports { reset }]
17 |
--------------------------------------------------------------------------------
/blinky/constraints/orange-crab.lpf:
--------------------------------------------------------------------------------
1 | LOCATE COMP "clock" SITE "A9";
2 | IOBUF PORT "clock" IO_TYPE=LVCMOS33;
3 | FREQUENCY PORT "clock" 48.000 MHZ;
4 |
5 | LOCATE COMP "reset" SITE "J17";
6 | IOBUF PORT "reset" IO_TYPE=SSTL135_I;
7 |
8 | LOCATE COMP "io_tx" SITE "N17";
9 | LOCATE COMP "io_rx" SITE "M18";
10 |
11 | IOBUF PORT "io_tx" IO_TYPE=LVCMOS33;
12 | IOBUF PORT "io_rx" IO_TYPE=LVCMOS33;
13 |
14 | LOCATE COMP "io_led0" SITE "K4";
15 | LOCATE COMP "io_led1" SITE "M3";
16 | LOCATE COMP "io_led2" SITE "J3";
17 |
18 | IOBUF PORT "io_led0" IO_TYPE=LVCMOS33;
19 | IOBUF PORT "io_led1" IO_TYPE=LVCMOS33;
20 | IOBUF PORT "io_led2" IO_TYPE=LVCMOS33;
21 |
--------------------------------------------------------------------------------
/blinky/constraints/polarfire_evaluation.pdc:
--------------------------------------------------------------------------------
1 | set_io -port_name {clock} -pin_name E25 -io_std LVCMOS18 -fixed true
2 | set_io -port_name {reset} -pin_name K22 -io_std LVCMOS18 -fixed true
3 |
4 | set_io -port_name {io_sw0} -pin_name B27 -io_std LVCMOS18 -fixed true
5 | set_io -port_name {io_sw1} -pin_name C21 -io_std LVCMOS18 -fixed true
6 | set_io -port_name {io_sw2} -pin_name A25 -io_std LVCMOS18 -fixed true
7 | set_io -port_name {io_sw3} -pin_name B19 -io_std LVCMOS18 -fixed true
8 |
9 | set_io -port_name {io_tx} -pin_name H18 -io_std LVCMOS18 -fixed true
10 | set_io -port_name {io_rx} -pin_name G17 -io_std LVCMOS18 -fixed true
11 |
12 | set_io -port_name {io_led0} -pin_name F22 -io_std LVCMOS18 -fixed true
13 | set_io -port_name {io_led1} -pin_name B26 -io_std LVCMOS18 -fixed true
14 | set_io -port_name {io_led2} -pin_name C26 -io_std LVCMOS18 -fixed true
15 | set_io -port_name {io_led3} -pin_name D25 -io_std LVCMOS18 -fixed true
16 | set_io -port_name {io_led4} -pin_name C27 -io_std LVCMOS18 -fixed true
17 | set_io -port_name {io_led5} -pin_name F23 -io_std LVCMOS18 -fixed true
18 | set_io -port_name {io_led6} -pin_name H22 -io_std LVCMOS18 -fixed true
19 | set_io -port_name {io_led7} -pin_name H21 -io_std LVCMOS18 -fixed true
20 |
21 | set_io -port_name {io_dip1} -pin_name H23 -io_std LVCMOS18 -fixed true
22 | set_io -port_name {io_dip2} -pin_name D21 -io_std LVCMOS18 -fixed true
23 | set_io -port_name {io_dip3} -pin_name H24 -io_std LVCMOS18 -fixed true
24 | set_io -port_name {io_dip4} -pin_name C22 -io_std LVCMOS18 -fixed true
25 | set_io -port_name {io_dip5} -pin_name B21 -io_std LVCMOS18 -fixed true
26 | set_io -port_name {io_dip6} -pin_name G20 -io_std LVCMOS18 -fixed true
27 | set_io -port_name {io_dip7} -pin_name F24 -io_std LVCMOS18 -fixed true
28 | set_io -port_name {io_dip8} -pin_name F25 -io_std LVCMOS18 -fixed true
29 |
--------------------------------------------------------------------------------
/blinky/constraints/qmtech-kintex7.xdc:
--------------------------------------------------------------------------------
1 | ##### Core board #####
2 | # Clock
3 | set_property LOC F22 [get_ports clock]
4 | set_property IOSTANDARD LVCMOS33 [get_ports {clock}]
5 |
6 | # LED2_FPGA J26
7 | set_property LOC J26 [get_ports io_led0]
8 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led0}]
9 |
10 | # LED3_FPGA H26
11 | set_property LOC H26 [get_ports io_led2]
12 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led2}]
13 |
14 | ##Buttons
15 | # Sw 2 - AF9
16 | # set_property LOC AF9 [get_ports reset]
17 | # set_property IOSTANDARD LVCMOS33 [get_ports {reset}]
18 |
19 | # Sw 3 - AF10
20 | # set_property LOC AF10 [get_ports sw3]
21 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw3}]
22 |
23 | ##### Daughter board #####
24 |
25 | # LED0
26 | # set_property LOC A18 [get_ports io_led0]
27 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_led0}]
28 |
29 | # LED1
30 | # set_property LOC A19 [get_ports io_led1]
31 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_led1}]
32 |
33 | # LED2
34 | # set_property LOC C17 [get_ports io_led2]
35 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_led2}]
36 |
37 | # LED3
38 | # set_property LOC C18 [get_ports io_led3]
39 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_led3}]
40 |
41 | # LED4
42 | # set_property LOC E18 [get_ports io_GPIO0[3]]
43 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_GPIO0[3]}]
44 |
45 | ##Buttons
46 | # SW2
47 | set_property LOC B20 [get_ports reset]
48 | set_property IOSTANDARD LVCMOS33 [get_ports {reset}]
49 | # SW3
50 | # set_property LOC A20 [get_ports d_sw3]
51 | # set_property IOSTANDARD LVCMOS33 [get_ports {d_sw3}]
52 | # SW4
53 | # set_property LOC C19 [get_ports d_sw4]
54 | # set_property IOSTANDARD LVCMOS33 [get_ports {d_sw4}]
55 | # SW5
56 | # set_property LOC B19 [get_ports d_sw5]
57 | # set_property IOSTANDARD LVCMOS33 [get_ports {d_sw5}]
58 |
59 |
60 | ##USB-UART Interface (On jp3 in daughter board) Pin 1 - GND, Pin 3 - TX, Pin 5 - RX
61 | # set_property LOC B12 [get_ports io_UART0tx]
62 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_UART0tx}]
63 | # set_property LOC B11 [get_ports io_UART0rx]
64 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_UART0rx}]
--------------------------------------------------------------------------------
/blinky/constraints/qmtech-zyjzgw.xdc:
--------------------------------------------------------------------------------
1 | ##### Core board #####
2 |
3 | set_property LOC F22 [get_ports clock]
4 | set_property IOSTANDARD LVCMOS33 [get_ports {clock}]
5 |
6 | # LED2_FPGA R26
7 | set_property LOC R26 [get_ports io_led0]
8 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led0}]
9 |
10 | # LED3_FPGA P26
11 | set_property LOC P26 [get_ports io_led2]
12 | set_property IOSTANDARD LVCMOS33 [get_ports {io_led2}]
13 |
14 | ##Buttons
15 | # Sw 2 - AB26
16 | set_property LOC AB26 [get_ports reset]
17 | set_property IOSTANDARD LVCMOS33 [get_ports {reset}]
18 |
19 | # Sw 3 - AC26
20 | # set_property LOC AC26 [get_ports sw3]
21 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw3}]
22 |
23 | ##### Daughter board #####
24 |
25 | # LED3_FPGA BANK14_E25
26 | # set_property LOC E25 [get_ports io_led1]
27 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_led1}]
28 |
29 | # LED4_FPGA BANK16_C14
30 | # set_property LOC C14 [get_ports io_GPIO0[2]]
31 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_GPIO0[2]}]
32 |
33 | # LED5_FPGA BANK16_B14
34 | # set_property LOC B14 [get_ports io_GPIO0[3]]
35 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_GPIO0[3]}]
36 |
37 | ##Buttons
38 | # Sw1
39 | # set_property LOC Y22 [get_ports sw1]
40 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw1}]
41 | # Sw2
42 | # set_property LOC AA22 [get_ports sw2]
43 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw2}]
44 | # Sw3
45 | # set_property LOC Y23 [get_ports sw3]
46 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw3}]
47 | # Sw4
48 | # set_property LOC AA24 [get_ports sw4]
49 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw4}]
50 | # Sw5
51 | # set_property LOC AC23 [get_ports sw5]
52 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw5}]
53 | # Sw6
54 | # set_property LOC AC24 [get_ports sw6]
55 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw6}]
56 | # Sw7
57 | # set_property LOC AA25 [get_ports sw7]
58 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw7}]
59 | # Sw8
60 | # set_property LOC AB25 [get_ports sw8]
61 | # set_property IOSTANDARD LVCMOS33 [get_ports {sw8}]
62 |
63 |
64 | ##USB-UART Interface (On jp3 in daughter board) Pin 1 - GND, Pin 3 - TX, Pin 5 - RX
65 | # set_property LOC AE26 [get_ports io_UART0tx]
66 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_UART0tx}]
67 | # set_property LOC AD26 [get_ports io_UART0rx]
68 | # set_property IOSTANDARD LVCMOS33 [get_ports {io_UART0rx}]
--------------------------------------------------------------------------------
/blinky/constraints/qomu.pcf:
--------------------------------------------------------------------------------
1 | // QuickFeather uses the QFN package, others mostly use the BGA package.
2 | // can do (QFN) : set_io SIGNAL_NAME QFN_PIN_NUM
3 | // can do (BGA) : set_io SIGNAL_NAME BGA_BALL_NUM
4 | // can do (WLCSP) : set_io SIGNAL_NAME WLCSP_PIN_NUM
5 | // can do (ALL) : set_io SIGNAL_NAME IO_PAD_NUM
6 | //
7 | // RED LED, for example is on IO_22, which is QFN_PIN_NUM 34 (BGA BALL G7)
8 | // so,
9 | // (QFN) : set_io red_led 34
10 | // (BGA) : set_io red_led G7
11 | // (ALL) : set_io red_led IO_22
12 | // are equivalent
13 | // NOTE that the WLSCP version of EOSS3 does not have IO_22 brought out at all!
14 | // So, this signal cannot be used with the WLCSP package.
15 | //
16 | // by using the IO_PAD_NUM -> we don't need to change PCF across chip package variants.
17 | // However, we need to be careful that the relevant IO_PAD is actually brought out in the variant we are using.
18 | // WLCSP package of EOSS3 has a much lower number of IOs compared to the BGA/QFN package.
19 | //
20 | // signals defined here, can be directly accessed in the Verilog code.
21 |
22 | // Qomu Pinout
23 | //
24 | // D2 - Red LED
25 | // A6 - Green LED
26 | // F4 - Blue LED
27 | // B5 - Touch 1
28 | // D1 - Touch 2
29 | // A7 - Touch 3
30 | // E3 - Touch 4
31 | // E7 - UART TX
32 | // F7 - UART RX
33 | // D5 - SPI SCLK
34 | // F5 - SPI MISO
35 | // E6 - SPI MOSI
36 |
37 | set_io io_led0 D2
38 | set_io io_led1 A6
39 | set_io io_led2 F4
--------------------------------------------------------------------------------
/blinky/constraints/storey_peak_stratixV.sdc:
--------------------------------------------------------------------------------
1 | # Main system clock (125 Mhz)
2 | create_clock -name "clk" -period 8.000ns [get_ports {clk}]
3 |
4 | # Automatically constrain PLL and other generated clocks
5 | derive_pll_clocks -create_base_clocks
6 |
7 | # Automatically calculate clock uncertainty to jitter and other effects.
8 | derive_clock_uncertainty
9 |
--------------------------------------------------------------------------------
/blinky/constraints/storey_peak_stratixV.tcl:
--------------------------------------------------------------------------------
1 | # Global
2 | set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "As output driving ground"
3 |
4 | # Clock
5 | set_location_assignment PIN_M23 -to clock
6 | set_instance_assignment -name IO_STANDARD "SSTL-135" -to clock
7 |
8 | # Reset
9 |
10 | # LEDs
11 | set_location_assignment PIN_A11 -to io_led0
12 | set_instance_assignment -name IO_STANDARD "2.5 V" -to io_led0
13 | set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to io_led0
14 | set_instance_assignment -name SLEW_RATE 0 -to io_led0
15 |
16 | set_location_assignment PIN_A10 -to io_led1
17 | set_instance_assignment -name IO_STANDARD "2.5 V" -to io_led1
18 | set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to io_led1
19 | set_instance_assignment -name SLEW_RATE 0 -to io_led1
20 |
21 | set_location_assignment PIN_B10 -to io_led2
22 | set_instance_assignment -name IO_STANDARD "2.5 V" -to io_led2
23 | set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to io_led2
24 | set_instance_assignment -name SLEW_RATE 0 -to io_led2
25 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5U-25F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x41111043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5U-45F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x41112043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5U-85F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x41113043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5UM-25F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x01111043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5UM-45F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x01112043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5UM-85F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x01113043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5UM5G-25F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x81111043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5UM5G-45F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x81112043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/LFE5UM5G-85F.cfg:
--------------------------------------------------------------------------------
1 | jtag newtap ecp5 tap -irlen 8 -expected-id 0x81113043
2 |
--------------------------------------------------------------------------------
/blinky/openocd/digilent-hs1.cfg:
--------------------------------------------------------------------------------
1 | # this supports JTAG-HS1 and JTAG-SMT1
2 | # (the later being the OEM on-board version)
3 |
4 | interface ftdi
5 | ftdi_device_desc "Digilent USB Device"
6 | ftdi_vid_pid 0x0403 0x6010
7 | # channel 1 does not have any functionality
8 | ftdi_channel 0
9 | # just TCK TDI TDO TMS, no reset
10 | ftdi_layout_init 0x0088 0x008b
11 | reset_config none
12 |
13 | # default speed
14 | adapter_khz 5000
15 |
--------------------------------------------------------------------------------
/blinky/openocd/ecp5-evn.cfg:
--------------------------------------------------------------------------------
1 | # this supports ECP5 Evaluation Board
2 |
3 | interface ftdi
4 | ftdi_device_desc "Lattice ECP5 Evaluation Board"
5 | ftdi_vid_pid 0x0403 0x6010
6 | # channel 1 does not have any functionality
7 | ftdi_channel 0
8 | # just TCK TDI TDO TMS, no reset
9 | ftdi_layout_init 0xfff8 0xfffb
10 | reset_config none
11 |
12 | # default speed
13 | adapter_khz 5000
14 |
--------------------------------------------------------------------------------
/blinky/openocd/ft231x.cfg:
--------------------------------------------------------------------------------
1 | adapter driver ft232r
2 | ft232r_vid_pid 0x0403 0x6015
3 | # ULX3S specific GPIO setting
4 | ft232r_tck_num DSR
5 | ft232r_tms_num DCD
6 | ft232r_tdi_num RI
7 | ft232r_tdo_num CTS
8 | # trst/srst are not used but must have different values than above
9 | ft232r_trst_num RTS
10 | ft232r_srst_num DTR
11 | adapter speed 1000
12 |
--------------------------------------------------------------------------------
/blinky/openocd/olimex-arm-usb-tiny-h.cfg:
--------------------------------------------------------------------------------
1 | #
2 | # Olimex ARM-USB-TINY-H
3 | #
4 | # http://www.olimex.com/dev/arm-usb-tiny-h.html
5 | #
6 |
7 | interface ftdi
8 | ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
9 | ftdi_vid_pid 0x15ba 0x002a
10 |
11 | ftdi_layout_init 0x0808 0x0a1b
12 | ftdi_layout_signal nSRST -oe 0x0200
13 | ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
14 | ftdi_layout_signal LED -data 0x0800
15 |
16 | # default speed
17 | adapter_khz 5000
18 |
--------------------------------------------------------------------------------
/blinky/openocd/xilinx-xc7.cfg:
--------------------------------------------------------------------------------
1 | # xilinx series 7 (artix, kintex, virtex)
2 | # http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
3 |
4 | if { [info exists CHIPNAME] } {
5 | set _CHIPNAME $CHIPNAME
6 | } else {
7 | set _CHIPNAME xc7
8 | }
9 |
10 | # the 4 top bits (28:31) are the die stepping/revisions. ignore it.
11 | jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \
12 | -expected-id 0x03622093 \
13 | -expected-id 0x03620093 \
14 | -expected-id 0x037C4093 \
15 | -expected-id 0x0362F093 \
16 | -expected-id 0x037C8093 \
17 | -expected-id 0x037C7093 \
18 | -expected-id 0x037C3093 \
19 | -expected-id 0x0362E093 \
20 | -expected-id 0x037C2093 \
21 | -expected-id 0x0362D093 \
22 | -expected-id 0x0362C093 \
23 | -expected-id 0x03632093 \
24 | -expected-id 0x03631093 \
25 | -expected-id 0x03636093 \
26 | -expected-id 0x03647093 \
27 | -expected-id 0x0364C093 \
28 | -expected-id 0x03651093 \
29 | -expected-id 0x03747093 \
30 | -expected-id 0x03656093 \
31 | -expected-id 0x03752093 \
32 | -expected-id 0x03751093 \
33 | -expected-id 0x03671093 \
34 | -expected-id 0x036B3093 \
35 | -expected-id 0x036B7093 \
36 | -expected-id 0x036BB093 \
37 | -expected-id 0x036BF093 \
38 | -expected-id 0x03667093 \
39 | -expected-id 0x03682093 \
40 | -expected-id 0x03687093 \
41 | -expected-id 0x03692093 \
42 | -expected-id 0x03691093 \
43 | -expected-id 0x03696093 \
44 | -expected-id 0x036D5093 \
45 | -expected-id 0x036D9093 \
46 | -expected-id 0x036DB093
47 |
48 | pld device virtex2 $_CHIPNAME.tap 1
49 |
50 | set XC7_JSHUTDOWN 0x0d
51 | set XC7_JPROGRAM 0x0b
52 | set XC7_JSTART 0x0c
53 | set XC7_BYPASS 0x3f
54 |
55 | proc xc7_program {tap} {
56 | global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
57 | irscan $tap $XC7_JSHUTDOWN
58 | irscan $tap $XC7_JPROGRAM
59 | runtest 60000
60 | #JSTART prevents this from working...
61 | #irscan $tap $XC7_JSTART
62 | runtest 2000
63 | irscan $tap $XC7_BYPASS
64 | runtest 2000
65 | }
66 |
--------------------------------------------------------------------------------
/blinky/proginfo/artix7-template.txt:
--------------------------------------------------------------------------------
1 | # Programming instructions for Digilent Arty A7 - Artix 7
2 |
3 | ## To program the board using OpenOCD, use the command:
4 |
5 | openocd -f $interfaceConfig -f $boardConfig -c "transport select jtag;init; pld load 0 $bitstream; exit"
6 |
--------------------------------------------------------------------------------
/blinky/proginfo/boardconfig.yaml:
--------------------------------------------------------------------------------
1 | # This is the board programming files config
2 | # The board parameters must match the template for each board
3 |
4 | boards:
5 | ulx3s-85f:
6 | templateFile: ulx3s-template.txt
7 | interfaceConfig: ft231x.cfg
8 | boardConfig: LFE5U-85F.cfg
9 | bitstream: carlosedp_demo_chiselblinky_0.bit
10 | bitstreamSVF: carlosedp_demo_chiselblinky_0.svf
11 |
12 | artya7-35t:
13 | templateFile: artix7-template.txt
14 | interfaceConfig: digilent-hs1.cfg
15 | boardConfig: xilinx-xc7.cfg
16 | bitstream: Toplevel.bit
17 |
18 | qmtech_k325t:
19 | templateFile: qmtech_k325t-template.txt
20 | bitstream: carlosedp_demo_chiselblinky_0.bit
21 |
--------------------------------------------------------------------------------
/blinky/proginfo/dfu-util.txt:
--------------------------------------------------------------------------------
1 | # Programming instructions for Fomu
2 |
3 | ## To program the board using dfu-util, use the command:
4 |
5 | dfu-util -e -d 1209:5bf0 -D $bitstream
6 |
--------------------------------------------------------------------------------
/blinky/proginfo/proginfo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | import os
3 | import sys
4 | import glob
5 | import yaml
6 | from string import Template
7 |
8 | def main():
9 | print("Build completed")
10 | with open(findFile('boardconfig.yaml')) as file:
11 | fullfile = yaml.full_load(file)
12 | boards = fullfile['boards']
13 | boardFiles = {}
14 | if sys.argv[1] in boards:
15 | for param in boards[sys.argv[1]]:
16 | boardFiles[param] = findFile(boards[sys.argv[1]][param])
17 | render(boardFiles, findFile(boards[sys.argv[1]]['templateFile']))
18 | else:
19 | print("ERROR: Board " + sys.argv[1] + " not found in boardconfig.yaml")
20 | exit(1)
21 | print("")
22 |
23 | # Utility Functions
24 |
25 | def findFile(f, filter=""):
26 | r = glob.glob("../**/" + f, recursive=True)
27 | if filter != "":
28 | r = [s for s in r if filter in s]
29 | if not r:
30 | print("ERROR: Could not find file " + f)
31 | exit(1)
32 | return os.path.realpath(r[0])
33 |
34 | def render(d, template):
35 | with open(os.path.join(os.getcwd(),template)) as f:
36 | src = Template(f.read())
37 | output = src.substitute(d)
38 | print(output)
39 |
40 | if __name__ == "__main__":
41 | if len(sys.argv) <= 1:
42 | print("Board not supplied")
43 | exit(1)
44 | main()
45 |
--------------------------------------------------------------------------------
/blinky/proginfo/qmtech_k325t-template.txt:
--------------------------------------------------------------------------------
1 | # Programming instructions for QMTech Kintex 7 board
2 |
3 | ## To program the board using OpenFPGAloader (), use the command:
4 |
5 | openfpgaloader -c ft232 $bitstream
6 |
--------------------------------------------------------------------------------
/blinky/proginfo/ulx3s-template.txt:
--------------------------------------------------------------------------------
1 | # Programming instructions for ULX3S based on Lattice ECP5
2 |
3 | ## To program with ujprog:
4 |
5 | ujprog $bitstreamSVF
6 |
7 | ## To program the board using OpenOCD, use the command:
8 |
9 | openocd -f $interfaceConfig -f $boardConfig -c "transport select jtag; init; scan_chain; svf -quiet -progress $bitstreamSVF; exit"
10 |
11 | Other programming options are listed here https://github.com/emard/ulx3s/blob/master/doc/MANUAL.md#programming-options
12 |
--------------------------------------------------------------------------------
/blinky/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.5.7
2 |
--------------------------------------------------------------------------------
/blinky/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
2 | addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.29")
3 | addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.19")
4 |
--------------------------------------------------------------------------------
/blinky/scripts/mill:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # This is a wrapper script, that automatically download mill from GitHub release pages
4 | # You can give the required mill version with MILL_VERSION env variable
5 | # If no version is given, it falls back to the value of DEFAULT_MILL_VERSION
6 | DEFAULT_MILL_VERSION=0.9.9
7 |
8 | set -e
9 |
10 | if [ -z "$MILL_VERSION" ] ; then
11 | if [ -f ".mill-version" ] ; then
12 | MILL_VERSION="$(head -n 1 .mill-version 2> /dev/null)"
13 | elif [ -f "mill" ] && [ "$BASH_SOURCE" != "mill" ] ; then
14 | MILL_VERSION=$(grep -F "DEFAULT_MILL_VERSION=" "mill" | head -n 1 | cut -d= -f2)
15 | else
16 | MILL_VERSION=$DEFAULT_MILL_VERSION
17 | fi
18 | fi
19 |
20 | if [ "x${XDG_CACHE_HOME}" != "x" ] ; then
21 | MILL_DOWNLOAD_PATH="${XDG_CACHE_HOME}/mill/download"
22 | else
23 | MILL_DOWNLOAD_PATH="${HOME}/.cache/mill/download"
24 | fi
25 | MILL_EXEC_PATH="${MILL_DOWNLOAD_PATH}/${MILL_VERSION}"
26 |
27 | version_remainder="$MILL_VERSION"
28 | MILL_MAJOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}"
29 | MILL_MINOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}"
30 |
31 | if [ ! -x "$MILL_EXEC_PATH" ] ; then
32 | mkdir -p $MILL_DOWNLOAD_PATH
33 | if [ "$MILL_MAJOR_VERSION" -gt 0 ] || [ "$MILL_MINOR_VERSION" -ge 5 ] ; then
34 | ASSEMBLY="-assembly"
35 | fi
36 | DOWNLOAD_FILE=$MILL_EXEC_PATH-tmp-download
37 | MILL_DOWNLOAD_URL="https://github.com/lihaoyi/mill/releases/download/${MILL_VERSION%%-*}/$MILL_VERSION${ASSEMBLY}"
38 | curl --fail -L -o "$DOWNLOAD_FILE" "$MILL_DOWNLOAD_URL"
39 | chmod +x "$DOWNLOAD_FILE"
40 | mv "$DOWNLOAD_FILE" "$MILL_EXEC_PATH"
41 | unset DOWNLOAD_FILE
42 | unset MILL_DOWNLOAD_URL
43 | fi
44 |
45 | unset MILL_DOWNLOAD_PATH
46 | unset MILL_VERSION
47 |
48 | exec $MILL_EXEC_PATH "$@"
49 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_artya7-35t.v:
--------------------------------------------------------------------------------
1 | `timescale 1ps/1ps
2 |
3 | // Input clock is 100Mhz
4 | // Output clock is 25Mhz
5 |
6 | module PLL0
7 |
8 | (
9 | output clko,
10 | output lock,
11 | input clki
12 | );
13 | // Input buffering
14 | //------------------------------------
15 | wire clki_clk_wiz_0;
16 | IBUF clkin1_ibufg
17 | (.O (clki_clk_wiz_0),
18 | .I (clki));
19 |
20 | // Clocking PRIMITIVE
21 | //------------------------------------
22 |
23 | // Instantiation of the MMCM PRIMITIVE
24 | // * Unused inputs are tied off
25 | // * Unused outputs are labeled unused
26 |
27 | wire clko_clk_wiz_0;
28 | wire clk_out2_clk_wiz_0;
29 | wire clk_out3_clk_wiz_0;
30 | wire clk_out4_clk_wiz_0;
31 | wire clk_out5_clk_wiz_0;
32 | wire clk_out6_clk_wiz_0;
33 | wire clk_out7_clk_wiz_0;
34 |
35 | wire [15:0] do_unused;
36 | wire drdy_unused;
37 | wire psdone_unused;
38 | wire lock_int;
39 | wire clkfbout_clk_wiz_0;
40 | wire clkfbout_buf_clk_wiz_0;
41 | wire clkfboutb_unused;
42 | wire clkout1_unused;
43 | wire clkout2_unused;
44 | wire clkout3_unused;
45 | wire clkout4_unused;
46 | wire clkout5_unused;
47 | wire clkout6_unused;
48 | wire clkfbstopped_unused;
49 | wire clkinstopped_unused;
50 |
51 | PLLE2_ADV
52 | #(.BANDWIDTH ("OPTIMIZED"),
53 | .COMPENSATION ("INTERNAL"),
54 | .STARTUP_WAIT ("FALSE"),
55 | .DIVCLK_DIVIDE (4),
56 | .CLKFBOUT_MULT (33),
57 | .CLKFBOUT_PHASE (0.000),
58 | .CLKOUT0_DIVIDE (33),
59 | .CLKOUT0_PHASE (0.000),
60 | .CLKOUT0_DUTY_CYCLE (0.500),
61 | .CLKIN1_PERIOD (10.000),
62 | .CLKIN2_PERIOD (10.312))
63 | plle2_adv_inst
64 | // Output clocks
65 | (
66 | .CLKFBOUT (clkfbout_clk_wiz_0),
67 | .CLKOUT0 (clko_clk_wiz_0),
68 | .CLKOUT1 (clkout1_unused),
69 | .CLKOUT2 (clkout2_unused),
70 | .CLKOUT3 (clkout3_unused),
71 | .CLKOUT4 (clkout4_unused),
72 | .CLKOUT5 (clkout5_unused),
73 | // Input clock control
74 | .CLKFBIN (clkfbout_buf_clk_wiz_0),
75 | .CLKIN1 (clki_clk_wiz_0),
76 | .CLKIN2 (clki_clk_wiz_0),
77 | .CLKINSEL (1'b1),
78 | // Ports for dynamic reconfiguration
79 | .DADDR (7'h0),
80 | .DCLK (1'b0),
81 | .DEN (1'b0),
82 | .DI (16'h0),
83 | .DO (do_unused),
84 | .DRDY (drdy_unused),
85 | .DWE (1'b0),
86 | // Other control and status signals
87 | .LOCKED (lock_int),
88 | .PWRDWN (1'b0),
89 | .RST (1'b0));
90 |
91 | assign lock = lock_int;
92 | // Clock Monitor clock assigning
93 | //--------------------------------------
94 | // Output buffering
95 | //-----------------------------------
96 |
97 | BUFG clkf_buf
98 | (.O (clkfbout_buf_clk_wiz_0),
99 | .I (clkfbout_clk_wiz_0));
100 |
101 | BUFG clkout1_buf
102 | (.O (clko),
103 | .I (clko_clk_wiz_0));
104 |
105 | endmodule
106 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_de1_soc_revF.v:
--------------------------------------------------------------------------------
1 | // This isn't really a PLL, but it halves the clock.
2 | module PLL0
3 | (
4 | input clki, // 50 MHz
5 | output clko, // 25 MHz
6 | output lock
7 | );
8 |
9 | reg half_clk;
10 | assign clko = half_clk;
11 |
12 | always @(posedge clki) begin
13 | half_clk <= !half_clk;
14 | end
15 |
16 | endmodule
17 |
18 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_evn.v:
--------------------------------------------------------------------------------
1 | module PLL0(
2 | input clki,
3 | output clko,
4 | output lock
5 | );
6 | (* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
7 |
8 | EHXPLLL #(
9 | .PLLRST_ENA("DISABLED"),
10 | .INTFB_WAKE("DISABLED"),
11 | .STDBY_ENABLE("DISABLED"),
12 | .DPHASE_SOURCE("DISABLED"),
13 | .CLKOP_FPHASE(0),
14 | .CLKOP_CPHASE(11),
15 | .OUTDIVIDER_MUXA("DIVA"),
16 | .CLKOP_ENABLE("ENABLED"),
17 | .CLKOP_DIV(12),
18 | .CLKFB_DIV(25),
19 | .CLKI_DIV(6),
20 | .FEEDBK_PATH("CLKOP")
21 | ) pll_i (
22 | .CLKI(clki),
23 | .CLKFB(clko),
24 | .CLKOP(clko),
25 | .LOCK(lock),
26 | .RST(1'b0),
27 | .STDBY(1'b0),
28 | .PHASESEL0(1'b0),
29 | .PHASESEL1(1'b0),
30 | .PHASEDIR(1'b0),
31 | .PHASESTEP(1'b0),
32 | .PLLWAKESYNC(1'b0),
33 | .ENCLKOP(1'b0)
34 | );
35 |
36 | endmodule
37 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_nexys4ddr.v:
--------------------------------------------------------------------------------
1 | `timescale 1ps/1ps
2 |
3 | module PLL0
4 |
5 | (
6 | output clko,
7 | output lock,
8 | input clki
9 | );
10 | // Input buffering
11 | //------------------------------------
12 | wire clki_clk_wiz_0;
13 | IBUF clkin1_ibufg
14 | (.O (clki_clk_wiz_0),
15 | .I (clki));
16 |
17 | // Clocking PRIMITIVE
18 | //------------------------------------
19 |
20 | // Instantiation of the MMCM PRIMITIVE
21 | // * Unused inputs are tied off
22 | // * Unused outputs are labeled unused
23 |
24 | wire clko_clk_wiz_0;
25 | wire clk_out2_clk_wiz_0;
26 | wire clk_out3_clk_wiz_0;
27 | wire clk_out4_clk_wiz_0;
28 | wire clk_out5_clk_wiz_0;
29 | wire clk_out6_clk_wiz_0;
30 | wire clk_out7_clk_wiz_0;
31 |
32 | wire [15:0] do_unused;
33 | wire drdy_unused;
34 | wire psdone_unused;
35 | wire lock_int;
36 | wire clkfbout_clk_wiz_0;
37 | wire clkfbout_buf_clk_wiz_0;
38 | wire clkfboutb_unused;
39 | wire clkout1_unused;
40 | wire clkout2_unused;
41 | wire clkout3_unused;
42 | wire clkout4_unused;
43 | wire clkout5_unused;
44 | wire clkout6_unused;
45 | wire clkfbstopped_unused;
46 | wire clkinstopped_unused;
47 |
48 | PLLE2_ADV
49 | #(.BANDWIDTH ("OPTIMIZED"),
50 | .COMPENSATION ("ZHOLD"),
51 | .STARTUP_WAIT ("FALSE"),
52 | .DIVCLK_DIVIDE (4),
53 | .CLKFBOUT_MULT (33),
54 | .CLKFBOUT_PHASE (0.000),
55 | .CLKOUT0_DIVIDE (33),
56 | .CLKOUT0_PHASE (0.000),
57 | .CLKOUT0_DUTY_CYCLE (0.500),
58 | .CLKIN1_PERIOD (10.000),
59 | .CLKIN2_PERIOD (10.312))
60 | plle2_adv_inst
61 | // Output clocks
62 | (
63 | .CLKFBOUT (clkfbout_clk_wiz_0),
64 | .CLKOUT0 (clko_clk_wiz_0),
65 | .CLKOUT1 (clkout1_unused),
66 | .CLKOUT2 (clkout2_unused),
67 | .CLKOUT3 (clkout3_unused),
68 | .CLKOUT4 (clkout4_unused),
69 | .CLKOUT5 (clkout5_unused),
70 | // Input clock control
71 | .CLKFBIN (clkfbout_buf_clk_wiz_0),
72 | .CLKIN1 (clki_clk_wiz_0),
73 | .CLKIN2 (clki_clk_wiz_0),
74 | .CLKINSEL (1'b1),
75 | // Ports for dynamic reconfiguration
76 | .DADDR (7'h0),
77 | .DCLK (1'b0),
78 | .DEN (1'b0),
79 | .DI (16'h0),
80 | .DO (do_unused),
81 | .DRDY (drdy_unused),
82 | .DWE (1'b0),
83 | // Other control and status signals
84 | .LOCKED (lock_int),
85 | .PWRDWN (1'b0),
86 | .RST (1'b0));
87 |
88 | assign lock = lock_int;
89 | // Clock Monitor clock assigning
90 | //--------------------------------------
91 | // Output buffering
92 | //-----------------------------------
93 |
94 | BUFG clkf_buf
95 | (.O (clkfbout_buf_clk_wiz_0),
96 | .I (clkfbout_clk_wiz_0));
97 |
98 | BUFG clkout1_buf
99 | (.O (clko),
100 | .I (clko_clk_wiz_0));
101 |
102 | endmodule
103 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_orange-crab.v:
--------------------------------------------------------------------------------
1 | module PLL0
2 | (
3 | input clki, // 48 MHz, 0 deg
4 | output clko, // 25 MHz, 0 deg
5 | output lock
6 | );
7 | (* FREQUENCY_PIN_CLKI="48" *)
8 | (* FREQUENCY_PIN_CLKOP="25.6" *)
9 | (* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
10 | EHXPLLL #(
11 | .PLLRST_ENA("DISABLED"),
12 | .INTFB_WAKE("DISABLED"),
13 | .STDBY_ENABLE("DISABLED"),
14 | .DPHASE_SOURCE("DISABLED"),
15 | .OUTDIVIDER_MUXA("DIVA"),
16 | .OUTDIVIDER_MUXB("DIVB"),
17 | .OUTDIVIDER_MUXC("DIVC"),
18 | .OUTDIVIDER_MUXD("DIVD"),
19 | .CLKI_DIV(15),
20 | .CLKOP_ENABLE("ENABLED"),
21 | .CLKOP_DIV(23),
22 | .CLKOP_CPHASE(11),
23 | .CLKOP_FPHASE(0),
24 | .FEEDBK_PATH("CLKOP"),
25 | .CLKFB_DIV(8)
26 | ) pll_i (
27 | .RST(1'b0),
28 | .STDBY(1'b0),
29 | .CLKI(clki),
30 | .CLKOP(clko),
31 | .CLKFB(clko),
32 | .CLKINTFB(),
33 | .PHASESEL0(1'b0),
34 | .PHASESEL1(1'b0),
35 | .PHASEDIR(1'b1),
36 | .PHASESTEP(1'b1),
37 | .PHASELOADREG(1'b1),
38 | .PLLWAKESYNC(1'b0),
39 | .ENCLKOP(1'b0),
40 | .LOCK(lock)
41 | );
42 | endmodule
43 |
44 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_polarfireeval.v:
--------------------------------------------------------------------------------
1 | `timescale 1 ns/100 ps
2 | // Version: v12.4 12.900.0.16
3 |
4 | module PLL0(
5 | input clki, // 50 MHz, 0 deg
6 | output clko, // 25 MHz, 0 deg
7 | output lock
8 | );
9 |
10 | wire gnd_net, vcc_net, pll_inst_0_clkint_0;
11 |
12 | CLKINT clkint_0 (.A(pll_inst_0_clkint_0), .Y(clko));
13 | PLL #( .VCOFREQUENCY(5000), .DELAY_LINE_SIMULATION_MODE(""), .DATA_RATE(0.0)
14 | , .FORMAL_NAME(""), .INTERFACE_NAME(""), .INTERFACE_LEVEL(3'b0)
15 | , .SOFTRESET(1'b0), .SOFT_POWERDOWN_N(1'b1), .RFDIV_EN(1'b1), .OUT0_DIV_EN(1'b1)
16 | , .OUT1_DIV_EN(1'b0), .OUT2_DIV_EN(1'b0), .OUT3_DIV_EN(1'b0), .SOFT_REF_CLK_SEL(1'b0)
17 | , .RESET_ON_LOCK(1'b1), .BYPASS_CLK_SEL(4'b0), .BYPASS_GO_EN_N(1'b1)
18 | , .BYPASS_PLL(4'b0), .BYPASS_OUT_DIVIDER(4'b0), .FF_REQUIRES_LOCK(1'b0)
19 | , .FSE_N(1'b0), .FB_CLK_SEL_0(2'b00), .FB_CLK_SEL_1(1'b0), .RFDIV(6'b000001)
20 | , .FRAC_EN(1'b0), .FRAC_DAC_EN(1'b0), .DIV0_RST_DELAY(3'b000)
21 | , .DIV0_VAL(7'b0110010), .DIV1_RST_DELAY(3'b0), .DIV1_VAL(7'b1)
22 | , .DIV2_RST_DELAY(3'b0), .DIV2_VAL(7'b1), .DIV3_RST_DELAY(3'b0)
23 | , .DIV3_VAL(7'b1), .DIV3_CLK_SEL(1'b0), .BW_INT_CTRL(2'b0), .BW_PROP_CTRL(2'b01)
24 | , .IREF_EN(1'b1), .IREF_TOGGLE(1'b0), .LOCK_CNT(4'b1000), .DESKEW_CAL_CNT(3'b110)
25 | , .DESKEW_CAL_EN(1'b1), .DESKEW_CAL_BYPASS(1'b0), .SYNC_REF_DIV_EN(1'b0)
26 | , .SYNC_REF_DIV_EN_2(1'b0), .OUT0_PHASE_SEL(3'b000), .OUT1_PHASE_SEL(3'b0)
27 | , .OUT2_PHASE_SEL(3'b0), .OUT3_PHASE_SEL(3'b0), .SOFT_LOAD_PHASE_N(1'b1)
28 | , .SSM_DIV_VAL(6'b1), .FB_FRAC_VAL(24'b0), .SSM_SPREAD_MODE(1'b0)
29 | , .SSM_MODULATION(5'b00101), .FB_INT_VAL(12'b000001100100), .SSM_EN_N(1'b1)
30 | , .SSM_EXT_WAVE_EN(2'b0), .SSM_EXT_WAVE_MAX_ADDR(8'b0), .SSM_RANDOM_EN(1'b0)
31 | , .SSM_RANDOM_PATTERN_SEL(3'b0), .CDMUX0_SEL(2'b0), .CDMUX1_SEL(1'b1)
32 | , .CDMUX2_SEL(1'b0), .CDELAY0_SEL(8'b0), .CDELAY0_EN(1'b0), .DRI_EN(1'b1)
33 | ) pll_inst_0 (.LOCK(lock), .SSCG_WAVE_TABLE_ADDR({nc0,
34 | nc1, nc2, nc3, nc4, nc5, nc6, nc7}), .DELAY_LINE_OUT_OF_RANGE()
35 | , .POWERDOWN_N(vcc_net), .OUT0_EN(vcc_net), .OUT1_EN(gnd_net),
36 | .OUT2_EN(gnd_net), .OUT3_EN(gnd_net), .REF_CLK_SEL(gnd_net),
37 | .BYPASS_EN_N(vcc_net), .LOAD_PHASE_N(vcc_net),
38 | .SSCG_WAVE_TABLE({gnd_net, gnd_net, gnd_net, gnd_net, gnd_net,
39 | gnd_net, gnd_net, gnd_net}), .PHASE_DIRECTION(gnd_net),
40 | .PHASE_ROTATE(gnd_net), .PHASE_OUT0_SEL(gnd_net),
41 | .PHASE_OUT1_SEL(gnd_net), .PHASE_OUT2_SEL(gnd_net),
42 | .PHASE_OUT3_SEL(gnd_net), .DELAY_LINE_MOVE(gnd_net),
43 | .DELAY_LINE_DIRECTION(gnd_net), .DELAY_LINE_WIDE(gnd_net),
44 | .DELAY_LINE_LOAD(vcc_net), .REFCLK_SYNC_EN(gnd_net),
45 | .REF_CLK_0(clki), .REF_CLK_1(gnd_net), .FB_CLK(gnd_net),
46 | .OUT0(pll_inst_0_clkint_0), .OUT1(), .OUT2(), .OUT3(),
47 | .DRI_CLK(gnd_net), .DRI_CTRL({gnd_net, gnd_net, gnd_net,
48 | gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net,
49 | gnd_net}), .DRI_WDATA({gnd_net, gnd_net, gnd_net, gnd_net,
50 | gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net,
51 | gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net,
52 | gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net,
53 | gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net,
54 | gnd_net}), .DRI_ARST_N(vcc_net), .DRI_RDATA({nc8, nc9, nc10,
55 | nc11, nc12, nc13, nc14, nc15, nc16, nc17, nc18, nc19, nc20,
56 | nc21, nc22, nc23, nc24, nc25, nc26, nc27, nc28, nc29, nc30,
57 | nc31, nc32, nc33, nc34, nc35, nc36, nc37, nc38, nc39, nc40}),
58 | .DRI_INTERRUPT());
59 | VCC vcc_inst (.Y(vcc_net));
60 | GND gnd_inst (.Y(gnd_net));
61 |
62 | endmodule
63 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_qmtech_k325t.v:
--------------------------------------------------------------------------------
1 | `timescale 1ps/1ps
2 |
3 | // Input clock is 50Mhz
4 | // Output clock is 25Mhz
5 |
6 | module PLL0
7 |
8 | (
9 | output clko,
10 | output lock,
11 | input clki
12 | );
13 | // Input buffering
14 | //------------------------------------
15 | wire clki_clk_wiz_0;
16 | IBUF clkin1_ibufg
17 | (.O (clki_clk_wiz_0),
18 | .I (clki));
19 |
20 | // Clocking PRIMITIVE
21 | //------------------------------------
22 |
23 | // Instantiation of the MMCM PRIMITIVE
24 | // * Unused inputs are tied off
25 | // * Unused outputs are labeled unused
26 |
27 | wire clko_clk_wiz_0;
28 | wire clk_out2_clk_wiz_0;
29 | wire clk_out3_clk_wiz_0;
30 | wire clk_out4_clk_wiz_0;
31 | wire clk_out5_clk_wiz_0;
32 | wire clk_out6_clk_wiz_0;
33 | wire clk_out7_clk_wiz_0;
34 |
35 | wire [15:0] do_unused;
36 | wire drdy_unused;
37 | wire psdone_unused;
38 | wire lock_int;
39 | wire clkfbout_clk_wiz_0;
40 | wire clkfbout_buf_clk_wiz_0;
41 | wire clkfboutb_unused;
42 | wire clkout1_unused;
43 | wire clkout2_unused;
44 | wire clkout3_unused;
45 | wire clkout4_unused;
46 | wire clkout5_unused;
47 | wire clkout6_unused;
48 | wire clkfbstopped_unused;
49 | wire clkinstopped_unused;
50 |
51 | PLLE2_ADV
52 | #(.BANDWIDTH ("OPTIMIZED"),
53 | .COMPENSATION ("INTERNAL"),
54 | .STARTUP_WAIT ("FALSE"),
55 | .DIVCLK_DIVIDE (2),
56 | .CLKFBOUT_MULT (33),
57 | .CLKFBOUT_PHASE (0.000),
58 | .CLKOUT0_DIVIDE (33),
59 | .CLKOUT0_PHASE (0.000),
60 | .CLKOUT0_DUTY_CYCLE (0.500),
61 | .CLKIN1_PERIOD (10.000),
62 | .CLKIN2_PERIOD (10.312))
63 | plle2_adv_inst
64 | // Output clocks
65 | (
66 | .CLKFBOUT (clkfbout_clk_wiz_0),
67 | .CLKOUT0 (clko_clk_wiz_0),
68 | .CLKOUT1 (clkout1_unused),
69 | .CLKOUT2 (clkout2_unused),
70 | .CLKOUT3 (clkout3_unused),
71 | .CLKOUT4 (clkout4_unused),
72 | .CLKOUT5 (clkout5_unused),
73 | // Input clock control
74 | .CLKFBIN (clkfbout_buf_clk_wiz_0),
75 | .CLKIN1 (clki_clk_wiz_0),
76 | .CLKIN2 (clki_clk_wiz_0),
77 | .CLKINSEL (1'b1),
78 | // Ports for dynamic reconfiguration
79 | .DADDR (7'h0),
80 | .DCLK (1'b0),
81 | .DEN (1'b0),
82 | .DI (16'h0),
83 | .DO (do_unused),
84 | .DRDY (drdy_unused),
85 | .DWE (1'b0),
86 | // Other control and status signals
87 | .LOCKED (lock_int),
88 | .PWRDWN (1'b0),
89 | .RST (1'b0));
90 |
91 | assign lock = lock_int;
92 | // Clock Monitor clock assigning
93 | //--------------------------------------
94 | // Output buffering
95 | //-----------------------------------
96 |
97 | BUFG clkf_buf
98 | (.O (clkfbout_buf_clk_wiz_0),
99 | .I (clkfbout_clk_wiz_0));
100 |
101 | BUFG clkout1_buf
102 | (.O (clko),
103 | .I (clko_clk_wiz_0));
104 |
105 | endmodule
106 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_qomu.v:
--------------------------------------------------------------------------------
1 | // This isn't really a PLL but a connection between the eFPGA and the MCU
2 | module PLL0
3 | (
4 | input clki, // No input since the MCU generates the clock
5 | output clko, // 24 MHz output from the MCU clock generator (bootloader has 24Mhz and 48Mhz clocks)
6 | output lock
7 | );
8 |
9 | /* CPU <-> FPGA interface
10 | * here only one of the two clock sources
11 | * and corresponding reset signal are used
12 | * Sys_Clk0/Sys_Clk0_Rst: C16 clock domain (default as 24Mhz from bootloader)
13 | * Sys_Clk1/Sys_Clk1_Rst: C21 clock domain (default as 48Mhz from bootloader)
14 | */
15 | qlal4s3b_cell_macro u_qlal4s3b_cell_macro (
16 | .Sys_Clk0 (clko), // we expect 25Mhz but the default 24Mhz from MCU is close :)
17 | .Sys_Clk0_Rst (),
18 | .Sys_Clk1 (),
19 | .Sys_Clk1_Rst ()
20 | );
21 |
22 | endmodule
23 |
24 |
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_storey_peak_stratixV.v:
--------------------------------------------------------------------------------
1 | `default_nettype none
2 | module PLL0
3 | (
4 | input clki, // 125 MHz
5 | output clko, // 25 MHz
6 | output lock
7 | );
8 |
9 | altera_pll #(
10 | .fractional_vco_multiplier("false"),
11 | .reference_clock_frequency("125.0 MHz"),
12 | .operation_mode("direct"),
13 | .number_of_clocks(1),
14 | .output_clock_frequency0("25.000000 MHz"),
15 | .phase_shift0("0 ps"),
16 | .duty_cycle0(50),
17 | .output_clock_frequency1("0 MHz"),
18 | .phase_shift1("0 ps"),
19 | .duty_cycle1(50),
20 | .output_clock_frequency2("0 MHz"),
21 | .phase_shift2("0 ps"),
22 | .duty_cycle2(50),
23 | .output_clock_frequency3("0 MHz"),
24 | .phase_shift3("0 ps"),
25 | .duty_cycle3(50),
26 | .output_clock_frequency4("0 MHz"),
27 | .phase_shift4("0 ps"),
28 | .duty_cycle4(50),
29 | .output_clock_frequency5("0 MHz"),
30 | .phase_shift5("0 ps"),
31 | .duty_cycle5(50),
32 | .output_clock_frequency6("0 MHz"),
33 | .phase_shift6("0 ps"),
34 | .duty_cycle6(50),
35 | .output_clock_frequency7("0 MHz"),
36 | .phase_shift7("0 ps"),
37 | .duty_cycle7(50),
38 | .output_clock_frequency8("0 MHz"),
39 | .phase_shift8("0 ps"),
40 | .duty_cycle8(50),
41 | .output_clock_frequency9("0 MHz"),
42 | .phase_shift9("0 ps"),
43 | .duty_cycle9(50),
44 | .output_clock_frequency10("0 MHz"),
45 | .phase_shift10("0 ps"),
46 | .duty_cycle10(50),
47 | .output_clock_frequency11("0 MHz"),
48 | .phase_shift11("0 ps"),
49 | .duty_cycle11(50),
50 | .output_clock_frequency12("0 MHz"),
51 | .phase_shift12("0 ps"),
52 | .duty_cycle12(50),
53 | .output_clock_frequency13("0 MHz"),
54 | .phase_shift13("0 ps"),
55 | .duty_cycle13(50),
56 | .output_clock_frequency14("0 MHz"),
57 | .phase_shift14("0 ps"),
58 | .duty_cycle14(50),
59 | .output_clock_frequency15("0 MHz"),
60 | .phase_shift15("0 ps"),
61 | .duty_cycle15(50),
62 | .output_clock_frequency16("0 MHz"),
63 | .phase_shift16("0 ps"),
64 | .duty_cycle16(50),
65 | .output_clock_frequency17("0 MHz"),
66 | .phase_shift17("0 ps"),
67 | .duty_cycle17(50),
68 | .pll_type("General"),
69 | .pll_subtype("General")
70 | ) altera_pll_i (
71 | .rst (1'b0),
72 | .outclk ({clko}),
73 | .locked (lock),
74 | .fboutclk ( ),
75 | .fbclk (1'b0),
76 | .refclk (clki)
77 | );
78 |
79 | endmodule
--------------------------------------------------------------------------------
/blinky/src/main/resources/pll_ulx3s.v:
--------------------------------------------------------------------------------
1 | module PLL0
2 | (
3 | input clki, // 25 MHz, 0 deg
4 | output clko, // 25 MHz, 0 deg
5 | output lock
6 | );
7 | (* FREQUENCY_PIN_CLKI="25" *)
8 | (* FREQUENCY_PIN_CLKOP="25" *)
9 | (* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *)
10 | EHXPLLL #(
11 | .PLLRST_ENA("DISABLED"),
12 | .INTFB_WAKE("DISABLED"),
13 | .STDBY_ENABLE("DISABLED"),
14 | .DPHASE_SOURCE("DISABLED"),
15 | .OUTDIVIDER_MUXA("DIVA"),
16 | .OUTDIVIDER_MUXB("DIVB"),
17 | .OUTDIVIDER_MUXC("DIVC"),
18 | .OUTDIVIDER_MUXD("DIVD"),
19 | .CLKI_DIV(1),
20 | .CLKOP_ENABLE("ENABLED"),
21 | .CLKOP_DIV(24),
22 | .CLKOP_CPHASE(11),
23 | .CLKOP_FPHASE(0),
24 | .FEEDBK_PATH("CLKOP"),
25 | .CLKFB_DIV(1)
26 | ) pll_i (
27 | .RST(1'b0),
28 | .STDBY(1'b0),
29 | .CLKI(clki),
30 | .CLKOP(clko),
31 | .CLKFB(clko),
32 | .CLKINTFB(),
33 | .PHASESEL0(1'b0),
34 | .PHASESEL1(1'b0),
35 | .PHASEDIR(1'b1),
36 | .PHASESTEP(1'b1),
37 | .PHASELOADREG(1'b1),
38 | .PLLWAKESYNC(1'b0),
39 | .ENCLKOP(1'b0),
40 | .LOCK(lock)
41 | );
42 | endmodule
--------------------------------------------------------------------------------
/blinky/src/main/scala/BlackBoxPLL.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import chisel3.util._
3 |
4 | import scala.io.Source
5 |
6 | class PLL0(board: String) extends BlackBox with HasBlackBoxInline {
7 | val io = IO(new Bundle() {
8 | val clki = Input(Clock())
9 | val clko = Output(Clock());
10 | val lock = Output(Clock())
11 | })
12 |
13 | val filename = "pll_" + board + ".v"
14 | val verilog = Source.fromResource(filename).getLines().mkString("\n")
15 | setInline("PLL.v", verilog)
16 | }
17 |
--------------------------------------------------------------------------------
/blinky/src/main/scala/Blinky.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import chisel3.util._
3 |
4 | /**
5 | * The blinking LED component.
6 | */
7 | class Blinky(freq: Int, startOn: Boolean = false) extends Module {
8 | val io = IO(new Bundle {
9 | val led0 = Output(Bool())
10 | val led1 = Output(Bool())
11 | val led2 = Output(Bool())
12 | })
13 |
14 | // Alternate blink leds every second
15 | val led = RegInit(startOn.B)
16 | val (_, counterWrap) = Counter(true.B, freq / 2)
17 | when(counterWrap) {
18 | led := ~led
19 | }
20 |
21 | io.led0 := led
22 | io.led1 := ~led
23 |
24 | // 1 beathe cycle every second
25 | io.led2 := breathe(freq, 1000)
26 |
27 | // To set a specific PWM value instead (Eg. 10% duty cycle)
28 | // io.led2 := pwmAbs(10.U)
29 |
30 | //-------------- Utility Functions --------------
31 | /**
32 | * pwmAbs creates a PWM output from a 0 to 100 Duty Cycle
33 | *
34 | * @param dutyCycle UInt from 0 to 100 (as in percent)
35 | * @return Bool output
36 | */
37 | def pwmAbs(dutyCycle: UInt) = {
38 | // Divide input frequency by 1024 to avoid switchind the LEDs at high freq
39 | val clockDiv = RegInit(0.U(log2Ceil(1024).W))
40 | clockDiv := clockDiv + 1.U
41 | val cnt = RegInit(0.U(7.W))
42 | val out = RegInit(false.B)
43 | when(clockDiv === 0.U) {
44 | cnt := Mux(cnt === 100.U, 0.U, cnt + 1.U)
45 | out := dutyCycle > cnt
46 | }
47 | out
48 | }
49 |
50 | /**
51 | * breathe creates a gradual off-on-off cycle with pwmAbs function
52 | *
53 | * @param freq is the module clock frequency
54 | * @param speed in miliseconts for a full off-on-off cycle
55 | * @return Bool output
56 | */
57 | def breathe(freq: Int, speed: Int) = {
58 | val pwmRange = 100
59 | val pwm = RegInit(0.U(log2Ceil(pwmRange).W))
60 | val upReg = RegInit(true.B)
61 | val (_, cw) = Counter(true.B, (freq * (speed.toFloat / 1000) / 2 / pwmRange).toInt)
62 | when(cw) {
63 | when(pwm < pwmRange.U && upReg)(pwm := pwm + 1.U)
64 | .elsewhen(pwm === pwmRange.U && upReg)(upReg := false.B)
65 | .elsewhen(pwm > 0.U && !upReg)(pwm := pwm - 1.U)
66 | .otherwise(upReg := true.B)
67 | }
68 | pwmAbs(pwm)
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/blinky/src/main/scala/Toplevel.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import com.carlosedp.scalautils.ParseArguments
3 |
4 | // Blinking LED top layer
5 | class Toplevel(board: String, invReset: Boolean = true) extends Module {
6 | val io = IO(new Bundle {
7 | val led0 = Output(Bool())
8 | val led1 = Output(Bool())
9 | val led2 = Output(Bool())
10 | })
11 |
12 | // Instantiate PLL module based on board
13 | val pll = Module(new PLL0(board))
14 | pll.io.clki := clock
15 | // Define if reset should be inverted based on board switch
16 | val customReset = if (invReset) ~reset.asBool() else reset
17 |
18 | // Wrap all module instantiation using our PLL clock and custom Reset
19 | withClockAndReset(pll.io.clko, customReset) {
20 | // Instantiate the Blink module using 25Mhz from PLL output
21 | val bl = Module(new Blinky(25000000))
22 |
23 | // Connect IO between Toplevel and Blinky
24 | bl.io <> io
25 | }
26 | }
27 |
28 | // The Main object extending App to generate the Verilog code.
29 | object Toplevel extends App {
30 |
31 | // Parse command line arguments and extract required parameters
32 | // pass the input arguments and a list of parameters to be extracted
33 | // The funcion will return the parameters map and the remaining non-extracted args
34 | val (params, chiselargs) = ParseArguments(args, List("board", "invreset"))
35 | val board: String =
36 | params.getOrElse("board", throw new IllegalArgumentException("The '-board' argument should be informed."))
37 | val invReset: Boolean =
38 | params.getOrElse("invreset", "true").toBoolean
39 |
40 | // Generate Verilog
41 | (new chisel3.stage.ChiselStage).emitVerilog(
42 | new Toplevel(board, invReset),
43 | chiselargs
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/blinky/src/test/scala/BlinkySpec.scala:
--------------------------------------------------------------------------------
1 | import chisel3.iotesters._
2 | import org.scalatest.flatspec._
3 | import org.scalatest.matchers.should._
4 |
5 | class BlinkySpec extends AnyFlatSpec with Matchers {
6 | "Blinky" should "pass" in {
7 | chisel3.iotesters.Driver(() => new Blinky(25000)) { c =>
8 | new PeekPokeTester(c) {
9 |
10 | println("Start the blinking LED")
11 | for (_ <- 0 until 25) {
12 | step(10000)
13 | val l0 = if (peek(c.io.led0) == 0) 'o' else '*'
14 | val l1 = if (peek(c.io.led1) == 0) 'o' else '*'
15 | val l2 = if (peek(c.io.led2) == 0) 'o' else '*'
16 | printf("Leds: " + l0 + " " + l1 + " " + l2 + "\r")
17 | }
18 | println("\nEnd the blinking LED")
19 | }
20 | } should be(true)
21 | }
22 | }
23 |
24 | // Verilator sim
25 | class VerilatorSpec extends AnyFlatSpec with Matchers {
26 | "VerilatorSim" should "pass" in {
27 | Driver.execute(
28 | Array("--backend-name", "verilator"),
29 | () => new Blinky(1)
30 | ) { c =>
31 | new WaveformCounterTester(c, 25)
32 | } should be(true)
33 | }
34 | }
35 |
36 | // Generate VCD output
37 | class WaveformCounterSpec extends AnyFlatSpec with Matchers {
38 | "WaveformCounter" should "pass" in {
39 | Driver.execute(
40 | Array("--generate-vcd-output", "on"),
41 | () => new Blinky(1)
42 | ) { c =>
43 | new WaveformCounterTester(c, 25)
44 | } should be(true)
45 | }
46 | }
47 |
48 | class WaveformCounterTester(dut: Blinky, cycles: Int) extends PeekPokeTester(dut) {
49 | for (_ <- 0 until cycles) {
50 | step(1)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/blockram/.gitignore:
--------------------------------------------------------------------------------
1 | out/
2 | target/
3 | project/target
4 | project/project
5 | docs/generated
6 | docs-target/
7 | *.fir
8 | *.v
9 | *.anno.json
10 | *.swp
11 | firrtl_black_box_resource_files.f
12 | *~
13 | .addons-dont-touch
14 | /lib/
15 | /test_lib/
16 | /testbuild/
17 | obj_dir
18 | test_run_dir
19 | generated
20 | .metals
21 | .bloop
22 | .bsp
23 | .vscode
24 |
--------------------------------------------------------------------------------
/blockram/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = "2.7.5"
2 | maxColumn = 120
3 | align.preset = most
4 | align.multiline = false
5 | continuationIndent.defnSite = 2
6 | assumeStandardLibraryStripMargin = true
7 | docstrings = JavaDoc
8 | lineEndings = preserve
9 | includeCurlyBraceInSelectChains = false
10 | danglingParentheses.preset = true
11 | optIn.annotationNewlines = true
12 | newlines.alwaysBeforeMultilineDef = false
13 |
14 | rewrite.rules = [RedundantBraces]
15 |
16 | rewrite.redundantBraces.generalExpressions = false
17 | rewriteTokens = {
18 | "⇒": "=>"
19 | "→": "->"
20 | "←": "<-"
21 | }
--------------------------------------------------------------------------------
/blockram/Makefile:
--------------------------------------------------------------------------------
1 | SHELL = bash
2 |
3 | # Project name and toplevel
4 | project = toplevel
5 | toplevel = Toplevel
6 |
7 | # Use Docker images
8 | DOCKER=docker
9 |
10 | PWD = $(shell pwd)
11 | USBDEVICE ?= /dev/bus/usb
12 | DOCKERARGS = run --rm -v $(PWD):/src -w /src
13 | VERILATORARGS = run --name verilator --hostname verilator --rm -it --entrypoint= -v $(PWD):/work -w /work
14 |
15 | YOSYS = $(DOCKER) $(DOCKERARGS) hdlc/yosys yosys
16 | NEXTPNR = $(DOCKER) $(DOCKERARGS) hdlc/nextpnr nextpnr-$(FPGA)
17 | ECPPACK = $(DOCKER) $(DOCKERARGS) hdlc/prjtrellis ecppack
18 |
19 | scala_files = $(wildcard src/main/scala/*scala)
20 | generated_files = generated
21 | verilog_files = $(generated_files)/*.v
22 |
23 | # Targets
24 | chisel: $(verilog_files) ## Generates Verilog code from Chisel sources using Mill
25 | $(verilog_files): $(scala_files) check-board-vars clean
26 | sbt "run -td $(generated_files)"
27 |
28 | chisel_tests:
29 | sbt test
30 |
31 | check: chisel_tests ## Run Chisel tests
32 |
33 | fmt:
34 | scripts/mill $(project).reformat
35 | scripts/mill $(project).fix
36 |
37 | synth: check-board-vars $(project).bit ## Synthesizes for target BOARD with "make BOARD=board synth"
38 |
39 | check-board-vars:
40 | @test -n "$(BOARD)" || (echo "Set BOARD variable to a board from:" ; echo -n " "; cat Makefile.boards|grep BOARD| cut -d ',' -f 2 |tr -s ')\n' ', ' | sed 's/, $$/\n/'; echo "Eg. make chisel BOARD=polarfireeval"; echo; exit 1)
41 |
42 | $(project).json: $(verilog_files)
43 | $(YOSYS) -p "read_verilog -sv $^; synth_$(FPGA) -json $(generated_files)/$@ -top $(toplevel)"
44 |
45 | $(project).config: $(project).json $(LPF)
46 | $(NEXTPNR) --json $(generated_files)/$< --lpf $(LPF) --textcfg $(generated_files)/$@ $(NEXTPNR_FLAGS) --package $(PACKAGE)
47 |
48 | $(project).bit: $(project).config
49 | $(PACK) --svf $(generated_files)/$(project).svf $(generated_files)/$< $(generated_files)/$@
50 |
51 | $(project).svf: $(project).bit
52 |
53 | prog: check-board-vars $(project).svf ## Programs target BOARD with "make BOARD=board prog"
54 | $(OPENOCD) -f $(OPENOCD_JTAG_CONFIG) -f $(OPENOCD_DEVICE_CONFIG) -c "transport select jtag; init; svf $(generated_files)/$(project).svf; exit"
55 |
56 | clean: ## Clean all generated files
57 | @./scripts/mill clean
58 | @rm -rf obj_dir test_run_dir target
59 | @rm -rf $(generated_files)
60 | @rm -rf out
61 | @rm -f $(project)
62 | @rm -f *.v
63 | @rm -f *.json
64 | @rm -f *.fir
65 |
66 | help:
67 | @echo "Makefile targets:"
68 | @echo ""
69 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = "[:##]"}; {printf "\033[36m%-20s\033[0m %s\n", $$2, $$5}'
70 | @echo ""
71 | @echo "Supported boards:"
72 | @echo ""
73 | @grep -E 'BOARD|##' Makefile.boards |sed 's/.*BOARD)\,\(.*\))/\1/' | sed -n 'N;s/\n/ /;p' | awk -F"[ \t]*##" '{printf "\033[36m%-15s\033[0m - %s\n", $$1, $$2}'
74 |
75 | .PHONY: chisel clean prog help
76 | .PRECIOUS: $(project).json $(project).config $(project).bit
77 | .DEFAULT_GOAL := help
78 |
--------------------------------------------------------------------------------
/blockram/build.sbt:
--------------------------------------------------------------------------------
1 | // See README.md for license details.
2 |
3 | lazy val blinky = (project in file("."))
4 | .settings(
5 | organization := "com.carlosedp",
6 | name := "blockram",
7 | version := "0.0.1",
8 | scalaVersion := "2.12.13",
9 | semanticdbEnabled := true,
10 | semanticdbVersion := scalafixSemanticdb.revision,
11 | maxErrors := 3
12 | )
13 |
14 | crossScalaVersions := Seq("2.12.10")
15 | // Library default versions
16 | val defaultVersions = Map(
17 | "chisel3" -> "3.5-SNAPSHOT",
18 | "chisel-iotesters" -> "1.5.3",
19 | "chiseltest" -> "0.3.3",
20 | "scalatest" -> "3.2.9",
21 | "organize-imports" -> "0.5.0"
22 | )
23 | // Import libraries
24 | libraryDependencies ++= Seq("chisel3", "chisel-iotesters", "chiseltest").map { dep: String =>
25 | "edu.berkeley.cs" %% dep % sys.props
26 | .getOrElse(dep + "Version", defaultVersions(dep))
27 | }
28 | libraryDependencies += "org.scalatest" %% "scalatest" % defaultVersions("scalatest")
29 |
30 | ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % defaultVersions("organize-imports")
31 |
32 | // Aliases
33 | addCommandAlias("com", "all compile test:compile")
34 | addCommandAlias("rel", "reload")
35 | addCommandAlias("fix", "all compile:scalafix test:scalafix")
36 | addCommandAlias("fmt", "all scalafmtSbt scalafmtAll")
37 |
38 | resolvers ++= Seq(
39 | Resolver.sonatypeRepo("snapshots"),
40 | Resolver.sonatypeRepo("releases")
41 | )
42 |
43 | addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % defaultVersions("chisel3") cross CrossVersion.full)
44 |
45 | scalacOptions ++= Seq(
46 | "-unchecked",
47 | "-deprecation",
48 | "-language:reflectiveCalls",
49 | "-feature",
50 | "-Xfatal-warnings",
51 | "-Ywarn-value-discard",
52 | "-Ywarn-dead-code",
53 | "-Ywarn-unused",
54 | "-Xsource:2.11"
55 | )
56 |
--------------------------------------------------------------------------------
/blockram/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.5.5
2 |
--------------------------------------------------------------------------------
/blockram/project/metals.sbt:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT! This file is auto-generated.
2 | // This file enables sbt-bloop to create bloop config files.
3 |
4 | addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.8-19-4d9f966b")
5 |
--------------------------------------------------------------------------------
/blockram/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | logLevel := Level.Warn
2 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
3 | addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.29")
4 | addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.19")
5 |
--------------------------------------------------------------------------------
/blockram/sample.hex:
--------------------------------------------------------------------------------
1 | 000000004800012c
2 | 0000000000000000
3 | 4800002408000048
4 | 01006b69a600607d
5 | a602487d05009f42
6 | a64b5a7d14004a39
7 | 2402004ca64b7b7d
8 | 00000000480000f4
9 | 0000000000000000
10 | 0000000000000000
11 | 0000000000000000
12 | 0000000000000000
13 | 0000000000000000
14 | 0000000000000000
15 | 0000000000000000
16 | 0000000000000000
17 | 0000000000000000
18 | 0000000000000000
19 | 0000000000000000
20 | 0000000000000000
21 | 0000000000000000
22 | 0000000000000000
23 | 0000000000000000
24 | 0000000000000000
25 | 0000000000000000
26 | 0000000000000000
27 | 0000000000000000
28 | 0000000000000000
29 | 0000000000000000
30 | 0000000000000000
31 | 0000000000000000
32 | 0000000000000000
33 | 4800002408000048
34 | 01006b69a600607d
35 | a602487d05009f42
36 | a64b5a7d14004a39
37 | 2402004ca64b7b7d
38 | 3c20000048000004
39 | 782107c660210000
40 | 60211f0064210000
41 | 618c00003d800000
42 | 658c0000798c07c6
43 | 7d8903a6618c1190
44 | 480000004e800421
45 | 0000000000000000
46 | 0000000000000000
47 | 0000000000000000
48 | 0000000000000000
49 | 0000000000000000
50 | 0000000000000000
51 | 0000000000000000
52 | 0000000000000000
53 | 0000000000000000
54 | 0000000000000000
55 | 0000000000000000
56 | 0000000000000000
57 | 0000000000000000
58 | 0000000000000000
59 | 0000000000000000
60 | 0000000000000000
61 | 0000000000000000
62 | 0000000000000000
63 | 0000000000000000
64 | 0000000000000000
65 | 0000000000000000
66 | 0000000000000000
67 | 0000000000000000
68 | 0000000000000000
69 | 0000000000000000
70 | 0000000000000000
71 | 0000000000000000
72 | 0000000000000000
73 | 0000000000000000
74 | 0000000000000000
75 | 0000000000000000
76 | 0000000000000000
77 | 0000000000000000
78 | 0000000000000000
79 | 0000000000000000
80 | 0000000000000000
81 | 0000000000000000
82 | 0000000000000000
83 | 0000000000000000
84 | 0000000000000000
85 | 0000000000000000
86 | 0000000000000000
87 | 0000000000000000
88 | 0000000000000000
89 | 0000000000000000
90 | 0000000000000000
91 | 0000000000000000
92 | 0000000000000000
93 | 0000000000000000
94 | 0000000000000000
95 | 0000000000000000
96 | 0000000000000000
97 | 0000000048000000
98 | 0000000000000000
99 | 0000000000000000
100 | 0000000000000000
101 | 0000000000000000
102 | 0000000000000000
103 | 0000000000000000
104 | 0000000000000000
105 | 0000000000000000
106 | 0000000000000000
107 | 0000000000000000
108 | 0000000000000000
109 | 0000000000000000
110 | 0000000000000000
111 | 0000000000000000
112 | 0000000000000000
113 | 0000000048000000
114 | 0000000000000000
115 | 0000000000000000
116 | 0000000000000000
117 | 0000000000000000
118 | 0000000000000000
119 | 0000000000000000
120 | 0000000000000000
121 | 0000000000000000
122 | 0000000000000000
123 | 0000000000000000
124 | 0000000000000000
125 | 0000000000000000
126 | 0000000000000000
127 | 0000000000000000
128 | 0000000000000000
129 | 0000000048000000
130 | 0000000000000000
131 | 0000000000000000
132 | 0000000000000000
133 | 0000000000000000
134 | 0000000000000000
135 | 0000000000000000
136 | 0000000000000000
137 | 0000000000000000
138 | 0000000000000000
139 | 0000000000000000
140 | 0000000000000000
141 | 0000000000000000
142 | 0000000000000000
143 | 0000000000000000
144 | 0000000000000000
145 | 0000000048000000
146 | 0000000000000000
147 | 0000000000000000
148 | 0000000000000000
149 | 0000000000000000
150 | 0000000000000000
151 | 0000000000000000
152 | 0000000000000000
153 | 0000000000000000
154 | 0000000000000000
155 | 0000000000000000
156 | 0000000000000000
157 | 0000000000000000
158 | 0000000000000000
159 | 0000000000000000
160 | 0000000000000000
161 | 0000000048000000
162 | 0000000000000000
163 | 0000000000000000
164 | 0000000000000000
165 | 0000000000000000
166 | 0000000000000000
167 | 0000000000000000
168 | 0000000000000000
169 | 0000000000000000
170 | 0000000000000000
171 | 0000000000000000
172 | 0000000000000000
173 | 0000000000000000
174 | 0000000000000000
175 | 0000000000000000
176 | 0000000000000000
177 | 0000000000000000
178 | 0000000000000000
179 | 0000000000000000
180 | 0000000000000000
181 | 0000000000000000
182 | 0000000000000000
183 | 0000000000000000
184 | 0000000000000000
185 | 0000000000000000
186 | 0000000000000000
187 | 0000000000000000
188 | 0000000000000000
189 | 0000000000000000
190 | 0000000000000000
191 | 0000000000000000
192 | 0000000000000000
193 | 0000000048000000
194 | 0000000000000000
195 | 0000000000000000
196 | 0000000000000000
197 | 0000000000000000
198 | 0000000000000000
199 | 0000000000000000
200 | 0000000000000000
201 | 0000000000000000
202 | 0000000000000000
203 | 0000000000000000
204 | 0000000000000000
205 | 0000000000000000
206 | 0000000000000000
207 | 0000000000000000
208 | 0000000000000000
209 | 0000000000000000
210 | 0000000000000000
211 | 0000000000000000
212 | 0000000000000000
213 | 0000000000000000
214 | 0000000000000000
215 | 0000000000000000
216 | 0000000000000000
217 | 0000000000000000
218 | 0000000000000000
219 | 0000000000000000
220 | 0000000000000000
221 | 0000000000000000
222 | 0000000000000000
223 | 0000000000000000
224 | 0000000000000000
225 | 0000000048000000
226 | 0000000000000000
227 | 0000000000000000
228 | 0000000000000000
229 | 0000000000000000
230 | 0000000000000000
231 | 0000000000000000
232 | 0000000000000000
233 | 0000000000000000
234 | 0000000000000000
235 | 0000000000000000
236 | 0000000000000000
237 | 0000000000000000
238 | 0000000000000000
239 | 0000000000000000
240 | 0000000000000000
241 | 0000000000000000
242 | 0000000000000000
243 | 0000000000000000
244 | 0000000000000000
245 | 0000000000000000
246 | 0000000000000000
247 | 0000000000000000
248 | 0000000000000000
249 | 0000000000000000
250 | 0000000000000000
251 | 0000000000000000
252 | 0000000000000000
253 | 0000000000000000
254 | 0000000000000000
255 | 0000000000000000
256 | 0000000000000000
257 | 0000000048000000
258 | 0000000000000000
259 | 0000000000000000
260 | 0000000000000000
261 | 0000000000000000
262 | 0000000000000000
263 | 0000000000000000
264 | 0000000000000000
265 | 0000000000000000
266 | 0000000000000000
267 | 0000000000000000
268 | 0000000000000000
269 | 0000000000000000
270 | 0000000000000000
271 | 0000000000000000
272 | 0000000000000000
273 | 0000000000000000
274 | 0000000000000000
275 | 0000000000000000
276 | 0000000000000000
277 | 0000000000000000
278 | 0000000000000000
279 | 0000000000000000
280 | 0000000000000000
281 | 0000000000000000
282 | 0000000000000000
283 | 0000000000000000
284 | 0000000000000000
285 | 0000000000000000
286 | 0000000000000000
287 | 0000000000000000
288 | 0000000000000000
289 | 0000000048000000
290 | 0000000000000000
291 | 0000000000000000
292 | 0000000000000000
293 | 0000000000000000
294 | 0000000000000000
295 | 0000000000000000
296 | 0000000000000000
297 | 0000000000000000
298 | 0000000000000000
299 | 0000000000000000
300 | 0000000000000000
301 | 0000000000000000
302 | 0000000000000000
303 | 0000000000000000
304 | 0000000000000000
305 | 0000000048000000
306 | 0000000000000000
307 | 0000000000000000
308 | 0000000000000000
309 | 0000000000000000
310 | 0000000000000000
311 | 0000000000000000
312 | 0000000000000000
313 | 0000000000000000
314 | 0000000000000000
315 | 0000000000000000
316 | 0000000000000000
317 | 0000000000000000
318 | 0000000000000000
319 | 0000000000000000
320 | 0000000000000000
321 | 0000000048000000
322 | 0000000000000000
323 | 0000000000000000
324 | 0000000000000000
325 | 0000000000000000
326 | 0000000000000000
327 | 0000000000000000
328 | 0000000000000000
329 | 0000000000000000
330 | 0000000000000000
331 | 0000000000000000
332 | 0000000000000000
333 | 0000000000000000
334 | 0000000000000000
335 | 0000000000000000
336 | 0000000000000000
337 | 0000000000000000
338 | 0000000000000000
339 | 0000000000000000
340 | 0000000000000000
341 | 0000000000000000
342 | 0000000000000000
343 | 0000000000000000
344 | 0000000000000000
345 | 0000000000000000
346 | 0000000000000000
347 | 0000000000000000
348 | 0000000000000000
349 | 0000000000000000
350 | 0000000000000000
351 | 0000000000000000
352 | 0000000000000000
353 | 0000000048000000
354 | 0000000000000000
355 | 0000000000000000
356 | 0000000000000000
357 | 0000000000000000
358 | 0000000000000000
359 | 0000000000000000
360 | 0000000000000000
361 | 0000000000000000
362 | 0000000000000000
363 | 0000000000000000
364 | 0000000000000000
365 | 0000000000000000
366 | 0000000000000000
367 | 0000000000000000
368 | 0000000000000000
369 | 0000000000000000
370 | 0000000000000000
371 | 0000000000000000
372 | 0000000000000000
373 | 0000000000000000
374 | 0000000000000000
375 | 0000000000000000
376 | 0000000000000000
377 | 0000000000000000
378 | 0000000000000000
379 | 0000000000000000
380 | 0000000000000000
381 | 0000000000000000
382 | 0000000000000000
383 | 0000000000000000
384 | 0000000000000000
385 | 0000000048000000
386 | 0000000000000000
387 | 0000000000000000
388 | 0000000000000000
389 | 0000000000000000
390 | 0000000000000000
391 | 0000000000000000
392 | 0000000000000000
393 | 0000000000000000
394 | 0000000000000000
395 | 0000000000000000
396 | 0000000000000000
397 | 0000000000000000
398 | 0000000000000000
399 | 0000000000000000
400 | 0000000000000000
401 | 0000000000000000
402 | 0000000000000000
403 | 0000000000000000
404 | 0000000000000000
405 | 0000000000000000
406 | 0000000000000000
407 | 0000000000000000
408 | 0000000000000000
409 | 0000000000000000
410 | 0000000000000000
411 | 0000000000000000
412 | 0000000000000000
413 | 0000000000000000
414 | 0000000000000000
415 | 0000000000000000
416 | 0000000000000000
417 | 0000000048000000
418 | 0000000000000000
419 | 0000000000000000
420 | 0000000000000000
421 | 0000000000000000
422 | 0000000000000000
423 | 0000000000000000
424 | 0000000000000000
425 | 0000000000000000
426 | 0000000000000000
427 | 0000000000000000
428 | 0000000000000000
429 | 0000000000000000
430 | 0000000000000000
431 | 0000000000000000
432 | 0000000000000000
433 | 0000000000000000
434 | 0000000000000000
435 | 0000000000000000
436 | 0000000000000000
437 | 0000000000000000
438 | 0000000000000000
439 | 0000000000000000
440 | 0000000000000000
441 | 0000000000000000
442 | 0000000000000000
443 | 0000000000000000
444 | 0000000000000000
445 | 0000000000000000
446 | 0000000000000000
447 | 0000000000000000
448 | 0000000000000000
449 | 0000000048000000
450 | 0000000000000000
451 | 0000000000000000
452 | 0000000000000000
453 | 0000000048000000
454 | 0000000000000000
455 | 0000000000000000
456 | 0000000000000000
457 | 0000000048000000
458 | 0000000000000000
459 | 0000000000000000
460 | 0000000000000000
461 | 0000000048000000
462 | 0000000000000000
463 | 0000000000000000
464 | 0000000000000000
465 | 0000000048000000
466 | 0000000000000000
467 | 0000000000000000
468 | 0000000000000000
469 | 0000000000000000
470 | 0000000000000000
471 | 0000000000000000
472 | 0000000000000000
473 | 0000000000000000
474 | 0000000000000000
475 | 0000000000000000
476 | 0000000000000000
477 | 0000000000000000
478 | 0000000000000000
479 | 0000000000000000
480 | 0000000000000000
481 | 0000000048000000
482 | 0000000000000000
483 | 0000000000000000
484 | 0000000000000000
485 | 0000000048000000
486 | 0000000000000000
487 | 0000000000000000
488 | 0000000000000000
489 | 0000000048000000
490 | 0000000000000000
491 | 0000000000000000
492 | 0000000000000000
493 | 0000000048000000
494 | 0000000000000000
495 | 0000000000000000
496 | 0000000000000000
497 | 0000000048000000
498 | 0000000000000000
499 | 0000000000000000
500 | 0000000000000000
501 | 0000000000000000
502 | 0000000000000000
503 | 0000000000000000
504 | 0000000000000000
505 | 0000000000000000
506 | 0000000000000000
507 | 0000000000000000
508 | 0000000000000000
509 | 0000000000000000
510 | 0000000000000000
511 | 0000000000000000
512 | 0000000000000000
513 | e8010010ebc1fff0
514 | 7c0803a6ebe1fff8
515 | 3c4000014e800020
516 | 3d20c0003842a000
517 | 6129200060000000
518 | f922800079290020
519 | 394000d83d20c000
520 | 7929002061292018
521 | 4e800020f9490000
522 | 0000000000000000
523 | 3c40000100000000
524 | 600000003842a000
525 | 39090010e9228000
526 | 714a0001e9480000
527 | e86900084082fff8
528 | 4e8000205463063e
529 | 0000000000000000
530 | 3c40000100000000
531 | 600000003842a000
532 | 39090010e9228000
533 | 714a0008e9480000
534 | f86900004082fff8
535 | 000000004e800020
536 | 0000000000000000
537 | 3842a0003c400001
538 | fbc1fff07c0802a6
539 | 7fc32214fbe1fff8
540 | f80100107c7f1b78
541 | 7c3ff040f821ffd1
542 | 382100304082000c
543 | 887f00004bffff10
544 | 4bffff993bff0001
545 | 000000004bffffe4
546 | 0000028001000000
547 | 386000007c691b78
548 | 2c0a00007d4918ae
549 | 386300014d820020
550 | 000000004bfffff0
551 | 0000000000000000
552 | 3842a0003c400001
553 | fbc1fff07c0802a6
554 | 7c7e1b78fbe1fff8
555 | f80100103be00000
556 | 7fc3f378f821ffd1
557 | 7c23f8404bffffb1
558 | 382100304181000c
559 | 7c7ef8ae4bfffe90
560 | 4bffff193bff0001
561 | 000000004bffffdc
562 | 0000028001000000
563 | 3842a0003c400001
564 | fbe1fff87c0802a6
565 | 3bff72403fe2ffff
566 | f821ffd1f8010010
567 | 3c62ffff4bfffe6d
568 | 4bffff8538637200
569 | 386372383c62ffff
570 | 4bfffe914bffff79
571 | 2803000d5463063e
572 | 7fe3fb7840820010
573 | 4bffffe84bffff61
574 | 4bffffe04bfffead
575 | 0100000000000000
576 | 0000000000000180
577 | 7266206f6c6c6548
578 | 6573696843206d6f
579 | 61202c747461776c
580 | 6f506e65704f206e
581 | 636f727020726577
582 | 0a0d21726f737365
583 | 0000000000000000
584 | 000000000000203e
585 | 00000000203e0a0d
586 | 0000000000000010
587 | 0141780400527a01
588 | 0000001000010c1b
589 | fffffdb000000018
590 | 0000000000000040
591 | 0000002c00000010
592 | 00000038fffffddc
593 | 0000001000000000
594 | fffffe0000000040
595 | 0000000000000034
596 | 0000005400000028
597 | 00000050fffffe20
598 | 9f029e0041094500
599 | 437e4111300e4401
600 | 4106dedf41000e0a
601 | 000000100000000b
602 | fffffe4400000080
603 | 0000000000000028
604 | 0000009400000028
605 | 00000058fffffe58
606 | 9f029e0041094500
607 | 457e4111300e4401
608 | 4106dedf41000e0a
609 | 0000001c0000000b
610 | fffffe84000000c0
611 | 410944000000006c
612 | 4111300e44019f00
613 | 000000000000007e
614 |
--------------------------------------------------------------------------------
/blockram/src/main/scala/utils/DualportRAM.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import chisel3.util.log2Ceil
3 | import chisel3.util.experimental.loadMemoryFromFileInline
4 | import chisel3.experimental.{annotate, ChiselAnnotation}
5 | import firrtl._
6 |
7 | class MemoryPort(val bitWidth: Int, val words: Int, val rw: Boolean = true) extends Bundle {
8 | val addr = Output(UInt(log2Ceil(words).W))
9 | val readData = Input(UInt(bitWidth.W))
10 |
11 | val writeEnable = if (rw) Some(Output(Bool())) else None
12 | val writeData = if (rw) Some(Output(UInt(bitWidth.W))) else None
13 | // val writeEnable = (Output(Bool()))
14 | // val writeData = (Output(UInt(bitWidth.W)))
15 | }
16 |
17 | class DualPortRAM(
18 | sizeBytes: Int = 1,
19 | bitWidth: Int = 32,
20 | memoryFile: String = ""
21 | ) extends Module {
22 | val words = sizeBytes / bitWidth
23 | val io = IO(new Bundle() {
24 | val loadStorePort = Flipped(new MemoryPort(bitWidth, words, true))
25 | val fetchPort = Flipped(new MemoryPort(bitWidth, words, false))
26 | })
27 |
28 | println(s"Dual-port Memory Parameters:")
29 | println(s" Words: $words")
30 | println(s" Size: " + words * bitWidth + " Kb")
31 | println(s" Bit width: $bitWidth bit")
32 | println(s" Addr Width: " + io.loadStorePort.addr.getWidth + " bit")
33 |
34 | // This is required to have readmem outside `ifndef SYNTHESIS` and be synthesized by FPGA tools
35 | annotate(new ChiselAnnotation {
36 | override def toFirrtl =
37 | firrtl.annotations.MemorySynthInit
38 | })
39 |
40 | val mem = SyncReadMem(words, UInt(bitWidth.W))
41 | if (memoryFile.trim().nonEmpty) {
42 | println(s" Load memory file: " + memoryFile)
43 | loadMemoryFromFileInline(mem, memoryFile)
44 | }
45 |
46 | io.loadStorePort.readData := mem.read(io.loadStorePort.addr)
47 | io.fetchPort.readData := mem.read(io.fetchPort.addr)
48 |
49 | when(io.loadStorePort.writeEnable.get) {
50 | mem.write(io.loadStorePort.addr, io.loadStorePort.writeData.get)
51 | }
52 | }
53 |
54 | object DualPortRAMObj extends App {
55 | (new chisel3.stage.ChiselStage).emitVerilog(
56 | new DualPortRAM(
57 | sizeBytes = 8,
58 | bitWidth = 8,
59 | memoryFile = "sample.hex"
60 | ),
61 | Array("-X", "verilog") ++ args
62 | )
63 | }
64 |
--------------------------------------------------------------------------------
/blockram/src/main/scala/utils/MultiMemory.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import chisel3.util.log2Ceil
3 | import chisel3.util.experimental.loadMemoryFromFileInline
4 | import chisel3.experimental.{annotate, ChiselAnnotation}
5 |
6 | class MultiMem extends Module {
7 | val io = IO(new Bundle() {
8 | val loadStorePort = Flipped(new MemoryPort2(32, 32, true))
9 | val loadStorePort2 = Flipped(new MemoryPort2(32, 32, true))
10 | })
11 | // This is required to have readmem outside `ifndef SYNTHESIS` and be synthesized by FPGA tools
12 | annotate(new ChiselAnnotation {
13 | override def toFirrtl =
14 | firrtl.annotations.MemorySynthInit
15 | })
16 | val mem1 =
17 | Module(
18 | new DualPortMultiRAM(
19 | sizeBytes = 32 * 1024,
20 | bitWidth = 32,
21 | memoryFile = "sample.hex"
22 | )
23 | )
24 | mem1.io.loadStorePort <> io.loadStorePort
25 |
26 | val mem2 =
27 | Module(
28 | new DualPortMultiRAM(
29 | sizeBytes = 32 * 1024,
30 | bitWidth = 32,
31 | memoryFile = "sample2.hex"
32 | )
33 | )
34 | mem2.io.loadStorePort <> io.loadStorePort2
35 | }
36 |
37 | class MemoryPort2(val bitWidth: Int, val words: Int, val rw: Boolean) extends Bundle {
38 | val addr = Output(UInt(log2Ceil(words).W))
39 | val readData = Input(UInt(bitWidth.W))
40 |
41 | val writeEnable = if (rw) Some(Output(Bool())) else None
42 | val writeData = if (rw) Some(Output(UInt(bitWidth.W))) else None
43 | }
44 |
45 | class DualPortMultiRAM(
46 | sizeBytes: Int = 1,
47 | bitWidth: Int = 32,
48 | memoryFile: String = ""
49 | ) extends Module {
50 | val words = sizeBytes / bitWidth
51 | val io = IO(new Bundle() {
52 | val loadStorePort = Flipped(new MemoryPort2(bitWidth, words, true))
53 | })
54 |
55 | println(s"Dual-port Memory $name Parameters:")
56 | println(s" Words: $words")
57 | println(s" Size: " + words * bitWidth + " Kb")
58 | println(s" Bit width: $bitWidth bit")
59 | println(s" Addr Width: " + io.loadStorePort.addr.getWidth + " bit")
60 |
61 | val mem = SyncReadMem(words, UInt(bitWidth.W))
62 | // This prevents deduping this memory module
63 | // Ref. https://github.com/chipsalliance/firrtl/issues/2168
64 | val dedupBlock = WireInit(mem.hashCode.U)
65 |
66 | if (memoryFile.trim().nonEmpty) {
67 | println(s" Load memory file: " + memoryFile)
68 | loadMemoryFromFileInline(mem, memoryFile)
69 | }
70 |
71 | io.loadStorePort.readData := mem.read(io.loadStorePort.addr)
72 |
73 | when(io.loadStorePort.writeEnable.get) {
74 | mem.write(io.loadStorePort.addr, io.loadStorePort.writeData.get)
75 | }
76 | }
77 |
78 | object MultiMem extends App {
79 | (new chisel3.stage.ChiselStage).emitVerilog(
80 | new MultiMem(),
81 | Array() ++ args
82 | )
83 | }
84 |
--------------------------------------------------------------------------------
/blockram/src/main/scala/utils/SingleportRAM.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import chisel3.util.experimental.loadMemoryFromFileInline
3 | import chisel3.experimental.{annotate, ChiselAnnotation}
4 |
5 | class SinglePortRAM(words: Int = 1, width: Int = 32, memoryFile: String = "") extends Module {
6 | val addrWidth = chiselTypeOf((words * 1024).U)
7 | val io = IO(new Bundle {
8 | val addr1 = Input(addrWidth)
9 | val dataIn1 = Input(UInt(width.W))
10 | val en1 = Input(Bool())
11 | val we1 = Input(Bool())
12 | val dataOut1 = Output(UInt(width.W))
13 | })
14 | println(s"Dual-port Memory Parameters:")
15 | println(s" Size (words): $words")
16 | println(s" Size (kb): " + words * width + " Kb")
17 | println(s" Width: $width bit")
18 | println(s" Addr Width: " + io.addr1.getWidth + " bit")
19 |
20 | // This is required to have readmem outside `ifndef SYNTHESIS` and be synthesized by FPGA tools
21 | annotate(new ChiselAnnotation {
22 | override def toFirrtl =
23 | firrtl.annotations.MemorySynthInit
24 | })
25 |
26 | val mem = SyncReadMem(words, UInt(width.W))
27 | if (memoryFile.trim().nonEmpty) {
28 | println(s" Load memory file: " + memoryFile)
29 | loadMemoryFromFileInline(mem, memoryFile)
30 | }
31 |
32 | when(io.we1) {
33 | mem.write(io.addr1, io.dataIn1)
34 | }
35 | io.dataOut1 := mem.read(io.addr1, io.en1)
36 | }
37 |
38 | object SinglePortRAMObj extends App {
39 | (new chisel3.stage.ChiselStage).emitVerilog(
40 | new SinglePortRAM(16, width = 64, memoryFile = "sample.hex"),
41 | Array("-X", "verilog") ++ args
42 | )
43 | }
44 |
--------------------------------------------------------------------------------
/blockram/src/main/scala/utils/SubByteMemory.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | // import chisel3.experimental.{ChiselAnnotation, annotate}
3 | // import firrtl.annotations.MemoryFileInlineAnnotation
4 |
5 | class SubByteMemory(words: Int, bits: Int, addrBits: Int, filename: String) extends Module {
6 | val io = IO(new Bundle {
7 | val dataOut = Output(Vec(bits / 8, UInt(8.W)))
8 | val dataIn = Input(Vec(bits / 8, UInt(8.W)))
9 | val readAddr = Input(UInt(addrBits.W))
10 | val readEnable = Input(Bool())
11 | val writeAddr = Input(UInt(addrBits.W))
12 | val writeMask = Input(Vec(bits / 8, Bool()))
13 | })
14 |
15 | println(s"Memory initialized with file: $filename")
16 | val mem = SyncReadMem(words, Vec(bits / 8, UInt(8.W)))
17 | mem.write(io.writeAddr, io.dataIn, io.writeMask)
18 | io.dataOut := mem.read(io.readAddr, io.readEnable)
19 | }
20 |
21 | object SubByteMemoryObj extends App {
22 | (new chisel3.stage.ChiselStage).emitVerilog(
23 | new SubByteMemory(16, 64, 32, "sample.hex"),
24 | Array("-X", "verilog") ++ args
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/fomublink/.gitignore:
--------------------------------------------------------------------------------
1 | out/
2 | target/
3 | project/target
4 | project/project
5 | docs/generated
6 | docs-target/
7 | *.fir
8 | *.v
9 | *.anno.json
10 | *.swp
11 | *~
12 | .addons-dont-touch
13 | /lib/
14 | /test_lib/
15 | /testbuild/
16 | obj_dir
17 | test_run_dir
18 | generated
19 | .metals
20 | .bloop
21 | .bsp
22 | .vscode
23 |
--------------------------------------------------------------------------------
/fomublink/.scalafix.conf:
--------------------------------------------------------------------------------
1 | rules = [
2 | RemoveUnused,
3 | DisableSyntax,
4 | LeakingImplicitClassVal,
5 | NoAutoTupling,
6 | NoValInForComprehension,
7 | OrganizeImports,
8 | ProcedureSyntax,
9 | ]
10 |
11 | OrganizeImports {
12 | groupedImports = Merge
13 | }
14 |
15 | RemoveUnused {
16 | imports = false // handled by OrganizeImports
17 | }
--------------------------------------------------------------------------------
/fomublink/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = "2.7.5"
2 | maxColumn = 120
3 | align.preset = most
4 | align.multiline = false
5 | continuationIndent.defnSite = 2
6 | assumeStandardLibraryStripMargin = true
7 | docstrings = JavaDoc
8 | lineEndings = preserve
9 | includeCurlyBraceInSelectChains = false
10 | danglingParentheses.preset = true
11 | optIn.annotationNewlines = true
12 | newlines.alwaysBeforeMultilineDef = false
13 |
14 | rewrite.rules = [RedundantBraces]
15 |
16 | rewrite.redundantBraces.generalExpressions = false
17 | rewriteTokens = {
18 | "⇒": "=>"
19 | "→": "->"
20 | "←": "<-"
21 | }
--------------------------------------------------------------------------------
/fomublink/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.watcherExclude": {
3 | "**/target": true
4 | }
5 | }
--------------------------------------------------------------------------------
/fomublink/Makefile:
--------------------------------------------------------------------------------
1 | project = toplevel
2 | toplayer = BlinkTop
3 |
4 | scala_files = $(wildcard src/main/scala/*scala)
5 | generated_files = generated
6 | verilog_files = $(generated_files)/*.v
7 |
8 | # Params for Fomu PVT
9 | YOSYSFLAGS ?= -D PVT=1
10 | PNRFLAGS ?= --up5k --package uwg30
11 | PCF ?= constraints/fomu-pvt.pcf
12 | FPGA ?= ice40
13 |
14 | # Tools Configuration
15 | DOCKER=docker
16 | PWD = $(shell pwd)
17 | DOCKERARGS = run --rm -v $(PWD):/src -w /src
18 | # Using Docker containers
19 | # YOSYS = $(DOCKER) $(DOCKERARGS) hdlc/yosys yosys
20 | # NEXTPNR = $(DOCKER) $(DOCKERARGS) hdlc/nextpnr nextpnr-$(FPGA)
21 | # ICEPACK = $(DOCKER) $(DOCKERARGS) hdlc/icestorm icepack
22 |
23 | # Using local tools
24 | YOSYS = yosys
25 | NEXTPNR = nextpnr-$(FPGA)
26 | ICEPACK = icepack
27 |
28 | # Targets
29 | all: $(project).dfu
30 |
31 | # Generate Verilog files from Chisel
32 | chisel: $(verilog_files)
33 | $(verilog_files): $(scala_files)
34 | scripts/mill $(project).run -td $(generated_files)
35 |
36 | fmt:
37 | scripts/mill all $(project).{reformat,fix}
38 |
39 | # Use *Yosys* to generate the synthesized netlist.
40 | # This is called the **synthesis** and **tech mapping** step.
41 | $(project).json: $(verilog_files)
42 | $(YOSYS) \
43 | $(YOSYSFLAGS) \
44 | -p 'synth_$(FPGA) -top $(toplayer) -json $(generated_files)/$(project).json' $(verilog_files)
45 |
46 | # Use **nextpnr** to generate the FPGA configuration.
47 | # This is called the **place** and **route** step.
48 | $(project).asc: $(project).json $(PCF)
49 | $(NEXTPNR) \
50 | $(PNRFLAGS) \
51 | --pcf $(PCF) \
52 | --json $(generated_files)/$(project).json \
53 | --asc $(generated_files)/$(project).asc
54 |
55 | # Use icepack to convert the FPGA configuration into a "bitstream" loadable onto the FPGA.
56 | # This is called the bitstream generation step.
57 | $(project).bit: $(project).asc
58 | $(ICEPACK) $(generated_files)/$(project).asc $(generated_files)/$(project).bit
59 |
60 | # Use dfu-suffix to generate the DFU image from the FPGA bitstream.
61 | $(project).dfu: $(project).bit
62 | cp $(generated_files)/$(project).bit $(generated_files)/$(project).dfu
63 | dfu-suffix -v 1209 -p 70b1 -a $(generated_files)/$(project).dfu
64 |
65 | # Use df-util to load the DFU image onto the Fomu.
66 | load: clean $(project).dfu
67 | dfu-util -D $(generated_files)/$(project).dfu
68 |
69 | clean: ## Clean all generated files
70 | @./scripts/mill clean
71 | @rm -f $(project).fir $(project).anno.json $(project).v
72 | @rm -rf obj_dir test_run_dir target
73 | @rm -rf $(generated_files)
74 | @rm -f $(project)
75 | @rm -rf *.bit *.json *.svf *.config out *.fir *.v *.f
76 |
77 | .PHONY: clean
--------------------------------------------------------------------------------
/fomublink/Readme.md:
--------------------------------------------------------------------------------
1 | # Chisel Blinky on FOMU
2 |
3 | This is a simple Blinky project to demonstrate Chisel functionality with scripts and tooling to be able to synth and run on [Fomu](https://tomu.im/fomu.html).
4 |
5 | This project uses two blackbox modules to import Verilog code from ICE40 IP, one for it's' PLL and another for the RGB led driver.
6 |
7 | ## Synthesis using Open Source tools (yosys/nextpnr)
8 |
9 | The faster way to get started is using FuseSoc and generating the files in containers. You would need **Docker** and **FuseSoc**. To program, use [dfu-util](http://dfu-util.sourceforge.net/).
10 |
11 | To install Fusesoc (requires Python3 and pip3) and add to your path:
12 |
13 | ```sh
14 | pip3 install --upgrade --user fusesoc
15 | export PATH=~/.local/bin:$PATH
16 |
17 | #Check if it's working:
18 |
19 | $ fusesoc --version
20 | 1.12.0
21 | ```
22 |
23 | Then create the project dir and files:
24 |
25 | ```sh
26 | mkdir fusesoc-fomublink && cd fusesoc-fomublink
27 | fusesoc library add fusesoc-cores https://github.com/fusesoc/fusesoc-cores
28 |
29 | # Since Fomublink is not a standalone repo (but a folder in an umbrella repo)
30 | # we clone it locally and add the library as a local dir.
31 | git clone https://github.com/carlosedp/chisel-playground
32 | fusesoc library add fomublink $(pwd)/chisel-playground/fomublink
33 |
34 | # Get the container wrapper
35 | wget https://gist.github.com/carlosedp/c0e29d55e48309a48961f2e3939acfe9/raw/bfeb1cfe2e188c1d5ced0b09aabc9902fdfda6aa/runme.py
36 | chmod +x runme.py
37 |
38 | # Generate the files (Chisel to Verilog, Synthesys, Place'nRoute, Bitstream packing)
39 | EDALIZE_LAUNCHER=$(realpath ../runme.py) fusesoc run --target=fomu-pvt carlosedp:demo:fomublink:0
40 | ```
41 |
42 | Then program the bitstream to the Fomu with provided instructions on terminal.
43 |
44 |
45 | [](https://twitter.com/carlosedp/status/1381700282246119425)
46 |
47 | Another option is using local tools. For this you need to download fomu-toolchain from and add it to your path.
48 |
49 | For example, on Mac:
50 |
51 | ```sh
52 | wget https://github.com/im-tomu/fomu-toolchain/releases/download/v1.5.6/fomu-toolchain-macos-v1.5.6.zip
53 | unzip fomu-toolchain-macos-v1.5.6.zip
54 |
55 | # Add to path
56 | export PATH=$(realpath ./bin):$PATH
57 | ```
58 |
59 | Build the bitstream:
60 |
61 | ```sh
62 | make
63 | ```
64 |
65 | And finally, with the Fomu connected, program the bitstream:
66 |
67 | ```sh
68 | make load
69 | ```
70 |
--------------------------------------------------------------------------------
/fomublink/build.sc:
--------------------------------------------------------------------------------
1 | import mill._
2 | import mill.scalalib._
3 | import scalafmt._
4 | import coursier.MavenRepository
5 | import $ivy.`com.goyeau::mill-scalafix:0.2.1`
6 | import com.goyeau.mill.scalafix.ScalafixModule
7 |
8 | def mainClass = Some("Blink")
9 |
10 | val defaultVersions = Map(
11 | "scala" -> "2.12.12",
12 | "chisel3" -> "3.4.3",
13 | "chisel-iotesters" -> "1.5.0",
14 | "chiseltest" -> "0.3.1",
15 | "scalatest" -> "3.2.2",
16 | "organize-imports" -> "0.5.0",
17 | "paradise" -> "2.1.1"
18 | )
19 | val binCrossScalaVersions = Seq("2.12.10", "2.11.12")
20 |
21 | trait HasChisel3 extends ScalaModule {
22 | override def ivyDeps = Agg(
23 | ivy"edu.berkeley.cs::chisel3:${defaultVersions("chisel3")}"
24 | )
25 | }
26 |
27 | trait HasChiselTests extends CrossSbtModule {
28 | object test extends Tests {
29 | override def ivyDeps = Agg(
30 | ivy"org.scalatest::scalatest:${defaultVersions("scalatest")}",
31 | ivy"edu.berkeley.cs::chisel-iotesters:${defaultVersions("chisel-iotesters")}",
32 | ivy"edu.berkeley.cs::chiseltest:${defaultVersions("chiseltest")}"
33 | )
34 | def repositories = super.repositories ++ Seq(
35 | MavenRepository("https://oss.sonatype.org/content/repositories/snapshots")
36 | )
37 | def testFrameworks = Seq("org.scalatest.tools.Framework")
38 |
39 | def testOne(args: String*) = T.command {
40 | super.runMain("org.scalatest.run", args: _*)
41 | }
42 | }
43 | }
44 |
45 | trait HasMacroParadise extends ScalaModule {
46 | // Enable macro paradise for @chiselName et al
47 | val macroPlugins = Agg(
48 | ivy"org.scalamacros:::paradise:${defaultVersions("paradise")}"
49 | )
50 | def scalacPluginIvyDeps = macroPlugins
51 | def compileIvyDeps = macroPlugins
52 | }
53 |
54 | /**
55 | * Scala 2.12 module that is source-compatible with 2.11.
56 | * This is due to Chisel's use of structural types. See
57 | * https://github.com/freechipsproject/chisel3/issues/606
58 | */
59 | trait HasXsource211 extends ScalaModule {
60 | override def scalacOptions = T {
61 | super.scalacOptions() ++ Seq(
62 | "-deprecation",
63 | "-unchecked",
64 | "-Xsource:2.11"
65 | )
66 | }
67 | }
68 |
69 | trait CodeQuality extends ScalafixModule with ScalafmtModule {
70 | def scalafixIvyDeps =
71 | Agg(
72 | ivy"com.github.liancheng::organize-imports:${defaultVersions("organize-imports")}"
73 | )
74 | }
75 |
76 | trait ScalacOptions extends ScalaModule {
77 | override def scalacOptions = T {
78 | super.scalacOptions() ++ Seq(
79 | "-language:reflectiveCalls",
80 | "-feature",
81 | "-Xfatal-warnings",
82 | "-Ywarn-value-discard",
83 | "-Ywarn-dead-code",
84 | "-Ywarn-unused"
85 | )
86 | }
87 | }
88 |
89 | object toplevel
90 | extends CrossSbtModule
91 | with HasChisel3
92 | with HasChiselTests
93 | with HasXsource211
94 | with HasMacroParadise
95 | with CodeQuality
96 | with ScalacOptions {
97 | override def millSourcePath = super.millSourcePath
98 | def crossScalaVersion = defaultVersions("scala")
99 | }
100 |
--------------------------------------------------------------------------------
/fomublink/constraints/fomu-pvt.pcf:
--------------------------------------------------------------------------------
1 | set_io io_clki F4
2 | set_io io_rgb0 A5
3 | set_io io_rgb1 B5
4 | set_io io_rgb2 C5
5 | set_io io_usb_dn A2
6 | set_io io_usb_dp A1
7 | set_io io_usb_dp_pu A4
8 | set_io pmod_1 E4
9 | set_io pmod_2 D5
10 | set_io pmod_3 E5
11 | set_io pmod_4 F5
12 | set_io pmoda_1 E4
13 | set_io pmoda_2 D5
14 | set_io pmoda_3 E5
15 | set_io pmoda_4 F5
16 | set_io user_1 E4
17 | set_io user_2 D5
18 | set_io user_3 E5
19 | set_io user_4 F5
20 | set_io touch_1 E4
21 | set_io touch_2 D5
22 | set_io touch_3 E5
23 | set_io touch_4 F5
24 | set_io spi_mosi F1
25 | set_io spi_miso E1
26 | set_io spi_clk D1
27 | set_io spi_io2 F2
28 | set_io spi_io3 B1
29 | set_io spi_cs C1
30 |
--------------------------------------------------------------------------------
/fomublink/fomublink.core:
--------------------------------------------------------------------------------
1 | CAPI=2:
2 |
3 | name: carlosedp:demo:fomublink:0
4 |
5 | filesets:
6 | fomu-pvt:
7 | depend: ["fusesoc:utils:generators:0.1.6"]
8 | files:
9 | - constraints/fomu-pvt.pcf : {file_type : PCF}
10 | - post-instructions.txt:
11 | { file_type: user, copyto: post-instructions.txt }
12 |
13 | generate:
14 | fomu-pvt:
15 | generator: chisel
16 | parameters:
17 | chiselproject: toplevel
18 | copy_core: true
19 | output:
20 | files:
21 | - generated/BlinkTop.v: { file_type: verilogSource }
22 |
23 | targets:
24 | fomu-pvt:
25 | default_tool : icestorm
26 | description : Fomu PVT with Lattice ICE40UP5K based open-source board
27 | hooks:
28 | post_run: [dfu-util-fomu]
29 | filesets : [fomu-pvt]
30 | generate: [fomu-pvt]
31 | tools:
32 | icestorm:
33 | nextpnr_options : ["--up5k", "--package", "uwg30"]
34 | pnr : next
35 | toplevel : BlinkTop
36 |
37 | scripts:
38 | dfu-util-fomu:
39 | cmd: ["python3", "-c", "import os;print(open('post-instructions.txt','r').read().replace('{}',os.path.join(os.getcwd(), 'carlosedp_demo_fomublink_0.bin')))"]
--------------------------------------------------------------------------------
/fomublink/post-instructions.txt:
--------------------------------------------------------------------------------
1 | Programming instructions:
2 |
3 | Download and install dfu-util from http://dfu-util.sourceforge.net/
4 | Run:
5 | dfu-util -e -d 1209:5bf0 -D {}
--------------------------------------------------------------------------------
/fomublink/scripts/mill:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # This is a wrapper script, that automatically download mill from GitHub release pages
4 | # You can give the required mill version with MILL_VERSION env variable
5 | # If no version is given, it falls back to the value of DEFAULT_MILL_VERSION
6 | DEFAULT_MILL_VERSION=0.9.6
7 |
8 | set -e
9 |
10 | if [ -z "$MILL_VERSION" ] ; then
11 | if [ -f ".mill-version" ] ; then
12 | MILL_VERSION="$(head -n 1 .mill-version 2> /dev/null)"
13 | elif [ -f "mill" ] && [ "$BASH_SOURCE" != "mill" ] ; then
14 | MILL_VERSION=$(grep -F "DEFAULT_MILL_VERSION=" "mill" | head -n 1 | cut -d= -f2)
15 | else
16 | MILL_VERSION=$DEFAULT_MILL_VERSION
17 | fi
18 | fi
19 |
20 | if [ "x${XDG_CACHE_HOME}" != "x" ] ; then
21 | MILL_DOWNLOAD_PATH="${XDG_CACHE_HOME}/mill/download"
22 | else
23 | MILL_DOWNLOAD_PATH="${HOME}/.cache/mill/download"
24 | fi
25 | MILL_EXEC_PATH="${MILL_DOWNLOAD_PATH}/${MILL_VERSION}"
26 |
27 | version_remainder="$MILL_VERSION"
28 | MILL_MAJOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}"
29 | MILL_MINOR_VERSION="${version_remainder%%.*}"; version_remainder="${version_remainder#*.}"
30 |
31 | if [ ! -x "$MILL_EXEC_PATH" ] ; then
32 | mkdir -p $MILL_DOWNLOAD_PATH
33 | if [ "$MILL_MAJOR_VERSION" -gt 0 ] || [ "$MILL_MINOR_VERSION" -ge 5 ] ; then
34 | ASSEMBLY="-assembly"
35 | fi
36 | DOWNLOAD_FILE=$MILL_EXEC_PATH-tmp-download
37 | MILL_DOWNLOAD_URL="https://github.com/lihaoyi/mill/releases/download/${MILL_VERSION%%-*}/$MILL_VERSION${ASSEMBLY}"
38 | curl --fail -L -o "$DOWNLOAD_FILE" "$MILL_DOWNLOAD_URL"
39 | chmod +x "$DOWNLOAD_FILE"
40 | mv "$DOWNLOAD_FILE" "$MILL_EXEC_PATH"
41 | unset DOWNLOAD_FILE
42 | unset MILL_DOWNLOAD_URL
43 | fi
44 |
45 | unset MILL_DOWNLOAD_PATH
46 | unset MILL_VERSION
47 |
48 | exec $MILL_EXEC_PATH "$@"
49 |
--------------------------------------------------------------------------------
/fomublink/src/main/scala/Blinky.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | import chisel3.experimental._
3 | import chisel3.util._
4 | import firrtl.annotations.PresetAnnotation
5 |
6 | // Blinking LED top layer
7 | // We use RawModule to avoid Chisel creating a module with implicit clock and reset
8 | class BlinkTop extends RawModule {
9 | val io = IO(new Bundle {
10 | // 48MHz Clock input
11 | val clki = Input(Clock())
12 | val reset = Input(AsyncReset())
13 |
14 | // LED outputs
15 | // --------
16 | val rgb0 = Output(Bool())
17 | val rgb1 = Output(Bool())
18 | val rgb2 = Output(Bool())
19 |
20 | // USB Pins (which should be statically driven if not being used).
21 | // --------
22 | val usb_dp = Output(Bool())
23 | val usb_dn = Output(Bool())
24 | val usb_dp_pu = Output(Bool())
25 | })
26 |
27 | // initialize registers to their reset value when the bitstream is programmed since there is no reset wire
28 | annotate(new ChiselAnnotation {
29 | override def toFirrtl = PresetAnnotation(io.reset.toTarget)
30 | })
31 |
32 | // Disconnect USB pins
33 | io.usb_dp := false.B
34 | io.usb_dn := false.B
35 | io.usb_dp_pu := false.B
36 |
37 | // Instantiate the PLL with clock
38 | val pll = Module(new SB_GB())
39 | pll.io.USER_SIGNAL_TO_GLOBAL_BUFFER := io.clki
40 |
41 | // Instantiate the RGB Led driver from ICE40 FPGA.
42 | val ledDrv = Module(new SB_RGBA_DRV())
43 | io.rgb0 := ledDrv.io.RGB0
44 | io.rgb1 := ledDrv.io.RGB1
45 | io.rgb2 := ledDrv.io.RGB2
46 | ledDrv.io.CURREN := true.B
47 | ledDrv.io.RGBLEDEN := true.B
48 |
49 | chisel3.withClockAndReset(pll.io.GLOBAL_BUFFER_OUTPUT, io.reset) {
50 | // In this withClock scope, all synchronous elements are clocked against pll.io.clko.
51 | val (counterValue, _) = Counter(true.B, 48000000)
52 | ledDrv.io.RGB2PWM := counterValue(23)
53 | ledDrv.io.RGB1PWM := counterValue(24)
54 | ledDrv.io.RGB0PWM := counterValue(25)
55 | }
56 | }
57 |
58 | /**
59 | * An object extending App to generate the Verilog code.
60 | */
61 | object Blink extends App {
62 | (new chisel3.stage.ChiselStage).emitVerilog(
63 | new BlinkTop(),
64 | args
65 | )
66 | }
67 |
--------------------------------------------------------------------------------
/fomublink/src/main/scala/ICE40ledDrvBlackBox.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | // import chisel3.util.HasBlackBoxInline
3 |
4 | /**
5 | * Instantiate iCE40 LED driver hard logic, connecting up
6 | * counter state and LEDs.
7 | *
8 | * Note that it's possible to drive the LEDs directly,
9 | * however that is not current-limited and results in
10 | * overvolting the red LED.
11 | *
12 | * See also:
13 | * https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/IK/ICE40LEDDriverUsageGuide.ashx?document_id=50668
14 | */
15 |
16 | // Instantiate the IP directly instead of using inline Verilog
17 | class SB_RGBA_DRV()
18 | extends BlackBox(
19 | Map(
20 | "CURRENT_MODE" -> "0b1", // half current
21 | "RGB0_CURRENT" -> "0b000011", // 4 mA
22 | "RGB1_CURRENT" -> "0b000011", // 4 mA
23 | "RGB2_CURRENT" -> "0b000011" // 4 mA
24 | )
25 | ) {
26 | val io = IO(new Bundle {
27 | val CURREN = Input(Bool())
28 | val RGBLEDEN = Input(Bool())
29 | val RGB2PWM = Input(Bool()) // Blue
30 | val RGB1PWM = Input(Bool()) // Red
31 | val RGB0PWM = Input(Bool()) // Green
32 | val RGB0 = Output(Bool())
33 | val RGB1 = Output(Bool())
34 | val RGB2 = Output(Bool())
35 | })
36 | }
37 |
38 | // Instantiate thru inline verilog. Just here for documentation since
39 | // instantiation above does the same.
40 | // class ICE40ledDrvBlackBox() extends BlackBox with HasBlackBoxInline {
41 | // val io = IO(new Bundle() {
42 | // // LED inputs and outputs
43 | // val rgb0_in = Input(Bool())
44 | // val rgb1_in = Input(Bool())
45 | // val rgb2_in = Input(Bool())
46 | // val rgb0_out = Output(Bool())
47 | // val rgb1_out = Output(Bool())
48 | // val rgb2_out = Output(Bool())
49 | // })
50 |
51 | // setInline(
52 | // "ICE40ledDrvBlackBox.v",
53 | // s"""
54 | // | module ICE40ledDrvBlackBox(
55 | // | input rgb0_in,
56 | // | input rgb1_in,
57 | // | input rgb2_in,
58 | // | output rgb0_out,
59 | // | output rgb1_out,
60 | // | output rgb2_out
61 | // | );
62 | // |
63 | // | SB_RGBA_DRV #(
64 | // | .CURRENT_MODE("0b1"), // half current
65 | // | .RGB0_CURRENT("0b000011"), // 4 mA
66 | // | .RGB1_CURRENT("0b000011"), // 4 mA
67 | // | .RGB2_CURRENT("0b000011") // 4 mA
68 | // | ) RGBA_DRIVER (
69 | // | .CURREN(1'b1),
70 | // | .RGBLEDEN(1'b1),
71 | // | .RGB2PWM(rgb0_in), // Blue
72 | // | .RGB1PWM(rgb1_in), // Red
73 | // | .RGB0PWM(rgb2_in), // Green
74 | // | .RGB0(rgb0_out),
75 | // | .RGB1(rgb1_out),
76 | // | .RGB2(rgb2_out)
77 | // | );
78 | // |
79 | // | endmodule
80 | // |""".stripMargin
81 | // )
82 | // }
83 |
--------------------------------------------------------------------------------
/fomublink/src/main/scala/ICE40pllBlackbox.scala:
--------------------------------------------------------------------------------
1 | import chisel3._
2 | // import chisel3.util.HasBlackBoxInline
3 |
4 | // Instantiate the IP directly
5 | class SB_GB extends BlackBox() {
6 | val io = IO(new Bundle {
7 | val USER_SIGNAL_TO_GLOBAL_BUFFER = Input(Clock())
8 | val GLOBAL_BUFFER_OUTPUT = Output(Clock())
9 | })
10 | }
11 |
12 | // Instantiate thru inline verilog. Just here for documentation since
13 | // instantiation above does the same.
14 | // class ICE40pllBlackbox() extends BlackBox with HasBlackBoxInline {
15 | // val io = IO(new Bundle() {
16 | // val clki = Input(Clock())
17 | // val clko = Output(Clock())
18 | // })
19 |
20 | // setInline(
21 | // "ICE40pllBlackbox.v",
22 | // s"""
23 | // | module ICE40pllBlackbox(
24 | // | input clki,
25 | // | output clko
26 | // | );
27 | // |
28 | // | SB_GB clk_gb (
29 | // | .USER_SIGNAL_TO_GLOBAL_BUFFER(clki),
30 | // | .GLOBAL_BUFFER_OUTPUT(clko)
31 | // | );
32 | // | endmodule
33 | // |""".stripMargin
34 | // )
35 | // }
36 |
--------------------------------------------------------------------------------
/pdf/Chisel3-CheatSheet.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/carlosedp/chisel-playground/11ce6dd4c252696f28a7823e2253e92ce309ec06/pdf/Chisel3-CheatSheet.pdf
--------------------------------------------------------------------------------
/pdf/Chisel3-Documentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/carlosedp/chisel-playground/11ce6dd4c252696f28a7823e2253e92ce309ec06/pdf/Chisel3-Documentation.pdf
--------------------------------------------------------------------------------
/pdf/Digital Design with Chisel - Martin Schoeberl.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/carlosedp/chisel-playground/11ce6dd4c252696f28a7823e2253e92ce309ec06/pdf/Digital Design with Chisel - Martin Schoeberl.pdf
--------------------------------------------------------------------------------
/pdf/UCB-Chisel-Tutorial.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/carlosedp/chisel-playground/11ce6dd4c252696f28a7823e2253e92ce309ec06/pdf/UCB-Chisel-Tutorial.pdf
--------------------------------------------------------------------------------