Compare commits

...

36 Commits

Author SHA1 Message Date
552553e526 Load 32 MiB bootimage from a 2048 sector offset (first partiton) 2018-06-13 00:34:19 +02:00
ee888b8c7b Rebuild when changing the bootloader 2018-06-13 00:33:46 +02:00
c812a8878f Properly set clock frequencies 2018-06-06 01:05:36 +02:00
2c74ef7f03 Use correct frequency for the sd-spi interface 2018-05-19 19:04:56 +02:00
c27ee2215c Print everything send over serial to the terminal 2018-05-19 19:04:11 +02:00
ec4e3ec36d Use rocket config with fpu and mmu for booting linux 2018-05-19 19:00:57 +02:00
87bb3a5f24 Use correct clock period and memory size in config 2018-05-14 20:10:08 +02:00
a3f166d5a2 Pull in memory and terminal improvements 2018-05-14 20:09:55 +02:00
175ed051d3 Pull in the new XilinxML507MIGToTL implementation 2018-05-10 21:43:51 +02:00
291a765b8d Switch to new XilinxML507MIG and connect top level signals 2018-05-10 00:37:00 +02:00
7b46ed6b7c Move ml507 mig TL stub into fpga-shells 2018-05-09 23:22:53 +02:00
0cb89fd675 Add fragmenter in front of TLMemoryML507 and implementation notes 2018-05-03 01:57:06 +02:00
7a514c6477 Point all submodules to tiband 2018-05-01 00:14:53 +02:00
e57dfd0f63 Update rocket-chip to fix rom generation 2018-05-01 00:11:11 +02:00
df44d1a3bc Make DIP switches available as GPIO register 2018-05-01 00:09:14 +02:00
4f950772a1 Use 80 MHz for rocket and 48 MHz for the terminal 2018-04-30 22:54:57 +02:00
97eeb7af29 Add terminal peripheral (in same clock domain for now) 2018-04-30 00:54:21 +02:00
1cb558d2ea ml507: Don't accept any messages in the stub memory slave 2018-04-24 00:50:13 +02:00
d749f87696 ml507: Remove redundant clock definition 2018-04-24 00:49:39 +02:00
c10d2378e7 Disable TLMonitors 2018-04-19 01:34:10 +02:00
2b5509009c Increase gpio width to 8 2018-04-19 01:33:24 +02:00
06a623a05a Update to latest ml507 shell 2018-04-19 01:33:09 +02:00
48f3a7e590 Reduce rocket to a single core
More than one core does not fit on the ml507 and is more than enough for
booting linux and executing basic utilities.
2018-04-18 00:28:01 +02:00
7449f52b9a Update to latest ml507 shell 2018-04-18 00:27:45 +02:00
212821fe4d Switch to the new ML507Shell
This enables synthesis for the first time!
2018-04-12 00:50:38 +02:00
8e4eaf6603 Add TLMemoryML507 stub and integration 2018-04-11 22:26:14 +02:00
0134a8f4dc Remove vc707 memory interface from ml507 2018-04-11 20:55:00 +02:00
5fdadd244c Add makefile and config for the ml507 board
The config is based on the u500vc707devkit config.
2018-04-11 20:09:05 +02:00
cd9a525a66 Merge pull request #50 from sifive/update_readme_vc707_vivado2016dot4
U500 VC707 FPGA Dev Kit : update required Vivado version from 2016.1 to 2016.4
2018-04-06 10:55:00 -07:00
0e77cb9d87 U500 VC707 FPGA Dev Kit : update required Vivado version from 2016.1 to 2016.4 to fix synthesis bug effecting debug module 2018-04-06 10:54:03 -07:00
c0a2869e56 Merge pull request #49 from sifive/update_vc707_sdboot
Correct GPIO/SPI/UART base address for VC707 SDBOOT
2018-04-05 22:13:22 -07:00
0663bb7627 Correct GPIO/SPI/UART base addresse for vc707 sdboot 2018-04-05 22:11:39 -07:00
fff18810cd Merge pull request #48 from sifive/chiplink
Add a VC707 chiplink slave target
2018-03-22 20:38:30 -07:00
41f29484fd iofpga: add a vc707 chiplink slave target 2018-03-22 20:37:50 -07:00
ac070218d1 submodule: bump to master 2018-03-22 18:18:28 -07:00
d3fa3c8652 build.sbt: update to rocket's scala version 2018-03-22 18:10:19 -07:00
16 changed files with 474 additions and 16 deletions

