├── simulation ├── src │ └── verilog │ │ └── .gitkeep ├── .gitignore └── Makefile ├── common ├── project │ ├── build.properties │ └── build.scala ├── src │ └── main │ │ └── scala │ │ ├── Generator.scala │ │ ├── Top.scala │ │ ├── TestHarness.scala │ │ ├── Configs.scala │ │ ├── ZynqAdapter.scala │ │ ├── Serdes.scala │ │ └── Drivers.scala ├── scripts │ ├── upgrade_version.tcl │ └── upgrade_version.sh ├── make_bitstream.tcl ├── generate-pkg-mk.sh ├── load_card.sh ├── csrc │ ├── zynq_driver.h │ ├── fesvr_zynq.cc │ └── zynq_driver.cc ├── zynq_rocketchip.tcl ├── Makefrag └── rocketchip_wrapper.v ├── zybo ├── Makefile ├── src │ ├── constrs │ │ └── base.xdc │ ├── verilog │ │ └── clocking.vh │ └── xml │ │ └── ZYBO_zynq_def.xml └── soft_config │ ├── zynq_zybo.h │ └── zybo_devicetree.dts ├── zc706 ├── Makefile ├── src │ ├── constrs │ │ └── base.xdc │ └── verilog │ │ └── clocking.vh └── soft_config │ ├── zynq_zc70x.h │ └── zc706_devicetree.dts ├── zedboard ├── Makefile ├── src │ ├── constrs │ │ └── base.xdc │ └── verilog │ │ └── clocking.vh └── soft_config │ ├── skeleton.dtsi │ ├── zynq_zed.h │ ├── zedboard_devicetree.dts │ └── zynq-7000.dtsi ├── .gitmodules ├── .gitignore ├── LICENSE └── README.md /simulation/src/verilog/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /common/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.15 2 | -------------------------------------------------------------------------------- /simulation/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !Makefile 3 | !.gitignore 4 | !src/verilog/.gitkeep 5 | -------------------------------------------------------------------------------- /zybo/Makefile: -------------------------------------------------------------------------------- 1 | BOARD = zybo 2 | UBOOT_CONFIG = $(BOARD) 3 | PART = xc7z010clg400-1 4 | CONFIG = ZynqMediumFPGAConfig 5 | 6 | include ../common/Makefrag 7 | -------------------------------------------------------------------------------- /zc706/Makefile: -------------------------------------------------------------------------------- 1 | BOARD = zc706 2 | UBOOT_CONFIG = zc70x 3 | BOARD_MODEL = xilinx.com:zc706:part0:1.0 4 | PART = xc7z045ffg900-2 5 | CONFIG = ZynqFPGAConfig 6 | 7 | include ../common/Makefrag 8 | -------------------------------------------------------------------------------- /zedboard/Makefile: -------------------------------------------------------------------------------- 1 | BOARD = zedboard 2 | UBOOT_CONFIG = zed 3 | BOARD_MODEL = em.avnet.com:zed:part0:1.0 4 | PART = xc7z020clg484-1 5 | CONFIG = ZynqFPGAConfig 6 | 7 | include ../common/Makefrag 8 | -------------------------------------------------------------------------------- /zedboard/src/constrs/base.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN Y9 [get_ports clk] 2 | set_property IOSTANDARD LVCMOS33 [get_ports clk] 3 | create_clock -name gclk_0 -period "10" -waveform {0.0 5.0} [get_ports clk] 4 | -------------------------------------------------------------------------------- /zybo/src/constrs/base.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN L16 [get_ports clk] 2 | set_property IOSTANDARD LVCMOS33 [get_ports clk] 3 | create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports clk] 4 | -------------------------------------------------------------------------------- /common/src/main/scala/Generator.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | object Generator extends testchipip.GeneratorApp { 4 | override lazy val longName = names.topModuleClass + "." + names.configs 5 | generateFirrtl 6 | } 7 | -------------------------------------------------------------------------------- /common/scripts/upgrade_version.tcl: -------------------------------------------------------------------------------- 1 | open_project [lindex $argv 0] 2 | #update_compile_order -fileset sources_1 3 | export_ip_user_files -of_objects [get_ips -all] -no_script -reset -quiet 4 | upgrade_ip [get_ips -all] -log ip_upgrade.log 5 | validate_bd_design 6 | write_bd_tcl -force [lindex $argv 1] 7 | -------------------------------------------------------------------------------- /common/make_bitstream.tcl: -------------------------------------------------------------------------------- 1 | open_project BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE/BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE.xpr 2 | reset_run synth_1 3 | reset_run impl_1 4 | launch_runs synth_1 5 | wait_on_run synth_1 6 | launch_runs impl_1 -to_step write_bitstream 7 | wait_on_run impl_1 8 | exit 9 | -------------------------------------------------------------------------------- /zedboard/soft_config/skeleton.dtsi: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton device tree; the bare minimum needed to boot; just include and 3 | * add a compatible value. The bootloader will typically populate the memory 4 | * node. 5 | */ 6 | 7 | / { 8 | #address-cells = <1>; 9 | #size-cells = <1>; 10 | chosen { }; 11 | aliases { }; 12 | memory { device_type = "memory"; reg = <0 0>; }; 13 | }; 14 | -------------------------------------------------------------------------------- /zc706/src/constrs/base.xdc: -------------------------------------------------------------------------------- 1 | set_property PACKAGE_PIN H9 [get_ports SYSCLK_P] 2 | set_property IOSTANDARD LVDS [get_ports SYSCLK_P] 3 | set_property PACKAGE_PIN G9 [get_ports SYSCLK_N] 4 | set_property IOSTANDARD LVDS [get_ports SYSCLK_N] 5 | #set_property PACKAGE_PIN H9 [get_ports clk] 6 | #set_property IOSTANDARD LVCMOS33 [get_ports clk] 7 | create_clock -add -name SYSCLK_P -period 5.00 -waveform {0 2.5} [get_ports SYSCLK_P] 8 | -------------------------------------------------------------------------------- /common/project/build.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import Keys._ 3 | 4 | object BuildSettings extends Build { 5 | override lazy val settings = super.settings ++ Seq( 6 | organization := "berkeley", 7 | version := "1.2", 8 | scalaVersion := "2.11.12", 9 | parallelExecution in Global := false, 10 | traceLevel := 15, 11 | scalacOptions ++= Seq("-deprecation","-unchecked") 12 | ) 13 | lazy val zynq = (project in file(".")) 14 | } 15 | -------------------------------------------------------------------------------- /common/scripts/upgrade_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | # Argument 1: old vivado version sourceme 4 | # Argument 2: new vivado version sourceme 5 | 6 | # Run this in the directory of the board you'd like to upgrade 7 | project=$(basename $(pwd)) 8 | source $1 9 | make project 10 | 11 | cp src/tcl/${project}_bd.tcl src/tcl/${project}_bd.tcl.bak 12 | 13 | source $2 14 | vivado -mode batch -source ../common/scripts/upgrade_version.tcl -tclargs */*.xpr src/tcl/${project}_bd.tcl 15 | -------------------------------------------------------------------------------- /common/generate-pkg-mk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | common_dir=$(dirname $0) 4 | base_dir=${common_dir}/.. 5 | 6 | for pkg in $@ 7 | do 8 | pkg_dir="${base_dir}/${pkg}" 9 | cat < 29 | 30 | #endif /* __CONFIG_ZYNQ_ZED_H */ 31 | -------------------------------------------------------------------------------- /zybo/src/verilog/clocking.vh: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Rocket Chip Clock Configuration 4 | 5 | 6 | Rocket Chip 1000 RC_CLK_MULT 7 | Clockrate = --------------- X ------------- 8 | (in MHz) ZYNQ_CLK_PERIOD RC_CLK_DIVIDE 9 | 10 | 11 | This sets the parameters used by rocketchip_wrapper.v to 12 | generate its own clock. 13 | 14 | Most uses should only change RC_CLK_MULT & RC_CLK_DIVIDE. 15 | ZYNQ_CLK_PERIOD should only be changed to match the input 16 | clock period set in the Vivado GUI and 17 | hw/src/constrs/pin_constraints.xdc 18 | 19 | */ 20 | 21 | 22 | `ifndef _clocking_vh_ 23 | `define _clocking_vh_ 24 | 25 | 26 | `define ZYNQ_CLK_PERIOD 8.0 27 | 28 | `define RC_CLK_MULT 8.0 29 | 30 | `define RC_CLK_DIVIDE 20.0 31 | 32 | 33 | `endif // _clocking_vh_ 34 | -------------------------------------------------------------------------------- /zedboard/src/verilog/clocking.vh: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Rocket Chip Clock Configuration 4 | 5 | 6 | Rocket Chip 1000 RC_CLK_MULT 7 | Clockrate = --------------- X ------------- 8 | (in MHz) ZYNQ_CLK_PERIOD RC_CLK_DIVIDE 9 | 10 | 11 | This sets the parameters used by rocketchip_wrapper.v to 12 | generate its own clock. 13 | 14 | Most uses should only change RC_CLK_MULT & RC_CLK_DIVIDE. 15 | ZYNQ_CLK_PERIOD should only be changed to match the input 16 | clock period set in the Vivado GUI and 17 | hw/src/constrs/pin_constraints.xdc 18 | 19 | */ 20 | 21 | 22 | `ifndef _clocking_vh_ 23 | `define _clocking_vh_ 24 | 25 | 26 | `define ZYNQ_CLK_PERIOD 10.0 27 | 28 | `define RC_CLK_MULT 10.0 29 | 30 | `define RC_CLK_DIVIDE 40.0 31 | 32 | 33 | `endif // _clocking_vh_ 34 | -------------------------------------------------------------------------------- /zc706/src/verilog/clocking.vh: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Rocket Chip Clock Configuration 4 | 5 | 6 | Rocket Chip 1000 RC_CLK_MULT 7 | Clockrate = --------------- X ------------- 8 | (in MHz) ZYNQ_CLK_PERIOD RC_CLK_DIVIDE 9 | 10 | 11 | This sets the parameters used by rocketchip_wrapper.v to 12 | generate its own clock. 13 | 14 | Most uses should only change RC_CLK_MULT & RC_CLK_DIVIDE. 15 | ZYNQ_CLK_PERIOD should only be changed to match the input 16 | clock period set in the Vivado GUI and 17 | hw/src/constrs/pin_constraints.xdc 18 | 19 | */ 20 | 21 | 22 | `ifndef _clocking_vh_ 23 | `define _clocking_vh_ 24 | 25 | 26 | `define ZYNQ_CLK_PERIOD 5.0 27 | 28 | `define RC_CLK_MULT 4.0 29 | 30 | `define RC_CLK_DIVIDE 16.0 31 | 32 | `define differential_clock 33 | 34 | `endif // _clocking_vh_ 35 | -------------------------------------------------------------------------------- /common/csrc/zynq_driver.h: -------------------------------------------------------------------------------- 1 | #ifndef __ZYNQ_DRIVER_H 2 | #define __ZYNQ_DRIVER_H 3 | 4 | #include "fesvr/tsi.h" 5 | #include "blkdev.h" 6 | #include 7 | 8 | class zynq_driver_t { 9 | public: 10 | zynq_driver_t(tsi_t *tsi, BlockDevice *bdev); 11 | ~zynq_driver_t(); 12 | 13 | void poll(void); 14 | 15 | private: 16 | uint8_t *dev; 17 | int fd; 18 | tsi_t *tsi; 19 | BlockDevice *bdev; 20 | 21 | protected: 22 | uint32_t read(int off); 23 | void write(int off, uint32_t word); 24 | struct blkdev_request read_blkdev_request(); 25 | struct blkdev_data read_blkdev_req_data(); 26 | void write_blkdev_response(struct blkdev_data &resp); 27 | struct network_flit read_net_out(); 28 | void write_net_in(struct network_flit &flt); 29 | void write_macaddr(uint64_t macaddr); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "zedboard/fpga-images-zedboard"] 2 | path = zedboard/fpga-images-zedboard 3 | url = https://github.com/ucb-bar/fpga-images-zedboard.git 4 | [submodule "zybo/fpga-images-zybo"] 5 | path = zybo/fpga-images-zybo 6 | url = https://github.com/ucb-bar/fpga-images-zybo.git 7 | [submodule "common/u-boot-xlnx"] 8 | path = common/u-boot-xlnx 9 | url = https://github.com/Xilinx/u-boot-xlnx.git 10 | branch = master-next 11 | [submodule "common/linux-xlnx"] 12 | path = common/linux-xlnx 13 | url = https://github.com/Xilinx/linux-xlnx.git 14 | branch = master-next 15 | [submodule "zc706/fpga-images-zc706"] 16 | path = zc706/fpga-images-zc706 17 | url = https://github.com/ucb-bar/fpga-images-zc706.git 18 | [submodule "rocket-chip"] 19 | path = rocket-chip 20 | url = https://github.com/ucb-bar/rocket-chip.git 21 | [submodule "testchipip"] 22 | path = testchipip 23 | url = https://github.com/ucb-bar/testchipip.git 24 | -------------------------------------------------------------------------------- /zc706/soft_config/zynq_zc70x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Xilinx, Inc. 3 | * Modified by Sagar Karandikar for RISC-V Rocket Support 4 | * 5 | * u-boot Configuration settings for the Xilinx Zynq ZC702 and ZC706 boards 6 | * See zynq-common.h for Zynq common configs 7 | * 8 | * Adapted for RISC-V Rocket Support 9 | * 10 | * SPDX-License-Identifier: GPL-2.0+ 11 | */ 12 | 13 | #ifndef __CONFIG_ZYNQ_ZC70X_H 14 | #define __CONFIG_ZYNQ_ZC70X_H 15 | 16 | #define CONFIG_SYS_SDRAM_SIZE (256 * 1024 * 1024) 17 | 18 | #define CONFIG_ZYNQ_SERIAL_UART1 19 | #define CONFIG_ZYNQ_GEM0 20 | #define CONFIG_ZYNQ_GEM_PHY_ADDR0 7 21 | 22 | #define CONFIG_SYS_NO_FLASH 23 | 24 | #define CONFIG_ZYNQ_SDHCI0 25 | #define CONFIG_ZYNQ_USB 26 | #define CONFIG_ZYNQ_QSPI 27 | #define CONFIG_ZYNQ_I2C0 28 | #define CONFIG_ZYNQ_EEPROM 29 | #define CONFIG_ZYNQ_BOOT_FREEBSD 30 | #define CONFIG_DEFAULT_DEVICE_TREE zynq-zc702 31 | 32 | #include 33 | 34 | #endif /* __CONFIG_ZYNQ_ZC70X_H */ 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.jou 3 | *.Xil 4 | *.swp 5 | 6 | common/build 7 | common/target 8 | common/project/target 9 | common/lib 10 | common/Makefrag.pkgs 11 | 12 | zedboard/zedboard_rocketchip_* 13 | zedboard/src/tcl/zedboard_rocketchip_*.tcl 14 | zedboard/src/tcl/make_bitstream_*.tcl 15 | zedboard/src/verilog/rocketchip_wrapper.v 16 | zedboard/src/verilog/Top.*.v 17 | zedboard/src/verilog/AsyncResetReg.v 18 | zedboard/src/verilog/plusarg_reader.v 19 | zedboard/deliver_output 20 | zedboard/soft_build 21 | 22 | zybo/zybo_rocketchip_* 23 | zybo/src/tcl/zybo_rocketchip_*.tcl 24 | zybo/src/tcl/make_bitstream_*.tcl 25 | zybo/src/verilog/rocketchip_wrapper.v 26 | zybo/src/verilog/Top.*.v 27 | zybo/src/verilog/AsyncResetReg.v 28 | zybo/src/verilog/plusarg_reader.v 29 | zybo/deliver_output 30 | zybo/soft_build 31 | 32 | zc706/zc706_rocketchip_* 33 | zc706/src/tcl/zc706_rocketchip_*.tcl 34 | zc706/src/tcl/make_bitstream_*.tcl 35 | zc706/src/verilog/rocketchip_wrapper.v 36 | zc706/src/verilog/Top.*.v 37 | zc706/src/verilog/AsyncResetReg.v 38 | zc706/src/verilog/plusarg_reader.v 39 | zc706/deliver_output 40 | zc706/soft_build 41 | -------------------------------------------------------------------------------- /common/csrc/fesvr_zynq.cc: -------------------------------------------------------------------------------- 1 | #include "zynq_driver.h" 2 | #include "fesvr/tsi.h" 3 | #include 4 | 5 | #define BLKDEV_NTAGS 2 6 | 7 | static inline int copy_argv(int argc, char **argv, char **new_argv) 8 | { 9 | int optind = 1; 10 | int new_argc = argc; 11 | 12 | new_argv[0] = argv[0]; 13 | 14 | for (int i = 1; i < argc; i++) { 15 | if (argv[i][0] != '+') { 16 | optind = i - 1; 17 | new_argc = argc - i + 1; 18 | break; 19 | } 20 | } 21 | 22 | for (int i = 1; i < new_argc; i++) 23 | new_argv[i] = argv[i + optind]; 24 | 25 | return new_argc; 26 | } 27 | 28 | int main(int argc, char** argv) 29 | { 30 | char **new_argv = (char **) malloc(sizeof(char *) * argc); 31 | int new_argc = copy_argv(argc, argv, new_argv); 32 | tsi_t tsi(new_argc, new_argv); 33 | 34 | BlockDevice *blkdev = NULL; 35 | zynq_driver_t *driver; 36 | 37 | for (int i = 1; i < argc; i++) { 38 | const char *name = NULL; 39 | 40 | if (strncmp(argv[i], "+blkdev=", 8) == 0) { 41 | name = argv[i] + 8; 42 | blkdev = new BlockDevice(name, BLKDEV_NTAGS); 43 | } 44 | } 45 | 46 | driver = new zynq_driver_t(&tsi, blkdev); 47 | 48 | while(!tsi.done()){ 49 | driver->poll(); 50 | } 51 | 52 | delete driver; 53 | if (blkdev != NULL) 54 | delete blkdev; 55 | 56 | return tsi.exit_code(); 57 | } 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, The Regents of the University of California (Regents). 2 | All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the Regents nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 16 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 17 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 18 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 | 20 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 23 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 24 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | -------------------------------------------------------------------------------- /simulation/Makefile: -------------------------------------------------------------------------------- 1 | TOP_MODULE ?= TestHarness 2 | CONFIG ?= ZynqConfig 3 | TB ?= TestDriver 4 | 5 | simv = simv-$(CONFIG) 6 | simv_debug = simv-$(CONFIG)-debug 7 | 8 | default: $(simv) 9 | debug: $(simv_debug) 10 | 11 | include ../common/Makefrag 12 | 13 | sim_vsrcs = \ 14 | src/verilog/$(TOP_MODULE).$(CONFIG).v \ 15 | $(base_dir)/rocket-chip/vsrc/TestDriver.v \ 16 | $(base_dir)/rocket-chip/vsrc/AsyncResetReg.v \ 17 | $(base_dir)/rocket-chip/vsrc/plusarg_reader.v \ 18 | $(base_dir)/testchipip/vsrc/SimSerial.v \ 19 | $(base_dir)/testchipip/vsrc/SimBlockDevice.v \ 20 | 21 | sim_csrcs = \ 22 | $(base_dir)/testchipip/csrc/SimSerial.cc \ 23 | $(base_dir)/testchipip/csrc/SimBlockDevice.cc \ 24 | $(base_dir)/testchipip/csrc/blkdev.cc \ 25 | 26 | VCS = vcs -full64 27 | 28 | VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -error=PCWM-L -timescale=1ns/10ps -quiet \ 29 | +rad +v2k +vcs+lic+wait \ 30 | +vc+list -CC "-I$(VCS_HOME)/include" \ 31 | -CC "-I$(RISCV)/include -I$(base_dir)/testchipip/csrc" \ 32 | -CC "-std=c++11" \ 33 | -CC "-Wl,-rpath,$(RISCV)/lib" \ 34 | $(RISCV)/lib/libfesvr.so \ 35 | -sverilog \ 36 | +incdir+$(generated_dir) \ 37 | +define+CLOCK_PERIOD=1.0 $(sim_vsrcs) $(sim_csrcs) \ 38 | +define+PRINTF_COND=$(TB).printf_cond \ 39 | +define+STOP_COND=!$(TB).reset \ 40 | +define+RANDOMIZE_MEM_INIT \ 41 | +define+RANDOMIZE_REG_INIT \ 42 | +define+RANDOMIZE_GARBAGE_ASSIGN \ 43 | +define+RANDOMIZE_INVALID_ASSIGN \ 44 | +libext+.v \ 45 | 46 | verilog: $(sim_vsrcs) 47 | 48 | $(simv): $(sim_vsrcs) $(sim_csrcs) 49 | rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \ 50 | -debug_pp 51 | 52 | $(simv_debug) : $(sim_vsrcs) $(sim_csrcs) 53 | rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \ 54 | +define+DEBUG -debug_pp 55 | -------------------------------------------------------------------------------- /common/src/main/scala/Top.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | import chisel3._ 4 | import freechips.rocketchip.config.{Parameters, Field} 5 | import freechips.rocketchip.devices.tilelink._ 6 | import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 7 | import freechips.rocketchip.subsystem._ 8 | import freechips.rocketchip.util.DontTouch 9 | import testchipip._ 10 | 11 | case object ZynqAdapterBase extends Field[BigInt] 12 | 13 | class Top(implicit val p: Parameters) extends Module { 14 | val address = p(ZynqAdapterBase) 15 | val config = p(ExtIn) 16 | val target = Module(LazyModule(new FPGAZynqTop).module) 17 | val adapter = Module(LazyModule(new ZynqAdapter(address, config)).module) 18 | 19 | require(target.mem_axi4.size == 1) 20 | 21 | val io = IO(new Bundle { 22 | val ps_axi_slave = Flipped(adapter.axi.cloneType) 23 | val mem_axi = target.mem_axi4.head.cloneType 24 | }) 25 | 26 | io.mem_axi <> target.mem_axi4.head 27 | adapter.axi <> io.ps_axi_slave 28 | adapter.io.serial <> target.serial 29 | adapter.io.bdev <> target.bdev 30 | 31 | target.debug := DontCare 32 | target.tieOffInterrupts() 33 | target.dontTouchPorts() 34 | target.reset := adapter.io.sys_reset 35 | } 36 | 37 | class FPGAZynqTop(implicit p: Parameters) extends RocketSubsystem 38 | with HasMasterAXI4MemPort 39 | with HasSystemErrorSlave 40 | with HasPeripheryBootROM 41 | with HasSyncExtInterrupts 42 | with HasNoDebug 43 | with HasPeripherySerial 44 | with HasPeripheryBlockDevice { 45 | override lazy val module = new FPGAZynqTopModule(this) 46 | } 47 | 48 | class FPGAZynqTopModule(outer: FPGAZynqTop) extends RocketSubsystemModuleImp(outer) 49 | with HasRTCModuleImp 50 | with HasMasterAXI4MemPortModuleImp 51 | with HasPeripheryBootROMModuleImp 52 | with HasExtInterruptsModuleImp 53 | with HasNoDebugModuleImp 54 | with HasPeripherySerialModuleImp 55 | with HasPeripheryBlockDeviceModuleImp 56 | with DontTouch 57 | -------------------------------------------------------------------------------- /common/src/main/scala/TestHarness.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | import chisel3._ 4 | import chisel3.util.Queue 5 | import freechips.rocketchip.amba.axi4._ 6 | import freechips.rocketchip.subsystem.ExtIn 7 | import freechips.rocketchip.config.Parameters 8 | import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 9 | import freechips.rocketchip.tilelink._ 10 | import testchipip._ 11 | import testchipip.SerialAdapter._ 12 | 13 | class TestHarness(implicit val p: Parameters) extends Module { 14 | val io = IO(new Bundle { 15 | val success = Output(Bool()) 16 | }) 17 | 18 | val config = p(ExtIn) 19 | val driver = Module(LazyModule(new TestHarnessDriver).module) 20 | val dut = Module(LazyModule(new FPGAZynqTop).module) 21 | 22 | dut.reset := driver.io.sys_reset 23 | dut.debug := DontCare 24 | dut.tieOffInterrupts() 25 | dut.dontTouchPorts() 26 | dut.connectSimAXIMem() 27 | 28 | driver.io.serial <> dut.serial 29 | driver.io.bdev <> dut.bdev 30 | io.success := driver.io.success 31 | } 32 | 33 | class TestHarnessDriver(implicit p: Parameters) extends LazyModule { 34 | val xbar = LazyModule(new TLXbar) 35 | val config = p(ExtIn) 36 | val base = p(ZynqAdapterBase) 37 | 38 | val zynq = LazyModule(new ZynqAdapterCore(base, config.beatBytes)) 39 | val converter = LazyModule(new TLToAXI4) 40 | 41 | val serDriver = LazyModule(new SerialDriver) 42 | val resetDriver = LazyModule(new ResetDriver) 43 | val blkdevDriver = LazyModule(new BlockDeviceDriver) 44 | 45 | xbar.node := serDriver.node 46 | xbar.node := resetDriver.node 47 | xbar.node := blkdevDriver.node 48 | converter.node := xbar.node 49 | zynq.node := converter.node 50 | 51 | lazy val module = new LazyModuleImp(this) { 52 | val io = IO(new Bundle { 53 | val serial = Flipped(new SerialIO(SERIAL_IF_WIDTH)) 54 | val bdev = Flipped(new BlockDeviceIO) 55 | val sys_reset = Output(Bool()) 56 | val success = Output(Bool()) 57 | }) 58 | 59 | val simSerial = Module(new SimSerial(SERIAL_IF_WIDTH)) 60 | val simBlockDev = Module(new SimBlockDevice) 61 | simSerial.io.clock := clock 62 | simSerial.io.reset := reset 63 | simBlockDev.io.clock := clock 64 | simBlockDev.io.reset := reset 65 | serDriver.module.reset := zynq.module.io.sys_reset 66 | blkdevDriver.module.reset := zynq.module.io.sys_reset 67 | 68 | zynq.module.io.serial <> io.serial 69 | simSerial.io.serial <> serDriver.module.io.serial 70 | zynq.module.io.bdev <> io.bdev 71 | simBlockDev.io.bdev <> blkdevDriver.module.io.bdev 72 | 73 | io.sys_reset := zynq.module.io.sys_reset 74 | io.success := simSerial.io.exit 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /zedboard/soft_config/zedboard_devicetree.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 - 2014 Xilinx 3 | * Copyright (C) 2012 National Instruments Corp. 4 | * 5 | * This software is licensed under the terms of the GNU General Public 6 | * License version 2, as published by the Free Software Foundation, and 7 | * may be copied, distributed, and modified under those terms. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | */ 14 | /dts-v1/; 15 | /include/ "zynq-7000.dtsi" 16 | 17 | / { 18 | model = "Zynq Zed Development Board"; 19 | compatible = "xlnx,zynq-zed", "xlnx,zynq-7000"; 20 | 21 | aliases { 22 | ethernet0 = &gem0; 23 | serial0 = &uart1; 24 | spi0 = &qspi; 25 | }; 26 | 27 | memory { 28 | device_type = "memory"; 29 | reg = <0x0 0x10000000>; 30 | }; 31 | 32 | htif_0: htif@43c00000 { 33 | #address-cells = <1>; 34 | #size-cells = <1>; 35 | compatible = "generic-uio", "uio", "uio_pdrv"; 36 | reg = <0x43c00000 0x1000>; 37 | }; 38 | 39 | chosen { 40 | bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk"; 41 | linux,stdout-path = "/amba/serial@e0001000"; 42 | }; 43 | }; 44 | 45 | &qspi { 46 | status = "okay"; 47 | is-dual = <0>; 48 | num-cs = <1>; 49 | xlnx,fb-clk = <0x1>; 50 | xlnx,qspi-mode = <0x0>; 51 | flash@0 { 52 | compatible = "n25q128"; 53 | reg = <0x0>; 54 | spi-tx-bus-width = <1>; 55 | spi-rx-bus-width = <4>; 56 | spi-max-frequency = <50000000>; 57 | #address-cells = <1>; 58 | #size-cells = <1>; 59 | partition@qspi-fsbl-uboot { 60 | label = "qspi-fsbl-uboot"; 61 | reg = <0x0 0x100000>; 62 | }; 63 | partition@qspi-linux { 64 | label = "qspi-linux"; 65 | reg = <0x100000 0x500000>; 66 | }; 67 | partition@qspi-device-tree { 68 | label = "qspi-device-tree"; 69 | reg = <0x600000 0x20000>; 70 | }; 71 | partition@qspi-rootfs { 72 | label = "qspi-rootfs"; 73 | reg = <0x620000 0x5E0000>; 74 | }; 75 | partition@qspi-bitstream { 76 | label = "qspi-bitstream"; 77 | reg = <0xC00000 0x400000>; 78 | }; 79 | }; 80 | }; 81 | 82 | &usb0 { 83 | status = "okay"; 84 | dr_mode = "host"; 85 | phy_type = "ulpi"; 86 | }; 87 | 88 | &gem0 { 89 | status = "okay"; 90 | phy-mode = "rgmii-id"; 91 | 92 | phy0: phy@0 { 93 | reg = <0>; 94 | }; 95 | }; 96 | 97 | &sdhci0 { 98 | status = "okay"; 99 | }; 100 | 101 | &uart1 { 102 | status = "okay"; 103 | }; 104 | -------------------------------------------------------------------------------- /common/src/main/scala/Configs.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | import chisel3._ 4 | import freechips.rocketchip.config.{Parameters, Config} 5 | import freechips.rocketchip.subsystem._ 6 | import freechips.rocketchip.devices.tilelink.BootROMParams 7 | import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams} 8 | import freechips.rocketchip.tile.{RocketTileParams, BuildCore, XLen} 9 | import testchipip._ 10 | 11 | class WithBootROM extends Config((site, here, up) => { 12 | case BootROMParams => BootROMParams( 13 | contentFileName = s"../testchipip/bootrom/bootrom.rv${site(XLen)}.img") 14 | }) 15 | 16 | class WithZynqAdapter extends Config((site, here, up) => { 17 | case SerialFIFODepth => 16 18 | case ResetCycles => 10 19 | case ZynqAdapterBase => BigInt(0x43C00000L) 20 | case ExtMem => up(ExtMem, site).copy(idBits = 6) 21 | case ExtIn => up(ExtIn, site).copy(beatBytes = 4, idBits = 12) 22 | case BlockDeviceKey => BlockDeviceConfig(nTrackers = 2) 23 | case BlockDeviceFIFODepth => 16 24 | case NetworkFIFODepth => 16 25 | }) 26 | 27 | class WithNMediumCores(n: Int) extends Config((site, here, up) => { 28 | case RocketTilesKey => { 29 | val medium = RocketTileParams( 30 | core = RocketCoreParams(fpu = None), 31 | btb = None, 32 | dcache = Some(DCacheParams( 33 | rowBits = site(SystemBusKey).beatBytes*8, 34 | nSets = 64, 35 | nWays = 1, 36 | nTLBEntries = 4, 37 | nMSHRs = 0, 38 | blockBytes = site(CacheBlockBytes))), 39 | icache = Some(ICacheParams( 40 | rowBits = site(SystemBusKey).beatBytes*8, 41 | nSets = 64, 42 | nWays = 1, 43 | nTLBEntries = 4, 44 | blockBytes = site(CacheBlockBytes)))) 45 | List.tabulate(n)(i => medium.copy(hartId = i)) 46 | } 47 | }) 48 | 49 | class DefaultConfig extends Config( 50 | new WithBootROM ++ new freechips.rocketchip.system.DefaultConfig) 51 | class DefaultMediumConfig extends Config( 52 | new WithBootROM ++ new WithNMediumCores(1) ++ 53 | new freechips.rocketchip.system.BaseConfig) 54 | class DefaultSmallConfig extends Config( 55 | new WithBootROM ++ new freechips.rocketchip.system.DefaultSmallConfig) 56 | 57 | class ZynqConfig extends Config(new WithZynqAdapter ++ new DefaultConfig) 58 | class ZynqMediumConfig extends Config(new WithZynqAdapter ++ new DefaultMediumConfig) 59 | class ZynqSmallConfig extends Config(new WithZynqAdapter ++ new DefaultSmallConfig) 60 | 61 | class ZynqFPGAConfig extends Config(new WithoutTLMonitors ++ new ZynqConfig) 62 | class ZynqMediumFPGAConfig extends Config(new WithoutTLMonitors ++ new ZynqMediumConfig) 63 | class ZynqSmallFPGAConfig extends Config(new WithoutTLMonitors ++ new ZynqSmallConfig) 64 | -------------------------------------------------------------------------------- /common/csrc/zynq_driver.cc: -------------------------------------------------------------------------------- 1 | #include "zynq_driver.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define ZYNQ_BASE_PADDR 0x43C00000L 9 | 10 | #define TSI_OUT_FIFO_DATA 0x00 11 | #define TSI_OUT_FIFO_COUNT 0x04 12 | #define TSI_IN_FIFO_DATA 0x08 13 | #define TSI_IN_FIFO_COUNT 0x0C 14 | #define SYSTEM_RESET 0x10 15 | #define BLKDEV_REQ_FIFO_DATA 0x20 16 | #define BLKDEV_REQ_FIFO_COUNT 0x24 17 | #define BLKDEV_DATA_FIFO_DATA 0x28 18 | #define BLKDEV_DATA_FIFO_COUNT 0x2C 19 | #define BLKDEV_RESP_FIFO_DATA 0x30 20 | #define BLKDEV_RESP_FIFO_COUNT 0x34 21 | #define BLKDEV_NSECTORS 0x38 22 | #define BLKDEV_MAX_REQUEST_LENGTH 0x3C 23 | #define NET_OUT_FIFO_DATA 0x40 24 | #define NET_OUT_FIFO_COUNT 0x44 25 | #define NET_IN_FIFO_DATA 0x48 26 | #define NET_IN_FIFO_COUNT 0x4C 27 | #define NET_MACADDR_LO 0x50 28 | #define NET_MACADDR_HI 0x54 29 | 30 | #define BLKDEV_REQ_NWORDS 3 31 | #define BLKDEV_DATA_NWORDS 3 32 | #define NET_FLIT_NWORDS 3 33 | 34 | zynq_driver_t::zynq_driver_t(tsi_t *tsi, BlockDevice *bdev) 35 | { 36 | this->tsi = tsi; 37 | this->bdev = bdev; 38 | 39 | fd = open("/dev/mem", O_RDWR|O_SYNC); 40 | assert(fd != -1); 41 | dev = (uint8_t *) mmap( 42 | 0, sysconf(_SC_PAGESIZE), 43 | PROT_READ|PROT_WRITE, MAP_SHARED, fd, ZYNQ_BASE_PADDR); 44 | assert(dev != MAP_FAILED); 45 | 46 | // reset the target 47 | write(SYSTEM_RESET, 1); 48 | write(SYSTEM_RESET, 0); 49 | 50 | // set nsectors and max_request_length 51 | if (bdev == NULL) { 52 | write(BLKDEV_NSECTORS, 0); 53 | write(BLKDEV_MAX_REQUEST_LENGTH, 0); 54 | } else { 55 | write(BLKDEV_NSECTORS, bdev->nsectors()); 56 | write(BLKDEV_MAX_REQUEST_LENGTH, bdev->max_request_length()); 57 | } 58 | } 59 | 60 | zynq_driver_t::~zynq_driver_t() 61 | { 62 | munmap(dev, sysconf(_SC_PAGESIZE)); 63 | close(fd); 64 | } 65 | 66 | uint32_t zynq_driver_t::read(int off) 67 | { 68 | volatile uint32_t *ptr = (volatile uint32_t *) (this->dev + off); 69 | return *ptr; 70 | } 71 | 72 | void zynq_driver_t::write(int off, uint32_t word) 73 | { 74 | volatile uint32_t *ptr = (volatile uint32_t *) (this->dev + off); 75 | *ptr = word; 76 | } 77 | 78 | struct blkdev_request zynq_driver_t::read_blkdev_request() 79 | { 80 | uint32_t word; 81 | struct blkdev_request req; 82 | 83 | // tag + write 84 | word = read(BLKDEV_REQ_FIFO_DATA); 85 | req.write = word & 0x1; 86 | req.tag = word >> 1; 87 | // offset, then len 88 | req.offset = read(BLKDEV_REQ_FIFO_DATA); 89 | req.len = read(BLKDEV_REQ_FIFO_DATA); 90 | 91 | return req; 92 | } 93 | 94 | struct blkdev_data zynq_driver_t::read_blkdev_req_data() 95 | { 96 | struct blkdev_data data; 97 | 98 | data.tag = read(BLKDEV_DATA_FIFO_DATA); 99 | data.data = read(BLKDEV_DATA_FIFO_DATA) & 0xffffffffU; 100 | data.data |= ((uint64_t) read(BLKDEV_DATA_FIFO_DATA)) << 32; 101 | 102 | return data; 103 | } 104 | 105 | void zynq_driver_t::write_blkdev_response(struct blkdev_data &resp) 106 | { 107 | write(BLKDEV_RESP_FIFO_DATA, resp.tag); 108 | write(BLKDEV_RESP_FIFO_DATA, resp.data & 0xffffffffU); 109 | write(BLKDEV_RESP_FIFO_DATA, resp.data >> 32); 110 | } 111 | 112 | void zynq_driver_t::poll(void) 113 | { 114 | if (tsi != NULL) { 115 | while (read(TSI_OUT_FIFO_COUNT) > 0) { 116 | uint32_t out_data = read(TSI_OUT_FIFO_DATA); 117 | tsi->send_word(out_data); 118 | } 119 | 120 | while (tsi->data_available() && read(TSI_IN_FIFO_COUNT) > 0) { 121 | uint32_t in_data = tsi->recv_word(); 122 | write(TSI_IN_FIFO_DATA, in_data); 123 | } 124 | 125 | tsi->switch_to_host(); 126 | } 127 | 128 | if (bdev != NULL) { 129 | while (read(BLKDEV_REQ_FIFO_COUNT) >= BLKDEV_REQ_NWORDS) { 130 | struct blkdev_request req = read_blkdev_request(); 131 | bdev->send_request(req); 132 | } 133 | 134 | while (read(BLKDEV_DATA_FIFO_COUNT) >= BLKDEV_DATA_NWORDS) { 135 | struct blkdev_data data = read_blkdev_req_data(); 136 | bdev->send_data(data); 137 | } 138 | 139 | while (bdev->resp_valid() && read(BLKDEV_RESP_FIFO_COUNT) >= BLKDEV_DATA_NWORDS) { 140 | struct blkdev_data resp = bdev->recv_response(); 141 | write_blkdev_response(resp); 142 | } 143 | 144 | bdev->switch_to_host(); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /common/src/main/scala/ZynqAdapter.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import freechips.rocketchip.amba.axi4._ 6 | import freechips.rocketchip.config.{Parameters, Field} 7 | import freechips.rocketchip.subsystem.SlavePortParams 8 | import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, IdRange} 9 | import freechips.rocketchip.regmapper.{RegField, HasRegMap} 10 | import testchipip._ 11 | import testchipip.SerialAdapter._ 12 | 13 | case object SerialFIFODepth extends Field[Int] 14 | case object BlockDeviceFIFODepth extends Field[Int] 15 | case object NetworkFIFODepth extends Field[Int] 16 | case object ResetCycles extends Field[Int] 17 | 18 | trait ZynqAdapterCoreBundle extends Bundle { 19 | implicit val p: Parameters 20 | 21 | val sys_reset = Output(Bool()) 22 | val serial = Flipped(new SerialIO(SERIAL_IF_WIDTH)) 23 | val bdev = Flipped(new BlockDeviceIO) 24 | } 25 | 26 | trait ZynqAdapterCoreModule extends HasRegMap 27 | with HasBlockDeviceParameters { 28 | implicit val p: Parameters 29 | val io: ZynqAdapterCoreBundle 30 | val w = SERIAL_IF_WIDTH 31 | 32 | val serDepth = p(SerialFIFODepth) 33 | val bdevDepth = p(BlockDeviceFIFODepth) 34 | val serCountBits = log2Ceil(serDepth + 1) 35 | val bdevCountBits = log2Ceil(bdevDepth + 1) 36 | 37 | val ser_out_fifo = Module(new Queue(UInt(w.W), serDepth)) 38 | val ser_in_fifo = Module(new Queue(UInt(w.W), serDepth)) 39 | 40 | ser_out_fifo.io.enq <> io.serial.out 41 | io.serial.in <> ser_in_fifo.io.deq 42 | 43 | val sys_reset = RegInit(true.B) 44 | io.sys_reset := sys_reset 45 | 46 | val bdev_req_fifo = Module(new Queue(UInt(w.W), bdevDepth)) 47 | val bdev_data_fifo = Module(new Queue(UInt(w.W), bdevDepth)) 48 | val bdev_resp_fifo = Module(new Queue(UInt(w.W), bdevDepth)) 49 | val bdev_info = Reg(new BlockDeviceInfo) 50 | val bdev_serdes = Module(new BlockDeviceSerdes(w)) 51 | 52 | bdev_serdes.io.bdev <> io.bdev 53 | bdev_req_fifo.io.enq <> bdev_serdes.io.ser.req 54 | bdev_data_fifo.io.enq <> bdev_serdes.io.ser.data 55 | bdev_serdes.io.ser.resp <> bdev_resp_fifo.io.deq 56 | io.bdev.info := bdev_info 57 | 58 | val ser_in_space = (serDepth.U - ser_in_fifo.io.count) 59 | val bdev_resp_space = (bdevDepth.U - bdev_resp_fifo.io.count) 60 | 61 | /** 62 | * Address Map 63 | * 0x00 - serial out FIFO data 64 | * 0x04 - serial out FIFO data available (words) 65 | * 0x08 - serial in FIFO data 66 | * 0x0C - serial in FIFO space available (words) 67 | * 0x10 - system reset 68 | * 0x20 - req FIFO data 69 | * 0x24 - req FIFO data available (words) 70 | * 0x28 - data FIFO data 71 | * 0x2C - data FIFO data available (words) 72 | * 0x30 - resp FIFO data 73 | * 0x34 - resp FIFO space available (words) 74 | * 0x38 - nsectors 75 | * 0x3C - max request length 76 | */ 77 | regmap( 78 | 0x00 -> Seq(RegField.r(w, ser_out_fifo.io.deq)), 79 | 0x04 -> Seq(RegField.r(serCountBits, ser_out_fifo.io.count)), 80 | 0x08 -> Seq(RegField.w(w, ser_in_fifo.io.enq)), 81 | 0x0C -> Seq(RegField.r(serCountBits, ser_in_space)), 82 | 0x10 -> Seq(RegField(1, sys_reset)), 83 | 0x20 -> Seq(RegField.r(w, bdev_req_fifo.io.deq)), 84 | 0x24 -> Seq(RegField.r(bdevCountBits, bdev_req_fifo.io.count)), 85 | 0x28 -> Seq(RegField.r(w, bdev_data_fifo.io.deq)), 86 | 0x2C -> Seq(RegField.r(bdevCountBits, bdev_data_fifo.io.count)), 87 | 0x30 -> Seq(RegField.w(w, bdev_resp_fifo.io.enq)), 88 | 0x34 -> Seq(RegField.r(bdevCountBits, bdev_resp_space)), 89 | 0x38 -> Seq(RegField(sectorBits, bdev_info.nsectors)), 90 | 0x3C -> Seq(RegField(sectorBits, bdev_info.max_req_len))) 91 | } 92 | 93 | class ZynqAdapterCore(address: BigInt, beatBytes: Int)(implicit p: Parameters) 94 | extends AXI4RegisterRouter( 95 | address, beatBytes = beatBytes, concurrency = 1)( 96 | new AXI4RegBundle((), _) with ZynqAdapterCoreBundle)( 97 | new AXI4RegModule((), _, _) with ZynqAdapterCoreModule) 98 | 99 | class ZynqAdapter(address: BigInt, config: SlavePortParams)(implicit p: Parameters) 100 | extends LazyModule { 101 | 102 | val node = AXI4MasterNode(Seq(AXI4MasterPortParameters( 103 | masters = Seq(AXI4MasterParameters( 104 | name = "Zynq Adapter", 105 | id = IdRange(0, 1 << config.idBits)))))) 106 | 107 | val core = LazyModule(new ZynqAdapterCore(address, config.beatBytes)) 108 | core.node := AXI4Fragmenter() := node 109 | 110 | lazy val module = new LazyModuleImp(this) { 111 | val io = IO(new Bundle { 112 | val sys_reset = Output(Bool()) 113 | val serial = Flipped(new SerialIO(SERIAL_IF_WIDTH)) 114 | val bdev = Flipped(new BlockDeviceIO) 115 | }) 116 | val axi = IO(Flipped(node.out(0)._1.cloneType)) 117 | node.out(0)._1 <> axi 118 | 119 | val coreIO = core.module.io 120 | io.sys_reset := coreIO.sys_reset 121 | coreIO.serial <> io.serial 122 | coreIO.bdev <> io.bdev 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /zybo/soft_config/zynq_zybo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2012 Xilinx 3 | * (C) Copyright 2014 Digilent Inc. 4 | * Modified by Sagar Karandikar for RISC-V Rocket Support + Support for 5 | * upstream u-boot-xlnx 6 | * 7 | * Originally taken from 8 | * https://github.com/Digilent/u-boot-Digilent-Dev/commit/e7773ea2067c224f178a40a97d003ff418f47e12 9 | * 10 | * u-boot Configuration for Zynq Development Board - ZYBO 11 | * See zynq-common.h for Zynq common configs 12 | * 13 | * SPDX-License-Identifier: GPL-2.0+ 14 | */ 15 | 16 | #ifndef __CONFIG_ZYNQ_ZYBO_H 17 | #define __CONFIG_ZYNQ_ZYBO_H 18 | 19 | /* originally 512 * ..., but Rocket gets upper half of RAM */ 20 | #define CONFIG_SYS_SDRAM_SIZE (256 * 1024 * 1024) 21 | 22 | #define CONFIG_ZYNQ_SERIAL_UART1 23 | #define CONFIG_ZYNQ_GEM0 24 | #define CONFIG_ZYNQ_GEM_PHY_ADDR0 0 25 | 26 | #define CONFIG_SYS_NO_FLASH 27 | 28 | #define CONFIG_ZYNQ_SDHCI0 29 | #define CONFIG_ZYNQ_QSPI 30 | #define CONFIG_ZYNQ_BOOT_FREEBSD 31 | 32 | /* Define ZYBO PS Clock Frequency to 50MHz */ 33 | #define CONFIG_ZYNQ_PS_CLK_FREQ 50000000UL 34 | 35 | #include 36 | 37 | /* Overwrite Default environment */ 38 | #ifdef CONFIG_EXTRA_ENV_SETTINGS 39 | #undef CONFIG_EXTRA_ENV_SETTINGS 40 | #endif 41 | 42 | #define CONFIG_EXTRA_ENV_SETTINGS \ 43 | "kernel_image=uImage\0" \ 44 | "ramdisk_image=uramdisk.image.gz\0" \ 45 | "devicetree_image=devicetree.dtb\0" \ 46 | "bitstream_image=system.bit.bin\0" \ 47 | "boot_image=BOOT.bin\0" \ 48 | "loadbit_addr=0x100000\0" \ 49 | "loadbootenv_addr=0x2000000\0" \ 50 | "kernel_size=0x500000\0" \ 51 | "devicetree_size=0x20000\0" \ 52 | "ramdisk_size=0x5E0000\0" \ 53 | "boot_size=0xF00000\0" \ 54 | "fdt_high=0x10000000\0" \ 55 | "initrd_high=0x10000000\0" \ 56 | "bootenv=uEnv.txt\0" \ 57 | "loadbootenv=fatload mmc 0 ${loadbootenv_addr} ${bootenv}\0" \ 58 | "importbootenv=echo Importing environment from SD ...; " \ 59 | "env import -t ${loadbootenv_addr} $filesize\0" \ 60 | "mmc_loadbit_fat=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \ 61 | "mmcinfo && " \ 62 | "fatload mmc 0 ${loadbit_addr} ${bitstream_image} && " \ 63 | "fpga load 0 ${loadbit_addr} ${filesize}\0" \ 64 | "norboot=echo Copying Linux from NOR flash to RAM... && " \ 65 | "cp.b 0xE2100000 0x3000000 ${kernel_size} && " \ 66 | "cp.b 0xE2600000 0x2A00000 ${devicetree_size} && " \ 67 | "echo Copying ramdisk... && " \ 68 | "cp.b 0xE2620000 0x2000000 ${ramdisk_size} && " \ 69 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 70 | "qspiboot=echo Copying Linux from QSPI flash to RAM... && " \ 71 | "sf probe 0 0 0 && " \ 72 | "sf read 0x3000000 0x100000 ${kernel_size} && " \ 73 | "sf read 0x2A00000 0x600000 ${devicetree_size} && " \ 74 | "echo Copying ramdisk... && " \ 75 | "sf read 0x2000000 0x620000 ${ramdisk_size} && " \ 76 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 77 | "uenvboot=" \ 78 | "if run loadbootenv; then " \ 79 | "echo Loaded environment from ${bootenv}; " \ 80 | "run importbootenv; " \ 81 | "fi; " \ 82 | "if test -n $uenvcmd; then " \ 83 | "echo Running uenvcmd ...; " \ 84 | "run uenvcmd; " \ 85 | "fi\0" \ 86 | "sdboot=if mmcinfo; then " \ 87 | "run uenvboot; " \ 88 | "echo Copying Linux from SD to RAM... && " \ 89 | "fatload mmc 0 0x3000000 ${kernel_image} && " \ 90 | "fatload mmc 0 0x2A00000 ${devicetree_image} && " \ 91 | "fatload mmc 0 0x2000000 ${ramdisk_image} && " \ 92 | "bootm 0x3000000 0x2000000 0x2A00000; " \ 93 | "fi\0" \ 94 | "nandboot=echo Copying Linux from NAND flash to RAM... && " \ 95 | "nand read 0x3000000 0x100000 ${kernel_size} && " \ 96 | "nand read 0x2A00000 0x600000 ${devicetree_size} && " \ 97 | "echo Copying ramdisk... && " \ 98 | "nand read 0x2000000 0x620000 ${ramdisk_size} && " \ 99 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 100 | "jtagboot=echo TFTPing Linux to RAM... && " \ 101 | "tftp 0x3000000 ${kernel_image} && " \ 102 | "tftp 0x2A00000 ${devicetree_image} && " \ 103 | "tftp 0x2000000 ${ramdisk_image} && " \ 104 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 105 | "rsa_norboot=echo Copying Image from NOR flash to RAM... && " \ 106 | "cp.b 0xE2100000 0x100000 ${boot_size} && " \ 107 | "zynqrsa 0x100000 && " \ 108 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 109 | "rsa_nandboot=echo Copying Image from NAND flash to RAM... && " \ 110 | "nand read 0x100000 0x0 ${boot_size} && " \ 111 | "zynqrsa 0x100000 && " \ 112 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 113 | "rsa_qspiboot=echo Copying Image from QSPI flash to RAM... && " \ 114 | "sf probe 0 0 0 && " \ 115 | "sf read 0x100000 0x0 ${boot_size} && " \ 116 | "zynqrsa 0x100000 && " \ 117 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 118 | "rsa_sdboot=echo Copying Image from SD to RAM... && " \ 119 | "fatload mmc 0 0x100000 ${boot_image} && " \ 120 | "zynqrsa 0x100000 && " \ 121 | "bootm 0x3000000 0x2000000 0x2A00000\0" \ 122 | "rsa_jtagboot=echo TFTPing Image to RAM... && " \ 123 | "tftp 0x100000 ${boot_image} && " \ 124 | "zynqrsa 0x100000 && " \ 125 | "bootm 0x3000000 0x2000000 0x2A00000\0" 126 | 127 | #endif /* __CONFIG_ZYNQ_ZYBO_H */ 128 | -------------------------------------------------------------------------------- /common/src/main/scala/Serdes.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import freechips.rocketchip.config.Parameters 6 | import testchipip._ 7 | 8 | class BlockDeviceSerialIO(w: Int) extends Bundle { 9 | val req = Decoupled(UInt(w.W)) 10 | val data = Decoupled(UInt(w.W)) 11 | val resp = Flipped(Decoupled(UInt(w.W))) 12 | 13 | override def cloneType = new BlockDeviceSerialIO(w).asInstanceOf[this.type] 14 | } 15 | 16 | class BlockDeviceSerdes(w: Int)(implicit p: Parameters) 17 | extends BlockDeviceModule { 18 | val io = IO(new Bundle { 19 | val bdev = Flipped(new BlockDeviceIO) 20 | val ser = new BlockDeviceSerialIO(w) 21 | }) 22 | 23 | require(w >= sectorBits) 24 | require(w >= (tagBits + 1)) 25 | require(dataBitsPerBeat % w == 0) 26 | 27 | val reqWords = 3 28 | val dataWords = 1 + dataBitsPerBeat / w 29 | 30 | val req = Reg(new BlockDeviceRequest) 31 | val data = Reg(new BlockDeviceData) 32 | val resp = Reg(new BlockDeviceData) 33 | 34 | val (req_idx, req_done) = Counter(io.ser.req.fire(), reqWords) 35 | val req_send = RegInit(false.B) 36 | 37 | val (data_idx, data_done) = Counter(io.ser.data.fire(), dataWords) 38 | val data_send = RegInit(false.B) 39 | 40 | val (resp_idx, resp_done) = Counter(io.ser.resp.fire(), dataWords) 41 | val resp_send = RegInit(false.B) 42 | 43 | when (io.bdev.req.fire()) { 44 | req := io.bdev.req.bits 45 | req_send := true.B 46 | } 47 | when (req_done) { req_send := false.B } 48 | 49 | when (io.bdev.data.fire()) { 50 | data := io.bdev.data.bits 51 | data_send := true.B 52 | } 53 | when (data_done) { data_send := false.B } 54 | 55 | when (io.ser.resp.fire()) { 56 | when (resp_idx === 0.U) { 57 | resp.tag := io.ser.resp.bits 58 | resp.data := 0.U 59 | } .otherwise { 60 | val shift_amt = (resp_idx - 1.U) << log2Ceil(w).U 61 | resp.data := resp.data | (io.ser.resp.bits << shift_amt) 62 | } 63 | } 64 | when (resp_done) { resp_send := true.B } 65 | when (io.bdev.resp.fire()) { resp_send := false.B } 66 | 67 | io.bdev.req.ready := !req_send 68 | io.bdev.data.ready := !data_send 69 | io.bdev.resp.valid := resp_send 70 | io.bdev.resp.bits := resp 71 | io.bdev.info := DontCare 72 | 73 | val req_vec = Vec(Cat(req.tag, req.write), req.offset, req.len) 74 | val data_vec = Vec(data.tag +: Seq.tabulate(dataBitsPerBeat/w) { 75 | i => data.data((i + 1) * w - 1, i * w) 76 | }) 77 | 78 | io.ser.req.valid := req_send 79 | io.ser.req.bits := req_vec(req_idx) 80 | io.ser.data.valid := data_send 81 | io.ser.data.bits := data_vec(data_idx) 82 | io.ser.resp.ready := !resp_send 83 | } 84 | 85 | class BlockDeviceDesser(w: Int)(implicit p: Parameters) extends BlockDeviceModule { 86 | val io = IO(new Bundle { 87 | val bdev = new BlockDeviceIO 88 | val ser = Flipped(new BlockDeviceSerialIO(w)) 89 | }) 90 | 91 | require(w >= sectorBits) 92 | require(w >= (tagBits + 1)) 93 | require(dataBitsPerBeat % w == 0) 94 | 95 | val reqWords = 3 96 | val dataWords = 1 + dataBitsPerBeat / w 97 | 98 | val req = Reg(new BlockDeviceRequest) 99 | val data = Reg(new BlockDeviceData) 100 | val resp = Reg(new BlockDeviceData) 101 | 102 | val (req_idx, req_done) = Counter(io.ser.req.fire(), reqWords) 103 | val req_send = RegInit(false.B) 104 | 105 | val (data_idx, data_done) = Counter(io.ser.data.fire(), dataWords) 106 | val data_send = RegInit(false.B) 107 | 108 | val (resp_idx, resp_done) = Counter(io.ser.resp.fire(), dataWords) 109 | val resp_send = RegInit(false.B) 110 | 111 | when (io.ser.req.fire()) { 112 | switch (req_idx) { 113 | is (0.U) { 114 | req.write := io.ser.req.bits(0) 115 | req.tag := io.ser.req.bits(tagBits, 1) 116 | } 117 | is (1.U) { 118 | req.offset := io.ser.req.bits 119 | } 120 | is (2.U) { 121 | req.len := io.ser.req.bits 122 | } 123 | } 124 | } 125 | when (req_done) { req_send := true.B } 126 | when (io.bdev.req.fire()) { 127 | req_send := false.B 128 | } 129 | 130 | when (io.ser.data.fire()) { 131 | when (data_idx === 0.U) { 132 | data.tag := io.ser.data.bits 133 | data.data := 0.U 134 | } .otherwise { 135 | val shift_amt = (data_idx - 1.U) << log2Ceil(w).U 136 | data.data := data.data | (io.ser.data.bits << shift_amt) 137 | } 138 | } 139 | when (data_done) { data_send := true.B } 140 | when (io.bdev.data.fire()) { data_send := false.B } 141 | 142 | when (io.bdev.resp.fire()) { 143 | resp := io.bdev.resp.bits 144 | resp_send := true.B 145 | } 146 | when (resp_done) { resp_send := false.B } 147 | 148 | io.bdev.req.valid := req_send 149 | io.bdev.req.bits := req 150 | io.bdev.data.valid := data_send 151 | io.bdev.data.bits := data 152 | io.bdev.resp.ready := !resp_send 153 | 154 | val resp_vec = Vec(resp.tag +: Seq.tabulate(dataBitsPerBeat/w) { 155 | i => resp.data((i + 1) * w - 1, i * w) 156 | }) 157 | 158 | io.ser.req.ready := !req_send 159 | io.ser.data.ready := !data_send 160 | io.ser.resp.valid := resp_send 161 | io.ser.resp.bits := resp_vec(resp_idx) 162 | } 163 | -------------------------------------------------------------------------------- /common/zynq_rocketchip.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Vivado (TM) v2015.4 (64-bit) 3 | # 4 | # BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE.tcl: Tcl script for re-creating project 'BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE' 5 | # 6 | # Generated by Vivado on Tue Jan 05 14:52:20 PST 2016 7 | # IP Build 1412160 on Tue Nov 17 13:47:24 MST 2015 8 | # 9 | # This file contains the Vivado Tcl commands for re-creating the project to the state* 10 | # when this script was generated. In order to re-create the project, please source this 11 | # file in the Vivado Tcl Shell. 12 | # 13 | # * Note that the runs in the created project will be configured the same way as the 14 | # original project, however they will not be launched automatically. To regenerate the 15 | # run results please launch the synthesis/implementation runs as needed. 16 | 17 | # Set the reference directory for source file relative paths (by default the value is script directory path) 18 | set origin_dir "." 19 | 20 | # Use origin directory path location variable, if specified in the tcl shell 21 | if { [info exists ::origin_dir_loc] } { 22 | set origin_dir $::origin_dir_loc 23 | } 24 | 25 | variable script_file 26 | set script_file "BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE.tcl" 27 | 28 | # Help information for this script 29 | proc help {} { 30 | variable script_file 31 | puts "\nDescription:" 32 | puts "Recreate a Vivado project from this script. The created project will be" 33 | puts "functionally equivalent to the original project for which this script was" 34 | puts "generated. The script contains commands for creating a project, filesets," 35 | puts "runs, adding/importing sources and setting properties on various objects.\n" 36 | puts "Syntax:" 37 | puts "$script_file" 38 | puts "$script_file -tclargs \[--origin_dir \]" 39 | puts "$script_file -tclargs \[--help\]\n" 40 | puts "Usage:" 41 | puts "Name Description" 42 | puts "-------------------------------------------------------------------------" 43 | puts "\[--origin_dir \] Determine source file paths wrt this path. Default" 44 | puts " origin_dir path value is \".\", otherwise, the value" 45 | puts " that was set with the \"-paths_relative_to\" switch" 46 | puts " when this script was generated.\n" 47 | puts "\[--help\] Print help information for this script" 48 | puts "-------------------------------------------------------------------------\n" 49 | exit 0 50 | } 51 | 52 | if { $::argc > 0 } { 53 | for {set i 0} {$i < [llength $::argc]} {incr i} { 54 | set option [string trim [lindex $::argv $i]] 55 | switch -regexp -- $option { 56 | "--origin_dir" { incr i; set origin_dir [lindex $::argv $i] } 57 | "--help" { help } 58 | default { 59 | if { [regexp {^-} $option] } { 60 | puts "ERROR: Unknown option '$option' specified, please type '$script_file -tclargs --help' for usage info.\n" 61 | return 1 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | # Set the directory path for the original project from where this script was exported 69 | set orig_proj_dir "[file normalize "$origin_dir/BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE"]" 70 | 71 | # Create project 72 | create_project BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE $orig_proj_dir 73 | 74 | # Set the directory path for the new project 75 | set proj_dir [get_property directory [current_project]] 76 | 77 | # Set project properties 78 | set obj [get_projects BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE] 79 | set_property "default_lib" "xil_defaultlib" $obj 80 | set_property "part" "PART_NUMBER_HERE" $obj 81 | # REPLACE FOR OFFICIAL BOARD NAME $obj 82 | set_property "simulator_language" "Mixed" $obj 83 | 84 | # Create 'sources_1' fileset (if not found) 85 | if {[string equal [get_filesets -quiet sources_1] ""]} { 86 | create_fileset -srcset sources_1 87 | } 88 | 89 | # Set 'sources_1' fileset object 90 | set obj [get_filesets sources_1] 91 | set files [list \ 92 | "[file normalize "$origin_dir/src/verilog/clocking.vh"]"\ 93 | "[file normalize "$origin_dir/src/verilog/Top.CHISEL_CONFIG_HERE.v"]"\ 94 | "[file normalize "$origin_dir/src/verilog/rocketchip_wrapper.v"]"\ 95 | "[file normalize "$origin_dir/src/verilog/AsyncResetReg.v"]" \ 96 | "[file normalize "$origin_dir/src/verilog/plusarg_reader.v"]" \ 97 | ] 98 | add_files -norecurse -fileset $obj $files 99 | 100 | # Set 'sources_1' fileset file properties for remote files 101 | # None 102 | 103 | # Set 'sources_1' fileset file properties for local files 104 | # None 105 | 106 | # Set 'sources_1' fileset properties 107 | set obj [get_filesets sources_1] 108 | set_property "top" "rocketchip_wrapper" $obj 109 | 110 | # Create 'constrs_1' fileset (if not found) 111 | if {[string equal [get_filesets -quiet constrs_1] ""]} { 112 | create_fileset -constrset constrs_1 113 | } 114 | 115 | # Set 'constrs_1' fileset object 116 | set obj [get_filesets constrs_1] 117 | 118 | # Add/Import constrs file and set constrs file properties 119 | set file "[file normalize "$origin_dir/src/constrs/base.xdc"]" 120 | set file_added [add_files -norecurse -fileset $obj $file] 121 | set file "$origin_dir/src/constrs/base.xdc" 122 | set file [file normalize $file] 123 | set file_obj [get_files -of_objects [get_filesets constrs_1] [list "*$file"]] 124 | set_property "file_type" "XDC" $file_obj 125 | 126 | # Set 'constrs_1' fileset properties 127 | set obj [get_filesets constrs_1] 128 | set_property "target_constrs_file" "[file normalize "$origin_dir/src/constrs/base.xdc"]" $obj 129 | 130 | # Create 'sim_1' fileset (if not found) 131 | if {[string equal [get_filesets -quiet sim_1] ""]} { 132 | create_fileset -simset sim_1 133 | } 134 | 135 | # Set 'sim_1' fileset object 136 | set obj [get_filesets sim_1] 137 | # Empty (no sources present) 138 | 139 | # Set 'sim_1' fileset properties 140 | set obj [get_filesets sim_1] 141 | set_property "top" "rocketchip_wrapper" $obj 142 | 143 | # Create 'synth_1' run (if not found) 144 | if {[string equal [get_runs -quiet synth_1] ""]} { 145 | create_run -name synth_1 -part PART_NUMBER_HERE -flow {Vivado Synthesis 2015} -strategy "Vivado Synthesis Defaults" -constrset constrs_1 146 | } else { 147 | set_property strategy "Vivado Synthesis Defaults" [get_runs synth_1] 148 | set_property flow "Vivado Synthesis 2015" [get_runs synth_1] 149 | } 150 | set obj [get_runs synth_1] 151 | set_property "needs_refresh" "1" $obj 152 | set_property "part" "PART_NUMBER_HERE" $obj 153 | 154 | # Create 'impl_1' run (if not found) 155 | if {[string equal [get_runs -quiet impl_1] ""]} { 156 | create_run -name impl_1 -part PART_NUMBER_HERE -flow {Vivado Implementation 2015} -strategy "Vivado Implementation Defaults" -constrset constrs_1 -parent_run synth_1 157 | } else { 158 | set_property strategy "Vivado Implementation Defaults" [get_runs impl_1] 159 | set_property flow "Vivado Implementation 2015" [get_runs impl_1] 160 | } 161 | set obj [get_runs impl_1] 162 | set_property "needs_refresh" "1" $obj 163 | set_property "part" "PART_NUMBER_HERE" $obj 164 | 165 | puts "INFO: Project created:BOARD_NAME_HERE_rocketchip_CHISEL_CONFIG_HERE" 166 | 167 | puts "INFO: Recreating block diagram from src/tcl/BOARD_NAME_HERE_bd.tcl" 168 | source src/tcl/BOARD_NAME_HERE_bd.tcl 169 | 170 | exit 171 | -------------------------------------------------------------------------------- /common/src/main/scala/Drivers.scala: -------------------------------------------------------------------------------- 1 | package zynq 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import freechips.rocketchip.config.Parameters 6 | import freechips.rocketchip.diplomacy._ 7 | import freechips.rocketchip.tilelink._ 8 | import freechips.rocketchip.util._ 9 | import testchipip._ 10 | import testchipip.SerialAdapter._ 11 | 12 | class InFIFODriver(name: String, addr: BigInt, maxSpace: Int) 13 | (implicit p: Parameters) extends LazyModule { 14 | 15 | val node = TLHelper.makeClientNode( 16 | name = name, sourceId = IdRange(0, 1)) 17 | 18 | lazy val module = new LazyModuleImp(this) { 19 | val (tl, edge) = node.out(0) 20 | val dataBits = edge.bundle.dataBits 21 | val beatBytes = dataBits / 8 22 | 23 | val io = IO(new Bundle { 24 | val in = Flipped(Decoupled(UInt(dataBits.W))) 25 | }) 26 | 27 | val timeout = 64 28 | val timer = RegInit(0.U(log2Ceil(timeout).W)) 29 | val space = RegInit(0.U(log2Ceil(maxSpace + 1).W)) 30 | 31 | val (s_start :: s_read_acq :: s_read_gnt :: 32 | s_req :: s_write_acq :: s_write_gnt :: Nil) = Enum(6) 33 | val state = RegInit(s_start) 34 | val data = Reg(UInt(dataBits.W)) 35 | 36 | val put_acq = edge.Put( 37 | fromSource = 0.U, 38 | toAddress = addr.U, 39 | lgSize = log2Ceil(beatBytes).U, 40 | data = data)._2 41 | 42 | val get_acq = edge.Get( 43 | fromSource = 0.U, 44 | toAddress = (addr + beatBytes).U, 45 | lgSize = log2Ceil(beatBytes).U)._2 46 | 47 | tl.a.valid := state.isOneOf(s_read_acq, s_write_acq) 48 | tl.a.bits := Mux(state === s_read_acq, get_acq, put_acq) 49 | tl.d.ready := state.isOneOf(s_read_gnt, s_write_gnt) 50 | io.in.ready := state === s_req 51 | 52 | when (state === s_start) { 53 | when (space =/= 0.U) { 54 | state := s_req 55 | } .elsewhen (timer === 0.U) { 56 | timer := (timeout - 1).U 57 | state := s_read_acq 58 | } .otherwise { 59 | timer := timer - 1.U 60 | } 61 | } 62 | 63 | when (state === s_read_acq && tl.a.ready) { state := s_read_gnt } 64 | when (state === s_read_gnt && tl.d.valid) { 65 | space := tl.d.bits.data 66 | state := s_start 67 | } 68 | 69 | when (io.in.fire()) { 70 | data := io.in.bits 71 | space := space - 1.U 72 | state := s_write_acq 73 | } 74 | 75 | when (state === s_write_acq && tl.a.ready) { state := s_write_gnt } 76 | when (state === s_write_gnt && tl.d.valid) { state := s_start } 77 | } 78 | } 79 | 80 | class OutFIFODriver(name: String, addr: BigInt, maxCount: Int) 81 | (implicit p: Parameters) extends LazyModule { 82 | 83 | val node = TLHelper.makeClientNode( 84 | name = name, sourceId = IdRange(0, 1)) 85 | 86 | lazy val module = new LazyModuleImp(this) { 87 | val (tl, edge) = node.out(0) 88 | val dataBits = edge.bundle.dataBits 89 | val beatBytes = dataBits / 8 90 | val lgSize = log2Ceil(beatBytes) 91 | 92 | val io = IO(new Bundle { 93 | val out = Decoupled(UInt(dataBits.W)) 94 | }) 95 | 96 | val timeout = 64 97 | val timer = RegInit(0.U(log2Ceil(timeout).W)) 98 | val count = RegInit(0.U(log2Ceil(maxCount + 1).W)) 99 | val (s_start :: s_count_acq :: s_count_gnt :: 100 | s_fifo_acq :: s_fifo_gnt :: Nil) = Enum(5) 101 | val state = RegInit(s_start) 102 | 103 | tl.a.valid := state.isOneOf(s_count_acq, s_fifo_acq) 104 | tl.a.bits := edge.Get( 105 | fromSource = 0.U, 106 | toAddress = Mux(state === s_count_acq, (addr + beatBytes).U, addr.U), 107 | lgSize = lgSize.U)._2 108 | 109 | tl.d.ready := 110 | (state === s_count_gnt) || 111 | (state === s_fifo_gnt && io.out.ready) 112 | 113 | io.out.valid := state === s_fifo_gnt && tl.d.valid 114 | io.out.bits := tl.d.bits.data 115 | 116 | when (state === s_start) { 117 | when (count =/= 0.U) { 118 | state := s_fifo_acq 119 | } .elsewhen (timer === 0.U) { 120 | timer := (timeout - 1).U 121 | state := s_count_acq 122 | } .otherwise { 123 | timer := timer - 1.U 124 | } 125 | } 126 | 127 | when (tl.a.fire()) { 128 | state := Mux(state === s_count_acq, s_count_gnt, s_fifo_gnt) 129 | } 130 | 131 | when (tl.d.fire()) { 132 | count := Mux(state === s_count_gnt, tl.d.bits.data, count - 1.U) 133 | state := s_start 134 | } 135 | } 136 | } 137 | 138 | class SetRegisterDriver(name: String, addr: BigInt, n: Int) 139 | (implicit p: Parameters) extends LazyModule { 140 | 141 | val node = TLHelper.makeClientNode( 142 | name = name, sourceId = IdRange(0, 1)) 143 | 144 | lazy val module = new LazyModuleImp(this) { 145 | val (tl, edge) = node.out(0) 146 | val dataBits = edge.bundle.dataBits 147 | val beatBytes = dataBits / 8 148 | val lgSize = log2Ceil(beatBytes) 149 | 150 | val io = IO(new Bundle { 151 | val values = Input(Vec(n, UInt(dataBits.W))) 152 | }) 153 | 154 | val (s_start :: s_write_acq :: s_write_gnt :: s_wait :: Nil) = Enum(4) 155 | val state = RegInit(s_start) 156 | val values = Reg(Vec(n, UInt(dataBits.W))) 157 | 158 | val value_diff = Cat(io.values.zip(values).map { 159 | case (iovalue, value) => iovalue != value 160 | }.reverse) 161 | val value_set = RegInit(UInt(n.W), ~0.U(n.W)) 162 | val value_set_oh = PriorityEncoderOH(value_set) 163 | val value_idx = OHToUInt(value_set_oh) 164 | 165 | tl.a.valid := state === s_write_acq 166 | tl.a.bits := edge.Put( 167 | fromSource = 0.U, 168 | toAddress = addr.U + (value_idx << lgSize.U), 169 | lgSize = lgSize.U, 170 | data = values(value_idx))._2 171 | tl.d.ready := state === s_write_gnt 172 | 173 | when (state === s_start) { 174 | state := s_write_acq 175 | for (i <- 0 until n) { 176 | when (value_set(i)) { 177 | values(i) := io.values(i) 178 | } 179 | } 180 | } 181 | when (tl.a.fire()) { state := s_write_gnt } 182 | when (tl.d.fire()) { 183 | value_set := value_set & ~value_set_oh 184 | state := s_wait 185 | } 186 | when (state === s_wait) { 187 | when (value_set.orR) { 188 | state := s_write_acq 189 | } .elsewhen (value_diff.orR) { 190 | value_set := value_diff 191 | state := s_start 192 | } 193 | } 194 | } 195 | } 196 | 197 | class SerialDriver(implicit p: Parameters) extends LazyModule { 198 | val base = p(ZynqAdapterBase) 199 | val depth = p(SerialFIFODepth) 200 | 201 | val node = TLIdentityNode() 202 | val xbar = LazyModule(new TLXbar) 203 | val outdrv = LazyModule(new OutFIFODriver("serial-out", base, depth)) 204 | val indrv = LazyModule(new InFIFODriver("serial-in", base + BigInt(8), depth)) 205 | 206 | xbar.node := outdrv.node 207 | xbar.node := indrv.node 208 | node := xbar.node 209 | 210 | lazy val module = new LazyModuleImp(this) { 211 | val (tl, edge) = node.out(0) 212 | require(edge.bundle.dataBits == SERIAL_IF_WIDTH) 213 | 214 | val io = IO(new Bundle { 215 | val serial = new SerialIO(SERIAL_IF_WIDTH) 216 | }) 217 | 218 | indrv.module.io.in <> io.serial.in 219 | io.serial.out <> outdrv.module.io.out 220 | } 221 | } 222 | 223 | class ResetDriver(implicit p: Parameters) extends LazyModule { 224 | val base = p(ZynqAdapterBase) 225 | 226 | val node = TLIdentityNode() 227 | val driver = LazyModule(new SetRegisterDriver("reset", base + BigInt(0x10), 1)) 228 | 229 | node := driver.node 230 | 231 | lazy val module = new LazyModuleImp(this) { 232 | driver.module.io.values(0) := 0.U 233 | } 234 | } 235 | 236 | class BlockDeviceDriver(implicit p: Parameters) extends LazyModule { 237 | val base = p(ZynqAdapterBase) 238 | val depth = p(BlockDeviceFIFODepth) 239 | 240 | val node = TLIdentityNode() 241 | val xbar = LazyModule(new TLXbar) 242 | val reqdrv = LazyModule(new OutFIFODriver( 243 | "bdev-req", base + BigInt(0x20), depth)) 244 | val datadrv = LazyModule(new OutFIFODriver( 245 | "bdev-data", base + BigInt(0x28), depth)) 246 | val respdrv = LazyModule(new InFIFODriver( 247 | "bdev-resp", base + BigInt(0x30), depth)) 248 | val infodrv = LazyModule(new SetRegisterDriver( 249 | "bdev-info", base + BigInt(0x38), 2)) 250 | 251 | xbar.node := reqdrv.node 252 | xbar.node := datadrv.node 253 | xbar.node := respdrv.node 254 | xbar.node := infodrv.node 255 | node := xbar.node 256 | 257 | lazy val module = new LazyModuleImp(this) { 258 | val (tl, edge) = node.out(0) 259 | val dataBits = edge.bundle.dataBits 260 | 261 | val io = IO(new Bundle { 262 | val bdev = new BlockDeviceIO 263 | }) 264 | 265 | val desser = Module(new BlockDeviceDesser(dataBits)) 266 | io.bdev <> desser.io.bdev 267 | desser.io.ser.req <> reqdrv.module.io.out 268 | desser.io.ser.data <> datadrv.module.io.out 269 | respdrv.module.io.in <> desser.io.ser.resp 270 | infodrv.module.io.values := Seq( 271 | io.bdev.info.nsectors, io.bdev.info.max_req_len) 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /common/Makefrag: -------------------------------------------------------------------------------- 1 | # This makefrag is sourced by each board's subdirectory 2 | 3 | JOBS = 16 4 | ROCKET_DIR ?= $(base_dir)/rocket-chip 5 | TOP_MODULE_PROJECT ?= zynq 6 | TOP_MODULE ?= Top 7 | CFG_PROJECT ?= $(TOP_MODULE_PROJECT) 8 | CONFIG ?= ZynqConfig 9 | SCALA_VERSION=2.11.12 10 | EXTRA_PACKAGES=testchipip 11 | 12 | base_dir = $(abspath ..) 13 | common = $(base_dir)/common 14 | common_build = $(common)/build 15 | testchipip = $(base_dir)/testchipip 16 | output_delivery = deliver_output 17 | SHELL := /bin/bash 18 | 19 | bootrom_img = $(testchipip)/bootrom/bootrom.rv64.img $(testchipip)/bootrom/bootrom.rv32.img 20 | rocketchip_stamp = $(common)/lib/rocketchip.stamp 21 | extra_stamps = $(addprefix $(common)/lib/,$(addsuffix .stamp,$(EXTRA_PACKAGES))) 22 | 23 | ifneq ($(BOARD_MODEL),) 24 | insert_board = s/\# REPLACE FOR OFFICIAL BOARD NAME/set_property "board_part" "$(BOARD_MODEL)"/g 25 | endif 26 | 27 | proj_name = $(BOARD)_rocketchip_$(CONFIG) 28 | 29 | verilog_srcs = \ 30 | src/verilog/clocking.vh \ 31 | src/verilog/rocketchip_wrapper.v \ 32 | src/verilog/$(TOP_MODULE).$(CONFIG).v \ 33 | src/verilog/AsyncResetReg.v \ 34 | src/verilog/plusarg_reader.v \ 35 | 36 | bootimage = fpga-images-$(BOARD)/boot.bin 37 | bootimage: $(bootimage) 38 | 39 | # Taken from rocket chip 2a5aeea. TODO: Maybe source this directly from makefrag? 40 | SBT ?= java -Xmx2G -Xss8M -XX:MaxPermSize=256M -jar $(ROCKET_DIR)/sbt-launch.jar 41 | 42 | FIRRTL_JAR ?= $(ROCKET_DIR)/firrtl/utils/bin/firrtl.jar 43 | FIRRTL ?= java -Xmx2G -Xss8M -XX:MaxPermSize=256M -cp $(FIRRTL_JAR) firrtl.Driver 44 | 45 | $(FIRRTL_JAR): $(shell find $(ROCKET_DIR)/firrtl/src/main/scala -iname "*.scala" 2> /dev/null) 46 | $(MAKE) -C $(ROCKET_DIR)/firrtl SBT="$(SBT)" root_dir=$(ROCKET_DIR)/firrtl build-scala 47 | 48 | CHISEL_ARGS := $(common_build) 49 | 50 | lookup_scala_srcs = $(shell find $(1)/. -iname "*.scala" 2> /dev/null) 51 | 52 | # Initialize rocket-chip submodule 53 | # ------------------------------------------------------------------------------ 54 | 55 | init-submodules: 56 | cd $(base_dir) && git submodule update --init rocket-chip $(EXTRA_PACKAGES) 57 | cd $(ROCKET_DIR) && git submodule update --init 58 | 59 | # Specialize sources for board 60 | # ------------------------------------------------------------------------------ 61 | src/verilog/rocketchip_wrapper.v: $(common)/rocketchip_wrapper.v 62 | cp $(common)/rocketchip_wrapper.v src/verilog/ 63 | 64 | src/tcl/$(proj_name).tcl: $(common)/zynq_rocketchip.tcl Makefile 65 | sed 's/BOARD_NAME_HERE/$(BOARD)/g;s/PART_NUMBER_HERE/$(PART)/g;$(insert_board);s/CHISEL_CONFIG_HERE/$(CONFIG)/g' \ 66 | $(common)/zynq_rocketchip.tcl > src/tcl/$(proj_name).tcl 67 | 68 | src/tcl/make_bitstream_$(CONFIG).tcl: $(common)/make_bitstream.tcl 69 | sed 's/BOARD_NAME_HERE/$(BOARD)/g;s/CHISEL_CONFIG_HERE/$(CONFIG)/g' \ 70 | $(common)/make_bitstream.tcl > src/tcl/make_bitstream_$(CONFIG).tcl 71 | 72 | src/verilog/%.v: $(ROCKET_DIR)/vsrc/%.v 73 | cp $< $@ 74 | 75 | $(ROCKET_DIR)/lib/firrtl.jar: $(FIRRTL_JAR) 76 | mkdir -p $(@D) 77 | cp $< $@ 78 | 79 | $(rocketchip_stamp): $(call lookup_scala_srcs, $(ROCKET_DIR)) $(ROCKET_DIR)/lib/firrtl.jar 80 | cd $(ROCKET_DIR) && $(SBT) pack 81 | mkdir -p $(common)/lib 82 | cp $(ROCKET_DIR)/target/pack/lib/* $(common)/lib 83 | touch $(rocketchip_stamp) 84 | 85 | $(common)/Makefrag.pkgs: $(common)/generate-pkg-mk.sh 86 | bash $(common)/generate-pkg-mk.sh $(EXTRA_PACKAGES) > $@ 87 | 88 | -include $(common)/Makefrag.pkgs 89 | 90 | $(common_build)/$(TOP_MODULE).$(CONFIG).fir: $(rocketchip_stamp) $(extra_stamps) $(bootrom_img) $(call lookup_scala_srcs,$(common)) 91 | mkdir -p $(@D) 92 | cd $(common) && $(SBT) "run $(CHISEL_ARGS) $(TOP_MODULE_PROJECT) $(TOP_MODULE) $(CFG_PROJECT) $(CONFIG)" 93 | 94 | $(common_build)/$(TOP_MODULE).$(CONFIG).v: $(common_build)/$(TOP_MODULE).$(CONFIG).fir $(FIRRTL_JAR) 95 | $(FIRRTL) -i $< -o $@ -X verilog 96 | 97 | src/verilog/$(TOP_MODULE).$(CONFIG).v: $(common_build)/$(TOP_MODULE).$(CONFIG).v 98 | cp $< $@ 99 | 100 | rocket: src/verilog/$(TOP_MODULE).$(CONFIG).v 101 | 102 | 103 | # Project generation 104 | # ------------------------------------------------------------------------------ 105 | project = $(proj_name)/$(proj_name).xpr 106 | $(project): src/tcl/$(proj_name).tcl | $(verilog_srcs) 107 | rm -rf $(proj_name) 108 | vivado -mode tcl -source src/tcl/$(proj_name).tcl; 109 | 110 | project: $(project) 111 | 112 | vivado: $(project) 113 | vivado $(project) & 114 | 115 | bitstream = $(proj_name)/$(proj_name).runs/impl_1/rocketchip_wrapper.bit 116 | $(bitstream): src/tcl/make_bitstream_$(CONFIG).tcl $(verilog_srcs) src/constrs/base.xdc | $(project) 117 | vivado -mode tcl -source src/tcl/make_bitstream_$(CONFIG).tcl 118 | bitstream: $(bitstream) 119 | 120 | 121 | 122 | # Platform software generation 123 | # ------------------------------------------------------------------------------ 124 | arm_linux_dir = $(base_dir)/common/linux-xlnx 125 | uboot_dir = $(base_dir)/common/u-boot-xlnx 126 | soft_build_dir = soft_build 127 | 128 | arm-linux: arm-uboot # must first build uboot because we need tools 129 | # compile kernel 130 | git submodule update --init $(arm_linux_dir) 131 | # no make clean included here since one copy of linux should work on all boards 132 | cd $(arm_linux_dir) && make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- xilinx_zynq_defconfig 133 | cd $(arm_linux_dir) && make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- -j$(JOBS) 134 | # convert zImage to uImage 135 | cd $(arm_linux_dir) && export PATH=$(uboot_dir)/tools:$$PATH && make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- UIMAGE_LOADADDR=0x8000 uImage 136 | mkdir -p $(output_delivery) 137 | cp $(arm_linux_dir)/arch/arm/boot/uImage $(output_delivery)/ 138 | 139 | arm-uboot: 140 | # compile board-compatible u-boot 141 | git submodule update --init $(uboot_dir) 142 | # copy relevant configuration files 143 | if [ -a soft_config/boards.cfg ] ; \ 144 | then \ 145 | cp soft_config/boards.cfg $(uboot_dir)/ ; \ 146 | fi; 147 | cp soft_config/zynq_$(UBOOT_CONFIG).h $(uboot_dir)/include/configs/ 148 | # actually build 149 | cd $(uboot_dir) && make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_$(UBOOT_CONFIG)_config 150 | cd $(uboot_dir) && make CROSS_COMPILE=arm-xilinx-linux-gnueabi- -j$(JOBS) 151 | mkdir -p $(soft_build_dir) 152 | cp $(uboot_dir)/u-boot $(soft_build_dir)/u-boot.elf 153 | 154 | arm-dtb: 155 | export PATH=$(arm_linux_dir)/scripts/dtc:$$PATH && dtc -I dts -O dtb -o $(output_delivery)/devicetree.dtb soft_config/$(BOARD)_devicetree.dts 156 | 157 | 158 | 159 | # Handle images and git submodule for prebuilt modules 160 | # ------------------------------------------------------------------------------ 161 | images = fpga-images-$(BOARD)/boot.bif 162 | $(images): 163 | git submodule update --init --depth=1 fpga-images-$(BOARD) 164 | 165 | fetch-images: $(images) 166 | 167 | $(bootimage): $(images) $(bitstream) 168 | ln -sf ../../$(bitstream) fpga-images-$(BOARD)/boot_image/rocketchip_wrapper.bit 169 | cd fpga-images-$(BOARD); bootgen -image boot.bif -w -o boot.bin 170 | 171 | load-sd: $(images) 172 | $(base_dir)/common/load_card.sh $(SD) 173 | 174 | ramdisk-open: $(images) 175 | mkdir ramdisk 176 | dd if=fpga-images-$(BOARD)/uramdisk.image.gz bs=64 skip=1 | \ 177 | gunzip -c | sudo sh -c 'cd ramdisk/ && cpio -i' 178 | 179 | ramdisk-close: 180 | @if [ ! -d "ramdisk" ]; then \ 181 | echo "No ramdisk to close (use make ramdisk-open first)"; \ 182 | exit 1; \ 183 | fi 184 | sh -c 'cd ramdisk/ && sudo find . | sudo cpio -H newc -o' | gzip -9 > uramdisk.cpio.gz 185 | mkimage -A arm -O linux -T ramdisk -d uramdisk.cpio.gz fpga-images-$(BOARD)/uramdisk.image.gz 186 | rm uramdisk.cpio.gz 187 | @echo "Don't forget to remove ramdisk before opening it again (sudo rm -rf ramdisk)" 188 | 189 | 190 | # Fetch ramdisk for user building from scratch 191 | # ------------------------------------------------------------------------------ 192 | s3_url = https://s3-us-west-1.amazonaws.com/riscv.org/fpga-zynq-files 193 | ramdisk_url = $(s3_url)/uramdisk.image.gz 194 | fetch-ramdisk: 195 | mkdir -p $(output_delivery) 196 | curl $(ramdisk_url) > $(output_delivery)/uramdisk.image.gz 197 | 198 | 199 | # Rebuild from bif for user building from scratch 200 | # ------------------------------------------------------------------------------ 201 | $(output_delivery)/boot.bin: 202 | cd $(output_delivery); bootgen -image output.bif -w -o boot.bin 203 | 204 | # Build riscv-fesvr for zynq 205 | # ------------------------------------------------------------------------------ 206 | 207 | fesvr-main = fesvr-zynq 208 | fesvr-srcs = \ 209 | $(common)/csrc/fesvr_zynq.cc \ 210 | $(common)/csrc/zynq_driver.cc \ 211 | $(testchipip)/csrc/blkdev.cc \ 212 | 213 | fesvr-hdrs = \ 214 | $(common)/csrc/zynq_driver.h \ 215 | $(testchipip)/csrc/blkdev.h \ 216 | 217 | fesvr-lib = $(common_build)/libfesvr.so 218 | 219 | CXX_FPGA = arm-xilinx-linux-gnueabi-g++ 220 | CXXFLAGS_FPGA = -O2 -std=c++11 -Wall -L$(common_build) -lfesvr \ 221 | -Wl,-rpath,/usr/local/lib \ 222 | -I $(common)/csrc -I $(testchipip)/csrc \ 223 | -I $(ROCKET_DIR)/riscv-tools/riscv-fesvr/ \ 224 | -Wl,-rpath,/usr/local/lib \ 225 | 226 | $(fesvr-lib): 227 | mkdir -p $(common_build) 228 | cd $(common_build) && \ 229 | $(ROCKET_DIR)/riscv-tools/riscv-fesvr/configure \ 230 | --host=arm-xilinx-linux-gnueabi && \ 231 | make libfesvr.so 232 | 233 | $(common_build)/$(fesvr-main): $(fesvr-lib) $(fesvr-srcs) $(fesvr-hdrs) 234 | $(CXX_FPGA) $(CXXFLAGS_FPGA) -o $(common_build)/$(fesvr-main) $(fesvr-srcs) 235 | 236 | fesvr-zynq: $(common_build)/$(fesvr-main) 237 | 238 | clean: 239 | rm -f *.log *.jou *.str 240 | rm -rf csrc simv-* output ucli.key vc_hdrs.h DVEfiles 241 | 242 | .PHONY: vivado project init-submodules rocket fesvr-zynq fetch-images load-sd ramdisk-open ramdisk-close clean 243 | -------------------------------------------------------------------------------- /zybo/soft_config/zybo_devicetree.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Device Tree for Zybo board 3 | * Partially generated by Device Tree Generator 1.1 4 | * 5 | * (C) Copyright 2007-2013 Xilinx, Inc. 6 | * (C) Copyright 2007-2013 Michal Simek 7 | * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd 8 | * (C) Copyright 2014 Digilent, Inc. 9 | * 10 | * Michal SIMEK 11 | * Tinghui Wang 12 | * Modified for RISC-V Rocket Support by Sagar Karandikar 13 | * 14 | * This program is free software; you can redistribute it and/or 15 | * modify it under the terms of the GNU General Public License as 16 | * published by the Free Software Foundation; either version 2 of 17 | * the License, or (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program; if not, write to the Free Software 26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 27 | * MA 02111-1307 USA 28 | * 29 | */ 30 | 31 | /dts-v1/; 32 | / { 33 | #address-cells = <1>; 34 | #size-cells = <1>; 35 | compatible = "xlnx,zynq-7000"; 36 | model = "Xilinx Zynq"; 37 | aliases { 38 | ethernet0 = &ps7_ethernet_0; 39 | serial0 = &ps7_uart_1; 40 | spi0 = &ps7_qspi_0; 41 | } ; 42 | chosen { 43 | bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk"; 44 | linux,stdout-path = "/amba@0/serial@e0001000"; 45 | } ; 46 | cpus { 47 | #address-cells = <1>; 48 | #size-cells = <0>; 49 | ps7_cortexa9_0: cpu@0 { 50 | bus-handle = <&ps7_axi_interconnect_0>; 51 | clock-latency = <1000>; 52 | clocks = <&clkc 3>; 53 | compatible = "arm,cortex-a9"; 54 | device_type = "cpu"; 55 | interrupt-handle = <&ps7_scugic_0>; 56 | operating-points = <666667 1000000 333334 1000000 222223 1000000>; 57 | reg = <0x0>; 58 | } ; 59 | ps7_cortexa9_1: cpu@1 { 60 | bus-handle = <&ps7_axi_interconnect_0>; 61 | clocks = <&clkc 3>; 62 | compatible = "arm,cortex-a9"; 63 | device_type = "cpu"; 64 | interrupt-handle = <&ps7_scugic_0>; 65 | reg = <0x1>; 66 | } ; 67 | } ; 68 | pmu { 69 | compatible = "arm,cortex-a9-pmu"; 70 | interrupt-parent = <&ps7_scugic_0>; 71 | interrupts = <0 5 4>, <0 6 4>; 72 | reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>; 73 | reg-names = "cpu0", "cpu1"; 74 | } ; 75 | ps7_ddr_0: memory@0 { 76 | device_type = "memory"; 77 | reg = <0x0 0x10000000>; 78 | } ; 79 | 80 | htif_0: htif@43c00000 { 81 | #address-cells = <1>; 82 | #size-cells = <1>; 83 | compatible = "generic-uio", "uio", "uio_pdrv"; 84 | reg = <0x43c00000 0x1000>; 85 | }; 86 | 87 | ps7_axi_interconnect_0: amba@0 { 88 | #address-cells = <1>; 89 | #size-cells = <1>; 90 | compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus"; 91 | ranges ; 92 | ps7_afi_0: ps7-afi@f8008000 { 93 | compatible = "xlnx,ps7-afi-1.00.a"; 94 | reg = <0xf8008000 0x1000>; 95 | } ; 96 | ps7_afi_1: ps7-afi@f8009000 { 97 | compatible = "xlnx,ps7-afi-1.00.a"; 98 | reg = <0xf8009000 0x1000>; 99 | } ; 100 | ps7_afi_2: ps7-afi@f800a000 { 101 | compatible = "xlnx,ps7-afi-1.00.a"; 102 | reg = <0xf800a000 0x1000>; 103 | } ; 104 | ps7_afi_3: ps7-afi@f800b000 { 105 | compatible = "xlnx,ps7-afi-1.00.a"; 106 | reg = <0xf800b000 0x1000>; 107 | } ; 108 | ps7_ddrc_0: ps7-ddrc@f8006000 { 109 | compatible = "xlnx,zynq-ddrc-1.0"; 110 | reg = <0xf8006000 0x1000>; 111 | xlnx,has-ecc = <0x0>; 112 | } ; 113 | ps7_dev_cfg_0: ps7-dev-cfg@f8007000 { 114 | clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; 115 | clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>; 116 | compatible = "xlnx,zynq-devcfg-1.0"; 117 | interrupt-parent = <&ps7_scugic_0>; 118 | interrupts = <0 8 4>; 119 | reg = <0xf8007000 0x100>; 120 | } ; 121 | ps7_dma_s: ps7-dma@f8003000 { 122 | #dma-cells = <1>; 123 | #dma-channels = <8>; 124 | #dma-requests = <4>; 125 | clock-names = "apb_pclk"; 126 | clocks = <&clkc 27>; 127 | compatible = "arm,primecell", "arm,pl330"; 128 | interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", 129 | "dma4", "dma5", "dma6", "dma7"; 130 | interrupt-parent = <&ps7_scugic_0>; 131 | interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>; 132 | reg = <0xf8003000 0x1000>; 133 | } ; 134 | ps7_ethernet_0: ps7-ethernet@e000b000 { 135 | #address-cells = <1>; 136 | #size-cells = <0>; 137 | clock-names = "ref_clk", "aper_clk"; 138 | clocks = <&clkc 13>, <&clkc 30>; 139 | compatible = "xlnx,ps7-ethernet-1.00.a"; 140 | interrupt-parent = <&ps7_scugic_0>; 141 | interrupts = <0 22 4>; 142 | phy-handle = <&phy0>; 143 | phy-mode = "rgmii-id"; 144 | reg = <0xe000b000 0x1000>; 145 | xlnx,eth-mode = <0x1>; 146 | xlnx,has-mdio = <0x1>; 147 | xlnx,ptp-enet-clock = <108333336>; 148 | mdio { 149 | #address-cells = <1>; 150 | #size-cells = <0>; 151 | phy0: phy@1 { 152 | compatible = "realtek,RTL8211E"; 153 | device_type = "ethernet-phy"; 154 | reg = <1>; 155 | } ; 156 | } ; 157 | } ; 158 | ps7_globaltimer_0: ps7-globaltimer@f8f00200 { 159 | clocks = <&clkc 4>; 160 | compatible = "arm,cortex-a9-global-timer"; 161 | interrupt-parent = <&ps7_scugic_0>; 162 | interrupts = <1 11 0x301>; 163 | reg = <0xf8f00200 0x100>; 164 | } ; 165 | ps7_gpio_0: ps7-gpio@e000a000 { 166 | #gpio-cells = <2>; 167 | clocks = <&clkc 42>; 168 | compatible = "xlnx,zynq-gpio-1.0"; 169 | emio-gpio-width = <64>; 170 | gpio-controller ; 171 | gpio-mask-high = <0xc0000>; 172 | gpio-mask-low = <0xfe81>; 173 | interrupt-parent = <&ps7_scugic_0>; 174 | interrupts = <0 20 4>; 175 | reg = <0xe000a000 0x1000>; 176 | } ; 177 | ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 { 178 | compatible = "xlnx,ps7-iop-bus-config-1.00.a"; 179 | reg = <0xe0200000 0x1000>; 180 | } ; 181 | ps7_ocmc_0: ps7-ocmc@f800c000 { 182 | compatible = "xlnx,zynq-ocmc-1.0"; 183 | interrupt-parent = <&ps7_scugic_0>; 184 | interrupts = <0 3 4>; 185 | reg = <0xf800c000 0x1000>; 186 | } ; 187 | ps7_pl310_0: ps7-pl310@f8f02000 { 188 | arm,data-latency = <3 2 2>; 189 | arm,tag-latency = <2 2 2>; 190 | cache-level = <2>; 191 | cache-unified ; 192 | compatible = "arm,pl310-cache"; 193 | interrupt-parent = <&ps7_scugic_0>; 194 | interrupts = <0 2 4>; 195 | reg = <0xf8f02000 0x1000>; 196 | } ; 197 | ps7_qspi_0: ps7-qspi@e000d000 { 198 | clock-names = "ref_clk", "pclk"; 199 | clocks = <&clkc 10>, <&clkc 43>; 200 | compatible = "xlnx,zynq-qspi-1.0"; 201 | interrupt-parent = <&ps7_scugic_0>; 202 | interrupts = <0 19 4>; 203 | is-dual = <0>; 204 | num-cs = <1>; 205 | reg = <0xe000d000 0x1000>; 206 | xlnx,fb-clk = <0x1>; 207 | xlnx,qspi-mode = <0x0>; 208 | #address-cells = <1>; 209 | #size-cells = <0>; 210 | flash@0 { 211 | compatible = "n25q128"; 212 | reg = <0x0>; 213 | spi-tx-bus-width = <1>; 214 | spi-rx-bus-width = <4>; 215 | spi-max-frequency = <50000000>; 216 | #address-cells = <1>; 217 | #size-cells = <1>; 218 | partition@qspi-fsbl-uboot { 219 | label = "qspi-fsbl-uboot"; 220 | reg = <0x0 0x400000>; 221 | }; 222 | partition@qspi-linux { 223 | label = "qspi-linux"; 224 | reg = <0x400000 0x500000>; 225 | }; 226 | partition@qspi-device-tree { 227 | label = "qspi-device-tree"; 228 | reg = <0x900000 0x20000>; 229 | }; 230 | partition@qspi-user { 231 | label = "qspi-user"; 232 | reg = <0x920000 0x6E0000>; 233 | }; 234 | }; 235 | 236 | } ; 237 | ps7_qspi_linear_0: ps7-qspi-linear@fc000000 { 238 | clock-names = "ref_clk", "aper_clk"; 239 | clocks = <&clkc 10>, <&clkc 43>; 240 | compatible = "xlnx,ps7-qspi-linear-1.00.a"; 241 | reg = <0xfc000000 0x1000000>; 242 | } ; 243 | ps7_scugic_0: ps7-scugic@f8f01000 { 244 | #address-cells = <2>; 245 | #interrupt-cells = <3>; 246 | #size-cells = <1>; 247 | compatible = "arm,cortex-a9-gic", "arm,gic"; 248 | interrupt-controller ; 249 | num_cpus = <2>; 250 | num_interrupts = <96>; 251 | reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>; 252 | } ; 253 | ps7_scutimer_0: ps7-scutimer@f8f00600 { 254 | clocks = <&clkc 4>; 255 | compatible = "arm,cortex-a9-twd-timer"; 256 | interrupt-parent = <&ps7_scugic_0>; 257 | interrupts = <1 13 0x301>; 258 | reg = <0xf8f00600 0x20>; 259 | } ; 260 | ps7_scuwdt_0: ps7-scuwdt@f8f00620 { 261 | clocks = <&clkc 4>; 262 | compatible = "xlnx,ps7-scuwdt-1.00.a"; 263 | device_type = "watchdog"; 264 | interrupt-parent = <&ps7_scugic_0>; 265 | interrupts = <1 14 0x301>; 266 | reg = <0xf8f00620 0xe0>; 267 | } ; 268 | ps7_sd_0: ps7-sdio@e0100000 { 269 | clock-frequency = <50000000>; 270 | clock-names = "clk_xin", "clk_ahb"; 271 | clocks = <&clkc 21>, <&clkc 32>; 272 | compatible = "arasan,sdhci-8.9a"; 273 | interrupt-parent = <&ps7_scugic_0>; 274 | interrupts = <0 24 4>; 275 | reg = <0xe0100000 0x1000>; 276 | xlnx,has-cd = <0x1>; 277 | xlnx,has-power = <0x0>; 278 | xlnx,has-wp = <0x1>; 279 | } ; 280 | ps7_slcr_0: ps7-slcr@f8000000 { 281 | #address-cells = <1>; 282 | #size-cells = <1>; 283 | compatible = "xlnx,zynq-slcr", "syscon"; 284 | ranges ; 285 | reg = <0xf8000000 0x1000>; 286 | clkc: clkc@100 { 287 | #clock-cells = <1>; 288 | clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", 289 | "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", 290 | "lqspi", "smc", "pcap", "gem0", "gem1", 291 | "fclk0", "fclk1", "fclk2", "fclk3", "can0", 292 | "can1", "sdio0", "sdio1", "uart0", "uart1", 293 | "spi0", "spi1", "dma", "usb0_aper", "usb1_aper", 294 | "gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper", 295 | "spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", 296 | "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper", 297 | "swdt", "dbg_trc", "dbg_apb"; 298 | compatible = "xlnx,ps7-clkc"; 299 | fclk-enable = <0xf>; 300 | ps-clk-frequency = <50000000>; 301 | reg = <0x100 0x100>; 302 | } ; 303 | } ; 304 | ps7_ttc_0: ps7-ttc@f8001000 { 305 | clocks = <&clkc 6>; 306 | compatible = "cdns,ttc"; 307 | interrupt-names = "ttc0", "ttc1", "ttc2"; 308 | interrupt-parent = <&ps7_scugic_0>; 309 | interrupts = <0 10 4>, <0 11 4>, <0 12 4>; 310 | reg = <0xf8001000 0x1000>; 311 | } ; 312 | ps7_uart_1: serial@e0001000 { 313 | clock-names = "uart_clk", "pclk"; 314 | clocks = <&clkc 24>, <&clkc 41>; 315 | compatible = "xlnx,xuartps", "cdns,uart-r1p8"; 316 | current-speed = <115200>; 317 | device_type = "serial"; 318 | interrupt-parent = <&ps7_scugic_0>; 319 | interrupts = <0 50 4>; 320 | port-number = <0>; 321 | reg = <0xe0001000 0x1000>; 322 | xlnx,has-modem = <0x0>; 323 | } ; 324 | ps7_usb_0: ps7-usb@e0002000 { 325 | clocks = <&clkc 28>; 326 | compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a"; 327 | dr_mode = "host"; 328 | interrupt-parent = <&ps7_scugic_0>; 329 | interrupts = <0 21 4>; 330 | phy_type = "ulpi"; 331 | reg = <0xe0002000 0x1000>; 332 | xlnx,usb-reset = "MIO 46"; 333 | } ; 334 | ps7_xadc: ps7-xadc@f8007100 { 335 | clocks = <&clkc 12>; 336 | compatible = "xlnx,zynq-xadc-1.00.a"; 337 | interrupt-parent = <&ps7_scugic_0>; 338 | interrupts = <0 7 4>; 339 | reg = <0xf8007100 0x20>; 340 | } ; 341 | } ; 342 | } ; 343 | -------------------------------------------------------------------------------- /zedboard/soft_config/zynq-7000.dtsi: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 - 2014 Xilinx 3 | * 4 | * This software is licensed under the terms of the GNU General Public 5 | * License version 2, as published by the Free Software Foundation, and 6 | * may be copied, distributed, and modified under those terms. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | /include/ "skeleton.dtsi" 14 | 15 | / { 16 | compatible = "xlnx,zynq-7000"; 17 | 18 | cpus { 19 | #address-cells = <1>; 20 | #size-cells = <0>; 21 | 22 | cpu@0 { 23 | compatible = "arm,cortex-a9"; 24 | device_type = "cpu"; 25 | reg = <0>; 26 | clocks = <&clkc 3>; 27 | clock-latency = <1000>; 28 | cpu0-supply = <®ulator_vccpint>; 29 | operating-points = < 30 | /* kHz uV */ 31 | 666667 1000000 32 | 333334 1000000 33 | 222223 1000000 34 | >; 35 | }; 36 | 37 | cpu@1 { 38 | compatible = "arm,cortex-a9"; 39 | device_type = "cpu"; 40 | reg = <1>; 41 | clocks = <&clkc 3>; 42 | }; 43 | }; 44 | 45 | pmu { 46 | compatible = "arm,cortex-a9-pmu"; 47 | interrupts = <0 5 4>, <0 6 4>; 48 | interrupt-parent = <&intc>; 49 | reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >; 50 | }; 51 | 52 | regulator_vccpint: fixedregulator@0 { 53 | compatible = "regulator-fixed"; 54 | regulator-name = "VCCPINT"; 55 | regulator-min-microvolt = <1000000>; 56 | regulator-max-microvolt = <1000000>; 57 | regulator-boot-on; 58 | regulator-always-on; 59 | }; 60 | 61 | amba { 62 | compatible = "simple-bus"; 63 | #address-cells = <1>; 64 | #size-cells = <1>; 65 | interrupt-parent = <&intc>; 66 | ranges; 67 | 68 | adc@f8007100 { 69 | compatible = "xlnx,zynq-xadc-1.00.a"; 70 | reg = <0xf8007100 0x20>; 71 | interrupts = <0 7 4>; 72 | interrupt-parent = <&intc>; 73 | clocks = <&clkc 12>; 74 | }; 75 | 76 | can0: can@e0008000 { 77 | compatible = "xlnx,zynq-can-1.0"; 78 | status = "disabled"; 79 | clocks = <&clkc 19>, <&clkc 36>; 80 | clock-names = "ref_clk", "aper_clk"; 81 | reg = <0xe0008000 0x1000>; 82 | interrupts = <0 28 4>; 83 | interrupt-parent = <&intc>; 84 | }; 85 | 86 | can1: can@e0009000 { 87 | compatible = "xlnx,zynq-can-1.0"; 88 | status = "disabled"; 89 | clocks = <&clkc 20>, <&clkc 37>; 90 | clock-names = "ref_clk", "aper_clk"; 91 | reg = <0xe0009000 0x1000>; 92 | interrupts = <0 51 4>; 93 | interrupt-parent = <&intc>; 94 | }; 95 | 96 | gpio0: gpio@e000a000 { 97 | compatible = "xlnx,zynq-gpio-1.0"; 98 | #gpio-cells = <2>; 99 | clocks = <&clkc 42>; 100 | gpio-controller; 101 | interrupt-parent = <&intc>; 102 | interrupts = <0 20 4>; 103 | reg = <0xe000a000 0x1000>; 104 | }; 105 | 106 | i2c0: i2c@e0004000 { 107 | compatible = "cdns,i2c-r1p10"; 108 | status = "disabled"; 109 | clocks = <&clkc 38>; 110 | interrupt-parent = <&intc>; 111 | interrupts = <0 25 4>; 112 | reg = <0xe0004000 0x1000>; 113 | #address-cells = <1>; 114 | #size-cells = <0>; 115 | }; 116 | 117 | i2c1: i2c@e0005000 { 118 | compatible = "cdns,i2c-r1p10"; 119 | status = "disabled"; 120 | clocks = <&clkc 39>; 121 | interrupt-parent = <&intc>; 122 | interrupts = <0 48 4>; 123 | reg = <0xe0005000 0x1000>; 124 | #address-cells = <1>; 125 | #size-cells = <0>; 126 | }; 127 | 128 | intc: interrupt-controller@f8f01000 { 129 | compatible = "arm,cortex-a9-gic"; 130 | #interrupt-cells = <3>; 131 | interrupt-controller; 132 | reg = <0xF8F01000 0x1000>, 133 | <0xF8F00100 0x100>; 134 | }; 135 | 136 | L2: cache-controller { 137 | compatible = "arm,pl310-cache"; 138 | reg = <0xF8F02000 0x1000>; 139 | arm,data-latency = <3 2 2>; 140 | arm,tag-latency = <2 2 2>; 141 | cache-unified; 142 | cache-level = <2>; 143 | }; 144 | 145 | memory-controller@f8006000 { 146 | compatible = "xlnx,zynq-ddrc-1.0"; 147 | reg = <0xf8006000 0x1000>; 148 | xlnx,has-ecc = <0x0>; 149 | }; 150 | 151 | ocmc: ocmc@f800c000 { 152 | compatible = "xlnx,zynq-ocmc-1.0"; 153 | interrupt-parent = <&intc>; 154 | interrupts = <0 3 4>; 155 | reg = <0xf800c000 0x1000>; 156 | }; 157 | 158 | uart0: serial@e0000000 { 159 | compatible = "xlnx,xuartps"; 160 | status = "disabled"; 161 | clocks = <&clkc 23>, <&clkc 40>; 162 | clock-names = "ref_clk", "aper_clk"; 163 | reg = <0xE0000000 0x1000>; 164 | interrupts = <0 27 4>; 165 | }; 166 | 167 | uart1: serial@e0001000 { 168 | compatible = "xlnx,xuartps"; 169 | status = "disabled"; 170 | clocks = <&clkc 24>, <&clkc 41>; 171 | clock-names = "ref_clk", "aper_clk"; 172 | reg = <0xE0001000 0x1000>; 173 | interrupts = <0 50 4>; 174 | }; 175 | 176 | spi0: spi@e0006000 { 177 | compatible = "xlnx,zynq-spi-r1p6"; 178 | reg = <0xe0006000 0x1000>; 179 | status = "disabled"; 180 | interrupt-parent = <&intc>; 181 | interrupts = <0 26 4>; 182 | clocks = <&clkc 25>, <&clkc 34>; 183 | clock-names = "ref_clk", "pclk"; 184 | #address-cells = <1>; 185 | #size-cells = <0>; 186 | }; 187 | 188 | spi1: spi@e0007000 { 189 | compatible = "xlnx,zynq-spi-r1p6"; 190 | reg = <0xe0007000 0x1000>; 191 | status = "disabled"; 192 | interrupt-parent = <&intc>; 193 | interrupts = <0 49 4>; 194 | clocks = <&clkc 26>, <&clkc 35>; 195 | clock-names = "ref_clk", "pclk"; 196 | #address-cells = <1>; 197 | #size-cells = <0>; 198 | }; 199 | 200 | qspi: spi@e000d000 { 201 | clock-names = "ref_clk", "pclk"; 202 | clocks = <&clkc 10>, <&clkc 43>; 203 | compatible = "xlnx,zynq-qspi-1.0"; 204 | status = "disabled"; 205 | interrupt-parent = <&intc>; 206 | interrupts = <0 19 4>; 207 | reg = <0xe000d000 0x1000>; 208 | #address-cells = <1>; 209 | #size-cells = <0>; 210 | }; 211 | 212 | smcc: memory-controller@e000e000 { 213 | #address-cells = <1>; 214 | #size-cells = <1>; 215 | status = "disabled"; 216 | clock-names = "memclk", "aclk"; 217 | clocks = <&clkc 11>, <&clkc 44>; 218 | compatible = "arm,pl353-smc-r2p1"; 219 | interrupt-parent = <&intc>; 220 | interrupts = <0 18 4>; 221 | ranges ; 222 | reg = <0xe000e000 0x1000>; 223 | nand0: flash@e1000000 { 224 | status = "disabled"; 225 | compatible = "arm,pl353-nand-r2p1"; 226 | reg = <0xe1000000 0x1000000>; 227 | #address-cells = <0x1>; 228 | #size-cells = <0x1>; 229 | }; 230 | nor0: flash@e2000000 { 231 | status = "disabled"; 232 | compatible = "cfi-flash"; 233 | reg = <0xe2000000 0x1000>; 234 | #address-cells = <1>; 235 | #size-cells = <1>; 236 | }; 237 | }; 238 | 239 | gem0: ethernet@e000b000 { 240 | compatible = "cdns,gem"; 241 | reg = <0xe000b000 0x4000>; 242 | status = "disabled"; 243 | interrupts = <0 22 4>; 244 | clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>; 245 | clock-names = "pclk", "hclk", "tx_clk"; 246 | #address-cells = <1>; 247 | #size-cells = <0>; 248 | }; 249 | 250 | gem1: ethernet@e000c000 { 251 | compatible = "cdns,gem"; 252 | reg = <0xe000c000 0x4000>; 253 | status = "disabled"; 254 | interrupts = <0 45 4>; 255 | clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>; 256 | clock-names = "pclk", "hclk", "tx_clk"; 257 | #address-cells = <1>; 258 | #size-cells = <0>; 259 | }; 260 | 261 | sdhci0: sdhci@e0100000 { 262 | compatible = "arasan,sdhci-8.9a"; 263 | status = "disabled"; 264 | clock-names = "clk_xin", "clk_ahb"; 265 | clocks = <&clkc 21>, <&clkc 32>; 266 | interrupt-parent = <&intc>; 267 | interrupts = <0 24 4>; 268 | reg = <0xe0100000 0x1000>; 269 | }; 270 | 271 | sdhci1: sdhci@e0101000 { 272 | compatible = "arasan,sdhci-8.9a"; 273 | status = "disabled"; 274 | clock-names = "clk_xin", "clk_ahb"; 275 | clocks = <&clkc 22>, <&clkc 33>; 276 | interrupt-parent = <&intc>; 277 | interrupts = <0 47 4>; 278 | reg = <0xe0101000 0x1000>; 279 | }; 280 | 281 | slcr: slcr@f8000000 { 282 | #address-cells = <1>; 283 | #size-cells = <1>; 284 | compatible = "xlnx,zynq-slcr", "syscon"; 285 | reg = <0xF8000000 0x1000>; 286 | ranges; 287 | clkc: clkc@100 { 288 | #clock-cells = <1>; 289 | compatible = "xlnx,ps7-clkc"; 290 | ps-clk-frequency = <33333333>; 291 | fclk-enable = <0>; 292 | clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", 293 | "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", 294 | "dci", "lqspi", "smc", "pcap", "gem0", "gem1", 295 | "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", 296 | "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", 297 | "dma", "usb0_aper", "usb1_aper", "gem0_aper", 298 | "gem1_aper", "sdio0_aper", "sdio1_aper", 299 | "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", 300 | "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", 301 | "gpio_aper", "lqspi_aper", "smc_aper", "swdt", 302 | "dbg_trc", "dbg_apb"; 303 | reg = <0x100 0x100>; 304 | }; 305 | }; 306 | 307 | dmac_s: dmac@f8003000 { 308 | compatible = "arm,pl330", "arm,primecell"; 309 | reg = <0xf8003000 0x1000>; 310 | interrupt-parent = <&intc>; 311 | interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", 312 | "dma4", "dma5", "dma6", "dma7"; 313 | interrupts = <0 13 4>, 314 | <0 14 4>, <0 15 4>, 315 | <0 16 4>, <0 17 4>, 316 | <0 40 4>, <0 41 4>, 317 | <0 42 4>, <0 43 4>; 318 | #dma-cells = <1>; 319 | #dma-channels = <8>; 320 | #dma-requests = <4>; 321 | clocks = <&clkc 27>; 322 | clock-names = "apb_pclk"; 323 | }; 324 | 325 | devcfg: devcfg@f8007000 { 326 | clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; 327 | clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>; 328 | compatible = "xlnx,zynq-devcfg-1.0"; 329 | interrupt-parent = <&intc>; 330 | interrupts = <0 8 4>; 331 | reg = <0xf8007000 0x100>; 332 | }; 333 | 334 | global_timer: timer@f8f00200 { 335 | compatible = "arm,cortex-a9-global-timer"; 336 | reg = <0xf8f00200 0x20>; 337 | interrupts = <1 11 0x301>; 338 | interrupt-parent = <&intc>; 339 | clocks = <&clkc 4>; 340 | }; 341 | 342 | ttc0: timer@f8001000 { 343 | interrupt-parent = <&intc>; 344 | interrupts = <0 10 4>, <0 11 4>, <0 12 4>; 345 | compatible = "cdns,ttc"; 346 | clocks = <&clkc 6>; 347 | reg = <0xF8001000 0x1000>; 348 | }; 349 | 350 | ttc1: timer@f8002000 { 351 | interrupt-parent = <&intc>; 352 | interrupts = <0 37 4>, <0 38 4>, <0 39 4>; 353 | compatible = "cdns,ttc"; 354 | clocks = <&clkc 6>; 355 | reg = <0xF8002000 0x1000>; 356 | }; 357 | 358 | scutimer: timer@f8f00600 { 359 | interrupt-parent = <&intc>; 360 | interrupts = <1 13 0x301>; 361 | compatible = "arm,cortex-a9-twd-timer"; 362 | reg = <0xf8f00600 0x20>; 363 | clocks = <&clkc 4>; 364 | }; 365 | 366 | watchdog0: watchdog@f8005000 { 367 | clocks = <&clkc 45>; 368 | compatible = "xlnx,zynq-wdt-r1p2"; 369 | device_type = "watchdog"; 370 | interrupt-parent = <&intc>; 371 | interrupts = <0 9 1>; 372 | reg = <0xf8005000 0x1000>; 373 | reset = <0>; 374 | timeout-sec = <10>; 375 | }; 376 | 377 | scuwatchdog: watchdog@f8f00620 { 378 | clocks = <&clkc 4>; 379 | compatible = "xlnx,ps7-scuwdt-1.00.a"; 380 | device_type = "watchdog"; 381 | interrupt-parent = <&intc>; 382 | interrupts = <1 14 0x301>; 383 | reg = <0xf8f00620 0xe0>; 384 | }; 385 | 386 | usb0: usb@e0002000 { 387 | clocks = <&clkc 28>; 388 | compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a"; 389 | status = "disabled"; 390 | interrupt-parent = <&intc>; 391 | interrupts = <0 21 4>; 392 | reg = <0xe0002000 0x1000>; 393 | }; 394 | 395 | usb1: usb@e0003000 { 396 | clocks = <&clkc 29>; 397 | compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a"; 398 | status = "disabled"; 399 | interrupt-parent = <&intc>; 400 | interrupts = <0 44 4>; 401 | reg = <0xe0003000 0x1000>; 402 | }; 403 | }; 404 | }; 405 | -------------------------------------------------------------------------------- /zc706/soft_config/zc706_devicetree.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Device Tree Generator version: 1.1 3 | * 4 | * (C) Copyright 2007-2013 Xilinx, Inc. 5 | * (C) Copyright 2007-2013 Michal Simek 6 | * (C) Copyright 2007-2012 PetaLogix Qld Pty Ltd 7 | * 8 | * Michal SIMEK 9 | * Modified for RISC-V Rocket Support by Sagar Karandikar 10 | * 11 | * CAUTION: This file is automatically generated by libgen. 12 | * Version: Xilinx EDK 14.5 EDK_P.58f 13 | * 14 | */ 15 | 16 | /dts-v1/; 17 | / { 18 | #address-cells = <1>; 19 | #size-cells = <1>; 20 | compatible = "xlnx,zynq-7000"; 21 | model = "Xilinx Zynq"; 22 | aliases { 23 | ethernet0 = &ps7_ethernet_0; 24 | i2c0 = &ps7_i2c_0; 25 | serial0 = &ps7_uart_1; 26 | spi0 = &ps7_qspi_0; 27 | } ; 28 | chosen { 29 | bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk"; 30 | linux,stdout-path = "/amba@0/serial@e0001000"; 31 | } ; 32 | cpus { 33 | #address-cells = <1>; 34 | #size-cells = <0>; 35 | ps7_cortexa9_0: cpu@0 { 36 | bus-handle = <&ps7_axi_interconnect_0>; 37 | clock-latency = <1000>; 38 | clocks = <&clkc 3>; 39 | compatible = "arm,cortex-a9"; 40 | device_type = "cpu"; 41 | interrupt-handle = <&ps7_scugic_0>; 42 | operating-points = <666667 1000000 333334 1000000 222223 1000000>; 43 | reg = <0x0>; 44 | } ; 45 | ps7_cortexa9_1: cpu@1 { 46 | bus-handle = <&ps7_axi_interconnect_0>; 47 | clocks = <&clkc 3>; 48 | compatible = "arm,cortex-a9"; 49 | device_type = "cpu"; 50 | interrupt-handle = <&ps7_scugic_0>; 51 | reg = <0x1>; 52 | } ; 53 | } ; 54 | pmu { 55 | compatible = "arm,cortex-a9-pmu"; 56 | interrupt-parent = <&ps7_scugic_0>; 57 | interrupts = <0 5 4>, <0 6 4>; 58 | reg = <0xf8891000 0x1000>, <0xf8893000 0x1000>; 59 | reg-names = "cpu0", "cpu1"; 60 | } ; 61 | ps7_ddr_0: memory@0 { 62 | device_type = "memory"; 63 | reg = <0x0 0x10000000>; 64 | } ; 65 | 66 | htif_0: htif@43c00000 { 67 | #address-cells = <1>; 68 | #size-cells = <1>; 69 | compatible = "generic-uio", "uio", "uio_pdrv"; 70 | reg = <0x43c00000 0x1000>; 71 | }; 72 | 73 | ps7_axi_interconnect_0: amba@0 { 74 | #address-cells = <1>; 75 | #size-cells = <1>; 76 | compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus"; 77 | ranges ; 78 | ps7_afi_0: ps7-afi@f8008000 { 79 | compatible = "xlnx,ps7-afi-1.00.a"; 80 | reg = <0xf8008000 0x1000>; 81 | } ; 82 | ps7_afi_1: ps7-afi@f8009000 { 83 | compatible = "xlnx,ps7-afi-1.00.a"; 84 | reg = <0xf8009000 0x1000>; 85 | } ; 86 | ps7_afi_2: ps7-afi@f800a000 { 87 | compatible = "xlnx,ps7-afi-1.00.a"; 88 | reg = <0xf800a000 0x1000>; 89 | } ; 90 | ps7_afi_3: ps7-afi@f800b000 { 91 | compatible = "xlnx,ps7-afi-1.00.a"; 92 | reg = <0xf800b000 0x1000>; 93 | } ; 94 | ps7_ddrc_0: ps7-ddrc@f8006000 { 95 | compatible = "xlnx,zynq-ddrc-1.0"; 96 | reg = <0xf8006000 0x1000>; 97 | xlnx,has-ecc = <0x0>; 98 | } ; 99 | ps7_dev_cfg_0: ps7-dev-cfg@f8007000 { 100 | clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; 101 | clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>; 102 | compatible = "xlnx,zynq-devcfg-1.0"; 103 | interrupt-parent = <&ps7_scugic_0>; 104 | interrupts = <0 8 4>; 105 | reg = <0xf8007000 0x100>; 106 | } ; 107 | ps7_dma_s: ps7-dma@f8003000 { 108 | #dma-cells = <1>; 109 | #dma-channels = <8>; 110 | #dma-requests = <4>; 111 | clock-names = "apb_pclk"; 112 | clocks = <&clkc 27>; 113 | compatible = "arm,primecell", "arm,pl330"; 114 | interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", 115 | "dma4", "dma5", "dma6", "dma7"; 116 | interrupt-parent = <&ps7_scugic_0>; 117 | interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>; 118 | reg = <0xf8003000 0x1000>; 119 | } ; 120 | ps7_ethernet_0: ps7-ethernet@e000b000 { 121 | #address-cells = <1>; 122 | #size-cells = <0>; 123 | clock-names = "ref_clk", "aper_clk"; 124 | clocks = <&clkc 13>, <&clkc 30>; 125 | compatible = "xlnx,ps7-ethernet-1.00.a"; 126 | enet-reset = <&ps7_gpio_0 47 0>; 127 | interrupt-parent = <&ps7_scugic_0>; 128 | interrupts = <0 22 4>; 129 | local-mac-address = [00 0a 35 00 00 00]; 130 | phy-handle = <&phy0>; 131 | phy-mode = "rgmii-id"; 132 | reg = <0xe000b000 0x1000>; 133 | xlnx,eth-mode = <0x1>; 134 | xlnx,has-mdio = <0x1>; 135 | xlnx,ptp-enet-clock = <111111115>; 136 | mdio { 137 | #address-cells = <1>; 138 | #size-cells = <0>; 139 | phy0: phy@7 { 140 | compatible = "marvell,88e1116r"; 141 | device_type = "ethernet-phy"; 142 | reg = <7>; 143 | } ; 144 | } ; 145 | } ; 146 | ps7_globaltimer_0: ps7-globaltimer@f8f00200 { 147 | clocks = <&clkc 4>; 148 | compatible = "arm,cortex-a9-global-timer"; 149 | interrupt-parent = <&ps7_scugic_0>; 150 | interrupts = <1 11 0x301>; 151 | reg = <0xf8f00200 0x100>; 152 | } ; 153 | ps7_gpio_0: ps7-gpio@e000a000 { 154 | #gpio-cells = <2>; 155 | clocks = <&clkc 42>; 156 | compatible = "xlnx,zynq-gpio-1.0"; 157 | emio-gpio-width = <64>; 158 | gpio-controller ; 159 | gpio-mask-high = <0x0>; 160 | gpio-mask-low = <0x0>; 161 | interrupt-parent = <&ps7_scugic_0>; 162 | interrupts = <0 20 4>; 163 | reg = <0xe000a000 0x1000>; 164 | } ; 165 | ps7_i2c_0: ps7-i2c@e0004000 { 166 | clock-frequency = <400000>; 167 | clocks = <&clkc 38>; 168 | compatible = "cdns,i2c-r1p10"; 169 | i2c-reset = <&ps7_gpio_0 46 0>; 170 | interrupt-parent = <&ps7_scugic_0>; 171 | interrupts = <0 25 4>; 172 | reg = <0xe0004000 0x1000>; 173 | xlnx,has-interrupt = <0x0>; 174 | #address-cells = <1>; 175 | #size-cells = <0>; 176 | i2cswitch@74 { 177 | compatible = "nxp,pca9548"; 178 | #address-cells = <1>; 179 | #size-cells = <0>; 180 | reg = <0x74>; 181 | 182 | i2c@0 { 183 | #address-cells = <1>; 184 | #size-cells = <0>; 185 | reg = <0>; 186 | si570: clock-generator@5d { 187 | #clock-cells = <0>; 188 | compatible = "silabs,si570"; 189 | temperature-stability = <50>; 190 | reg = <0x5d>; 191 | factory-fout = <156250000>; 192 | clock-frequency = <148500000>; 193 | }; 194 | }; 195 | 196 | i2c@2 { 197 | #address-cells = <1>; 198 | #size-cells = <0>; 199 | reg = <2>; 200 | eeprom@54 { 201 | compatible = "at,24c08"; 202 | reg = <0x54>; 203 | }; 204 | }; 205 | 206 | i2c@3 { 207 | #address-cells = <1>; 208 | #size-cells = <0>; 209 | reg = <3>; 210 | gpio@21 { 211 | compatible = "ti,tca6416"; 212 | reg = <0x21>; 213 | gpio-controller; 214 | #gpio-cells = <2>; 215 | }; 216 | }; 217 | 218 | i2c@4 { 219 | #address-cells = <1>; 220 | #size-cells = <0>; 221 | reg = <4>; 222 | rtc@51 { 223 | compatible = "nxp,pcf8563"; 224 | reg = <0x51>; 225 | }; 226 | }; 227 | 228 | 229 | i2c@7 { 230 | #address-cells = <1>; 231 | #size-cells = <0>; 232 | reg = <7>; 233 | ucd90120@65 { 234 | compatible = "ti,ucd90120"; 235 | reg = <0x65>; 236 | }; 237 | }; 238 | }; 239 | 240 | } ; 241 | ps7_iop_bus_config_0: ps7-iop-bus-config@e0200000 { 242 | compatible = "xlnx,ps7-iop-bus-config-1.00.a"; 243 | reg = <0xe0200000 0x1000>; 244 | } ; 245 | ps7_ocmc_0: ps7-ocmc@f800c000 { 246 | compatible = "xlnx,zynq-ocmc-1.0"; 247 | interrupt-parent = <&ps7_scugic_0>; 248 | interrupts = <0 3 4>; 249 | reg = <0xf800c000 0x1000>; 250 | } ; 251 | ps7_pl310_0: ps7-pl310@f8f02000 { 252 | arm,data-latency = <3 2 2>; 253 | arm,tag-latency = <2 2 2>; 254 | cache-level = <2>; 255 | cache-unified ; 256 | compatible = "arm,pl310-cache"; 257 | interrupt-parent = <&ps7_scugic_0>; 258 | interrupts = <0 2 4>; 259 | reg = <0xf8f02000 0x1000>; 260 | } ; 261 | ps7_qspi_0: ps7-qspi@e000d000 { 262 | clock-names = "ref_clk", "pclk"; 263 | clocks = <&clkc 10>, <&clkc 43>; 264 | compatible = "xlnx,zynq-qspi-1.0"; 265 | interrupt-parent = <&ps7_scugic_0>; 266 | interrupts = <0 19 4>; 267 | is-dual = <1>; 268 | num-cs = <1>; 269 | reg = <0xe000d000 0x1000>; 270 | xlnx,fb-clk = <0x1>; 271 | xlnx,qspi-mode = <0x2>; 272 | #address-cells = <1>; 273 | #size-cells = <0>; 274 | flash@0 { 275 | compatible = "n25q128"; 276 | reg = <0x0>; 277 | spi-tx-bus-width = <1>; 278 | spi-rx-bus-width = <4>; 279 | spi-max-frequency = <50000000>; 280 | #address-cells = <1>; 281 | #size-cells = <1>; 282 | partition@qspi-fsbl-uboot { 283 | label = "qspi-fsbl-uboot"; 284 | reg = <0x0 0x100000>; 285 | }; 286 | partition@qspi-linux { 287 | label = "qspi-linux"; 288 | reg = <0x100000 0x500000>; 289 | }; 290 | partition@qspi-device-tree { 291 | label = "qspi-device-tree"; 292 | reg = <0x600000 0x20000>; 293 | }; 294 | partition@qspi-rootfs { 295 | label = "qspi-rootfs"; 296 | reg = <0x620000 0x5E0000>; 297 | }; 298 | partition@qspi-bitstream { 299 | label = "qspi-bitstream"; 300 | reg = <0xC00000 0x400000>; 301 | }; 302 | }; 303 | 304 | } ; 305 | ps7_qspi_linear_0: ps7-qspi-linear@fc000000 { 306 | clock-names = "ref_clk", "aper_clk"; 307 | clocks = <&clkc 10>, <&clkc 43>; 308 | compatible = "xlnx,ps7-qspi-linear-1.00.a"; 309 | reg = <0xfc000000 0x2000000>; 310 | } ; 311 | ps7_scugic_0: ps7-scugic@f8f01000 { 312 | #address-cells = <2>; 313 | #interrupt-cells = <3>; 314 | #size-cells = <1>; 315 | compatible = "arm,cortex-a9-gic", "arm,gic"; 316 | interrupt-controller ; 317 | num_cpus = <2>; 318 | num_interrupts = <96>; 319 | reg = <0xf8f01000 0x1000>, <0xf8f00100 0x100>; 320 | } ; 321 | ps7_scutimer_0: ps7-scutimer@f8f00600 { 322 | clocks = <&clkc 4>; 323 | compatible = "arm,cortex-a9-twd-timer"; 324 | interrupt-parent = <&ps7_scugic_0>; 325 | interrupts = <1 13 0x301>; 326 | reg = <0xf8f00600 0x20>; 327 | } ; 328 | ps7_scuwdt_0: ps7-scuwdt@f8f00620 { 329 | clocks = <&clkc 4>; 330 | compatible = "xlnx,ps7-scuwdt-1.00.a"; 331 | device_type = "watchdog"; 332 | interrupt-parent = <&ps7_scugic_0>; 333 | interrupts = <1 14 0x301>; 334 | reg = <0xf8f00620 0xe0>; 335 | } ; 336 | ps7_sd_0: ps7-sdio@e0100000 { 337 | clock-frequency = <50000000>; 338 | clock-names = "clk_xin", "clk_ahb"; 339 | clocks = <&clkc 21>, <&clkc 32>; 340 | compatible = "arasan,sdhci-8.9a"; 341 | interrupt-parent = <&ps7_scugic_0>; 342 | interrupts = <0 24 4>; 343 | reg = <0xe0100000 0x1000>; 344 | xlnx,has-cd = <0x1>; 345 | xlnx,has-power = <0x0>; 346 | xlnx,has-wp = <0x1>; 347 | } ; 348 | ps7_slcr_0: ps7-slcr@f8000000 { 349 | #address-cells = <1>; 350 | #size-cells = <1>; 351 | compatible = "xlnx,zynq-slcr", "syscon"; 352 | ranges ; 353 | reg = <0xf8000000 0x1000>; 354 | clkc: clkc@100 { 355 | #clock-cells = <1>; 356 | clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", 357 | "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", 358 | "lqspi", "smc", "pcap", "gem0", "gem1", 359 | "fclk0", "fclk1", "fclk2", "fclk3", "can0", 360 | "can1", "sdio0", "sdio1", "uart0", "uart1", 361 | "spi0", "spi1", "dma", "usb0_aper", "usb1_aper", 362 | "gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper", 363 | "spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", 364 | "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper", 365 | "swdt", "dbg_trc", "dbg_apb"; 366 | compatible = "xlnx,ps7-clkc"; 367 | fclk-enable = <0xf>; 368 | ps-clk-frequency = <33333333>; 369 | reg = <0x100 0x100>; 370 | } ; 371 | } ; 372 | ps7_ttc_0: ps7-ttc@f8001000 { 373 | clocks = <&clkc 6>; 374 | compatible = "cdns,ttc"; 375 | interrupt-names = "ttc0", "ttc1", "ttc2"; 376 | interrupt-parent = <&ps7_scugic_0>; 377 | interrupts = <0 10 4>, <0 11 4>, <0 12 4>; 378 | reg = <0xf8001000 0x1000>; 379 | } ; 380 | ps7_ttc_1: ps7-ttc@f8002000 { 381 | clocks = <&clkc 6>; 382 | compatible = "cdns,ttc"; 383 | interrupt-names = "ttc0", "ttc1", "ttc2"; 384 | interrupt-parent = <&ps7_scugic_0>; 385 | interrupts = <0 37 4>, <0 38 4>, <0 39 4>; 386 | reg = <0xf8002000 0x1000>; 387 | } ; 388 | ps7_uart_1: serial@e0001000 { 389 | clock-names = "uart_clk", "pclk"; 390 | clocks = <&clkc 24>, <&clkc 41>; 391 | compatible = "xlnx,xuartps", "cdns,uart-r1p8"; 392 | current-speed = <115200>; 393 | device_type = "serial"; 394 | interrupt-parent = <&ps7_scugic_0>; 395 | interrupts = <0 50 4>; 396 | port-number = <0>; 397 | reg = <0xe0001000 0x1000>; 398 | xlnx,has-modem = <0x0>; 399 | } ; 400 | ps7_usb_0: ps7-usb@e0002000 { 401 | clocks = <&clkc 28>; 402 | compatible = "xlnx,ps7-usb-1.00.a", "xlnx,zynq-usb-1.00.a"; 403 | dr_mode = "host"; 404 | interrupt-parent = <&ps7_scugic_0>; 405 | interrupts = <0 21 4>; 406 | phy_type = "ulpi"; 407 | reg = <0xe0002000 0x1000>; 408 | usb-reset = <&ps7_gpio_0 7 0>; 409 | } ; 410 | ps7_wdt_0: ps7-wdt@f8005000 { 411 | clocks = <&clkc 45>; 412 | compatible = "xlnx,zynq-wdt-r1p2"; 413 | device_type = "watchdog"; 414 | interrupt-parent = <&ps7_scugic_0>; 415 | interrupts = <0 9 1>; 416 | reg = <0xf8005000 0x1000>; 417 | reset = <0>; 418 | timeout-sec = <10>; 419 | } ; 420 | ps7_xadc: ps7-xadc@f8007100 { 421 | clocks = <&clkc 12>; 422 | compatible = "xlnx,zynq-xadc-1.00.a"; 423 | interrupt-parent = <&ps7_scugic_0>; 424 | interrupts = <0 7 4>; 425 | reg = <0xf8007100 0x20>; 426 | } ; 427 | } ; 428 | } ; 429 | -------------------------------------------------------------------------------- /common/rocketchip_wrapper.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ps / 1 ps 2 | `include "clocking.vh" 3 | 4 | module rocketchip_wrapper 5 | (DDR_addr, 6 | DDR_ba, 7 | DDR_cas_n, 8 | DDR_ck_n, 9 | DDR_ck_p, 10 | DDR_cke, 11 | DDR_cs_n, 12 | DDR_dm, 13 | DDR_dq, 14 | DDR_dqs_n, 15 | DDR_dqs_p, 16 | DDR_odt, 17 | DDR_ras_n, 18 | DDR_reset_n, 19 | DDR_we_n, 20 | FIXED_IO_ddr_vrn, 21 | FIXED_IO_ddr_vrp, 22 | FIXED_IO_mio, 23 | FIXED_IO_ps_clk, 24 | FIXED_IO_ps_porb, 25 | FIXED_IO_ps_srstb, 26 | `ifndef differential_clock 27 | clk); 28 | `else 29 | SYSCLK_P, 30 | SYSCLK_N); 31 | `endif 32 | 33 | inout [14:0]DDR_addr; 34 | inout [2:0]DDR_ba; 35 | inout DDR_cas_n; 36 | inout DDR_ck_n; 37 | inout DDR_ck_p; 38 | inout DDR_cke; 39 | inout DDR_cs_n; 40 | inout [3:0]DDR_dm; 41 | inout [31:0]DDR_dq; 42 | inout [3:0]DDR_dqs_n; 43 | inout [3:0]DDR_dqs_p; 44 | inout DDR_odt; 45 | inout DDR_ras_n; 46 | inout DDR_reset_n; 47 | inout DDR_we_n; 48 | 49 | inout FIXED_IO_ddr_vrn; 50 | inout FIXED_IO_ddr_vrp; 51 | inout [53:0]FIXED_IO_mio; 52 | inout FIXED_IO_ps_clk; 53 | inout FIXED_IO_ps_porb; 54 | inout FIXED_IO_ps_srstb; 55 | 56 | `ifndef differential_clock 57 | input clk; 58 | `else 59 | input SYSCLK_P; 60 | input SYSCLK_N; 61 | `endif 62 | 63 | wire FCLK_RESET0_N; 64 | 65 | wire [31:0]M_AXI_araddr; 66 | wire [1:0]M_AXI_arburst; 67 | wire [7:0]M_AXI_arlen; 68 | wire M_AXI_arready; 69 | wire [2:0]M_AXI_arsize; 70 | wire M_AXI_arvalid; 71 | wire [31:0]M_AXI_awaddr; 72 | wire [1:0]M_AXI_awburst; 73 | wire [7:0]M_AXI_awlen; 74 | wire [3:0]M_AXI_wstrb; 75 | wire M_AXI_awready; 76 | wire [2:0]M_AXI_awsize; 77 | wire M_AXI_awvalid; 78 | wire M_AXI_bready; 79 | wire M_AXI_bvalid; 80 | wire [31:0]M_AXI_rdata; 81 | wire M_AXI_rlast; 82 | wire M_AXI_rready; 83 | wire M_AXI_rvalid; 84 | wire [31:0]M_AXI_wdata; 85 | wire M_AXI_wlast; 86 | wire M_AXI_wready; 87 | wire M_AXI_wvalid; 88 | wire [11:0] M_AXI_arid, M_AXI_awid; // outputs from ARM core 89 | wire [11:0] M_AXI_bid, M_AXI_rid; // inputs to ARM core 90 | 91 | wire S_AXI_arready; 92 | wire S_AXI_arvalid; 93 | wire [31:0] S_AXI_araddr; 94 | wire [5:0] S_AXI_arid; 95 | wire [2:0] S_AXI_arsize; 96 | wire [7:0] S_AXI_arlen; 97 | wire [1:0] S_AXI_arburst; 98 | wire S_AXI_arlock; 99 | wire [3:0] S_AXI_arcache; 100 | wire [2:0] S_AXI_arprot; 101 | wire [3:0] S_AXI_arqos; 102 | //wire [3:0] S_AXI_arregion; 103 | 104 | wire S_AXI_awready; 105 | wire S_AXI_awvalid; 106 | wire [31:0] S_AXI_awaddr; 107 | wire [5:0] S_AXI_awid; 108 | wire [2:0] S_AXI_awsize; 109 | wire [7:0] S_AXI_awlen; 110 | wire [1:0] S_AXI_awburst; 111 | wire S_AXI_awlock; 112 | wire [3:0] S_AXI_awcache; 113 | wire [2:0] S_AXI_awprot; 114 | wire [3:0] S_AXI_awqos; 115 | //wire [3:0] S_AXI_awregion; 116 | 117 | wire S_AXI_wready; 118 | wire S_AXI_wvalid; 119 | wire [7:0] S_AXI_wstrb; 120 | wire [63:0] S_AXI_wdata; 121 | wire S_AXI_wlast; 122 | 123 | wire S_AXI_bready; 124 | wire S_AXI_bvalid; 125 | wire [1:0] S_AXI_bresp; 126 | wire [5:0] S_AXI_bid; 127 | 128 | wire S_AXI_rready; 129 | wire S_AXI_rvalid; 130 | wire [1:0] S_AXI_rresp; 131 | wire [5:0] S_AXI_rid; 132 | wire [63:0] S_AXI_rdata; 133 | wire S_AXI_rlast; 134 | 135 | wire reset, reset_cpu; 136 | wire host_clk; 137 | wire gclk_i, gclk_fbout, host_clk_i, mmcm_locked; 138 | 139 | system system_i 140 | (.DDR_addr(DDR_addr), 141 | .DDR_ba(DDR_ba), 142 | .DDR_cas_n(DDR_cas_n), 143 | .DDR_ck_n(DDR_ck_n), 144 | .DDR_ck_p(DDR_ck_p), 145 | .DDR_cke(DDR_cke), 146 | .DDR_cs_n(DDR_cs_n), 147 | .DDR_dm(DDR_dm), 148 | .DDR_dq(DDR_dq), 149 | .DDR_dqs_n(DDR_dqs_n), 150 | .DDR_dqs_p(DDR_dqs_p), 151 | .DDR_odt(DDR_odt), 152 | .DDR_ras_n(DDR_ras_n), 153 | .DDR_reset_n(DDR_reset_n), 154 | .DDR_we_n(DDR_we_n), 155 | .FCLK_RESET0_N(FCLK_RESET0_N), 156 | .FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn), 157 | .FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp), 158 | .FIXED_IO_mio(FIXED_IO_mio), 159 | .FIXED_IO_ps_clk(FIXED_IO_ps_clk), 160 | .FIXED_IO_ps_porb(FIXED_IO_ps_porb), 161 | .FIXED_IO_ps_srstb(FIXED_IO_ps_srstb), 162 | // master AXI interface (zynq = master, fpga = slave) 163 | .M_AXI_araddr(M_AXI_araddr), 164 | .M_AXI_arburst(M_AXI_arburst), // burst type 165 | .M_AXI_arcache(), 166 | .M_AXI_arid(M_AXI_arid), 167 | .M_AXI_arlen(M_AXI_arlen), // burst length (#transfers) 168 | .M_AXI_arlock(), 169 | .M_AXI_arprot(), 170 | .M_AXI_arqos(), 171 | .M_AXI_arready(M_AXI_arready), 172 | .M_AXI_arregion(), 173 | .M_AXI_arsize(M_AXI_arsize), // burst size (bits/transfer) 174 | .M_AXI_arvalid(M_AXI_arvalid), 175 | // 176 | .M_AXI_awaddr(M_AXI_awaddr), 177 | .M_AXI_awburst(M_AXI_awburst), 178 | .M_AXI_awcache(), 179 | .M_AXI_awid(M_AXI_awid), 180 | .M_AXI_awlen(M_AXI_awlen), 181 | .M_AXI_awlock(), 182 | .M_AXI_awprot(), 183 | .M_AXI_awqos(), 184 | .M_AXI_awready(M_AXI_awready), 185 | .M_AXI_awregion(), 186 | .M_AXI_awsize(M_AXI_awsize), 187 | .M_AXI_awvalid(M_AXI_awvalid), 188 | // 189 | .M_AXI_bid(M_AXI_bid), 190 | .M_AXI_bready(M_AXI_bready), 191 | .M_AXI_bresp(2'b00), 192 | .M_AXI_bvalid(M_AXI_bvalid), 193 | // 194 | .M_AXI_rdata(M_AXI_rdata), 195 | .M_AXI_rid(M_AXI_rid), 196 | .M_AXI_rlast(M_AXI_rlast), 197 | .M_AXI_rready(M_AXI_rready), 198 | .M_AXI_rresp(), 199 | .M_AXI_rvalid(M_AXI_rvalid), 200 | // 201 | .M_AXI_wdata(M_AXI_wdata), 202 | .M_AXI_wlast(M_AXI_wlast), 203 | .M_AXI_wready(M_AXI_wready), 204 | .M_AXI_wstrb(M_AXI_wstrb), 205 | .M_AXI_wvalid(M_AXI_wvalid), 206 | 207 | // slave AXI interface (fpga = master, zynq = slave) 208 | // connected directly to DDR controller to handle test chip mem 209 | .S_AXI_araddr(S_AXI_araddr), 210 | .S_AXI_arburst(S_AXI_arburst), 211 | .S_AXI_arcache(S_AXI_arcache), 212 | .S_AXI_arid(S_AXI_arid), 213 | .S_AXI_arlen(S_AXI_arlen), 214 | .S_AXI_arlock(S_AXI_arlock), 215 | .S_AXI_arprot(S_AXI_arprot), 216 | .S_AXI_arqos(S_AXI_arqos), 217 | .S_AXI_arready(S_AXI_arready), 218 | .S_AXI_arregion(4'b0), 219 | .S_AXI_arsize(S_AXI_arsize), 220 | .S_AXI_arvalid(S_AXI_arvalid), 221 | // 222 | .S_AXI_awaddr(S_AXI_awaddr), 223 | .S_AXI_awburst(S_AXI_awburst), 224 | .S_AXI_awcache(S_AXI_awcache), 225 | .S_AXI_awid(S_AXI_awid), 226 | .S_AXI_awlen(S_AXI_awlen), 227 | .S_AXI_awlock(S_AXI_awlock), 228 | .S_AXI_awprot(S_AXI_awprot), 229 | .S_AXI_awqos(S_AXI_awqos), 230 | .S_AXI_awready(S_AXI_awready), 231 | .S_AXI_awregion(4'b0), 232 | .S_AXI_awsize(S_AXI_awsize), 233 | .S_AXI_awvalid(S_AXI_awvalid), 234 | // 235 | .S_AXI_bid(S_AXI_bid), 236 | .S_AXI_bready(S_AXI_bready), 237 | .S_AXI_bresp(S_AXI_bresp), 238 | .S_AXI_bvalid(S_AXI_bvalid), 239 | // 240 | .S_AXI_rid(S_AXI_rid), 241 | .S_AXI_rdata(S_AXI_rdata), 242 | .S_AXI_rlast(S_AXI_rlast), 243 | .S_AXI_rready(S_AXI_rready), 244 | .S_AXI_rresp(S_AXI_rresp), 245 | .S_AXI_rvalid(S_AXI_rvalid), 246 | // 247 | .S_AXI_wdata(S_AXI_wdata), 248 | .S_AXI_wlast(S_AXI_wlast), 249 | .S_AXI_wready(S_AXI_wready), 250 | .S_AXI_wstrb(S_AXI_wstrb), 251 | .S_AXI_wvalid(S_AXI_wvalid), 252 | .ext_clk_in(host_clk) 253 | ); 254 | 255 | assign reset = !FCLK_RESET0_N || !mmcm_locked; 256 | 257 | wire [31:0] mem_araddr; 258 | wire [31:0] mem_awaddr; 259 | 260 | // Memory given to Rocket is the upper 256 MB of the 512 MB DRAM 261 | assign S_AXI_araddr = {4'd1, mem_araddr[27:0]}; 262 | assign S_AXI_awaddr = {4'd1, mem_awaddr[27:0]}; 263 | 264 | Top top( 265 | .clock(host_clk), 266 | .reset(reset), 267 | 268 | .io_ps_axi_slave_aw_ready (M_AXI_awready), 269 | .io_ps_axi_slave_aw_valid (M_AXI_awvalid), 270 | .io_ps_axi_slave_aw_bits_addr (M_AXI_awaddr), 271 | .io_ps_axi_slave_aw_bits_len (M_AXI_awlen), 272 | .io_ps_axi_slave_aw_bits_size (M_AXI_awsize), 273 | .io_ps_axi_slave_aw_bits_burst (M_AXI_awburst), 274 | .io_ps_axi_slave_aw_bits_id (M_AXI_awid), 275 | .io_ps_axi_slave_aw_bits_lock (1'b0), 276 | .io_ps_axi_slave_aw_bits_cache (4'b0), 277 | .io_ps_axi_slave_aw_bits_prot (3'b0), 278 | .io_ps_axi_slave_aw_bits_qos (4'b0), 279 | 280 | .io_ps_axi_slave_ar_ready (M_AXI_arready), 281 | .io_ps_axi_slave_ar_valid (M_AXI_arvalid), 282 | .io_ps_axi_slave_ar_bits_addr (M_AXI_araddr), 283 | .io_ps_axi_slave_ar_bits_len (M_AXI_arlen), 284 | .io_ps_axi_slave_ar_bits_size (M_AXI_arsize), 285 | .io_ps_axi_slave_ar_bits_burst (M_AXI_arburst), 286 | .io_ps_axi_slave_ar_bits_id (M_AXI_arid), 287 | .io_ps_axi_slave_ar_bits_lock (1'b0), 288 | .io_ps_axi_slave_ar_bits_cache (4'b0), 289 | .io_ps_axi_slave_ar_bits_prot (3'b0), 290 | .io_ps_axi_slave_ar_bits_qos (4'b0), 291 | 292 | .io_ps_axi_slave_w_valid (M_AXI_wvalid), 293 | .io_ps_axi_slave_w_ready (M_AXI_wready), 294 | .io_ps_axi_slave_w_bits_data (M_AXI_wdata), 295 | .io_ps_axi_slave_w_bits_strb (M_AXI_wstrb), 296 | .io_ps_axi_slave_w_bits_last (M_AXI_wlast), 297 | 298 | .io_ps_axi_slave_r_valid (M_AXI_rvalid), 299 | .io_ps_axi_slave_r_ready (M_AXI_rready), 300 | .io_ps_axi_slave_r_bits_id (M_AXI_rid), 301 | .io_ps_axi_slave_r_bits_resp (M_AXI_rresp), 302 | .io_ps_axi_slave_r_bits_data (M_AXI_rdata), 303 | .io_ps_axi_slave_r_bits_last (M_AXI_rlast), 304 | 305 | .io_ps_axi_slave_b_valid (M_AXI_bvalid), 306 | .io_ps_axi_slave_b_ready (M_AXI_bready), 307 | .io_ps_axi_slave_b_bits_id (M_AXI_bid), 308 | .io_ps_axi_slave_b_bits_resp (M_AXI_bresp), 309 | 310 | .io_mem_axi_ar_valid (S_AXI_arvalid), 311 | .io_mem_axi_ar_ready (S_AXI_arready), 312 | .io_mem_axi_ar_bits_addr (mem_araddr), 313 | .io_mem_axi_ar_bits_id (S_AXI_arid), 314 | .io_mem_axi_ar_bits_size (S_AXI_arsize), 315 | .io_mem_axi_ar_bits_len (S_AXI_arlen), 316 | .io_mem_axi_ar_bits_burst (S_AXI_arburst), 317 | .io_mem_axi_ar_bits_cache (S_AXI_arcache), 318 | .io_mem_axi_ar_bits_lock (S_AXI_arlock), 319 | .io_mem_axi_ar_bits_prot (S_AXI_arprot), 320 | .io_mem_axi_ar_bits_qos (S_AXI_arqos), 321 | .io_mem_axi_aw_valid (S_AXI_awvalid), 322 | .io_mem_axi_aw_ready (S_AXI_awready), 323 | .io_mem_axi_aw_bits_addr (mem_awaddr), 324 | .io_mem_axi_aw_bits_id (S_AXI_awid), 325 | .io_mem_axi_aw_bits_size (S_AXI_awsize), 326 | .io_mem_axi_aw_bits_len (S_AXI_awlen), 327 | .io_mem_axi_aw_bits_burst (S_AXI_awburst), 328 | .io_mem_axi_aw_bits_cache (S_AXI_awcache), 329 | .io_mem_axi_aw_bits_lock (S_AXI_awlock), 330 | .io_mem_axi_aw_bits_prot (S_AXI_awprot), 331 | .io_mem_axi_aw_bits_qos (S_AXI_awqos), 332 | .io_mem_axi_w_valid (S_AXI_wvalid), 333 | .io_mem_axi_w_ready (S_AXI_wready), 334 | .io_mem_axi_w_bits_strb (S_AXI_wstrb), 335 | .io_mem_axi_w_bits_data (S_AXI_wdata), 336 | .io_mem_axi_w_bits_last (S_AXI_wlast), 337 | .io_mem_axi_b_valid (S_AXI_bvalid), 338 | .io_mem_axi_b_ready (S_AXI_bready), 339 | .io_mem_axi_b_bits_resp (S_AXI_bresp), 340 | .io_mem_axi_b_bits_id (S_AXI_bid), 341 | .io_mem_axi_r_valid (S_AXI_rvalid), 342 | .io_mem_axi_r_ready (S_AXI_rready), 343 | .io_mem_axi_r_bits_resp (S_AXI_rresp), 344 | .io_mem_axi_r_bits_id (S_AXI_rid), 345 | .io_mem_axi_r_bits_data (S_AXI_rdata), 346 | .io_mem_axi_r_bits_last (S_AXI_rlast) 347 | ); 348 | `ifndef differential_clock 349 | IBUFG ibufg_gclk (.I(clk), .O(gclk_i)); 350 | `else 351 | IBUFDS #(.DIFF_TERM("TRUE"), .IBUF_LOW_PWR("TRUE"), .IOSTANDARD("DEFAULT")) clk_ibufds (.O(gclk_i), .I(SYSCLK_P), .IB(SYSCLK_N)); 352 | `endif 353 | BUFG bufg_host_clk (.I(host_clk_i), .O(host_clk)); 354 | 355 | MMCME2_BASE #( 356 | .BANDWIDTH("OPTIMIZED"), 357 | .CLKFBOUT_MULT_F(`RC_CLK_MULT), 358 | .CLKFBOUT_PHASE(0.0), 359 | .CLKIN1_PERIOD(`ZYNQ_CLK_PERIOD), 360 | .CLKOUT1_DIVIDE(1), 361 | .CLKOUT2_DIVIDE(1), 362 | .CLKOUT3_DIVIDE(1), 363 | .CLKOUT4_DIVIDE(1), 364 | .CLKOUT5_DIVIDE(1), 365 | .CLKOUT6_DIVIDE(1), 366 | .CLKOUT0_DIVIDE_F(`RC_CLK_DIVIDE), 367 | .CLKOUT0_DUTY_CYCLE(0.5), 368 | .CLKOUT1_DUTY_CYCLE(0.5), 369 | .CLKOUT2_DUTY_CYCLE(0.5), 370 | .CLKOUT3_DUTY_CYCLE(0.5), 371 | .CLKOUT4_DUTY_CYCLE(0.5), 372 | .CLKOUT5_DUTY_CYCLE(0.5), 373 | .CLKOUT6_DUTY_CYCLE(0.5), 374 | .CLKOUT0_PHASE(0.0), 375 | .CLKOUT1_PHASE(0.0), 376 | .CLKOUT2_PHASE(0.0), 377 | .CLKOUT3_PHASE(0.0), 378 | .CLKOUT4_PHASE(0.0), 379 | .CLKOUT5_PHASE(0.0), 380 | .CLKOUT6_PHASE(0.0), 381 | .CLKOUT4_CASCADE("FALSE"), 382 | .DIVCLK_DIVIDE(1), 383 | .REF_JITTER1(0.0), 384 | .STARTUP_WAIT("FALSE") 385 | ) MMCME2_BASE_inst ( 386 | .CLKOUT0(host_clk_i), 387 | .CLKOUT0B(), 388 | .CLKOUT1(), 389 | .CLKOUT1B(), 390 | .CLKOUT2(), 391 | .CLKOUT2B(), 392 | .CLKOUT3(), 393 | .CLKOUT3B(), 394 | .CLKOUT4(), 395 | .CLKOUT5(), 396 | .CLKOUT6(), 397 | .CLKFBOUT(gclk_fbout), 398 | .CLKFBOUTB(), 399 | .LOCKED(mmcm_locked), 400 | .CLKIN1(gclk_i), 401 | .PWRDWN(1'b0), 402 | .RST(1'b0), 403 | .CLKFBIN(gclk_fbout)); 404 | 405 | endmodule 406 | -------------------------------------------------------------------------------- /zybo/src/xml/ZYBO_zynq_def.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Zynq board definition file for the ZYBO Rev. B. 6 | 7 | This file can be imported into XPS or Vivado IP Integrator to configure the PS7 core 8 | to work properly with the ZYBO's DDR3, microSD, UART, Ethernet, USB-OTG, and other 9 | onboard peripherals. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rocket Chip on Zynq FPGAs 2 | ========================= 3 | ### Warning: This repository is deprecated and does not track Rocket Chip master. 4 | #### Those looking for an FPGA prototype of Rocket Chip should checkout SiFive’s [Freedom platform](https://github.com/sifive/freedom). Those looking for an FPGA-accelerated simulation environment (for obtaining cycle-accurate performance measurements) should use [FireSim](https://github.com/firesim/firesim). Both of these tools regularly update their version of Rocket Chip. 5 | 6 | This repository contains the files needed to run the RISC-V [rocket chip](https://github.com/ucb-bar/rocket-chip) on 7 | various Zynq FPGA boards ([Zybo](http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,1198&Prod=ZYBO), [Zedboard](http://zedboard.org/product/zedboard), [ZC706](http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm)) with Vivado 2016.2. Efforts have been made to not only automate the process of generating files for these boards, but to also reduce duplication as well as the size of this repo. Prebuilt images are available in git submodules, and they are only shallowly cloned if requested. 8 | 9 | 10 | ### How to use this README 11 | 12 | This README contains 3 major sets of instructions: 13 | 14 | 1) [Quick Instructions](#quickinst): This is the simplest way to get started - you'll download the relevant prebuilt images for your board and learn how to run binaries on the RISC-V Rocket Core. These instructions require only that you have a compatible board - neither Vivado nor the RISC-V Toolchain are necessary. 15 | 16 | 2) [Pushing Your Rocket Modifications to the FPGA](#bitstream): These instructions walk through what we believe is the common case - a user wanting to utilize a custom-generated Rocket Core. 17 | 18 | 3) [Building Everything from Scratch](#fromscratch): Here, we discuss how to build the full stack from scratch. It is unlikely that you'll need to use these instructions, unless you are intending to make changes to the configuration of the Zynq ARM Core or `u-boot`. 19 | 20 | Finally, the bottom of the README contains a set of [Appendices](#appendices), which document some common operations that we believe are useful or provides more depth on commands described elsewhere in the documentation. 21 | 22 | To guide you through the rest of the documentation, we have provide both a [Table of Contents](#toc) and an [Overview](#overview). 23 | 24 | _Note_: If you are seeking to test your own modifications to rocket chip (RC) using this repository, it must be derived from RC commit [fb476d1](https://github.com/ucb-bar/rocket-chip/tree/fb476d193cc21dd66d81cc5890883bd466f889f7) or later, as this project expects both a debug module to be present, and links directly against RC to build a top-level project directly in chisel. Otherwise, you should use an older version of this repository [bf6d00c2](https://github.com/ucb-bar/fpga-zynq/tree/bf6d00c211c46d60662a9ef6e9460a405cc9b0d5) or earlier, which has support for HTIF-based rocket chip instances. 25 | 26 | ### Table of Contents 27 | + [Overview of System Stack](#overview) 28 | + [1 - Quick Instructions](#quickinst) 29 | + [2 - Pushing Your Rocket Modifications to the FPGA](#bitstream) 30 | + [Setting Up Your Workspace](#workspace) 31 | + [Configuring Rocket Chip](#configRC) 32 | + [Generating Verilog for Rocket Chip](#genRC) 33 | + [Generating Project for Configuration](#projRC) 34 | + [Repacking `boot.bin`](#repack) 35 | + [3 - Building Everything from Scratch](#fromscratch) 36 | + [Project Setup](#setup) 37 | + [Generating a Bitstream](#bitstream) 38 | + [Building the FSBL](#fsbl) 39 | + [Building u-boot for the Zynq ARM Core](#u-boot) 40 | + [Creating `boot.bin`](#boot.bin) 41 | + [Building linux for the ARM PS](#arm-linux) 42 | + [Building riscv-linux](#riscv-linux) 43 | + [Booting Up and Interacting with the RISC-V Rocket Core](#booting) 44 | + [Appendices](#appendices) 45 | + [Connecting to the Board](#connecting) 46 | + [Getting Files On & Off the Board](#transferring) 47 | + [Working with Vivado](#vivado) 48 | + [Changing the Processor's Clockrate](#clockrate) 49 | + [Contents of the SD Card](#sdcard) 50 | + [Building fesvr-zynq](#fesvr) 51 | + [Building riscv-tools for Zybo](#zybotools) 52 | + [Acknowledgements](#ack) 53 | 54 | 55 | 56 | ### Overview of System Stack 57 | Our system will allow you to run a RISC-V binary on a rocket core instantiated on a supported Zynq FPGA. This section will outline the stack of all of the parts involved and by proxy, outline the rest of the documentation. Going top-down from the RISC-V binary to the development system: 58 | 59 | **Target Application** (RISC-V binary) 60 | will run on top of whatever kernel the rocket chip is running. Compiled by [riscv-gcc](https://github.com/riscv/riscv-gcc) or [riscv-llvm](https://github.com/riscv/riscv-llvm). 61 | 62 | **RISC-V Kernel** ([proxy kernel](https://github.com/riscv/riscv-pk) or [RISC-V Linux](https://github.com/riscv/riscv-linux)) 63 | runs on top of the rocket chip. The proxy kernel is extremely lightweight and designed to be used with a single binary linked against Newlib while RISC-V Linux is appropriate for everything else. 64 | 65 | **Rocket Chip** ([rocket core](https://github.com/ucb-bar/rocket) with L1 instruction and data caches) 66 | is instantiated on the FPGA. Many of its structures will typically map to various hard blocks including BRAMs and DSP slices. It communicates to the host ARM core on the Zynq via AXI. 67 | 68 | **Front-end Server** ([riscv-fesvr](https://github.com/riscv/riscv-fesvr)) 69 | runs on the host ARM core and provides an interface to the rocket chip running on the FPGA (connected via AXI). 70 | 71 | **Zynq ARM Core** (actually dual Cortex A9) 72 | runs Linux and simplifies interfacing with the FPGA. 73 | 74 | **FPGA Board** (Zybo, Zedboard, or ZC706) 75 | contains the Zynq FPGA and several I/O devices. At power on, the contents of the SD card are used to configure the FPGA and boot Linux on the ARM core. 76 | 77 | **External Communication** (TTY over serial on USB or telnet/ssh over ethernet) 78 | allows the development system to communicate with the FPGA board. 79 | 80 | **Development System** (PC with SD card reader) 81 | generates the images to configure the FPGA. 82 | 83 | 84 | 85 | 1) Quick Instructions 86 | ------------------ 87 | _Using prebuilt images, run hello world and/or linux on rocket_ 88 | 89 | First, enter into the directory for your board (current options are `zybo`, `zedboard`, and `zc706`). From there, run the following to download all of the necessary images: 90 | 91 | $ make fetch-images 92 | 93 | Next, insert the SD card on the development system and copy over the images: 94 | 95 | $ make load-sd SD=path_to_mounted_sdcard 96 | 97 | Finally, eject the SD card, insert it into the board, set the board's boot jumper to "SD", and power the board on. Connect to the board with an ethernet cable (password is _root_) and run hello world: 98 | 99 | $ ssh root@192.168.1.5 100 | root@zynq:~# ./fesvr-zynq pk hello 101 | hello! 102 | 103 | Awesome! You can now run RISC-V binaries on Rocket. If you'd like to boot linux on the Rocket core, see _[Booting Up and Interacting with the RISC-V Rocket Core](#booting)_. 104 | 105 | 106 | 107 | 2) Pushing Your Rocket Modifications to the FPGA 108 | ------------------------- 109 | 110 | #### Setting Up Your Workspace 111 | _Requires: Vivado 2016.2 and its settings64.sh and a JVM that can run Scala_ 112 | 113 | After you clone the repository for the first time, you must initialize 114 | the submodules rocket-chip and testchipip, as well as the first-level 115 | submodules of rocket-chip itself. 116 | 117 | $ make init-submodules 118 | 119 | If you have your own working rocket-chip directory that you would like to use, override the `ROCKET_DIR` make variable set in common/Makefrag. 120 | 121 | #### Configuring Rocket Chip 122 | 123 | The verilog for the rocket chip is generated by [Chisel](https://chisel.eecs.berkeley.edu) and thus is not intended to be edited by humans. This project instantiates rocket chip as module larger top level chisel project, that includes an adapter to interface the ARM core with rocket chip's debug module. 124 | 125 | The configuration used to generate the rocket chip comes from the `CONFIG` environment variables. If `CONFIG` isn't set by the environment, it is taken from the `Makefile` for the current board. For this example, we use the Zybo which has a default configuration of `ZynqSmallConfig`. 126 | 127 | #### Generating Verilog for Rocket Chip 128 | 129 | Enter into the directory for your board (current options are `zybo`, `zedboard`, and `zc706`). After making changes within `rocket-chip` and/or `common/src/main/scala`, you can run the rocket chip generator and copy the newly generated verilog back into the board's src/verilog directory with: 130 | 131 | $ make rocket 132 | 133 | You can also explicitly set the `CONFIG` variable from the command-line (can do this for any command): 134 | 135 | $ make rocket CONFIG=MyFPGAConfig 136 | 137 | By default this will look up a configuration specified in the rocket chip library. You may define a custom one without recompiling rocketchip, by defining in the zynq chisel sources at `common/src/main/scala`, and instead calling: 138 | 139 | $ make rocket CONFIG_PROJECT=zynq CONFIG=MyCustomZynqConfig 140 | 141 | The generator will instead look for the configuration definition in the local project instead of the rocket chip library. 142 | 143 | 144 | #### Generating Project for Configuration 145 | To generate a Vivado project specific to the board and the configuration (one project per configuration): 146 | 147 | $ make project 148 | 149 | This step only needs to be done once per configuration. 150 | 151 | 152 | #### Repacking `boot.bin` 153 | 154 | Once you have changed the design, you will need to generate a new bitstream and that will need to be packaged in `boot.bin`. `boot.bin` also contains the binaries needed for startup (`FSBL.elf` and `u-boot.elf`) but these can be reused. From within the board's directory (_zybo_ in this example), to repack `boot.bin`: 155 | 156 | $ make fpga-images-zybo/boot.bin 157 | 158 | If you have modified the verilog for your project but not generated a new bitstream, `make` should generate a new bitstream automatically. To use the new `boot.bin`, copy it to the SD card, insert the SD card into the board, and power on the board. 159 | 160 | 161 | 162 | 3) Building Everything from Scratch 163 | ----------------------- 164 | This section describes how to build the entire project from scratch. Most likely, you will not need to perform all of these steps, however we keep them here for reference. Various other sections of this README may selectively refer to these sections. This section assumes that you've just pulled this repository and have sourced the settings file for Vivado 2016.2. 165 | 166 | For ease of exposition, we will be describing all of the commands assuming that we are working with the `zybo` and its default configuration `ZynqSmallConfig`. Replacing references to the `zybo` with `zedboard` or `zc706` will allow you to use these instructions for those boards. 167 | 168 | From here on, `$REPO` will refer to the location of the `fpga-zynq` repository. 169 | 170 | ### 3.1) Project Setup 171 | 172 | First, we need to generate a Vivado project from the source files that are present in a particular board's directory. 173 | 174 | $ cd $REPO/zybo 175 | $ make project 176 | 177 | ### 3.2) Generating a Bitstream 178 | 179 | Next, let's open up the project in the Vivado GUI: 180 | 181 | $ make vivado 182 | # OR 183 | $ cd zybo_rocketchip_ZynqSmallConfig 184 | $ vivado zybo_rocketchip_ZynqSmallConfig.xpr 185 | 186 | If you wish to make any modifications to the project, you may now do so. Once you've finished, let's move on: 187 | 188 | Inside Vivado, select _Open Block Design_ followed by _system.bd_ in the dropdown. This will open a block diagram for the Zynq PS Configuration and is necessary for correct FSBL generation. 189 | 190 | Next, select _Generate Bitstream_. Vivado will now step through the usual Synthesis/Implementation steps. Upon completion, if you're interested in only the bitstream, you can stop here; the file you want is in: 191 | 192 | `$REPO/zybo/zybo_rocketchip_ZynqSmallConfig/zybo_rocketchip_ZynqSmallConfig.runs/impl_1/rocketchip_wrapper.bit` 193 | 194 | Otherwise, let's continue on to select _Open Implemented Design_. This is again necessary to properly export the description of our Hardware for the Xilinx SDK to use. 195 | 196 | At this point, select _File -> Export -> Export Hardware_. This will create the following directory: 197 | 198 | `$REPO/zybo/zybo_rocketchip_ZynqSmallConfig/zybo_rocketchip_ZynqSmallConfig.sdk` 199 | 200 | This directory contains a variety of files that provide information about the hardware to the SDK. Let's continue on to building the FSBL. 201 | 202 | 203 | ### 3.3) Building the FSBL 204 | 205 | This step assumes that you have just generated the bitstream. Inside the Vivado GUI, select "Launch SDK". This will open up the Xilinx SDK preconfigured with the description of our hardware. In order to generate the FSBL, do the following: 206 | 207 | 1) Select _File -> New -> Application Project_ 208 | 209 | 2) In the new window, type "FSBL" as the Project name, and ensure that the rest of the properties are correctly set (disregarding the greyed out _Location_ field): 210 | 211 | 212 | 213 | 3) Select _Next_, at which point you should be given a set of options. Select _Zynq FSBL_ and _Finish_. 214 | 215 | 4) The SDK will proceed to automatically compile the FSBL. You can see the progress in the Console. 216 | 217 | 5) Once the build is finished, we need to build u-boot before returning to the SDK in order to create our BOOT.bin. 218 | 219 | ### 3.4) Building u-boot for the Zynq ARM Core 220 | 221 | Returning to the command line, do the following from the directory corresponding to your board: 222 | 223 | $ make arm-uboot 224 | 225 | This target performs a variety of commands. It will first pull the u-boot source from the Xilinx repositories (see the submodule in `$REPO/common/u-boot-xlnx`), patch it with the necessary files found in `$REPO/zybo/soft_config/`, compile u-boot, and place the resulting u-boot.elf file in `$REPO/zybo/soft_build/u-boot.elf`. 226 | 227 | ### 3.5) Creating `boot.bin` 228 | 229 | At this point, we have built up all of the necessary components to create our `boot.bin` file. Returning to the Xilinx SDK, select _Xilinx Tools -> Create Zynq Boot Image_. 230 | 231 | First, you should fill in the _Output BIF file path_ with `$REPO/zybo/deliver_output`. If this directory has not already been created, you may go ahead and create it (this is where we will place all of the items that we will ultimately transfer to the SD card). See the below for a sample path. Performing this step will also fill in the _Output path_ field, which specifies the location of the `BOOT.bin` file that we desire. 232 | 233 | Next, we will add the individual files that make up `BOOT.bin`. Order is important, so follow these steps exactly: 234 | 235 | 1) Select _Add_ and in the window that opens, click _Browse_ and specify the following location: 236 | 237 | `$REPO/zybo/zybo_rocketchip_ZynqSmallConfig/zybo_rocketchip_ZynqSmallConfig.sdk/FSBL/Debug/FSBL.elf` 238 | 239 | Once you have done so select the dropdown next to _Partition type_ and select _bootloader_. You must perform this step **after** selecting the path, else the SDK will change it back to _datafile_, and your `BOOT.bin` will not work. 240 | 241 | At the conclusion of this step, the _Add partition_ window will look something like: 242 | 243 | 244 | 245 | Click _OK_to return to the previous window. 246 | 247 | 2) Once more, click _Add_. In the new _Add partition_ window, click _Browse_ and specify the following location: 248 | 249 | `$REPO/zybo/zybo_rocketchip_ZynqSmallConfig/zybo_rocketchip_ZynqSmallConfig.runs/impl_1/rocketchip_wrapper.bit` 250 | 251 | Ensure that _Partition type_ is set to datafile and click _OK_. 252 | 253 | 3) Click _Add_ a final time. Click _Browse_ and this time select our compiled `u-boot.elf`: 254 | 255 | `$REPO/zybo/soft_build/u-boot.elf` 256 | 257 | Again, ensure that _Partition type_ is set to datafile and click _OK_. 258 | 259 | 4) At this point, the window should match the following (click the image to zoom in): 260 | 261 | 262 | 263 | Select _Create Image_. This will produce a `BOOT.bin` file in the `$REPO/zybo/deliver_output` directory. 264 | 265 | If you make modifications to the project in the future, you can avoid having to perform this step manually and 266 | instead may reuse the output.bif file that the SDK generates the first time you use _Create Zynq Boot Image._ 267 | Use the following make target to do so: 268 | 269 | $ make deliver_output/boot.bin 270 | 271 | ### 3.6) Building linux for the ARM PS 272 | 273 | As part of our bootstrapping process, we need to boot linux on the ARM core in the Zynq. We can build this copy of linux like so (again assuming that we are in `$REPO/zybo`): 274 | 275 | $ make arm-linux 276 | 277 | We additionally need to produce the `devicetree.dtb` file that linux will use to setup peripherals of the ARM core. We can produce this like so: 278 | 279 | $ make arm-dtb 280 | 281 | At this point, the `$REPO/zybo/deliver_output` directory contains the following files: 282 | 283 | * `BOOT.bin` - (the filename is case insensitive, you may see `boot.bin`). This contains the FSBL, the bitstream with Rocket, and u-boot. 284 | * `uImage` - Linux for the ARM PS 285 | * `devicetree.dtb` - Contains information about the ARM core's peripherals for linux. 286 | 287 | The only remaining file that we are missing at this point is `uramdisk.image.gz`, the root filesystem for linux on the ARM Core. You can obtain it like so (it will be placed in `$REPO/zybo/deliver_output`): 288 | 289 | $ make fetch-ramdisk 290 | 291 | Now, take the four files in `deliver_output/`, and place them on the root of the SD card that we will insert into the Zybo. The layout of your SD card should match the following: 292 | 293 | SD_ROOT/ 294 | |-> boot.bin 295 | |-> devicetree.dtb 296 | |-> uImage 297 | |-> uramdisk.image.gz 298 | 299 | At this point, you have performed the necessary steps to run binaries on Rocket. See [Section 3.8](#booting) for how to do so. If you are interested in running riscv-linux on Rocket, continue on to Section 3.7: 300 | 301 | ### 3.7) Building/Obtaining riscv-linux 302 | 303 | There are two options to obtain riscv-linux: 304 | 305 | #### Method 1) Build from Source 306 | 307 | To build [riscv-linux](http://github.com/riscv/riscv-linux) for Rocket, follow the instructions [here](https://github.com/riscv/riscv-tools#linuxman). 308 | These instructions will show you how to create a linux image that boots from an initramfs. 309 | We also now have support for block devices, so you can also boot from an ext2 image created by [buildroot](https://github.com/sifive/buildroot). 310 | To configure linux to boot from a block device, instead of selecting "Initial RAM filesystem and RAM disk", 311 | add the arguments "root=/dev/generic-blkdev rw" to the kernel command line 312 | under "Kernel Hacking" -> "Built-in Kernel Command String". To use the block 313 | device, you will need to use the ucbbar-all branch of riscv-linux. 314 | 315 | Next, you'll need to build an instance of the Berkeley Bootloader(BBL) that contains your linux image as a payload. BBL is provided alongside the proxy kernel at [this repository](https://github.com/riscv/riscv-pk). 316 | 317 | Finally, drop your bbl image into SD_ROOT/, which will be mounted as `/mnt/boot/` in the ARM core's filesystem. 318 | 319 | Warning: If you are working with the Zybo, you need to make sure you compile with a version of the riscv-gnu-toolchain that targets RV64IMA, as the zybo configuration does not possess an FPU. 320 | 321 | #### Method 2) Use the provided BBL instance 322 | 323 | Included in the home directory of the ARM core's ramdisk we've provided an instance of bbl preloaded with a miniminal linux image. All you have to do is follow the instructions in the [next](#booting) section. 324 | 325 | ### 3.8) Booting Up and Interacting with the RISC-V Rocket Core 326 | 327 | First, insert the SD card and follow the instructions in [Appendix A](#connecting) to connect to your board. You can login to the board with username _root_ and password _root_. Once you're at the prompt, you can run a basic hello world program on rocket like so: 328 | 329 | root@zynq:~# ./fesvr-zynq pk hello 330 | hello! 331 | 332 | To boot riscv-linux, run: 333 | 334 | root@zynq:~# ./fesvr-zynq bbl 335 | vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 336 | vvvvvvvvvvvvvvvvvvvvvvvvvvvv 337 | rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvvvv 338 | rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv 339 | rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv 340 | rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv 341 | rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv 342 | rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv 343 | rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv 344 | rr vvvvvvvvvvvvvvvvvvvvvv 345 | rr vvvvvvvvvvvvvvvvvvvvvvvv rr 346 | rrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrr 347 | rrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrr 348 | rrrrrrrr vvvvvvvvvvvvvvvvvv rrrrrrrr 349 | rrrrrrrrrr vvvvvvvvvvvvvv rrrrrrrrrr 350 | rrrrrrrrrrrr vvvvvvvvvv rrrrrrrrrrrr 351 | rrrrrrrrrrrrrr vvvvvv rrrrrrrrrrrrrr 352 | rrrrrrrrrrrrrrrr vv rrrrrrrrrrrrrrrr 353 | rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr 354 | rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr 355 | rrrrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr 356 | 357 | INSTRUCTION SETS WANT TO BE FREE 358 | [ 0.000000] Linux version 4.6.2 359 | 360 | After linux boots you'll be presented with a busybox prompt from riscv-linux running on rocket! 361 | 362 | If you are using a root filesystem on a seperate filesystem image, you can 363 | boot linux by running 364 | 365 | root@zynq:~# ./fesvr-zynq +blkdev=rootfs.ext2 bbl 366 | 367 | Appendices 368 | ------------ 369 | 370 | ### A) Connecting to the Board 371 | 372 | #### Serial-USB 373 | On the Zybo and Zedboard a single serial-USB cable is needed but on the ZC706 you will also need a USB type A to type B cable (and possibly some drivers). To connect: 374 | 375 | $ screen /dev/tty.usbmodem1411 115200,cs8,-parenb,-cstopb 376 | 377 | _Note:_ The numbers following `tty.usbmodem` may vary slightly. On the Zybo, 378 | replace `usbmodem` with `usbserial-` and on the ZC706, replace it with 379 | `SLAB_USBtoUART`. 380 | 381 | #### Ethernet 382 | The board has an IP of 192.168.1.5 and can be accessed by username/password of root/root on telnet and ssh. For example: 383 | 384 | $ ssh root@192.168.1.5 385 | 386 | _Note:_ Make sure your development system ethernet interface is configured to be on the 192.168.1.x subnet. The default configuration intends for the board to be directly attached to the development system (single cable). If you want to place the board on a larger network, we recommend changing the root password to something stronger and changing the IP configuration to mesh well with your network. 387 | 388 | 389 | ### B) Getting Files On & Off the Board 390 | 391 | #### Copying Files over Ethernet 392 | The easiest way to get a file onto the board is to copy it with scp over ethernet: 393 | 394 | $ scp file root@192.168.1.5:~/ 395 | 396 | _Note:_ Linux is running out of a RAMdisk, so to make a file available after a reboot, copy it to the SD card or modify the RAMdisk. 397 | 398 | #### Changing the RAMDisk 399 | _Requires: [u-boot](http://www.denx.de/wiki/U-Boot/) and sudo_ 400 | 401 | The RAMDisk (`uramdisk.image.gz`) that holds Linux for the ARM cores is a gzipped cpio archive with a u-boot header for the board. To open the RAMdisk: 402 | 403 | $ make ramdisk-open 404 | 405 | When changing or adding files, be sure to keep track of owners, groups, and permissions. When you are done, to package it back up: 406 | 407 | $ make ramdisk-close 408 | 409 | A useful application of this is to add your SSH public key to `.ssh/authorized_keys` so you can have passwordless login to the board. 410 | 411 | _Note:_ Since these ramdisk operations use sudo on files, they may not work on a network mounted filesystem. To get around this limitation, it is easiest to just copy it to a local filesystem when modifying the ramdisk. 412 | 413 | 414 | ### C) Working with Vivado 415 | 416 | _Requires: Vivado 2016.2 and its settings64.sh sourced_ 417 | 418 | First, enter into the directory for your board (current options are `zybo`, `zedboard`, and `zc706`). To generate a bitstream, you will need a Vivado project. You should only need to generate it once, but the automation this repo provides makes it easy to generate again if you delete the project. To generate a Vivado project from scratch: 419 | 420 | $ make project 421 | 422 | To generate a bitstream from the command-line: 423 | 424 | $ make bitstream 425 | 426 | To launch Vivado in GUI mode: 427 | 428 | $ make vivado 429 | 430 | 431 | ### D) Changing the Processor's Clockrate 432 | You can change the clockrate for the rocket chip by changing `RC_CLK_MULT` and `RC_CLK_DIVIDE` within a board's `src/verilog/clocking.vh`. After that change, you will need to generate a new bitstream (and `boot.bin`). 433 | 434 | _Note:_ Although rarely needed, it is possible to change the input clockrate to the FPGA by changing it within the block design, `src/constrs/base.xdc`, and `ZYNQ_CLK_PERIOD` within `src/verilog/clocking.vh`. This will also require regenerating `FSBL.elf`, the bitstream, and of course `boot.bin`. 435 | 436 | 437 | ### E) Contents of the SD Card 438 | The SD card is used by the board to configure the FPGA and boot up the ARM core. All of these files are available within a board's fpga-images submodule, but they can also be built from scratch. Here is a summary of the files and their purposes: 439 | 440 | * `boot.bin` is generated by the Xilinx SDK and is actually three files. To generate it from scratch, follow the instructions from Section 3 up through [Section 3.5 Creating boot.bin](#boot.bin). To repack it from existing components, follow [Repacking boot.bin](#repack). `boot.bin` contains: 441 | * Bitstream (`rocketchip_wrapper.bit`) configures the FPGA with the rocket chip design. To build it with the GUI, see [Section 3.2 Generating a Bitstream](#bitstream) and to build it with the command-line, see: [Working with Vivado](#vivado). 442 | * First Stage Bootloader (`FSBL.elf`) - This bootloader configures the Zynq processing system based on the block design in the Vivado project. The FSBL will hand-off to `u-boot` once the processing system is setup. We build the FSBL using the Xilinx SDK and hardware information exported from Vivado. (see [Section 3.3](#fsbl)) 443 | * u-boot (`u-boot.elf`) - This bootloader takes configuration information and prepares the ARM processing system for booting linux. Once configuration is complete, `u-boot` will hand-off execution to the ARM linux kernel. We build `u-boot` directly from the [Xilinx u-boot repository](https://github.com/Xilinx/u-boot-xlnx), with some configuration modifications to support Rocket. (see [Section 3.4](#u-boot)) 444 | * ARM Linux (`uImage`) - This is a copy of linux designed to run on the ARM processing system. From within this linux environment, we will be able to run tools (like `fesvr-zedboard`) to interact with the RISC-V Rocket Core. We build directly from the [Xilinx linux repository](https://github.com/Xilinx/linux-xlnx), with a custom device tree file to support Rocket. (see [Section 3.6](#arm-linux)) 445 | * ARM RAMDisk (`uramdisk.image.gz`) - The RAMDisk is mounted by ARM Linux and contains the root filesystem. For obtaining it, see [Section 3.6](#arm-linux), and for modifying it, see [Appendix B](#transferring). 446 | * `devicetree.dtb` - Contains information about the ARM core's peripherals for Linux. (See [Section 3.6](#arm-linux)) 447 | 448 | 449 | ### F) Building fesvr-zynq 450 | 451 | The [riscv-fesvr repo](http://github.com/riscv/riscv-fesvr) provides against which the zynq-fesvr is linked. Additionally, `common/csrc` includes source for main, and a simple driver, which hands off debug module requests and reponses between the ARM core and rocket chip. Before building, make sure the 2016.2 version of settings64.sh is sourced. To build the riscv-fesvr binary for Linux ARM target (to run on Zynq board), type: 452 | 453 | $ make fesvr-zynq 454 | 455 | and make sure you have the Xilinx SDK in your PATH, and the riscv-tools/riscv-fesvr submodule initialized in your rocket chip directory. When installing fesvr-zynq, don't forget to copy the library as well (`common/build/libfesvr.so` to `/usr/local/lib` on the board). 456 | 457 | 458 | ### G) Building riscv-tools for Zybo 459 | 460 | The Zybo build was last tested with [this version of the toolchain](https://github.com/ucb-bar/rocket-chip/commit/2f71a3da5a7d41b4aa2c7a617902f2aee8f2cbe1). 461 | 462 | Because the Zybo board uses `ZynqSmallConfig`, [riscv-tools](https://github.com/riscv/riscv-tools) must be recompiled to omit floating point instructions. Add the `--with-arch=RV64IMA` tag to the line in `build.sh` that builds [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain). It should read as follows: 463 | 464 | build_project riscv-gnu-toolchain --prefix=$RISCV --with-arch=RV64IMA 465 | 466 | Then run `./build.sh` as normal. 467 | 468 | When testing on spike, run spike with the `--isa=RV64IMA` flag. 469 | 470 | If [pk](https://github.com/riscv/riscv-pk) does not work, make sure it is being built using this version of the toolchain, since it is specifically generated to not have floating point instructions. Also make sure any binaries you want to run on the Zybo are compiled using this toolchain. 471 | 472 | Acknowledgments 473 | --------------- 474 | In addition to those that [contributed](https://github.com/ucb-bar/rocket-chip#contributors) to rocket chip, this repository is based on internal repositories contributed by: 475 | 476 | - Rimas Avizienis 477 | - Jonathan Bachrach 478 | - David Biancolin 479 | - Scott Beamer 480 | - Sagar Karandikar 481 | - Deborah Soung 482 | - Andrew Waterman 483 | 484 | --------------------------------------------------------------------------------