6
.gitmodules vendored
View File

@ -1,9 +1,9 @@
[submodule "rocket-chip"] [submodule "rocket-chip"]
path = rocket-chip path = rocket-chip
url = https://github.com/ucb-bar/rocket-chip.git url = https://git.tiband.de/riscv/rocket-chip.git
[submodule "sifive-blocks"] [submodule "sifive-blocks"]
path = sifive-blocks path = sifive-blocks
url = https://github.com/sifive/sifive-blocks.git url = https://git.tiband.de/riscv/sifive-blocks.git
[submodule "fpga-shells"] [submodule "fpga-shells"]
path = fpga-shells path = fpga-shells
url = https://github.com/sifive/fpga-shells url = https://git.tiband.de/riscv/fpga-shells.git

24
Makefile.u500ml507devkit Normal file
View File

@ -0,0 +1,24 @@
# See LICENSE for license details.
base_dir := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
BUILD_DIR := $(base_dir)/builds/u500ml507devkit
FPGA_DIR := $(base_dir)/fpga-shells/xilinx
MODEL := U500ML507DevKitFPGAChip
PROJECT := sifive.freedom.unleashed.u500ml507devkit
export CONFIG_PROJECT := sifive.freedom.unleashed.u500ml507devkit
export CONFIG := U500ML507DevKitConfig
export BOARD := ml507
export BOOTROM_DIR := $(base_dir)/bootrom/sdboot
rocketchip_dir := $(base_dir)/rocket-chip
sifiveblocks_dir := $(base_dir)/sifive-blocks
VSRCS := \
$(rocketchip_dir)/vsrc/AsyncResetReg.v \
$(rocketchip_dir)/vsrc/plusarg_reader.v \
$(sifiveblocks_dir)/vsrc/SRLatch.v \
$(FPGA_DIR)/common/vsrc/PowerOnResetFPGAOnly.v \
$(FPGA_DIR)/$(BOARD)/vsrc/sdio.v \
$(FPGA_DIR)/$(BOARD)/vsrc/ml507reset.v \
$(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).rom.v \
$(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).v
include common.mk

22
Makefile.u500vc707iofpga Normal file
View File

@ -0,0 +1,22 @@
# See LICENSE for license details.
base_dir := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
BUILD_DIR := $(base_dir)/builds/u500vc707iofpga
FPGA_DIR := $(base_dir)/fpga-shells/xilinx
MODEL := IOFPGAChip
PROJECT := sifive.freedom.unleashed.vc707.iofpga
export CONFIG_PROJECT := sifive.freedom.unleashed.vc707.iofpga
export CONFIG := IOFPGAConfig
export BOARD := vc707
rocketchip_dir := $(base_dir)/rocket-chip
sifiveblocks_dir := $(base_dir)/sifive-blocks
VSRCS := \
$(rocketchip_dir)/vsrc/AsyncResetReg.v \
$(rocketchip_dir)/vsrc/plusarg_reader.v \
$(sifiveblocks_dir)/vsrc/SRLatch.v \
$(FPGA_DIR)/common/vsrc/PowerOnResetFPGAOnly.v \
$(FPGA_DIR)/$(BOARD)/vsrc/sdio.v \
$(FPGA_DIR)/$(BOARD)/vsrc/vc707reset.v \
$(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).v
include common.mk

View File

@ -44,7 +44,7 @@ $ make -f Makefile.e300artydevkit verilog
$ make -f Makefile.e300artydevkit mcs $ make -f Makefile.e300artydevkit mcs
``` ```
Note: This flow requires vivado 2017.1. Old versions are known to fail. Note: This flow requires Vivado 2017.1. Old versions are known to fail.
These will place the files under `builds/e300artydevkit/obj`. These will place the files under `builds/e300artydevkit/obj`.
@ -82,7 +82,7 @@ $ make -f Makefile.u500vc707devkit verilog
$ make -f Makefile.u500vc707devkit mcs $ make -f Makefile.u500vc707devkit mcs
``` ```
Note: This flow requires vivado 2016.1. Newer versions are known to fail. Note: This flow requires Vivado 2016.4. Newer versions are known to fail.
These will place the files under `builds/u500vc707devkit/obj`. These will place the files under `builds/u500vc707devkit/obj`.

View File

@ -38,7 +38,7 @@
#define DEBUG_CTRL_SIZE _AC(0x1000,UL) #define DEBUG_CTRL_SIZE _AC(0x1000,UL)
#define ERROR_MEM_ADDR _AC(0x3000,UL) #define ERROR_MEM_ADDR _AC(0x3000,UL)
#define ERROR_MEM_SIZE _AC(0x1000,UL) #define ERROR_MEM_SIZE _AC(0x1000,UL)
#define GPIO_CTRL_ADDR _AC(0x54002000,UL) #define GPIO_CTRL_ADDR _AC(0x64002000,UL)
#define GPIO_CTRL_SIZE _AC(0x1000,UL) #define GPIO_CTRL_SIZE _AC(0x1000,UL)
#define MASKROM_MEM_ADDR _AC(0x10000,UL) #define MASKROM_MEM_ADDR _AC(0x10000,UL)
#define MASKROM_MEM_SIZE _AC(0x2000,UL) #define MASKROM_MEM_SIZE _AC(0x2000,UL)
@ -46,11 +46,11 @@
#define MEMORY_MEM_SIZE _AC(0x40000000,UL) #define MEMORY_MEM_SIZE _AC(0x40000000,UL)
#define PLIC_CTRL_ADDR _AC(0xc000000,UL) #define PLIC_CTRL_ADDR _AC(0xc000000,UL)
#define PLIC_CTRL_SIZE _AC(0x4000000,UL) #define PLIC_CTRL_SIZE _AC(0x4000000,UL)
#define SPI_CTRL_ADDR _AC(0x54001000,UL) #define SPI_CTRL_ADDR _AC(0x64001000,UL)
#define SPI_CTRL_SIZE _AC(0x1000,UL) #define SPI_CTRL_SIZE _AC(0x1000,UL)
#define TEST_CTRL_ADDR _AC(0x4000,UL) #define TEST_CTRL_ADDR _AC(0x4000,UL)
#define TEST_CTRL_SIZE _AC(0x1000,UL) #define TEST_CTRL_SIZE _AC(0x1000,UL)
#define UART_CTRL_ADDR _AC(0x54000000,UL) #define UART_CTRL_ADDR _AC(0x64000000,UL)
#define UART_CTRL_SIZE _AC(0x1000,UL) #define UART_CTRL_SIZE _AC(0x1000,UL)
// IOF masks // IOF masks

View File

@ -33,6 +33,9 @@ static inline void kputc(char c)
while ((int32_t)(*tx) < 0); while ((int32_t)(*tx) < 0);
*tx = c; *tx = c;
#endif #endif
volatile uint32_t *term = (void *) 0x64003000; // Terminal (32 bit)
while ((int32_t)(*term) < 0);
*term = c;
} }
extern void kputs(const char *); extern void kputs(const char *);

View File

@ -10,9 +10,13 @@
#define MAX_CORES 8 #define MAX_CORES 8
#define PAYLOAD_SIZE (16 << 11) //#define PAYLOAD_START 0
//#define PAYLOAD_CRC7 0xE1
#define PAYLOAD_START 2048
#define PAYLOAD_CRC7 0x51
#define PAYLOAD_SIZE (16 << 12)
#define F_CLK 50000000UL #define F_CLK 60000000UL
static volatile uint32_t * const spi = (void *)(SPI_CTRL_ADDR); static volatile uint32_t * const spi = (void *)(SPI_CTRL_ADDR);
@ -163,7 +167,7 @@ static int copy(void)
kprintf("LOADING "); kprintf("LOADING ");
REG32(spi, SPI_REG_SCKDIV) = (F_CLK / 20000000UL); REG32(spi, SPI_REG_SCKDIV) = (F_CLK / 20000000UL);
if (sd_cmd(0x52, 0, 0xE1) != 0x00) { if (sd_cmd(0x52, PAYLOAD_START, PAYLOAD_CRC7) != 0x00) {
sd_cmd_end(); sd_cmd_end();
return 1; return 1;
} }

View File

@ -4,7 +4,7 @@ name := "freedom"
version := "0.1.0" version := "0.1.0"
lazy val commonSettings = Seq( lazy val commonSettings = Seq(
scalaVersion := "2.11.7", // This needs to match rocket-chip's scalaVersion scalaVersion := "2.11.12", // This needs to match rocket-chip's scalaVersion
scalacOptions ++= Seq( scalacOptions ++= Seq(
"-deprecation", "-deprecation",
"-feature", "-feature",

View File

@ -63,7 +63,7 @@ endif
verilog: $(verilog) verilog: $(verilog)
romgen := $(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).rom.v romgen := $(BUILD_DIR)/$(CONFIG_PROJECT).$(CONFIG).rom.v
$(romgen): $(verilog) $(romgen): $(verilog) $(BOOTROM_DIR)
ifneq ($(BOOTROM_DIR),"") ifneq ($(BOOTROM_DIR),"")
$(MAKE) -C $(BOOTROM_DIR) romgen $(MAKE) -C $(BOOTROM_DIR) romgen
mv $(BUILD_DIR)/rom.v $@ mv $(BUILD_DIR)/rom.v $@

View File

@ -0,0 +1,58 @@
// See LICENSE for license details.
package sifive.freedom.unleashed.u500ml507devkit
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.system._
import freechips.rocketchip.tile._
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.spi._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.terminal._
import sifive.fpgashells.devices.xilinx.xilinxml507mig._
// Default FreedomUML507Config
class FreedomUML507Config extends Config(
new WithoutTLMonitors ++
new WithJtagDTM ++
new WithClockFrequency(60000000) ++ // 60 MHz
new WithNMemoryChannels(1) ++
new WithNSmallLinuxCores(1) ++
new BaseConfig
)
// Freedom U500 ML507 Dev Kit Peripherals
class U500ML507DevKitPeripherals extends Config((site, here, up) => {
case PeripheryUARTKey => List(
UARTParams(address = BigInt(0x64000000L)))
case PeripherySPIKey => List(
SPIParams(rAddress = BigInt(0x64001000L)))
case PeripheryGPIOKey => List(
GPIOParams(address = BigInt(0x64002000L), width = 8))
case PeripheryTerminalKey =>
TerminalParams(address = BigInt(0x64003000L))
case PeripheryMaskROMKey => List(
MaskROMParams(address = 0x10000, name = "BootROM"))
})
// Freedom U500 ML507 Dev Kit
class U500ML507DevKitConfig extends Config(
new WithNExtTopInterrupts(0) ++
new U500ML507DevKitPeripherals ++
new FreedomUML507Config().alter((site,here,up) => {
case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=128)
case MemoryML507Key => XilinxML507MIGParams(address = Seq(AddressSet(0x80000000L,0x10000000L-1))) // 256 MiB
case DTSTimebase => BigInt(1000000)
case ExtMem => up(ExtMem).copy(size = 0x10000000L)
case JtagDTMKey => new JtagDTMConfig (
idcodeVersion = 2, // 1 was legacy (FE310-G000, Acai).
idcodePartNum = 0x000, // Decided to simplify.
idcodeManufId = 0x489, // As Assigned by JEDEC to SiFive. Only used in wrappers / test harnesses.
debugIdleCycles = 5) // Reasonable guess for synchronization
})
)

View File

@ -0,0 +1,66 @@
// See LICENSE for license details.
package sifive.freedom.unleashed.u500ml507devkit
import Chisel._
import chisel3.experimental.{withClockAndReset}
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.pinctrl.{BasePin}
import sifive.fpgashells.shell.xilinx.ml507shell._
//-------------------------------------------------------------------------
// PinGen
//-------------------------------------------------------------------------
object PinGen {
def apply(): BasePin = {
new BasePin()
}
}
//-------------------------------------------------------------------------
// U500ML507DevKitFPGAChip
//-------------------------------------------------------------------------
class U500ML507DevKitFPGAChip(implicit override val p: Parameters)
extends ML507Shell
with HasDebugJTAG {
//-----------------------------------------------------------------------
// DUT
//-----------------------------------------------------------------------
withClockAndReset(dut_clock, dut_reset) {
val dut = Module(LazyModule(new U500ML507DevKitSystem).module)
//---------------------------------------------------------------------
// Connect peripherals
//---------------------------------------------------------------------
connectTerminal (dut)
connectDDRMemory(dut)
connectDebugJTAG(dut)
connectSPI (dut)
connectUART (dut)
//---------------------------------------------------------------------
// GPIO
//---------------------------------------------------------------------
val gpioParams = p(PeripheryGPIOKey)
val gpio_pins = Wire(new GPIOPins(() => PinGen(), gpioParams(0)))
GPIOPinsFromPort(gpio_pins, dut.gpio(0))
gpio_pins.pins.zipWithIndex.foreach {
case(pin, idx) =>
pin.i.ival := dip(idx)
led(idx) := pin.o.oval
}
}
}

View File

@ -0,0 +1,48 @@
// See LICENSE for license details.
package sifive.freedom.unleashed.u500ml507devkit
import Chisel._
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.debug._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.system._
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.spi._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.terminal._
import sifive.fpgashells.devices.xilinx.xilinxml507mig._
//-------------------------------------------------------------------------
// U500ML507DevKitSystem
//-------------------------------------------------------------------------
class U500ML507DevKitSystem(implicit p: Parameters) extends RocketSubsystem
with HasPeripheryMaskROMSlave
with HasPeripheryDebug
with HasSystemErrorSlave
with HasPeripheryUART
with HasPeripheryTerminal
with HasPeripherySPI
with HasPeripheryGPIO
with HasMemoryML507 {
override lazy val module = new U500ML507DevKitSystemModule(this)
}
class U500ML507DevKitSystemModule[+L <: U500ML507DevKitSystem](_outer: L)
extends RocketSubsystemModuleImp(_outer)
with HasRTCModuleImp
with HasPeripheryDebugModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryTerminalModuleImp
with HasPeripherySPIModuleImp
with HasPeripheryGPIOModuleImp
with HasMemoryML507ModuleImp {
// Reset vector is set to the location of the mask rom
val maskROMParams = p(PeripheryMaskROMKey)
global_reset_vector := maskROMParams(0).address.U
}

View File

@ -0,0 +1,233 @@
// See LICENSE for license details.
package sifive.freedom.unleashed.vc707.iofpga
import Chisel._
import chisel3.experimental.{withClockAndReset}
import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.util.{ElaborationArtefacts,ResetCatchAndSync}
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.pinctrl.{BasePin}
import sifive.blocks.devices.msi._
import sifive.blocks.devices.chiplink._
import sifive.fpgashells.shell.xilinx.vc707shell.{VC707Shell,HasPCIe,HasDDR3,HasVC707ChipLink}
import sifive.fpgashells.ip.xilinx.{IOBUF,vc707_sys_clock_mmcm3}
import sifive.fpgashells.devices.xilinx.xilinxvc707mig._
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._
import sifive.freedom.unleashed.u500vc707devkit.FreedomUVC707Config
//-------------------------------------------------------------------------
// PinGen
//-------------------------------------------------------------------------
object PinGen {
def apply(): BasePin = {
new BasePin()
}
}
//-------------------------------------------------------------------------
// ShadowRAMHack -- shadow 512MiB of DDR at 0x6000_0000 from 0x30_0000_000
// this makes it possible to boot linux using FPGA DDR
//-------------------------------------------------------------------------
class ShadowRAMHack(implicit p: Parameters) extends LazyModule
{
val from = AddressSet(0x60000000L, 0x1fffffffL)
val to = AddressSet(0x3000000000L, 0x1fffffffL)
val node = TLAdapterNode(
clientFn = {cp => cp },
managerFn = { mp =>
require (mp.managers.size == 1)
mp.copy(managers = mp.managers.map { m =>
m.copy(address = m.address ++ Seq(from))
})
})
lazy val module = new LazyModuleImp(this) {
(node.in zip node.out) foreach { case ((in, _), (out, _)) =>
out <> in
out.a.bits.address := Mux(
from.contains(in.a.bits.address),
in.a.bits.address + UInt(to.base - from.base),
in.a.bits.address)
}
}
}
//-------------------------------------------------------------------------
// IOFPGAChip
//-------------------------------------------------------------------------
class IOFPGA(
localRoute: Seq[AddressSet],
ddrparams: XilinxVC707MIGParams,
chiplinkparams: ChipLinkParams,
gpioparams: GPIOParams)(implicit p: Parameters) extends LazyModule
{
val link = LazyModule(new ChipLink(chiplinkparams))
val sbar = LazyModule(new TLXbar)
val xbar = LazyModule(new TLXbar)
val mbar = LazyModule(new TLXbar)
val serr = LazyModule(new TLError(ErrorParams(Seq(AddressSet(0x2800000000L, 0xffffffffL)), 8, 128, true), beatBytes = 8))
val gpio = LazyModule(new TLGPIO(w = 8, c = gpioparams))
val xilinxvc707mig = LazyModule(new XilinxVC707MIG(ddrparams))
val xilinxvc707pcie = LazyModule(new XilinxVC707PCIeX1)
val hack = LazyModule(new ShadowRAMHack)
val msimaster = LazyModule(new MSIMaster(Seq(MSITarget(address=0x2020000, spacing=4, number=10))))
private def filter(m: TLManagerParameters) = // keep only managers that are locally routed
if (m.address.exists(a => localRoute.exists(_.overlaps(a)))) Some(m) else None
// local master Xbar
mbar.node := msimaster.masterNode
mbar.node := TLFIFOFixer() := xilinxvc707pcie.crossTLOut := xilinxvc707pcie.master
// split local master traffic either to local routing or off-chip
link.node := TLBuffer() := mbar.node
xbar.node := TLFilter(filter) := TLBuffer() := mbar.node
xbar.node := TLBuffer() := link.node
// receive traffic either from local routing or from off-chip
sbar.node := TLBuffer() := TLAtomicAutomata() := TLFIFOFixer() := TLHintHandler() := TLBuffer() := TLWidthWidget(4) := xbar.node
// local slave Xbar
serr.node := sbar.node
gpio.node := TLFragmenter(8,64,true) := sbar.node
xilinxvc707mig.node := hack.node := sbar.node
xilinxvc707pcie.slave := xilinxvc707pcie.crossTLIn := TLWidthWidget(8) := sbar.node
xilinxvc707pcie.control := xilinxvc707pcie.crossTLIn := TLWidthWidget(8) := sbar.node
// interrupts are fed into chiplink via MSI
msimaster.intNode := xilinxvc707pcie.crossIntOut := xilinxvc707pcie.intnode
msimaster.intNode := gpio.intnode
lazy val module = new LazyModuleImp(this) {
val io = IO (new Bundle {
val chiplink = new WideDataLayerPort(chiplinkparams)
val gpio = new GPIOPortIO(gpioparams)
val xilinxvc707mig = new XilinxVC707MIGIO(AddressRange.fromSets(ddrparams.address).head.size)
val xilinxvc707pcie = new XilinxVC707PCIeX1IO
val rxlocked = Bool(INPUT)
})
io.xilinxvc707pcie <> xilinxvc707pcie.module.io.port
xilinxvc707pcie.module.clock := xilinxvc707pcie.module.io.port.axi_aclk_out
xilinxvc707pcie.module.reset := ~io.xilinxvc707pcie.axi_aresetn
io.xilinxvc707mig <> xilinxvc707mig.module.io.port
// Hold ChipLink in reset for a bit after power-on
val timer = RegInit(UInt(255, width=8))
timer := timer - timer.orR
io.chiplink <> link.module.io.port
link.module.io.c2b_clk := clock
link.module.io.c2b_rst := ResetCatchAndSync(clock, reset || timer.orR || !io.rxlocked)
io.gpio <> gpio.module.io.port
}
}
class IOFPGAChip(implicit override val p: Parameters) extends VC707Shell
with HasVC707ChipLink {
val ddrParams = XilinxVC707MIGParams(address = Seq(AddressSet(0x3000000000L, 0xFFFFFFFFL))) // 192GB - 196GB (behind L2)
val chipLinkParams = ChipLinkParams(
TLUH = AddressSet.misaligned(0, 0x40000000L), // Aloe MMIO [ 0GB, 1GB)
TLC = AddressSet.misaligned(0x60000000L, 0x20000000L) ++ // local memory behind L2 [1.5GB, 2GB)
AddressSet.misaligned(0x80000000L, 0x2000000000L - 0x80000000L) ++ // Aloe DDR [ 2GB, 128GB)
AddressSet.misaligned(0x3000000000L, 0x1000000000L), // local memory behind L2 [192GB, 256GB)
syncTX = true
)
val localRoute = AddressSet.misaligned(0x40000000L, 0x20000000L) ++ // local MMIO [ 1GB, 1.5GB)
AddressSet.misaligned(0x2000000000L, 0x1000000000L) // local MMIO [128GB, 192GB)
val gpioParams = GPIOParams(address = BigInt(0x2400000000L), width = 4)
// ChipLink skew RX clock
val vc707_sys_clock_mmcm3 = Module(new vc707_sys_clock_mmcm3)
//-----------------------------------------------------------------------
// DUT
//-----------------------------------------------------------------------
// System runs at 100 MHz
dut_clock := clk100
dut_ndreset := !ereset_n // debug reset is external
val ddr = IO(new XilinxVC707MIGPads(ddrParams))
val pcie = IO(new XilinxVC707PCIeX1Pads)
withClockAndReset(dut_clock, dut_reset) {
val iofpga = Module(LazyModule(new IOFPGA(localRoute,ddrParams,chipLinkParams,gpioParams)).module)
//---------------------------------------------------------------------
// DDR
//---------------------------------------------------------------------
iofpga.io.xilinxvc707mig.sys_clk_i := sys_clock.asUInt
mig_clock := iofpga.io.xilinxvc707mig.ui_clk
mig_sys_reset := iofpga.io.xilinxvc707mig.ui_clk_sync_rst
mig_mmcm_locked := iofpga.io.xilinxvc707mig.mmcm_locked
iofpga.io.xilinxvc707mig.aresetn := mig_resetn
iofpga.io.xilinxvc707mig.sys_rst := sys_reset
ddr <> iofpga.io.xilinxvc707mig
//---------------------------------------------------------------------
// PCIe
//---------------------------------------------------------------------
iofpga.io.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn
pcie_dat_clock := iofpga.io.xilinxvc707pcie.axi_aclk_out
pcie_cfg_clock := iofpga.io.xilinxvc707pcie.axi_ctl_aclk_out
mmcm_lock_pcie := iofpga.io.xilinxvc707pcie.mmcm_lock
iofpga.io.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn
pcie <> iofpga.io.xilinxvc707pcie
//---------------------------------------------------------------------
// ChipLink
//---------------------------------------------------------------------
chiplink <> iofpga.io.chiplink
constrainChipLink(iofpga=true)
chiplink.c2b.clk := clk100_180
vc707_sys_clock_mmcm3.io.reset := reset
vc707_sys_clock_mmcm3.io.clk_in1 := chiplink.b2c.clk.asUInt.toBool
iofpga.io.chiplink.b2c.clk := vc707_sys_clock_mmcm3.io.clk_out1
iofpga.io.rxlocked := vc707_sys_clock_mmcm3.io.locked
//---------------------------------------------------------------------
// GPIO
//---------------------------------------------------------------------
val gpio_pins = Wire(new GPIOPins(() => PinGen(), gpioParams))
GPIOPinsFromPort(gpio_pins, iofpga.io.gpio)
gpio_pins.pins.foreach { _.i.ival := Bool(false) }
gpio_pins.pins.zipWithIndex.foreach {
case(pin, idx) => led(idx) := pin.o.oval
}
// diagnostics
led(4) := vc707_sys_clock_mmcm3.io.locked
led(5) := ereset_n
led(6) := iofpga.io.chiplink.b2c.send
led(7) := iofpga.io.chiplink.c2b.send
}
}
class IOFPGAConfig extends Config(new FreedomUVC707Config)