├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .gitmodules
├── .travis.yml
├── LICENSE.Berkeley
├── LICENSE.SiFive
├── LICENSE.jtag
├── Makefrag
├── README-rocketchip.md
├── README.md
├── README_LvNA.md
├── README_TRAVIS.md
├── bootrom
├── .gitignore
├── Makefile
├── bootrom.S
└── linker.ld
├── build.sbt
├── csrc
├── client.c
└── dmi.h
├── emulator
├── .gitignore
├── Makefile
└── Makefrag-verilator
├── fpga
├── .gitignore
├── Makefile
├── Makefile.check
├── Makefile.sw
├── README.md
├── board
│ ├── common.tcl
│ ├── sidewinder
│ │ ├── bd
│ │ │ └── prm.tcl
│ │ ├── constr
│ │ │ └── constr.xdc
│ │ ├── mk.tcl
│ │ ├── rtl
│ │ │ ├── addr_mapper.v
│ │ │ └── system_top.v
│ │ └── vivado
│ │ │ ├── README.md
│ │ │ └── sidewinder
│ │ │ └── Fidus
│ │ │ └── 2.0
│ │ │ ├── Fidus.jpeg
│ │ │ ├── board.xml
│ │ │ └── preset.xml
│ ├── ultraZ
│ │ ├── bd
│ │ │ └── prm.tcl
│ │ ├── constr
│ │ │ └── constr.xdc
│ │ ├── mk.tcl
│ │ └── rtl
│ │ │ ├── addr_mapper.v
│ │ │ └── system_top.v
│ ├── zcu102
│ │ ├── bd
│ │ │ └── prm.tcl
│ │ ├── constr
│ │ │ └── constr.xdc
│ │ ├── mk.tcl
│ │ ├── patch
│ │ │ └── 0001-patch-for-new-version-of-zcu102.patch
│ │ └── rtl
│ │ │ ├── addr_mapper.v
│ │ │ └── system_top.v
│ └── zedboard
│ │ ├── bd
│ │ └── prm.tcl
│ │ ├── constr
│ │ └── constr.xdc
│ │ ├── mk.tcl
│ │ └── rtl
│ │ ├── addr_mapper.v
│ │ └── system_top.v
├── boot
│ ├── .gitignore
│ ├── README.md
│ ├── bootgen-zynq.bif
│ ├── bootgen-zynqmp.bif
│ ├── bug-list.md
│ └── mk.tcl
├── doc
│ ├── lazy_module.md
│ ├── openocd-rpc-on-smp.md
│ ├── riscv-pard-fpga-how-to.md
│ ├── riscv-pard-fpga-old.md
│ ├── rocketchip-bus.md
│ ├── rocketchip-pcie-ssd-debian.md
│ ├── rocketchip_config_detail.md
│ ├── rocketchip_linux_kernel_clock.md
│ ├── rocketchip_on_pard_details.md
│ ├── rocketchip_on_pard_journal_tailored.md
│ └── rocketchip_on_pard_simulation.md
├── emu
│ ├── Makefile
│ ├── gen_bin.sh
│ ├── gen_dtb_bin.sh
│ ├── gen_nohype_dtb
│ ├── mem_init
│ ├── py-check.sh
│ └── python
│ │ ├── .gitignore
│ │ ├── common.py
│ │ └── emu_wrapper.py
├── lib
│ ├── dmi
│ │ ├── dmi.xml
│ │ └── dmi_rtl.xml
│ ├── include
│ │ ├── axi.vh
│ │ └── dmi.vh
│ ├── jtag
│ │ ├── axi4_lite_if.v
│ │ ├── axi_jtag_v1_0.v
│ │ └── jtag_proc.v
│ └── util
│ │ ├── axi_reg.v
│ │ ├── cdma_addr.v
│ │ ├── cross_domain.v
│ │ ├── leds_mux_controller.v
│ │ └── uart_inverter.v
├── openocd_rpc
│ ├── .gitignore
│ ├── dm_reg.py
│ ├── dm_utils.py
│ ├── dmcontrol
│ ├── dmstatus
│ ├── dpc
│ ├── get_cp
│ ├── get_mem
│ ├── halt
│ ├── haltsum0
│ ├── log
│ ├── openocd.py
│ ├── put_mem
│ ├── restart
│ ├── resume
│ ├── scause
│ ├── sepc
│ ├── set_cp
│ ├── show_cache_capacity
│ ├── show_traffic
│ └── stval
├── pardcore
│ ├── Makefile
│ ├── bd
│ │ └── pardcore.tcl
│ └── rtl
│ │ └── rocket
│ │ └── .gitignore
└── scripts
│ ├── account.py
│ ├── gen.sh
│ └── range.py
├── macros
└── src
│ └── main
│ └── scala
│ └── ValName.scala
├── origin_rocket_README.md
├── project
├── .gitignore
├── build.properties
└── plugins.sbt
├── regression
├── .gitignore
└── Makefile
├── riscv-tools.hash
├── sbt-launch.jar
├── scripts
├── .gitignore
├── Makefile
├── RocketSim.cfg
├── RocketSim.py
├── RocketSim32.py
├── RocketSim64.py
├── authors
├── check_cache_trace.py
├── check_comparator_trace.py
├── copyright-file
├── debug_rom
│ ├── .gitignore
│ ├── Makefile
│ ├── debug_rom.S
│ └── link.ld
├── modify-copyright
├── toaxe.py
├── tracegen+check.sh
├── tracegen.py
├── tracestats.py
├── vlsi_mem_gen
└── vlsi_rom_gen
├── src
└── main
│ ├── resources
│ ├── csrc
│ │ ├── SimDTM.cc
│ │ ├── SimJTAG.cc
│ │ ├── comlog.cc
│ │ ├── emulator.cc
│ │ ├── float_fix.cc
│ │ ├── remote_bitbang.cc
│ │ ├── remote_bitbang.h
│ │ └── verilator.h
│ └── vsrc
│ │ ├── AsyncResetReg.v
│ │ ├── ClockDivider2.v
│ │ ├── ClockDivider3.v
│ │ ├── EICG_wrapper.v
│ │ ├── SimDTM.v
│ │ ├── SimJTAG.v
│ │ ├── TestDriver.v
│ │ ├── UARTPrinter.v
│ │ └── plusarg_reader.v
│ └── scala
│ ├── amba
│ ├── ahb
│ │ ├── Bundles.scala
│ │ ├── Nodes.scala
│ │ ├── Parameters.scala
│ │ ├── Protocol.scala
│ │ ├── RegisterRouter.scala
│ │ ├── SRAM.scala
│ │ ├── Test.scala
│ │ ├── ToTL.scala
│ │ ├── Xbar.scala
│ │ └── package.scala
│ ├── apb
│ │ ├── Bundles.scala
│ │ ├── Nodes.scala
│ │ ├── Parameters.scala
│ │ ├── Protocol.scala
│ │ ├── RegisterRouter.scala
│ │ ├── SRAM.scala
│ │ ├── Test.scala
│ │ ├── Xbar.scala
│ │ └── package.scala
│ └── axi4
│ │ ├── AsyncCrossing.scala
│ │ ├── Buffer.scala
│ │ ├── Bundles.scala
│ │ ├── CrossingHelper.scala
│ │ ├── Deinterleaver.scala
│ │ ├── Delayer.scala
│ │ ├── Dumper.scala
│ │ ├── Filter.scala
│ │ ├── Fragmenter.scala
│ │ ├── IdIndexer.scala
│ │ ├── Nodes.scala
│ │ ├── Parameters.scala
│ │ ├── Protocol.scala
│ │ ├── RegisterRouter.scala
│ │ ├── SRAM.scala
│ │ ├── Test.scala
│ │ ├── ToTL.scala
│ │ ├── UserYanker.scala
│ │ ├── Xbar.scala
│ │ └── package.scala
│ ├── config
│ └── Config.scala
│ ├── debug
│ ├── DebugBundles.scala
│ └── Stats.scala
│ ├── devices
│ ├── debug
│ │ ├── Custom.scala
│ │ ├── DMI.scala
│ │ ├── Debug.scala
│ │ ├── DebugRomContents.scala
│ │ ├── DebugTransport.scala
│ │ ├── Periphery.scala
│ │ ├── SBA.scala
│ │ ├── abstract_commands.scala
│ │ └── dm_registers.scala
│ └── tilelink
│ │ ├── BootROM.scala
│ │ ├── BusBlocker.scala
│ │ ├── BusBypass.scala
│ │ ├── CLINT.scala
│ │ ├── CanHaveBuiltInDevices.scala
│ │ ├── Deadlock.scala
│ │ ├── DevNull.scala
│ │ ├── Error.scala
│ │ ├── MaskROM.scala
│ │ ├── MasterMux.scala
│ │ ├── PhysicalFilter.scala
│ │ ├── Plic.scala
│ │ ├── TestRAM.scala
│ │ └── Zero.scala
│ ├── diplomacy
│ ├── AddressDecoder.scala
│ ├── AddressRange.scala
│ ├── BundleBridge.scala
│ ├── ClockDomain.scala
│ ├── Clone.scala
│ ├── CloneModule.scala
│ ├── DeviceTree.scala
│ ├── FixedClockResource.scala
│ ├── JSON.scala
│ ├── LazyModule.scala
│ ├── Nodes.scala
│ ├── Parameters.scala
│ ├── Resources.scala
│ ├── SRAM.scala
│ ├── ValName.scala
│ └── package.scala
│ ├── diplomaticobjectmodel
│ ├── DiplomaticObjectModel.scala
│ ├── DiplomaticObjectModelUtils.scala
│ └── model
│ │ ├── ISASpecifications.scala
│ │ ├── OMAddressing.scala
│ │ ├── OMBase.scala
│ │ ├── OMBranchPredictor.scala
│ │ ├── OMCLINT.scala
│ │ ├── OMCaches.scala
│ │ ├── OMCore.scala
│ │ ├── OMDebug.scala
│ │ ├── OMDevice.scala
│ │ ├── OMFPU.scala
│ │ ├── OMISA.scala
│ │ ├── OMInterrupts.scala
│ │ ├── OMMemory.scala
│ │ ├── OMMulDiv.scala
│ │ ├── OMPLIC.scala
│ │ ├── OMPMP.scala
│ │ ├── OMPerformanceMonitor.scala
│ │ ├── OMRTLModule.scala
│ │ ├── OMRegFieldAccessType.scala
│ │ ├── OMRegFieldRdAction.scala
│ │ ├── OMRegFieldWrType.scala
│ │ ├── OMRocketCore.scala
│ │ └── OMSpecification.scala
│ ├── groundtest
│ ├── Configs.scala
│ ├── DummyPTW.scala
│ ├── Generator.scala
│ ├── GroundTestSubsystem.scala
│ ├── Package.scala
│ ├── Status.scala
│ ├── TestHarness.scala
│ ├── Tile.scala
│ └── TraceGen.scala
│ ├── interrupts
│ ├── Bundles.scala
│ ├── Crossing.scala
│ ├── CrossingHelper.scala
│ ├── Nodes.scala
│ ├── NullIntSource.scala
│ ├── Parameters.scala
│ ├── RegisterRouter.scala
│ ├── Xbar.scala
│ └── package.scala
│ ├── jtag
│ ├── JtagShifter.scala
│ ├── JtagStateMachine.scala
│ ├── JtagTap.scala
│ ├── JtagUtils.scala
│ ├── Utils.scala
│ └── package.scala
│ ├── l2cache
│ ├── SimpleL2.scala
│ └── TLSimpleL2.scala
│ ├── lvna
│ ├── Dirty.scala
│ ├── ILA.scala
│ ├── LvNAConfigs.scala
│ ├── LvNATop.scala
│ └── controlplane
│ │ ├── ControlPlane.scala
│ │ ├── TokenBucket.scala
│ │ └── TokenBucketNode.scala
│ ├── regmapper
│ ├── Annotation.scala
│ ├── DescribedReg.scala
│ ├── RegField.scala
│ ├── RegMapper.scala
│ ├── RegisterCrossing.scala
│ └── RegisterRouter.scala
│ ├── rocket
│ ├── ALU.scala
│ ├── AMOALU.scala
│ ├── BTB.scala
│ ├── Breakpoint.scala
│ ├── CSR.scala
│ ├── Consts.scala
│ ├── DCache.scala
│ ├── Decode.scala
│ ├── Events.scala
│ ├── Frontend.scala
│ ├── HellaCache.scala
│ ├── HellaCacheArbiter.scala
│ ├── IBuf.scala
│ ├── ICache.scala
│ ├── IDecode.scala
│ ├── Instructions.scala
│ ├── Multiplier.scala
│ ├── NBDcache.scala
│ ├── PMP.scala
│ ├── PTW.scala
│ ├── Prefetch.scala
│ ├── RVC.scala
│ ├── RocketCore.scala
│ ├── ScratchpadSlavePort.scala
│ ├── SimpleHellaCacheIF.scala
│ ├── TLB.scala
│ ├── TLBPermissions.scala
│ └── package.scala
│ ├── scie
│ └── SCIE.scala
│ ├── sifive-blocks
│ ├── LICENSE
│ ├── devices
│ │ └── uart
│ │ │ ├── UART.scala
│ │ │ ├── UARTCtrlRegs.scala
│ │ │ ├── UARTPeriphery.scala
│ │ │ └── UARTPrinter.scala
│ ├── util
│ │ ├── DeglitchShiftRegister.scala
│ │ ├── RegMapFIFO.scala
│ │ ├── ResetCatchAndSync.scala
│ │ ├── SRLatch.scala
│ │ ├── ShiftReg.scala
│ │ └── Timer.scala
│ └── vsrc
│ │ ├── SRLatch.v
│ │ └── vc707reset.v
│ ├── subsystem
│ ├── BaseSubsystem.scala
│ ├── Configs.scala
│ ├── CrossingWrapper.scala
│ ├── FrontBus.scala
│ ├── HasTiles.scala
│ ├── InterruptBus.scala
│ ├── MemoryBus.scala
│ ├── PeripheryBus.scala
│ ├── Ports.scala
│ ├── RTC.scala
│ ├── ResetVector.scala
│ ├── RocketSubsystem.scala
│ └── SystemBus.scala
│ ├── system
│ ├── Configs.scala
│ ├── ExampleRocketSystem.scala
│ ├── Generator.scala
│ ├── RocketTestSuite.scala
│ └── TestHarness.scala
│ ├── tile
│ ├── BaseTile.scala
│ ├── BusErrorUnit.scala
│ ├── Core.scala
│ ├── CustomCSRs.scala
│ ├── FPU.scala
│ ├── Interrupts.scala
│ ├── L1Cache.scala
│ ├── LazyRoCC.scala
│ └── RocketTile.scala
│ ├── tilelink
│ ├── AddressAdjuster.scala
│ ├── Arbiter.scala
│ ├── AsyncCrossing.scala
│ ├── AtomicAutomata.scala
│ ├── Atomics.scala
│ ├── BankBinder.scala
│ ├── Broadcast.scala
│ ├── Buffer.scala
│ ├── Bundles.scala
│ ├── BusWrapper.scala
│ ├── CacheCork.scala
│ ├── CrossingHelper.scala
│ ├── Delayer.scala
│ ├── Dumper.scala
│ ├── Edges.scala
│ ├── ErrorEvaluator.scala
│ ├── Example.scala
│ ├── FIFOFixer.scala
│ ├── Filter.scala
│ ├── Fragmenter.scala
│ ├── Fuzzer.scala
│ ├── HintHandler.scala
│ ├── Isolation.scala
│ ├── Map.scala
│ ├── Metadata.scala
│ ├── Monitor.scala
│ ├── Nodes.scala
│ ├── Parameters.scala
│ ├── PatternPusher.scala
│ ├── ProbePicker.scala
│ ├── RAMModel.scala
│ ├── RationalCrossing.scala
│ ├── RegionReplication.scala
│ ├── RegisterRouter.scala
│ ├── RegisterRouterTest.scala
│ ├── SRAM.scala
│ ├── SourceShrinker.scala
│ ├── ToAHB.scala
│ ├── ToAPB.scala
│ ├── ToAXI4.scala
│ ├── WidthWidget.scala
│ ├── Xbar.scala
│ └── package.scala
│ ├── unittest
│ ├── Configs.scala
│ ├── Generator.scala
│ ├── TestGenerator.scala
│ ├── TestHarness.scala
│ ├── UnitTest.scala
│ └── package.scala
│ └── util
│ ├── Annotations.scala
│ ├── Arbiters.scala
│ ├── AsyncQueue.scala
│ ├── AsyncResetReg.scala
│ ├── Broadcaster.scala
│ ├── CRC.scala
│ ├── CheckOneHot.scala
│ ├── ClockDivider.scala
│ ├── ClockGate.scala
│ ├── CoreMonitor.scala
│ ├── Counters.scala
│ ├── Crossing.scala
│ ├── DescribedSRAM.scala
│ ├── ECC.scala
│ ├── Frequency.scala
│ ├── GeneratorUtils.scala
│ ├── GenericParameterizedBundle.scala
│ ├── GlobalTimer.scala
│ ├── HellaQueue.scala
│ ├── HeterogeneousBag.scala
│ ├── IDPool.scala
│ ├── IdentityModule.scala
│ ├── LCG.scala
│ ├── LanePositionedQueue.scala
│ ├── LatencyPipe.scala
│ ├── Misc.scala
│ ├── MultiLaneQueue.scala
│ ├── MultiPortQueue.scala
│ ├── MultiWidthFifo.scala
│ ├── MuxLiteral.scala
│ ├── PSDTestMode.scala
│ ├── PlusArg.scala
│ ├── PrefixSum.scala
│ ├── Property.scala
│ ├── ROMGenerator.scala
│ ├── RationalCrossing.scala
│ ├── ReduceOthers.scala
│ ├── ReorderQueue.scala
│ ├── Repeater.scala
│ ├── Replacement.scala
│ ├── ResetCatchAndSync.scala
│ ├── ScatterGather.scala
│ ├── SeededRandom.scala
│ ├── ShiftQueue.scala
│ ├── ShiftReg.scala
│ ├── Timer.scala
│ └── package.scala
└── vsim
├── .gitignore
├── Makefile
├── Makefrag
├── Makefrag-verilog
└── vlsi_mem_gen
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | **Type of issue**: bug report | feature request | other enhancement
8 |
9 |
10 | **Impact**: no functional change | API addition (no impact on existing code) | API modification | unknown
11 |
12 |
13 | **Development Phase**: request | proposal
14 |
15 | **Other information**
16 |
17 |
18 | **If the current behavior is a bug, please provide the steps to reproduce the problem:**
19 |
20 | **What is the current behavior?**
21 |
22 | **What is the expected behavior?**
23 |
24 | **Please tell us about your environment:**
25 |
29 | **What is the use case for changing the behavior?**
30 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | **Related issue**:
5 |
6 |
7 | **Type of change**: bug report | feature request | other enhancement
8 |
9 |
10 | **Impact**: no functional change | API addition (no impact on existing code) | API modification
11 |
12 |
13 | **Development Phase**: proposal | implementation
14 |
15 | **Release Notes**
16 |
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | project/target
3 | *.swp
4 | *~
5 | .addons-dont-touch
6 | /lib/
7 | ControlPlanes.v
8 |
9 | # ignore intellij idea projects under src/main/scala
10 | src/main/scala/.idea/
11 | src/main/scala/build.sbt
12 | src/main/scala/project/
13 |
14 | .idea/
15 | boom-ether.err
16 | bootrom/bootrom.txt
17 | emulator/boom-failed.md
18 | emulator/log.txt
19 | emulator/serial6*
20 | fpga/.Xil/
21 | fpga/bbl.elf.txt
22 | fpga/vivado_*.str
23 | fpga/vmlinux.txt
24 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "hardfloat"]
2 | path = hardfloat
3 | url = https://github.com/ucb-bar/berkeley-hardfloat.git
4 | [submodule "torture"]
5 | path = torture
6 | url = https://github.com/ucb-bar/riscv-torture.git
7 | [submodule "chisel3"]
8 | path = chisel3
9 | url = https://github.com/ucb-bar/chisel3.git
10 | [submodule "firrtl"]
11 | path = firrtl
12 | url = https://github.com/ucb-bar/firrtl.git
13 | [submodule "src/main/scala/boom"]
14 | path = src/main/scala/boom
15 | url = https://github.com/shinezyy/BOOM-inside-LvNA.git
16 |
--------------------------------------------------------------------------------
/LICENSE.Berkeley:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012-2014, The Regents of the University of California
2 | (Regents). 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 |
--------------------------------------------------------------------------------
/LICENSE.jtag:
--------------------------------------------------------------------------------
1 | chisel-jtag license terms
2 |
3 | Copyright (c) 2016 The Regents of the University of
4 | California (Regents). All Rights Reserved. Redistribution and use in
5 | source and binary forms, with or without modification, are permitted
6 | provided that the following conditions are met:
7 | * Redistributions of source code must retain the above
8 | copyright notice, this list of conditions and the following
9 | two paragraphs of disclaimer.
10 | * Redistributions in binary form must reproduce the above
11 | copyright notice, this list of conditions and the following
12 | two paragraphs of disclaimer in the documentation and/or other materials
13 | provided with the distribution.
14 | * Neither the name of the Regents nor the names of its contributors
15 | may be used to endorse or promote products derived from this
16 | software without specific prior written permission.
17 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
18 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
19 | ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
20 | REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
24 | ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
25 | TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
26 | MODIFICATIONS.
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Labeled RISC-V based on Rocketchip
2 |
3 | We build our labeled RISC-V prototype based on rocketchip.
4 |
5 | - [Quick start guide for labeled RISC-V](./fpga/README.md),
6 | - [Original Rocketchip README](./README-rocketchip.md).
7 |
--------------------------------------------------------------------------------
/README_LvNA.md:
--------------------------------------------------------------------------------
1 | For a quick start flow about Labeled RISC-V, please refer to [the README.md under `fpga/` directory](fpga/README.md).
2 |
--------------------------------------------------------------------------------
/README_TRAVIS.md:
--------------------------------------------------------------------------------
1 | # Travis Notes for Administrators
2 |
3 | Administrators: Are PRs taking > 1 hr to run through Travis? If you look at the Travis logs is it building `riscv-tools`?
4 |
5 | This is because someone committed a PR to `master` which bumped `riscv-tools` and the master cache needs to be updated.
6 | This is the procedure to follow to get things fast again. We don't generally branch updates (e.g. to `master`), just PRs.
7 |
8 | To get the `master` cache good again:
9 | ----------------------------------
10 |
11 | 1. Wait for the PR that is changing `riscv-tools` to go green.
12 | 2. On Travis, click `More Options -> Caches` on the upper right.
13 | 3. Click `Delete` for the `master` Cache.
14 | 4. Click `More Options->Settings`
15 | 5. On the `General Settings` section, switch the `Build Branch Updates` toggle to `ON`.
16 | 6. Perform the PR's merge to `master`. This will cause the `master` cache to build `riscv-tools`.
17 | 7. Once the merge commit goes green on Travis, switch the `Build Branch Updates` toggle to `OFF`.
18 |
19 | For other PRs which were happening in parallel to the bump of `riscv-tools`:
20 | ----------------------------------------------------------------------------
21 |
22 | If your PR already has a cache and you want to keep doing development with the old version of `riscv-tools`, no action is needed.
23 |
24 | If you want to merge or rebase your PR on top of `master` with the new version of `riscv-tools`, you should delete your PR branch's local cache. Otherwise it will rebuild the branch cache instead of using `master`'s cache. To do this:
25 |
26 | 1. Wait for the previous steps to go through so that the `master` cache is done.
27 | 2. On Travis, click `More Options -> Caches` on the upper right.
28 | 3. Click `Delete` for your PR branch's cache.
29 | 4. Push updates to the PR as usual, it should download the new `master` cache.
30 |
--------------------------------------------------------------------------------
/bootrom/.gitignore:
--------------------------------------------------------------------------------
1 | *.elf
2 | bootrom.img
3 |
--------------------------------------------------------------------------------
/bootrom/Makefile:
--------------------------------------------------------------------------------
1 | bootrom_img = bootrom.img
2 |
3 | GCC=riscv64-unknown-elf-gcc
4 | OBJCOPY=riscv64-unknown-elf-objcopy
5 |
6 | all: $(bootrom_img)
7 |
8 | %.img: %.bin
9 | dd if=$< of=$@ bs=128 count=1
10 |
11 | %.bin: %.elf
12 | $(OBJCOPY) -O binary $< $@
13 |
14 | %.elf: %.S linker.ld
15 | $(GCC) -Tlinker.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@
16 | riscv64-unknown-elf-objdump -d $@ >bootrom.txt
17 |
--------------------------------------------------------------------------------
/bootrom/bootrom.S:
--------------------------------------------------------------------------------
1 | // #define DRAM_BASE 0x80000000
2 | #define DRAM_BASE 0x100000000
3 |
4 | .section .text.start, "ax", @progbits
5 | .globl _start
6 | _start:
7 | // csrwi 0x7c1, 0 // disable chicken bits
8 | li s0, DRAM_BASE
9 | csrr a0, mhartid
10 | la a1, _dtb
11 |
12 | jr s0
13 |
14 | .section .text.hang, "ax", @progbits
15 | .globl _hang
16 | _hang:
17 | // csrwi 0x7c1, 0 // disable chicken bits
18 | csrr a0, mhartid
19 | la a1, _dtb
20 | csrwi mie, 0
21 | 1:
22 | wfi
23 | j 1b
24 |
25 | .section .rodata.dtb, "a", @progbits
26 | .globl _dtb
27 | .align 5, 0
28 | _dtb:
29 | .ascii "DTB goes here"
30 |
--------------------------------------------------------------------------------
/bootrom/linker.ld:
--------------------------------------------------------------------------------
1 | SECTIONS
2 | {
3 | ROM_BASE = 0x10000; /* ... but actually position independent */
4 |
5 | . = ROM_BASE;
6 | .text.start : { *(.text.start) }
7 | . = ROM_BASE + 0x40;
8 | .text.hang : { *(.text.hang) }
9 | . = ROM_BASE + 0x80;
10 | .rodata.dtb : { *(.rodata.dtb) }
11 | }
12 |
--------------------------------------------------------------------------------
/emulator/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.o
3 | *.a
4 | *.log
5 | output/
6 | emulator-*
7 | generated-src
8 | generated-src-debug
9 | kernel
10 | kernel.hex
11 | verilator/
12 |
--------------------------------------------------------------------------------
/fpga/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | scripts/*.bit
3 |
--------------------------------------------------------------------------------
/fpga/Makefile:
--------------------------------------------------------------------------------
1 | include Makefile.check
2 |
3 | default: project
4 |
5 | # vivado project name
6 | PRJ ?= myproject
7 | PRJ_FULL = $(PRJ)-$(BOARD)
8 | VIVADO_FLAG = -nolog -nojournal -notrace
9 |
10 | #--------------------------------------------------------------------
11 | # Project building and implementation
12 | #--------------------------------------------------------------------
13 |
14 | PRJ_ROOT = board/$(BOARD)/build/$(PRJ_FULL)
15 | XPR_FILE = $(PRJ_ROOT)/$(PRJ_FULL).xpr
16 | $(XPR_FILE):
17 | make -C pardcore BOARD=$(BOARD)
18 | vivado $(VIVADO_FLAG) -mode batch -source board/$(BOARD)/mk.tcl -tclargs $(PRJ_FULL)
19 |
20 | project: $(XPR_FILE)
21 |
22 | bootgen:
23 | cd boot && hsi $(VIVADO_FLAG) -source mk.tcl -tclargs $(abspath $(PRJ_ROOT)/$(PRJ_FULL).sdk/system_top.hdf) $(PRJ_FULL)
24 |
25 | vivado: $(XPR_FILE)
26 | vivado $(VIVADO_FLAG) $(XPR_FILE) &
27 |
28 | .PHONY: default project vivado bootgen
29 |
30 | include Makefile.sw
31 |
--------------------------------------------------------------------------------
/fpga/Makefile.check:
--------------------------------------------------------------------------------
1 | ifneq ($(MAKECMDGOALS),clean) # ignore check for make clean
2 |
3 | BOARD ?= zcu102
4 |
5 | BOARDS = $(shell ls board/)
6 |
7 | ifeq ($(filter $(BOARDS), $(BOARD)), ) # BOARD must be valid
8 | $(error Invalid BOARD. Supported: $(BOARDS))
9 | endif
10 |
11 | endif
12 |
--------------------------------------------------------------------------------
/fpga/board/sidewinder/constr/constr.xdc:
--------------------------------------------------------------------------------
1 | create_clock -period 10.000 -name pcie_x86_refclk -waveform {0.000 5.000} [get_ports CLK_IN_D_clk_p]
2 | set_property PACKAGE_PIN AB35 [get_ports {CLK_IN_D_clk_n[0]}]
3 | set_property PACKAGE_PIN AB34 [get_ports {CLK_IN_D_clk_p[0]}]
--------------------------------------------------------------------------------
/fpga/board/sidewinder/mk.tcl:
--------------------------------------------------------------------------------
1 | set device xczu19eg-ffvc1760-2-i
2 | set board fidus:none:part0:2.0
3 |
4 | set script_dir [file dirname [info script]]
5 |
6 | # Add files for system top
7 | set src_files [list \
8 | "[file normalize "${script_dir}/rtl/system_top.v"]" \
9 | "[file normalize "${script_dir}/rtl/addr_mapper.v"]" \
10 | ]
11 |
12 | # Add files for constraint
13 | set xdc_files [list \
14 | "[file normalize "${script_dir}/constr/constr.xdc"]" \
15 | ]
16 |
17 | source ${script_dir}/../common.tcl
18 |
--------------------------------------------------------------------------------
/fpga/board/sidewinder/vivado/README.md:
--------------------------------------------------------------------------------
1 | Put the `sidewinder` directory under `/opt/Xilinx/Vivado/2019.1/data/boards/board_parts/` to let vivado find this board.
2 |
--------------------------------------------------------------------------------
/fpga/board/sidewinder/vivado/sidewinder/Fidus/2.0/Fidus.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LvNA-system/labeled-RISC-V/f6895abf0a3d6c05fd1b87c9de21d251ffa43887/fpga/board/sidewinder/vivado/sidewinder/Fidus/2.0/Fidus.jpeg
--------------------------------------------------------------------------------
/fpga/board/sidewinder/vivado/sidewinder/Fidus/2.0/board.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Fidus Sidewinder Board File Image
6 |
7 |
8 |
9 | 1.0
10 |
11 | 2.0
12 | Fidus Sidewinder 100 Board
13 |
14 |
15 |
16 |
17 | FPGA part on the board
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/fpga/board/ultraZ/constr/constr.xdc:
--------------------------------------------------------------------------------
1 | set_property PACKAGE_PIN F12 [get_ports {led[7]}]
2 | set_property PACKAGE_PIN G12 [get_ports {led[6]}]
3 | set_property PACKAGE_PIN G11 [get_ports {led[5]}]
4 | set_property PACKAGE_PIN H11 [get_ports {led[4]}]
5 | set_property PACKAGE_PIN F10 [get_ports {led[3]}]
6 | set_property PACKAGE_PIN G10 [get_ports {led[2]}]
7 | set_property PACKAGE_PIN H9 [get_ports {led[1]}]
8 | set_property PACKAGE_PIN H10 [get_ports {led[0]}]
9 |
10 | set_property IOSTANDARD LVCMOS18 [get_ports {led[7]}]
11 | set_property IOSTANDARD LVCMOS18 [get_ports {led[6]}]
12 | set_property IOSTANDARD LVCMOS18 [get_ports {led[5]}]
13 | set_property IOSTANDARD LVCMOS18 [get_ports {led[4]}]
14 | set_property IOSTANDARD LVCMOS18 [get_ports {led[3]}]
15 | set_property IOSTANDARD LVCMOS18 [get_ports {led[2]}]
16 | set_property IOSTANDARD LVCMOS18 [get_ports {led[1]}]
17 | set_property IOSTANDARD LVCMOS18 [get_ports {led[0]}]
18 |
--------------------------------------------------------------------------------
/fpga/board/ultraZ/mk.tcl:
--------------------------------------------------------------------------------
1 | set device xczu2eg-sfva625-1-e
2 | set board interwiser:none:part0:2.0
3 |
4 | set script_dir [file dirname [info script]]
5 |
6 | # Add files for system top
7 | set src_files [list \
8 | "[file normalize "${script_dir}/rtl/system_top.v"]" \
9 | "[file normalize "${script_dir}/rtl/addr_mapper.v"]" \
10 | ]
11 |
12 | # Add files for constraint
13 | set xdc_files [list \
14 | "[file normalize "${script_dir}/constr/constr.xdc"]" \
15 | ]
16 |
17 | source ${script_dir}/../common.tcl
18 |
--------------------------------------------------------------------------------
/fpga/board/ultraZ/rtl/addr_mapper.v:
--------------------------------------------------------------------------------
1 | module addr_mapper (
2 | `axi_slave_if(s_axi, 64, 1),
3 | `axi_master_if(m_axi, 64, 1)
4 | );
5 |
6 | assign m_axi_awaddr = {4'd0, 2'b01, s_axi_awaddr[29:0]};
7 | assign m_axi_araddr = {4'd0, 2'b01, s_axi_araddr[29:0]};
8 | assign m_axi_arburst = s_axi_arburst;
9 | assign m_axi_arcache = s_axi_arcache;
10 | assign m_axi_arid = s_axi_arid ;
11 | // assign m_axi_aruser = s_axi_aruser ;
12 | assign m_axi_arlen = s_axi_arlen ;
13 | assign m_axi_arlock = s_axi_arlock ;
14 | assign m_axi_arprot = s_axi_arprot ;
15 | assign s_axi_arready = m_axi_arready;
16 | assign m_axi_arsize = s_axi_arsize ;
17 | assign m_axi_arvalid = s_axi_arvalid;
18 | assign m_axi_awburst = s_axi_awburst;
19 | assign m_axi_awcache = s_axi_awcache;
20 | assign m_axi_awid = s_axi_awid ;
21 | // assign m_axi_awuser = s_axi_awuser ;
22 | assign m_axi_awlen = s_axi_awlen ;
23 | assign m_axi_awlock = s_axi_awlock ;
24 | assign m_axi_awprot = s_axi_awprot ;
25 | assign s_axi_awready = m_axi_awready;
26 | assign m_axi_awsize = s_axi_awsize ;
27 | assign m_axi_awvalid = s_axi_awvalid;
28 | assign s_axi_bid = m_axi_bid ;
29 | assign m_axi_bready = s_axi_bready ;
30 | assign s_axi_bresp = m_axi_bresp ;
31 | assign s_axi_bvalid = m_axi_bvalid ;
32 | assign s_axi_rdata = m_axi_rdata ;
33 | assign s_axi_rid = m_axi_rid ;
34 | assign s_axi_rlast = m_axi_rlast ;
35 | assign m_axi_rready = s_axi_rready ;
36 | assign s_axi_rresp = m_axi_rresp ;
37 | assign s_axi_rvalid = m_axi_rvalid ;
38 | assign m_axi_wdata = s_axi_wdata ;
39 | assign m_axi_wlast = s_axi_wlast ;
40 | assign s_axi_wready = m_axi_wready ;
41 | assign m_axi_wstrb = s_axi_wstrb ;
42 | assign m_axi_wvalid = s_axi_wvalid ;
43 | assign m_axi_arqos = s_axi_arqos ;
44 | assign m_axi_awqos = s_axi_awqos ;
45 |
46 | endmodule
47 |
--------------------------------------------------------------------------------
/fpga/board/ultraZ/rtl/system_top.v:
--------------------------------------------------------------------------------
1 | `include "axi.vh"
2 |
3 | module system_top (
4 | output [7:0] led
5 | );
6 |
7 | `axi_wire(AXI_MEM_MAPPED, 64, 1);
8 | `axi_wire(AXI_MEM, 64, 1);
9 | `axilite_wire(AXILITE_MMIO);
10 | `axi_wire(AXI_DMA, 64, 1);
11 |
12 | wire jtag_TCK;
13 | wire jtag_TMS;
14 | wire jtag_TDI;
15 | wire jtag_TDO;
16 | wire jtag_TRST;
17 |
18 | wire pardcore_coreclk;
19 | wire [1:0] pardcore_corerstn;
20 | wire pardcore_uncoreclk;
21 | wire pardcore_uncorerstn;
22 |
23 | wire mm2s_introut;
24 | wire s2mm_introut;
25 |
26 | zynq_soc zynq_soc_i (
27 | `axi_connect_if(S_AXI_MEM, AXI_MEM_MAPPED),
28 | `axilite_connect_if(S_AXILITE_MMIO, AXILITE_MMIO),
29 | `axi_connect_if_no_id(M_AXI_DMA, AXI_DMA),
30 |
31 | .jtag_TCK(jtag_TCK),
32 | .jtag_TMS(jtag_TMS),
33 | .jtag_TDI(jtag_TDI),
34 | .jtag_TDO(jtag_TDO),
35 |
36 | .led(led[6:0]),
37 |
38 | .mm2s_introut(mm2s_introut),
39 | .s2mm_introut(s2mm_introut),
40 |
41 | .pardcore_coreclk(pardcore_coreclk),
42 | .pardcore_corerstn(pardcore_corerstn),
43 | .pardcore_uncoreclk(pardcore_uncoreclk),
44 | .pardcore_uncorerstn(pardcore_uncorerstn)
45 | );
46 |
47 | addr_mapper addr_mapper_i(
48 | `axi_connect_if(s_axi, AXI_MEM),
49 | `axi_connect_if(m_axi, AXI_MEM_MAPPED)
50 | );
51 |
52 | pardcore pardcore_i(
53 | `axi_connect_if(M_AXI_MEM, AXI_MEM),
54 | `axi_connect_if(S_AXI_DMA, AXI_DMA),
55 | `axilite_connect_if(M_AXILITE_MMIO, AXILITE_MMIO),
56 |
57 | .jtag_TCK(jtag_TCK),
58 | .jtag_TMS(jtag_TMS),
59 | .jtag_TDI(jtag_TDI),
60 | .jtag_TDO(jtag_TDO),
61 | .jtag_TRST(~pardcore_corerstn),
62 |
63 | .intr0(mm2s_introut),
64 | .intr1(s2mm_introut),
65 |
66 | .led(led[7]),
67 |
68 | .coreclk(pardcore_coreclk),
69 | .corersts(~pardcore_corerstn),
70 | .uncoreclk(pardcore_uncoreclk),
71 | .uncore_rstn(pardcore_uncorerstn)
72 | );
73 |
74 | endmodule
75 |
--------------------------------------------------------------------------------
/fpga/board/zcu102/constr/constr.xdc:
--------------------------------------------------------------------------------
1 | set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
2 | set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
3 | set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
4 | set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
5 | set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
6 | set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
7 | set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
8 | set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
9 |
10 | set_property PACKAGE_PIN AG14 [get_ports {led[0]}]
11 | set_property PACKAGE_PIN AF13 [get_ports {led[1]}]
12 | set_property PACKAGE_PIN AE13 [get_ports {led[2]}]
13 | set_property PACKAGE_PIN AJ14 [get_ports {led[3]}]
14 | set_property PACKAGE_PIN AJ15 [get_ports {led[4]}]
15 | set_property PACKAGE_PIN AH13 [get_ports {led[5]}]
16 | set_property PACKAGE_PIN AH14 [get_ports {led[6]}]
17 | set_property PACKAGE_PIN AL12 [get_ports {led[7]}]
18 |
--------------------------------------------------------------------------------
/fpga/board/zcu102/mk.tcl:
--------------------------------------------------------------------------------
1 | set device xczu9eg-ffvb1156-2-e
2 | set board xilinx.com:zcu102:part0:3.1
3 |
4 | set script_dir [file dirname [info script]]
5 |
6 | # Add files for system top
7 | set src_files [list \
8 | "[file normalize "${script_dir}/rtl/system_top.v"]" \
9 | "[file normalize "${script_dir}/rtl/addr_mapper.v"]" \
10 | ]
11 |
12 | # Add files for constraint
13 | set xdc_files [list \
14 | "[file normalize "${script_dir}/constr/constr.xdc"]" \
15 | ]
16 |
17 | source ${script_dir}/../common.tcl
18 |
--------------------------------------------------------------------------------
/fpga/board/zcu102/patch/0001-patch-for-new-version-of-zcu102.patch:
--------------------------------------------------------------------------------
1 | From d3211ce94e3c3e477991f1dd1a38e1399fbf50fc Mon Sep 17 00:00:00 2001
2 | From: chuanqizhang
3 | Date: Wed, 14 Apr 2021 12:08:12 +0800
4 | Subject: [PATCH] patch for new version of zcu102
5 |
6 | ---
7 | fpga/board/zcu102/bd/prm.tcl | 2 +-
8 | fpga/board/zcu102/mk.tcl | 2 +-
9 | 2 files changed, 2 insertions(+), 2 deletions(-)
10 |
11 | diff --git a/fpga/board/zcu102/bd/prm.tcl b/fpga/board/zcu102/bd/prm.tcl
12 | index b8c336a5..d562fe53 100644
13 | --- a/fpga/board/zcu102/bd/prm.tcl
14 | +++ b/fpga/board/zcu102/bd/prm.tcl
15 | @@ -924,7 +924,7 @@ proc create_root_design { parentCell } {
16 | CONFIG.PSU_DDR_RAM_HIGHADDR {0xFFFFFFFF} \
17 | CONFIG.PSU_DDR_RAM_HIGHADDR_OFFSET {0x800000000} \
18 | CONFIG.PSU_DDR_RAM_LOWADDR_OFFSET {0x80000000} \
19 | - CONFIG.PSU_DYNAMIC_DDR_CONFIG_EN {0} \
20 | + CONFIG.PSU_DYNAMIC_DDR_CONFIG_EN {1} \
21 | CONFIG.PSU_MIO_0_DIRECTION {inout} \
22 | CONFIG.PSU_MIO_0_INPUT_TYPE {schmitt} \
23 | CONFIG.PSU_MIO_10_DIRECTION {inout} \
24 | diff --git a/fpga/board/zcu102/mk.tcl b/fpga/board/zcu102/mk.tcl
25 | index 5edfde8f..22af30d4 100644
26 | --- a/fpga/board/zcu102/mk.tcl
27 | +++ b/fpga/board/zcu102/mk.tcl
28 | @@ -1,5 +1,5 @@
29 | set device xczu9eg-ffvb1156-2-e
30 | -set board xilinx.com:zcu102:part0:3.1
31 | +set board xilinx.com:zcu102:part0:3.3
32 |
33 | set script_dir [file dirname [info script]]
34 |
35 | --
36 | 2.20.1
37 |
38 |
--------------------------------------------------------------------------------
/fpga/board/zedboard/constr/constr.xdc:
--------------------------------------------------------------------------------
1 | set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
2 | set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
3 | set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
4 | set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
5 | set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
6 | set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
7 | set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
8 | set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
9 |
10 | set_property PACKAGE_PIN T22 [get_ports {led[0]}]
11 | set_property PACKAGE_PIN T21 [get_ports {led[1]}]
12 | set_property PACKAGE_PIN U22 [get_ports {led[2]}]
13 | set_property PACKAGE_PIN U21 [get_ports {led[3]}]
14 | set_property PACKAGE_PIN V22 [get_ports {led[4]}]
15 | set_property PACKAGE_PIN W22 [get_ports {led[5]}]
16 | set_property PACKAGE_PIN U19 [get_ports {led[6]}]
17 | set_property PACKAGE_PIN U14 [get_ports {led[7]}]
18 |
19 |
--------------------------------------------------------------------------------
/fpga/board/zedboard/mk.tcl:
--------------------------------------------------------------------------------
1 | set device xc7z020-1-clg484
2 | set board em.avnet.com:zed:part0:1.3
3 |
4 | set script_dir [file dirname [info script]]
5 |
6 | # Add files for system top
7 | set src_files [list \
8 | "[file normalize "${script_dir}/rtl/system_top.v"]" \
9 | "[file normalize "${script_dir}/rtl/addr_mapper.v"]" \
10 | ]
11 |
12 | # Add files for constraint
13 | set xdc_files [list \
14 | "[file normalize "${script_dir}/constr/constr.xdc"]" \
15 | ]
16 |
17 | source ${script_dir}/../common.tcl
18 |
--------------------------------------------------------------------------------
/fpga/boot/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 |
--------------------------------------------------------------------------------
/fpga/boot/bootgen-zynq.bif:
--------------------------------------------------------------------------------
1 | the_ROM_image:
2 | {
3 | [bootloader] build/zynq/fsbl.elf
4 | // build/zynq/system_top.bit
5 | build/zynq/u-boot.elf
6 | }
7 |
--------------------------------------------------------------------------------
/fpga/boot/bootgen-zynqmp.bif:
--------------------------------------------------------------------------------
1 | the_ROM_image:
2 | {
3 | [fsbl_config] a53_x64
4 | [bootloader] build/zynqmp/fsbl.elf
5 | [pmufw_image] build/zynqmp/pmufw.elf
6 | // [destination_device=pl] build/zynqmp/system_top.bit
7 | [destination_cpu=a53-0, exception_level=el-3,trustzone] build/zynqmp/bl31.elf
8 | [destination_cpu=a53-0, exception_level=el-2] build/zynqmp/u-boot.elf
9 | }
10 |
--------------------------------------------------------------------------------
/fpga/boot/bug-list.md:
--------------------------------------------------------------------------------
1 |
2 | ## sidewinder
3 |
4 | To make the SD card work, do the followings
5 | * use a class10 SD card
6 | * `fsbl/psu_init.c`: search for `IOU_SLCR_BANK1_CTRL5_OFFSET`, change `0x2000FFFU` to `0x3FFFFFFU` (already done inside `mk.tcl`)
7 | * add "disable-wp;" property to the node of "sdhci@ff170000" in device tree
8 |
9 | * remove gem3.phy node
10 |
11 | ## ultraZ
12 |
13 | To make the SD card work, do the followings
14 | * should use 2016.4 dts
15 | * add "no-1-8-v;" property to the node of "sdhci@ff170000" in device tree
16 | * modify gem3.phyc.reg to <0x5>
17 |
18 | ## u-boot
19 |
20 | define marco `CONFIG_ENV_OVERWRITE` in `u-boot-xlnx/include/configs/xilinx-zynqmp.h` to make `ethaddr` environment variable writable
21 |
--------------------------------------------------------------------------------
/fpga/doc/riscv-pard-fpga-how-to.md:
--------------------------------------------------------------------------------
1 | # PARD on FPGA
2 |
3 | 下面描述从chisel到上板运行的全流程。
4 |
5 | ## 编译
6 |
7 |
8 |
9 | 首先我们这里包含了三个目标对象:
10 | vivado工程文件、由chisel生成的verilog、编译生成的bbl。
11 | 由于我们这里使用了Makefile调用tcl,tcl调用Makefile的方式,并没有正确地处理好make及clean时的依赖关系。导致在更新某一部分之后,无法正确地检查依赖,增量编译;clean时也无法正确clean。
12 | 直接生成三者使用如下命令:
13 | ```
14 | make BOARD=zedboard
15 | ```
16 |
17 | 当某一部分发生变化之后,增量编译及单独清理一个目标,命令如下:
18 |
19 | |目标对象|生成|清理方式|
20 | |-----|-------|-----------------|
21 | |vivado工程 | make BOARD=zedboard | make clean |
22 | |bbl | make bbl -j32 | make sw-clean -j32 |
23 | |generated verilog | make -C pardcore BOARD=zedboard| make -C pardcore BOARD=zedboard clean |
24 |
25 | 上述编译完成之后,得到的是一个vivado project以及bbl.bin文件。
26 |
27 | 接下来,我们打开vivado工程,单击refresh module。再单击generatebitstream。经过漫长的等待后,我们得到了bitstream文件system_top.bit。
28 |
29 | ## 运行
30 |
31 | 步骤太多,我都不知道该怎么分步了。
32 |
33 | 将板子开关打开,上电。
34 |
35 | ssh上123服务器(10.30.6.123)
36 | ```
37 | ssh liuzhigang@10.30.6.123
38 | ```
39 |
40 | 打开arm核的串口
41 | ```
42 | minicom -D /dev/ttyACM0
43 | ```
44 |
45 | 烧板子及启动arm核
46 | 将刚编好的bitstream文件拷贝到123的pard目录下,拷贝时请这样用如下命令:
47 | ```
48 | scp system_top.bit liuzhigang@10.30.6.123:~
49 | ```
50 | 注意:后面的":~"不能少,不然会拷贝到本机上。
51 |
52 | 运行xsdb
53 | 输入`source noop.tcl`。则arm核启动。
54 |
55 | 切换到arm的minicom窗口,窗口提示符为:zynq-uboot>
56 | 输入bootm 0x3000000 - 0x2a00000,则arm核开始启动Linux kernel。
57 | 如果莫名奇妙地挂住,请重新`source noop.tcl`。
58 |
59 | 启动linux核之后,提示符为:`debian-airbook login:`,则说明成功启动linux。
60 |
61 | 用户名密码均为root,登录进去。
62 |
63 | 让zedboard上的linux获取ip地址
64 | ```
65 | dhclient eth0
66 | ```
67 |
68 | 查看arm linux的ip地址
69 | ```
70 | ifconfig
71 | ```
72 |
73 | 进入arm linux的pard目录下,从eda上将新编译的bbl.bin
74 | scp过来(实际上是scp到了arm核用的sd卡上),将runme.sh更改,保证a.out后面跟的是刚传上去的bbl文件。
75 |
76 | 打开FPGA上rocket核的串口
77 | 在123服务器上,新开一个窗口,ssh到arm linux上,运行`minicom -D /dev/ttyUL1`。
78 | 如果显示locked,则用`ps aux | grep "minicom"`来看一下在运行的minicom进程,并杀死。
79 |
80 | 启动rocket核
81 | 切换到arm linux上,运行bash runme.sh,在minicom上即可看到riscv linux的输出。
82 |
83 |
84 | 重新烧板子时记得先把arm上的debian给poweroff,不要直接烧,直接运行bootm,因为arm上的debian需要正常关机以保证sd卡上的东西不会被写坏。
85 |
86 | 不用了,记得把zync给关机。
87 |
--------------------------------------------------------------------------------
/fpga/doc/rocketchip-bus.md:
--------------------------------------------------------------------------------
1 |
2 | 系统中有不少总线, 本文档对这些总线的功能和结构进行简单梳理.
3 | 可以将这些总线想象为crossbar, 其in和out分别连接其它模块.
4 |
5 | ## ibus
6 |
7 | Interrupt Bus, 可以认为是中断网络.
8 | * in
9 | * external interrupts (async)
10 | * sifive-blocks中的uart中断 (sync)
11 | * out
12 | * plic
13 |
14 | ## sbus
15 |
16 | System Bus, 是连接其它所有总线的总线.
17 | * in
18 | * fbus
19 | * ICache和DCache的masterNode
20 | * out
21 | * cbus
22 | * coherence manager的in, 最终连到mbus
23 | * 各个mmio channel, 它们会转换成MasterAXI4MMIO端口, 从rocketchip的顶层出去
24 |
25 | ## fbus
26 |
27 | Front Bus, 不清楚为何采用这个命名.
28 | * in
29 | * Debug Module
30 | * rocketchip的SlaveAXI4端口
31 | * out
32 | * sbus
33 |
34 | ## mbus
35 |
36 | Memory Bus, 是连接各个memory channel的总线.
37 | * in
38 | * coherence manager的out
39 | * out
40 | * 各个memory channel, 它们会转换成MasterAXI4Mem端口, 从rocketchip的顶层出去
41 |
42 | ## cbus
43 |
44 | Control Bus, 是连接内部MMIO设备的总线.
45 | 在2016年9月21日5bb575的commit中从internal MMIO network改名为cbus.
46 | * in
47 | * sbus
48 | * out
49 | * pbus
50 | * error device
51 | * controlplane
52 | * plic
53 | * clint
54 | * bootrom
55 | * debug module
56 | * bus blocker, 最终连到ICache.slaveNode和dtim.slavePort, 但我们生成的verilog代码里面好像没有bus blocker相关的代码, 暂时不清楚为什么cbus要连到ICache和dtim
57 |
58 | ## pbus
59 |
60 | Periphery Bus, 是连接外部MMIO设备的总线.
61 | 在2016年9月21日5bb575的commit中从external MMIO network改名为pbus.
62 | * in
63 | * cbus
64 | * out
65 | * 连接的设备例子有: sifive-blocks中的uart
66 |
--------------------------------------------------------------------------------
/fpga/doc/rocketchip_config_detail.md:
--------------------------------------------------------------------------------
1 | # 对 `Config` 类的理解
2 | `config` 模块的设计需求是:
3 |
4 | 1. 通过 `Parameters(Key)` 获得 Key 所对应的数据;
5 | 2. 通过 `++` 操作将多份配置合并。
6 |
7 | `PartialParameters` 是执行搜索操作的最小单位。
8 | 只有它持有偏函数,如果没有找到需要的字段,则进一步去 `tail` 里寻找。
9 |
10 | `View` 类只提供搜索语义,参数集合间的拓扑信息由其子类 `Parameters` 维护。
11 | `Parameters` 类通过 `chain` 方法同时描述搜索和拓扑语义。`find` 成为了顶级的 `chain`.
12 |
13 | 偏函数本身是不能被合并的,所以只能通过链表将各个持有偏函数的 `PartialParameters` 链接起来。
14 | 这就是 `ChainParameters` 的作用。
15 | 任意两个 `Parameters` 类型的实例,都可以通过 `++` 操作变成一颗以 `ChainParameters` 为根的二叉树。
16 |
17 | 当 `chain` 操作执行到 `ChainParameters` 实例时,它有一个 `tail` 参数,用于自己以及子女都搜索失败时继续搜索。
18 | 那么,很自然地,先递归搜索左子女,然后递归搜索右子女,最后递归搜索 `tail`.
19 | 但是,作者希望左子女搜索完后自动搜索右子女,右子女搜索完后自动搜索 `tail`,
20 | 让 `ChainParameters` 执行一个函数调用后就当甩手掌柜。
21 | 此时自然不能直接把右子女直接当做左子女的 `tail`, 否则根节点自己的 `tail` 信息就丢失了。
22 | 而且传进去的 `tail` 是 `View` 实例,只提供搜索语义。
23 | 迭代语义是 `Parameters` 派生系的私货。
24 | 于是 `ChainView` 出现了。它将右节点和 `tail` 结合成一颗新树,先调用右节点的 `chain`,
25 | 让右节点把父节点的 `tail` 当做自己的 `tail`, 然后让自己成为左节点的 `tail`,
26 | 这样一切都自动串联了。
27 |
28 | 然后需要一个统一的容器抽象 `PartialParameters` 和 `ChainParameters`,
29 | 不过为什么要用一个新的类 `Config` 而不是直接用 `Parameters` 呢?
30 | `Config` 以形同的类名,提供不同构造接口的方式使代码统一化。
31 | 不过感觉 `Parameters` 类自己也提供两种构造接口不就行了?
32 |
33 |
--------------------------------------------------------------------------------
/fpga/doc/rocketchip_linux_kernel_clock.md:
--------------------------------------------------------------------------------
1 | # RISCV-Linux中的时钟源的问题。
2 |
3 | 在linux kernel中时钟是叫时钟源(clock source)。现代的系统上,有很多不同的时钟源,他们性质,包括访问的latency,精确度各不相同,在内核中的作用也各不相同。在内核中,内核需要自己维护时间,这个时间当然是越精确越好,最好是直接从RTC读,但是由于从RTC读非常慢,所以内核只是在启动的时候,把自己的时间根据RTC校准,然后再根据timer interrupt来维护时间。
4 |
5 | 所以我们在看riscv-linux代码关于时间相关的问题时,也要考虑两个问题,wall clock是从哪里来的,timer interrupt又是怎么来的。
6 |
7 | 根据riscv-spec的定义,CSR中有mtime寄存器,是wall clock,但是具体的单位需要环境来指定。另外,有一些counter,可以设置成当mtime寄存器大于counter值时,触发时钟中断。在riscv-kernel中,获取wall clock是要通过rdtime指令来读取mtime寄存器,设置中断就是通过写入time counter。
8 |
9 | 但是在看rocketchip的代码时,我们会看到HasRTCModuleImp这个东西,会以为RTC是一个单独的定时设备,搞不清RTC和上述两种计时工具的关系。但实际上这个RTC仅仅是一个简单的计数器,负责驱动mtime寄存器的更新。
10 |
11 | mtime以及counter都是CSR寄存器,但是他们不是在CSR模块中实现的,他们是在Clint中实现的,Clint是coreplex local interrupter的缩写。
12 |
13 | HasRTCModuleImp实例化了一个计数器,并连接到Clint中,驱动mtime的更新,compare counter以及raise timer interrupt是在Clint中完成的。
14 |
15 | 接下来还要考虑wall clock的单位的问题,wall clock的单位在rocketchip代码中是通过DTSTimebase来指定的,这个决定了RTC模块以多高的频率更新mtime。这个配置最终会进入DTB中,内核在启动时可以查询到这个参数。
16 |
--------------------------------------------------------------------------------
/fpga/doc/rocketchip_on_pard_details.md:
--------------------------------------------------------------------------------
1 | ## 为什么既有 AXI Interconnect 又有 AXI Crossbar
2 |
3 | AXI Interconnect 的地址映射信息在专门的 Address Editor 里,是给当前 block design 做路由的。
4 | 而 AXI Crossbar 则是在 IP 核设定中指定地址映射进行路由的。
5 |
6 | 为什么要有这两种划分,为什么在两种在工程里同时出现?这是因为工程中有多个地址映射域。
7 | 一个是 PRM, 另一个是 ldom, 这两个是隔离的,视角不同,所以不能只使用一个全局的 AXI Interconnect.
8 |
9 | ## Rocket Chip 是如何输出字符的?
10 |
11 | ### Hart 是如何访问自己对应的 UART 设备的?
12 |
13 | `PARDSimTop` 有 UART 接口,模拟器直接提供 UART 设备; 而 `PARDFPGATop` 则直接通过 MMIO 将串口输出送给 PRM.
14 |
15 | 在 FPGA 配置的 Rocket Chip 的 Device Tree 里, MMIO 的内存映射地址为 0x60000000 ~ 0x7fffffff. 再往上就是常规代码数据的地址空间了。
16 |
17 | 在 BBL 阶段,核心会查询 DTB 找到 UART 的相关描述,设置 MMIO 的基地址。 之后,出于 NoHype 的定制需求,UART 的内存映射基地址会以 0x10000B 为单位按 hartid 进行偏移。 最后,每个 hart 与 UART 地址的对应关系如下:
18 |
19 | | HART ID | UART BASE ADDR |
20 | | ------- | -------------- |
21 | | 0 | `0x60000000` |
22 | | 1 | `0x60010000` |
23 | | ... | ... |
24 |
25 | 不同 hart 向自己对应的 UART 内存映射空间发送数据时,都从 Rocket Chip 的同一个 MMIO 端口送出。 之后,会经过一个 AXI Crossbar. 在 Crossbar 中,会根据基地址的不同,路由到对应的 UART 总线上。
26 |
27 | ### 为什么进入 riscv-linux 后也能继续隔离 UART 地址空间?
28 |
29 | UART 地址空间的隔离在 BBL 阶段完成后,使用这一信息的代码驻留于 machine mode 的代码区。 操作系统内核(riscv-linux)处于 supervisor mode, 它使用 ecall(environment call) 陷入 machine mode, 以类似系统调用的方式执行 UART 相关的操作。 从 supervisor mode 陷入 machine mode 使用的是 9 号中断,在 BBL 里只有这个位置被设置成了 `mcall_trap`.
30 |
31 | ## DMA 传输镜像是如何工作的?
32 |
33 | [yzh 的文档](http://10.30.7.141/pard/riscv_pard_fpga/issues/33)
34 |
35 | SG 是 Scatter Gather 的缩写,是用来自动维护多个传输的模块,可以减少 CPU 用于控制 DMA 的时间。
36 |
37 | DMA 从 PRM 的内存取数据,通过 AXI4 总线将数据发送给 rocket chip.
38 | 在 rocket chip 里,这条总线通往 l2 frontside bus.
39 |
40 | 之后可能有这样两种情况:
41 |
42 | 1. 直接写到 cache 里,发生替换后写回到 rocket chip 的内存中,走内存控制平面做内存隔离;
43 | 2. 绕过核心,直接把请求转发给访存端口,走内存控制平面写到内存里。
44 |
--------------------------------------------------------------------------------
/fpga/doc/rocketchip_on_pard_simulation.md:
--------------------------------------------------------------------------------
1 | ## 如何运行模拟
2 |
3 | 1. 进入 `riscv_fpga_pard/fpga/emulator` 执行 `make run-emu`最终生成的可执行文件是build/emu,输出到串口的内容在serial1000或者serial2000中。在运行hello时,可能输出的串口中内容有两份,这是正常的,因为有两个核,他们都在运行hello,且都输出到了串口中。
4 | 2. 在修改之后,建议先运行AM里面的hello程序。再运行bbl。运行的程序需要被objcopy成bin文件,并dump成bin.txt放到build目录下。
5 | 这个过程建议你看一下Makefile,手动hack一下。在生成bbl时要注意,由于busybox太大了,而我们仿真的ram太小了,所以需要把程序改成hello,记得改一改initramfs.txt以及若干文件。
6 | 3. 我们这个加载程序不是用的rocket原有的dmi接口,而是直接用的readmemh,把bin.txt给copy到仿真出来的内存中。readmemh是在sram init verilog中。这个verilog是有某个python文件生成的。
7 |
--------------------------------------------------------------------------------
/fpga/emu/gen_bin.sh:
--------------------------------------------------------------------------------
1 | # $1 - bin file
2 | # $2 - bin text file
3 | /bin/echo -e "\033[1;31mremember to create a link from the target bin file to 'mem.bin' under build/ before calling this script\033[0m"
4 | hexdump -ve '2/ "%08x " "\n"' $1 | awk '{print $2$1}' > $2
5 |
--------------------------------------------------------------------------------
/fpga/emu/gen_dtb_bin.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | BUILD_DIR=$1
4 |
5 | for i in $(ls $1/c*.dtb)
6 | do
7 | sh gen_bin.sh $i $i.txt
8 | done
9 |
--------------------------------------------------------------------------------
/fpga/emu/py-check.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if ! which python3
4 | then
5 | echo python3 not found, please input password to allow apt-get to go forward
6 | sudo apt-get install -y python3
7 | else
8 | echo python3 installed
9 | fi
10 |
11 | if ! which pip3
12 | then
13 | echo python3-pip not found, please input password to allow apt-get to go forward
14 | sudo apt-get install -y python3-pip
15 | else
16 | echo python-pip installed
17 | fi
18 |
19 | if ! python3 -c 'import pyfdt' 2> /dev/null
20 | then
21 | echo pyfdt package not found, please input password to allow pip3 to go forward
22 | sudo -H pip3 install pyfdt
23 | else
24 | echo python module pyfdt installed
25 | fi
26 |
--------------------------------------------------------------------------------
/fpga/emu/python/.gitignore:
--------------------------------------------------------------------------------
1 | ts
2 | __pycache__
3 |
--------------------------------------------------------------------------------
/fpga/lib/dmi/dmi.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | riscv
4 | rocket
5 | dmi
6 | 1.0
7 | false
8 | false
9 | 1
10 | 1
11 | debug module interface
12 |
13 |
14 | DMI
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/fpga/lib/util/cdma_addr.v:
--------------------------------------------------------------------------------
1 | //`include "../include/axi.vh"
2 |
3 | module cdma_addr(
4 | `axi_slave_if(s_axi, 64, 4),
5 | `axi_master_if(m_axi, 64, 4)
6 | );
7 |
8 | assign m_axi_awaddr = {1'b1, s_axi_awaddr[30:0]};
9 | assign m_axi_araddr = {1'b1, s_axi_araddr[30:0]};
10 | assign m_axi_arburst = s_axi_arburst;
11 | assign m_axi_arcache = s_axi_arcache;
12 | assign m_axi_arid = s_axi_arid ;
13 | assign m_axi_aruser = s_axi_aruser ;
14 | assign m_axi_arlen = s_axi_arlen ;
15 | assign m_axi_arlock = s_axi_arlock ;
16 | assign m_axi_arprot = s_axi_arprot ;
17 | assign s_axi_arready = m_axi_arready;
18 | assign m_axi_arsize = s_axi_arsize ;
19 | assign m_axi_arvalid = s_axi_arvalid;
20 | assign m_axi_awburst = s_axi_awburst;
21 | assign m_axi_awcache = s_axi_awcache;
22 | assign m_axi_awid = s_axi_awid ;
23 | assign m_axi_awuser = s_axi_awuser ;
24 | assign m_axi_awlen = s_axi_awlen ;
25 | assign m_axi_awlock = s_axi_awlock ;
26 | assign m_axi_awprot = s_axi_awprot ;
27 | assign s_axi_awready = m_axi_awready;
28 | assign m_axi_awsize = s_axi_awsize ;
29 | assign m_axi_awvalid = s_axi_awvalid;
30 | assign s_axi_bid = m_axi_bid ;
31 | assign m_axi_bready = s_axi_bready ;
32 | assign s_axi_bresp = m_axi_bresp ;
33 | assign s_axi_bvalid = m_axi_bvalid ;
34 | assign s_axi_rdata = m_axi_rdata ;
35 | assign s_axi_rid = m_axi_rid ;
36 | assign s_axi_rlast = m_axi_rlast ;
37 | assign m_axi_rready = s_axi_rready ;
38 | assign s_axi_rresp = m_axi_rresp ;
39 | assign s_axi_rvalid = m_axi_rvalid ;
40 | assign m_axi_wdata = s_axi_wdata ;
41 | assign m_axi_wlast = s_axi_wlast ;
42 | assign s_axi_wready = m_axi_wready ;
43 | assign m_axi_wstrb = s_axi_wstrb ;
44 | assign m_axi_wvalid = s_axi_wvalid ;
45 | assign m_axi_arqos = s_axi_arqos ;
46 | assign m_axi_awqos = s_axi_awqos ;
47 |
48 | endmodule
49 |
--------------------------------------------------------------------------------
/fpga/lib/util/uart_inverter.v:
--------------------------------------------------------------------------------
1 | module uart_inverter(
2 | input tx_dest,
3 | input tx_src,
4 | output rx_src,
5 | output rx_dest
6 | );
7 | assign rx_src = tx_dest;
8 | assign rx_dest = tx_src;
9 |
10 | endmodule
11 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | __pycache__
3 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/dm_utils.py:
--------------------------------------------------------------------------------
1 | from ctypes import *
2 | from dm_reg import *
3 |
4 | def print_fields(dm_reg):
5 | names = [f[0] for f in dm_reg.reg._fields_ if f[0]]
6 | align = len(max(names, key=len))
7 | for name in reversed(names):
8 | aligned_name = name.ljust(align, ' ')
9 | value = hex(int(getattr(dm_reg, name)))
10 | print(aligned_name + ': ' + value)
11 |
12 | def set_reg(dm_reg, hex_str):
13 | dm_reg.bits = int(hex_str, 16)
14 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/dmcontrol:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | with OpenOcd(verbose=False) as ocd:
12 | ocd.dmi_read_fields(dmcontrol)
13 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/dmstatus:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | with OpenOcd(verbose=False) as ocd:
12 | ocd.dmi_read_fields(dmstatus)
13 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/dpc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | asm = [
12 | 0x7b1022f3, # csrr t0, dpc
13 | 0x00100073 # ebreak
14 | ]
15 | progbuf_cmds = [(i + 0x20, data) for i, data in enumerate(asm)]
16 | with OpenOcd() as ocd:
17 | # Progbuf
18 | for reg, data in progbuf_cmds:
19 | ocd.send("riscv dmi_write {} {}".format(reg, data))
20 | # Access Register
21 | ocd.send("riscv dmi_write 0x17 0x361001") # regno = sp, postexec, transfer, 64-bit
22 | ocd.send("riscv dmi_write 0x16 0xffffffff")
23 | abstractcs = ocd.send("riscv dmi_read 0x16")
24 | if abstractcs != "0x10000002":
25 | print("Exec error: abstracts " + abstractcs)
26 | ocd.send("riscv dmi_write 0x17 0x361005") # regno = t0, postexec, transfer, 64-bit
27 | dm_data0 = ocd.send("riscv dmi_read 0x4")
28 | dm_data1 = ocd.send("riscv dmi_read 0x5")
29 | print("data0: {}, data1: {}".format(dm_data0, dm_data1))
30 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/get_cp:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | # set_cp (in dec) [property]...
11 | # property: waymask bkt_freq bkt_size bkt_inc traffic l2_capacity
12 | VERBOSE = False
13 |
14 | DSID = 0x41
15 | DSID_SEL = 0x42
16 | DSID_COUNT = 0x43
17 | MEM_BASE_LO = 0x44
18 | MEM_BASE_HI = 0x45
19 | MEM_MASK_LO = 0x46
20 | MEM_MASK_HI = 0x47
21 | BUCKET_FREQ = 0x48
22 | BUCKET_SIZE = 0x49
23 | BUCKET_INC = 0x4a
24 | TRAFFIC = 0x4b
25 | WAYMASK = 0x4c
26 | L2_CAPACITY = 0x4d
27 |
28 | CP = {
29 | 'bkt_freq': BUCKET_FREQ,
30 | 'bkt_size': BUCKET_SIZE,
31 | 'bkt_inc' : BUCKET_INC,
32 | 'traffic' : TRAFFIC,
33 | 'l2_capacity' : L2_CAPACITY,
34 | 'waymask' : WAYMASK
35 | }
36 |
37 | if __name__ == "__main__":
38 | if len(sys.argv) == 1:
39 | print("get_cp.py [] ...")
40 | print("properties:")
41 | print(CP.keys())
42 | sys.exit(0)
43 |
44 | if len(sys.argv) == 2:
45 | queries = CP.keys()
46 | else:
47 | queries = sys.argv[2:]
48 |
49 | hartid = int(sys.argv[1])
50 | with OpenOcd(verbose=VERBOSE) as ocd:
51 | ocd.dmi_write(DSID_SEL, hartid)
52 | for query in queries:
53 | addr = CP[query]
54 | if not addr:
55 | print("Invalid control plane property: {}".format(query))
56 | continue
57 | resp = ocd.dmi_read(addr)
58 | print(query + ": " + resp)
59 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/get_mem:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | def check_busy(ocd):
11 | sbcs.bits = int(ocd.dmi_read(sbcs.addr), 16)
12 | return sbcs.sbbusy == 1
13 |
14 | if __name__ == "__main__":
15 | addr = int(sys.argv[1], 16)
16 | with OpenOcd(verbose=False) as ocd:
17 | sbcs.bits = int(ocd.dmi_read(sbcs.addr), 16)
18 | print_fields(sbcs)
19 |
20 | sbcs.sbaccess = 2 # 32-bit
21 | sbcs.sbreadonaddr = 1
22 | sbaddress0.bits = addr & 0xffffffff
23 | sbaddress1.bits = addr >> 32
24 |
25 | ocd.dmi_write(sbcs.addr, sbcs.bits)
26 | ocd.dmi_write(sbaddress1.addr, sbaddress1.bits)
27 | ocd.dmi_write(sbaddress0.addr, sbaddress0.bits)
28 |
29 | while check_busy(ocd):
30 | print("waiting")
31 | pass
32 |
33 | if sbcs.sberror or sbcs.sbbusyerror:
34 | print("Error:")
35 | print_fields(sbcs)
36 | sys.exit(-1)
37 |
38 | data = ocd.dmi_read(sbdata0.addr)
39 | print("{:x}: {}".format(addr, data))
40 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/halt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | with OpenOcd(verbose=False) as ocd:
12 | ocd.dmi_write_fields(dmcontrol, hartsello = int(sys.argv[1]), resumereq = 0, haltreq = 0)
13 | ocd.dmi_write_fields(dmcontrol, hartsello = int(sys.argv[1]), resumereq = 0, haltreq = 1)
14 | ocd.dmi_write_fields(dmcontrol, hartsello = int(sys.argv[1]), resumereq = 0, haltreq = 0)
15 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/haltsum0:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | with OpenOcd() as ocd:
12 | ocd.dmi_read_fields(haltsum0)
13 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/log:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | if sys.argv[1] == 'enable':
12 | asm = [ 0x8000d073 ]
13 | elif sys.argv[1] == 'disable':
14 | asm = [ 0x80005073 ]
15 | else:
16 | print("Unexpected command: " + sys.argv[1])
17 | sys.exit(-1)
18 |
19 | asm += [
20 | 0x00100073 # ebreak
21 | ]
22 |
23 | print(asm)
24 |
25 | progbuf_cmds = [(i + 0x20, data) for i, data in enumerate(asm)]
26 | with OpenOcd(verbose=False) as ocd:
27 | # Progbuf
28 | for reg, data in progbuf_cmds:
29 | ocd.send("riscv dmi_write {} {}".format(reg, data))
30 | # Access Register
31 | ocd.send("riscv dmi_write 0x17 0x361001") # regno = sp, postexec, transfer, 64-bit
32 | ret = ocd.send("riscv dmi_read 0x16")
33 | if ret != "0x10000002":
34 | print("Exec error: abstracts " + ret)
35 | set_reg(abstractcs, ret)
36 | print_fields(abstractcs)
37 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/put_mem:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | def check_busy(ocd):
11 | sbcs.bits = int(ocd.dmi_read(sbcs.addr), 16)
12 | return sbcs.sbbusy == 1
13 |
14 | if __name__ == "__main__":
15 | addr = int(sys.argv[1], 16)
16 | data = int(sys.argv[2], 16)
17 |
18 | with OpenOcd(verbose=False) as ocd:
19 | while check_busy(ocd):
20 | print("waiting")
21 | pass
22 |
23 | sbaddress0.bits = addr & 0xffffffff
24 | sbaddress1.bits = addr >> 32
25 | sbdata0.bits = data
26 |
27 | ocd.dmi_write(sbaddress1.addr, sbaddress1.bits)
28 | ocd.dmi_write(sbaddress0.addr, sbaddress0.bits)
29 | ocd.dmi_write(sbdata0.addr, sbdata0.bits)
30 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/resume:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | hartid = int(sys.argv[1])
12 | with OpenOcd(verbose=False) as ocd:
13 | ocd.dmi_write_fields(dmcontrol, hartsello = hartid, resumereq = 0, haltreq = 0)
14 | ocd.dmi_write_fields(dmcontrol, hartsello = hartid, resumereq = 1, haltreq = 0)
15 | ocd.dmi_write_fields(dmcontrol, hartsello = hartid, resumereq = 0, haltreq = 0)
16 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/scause:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | asm = [
12 | 0x142022f3, # csrr t0, scause
13 | #0x105022f3, # csrr t0, stvec
14 | 0x00100073 # ebreak
15 | ]
16 | progbuf_cmds = [(i + 0x20, data) for i, data in enumerate(asm)]
17 | with OpenOcd() as ocd:
18 | # Progbuf
19 | for reg, data in progbuf_cmds:
20 | ocd.send("riscv dmi_write {} {}".format(reg, data))
21 | # Access Register
22 | ocd.send("riscv dmi_write 0x17 0x361001") # regno = sp, postexec, transfer, 64-bit
23 | ocd.send("riscv dmi_write 0x16 0xffffffff")
24 | abstractcs = ocd.send("riscv dmi_read 0x16")
25 | if abstractcs != "0x10000002":
26 | print("Exec error: abstracts " + abstractcs)
27 | ocd.send("riscv dmi_write 0x17 0x361005") # regno = t0, postexec, transfer, 64-bit
28 | dm_data0 = ocd.send("riscv dmi_read 0x4")
29 | dm_data1 = ocd.send("riscv dmi_read 0x5")
30 | print("data0: {}, data1: {}".format(dm_data0, dm_data1))
31 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/sepc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | asm = [
12 | 0x141022f3, # csrr t0, scause
13 | #0x105022f3, # csrr t0, stvec
14 | 0x00100073 # ebreak
15 | ]
16 | progbuf_cmds = [(i + 0x20, data) for i, data in enumerate(asm)]
17 | with OpenOcd() as ocd:
18 | # Progbuf
19 | for reg, data in progbuf_cmds:
20 | ocd.send("riscv dmi_write {} {}".format(reg, data))
21 | # Access Register
22 | ocd.send("riscv dmi_write 0x17 0x361001") # regno = sp, postexec, transfer, 64-bit
23 | ocd.send("riscv dmi_write 0x16 0xffffffff")
24 | abstractcs = ocd.send("riscv dmi_read 0x16")
25 | if abstractcs != "0x10000002":
26 | print("Exec error: abstracts " + abstractcs)
27 | ocd.send("riscv dmi_write 0x17 0x361005") # regno = t0, postexec, transfer, 64-bit
28 | dm_data0 = ocd.send("riscv dmi_read 0x4")
29 | dm_data1 = ocd.send("riscv dmi_read 0x5")
30 | print("data0: {}, data1: {}".format(dm_data0, dm_data1))
31 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/set_cp:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | # set_cp (in dec) [property=value(in hex)]
11 | # property: waymask bkt_freq bkt_size bkt_inc
12 | # no space around '='!
13 | VERBOSE = False
14 |
15 | DSID = 0x41
16 | DSID_SEL = 0x42
17 | DSID_COUNT = 0x43
18 | MEM_BASE_LO = 0x44
19 | MEM_BASE_HI = 0x45
20 | MEM_MASK_LO = 0x46
21 | MEM_MASK_HI = 0x47
22 | BUCKET_FREQ = 0x48
23 | BUCKET_SIZE = 0x49
24 | BUCKET_INC = 0x4a
25 | TRAFFIC = 0x4b
26 | WAYMASK = 0x4c
27 | L2_CAPACITY = 0x4d
28 |
29 | CP = {
30 | 'bkt_freq': BUCKET_FREQ,
31 | 'bkt_size': BUCKET_SIZE,
32 | 'bkt_inc' : BUCKET_INC,
33 | 'waymask' : WAYMASK
34 | }
35 |
36 | if __name__ == "__main__":
37 | if len(sys.argv) == 1:
38 | print("set_cp.py [=] ...")
39 | print("NOTE: no space around '='")
40 | print("Properties:")
41 | print(CP.keys())
42 | sys.exit(0)
43 |
44 | hartid = int(sys.argv[1])
45 | with OpenOcd(verbose=VERBOSE) as ocd:
46 | ocd.dmi_write(DSID_SEL, hartid)
47 | for pair in sys.argv[2:]:
48 | dst, val = pair.split('=')
49 | addr = CP[dst]
50 | if not addr:
51 | print("Invalid control plane property: {}".format(dst))
52 | continue
53 | ocd.dmi_write(addr, val)
54 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/show_cache_capacity:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import socket
3 | import itertools
4 | import sys
5 | import time
6 |
7 | from dm_reg import *
8 | from dm_utils import *
9 | from openocd import *
10 |
11 | if __name__ == "__main__":
12 | with OpenOcd() as ocd:
13 | for i in range(0, 4):
14 | ocd.send("riscv dmi_write 0x42 {}" % i)
15 | print("hart " + i + ": " + ocd.send("riscv dmi_read 0x4d"))
16 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/show_traffic:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import socket
3 | import itertools
4 | import sys
5 | import time
6 |
7 | from dm_reg import *
8 | from dm_utils import *
9 | from openocd import *
10 |
11 | if __name__ == "__main__":
12 | with OpenOcd() as ocd:
13 | for i in range(0, 4):
14 | ocd.send("riscv dmi_write 0x42 {}" % i)
15 | print("hart " + i + ": " + ocd.send("riscv dmi_read 0x4b"))
16 |
--------------------------------------------------------------------------------
/fpga/openocd_rpc/stval:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import socket
3 | import itertools
4 | import sys
5 |
6 | from dm_reg import *
7 | from dm_utils import *
8 | from openocd import *
9 |
10 | if __name__ == "__main__":
11 | asm = [
12 | 0x143022f3, # csrr t0, scause
13 | #0x105022f3, # csrr t0, stvec
14 | 0x00100073 # ebreak
15 | ]
16 | progbuf_cmds = [(i + 0x20, data) for i, data in enumerate(asm)]
17 | with OpenOcd() as ocd:
18 | # Progbuf
19 | for reg, data in progbuf_cmds:
20 | ocd.send("riscv dmi_write {} {}".format(reg, data))
21 | # Access Register
22 | ocd.send("riscv dmi_write 0x17 0x361001") # regno = sp, postexec, transfer, 64-bit
23 | ocd.send("riscv dmi_write 0x16 0xffffffff")
24 | abstractcs = ocd.send("riscv dmi_read 0x16")
25 | if abstractcs != "0x10000002":
26 | print("Exec error: abstracts " + abstractcs)
27 | ocd.send("riscv dmi_write 0x17 0x361005") # regno = t0, postexec, transfer, 64-bit
28 | dm_data0 = ocd.send("riscv dmi_read 0x4")
29 | dm_data1 = ocd.send("riscv dmi_read 0x5")
30 | print("data0: {}, data1: {}".format(dm_data0, dm_data1))
31 |
--------------------------------------------------------------------------------
/fpga/pardcore/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # Makefile for Verilog simulation w/ VCS
3 | #-----------------------------------------------------------------------
4 | # Yunsup Lee (yunsup@cs.berkeley.edu)
5 | #
6 | # This makefile will build a rtl simulator and run various tests to
7 | # verify proper functionality.
8 | #
9 |
10 | default: verilog
11 |
12 | fpga_dir = $(abspath ..)
13 | base_dir = $(fpga_dir)/..
14 | build_dir = $(fpga_dir)/build
15 | generated_dir = $(build_dir)/generated-src
16 |
17 | MODEL ?= TestHarness
18 | BOARD ?= zcu102
19 | CONFIG ?= LvNAFPGAConfig$(BOARD)
20 |
21 | #--------------------------------------------------------------------
22 | # Rocket-chip verilog source generation
23 | #--------------------------------------------------------------------
24 |
25 | -include $(base_dir)/Makefrag
26 |
27 | gen_rtl = $(generated_dir)/$(long_name).v
28 | srams_rtl = $(generated_dir)/$(long_name).behav_srams.v
29 | other_rtl = $(base_dir)/src/main/resources/vsrc/AsyncResetReg.v \
30 | $(base_dir)/src/main/resources/vsrc/EICG_wrapper.v \
31 | $(base_dir)/src/main/resources/vsrc/plusarg_reader.v
32 |
33 | $(gen_rtl):
34 | $(MAKE) verilog -C $(base_dir)/vsim CONFIG=$(CONFIG) MODEL=$(MODEL) generated_dir=$(generated_dir)
35 |
36 | $(srams_rtl): $(gen_rtl)
37 |
38 | rocketchip_rtl = rtl/rocket/rocketchip_board_$(BOARD).v
39 |
40 | $(rocketchip_rtl): $(gen_rtl) $(srams_rtl) $(other_rtl)
41 | cat $^ > $@
42 | sed -i -e 's/_\(aw\|ar\|w\|r\|b\)_\(\|bits_\)/_\1/g' $@
43 | sed -i -e 's/LvNABoomFPGATop/LvNAFPGATop/g' $@
44 |
45 | verilog: $(rocketchip_rtl)
46 |
47 | .PHONY: $(gen_rtl) verilog
48 |
49 | #--------------------------------------------------------------------
50 | # Cleaning
51 | #--------------------------------------------------------------------
52 |
53 | clean:
54 | -rm -rf $(generated_dir)
55 |
56 | .PHONY: default clean
57 |
--------------------------------------------------------------------------------
/fpga/pardcore/rtl/rocket/.gitignore:
--------------------------------------------------------------------------------
1 | rocketchip_board_*.v
2 |
--------------------------------------------------------------------------------
/fpga/scripts/account.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | if __name__ == "__main__":
4 | if len(sys.argv) != 2:
5 | print "Log file expected."
6 | exit(1)
7 | files = {}
8 | with open(sys.argv[1], "r") as f:
9 | for line in f:
10 | l = line.split()
11 | if len(l) == 0 or l[0] != "Traffic":
12 | continue
13 | cycle = int(l[2])
14 | dsid = int(l[4])
15 | traffic = int(l[6])
16 | if dsid not in files:
17 | files[dsid] = open("%d.trace" % dsid,"w")
18 | f = files[dsid]
19 | f.write("%d %d\n" % (cycle, traffic))
20 | for dsid in files:
21 | files[dsid].close()
22 |
--------------------------------------------------------------------------------
/fpga/scripts/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | python account.py emu.log
3 | cp 0.trace nohype_0_32.trace
4 | cp 1.trace nohype_1_32.trace
5 |
--------------------------------------------------------------------------------
/fpga/scripts/range.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | def prepare(file_name):
4 | data = {}
5 | with open(file_name, "r") as f:
6 | for line in f:
7 | l = line.split()
8 | if len(l) == 0 or l[0] != "Traffic":
9 | continue
10 | cycle = int(l[2])
11 | dsid = int(l[4])
12 | traffic = int(l[6])
13 | if dsid not in data:
14 | data[dsid] = []
15 | data[dsid].append([cycle, traffic])
16 | return data
17 |
18 | def query(datas, dsid, start, end):
19 | total_traffic = 0
20 | for r in datas[dsid]:
21 | if r[0] > end:
22 | break
23 | if r[0] > start:
24 | total_traffic += r[1]
25 | return total_traffic
26 |
27 | if __name__ == "__main__":
28 | if len(sys.argv) != 2:
29 | print "Log file expected."
30 | exit(1)
31 |
32 | data = prepare(sys.argv[1])
33 |
34 | for i in range(0, 2000):
35 | start = 17000 * i
36 | end = 17000 * (i + 1)
37 | sample_0 = query(data, 0, start, start + 1000)
38 | sample_1 = query(data, 1, start, start + 1000)
39 | regulate_0 = query(data, 0, start + 1000, end)
40 | regulate_1 = query(data, 1, start + 1000, end)
41 | print i, "\t", sample_0, "\t", sample_1, "\t", regulate_0, "\t", regulate_1
42 |
--------------------------------------------------------------------------------
/macros/src/main/scala/ValName.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.macros
4 |
5 | import scala.language.experimental.macros
6 | import scala.reflect.macros.blackbox.Context
7 |
8 | case class ValNameImpl(name: String)
9 |
10 | object ValNameImpl
11 | {
12 | implicit def materialize: ValNameImpl = macro detail
13 | def detail(c: Context): c.Expr[ValNameImpl] = {
14 | import c.universe._
15 | def allOwners(s: c.Symbol): Seq[c.Symbol] =
16 | if (s == `NoSymbol`) Nil else s +: allOwners(s.owner)
17 | val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm)
18 | terms.filter(t => t.isVal || t.isLazy).map(_.name.toString).find(_(0) != '$').map { s =>
19 | val trim = s.replaceAll("\\s", "")
20 | c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${trim})" }
21 | }.getOrElse(c.abort(c.enclosingPosition, "Not a valid application."))
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/project/.gitignore:
--------------------------------------------------------------------------------
1 | *~
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.2.7
2 |
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven"
2 |
3 | addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.2")
4 |
5 | addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.1")
6 |
7 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0")
8 |
9 | addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.9.3")
10 |
11 | addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.1")
12 |
13 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1")
14 |
--------------------------------------------------------------------------------
/regression/.gitignore:
--------------------------------------------------------------------------------
1 | /install
2 | /stamps
3 | /torture-failures
4 |
--------------------------------------------------------------------------------
/riscv-tools.hash:
--------------------------------------------------------------------------------
1 | 0425658510490d4d093941749c4d26e37af23504
2 |
--------------------------------------------------------------------------------
/sbt-launch.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LvNA-system/labeled-RISC-V/f6895abf0a3d6c05fd1b87c9de21d251ffa43887/sbt-launch.jar
--------------------------------------------------------------------------------
/scripts/.gitignore:
--------------------------------------------------------------------------------
1 | /comlog
2 | /float_fix
3 |
--------------------------------------------------------------------------------
/scripts/Makefile:
--------------------------------------------------------------------------------
1 | base_dir = $(abspath ..)
2 |
3 | CXXSRCS := comlog float_fix
4 | CXXFLAGS := $(CXXFLAGS) -std=c++11 -Wall
5 |
6 | OBJS := $(addsuffix .o,$(CXXSRCS))
7 | PROGRAMS := $(CXXSRCS)
8 |
9 | all: $(PROGRAMS)
10 |
11 | %: %.o
12 | $(CXX) $< $(LDFLAGS) -o $@
13 |
14 | %.o: $(base_dir)/csrc/%.cc
15 | $(CXX) $(CXXFLAGS) -c $< -o $@
16 |
17 | clean:
18 | rm -f $(OBJS) $(PROGRAMS)
19 |
--------------------------------------------------------------------------------
/scripts/RocketSim.cfg:
--------------------------------------------------------------------------------
1 | adapter_khz 10000
2 |
3 | interface remote_bitbang
4 | remote_bitbang_host localhost
5 | #$::env(REMOTE_BITBANG_HOST)
6 | remote_bitbang_port $::env(JTAG_VPI_PORT)
7 |
8 | set _CHIPNAME riscv
9 | jtag newtap $_CHIPNAME cpu -irlen 5
10 |
11 | set _TARGETNAME $_CHIPNAME.cpu
12 | target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos riscv
13 |
14 | riscv set_reset_timeout_sec 120
15 | riscv set_command_timeout_sec 120
16 |
17 | riscv set_prefer_sba $::env(JTAG_DTM_ENABLE_SBA)
18 |
19 | init
20 | halt
21 | echo "Ready for Remote Connections"
22 |
--------------------------------------------------------------------------------
/scripts/RocketSim.py:
--------------------------------------------------------------------------------
1 | import targets
2 | import testlib
3 |
4 | class RocketSimHart(targets.Hart):
5 | # This isn't generically true, but it's true enough for the Default*Configs in this code for now.
6 | # to get these tests to pass.
7 | ram = 0x80000000
8 | ram_size = 0x4000
9 | instruction_hardware_breakpoint_count = 2
10 | pass
11 |
12 | class RocketSim(targets.Target):
13 | harts = [RocketSimHart()]
14 | timeout_sec = 6000
15 | server_timeout_sec = 60*60
16 | openocd_config_path = "RocketSim.cfg"
17 |
18 | def create(self):
19 | print "STARTING A SIMULATION"
20 | print self.sim_cmd
21 | return testlib.VcsSim(sim_cmd=self.sim_cmd, debug=False)
22 |
--------------------------------------------------------------------------------
/scripts/RocketSim32.py:
--------------------------------------------------------------------------------
1 | import targets
2 | import testlib
3 |
4 | class RocketSimHart(targets.Hart):
5 | xlen = 32
6 | # This isn't generically true, but it's true enough for the Default*Configs in this code for now.
7 | # to get these tests to pass.
8 | ram = 0x80000000
9 | ram_size = 0x4000
10 | instruction_hardware_breakpoint_count = 2
11 | pass
12 |
13 | class RocketSim(targets.Target):
14 | harts = [RocketSimHart()]
15 | timeout_sec = 6000
16 | server_timeout_sec = 60*60
17 | openocd_config_path = "RocketSim.cfg"
18 |
19 | def create(self):
20 | print "STARTING A SIMULATION"
21 | print self.sim_cmd
22 | return testlib.VcsSim(sim_cmd=self.sim_cmd, debug=False)
23 |
--------------------------------------------------------------------------------
/scripts/RocketSim64.py:
--------------------------------------------------------------------------------
1 | import targets
2 | import testlib
3 |
4 | class RocketSimHart(targets.Hart):
5 | # This isn't generically true, but it's true enough for the Default*Configs in this code for now.
6 | # to get these tests to pass.
7 | xlen = 64
8 | ram = 0x80000000
9 | ram_size = 0x4000
10 | instruction_hardware_breakpoint_count = 2
11 | pass
12 |
13 | class RocketSim(targets.Target):
14 | harts = [RocketSimHart()]
15 | timeout_sec = 6000
16 | server_timeout_sec = 60*60
17 | openocd_config_path = "RocketSim.cfg"
18 |
19 | def create(self):
20 | print "STARTING A SIMULATION"
21 | print self.sim_cmd
22 | return testlib.VcsSim(sim_cmd=self.sim_cmd, debug=False)
23 |
--------------------------------------------------------------------------------
/scripts/copyright-file:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | d=$(dirname $0)
3 | for i in "$@"; do
4 | if [ $# -gt 1 ]; then echo "$i:"; fi
5 | git blame --date="format:%Y%m%d" -M -C -C -C "$i" | sed 's/[^(]*(\([^0-46-9]*\) \([0-9]*\).*/\2 \1/' | $d/authors | sort | uniq -c | sort -rn
6 | done
7 |
--------------------------------------------------------------------------------
/scripts/debug_rom/.gitignore:
--------------------------------------------------------------------------------
1 | /debug_rom
2 |
--------------------------------------------------------------------------------
/scripts/debug_rom/Makefile:
--------------------------------------------------------------------------------
1 | # See LICENSE.SiFive for license details
2 | # Recursive make is bad, but in this case we're cross compiling which is a
3 | # pretty unusual use case.
4 |
5 | CC = $(RISCV)/bin/riscv64-unknown-elf-gcc
6 | OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy
7 |
8 | COMPILE = $(CC) -nostdlib -nostartfiles -I$(RISCV)/include/ -Tlink.ld
9 |
10 | ELFS = debug_rom
11 | DEPS = debug_rom.S link.ld
12 |
13 | all: $(patsubst %,%.h,$(ELFS))
14 |
15 | publish: debug_rom.scala
16 | mv $< ../../src/main/scala/devices/debug/DebugRomContents.scala
17 |
18 | %.scala: %.raw
19 | xxd -i $^ | sed -e "s/^unsigned char debug_rom_raw\[\] = {/\/\/ This file was auto-generated by 'make publish' in debug\/ directory.\n\npackage freechips.rocketchip.devices.debug\n\nobject DebugRomContents {\n\n def apply() : Array[Byte] = { Array (/" \
20 | -e "s/};/ ).map(_.toByte) }\n\n}/" \
21 | -e "s/^unsigned int debug_rom_raw_len.*//" > $@
22 |
23 |
24 | %.raw: %
25 | $(OBJCOPY) -O binary --only-section .text $^ $@
26 |
27 | debug_rom: $(DEPS)
28 | $(COMPILE) -o $@ $^
29 |
30 | clean:
31 | rm -f $(ELFS) debug_rom*.raw debug_rom*.h
32 |
--------------------------------------------------------------------------------
/scripts/debug_rom/link.ld:
--------------------------------------------------------------------------------
1 | /* See LICENSE.SiFive for license details. */
2 | OUTPUT_ARCH( "riscv" )
3 | ENTRY( entry )
4 | SECTIONS
5 | {
6 | .whereto 0x300 :
7 | {
8 | *(.whereto)
9 | }
10 | . = 0x800;
11 | .text :
12 | {
13 | *(.text)
14 | }
15 | _end = .;
16 | }
17 |
--------------------------------------------------------------------------------
/scripts/modify-copyright:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | d=$(dirname "$0")
3 | threshold=10
4 |
5 | for i in $(git ls-tree -r HEAD . | grep '\.\(scala\|cc\|v\)' | cut -f2); do
6 | ("$d/copyright-file" "$i" | sort -rn | awk 'NR == 1 || $1 > '$threshold' { print }' | sed 's@[^A-Z]*@// See LICENSE.@;s@$@ for license details.@;$a\\'; \
7 | grep -v "^// See LICENSE" $i | sed '/./,$!d') > $i.tmp
8 | mv $i.tmp $i
9 | done
10 |
--------------------------------------------------------------------------------
/scripts/tracegen.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # This file was originally written by Matthew Naylor, University of
4 | # Cambridge.
5 | #
6 | # This software was partly developed by the University of Cambridge
7 | # Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
8 | # ("CTSRD"), as part of the DARPA CRASH research programme.
9 | #
10 | # This software was partly developed by the University of Cambridge
11 | # Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
12 | # ("MRC2"), as part of the DARPA MRC research programme.
13 | #
14 | # This software was partly developed by the University of Cambridge
15 | # Computer Laboratory as part of the Rigorous Engineering of
16 | # Mainstream Systems (REMS) project, funded by EPSRC grant
17 | # EP/K008528/1.
18 |
19 | # -------
20 | # Outline
21 | # -------
22 |
23 | # Usage:
24 | #
25 | # tracegen.py EMULATOR SEED
26 | #
27 | # This script generates a trace using the given emulator (built
28 | # with CONFIG=TraceGenConfig). It waits until all cores have
29 | # completed trace generation before terminating the emulator.
30 |
31 | import sys
32 | import subprocess
33 | import re
34 |
35 | def main():
36 | if len(sys.argv) != 3:
37 | sys.stderr.write("Usage: tracegen.py EMULATOR SEED\n")
38 | sys.exit(-1)
39 |
40 | p = subprocess.Popen([sys.argv[1],
41 | "+verbose", "-s" + sys.argv[2]],
42 | stderr=subprocess.PIPE, stdout=subprocess.PIPE)
43 | if p == None:
44 | sys.stderr.write("File not found: " + sys.argv[1] + "\n")
45 | sys.exit(-1)
46 |
47 | numFinished = 0
48 | while True:
49 | line = p.stderr.readline()
50 | if line[0:9] == "FINISHED ":
51 | total = int(line[9:-1])
52 | numFinished = numFinished + 1
53 | if numFinished == total:
54 | break
55 | elif line[0:15] == "Completed after":
56 | break
57 | elif line[0:7] == "testing":
58 | continue
59 | else:
60 | print line,
61 |
62 | p.terminate()
63 |
64 | try:
65 | main()
66 | except KeyboardInterrupt:
67 | sys.exit(-1)
68 |
--------------------------------------------------------------------------------
/src/main/resources/csrc/SimDTM.cc:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | dtm_t* dtm;
8 |
9 | extern "C" int debug_tick
10 | (
11 | unsigned char* debug_req_valid,
12 | unsigned char debug_req_ready,
13 | int* debug_req_bits_addr,
14 | int* debug_req_bits_op,
15 | int* debug_req_bits_data,
16 | unsigned char debug_resp_valid,
17 | unsigned char* debug_resp_ready,
18 | int debug_resp_bits_resp,
19 | int debug_resp_bits_data
20 | )
21 | {
22 | if (!dtm) {
23 | s_vpi_vlog_info info;
24 | if (!vpi_get_vlog_info(&info))
25 | abort();
26 | dtm = new dtm_t(info.argc, info.argv);
27 | }
28 |
29 | dtm_t::resp resp_bits;
30 | resp_bits.resp = debug_resp_bits_resp;
31 | resp_bits.data = debug_resp_bits_data;
32 |
33 | dtm->tick
34 | (
35 | debug_req_ready,
36 | debug_resp_valid,
37 | resp_bits
38 | );
39 |
40 | *debug_resp_ready = dtm->resp_ready();
41 | *debug_req_valid = dtm->req_valid();
42 | *debug_req_bits_addr = dtm->req_bits().addr;
43 | *debug_req_bits_op = dtm->req_bits().op;
44 | *debug_req_bits_data = dtm->req_bits().data;
45 |
46 | return dtm->done() ? (dtm->exit_code() << 1 | 1) : 0;
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/resources/csrc/SimJTAG.cc:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | #include
4 | #include "remote_bitbang.h"
5 |
6 | remote_bitbang_t* jtag;
7 | extern "C" int jtag_tick
8 | (
9 | unsigned char * jtag_TCK,
10 | unsigned char * jtag_TMS,
11 | unsigned char * jtag_TDI,
12 | unsigned char * jtag_TRSTn,
13 | unsigned char jtag_TDO
14 | )
15 | {
16 | if (!jtag) {
17 | // TODO: Pass in real port number
18 | jtag = new remote_bitbang_t(0);
19 | }
20 |
21 | jtag->tick(jtag_TCK, jtag_TMS, jtag_TDI, jtag_TRSTn, jtag_TDO);
22 |
23 | return jtag->done() ? (jtag->exit_code() << 1 | 1) : 0;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/resources/csrc/remote_bitbang.h:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 |
3 | #ifndef REMOTE_BITBANG_H
4 | #define REMOTE_BITBANG_H
5 |
6 | #include
7 | #include
8 |
9 | class remote_bitbang_t
10 | {
11 | public:
12 | // Create a new server, listening for connections from localhost on the given
13 | // port.
14 | remote_bitbang_t(uint16_t port);
15 |
16 | // Do a bit of work.
17 | void tick(unsigned char * jtag_tck,
18 | unsigned char * jtag_tms,
19 | unsigned char * jtag_tdi,
20 | unsigned char * jtag_trstn,
21 | unsigned char jtag_tdo);
22 |
23 | unsigned char done() {return quit;}
24 |
25 | int exit_code() {return err;}
26 |
27 | private:
28 |
29 | int err;
30 |
31 | unsigned char tck;
32 | unsigned char tms;
33 | unsigned char tdi;
34 | unsigned char trstn;
35 | unsigned char tdo;
36 | unsigned char quit;
37 |
38 | int socket_fd;
39 | int client_fd;
40 |
41 | static const ssize_t buf_size = 64 * 1024;
42 | char recv_buf[buf_size];
43 | ssize_t recv_start, recv_end;
44 |
45 | // Check for a client connecting, and accept if there is one.
46 | void accept();
47 | // Execute any commands the client has for us.
48 | // But we only execute 1 because we need time for the
49 | // simulation to run.
50 | void execute_command();
51 |
52 | // Reset. Currently does nothing.
53 | void reset();
54 |
55 | void set_pins(char _tck, char _tms, char _tdi);
56 |
57 | };
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/src/main/resources/csrc/verilator.h:
--------------------------------------------------------------------------------
1 | #ifndef _ROCKET_VERILATOR_H
2 | #define _ROCKET_VERILATOR_H
3 |
4 | #include "verilated_vcd_c.h"
5 | #include
6 | #include
7 |
8 | extern bool verbose;
9 | extern bool done_reset;
10 |
11 | class VerilatedVcdFILE : public VerilatedVcdFile {
12 | public:
13 | VerilatedVcdFILE(FILE* file) : file(file) {}
14 | ~VerilatedVcdFILE() {}
15 | bool open(const std::string& name) override {
16 | // file should already be open
17 | return file != NULL;
18 | }
19 | void close() override {
20 | // file should be closed elsewhere
21 | }
22 | ssize_t write(const char* bufp, ssize_t len) override {
23 | return fwrite(bufp, 1, len, file);
24 | }
25 | private:
26 | FILE* file;
27 | };
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/main/resources/vsrc/ClockDivider2.v:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | /** This black-boxes a Clock Divider by 2.
4 | * The output clock is phase-aligned to the input clock.
5 | * If you use this in synthesis, make sure your sdc
6 | * declares that you want it to do the same.
7 | *
8 | * Because Chisel does not support
9 | * blocking assignments, it is impossible
10 | * to create a deterministic divided clock.
11 | *
12 | * @param clk_out Divided Clock
13 | * @param clk_in Clock Input
14 | *
15 | */
16 |
17 | module ClockDivider2 (output reg clk_out, input clk_in);
18 |
19 | initial clk_out = 1'b0;
20 | always @(posedge clk_in) begin
21 | clk_out = ~clk_out; // Must use =, NOT <=
22 | end
23 |
24 | endmodule // ClockDivider2
25 |
--------------------------------------------------------------------------------
/src/main/resources/vsrc/ClockDivider3.v:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | /** This black-boxes a Clock Divider by 3.
4 | * The output clock is phase-aligned to the input clock.
5 | * Do NOT use this in synthesis; the duty cycle is 2:1.
6 | *
7 | * Because Chisel does not support
8 | * blocking assignments, it is impossible
9 | * to create a deterministic divided clock.
10 | *
11 | * @param clk_out Divided Clock
12 | * @param clk_in Clock Input
13 | *
14 | */
15 |
16 | module ClockDivider3 (output reg clk_out, input clk_in);
17 |
18 | reg delay;
19 |
20 | initial begin
21 | clk_out = 1'b0;
22 | delay = 1'b0;
23 | end
24 |
25 | always @(posedge clk_in) begin
26 | if (clk_out == 1'b0) begin
27 | clk_out = 1'b1;
28 | delay <= 1'b0;
29 | end else if (delay == 1'b1) begin
30 | clk_out = 1'b0;
31 | delay <= 1'b0;
32 | end else begin
33 | delay <= 1'b1;
34 | end
35 | end
36 |
37 | endmodule // ClockDivider3
38 |
--------------------------------------------------------------------------------
/src/main/resources/vsrc/EICG_wrapper.v:
--------------------------------------------------------------------------------
1 | /* verilator lint_off UNOPTFLAT */
2 |
3 | module EICG_wrapper(
4 | output out,
5 | input en,
6 | input in
7 | );
8 |
9 | reg en_latched /*verilator clock_enable*/;
10 |
11 | always @(en or in) begin
12 | if (!in) begin
13 | en_latched = en;
14 | end
15 | end
16 |
17 | assign out = en_latched && in;
18 |
19 | endmodule
20 |
--------------------------------------------------------------------------------
/src/main/resources/vsrc/UARTPrinter.v:
--------------------------------------------------------------------------------
1 | module UARTPrinter
2 | #(
3 | parameter FILENAME = "serial"
4 | )(
5 | input clock,
6 | input valid,
7 | input [7:0] data // Always expect an ASCII character
8 | );
9 |
10 | integer fd;
11 |
12 | initial begin
13 | fd = $fopen(FILENAME, "w");
14 | end
15 |
16 | always @(posedge clock) begin
17 | if (valid) begin
18 | $fwrite(fd, "%c", data);
19 | $fflush(fd);
20 | end
21 | end
22 |
23 | endmodule
24 |
--------------------------------------------------------------------------------
/src/main/resources/vsrc/plusarg_reader.v:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | //VCS coverage exclude_file
4 |
5 | // No default parameter values are intended, nor does IEEE 1800-2012 require them (clause A.2.4 param_assignment),
6 | // but Incisive demands them. These default values should never be used.
7 | module plusarg_reader #(parameter FORMAT="borked=%d", DEFAULT=0) (
8 | output [31:0] out
9 | );
10 |
11 | `ifdef SYNTHESIS
12 | assign out = DEFAULT;
13 | `else
14 | reg [31:0] myplus;
15 | assign out = myplus;
16 |
17 | initial begin
18 | if (!$value$plusargs(FORMAT, myplus)) myplus = DEFAULT;
19 | end
20 | `endif
21 |
22 | endmodule
23 |
--------------------------------------------------------------------------------
/src/main/scala/amba/ahb/Bundles.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.ahb
4 |
5 | import Chisel._
6 | import freechips.rocketchip.util.GenericParameterizedBundle
7 |
8 | abstract class AHBBundleBase(params: AHBBundleParameters) extends GenericParameterizedBundle(params)
9 |
10 | // Signal directions are from the master's point-of-view
11 | class AHBBundle(params: AHBBundleParameters) extends AHBBundleBase(params)
12 | {
13 | // Flow control signals from the master
14 | val hmastlock = Bool(OUTPUT)
15 | val htrans = UInt(OUTPUT, width = params.transBits)
16 | val hsel = Bool(OUTPUT)
17 | val hready = Bool(OUTPUT) // on a master, drive this from readyout
18 |
19 | // Payload signals
20 | val hwrite = Bool(OUTPUT)
21 | val haddr = UInt(OUTPUT, width = params.addrBits)
22 | val hsize = UInt(OUTPUT, width = params.sizeBits)
23 | val hburst = UInt(OUTPUT, width = params.burstBits)
24 | val hprot = UInt(OUTPUT, width = params.protBits)
25 | val hwdata = UInt(OUTPUT, width = params.dataBits)
26 |
27 | val hreadyout = Bool(INPUT)
28 | val hresp = Bool(INPUT)
29 | val hrdata = UInt(INPUT, width = params.dataBits)
30 |
31 | def tieoff() {
32 | hreadyout.dir match {
33 | case INPUT =>
34 | hreadyout := Bool(false)
35 | hresp := AHBParameters.RESP_OKAY
36 | hrdata := UInt(0)
37 | case OUTPUT =>
38 | hmastlock := Bool(false)
39 | htrans := AHBParameters.TRANS_IDLE
40 | hsel := Bool(false)
41 | hready := Bool(false)
42 | hwrite := Bool(false)
43 | haddr := UInt(0)
44 | hsize := UInt(0)
45 | hburst := AHBParameters.BURST_SINGLE
46 | hprot := AHBParameters.PROT_DEFAULT
47 | hwdata := UInt(0)
48 | case _ =>
49 | }
50 | }
51 | }
52 |
53 | object AHBBundle
54 | {
55 | def apply(params: AHBBundleParameters) = new AHBBundle(params)
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/scala/amba/ahb/Nodes.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.ahb
4 |
5 | import Chisel._
6 | import chisel3.internal.sourceinfo.SourceInfo
7 | import freechips.rocketchip.config.Parameters
8 | import freechips.rocketchip.diplomacy._
9 |
10 | object AHBImp extends SimpleNodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
11 | {
12 | def edge(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = AHBEdgeParameters(pd, pu, p, sourceInfo)
13 | def bundle(e: AHBEdgeParameters) = AHBBundle(e.bundle)
14 | def render(e: AHBEdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, label = (e.slave.beatBytes * 8).toString)
15 |
16 | override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters =
17 | pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) })
18 | override def mixI(pu: AHBSlavePortParameters, node: InwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBSlavePortParameters =
19 | pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
20 | }
21 |
22 | // Nodes implemented inside modules
23 | case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends SourceNode(AHBImp)(portParams)
24 | case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams)
25 | case class AHBNexusNode(
26 | masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
27 | slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters)(
28 | implicit valName: ValName)
29 | extends NexusNode(AHBImp)(masterFn, slaveFn)
30 |
31 | case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)()
32 |
--------------------------------------------------------------------------------
/src/main/scala/amba/ahb/Protocol.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.ahb
4 |
5 | import Chisel._
6 |
7 | object AHBParameters
8 | {
9 | // These are all fixed by the AHB standard:
10 | val transBits = 2
11 | val burstBits = 3
12 | val protBits = 4
13 | val sizeBits = 3 // 8*2^s
14 |
15 | def TRANS_IDLE = UInt(0, width = transBits) // No transfer requested, not in a burst
16 | def TRANS_BUSY = UInt(1, width = transBits) // No transfer requested, in a burst
17 | def TRANS_NONSEQ = UInt(2, width = transBits) // First (potentially only) request in a burst
18 | def TRANS_SEQ = UInt(3, width = transBits) // Following requests in a burst
19 |
20 | def BURST_SINGLE = UInt(0, width = burstBits) // Single access (no burst)
21 | def BURST_INCR = UInt(1, width = burstBits) // Incrementing burst of arbitrary length, not crossing 1KB
22 | def BURST_WRAP4 = UInt(2, width = burstBits) // 4-beat wrapping burst
23 | def BURST_INCR4 = UInt(3, width = burstBits) // 4-beat incrementing burst
24 | def BURST_WRAP8 = UInt(4, width = burstBits) // 8-beat wrapping burst
25 | def BURST_INCR8 = UInt(5, width = burstBits) // 8-beat incrementing burst
26 | def BURST_WRAP16 = UInt(6, width = burstBits) // 16-beat wrapping burst
27 | def BURST_INCR16 = UInt(7, width = burstBits) // 16-beat incrementing burst
28 |
29 | val maxTransfer = 16
30 |
31 | def RESP_OKAY = Bool(false)
32 | def RESP_ERROR = Bool(true)
33 |
34 | def PROT_DATA = UInt(1, width = protBits)
35 | def PROT_PRIVILEDGED = UInt(2, width = protBits)
36 | def PROT_BUFFERABLE = UInt(4, width = protBits)
37 | def PROT_CACHEABLE = UInt(8, width = protBits)
38 | def PROT_DEFAULT = PROT_DATA | PROT_PRIVILEDGED
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/scala/amba/ahb/Xbar.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.ahb
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.regmapper._
9 | import scala.math.{min,max}
10 |
11 | class AHBFanout()(implicit p: Parameters) extends LazyModule {
12 | val node = AHBNexusNode(
13 | masterFn = { case Seq(m) => m },
14 | slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
15 |
16 | lazy val module = new LazyModuleImp(this) {
17 | if (node.edges.in.size >= 1) {
18 | require (node.edges.in.size == 1, "AHBFanout does not support multiple masters")
19 | require (node.edges.out.size > 0, "AHBFanout requires at least one slave")
20 |
21 | // Require consistent bus widths
22 | val (io_out, edgesOut) = node.out.unzip
23 | val port0 = edgesOut(0).slave
24 | edgesOut.foreach { edge =>
25 | val port = edge.slave
26 | require (port.beatBytes == port0.beatBytes,
27 | s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}")
28 | }
29 |
30 | val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten)
31 | val routingMask = AddressDecoder(port_addrs)
32 | val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct)
33 |
34 | val (in, _) = node.in(0)
35 | val a_sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.haddr)).reduce(_ || _)))
36 | val d_sel = Reg(a_sel)
37 |
38 | when (in.hready) { d_sel := a_sel }
39 | (a_sel zip io_out) foreach { case (sel, out) =>
40 | out := in
41 | out.hsel := in.hsel && sel
42 | }
43 |
44 | in.hreadyout := !Mux1H(d_sel, io_out.map(!_.hreadyout))
45 | in.hresp := Mux1H(d_sel, io_out.map(_.hresp))
46 | in.hrdata := Mux1H(d_sel, io_out.map(_.hrdata))
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/scala/amba/ahb/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba
4 |
5 | import Chisel._
6 | import freechips.rocketchip.diplomacy._
7 |
8 | package object ahb
9 | {
10 | type AHBOutwardNode = OutwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
11 | type AHBInwardNode = InwardNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
12 | type AHBNode = SimpleNodeHandle[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle]
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/Bundles.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.apb
4 |
5 | import Chisel._
6 | import freechips.rocketchip.util.GenericParameterizedBundle
7 |
8 | abstract class APBBundleBase(params: APBBundleParameters) extends GenericParameterizedBundle(params)
9 |
10 | // Signal directions are from the master's point-of-view
11 | class APBBundle(params: APBBundleParameters) extends APBBundleBase(params)
12 | {
13 | // Flow control signals from the master
14 | val psel = Bool(OUTPUT)
15 | val penable = Bool(OUTPUT)
16 |
17 | // Payload signals
18 | val pwrite = Bool(OUTPUT)
19 | val paddr = UInt(OUTPUT, width = params.addrBits)
20 | val pprot = UInt(OUTPUT, width = params.protBits)
21 | val pwdata = UInt(OUTPUT, width = params.dataBits)
22 | val pstrb = UInt(OUTPUT, width = params.dataBits/8)
23 |
24 | val pready = Bool(INPUT)
25 | val pslverr = Bool(INPUT)
26 | val prdata = UInt(INPUT, width = params.dataBits)
27 |
28 | def tieoff() {
29 | pready.dir match {
30 | case INPUT =>
31 | pready := Bool(false)
32 | pslverr := Bool(false)
33 | prdata := UInt(0)
34 | case OUTPUT =>
35 | pwrite := Bool(false)
36 | paddr := UInt(0)
37 | pprot := APBParameters.PROT_DEFAULT
38 | pwdata := UInt(0)
39 | pstrb := UInt(0)
40 | case _ =>
41 | }
42 | }
43 | }
44 |
45 | object APBBundle
46 | {
47 | def apply(params: APBBundleParameters) = new APBBundle(params)
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/Nodes.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.apb
4 |
5 | import Chisel._
6 | import chisel3.internal.sourceinfo.SourceInfo
7 | import freechips.rocketchip.config.Parameters
8 | import freechips.rocketchip.diplomacy._
9 |
10 | object APBImp extends SimpleNodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
11 | {
12 | def edge(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = APBEdgeParameters(pd, pu, p, sourceInfo)
13 | def bundle(e: APBEdgeParameters) = APBBundle(e.bundle)
14 | def render(e: APBEdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, (e.slave.beatBytes * 8).toString)
15 |
16 | override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters =
17 | pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) })
18 | override def mixI(pu: APBSlavePortParameters, node: InwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBSlavePortParameters =
19 | pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
20 | }
21 |
22 | case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends SourceNode(APBImp)(portParams)
23 | case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams)
24 | case class APBNexusNode(
25 | masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
26 | slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters)(
27 | implicit valName: ValName)
28 | extends NexusNode(APBImp)(masterFn, slaveFn)
29 |
30 | case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)()
31 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/Protocol.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.apb
4 |
5 | import Chisel._
6 |
7 | object APBParameters
8 | {
9 | // These are all fixed by the AHB standard:
10 | val protBits = 3
11 |
12 | def PROT_PRIVILEDGED = UInt(1, width = protBits)
13 | def PROT_NONSECURE = UInt(2, width = protBits)
14 | def PROT_INSTRUCTION = UInt(4, width = protBits)
15 | def PROT_DEFAULT = PROT_PRIVILEDGED
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/SRAM.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.apb
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.util._
9 | import freechips.rocketchip.tilelink.LFSRNoiseMaker
10 |
11 | class APBRAM(
12 | address: AddressSet,
13 | executable: Boolean = true,
14 | beatBytes: Int = 4,
15 | devName: Option[String] = None,
16 | errors: Seq[AddressSet] = Nil,
17 | fuzzReady: Boolean = false,
18 | fuzzError: Boolean = false)
19 | (implicit p: Parameters) extends DiplomaticSRAM(address, beatBytes, devName)
20 | {
21 | val node = APBSlaveNode(Seq(APBSlavePortParameters(
22 | Seq(APBSlaveParameters(
23 | address = List(address) ++ errors,
24 | resources = resources,
25 | regionType = RegionType.UNCACHED,
26 | executable = executable,
27 | supportsRead = true,
28 | supportsWrite = true)),
29 | beatBytes = beatBytes)))
30 |
31 | lazy val module = new LazyModuleImp(this) {
32 | val (in, _) = node.in(0)
33 | val (mem, omMem) = makeSinglePortedByteWriteSeqMem(1 << mask.filter(b=>b).size)
34 |
35 | val paddr = Cat((mask zip (in.paddr >> log2Ceil(beatBytes)).asBools).filter(_._1).map(_._2).reverse)
36 | val legal = address.contains(in.paddr)
37 |
38 | val read = in.psel && !in.penable && !in.pwrite
39 | when (in.psel && !in.penable && in.pwrite && legal) {
40 | mem.write(paddr, Vec.tabulate(beatBytes) { i => in.pwdata(8*(i+1)-1, 8*i) }, in.pstrb.asBools)
41 | }
42 |
43 | in.pready := Bool(!fuzzReady) || LFSRNoiseMaker(1)(0)
44 | in.pslverr := RegEnable(!legal, !in.penable) || (Bool(fuzzError) && LFSRNoiseMaker(1)(0))
45 | in.prdata := mem.readAndHold(paddr, read).asUInt
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/Test.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.apb
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.tilelink._
9 | import freechips.rocketchip.unittest._
10 |
11 | class RRTest0(address: BigInt)(implicit p: Parameters) extends APBRegisterRouter(address, 0, 32, 0, 4)(
12 | new APBRegBundle((), _) with RRTest0Bundle)(
13 | new APBRegModule((), _, _) with RRTest0Module)
14 |
15 | class RRTest1(address: BigInt)(implicit p: Parameters) extends APBRegisterRouter(address, 0, 32, 1, 4, false)(
16 | new APBRegBundle((), _) with RRTest1Bundle)(
17 | new APBRegModule((), _, _) with RRTest1Module)
18 |
19 | class APBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule
20 | {
21 | val fuzz = LazyModule(new TLFuzzer(txns))
22 | val model = LazyModule(new TLRAMModel("APBFuzzMaster"))
23 | val xbar = LazyModule(new APBFanout)
24 | val ram = LazyModule(new APBRAM(AddressSet(0x0, 0xff), fuzzReady = true, fuzzError = true))
25 | val gpio = LazyModule(new RRTest0(0x100))
26 |
27 | ram.node := xbar.node
28 | gpio.node := xbar.node
29 | (xbar.node
30 | := TLToAPB(aFlow)
31 | := TLDelayer(0.2)
32 | := TLBuffer(BufferParams.flow)
33 | := TLDelayer(0.2)
34 | := TLFragmenter(4, 8)
35 | := model.node
36 | := fuzz.node)
37 |
38 | lazy val module = new LazyModuleImp(this) with UnitTestModule {
39 | io.finished := fuzz.module.io.finished
40 | }
41 | }
42 |
43 | class APBBridgeTest(aFlow: Boolean, txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
44 | val dut = Module(LazyModule(new APBFuzzBridge(aFlow, txns)).module)
45 | io.finished := dut.io.finished
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/Xbar.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.apb
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.regmapper._
9 | import scala.math.{min,max}
10 |
11 | class APBFanout()(implicit p: Parameters) extends LazyModule {
12 | val node = APBNexusNode(
13 | masterFn = { case Seq(m) => m },
14 | slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
15 |
16 | lazy val module = new LazyModuleImp(this) {
17 | if (node.edges.in.size >= 1) {
18 | require (node.edges.in.size == 1, "APBFanout does not support multiple masters")
19 | require (node.edges.out.size > 0, "APBFanout requires at least one slave")
20 |
21 | val (in, _) = node.in(0)
22 |
23 | // Require consistent bus widths
24 | val (io_out, edgesOut) = node.out.unzip
25 | val port0 = edgesOut(0).slave
26 | edgesOut.foreach { edge =>
27 | val port = edge.slave
28 | require (port.beatBytes == port0.beatBytes,
29 | s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}")
30 | }
31 |
32 | val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten)
33 | val routingMask = AddressDecoder(port_addrs)
34 | val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct)
35 |
36 | val sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.paddr)).reduce(_ || _)))
37 | (sel zip io_out) foreach { case (sel, out) =>
38 | out := in
39 | out.psel := sel && in.psel
40 | out.penable := sel && in.penable
41 | }
42 |
43 | in.pready := !Mux1H(sel, io_out.map(!_.pready))
44 | in.pslverr := Mux1H(sel, io_out.map(_.pslverr))
45 | in.prdata := Mux1H(sel, io_out.map(_.prdata))
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/scala/amba/apb/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba
4 |
5 | import Chisel._
6 | import freechips.rocketchip.diplomacy._
7 |
8 | package object apb
9 | {
10 | type APBOutwardNode = OutwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
11 | type APBInwardNode = InwardNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
12 | type APBNode = SimpleNodeHandle[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle]
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/scala/amba/axi4/CrossingHelper.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.axi4
4 |
5 | import freechips.rocketchip.config.Parameters
6 | import freechips.rocketchip.diplomacy._
7 |
8 | case class AXI4InwardCrossingHelper(name: String, scope: LazyScope, node: AXI4InwardNode) {
9 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): AXI4InwardNode = {
10 | xing match {
11 | case x: AsynchronousCrossing =>
12 | node :*=* scope { AXI4AsyncCrossingSink(x.asSinkParams) :*=* AXI4AsyncNameNode(name) } :*=* AXI4AsyncNameNode(name) :*=* AXI4AsyncCrossingSource(x.sourceSync)
13 | case RationalCrossing(direction) =>
14 | throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
15 | case SynchronousCrossing(buffer) =>
16 | node :*=* scope { AXI4Buffer(buffer) :*=* AXI4NameNode(name) } :*=* AXI4NameNode(name)
17 | }
18 | }
19 | }
20 |
21 | case class AXI4OutwardCrossingHelper(name: String, scope: LazyScope, node: AXI4OutwardNode) {
22 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): AXI4OutwardNode = {
23 | xing match {
24 | case x: AsynchronousCrossing =>
25 | AXI4AsyncCrossingSink(x.asSinkParams) :*=* AXI4AsyncNameNode(name) :*=* scope { AXI4AsyncNameNode(name) :*=* AXI4AsyncCrossingSource(x.sourceSync) } :*=* node
26 | case RationalCrossing(direction) =>
27 | throw new IllegalArgumentException("AXI4 Rational crossing unimplemented")
28 | case SynchronousCrossing(buffer) =>
29 | AXI4NameNode(name) :*=* scope { AXI4NameNode(name) :*=* AXI4Buffer(buffer) } :*=* node
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/scala/amba/axi4/Dumper.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.axi4
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 |
9 | class AXI4Dumper()(implicit p: Parameters) extends LazyModule
10 | {
11 | val node = AXI4AdapterNode()
12 |
13 | lazy val module = new LazyModuleImp(this) {
14 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
15 | out <> in
16 | when (in.ar.fire()) {
17 | // printf("dumper: ar[len] = %d [addr] = 0x%x\n", in.ar.bits.len, in.ar.bits.addr)
18 | }
19 | }
20 | }
21 | }
22 |
23 | object AXI4Dumper
24 | {
25 | def apply()(implicit p: Parameters): AXI4Node =
26 | {
27 | val axi4dump = LazyModule(new AXI4Dumper())
28 | axi4dump.node
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/src/main/scala/amba/axi4/Protocol.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba.axi4
4 |
5 | import Chisel._
6 | import chisel3.util.{Irrevocable, IrrevocableIO}
7 |
8 | object AXI4Parameters
9 | {
10 | // These are all fixed by the AXI4 standard:
11 | val lenBits = 8
12 | val sizeBits = 3
13 | val burstBits = 2
14 | val lockBits = 1
15 | val cacheBits = 4
16 | val protBits = 3
17 | val qosBits = 4
18 | val respBits = 2
19 |
20 | def CACHE_RALLOCATE = UInt(8, width = cacheBits)
21 | def CACHE_WALLOCATE = UInt(4, width = cacheBits)
22 | def CACHE_MODIFIABLE = UInt(2, width = cacheBits)
23 | def CACHE_BUFFERABLE = UInt(1, width = cacheBits)
24 |
25 | def PROT_PRIVILEDGED = UInt(1, width = protBits)
26 | def PROT_INSECURE = UInt(2, width = protBits)
27 | def PROT_INSTRUCTION = UInt(4, width = protBits)
28 |
29 | def BURST_FIXED = UInt(0, width = burstBits)
30 | def BURST_INCR = UInt(1, width = burstBits)
31 | def BURST_WRAP = UInt(2, width = burstBits)
32 |
33 | def RESP_OKAY = UInt(0, width = respBits)
34 | def RESP_EXOKAY = UInt(1, width = respBits)
35 | def RESP_SLVERR = UInt(2, width = respBits)
36 | def RESP_DECERR = UInt(3, width = respBits)
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/scala/amba/axi4/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.amba
4 |
5 | import Chisel._
6 | import freechips.rocketchip.diplomacy._
7 |
8 | package object axi4
9 | {
10 | type AXI4Node = SimpleNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
11 | type AXI4OutwardNode = OutwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
12 | type AXI4InwardNode = InwardNodeHandle[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle]
13 |
14 | implicit class AXI4ClockDomainCrossing(val x: HasClockDomainCrossing) extends AnyVal {
15 | def crossIn (n: AXI4InwardNode) (implicit valName: ValName) = AXI4InwardCrossingHelper(valName.name, x, n)
16 | def crossOut(n: AXI4OutwardNode)(implicit valName: ValName) = AXI4OutwardCrossingHelper(valName.name, x, n)
17 | def cross(n: AXI4InwardNode) (implicit valName: ValName) = crossIn(n)
18 | def cross(n: AXI4OutwardNode)(implicit valName: ValName) = crossOut(n)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/scala/debug/DebugBundles.scala:
--------------------------------------------------------------------------------
1 |
2 | package freechips.rocketchip.debug
3 |
4 | import chisel3._
5 |
6 |
7 | class DebugCSRIntIO extends Bundle() {
8 | // from CSR/core's perspective
9 | val dmiInterrupt = Input(Bool())
10 | val ndmiInterrupts = Output(UInt(16.W))
11 | val eipOutstanding = Output(Bool())
12 | val csrOutInt = Output(Bool())
13 | val reg_mip = Output(UInt(64.W))
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/main/scala/debug/Stats.scala:
--------------------------------------------------------------------------------
1 |
2 | package freechips.rocketchip.debug
3 |
4 | import chisel3._
5 | import chisel3.internal.naming.chiselName
6 | import chisel3.util.experimental.BoringUtils
7 |
8 | @chiselName
9 | class Stats () {
10 | val counter = RegInit(0.U(48.W))
11 | }
12 |
13 | object Stats {
14 | @chiselName
15 | def apply(stat_name: String, hartId: Int): Stats = {
16 | val c = new freechips.rocketchip.debug.Stats()
17 | val dump_trigger = Wire(Bool())
18 | dump_trigger := false.B
19 | BoringUtils.addSink(dump_trigger, "DumpFlag" + hartId.toString)
20 | when (dump_trigger) {
21 | printf("Stats::")
22 | stat_name.foreach{c => printf(p"${Character(c.toInt.U)}")}
23 | printf(": %d\n", c.counter)
24 | }
25 | c
26 | }
27 | }
--------------------------------------------------------------------------------
/src/main/scala/devices/debug/DebugRomContents.scala:
--------------------------------------------------------------------------------
1 | // This file was auto-generated by 'make publish' in debug/ directory.
2 |
3 | package freechips.rocketchip.devices.debug
4 |
5 | object DebugRomContents {
6 |
7 | def apply() : Array[Byte] = { Array (
8 | 0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x80, 0x03, 0x6f, 0x00, 0x40, 0x04,
9 | 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1,
10 | 0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x34, 0x00,
11 | 0xe3, 0x08, 0x04, 0xfe, 0x13, 0x74, 0x14, 0x00, 0x63, 0x08, 0x04, 0x00,
12 | 0x73, 0x24, 0x20, 0x7b, 0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30,
13 | 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b,
14 | 0x73, 0x00, 0x20, 0x7b, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00
15 | ).map(_.toByte) }
16 |
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/src/main/scala/devices/tilelink/BusBlocker.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.devices.tilelink
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.regmapper._
9 | import freechips.rocketchip.tilelink._
10 | import freechips.rocketchip.util._
11 |
12 | /** BasicBusBlocker uses a single bit register to control whether
13 | * accesses of all types are allowed to proceed or bypassed to
14 | * a /dev/null device. It has a second bit register to report
15 | * whether any requests are pending on either path.
16 | */
17 |
18 | case class BasicBusBlockerParams(
19 | controlAddress: BigInt,
20 | controlBeatBytes: Int,
21 | deviceBeatBytes: Int,
22 | deadlock: Boolean = false)
23 |
24 | class BasicBusBlocker(params: BasicBusBlockerParams)(implicit p: Parameters)
25 | extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock)
26 | {
27 | val device = new SimpleDevice("basic-bus-blocker", Seq("sifive,basic-bus-blocker0"))
28 |
29 | val controlNode = TLRegisterNode(
30 | address = Seq(AddressSet(params.controlAddress, 0xFFF)),
31 | device = device,
32 | beatBytes = params.controlBeatBytes)
33 |
34 | lazy val module = new LazyModuleImp(this) {
35 | val allow = RegInit(true.B)
36 | val pending = RegNext(bar.module.io.pending)
37 |
38 | controlNode.regmap(
39 | 0 -> Seq(RegField (32, allow,
40 | RegFieldDesc("allow",
41 | "Used to enable/disable bus transactions", reset=Some(1)))),
42 | 4 -> Seq(RegField.r(32, pending, RegFieldDesc("pending",
43 | "Indicates if bus transactions are in-flight", volatile=true)))
44 | )
45 |
46 | bar.module.io.bypass := !allow
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/scala/devices/tilelink/CanHaveBuiltInDevices.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.devices.tilelink
4 |
5 | import freechips.rocketchip.config.Parameters
6 | import freechips.rocketchip.diplomacy._
7 | import freechips.rocketchip.tilelink._
8 |
9 | trait HasBuiltInDeviceParams {
10 | val zeroDevice: Option[AddressSet]
11 | val errorDevice: Option[DevNullParams]
12 | }
13 |
14 | /* Optionally add some built-in devices to a bus wrapper */
15 | trait CanHaveBuiltInDevices { this: TLBusWrapper =>
16 |
17 | def attachBuiltInDevices(params: HasBuiltInDeviceParams) {
18 | params.errorDevice.foreach { dnp => LazyScope("wrapped_error_device") {
19 | val error = LazyModule(new TLError(
20 | params = dnp,
21 | beatBytes = beatBytes))
22 | error.node := TLBuffer() := outwardNode
23 | }}
24 |
25 | params.zeroDevice.foreach { addr => LazyScope("wrapped_zero_device") {
26 | val zero = LazyModule(new TLZero(
27 | address = addr,
28 | beatBytes = beatBytes))
29 | zero.node := TLFragmenter(beatBytes, blockBytes) := TLBuffer() := outwardNode
30 | }}
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/src/main/scala/devices/tilelink/Deadlock.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.devices.tilelink
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 |
9 | /** Adds a /dev/null slave that does not raise ready for any incoming traffic.
10 | * !!! WARNING: This device WILL cause your bus to deadlock for as long as you
11 | * continue to send traffic to it !!!
12 | */
13 | class TLDeadlock(params: DevNullParams, beatBytes: Int = 4)(implicit p: Parameters)
14 | extends DevNullDevice(params, beatBytes, new SimpleDevice("deadlock-device", Seq("sifive,deadlock0")))
15 | {
16 | lazy val module = new LazyModuleImp(this) {
17 | val (in, _) = node.in(0)
18 | in.a.ready := Bool(false)
19 | in.b.valid := Bool(false)
20 | in.c.ready := Bool(false)
21 | in.d.valid := Bool(false)
22 | in.e.ready := Bool(false)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/scala/devices/tilelink/Zero.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.devices.tilelink
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.tilelink.TLMessages
9 |
10 | /** This /dev/null device accepts single beat gets/puts, as well as atomics.
11 | * Response data is always 0. Reequests to write data have no effect.
12 | */
13 | class TLZero(address: AddressSet, beatBytes: Int = 4)(implicit p: Parameters)
14 | extends DevNullDevice(
15 | params = DevNullParams(
16 | address = List(address),
17 | maxAtomic = beatBytes,
18 | maxTransfer = beatBytes,
19 | region = RegionType.UNCACHED,
20 | executable = true,
21 | mayDenyGet = false,
22 | mayDenyPut = false),
23 | beatBytes = beatBytes,
24 | device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))) {
25 | lazy val module = new LazyModuleImp(this) {
26 | val (in, edge) = node.in(0)
27 |
28 | val a = Queue(in.a, 2)
29 |
30 | a.ready := in.d.ready
31 | in.d.valid := a.valid
32 | in.d.bits := edge.AccessAck(a.bits)
33 | in.d.bits.opcode := TLMessages.adResponse(edge.opcode(a.bits))
34 |
35 | // Tie off unused channels
36 | in.b.valid := Bool(false)
37 | in.c.ready := Bool(true)
38 | in.e.ready := Bool(true)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/scala/diplomacy/ClockDomain.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomacy
4 |
5 | trait HasClockDomainCrossing extends LazyScope { this: LazyModule => }
6 |
--------------------------------------------------------------------------------
/src/main/scala/diplomacy/Clone.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomacy
4 |
5 | import Chisel._
6 | import chisel3.shim.CloneModule
7 |
8 | final class CloneLazyModule private (val base: LazyModule)
9 | {
10 | // Pay special attention to the .iParams and .oParams of the node, which
11 | // indicate the parameters a stand-in master must supply.
12 | def clone[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](node: NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO])(implicit valName: ValName) =
13 | new MixedTestNode(node, this)
14 |
15 | protected[diplomacy] lazy val io = CloneModule(base.module)
16 | }
17 |
18 | object CloneLazyModule
19 | {
20 | def apply(base: LazyModule) = new CloneLazyModule(base)
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/scala/diplomacy/FixedClockResource.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomacy
4 |
5 | class FixedClockResource(val name: String, val freqMHz: Double, val prefix: String = "soc/")
6 | {
7 | val device = new DeviceSnippet {
8 | def describe() =
9 | Description(prefix + name, Map(
10 | "#clock-cells" -> Seq(ResourceInt(0)),
11 | "clock-frequency" -> Seq(ResourceInt(freqMHz * 1000000)),
12 | "clock-output-names" -> Seq(ResourceString(name)),
13 | "compatible" -> Seq(ResourceString("fixed-clock"))))
14 | }
15 |
16 | def bind(dev: Device) {
17 | ResourceBinding { Resource(dev, "clocks").bind(ResourceReference(device.label)) }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/scala/diplomacy/JSON.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomacy
4 |
5 | import scala.collection.immutable.SortedMap
6 |
7 | object JSON
8 | {
9 | def apply(res: ResourceValue): String = {
10 | val root = res match {
11 | case ResourceMap(value, _) => value.toList match {
12 | case Seq(("/", Seq(subtree))) => subtree
13 | case _ => res
14 | }
15 | case _ => res
16 | }
17 | helper(root)(SortedMap(map(root):_*)).mkString
18 | }
19 |
20 | private def map(res: ResourceValue, path: String = ""): Seq[(String, String)] = res match {
21 | case ResourceMap(value, labels) => {
22 | labels.map(_ -> path) ++
23 | value.flatMap { case (key, seq) => seq.flatMap(map(_, path + "/" + key)) }
24 | }
25 | case _ => Nil
26 | }
27 |
28 | private def helper(res: ResourceValue)(implicit path: Map[String, String]): Seq[String] = res match {
29 | case ResourceAddress(address, ResourcePermissions(r, w, x, c, a)) =>
30 | AddressRange.fromSets(address).map { case AddressRange(base, size) =>
31 | s"""{"base":${base},"size":${size},"r":${r},"w":${w},"x":${x},"c":${c},"a":${a}}"""}
32 | case ResourceMapping(address, offset, ResourcePermissions(r, w, x, c, a)) =>
33 | AddressRange.fromSets(address).map { case AddressRange(base, size) =>
34 | s"""{"base":${base},"size":${size},"offset":${offset},"r":${r},"w":${w},"x":${x},"c":${c},"a":${a}}"""}
35 | case ResourceInt(value) => Seq(value.toString)
36 | case ResourceString(value) => Seq("\"" + value + "\"")
37 | case ResourceReference(value) => Seq("\"&" + path(value) + "\"")
38 | case ResourceAlias(value) => Seq("\"&" + path(value) + "\"")
39 | case ResourceMap(value, _) => {
40 | Seq(value.map {
41 | case (key, Seq(v: ResourceMap)) => s""""${key}":${helper(v).mkString}"""
42 | case (key, seq) => s""""${key}":[${seq.flatMap(helper).mkString(",")}]"""
43 | }.mkString("{", ",", "}"))
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/scala/diplomacy/ValName.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomacy
4 |
5 | import scala.language.experimental.macros
6 | import freechips.rocketchip.macros.ValNameImpl
7 |
8 | case class ValName(name: String)
9 |
10 | object ValName
11 | {
12 | implicit def materialize(implicit x: ValNameImpl): ValName = ValName(x.name)
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/DiplomaticObjectModel.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel
4 |
5 | import freechips.rocketchip.diplomaticobjectmodel.model.OMComponent
6 |
7 | import scala.collection.mutable.ListBuffer
8 |
9 | class OMCollector {
10 | def getComponent(): Seq[OMComponent] = Nil
11 | }
12 |
13 | object DiplomaticObjectModel {
14 | private val doms = ListBuffer[OMCollector]()
15 |
16 | def add(d: OMCollector): Unit = {
17 | doms += (d)
18 | }
19 |
20 | def getComponents(): OMComponent = {
21 | doms.flatMap(_.getComponent()).head
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/ISASpecifications.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | sealed trait PrivilegedArchitectureExtension extends OMEnum
6 | case object MachineLevelISA extends PrivilegedArchitectureExtension
7 | case object SupervisorLevelISA extends PrivilegedArchitectureExtension
8 |
9 | object PrivilegedArchitectureExtensions {
10 | val specifications = Map[PrivilegedArchitectureExtension, String](
11 | MachineLevelISA -> "Machine-Level ISA",
12 | SupervisorLevelISA -> "Supervisor-Level ISA"
13 | )
14 |
15 | def specVersion(extension: PrivilegedArchitectureExtension, version: String): OMSpecification = OMSpecification(specifications(extension), version)
16 | }
17 |
18 | object BaseExtensions {
19 | val specifications = Map[OMBaseInstructionSet, String](
20 | RV32E -> "RV32E Base Integer Instruction Set",
21 | RV32I -> "RV32I Base Integer Instruction Set",
22 | RV64I -> "RV64I Base Integer Instruction Set"
23 | )
24 |
25 | def specVersion(extension: OMBaseInstructionSet, version: String): OMSpecification = OMSpecification(specifications(extension), version)
26 | }
27 |
28 | object ISAExtensions {
29 | val specifications = Map[OMExtensionType, String](
30 | M -> "M Standard Extension for Integer Multiplication and Division",
31 | A -> "A Standard Extension for Atomic Instruction",
32 | F -> "F Standard Extension for Single-Precision Floating-Point",
33 | D -> "D Standard Extension for Double-Precision Floating-Point",
34 | C -> "C Standard Extension for Compressed Instruction",
35 | U -> "The RISC‑V Instruction Set Manual, Volume II: Privileged Architecture",
36 | S -> "Supervisor-Level ISA"
37 | )
38 |
39 | def specVersion(extension: OMExtensionType, version: String): OMSpecification = OMSpecification(specifications(extension), version)
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMBase.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | trait OMBaseType
6 |
7 | trait OMEnum extends OMBaseType
8 |
9 | trait OMCompoundType extends OMBaseType
10 |
11 | trait OMComponent extends OMCompoundType
12 |
13 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMBranchPredictor.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | trait OMBranchPredictor extends OMComponent
6 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMCLINT.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | case class OMCLINT(
6 | memoryRegions: Seq[OMMemoryRegion],
7 | interrupts: Seq[OMInterrupt],
8 | specifications: List[OMSpecification],
9 | _types: Seq[String] = Seq("OMCLINT", "OMDevice", "OMComponent", "OMCompoundType")
10 | ) extends OMDevice
11 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMCaches.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | trait OMCache extends OMDevice {
6 | def memoryRegions(): Seq[OMMemoryRegion]
7 | def interrupts(): Seq[OMInterrupt]
8 | def nSets: Int
9 | def nWays: Int
10 | def blockSizeBytes: Int
11 | def dataMemorySizeBytes: Int
12 | def dataECC: Option[OMECC]
13 | def tagECC: Option[OMECC]
14 | def nTLBEntries: Int
15 | }
16 |
17 | case class OMICache(
18 | memoryRegions: Seq[OMMemoryRegion],
19 | interrupts: Seq[OMInterrupt],
20 | nSets: Int,
21 | nWays: Int,
22 | blockSizeBytes: Int,
23 | dataMemorySizeBytes: Int,
24 | dataECC: Option[OMECC],
25 | tagECC: Option[OMECC],
26 | nTLBEntries: Int,
27 | maxTimSize: Int,
28 | _types: Seq[String] = Seq("OMICache", "OMCache", "OMDevice", "OMComponent", "OMCompoundType")
29 | ) extends OMCache
30 |
31 | case class OMDCache(
32 | memoryRegions: Seq[OMMemoryRegion],
33 | interrupts: Seq[OMInterrupt],
34 | nSets: Int,
35 | nWays: Int,
36 | blockSizeBytes: Int,
37 | dataMemorySizeBytes: Int,
38 | dataECC: Option[OMECC],
39 | tagECC: Option[OMECC],
40 | nTLBEntries: Int,
41 | _types: Seq[String] = Seq("OMDCache", "OMCache", "OMDevice", "OMComponent", "OMCompoundType")
42 | ) extends OMCache
43 |
44 | case class OMECC(code: String) extends OMBaseType
45 |
46 | object OMECC {
47 | val Identity = OMECC("Identity")
48 | val Parity = OMECC("Parity")
49 | val SEC = OMECC("SEC")
50 | val SECDED = OMECC("SECDED")
51 |
52 | def getCode(code: String): OMECC = {
53 | code.toLowerCase match {
54 | case "identity" => OMECC.Identity
55 | case "parity" => OMECC.Parity
56 | case "sec" => OMECC.SEC
57 | case "secded" => OMECC.SECDED
58 | case _ => throw new IllegalArgumentException(s"ERROR: invalid getCode arg: $code")
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMCore.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | trait OMCore extends OMComponent{
6 | def isa: OMISA
7 | def mulDiv: Option[OMMulDiv]
8 | def performanceMonitor: Option[OMPerformanceMonitor]
9 | def pmp: Option[OMPMP]
10 | def documentationName: String
11 | def hartIds: Seq[Int]
12 | def hasVectoredInterrupts: Boolean
13 | def interruptLatency: Int
14 | def nLocalInterrupts: Int
15 | def nBreakpoints: Int
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMDebug.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | sealed trait DebugInterfaceType extends OMEnum
6 | case object JTAG extends DebugInterfaceType
7 | case object CJTAG extends DebugInterfaceType
8 | case object DMI extends DebugInterfaceType
9 |
10 | case class OMDebug(
11 | memoryRegions: Seq[OMMemoryRegion],
12 | interrupts: Seq[OMInterrupt],
13 | specifications: List[OMSpecification],
14 | nAbstractDataWords: Int,
15 | nProgramBufferWords: Int,
16 | interfaceType: DebugInterfaceType,
17 | _types: Seq[String] = Seq("OMDebug", "OMDevice", "OMComponent", "OMCompoundType")
18 | ) extends OMDevice
19 |
20 | object OMDebug {
21 |
22 | def getDebugInterfaceType(jtag: Boolean, cjtag: Boolean, dmi: Boolean): DebugInterfaceType = {
23 | if (jtag) { JTAG }
24 | else if (cjtag) { CJTAG }
25 | else if (dmi) { DMI }
26 | else { throw new IllegalArgumentException }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMDevice.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | trait OMDevice extends OMComponent {
6 | def memoryRegions: Seq[OMMemoryRegion]
7 | def interrupts: Seq[OMInterrupt]
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMFPU.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | case class OMFPU(
6 | fLen: Int,
7 | _types: Seq[String] = Seq("OMFPU", "OMComponent", "OMCompoundType")
8 | ) extends OMComponent
9 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMInterrupts.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | case class OMInterrupt(
6 | receiver: String, // TODO Reference
7 | numberAtReceiver: BigInt,
8 | name: String,
9 | _types: Seq[String] = Seq("OMInterrupt", "OMCompoundType")
10 | ) extends OMCompoundType
11 |
12 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMMemory.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | case class OMMemory(
6 | description: String,
7 | addressWidth: Int,
8 | dataWidth: Int,
9 | depth: Int,
10 | writeMaskGranularity: Int,
11 | _types: Seq[String] = Seq("OMMemory")
12 | )
13 |
14 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMMulDiv.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | import freechips.rocketchip.rocket.MulDivParams
6 |
7 | case class OMMulDiv(
8 | divideBitsPerCycle: Int,
9 | divideMaxLatency: Int,
10 | divideMinLatency: Int,
11 | multiplyBitsPerCycle: Int,
12 | multiplyFullyPipelined: Boolean,
13 | multiplyMaxLatency: Int,
14 | multiplyMinLatency: Int,
15 | _types: Seq[String] = Seq("OMMulDiv", "OMComponent", "OMCompoundType")
16 | ) extends OMComponent
17 |
18 |
19 | object OMMulDiv {
20 | def makeOMI(md: MulDivParams, xLen: Int): OMMulDiv = {
21 | val mulMinLatency =
22 | if (md.mulUnroll > 0) {
23 | if (md.mulEarlyOut) { 2 }
24 | else { xLen/md.mulUnroll }
25 | }
26 | else { xLen }
27 |
28 | val divMinLatency =
29 | if (md.divUnroll > 0) {
30 | if (md.divEarlyOut) { 3 }
31 | else { 2 }
32 | }
33 | else { xLen }
34 |
35 | OMMulDiv(
36 | divideBitsPerCycle = md.divUnroll,
37 | divideMaxLatency = xLen / md.divUnroll,
38 | divideMinLatency = divMinLatency,
39 | multiplyBitsPerCycle = md.mulUnroll,
40 | multiplyFullyPipelined = md.mulUnroll == xLen,
41 | multiplyMaxLatency = xLen / md.mulUnroll,
42 | multiplyMinLatency = mulMinLatency
43 | )
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMPLIC.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | sealed trait OMPrivilegeMode extends OMEnum
6 | case object OMMachineMode extends OMPrivilegeMode
7 | case object OMSupervisorMode extends OMPrivilegeMode
8 | case object OMUserMode extends OMPrivilegeMode
9 |
10 | object OMModes {
11 | def getModes(useVM: Boolean): Seq[OMPrivilegeMode] = {
12 | useVM match {
13 | case false => Seq(OMMachineMode)
14 | case true => Seq(OMMachineMode, OMSupervisorMode)
15 | }
16 | }
17 | }
18 |
19 | case class OMInterruptTarget(
20 | hartId: Int,
21 | modes: Seq[OMPrivilegeMode],
22 | _types: Seq[String] = Seq("OMInterruptTarget", "OMCompoundType")
23 | ) extends OMCompoundType
24 |
25 | case class OMPLIC(
26 | memoryRegions: Seq[OMMemoryRegion],
27 | interrupts: Seq[OMInterrupt],
28 | specifications: Seq[OMSpecification],
29 | latency: Int,
30 | nPriorities: Int,
31 | targets: Seq[OMInterruptTarget],
32 | _types: Seq[String] = Seq("OMPLIC", "OMDevice", "OMComponent", "OMCompoundType")
33 | ) extends OMDevice
34 |
35 | object OMPLIC {
36 | def getMode(length: Int): Seq[OMPrivilegeMode] = {
37 | length match {
38 | case 1 => Seq(OMMachineMode)
39 | case 2 => Seq(OMMachineMode,OMSupervisorMode)
40 | case _ => throw new IllegalArgumentException
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMPMP.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | import freechips.rocketchip.rocket.RocketCoreParams
6 |
7 | case class OMPMP(
8 | specifications: Seq[OMSpecification],
9 | nRegions: Int,
10 | granularity: Int,
11 | _types: Seq[String] = Seq("OMPMP", "OMComponent", "OMCompoundType")
12 | ) extends OMComponent
13 |
14 | object OMPMP {
15 | def pmp(coreParams: RocketCoreParams): Option[OMPMP] = {
16 | if (coreParams.pmpGranularity > 0 || coreParams.nPMPs > 0) {
17 | Some(OMPMP(
18 | specifications = List[OMSpecification](PrivilegedArchitectureExtensions.specVersion(MachineLevelISA, "1.10")),
19 | nRegions = coreParams.nPMPs,
20 | granularity = coreParams.pmpGranularity
21 | ))
22 | }
23 | else {
24 | None
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMPerformanceMonitor.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | import freechips.rocketchip.rocket.RocketCoreParams
6 |
7 | case class OMPerformanceMonitor(
8 | specifications: List[OMSpecification],
9 | hasBasicCounters: Boolean,
10 | nAdditionalCounters: Int,
11 | _types: Seq[String] = Seq("OMPerformanceMonitor", "OMComponent", "OMCompoundType")
12 | ) extends OMComponent
13 |
14 | object PerformanceMonitor {
15 | def permon(coreParams: RocketCoreParams): Option[OMPerformanceMonitor] = {
16 | if (coreParams.haveBasicCounters || coreParams.nPerfCounters > 0) {
17 | Some(OMPerformanceMonitor(
18 | specifications = List[OMSpecification](PrivilegedArchitectureExtensions.specVersion(MachineLevelISA, "1.10")),
19 | hasBasicCounters = coreParams.haveBasicCounters,
20 | nAdditionalCounters = coreParams.nPerfCounters
21 | ))
22 | }
23 | else {
24 | None
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMRTLModule.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | trait RTLComponent extends OMCompoundType
6 |
7 | trait OMSignal extends RTLComponent {
8 | def name: String // This will always be the name of the signal on the top-level module
9 | def description: Option[String]
10 | }
11 |
12 | case class OMClock(
13 | name: String,
14 | description: Option[String]
15 | ) extends OMSignal
16 |
17 | case class OMClockRelationship(
18 | clock0: String,
19 | clock1: String,
20 | relationship: String,
21 | ) extends RTLComponent
22 |
23 | trait OMSignalAssertionLevel extends OMEnum
24 | trait High extends OMSignalAssertionLevel
25 | trait Low extends OMSignalAssertionLevel
26 |
27 | trait Synchronicity extends OMEnum
28 | trait Synchronous extends Synchronicity
29 | trait Asynchronous extends Synchronicity
30 |
31 | case class OMRTLReset(
32 | activeEdge: Option[OMSignalAssertionLevel],
33 | clock: String, // This will always be the name of the clock signal on the to p-level module
34 | synchronicity: Option[Synchronicity]
35 | )
36 |
37 | case class OMResetVector(
38 | width: Int
39 | )
40 |
41 | case class OMRTLInterface(
42 | clocks: List[OMClock],
43 | clockRelationships: List[OMClockRelationship],
44 | resets: List[OMRTLReset]
45 | ) extends RTLComponent
46 |
47 | case class OMRTLModule(
48 | moduleName: String,
49 | instanceName: Option[String], // TODO: This does not exist for the top-level module because the top-level module is the only one that is not instantiated
50 | hierarchicalId: Option[String], // Full dotted path from the root, where the root is described as a module name while all other path components are instance names
51 | interface: OMRTLInterface
52 | )
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMRegFieldAccessType.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | sealed trait OMRegFieldAccessType extends OMEnum
6 | case object R extends OMRegFieldAccessType
7 | case object W extends OMRegFieldAccessType
8 | case object RW extends OMRegFieldAccessType
9 |
10 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMRegFieldRdAction.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | sealed trait OMRegFieldRdAction extends OMEnum
6 | case object RFRA_CLEAR extends OMRegFieldRdAction
7 | case object RFRA_SET extends OMRegFieldRdAction
8 | case object RFRA_MODIFY extends OMRegFieldRdAction
9 |
10 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMRegFieldWrType.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | /* The following enum names come from IP-XACT */
6 | sealed trait OMRegFieldWrType extends OMEnum
7 | case object RFWT_ONE_TO_CLEAR extends OMRegFieldWrType
8 | case object RFWT_ONE_TO_SET extends OMRegFieldWrType
9 | case object RFWT_ONE_TO_TOGGLE extends OMRegFieldWrType
10 | case object RFWT_ZERO_TO_CLEAR extends OMRegFieldWrType
11 | case object RFWT_ZERO_TO_SET extends OMRegFieldWrType
12 | case object RFWT_ZERO_TO_TOGGLE extends OMRegFieldWrType
13 | case object RFWT_CLEAR extends OMRegFieldWrType
14 | case object RFWT_SET extends OMRegFieldWrType
15 | case object RFWT_MODIFY extends OMRegFieldWrType
16 |
17 |
--------------------------------------------------------------------------------
/src/main/scala/diplomaticobjectmodel/model/OMSpecification.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.diplomaticobjectmodel.model
4 |
5 | case class OMSpecification(
6 | name: String,
7 | version: String,
8 | _types: Seq[String] = Seq("OMSpecification")
9 | )
10 |
--------------------------------------------------------------------------------
/src/main/scala/groundtest/Configs.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 | // See LICENSE.Berkeley for license details.
3 |
4 | package freechips.rocketchip.groundtest
5 |
6 | import Chisel._
7 | import freechips.rocketchip.config.Config
8 | import freechips.rocketchip.subsystem._
9 | import freechips.rocketchip.rocket.{DCacheParams}
10 | import freechips.rocketchip.tile.{MaxHartIdBits, XLen}
11 |
12 | /** Actual testing target Configs */
13 |
14 | class TraceGenConfig extends Config(new WithTraceGen(List.fill(2){ DCacheParams(nSets = 16, nWays = 1) }) ++ new BaseSubsystemConfig)
15 |
16 | class TraceGenBufferlessConfig extends Config(new WithBufferlessBroadcastHub ++ new TraceGenConfig)
17 |
18 | /* Composable Configs to set individual parameters */
19 |
20 | class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192) extends Config((site, here, up) => {
21 | case GroundTestTilesKey => params.map { dcp => TraceGenParams(
22 | dcache = Some(dcp),
23 | wordBits = site(XLen),
24 | addrBits = 32,
25 | addrBag = {
26 | val nSets = 2
27 | val nWays = 1
28 | val blockOffset = site(SystemBusKey).blockOffset
29 | val nBeats = site(SystemBusKey).blockBeats
30 | List.tabulate(4 * nWays) { i =>
31 | Seq.tabulate(nBeats) { j => BigInt((j * 8) + ((i * nSets) << blockOffset)) }
32 | }.flatten
33 | },
34 | maxRequests = nReqs,
35 | memStart = site(ExtMem).get.master.base,
36 | numGens = params.size)
37 | }
38 | case MaxHartIdBits => log2Up(params.size)
39 | })
40 |
--------------------------------------------------------------------------------
/src/main/scala/groundtest/Generator.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.groundtest
4 |
5 | import freechips.rocketchip.util.GeneratorApp
6 |
7 | object Generator extends GeneratorApp {
8 | val longName = names.topModuleProject + "." + names.configs
9 | generateFirrtl
10 | generateAnno
11 | generateTestSuiteMakefrags // TODO: Needed only for legacy make targets
12 | generateArtefacts
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/scala/groundtest/Package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip
4 |
5 | package object groundtest {
6 | val testRamAddr = 0x10000
7 | val timeoutCodeBits = 4
8 | val errorCodeBits = 4
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/scala/groundtest/Status.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.groundtest
4 |
5 | import Chisel._
6 | import freechips.rocketchip.util.ValidMux
7 |
8 | class GroundTestStatus extends Bundle {
9 | val finished = Bool(OUTPUT)
10 | val timeout = Valid(UInt(width = 4))
11 | val error = Valid(UInt(width = 4))
12 | }
13 |
14 | object DebugCombiner {
15 | def apply(debugs: Seq[GroundTestStatus]): GroundTestStatus = {
16 | val out = Wire(new GroundTestStatus)
17 | out.finished := debugs.map(_.finished).reduce(_ && _)
18 | out.timeout := ValidMux(debugs.map(_.timeout))
19 | out.error := ValidMux(debugs.map(_.error))
20 | out
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/main/scala/groundtest/TestHarness.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.groundtest
4 |
5 | import Chisel._
6 |
7 | import freechips.rocketchip.config.Parameters
8 | import freechips.rocketchip.diplomacy.LazyModule
9 |
10 | class TestHarness(implicit p: Parameters) extends Module {
11 | val io = new Bundle { val success = Bool(OUTPUT) }
12 | val dut = Module(LazyModule(new GroundTestSubsystem).module)
13 | io.success := dut.success
14 | dut.connectSimAXIMem()
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/scala/interrupts/Bundles.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.interrupts
4 |
5 | import Chisel._
6 | import freechips.rocketchip.diplomacy._
7 | import freechips.rocketchip.util._
8 |
9 | class SyncInterrupts(params: IntEdge) extends GenericParameterizedBundle(params)
10 | {
11 | val sync = Vec(params.source.num, Bool())
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/scala/interrupts/CrossingHelper.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.interrupts
4 |
5 | import freechips.rocketchip.config.Parameters
6 | import freechips.rocketchip.diplomacy._
7 |
8 | case class IntInwardCrossingHelper(name: String, scope: LazyScope, node: IntInwardNode) {
9 | def apply(xing: ClockCrossingType = NoCrossing, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntInwardNode = {
10 | xing match {
11 | case x: AsynchronousCrossing =>
12 | node :*=* scope { IntSyncCrossingSink(x.sinkSync) :*=* IntSyncNameNode(name) } :*=* IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered)
13 | case RationalCrossing(_) =>
14 | node :*=* scope { IntSyncCrossingSink(1) :*=* IntSyncNameNode(name) } :*=* IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered)
15 | case SynchronousCrossing(_) =>
16 | node :*=* scope { IntSyncCrossingSink(0) :*=* IntSyncNameNode(name) } :*=* IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered)
17 | }
18 | }
19 | }
20 |
21 | case class IntOutwardCrossingHelper(name: String, scope: LazyScope, node: IntOutwardNode) {
22 | def apply(xing: ClockCrossingType = NoCrossing, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntOutwardNode = {
23 | xing match {
24 | case x: AsynchronousCrossing =>
25 | IntSyncCrossingSink(x.sinkSync) :*=* IntSyncNameNode(name) :*=* scope { IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) } :*=* node
26 | case RationalCrossing(_) =>
27 | IntSyncCrossingSink(1) :*=* IntSyncNameNode(name) :*=* scope { IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) } :*=* node
28 | case SynchronousCrossing(buffer) =>
29 | IntSyncCrossingSink(0) :*=* IntSyncNameNode(name) :*=* scope { IntSyncNameNode(name) :*=* IntSyncCrossingSource(alreadyRegistered) } :*=* node
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/scala/interrupts/NullIntSource.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.interrupts
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 |
9 | /** Useful for stubbing out parts of an interrupt interface where certain devices might be missing */
10 | class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters) extends LazyModule
11 | {
12 | val intnode = IntSourceNode(IntSourcePortSimple(num, ports, sources))
13 |
14 | lazy val module = new LazyModuleImp(this) {
15 | intnode.out.foreach { case (o, _) => o.foreach { _ := false.B } }
16 | }
17 | }
18 |
19 | object NullIntSource {
20 | def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntNode = {
21 | val null_int_source = LazyModule(new NullIntSource(num, ports, sources))
22 | null_int_source.intnode
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/scala/interrupts/RegisterRouter.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.interrupts
4 |
5 | import chisel3._
6 | import freechips.rocketchip.diplomacy._
7 | import freechips.rocketchip.regmapper._
8 |
9 | /** Mix this trait into a RegisterRouter to be able to attach its interrupt sources to an interrupt bus */
10 | trait HasInterruptSources { this: RegisterRouter[_] =>
11 | def nInterrupts: Int
12 | protected val intnode = IntSourceNode(IntSourcePortSimple(num = nInterrupts, resources = Seq(Resource(device, "int"))))
13 |
14 | // Externally, this helper should be used to connect the interrupts to a bus
15 | val intXing: IntOutwardCrossingHelper = this.crossOut(intnode)
16 |
17 | // Internally, this wire should be used to drive interrupt values
18 | val interrupts: ModuleValue[Vec[Bool]] = InModuleBody { if (intnode.out.isEmpty) Vec(0, Bool()) else intnode.out(0)._1 }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/scala/interrupts/Xbar.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.interrupts
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 |
9 | class IntXbar()(implicit p: Parameters) extends LazyModule
10 | {
11 | val intnode = IntNexusNode(
12 | sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
13 | sourceFn = { seq =>
14 | IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map {
15 | case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o)))
16 | }.flatten)
17 | })
18 |
19 | lazy val module = new LazyModuleImp(this) {
20 | val cat = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten
21 | intnode.out.foreach { case (o, _) => o := cat }
22 | }
23 | }
24 |
25 | object IntXbar {
26 | def apply(implicit p: Parameters): IntNode = {
27 | val xbar = LazyModule(new IntXbar)
28 | xbar.intnode
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/scala/interrupts/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip
4 |
5 | import Chisel._
6 | import freechips.rocketchip.diplomacy._
7 |
8 | package object interrupts
9 | {
10 | type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
11 | type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
12 | type IntNode = SimpleNodeHandle[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]]
13 |
14 | implicit class IntClockDomainCrossing(val x: HasClockDomainCrossing) extends AnyVal {
15 | def crossIn (n: IntInwardNode) (implicit valName: ValName) = IntInwardCrossingHelper(valName.name, x, n)
16 | def crossOut(n: IntOutwardNode)(implicit valName: ValName) = IntOutwardCrossingHelper(valName.name, x, n)
17 | def cross(n: IntInwardNode) (implicit valName: ValName) = crossIn(n)
18 | def cross(n: IntOutwardNode)(implicit valName: ValName) = crossOut(n)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/scala/jtag/JtagUtils.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.jtag for license details.
2 |
3 | package freechips.rocketchip.jtag
4 |
5 | import Chisel._
6 | //import chisel3._
7 | import chisel3.util._
8 |
9 | class JTAGIdcodeBundle extends Bundle {
10 | val version = UInt(4.W)
11 | val partNumber = UInt(16.W)
12 | val mfrId = UInt(11.W)
13 | val always1 = UInt(1.W)
14 | }
15 |
16 | object JtagIdcode {
17 | /** Generates a JTAG IDCODE as a 32-bit integer, using the format in 12.1.1d.
18 | */
19 | def apply(version: Int, partNumber: Int, mfrId: Int): BigInt = {
20 | require(version < (1 << 4), "version field must be 4 bits at most")
21 | require(partNumber < (1 << 16), "part number must be 16 bits at most")
22 | require(mfrId < (1 << 11), "manufacturer identity must be 11 bits at most")
23 | BigInt(version) << 28 | BigInt(partNumber) << 12 | BigInt(mfrId) << 1 | 1
24 | }
25 |
26 | /** A dummy manufacturer ID, not to be used per 12.2.1b since bus masters may shift this out to
27 | * determine the end of a bus.
28 | */
29 | def dummyMfrId: Int = 0x7f
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/scala/jtag/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.jtag for license details
2 |
3 | package freechips.rocketchip
4 |
5 | import scala.language.implicitConversions
6 |
7 | package object jtag {
8 | /** An implicit conversion to allow the instruction map for the TAP generator to be specified as
9 | * an Int instead of BigInt. Scala doesn't seem to want to automatically apply the built-in Int
10 | * to BigInt conversion when used as a Map key.
11 | *
12 | * This is limited to value types of Chain to limit application scope.
13 | */
14 | implicit def instructionIntKeyToBigInt[V <: Chain](x: (Int, V)) = (BigInt(x._1), x._2)
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/scala/lvna/Dirty.scala:
--------------------------------------------------------------------------------
1 |
2 | package freechips.rocketchip.config
3 |
4 |
5 | case object MemInitAddr extends Field[BigInt]
6 |
7 | class LvNADirtyConfig extends Config ((site, here, up) => {
8 | case MemInitAddr => BigInt(0x80000000L)
9 | })
10 |
--------------------------------------------------------------------------------
/src/main/scala/lvna/ILA.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package ila
4 |
5 | import Chisel._
6 |
7 | class ILABundle extends Bundle {
8 | val hartid = UInt(OUTPUT, 2)
9 |
10 | val csr_time = UInt(OUTPUT, 32)
11 | val pc = UInt(OUTPUT, 40)
12 | val instr_valid = Bool(OUTPUT)
13 | val instr = UInt(OUTPUT, 32)
14 |
15 | val rd_wen = Bool(OUTPUT)
16 | val rd_waddr = UInt(OUTPUT, 5)
17 | val rd_wdata = UInt(OUTPUT, 64)
18 |
19 | val rs_raddr = UInt(OUTPUT, 5)
20 | val rs_rdata = UInt(OUTPUT, 64)
21 | val rt_raddr = UInt(OUTPUT, 5)
22 | val rt_rdata = UInt(OUTPUT, 64)
23 | }
24 |
25 | class BoomCSRILABundle extends Bundle {
26 | val trigger = Bool(OUTPUT)
27 | val reg_mip = UInt(OUTPUT, 64)
28 | val csr_rw_cmd = UInt(OUTPUT, 3)
29 | val csr_rw_wdata = UInt(OUTPUT, 64)
30 | val wr_mip = Bool(OUTPUT)
31 | val reg_mbadaddr = UInt(OUTPUT, 64)
32 | }
33 |
34 | class FPGATraceBaseBundle(val commWidth: Int) extends Bundle {
35 | val traces = Vec(commWidth, new Bundle {
36 | val valid = Bool()
37 | val commPriv = UInt(OUTPUT, 2)
38 | val commPC = UInt(OUTPUT, 40)
39 | val commInst = UInt(OUTPUT, 32)
40 |
41 | val isFloat = Bool()
42 | val wbValueValid = Bool()
43 | val wbARFN = UInt(OUTPUT, 6)
44 | val wbValue = UInt(OUTPUT, 64)
45 |
46 | })
47 | }
48 |
49 | class FPGATraceExtraBundle extends Bundle { // For rocket's delayed wb
50 | val delayedWbValid = Bool()
51 | val wbARFN = UInt(OUTPUT, 6)
52 | val wbValue = UInt(OUTPUT, 64)
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/scala/lvna/LvNATop.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.system
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import lvna._
8 | import sifive.blocks.devices.uart._
9 |
10 |
11 | class LvNABoomEmuTop(implicit p: Parameters) extends ExampleBoomSystem
12 | with HasPeripheryUART
13 | with HasBoomControlPlane
14 | {
15 | override lazy val module = new LvNABoomEmuTopModule(this)
16 | }
17 |
18 | class LvNABoomEmuTopModule[+L <: LvNABoomEmuTop](_outer: L) extends ExampleBoomSystemModuleImp(_outer)
19 | with HasPeripheryUARTModuleImp
20 | with HasControlPlaneBoomModuleImpl
21 |
22 | class LvNAEmuTop(implicit p: Parameters) extends ExampleRocketSystem
23 | with HasPeripheryUART
24 | with HasControlPlane
25 | with BindL2WayMask
26 | {
27 | override lazy val module = new LvNAEmuTopModule(this)
28 | }
29 |
30 | class LvNAEmuTopModule[+L <: LvNAEmuTop](_outer: L) extends ExampleRocketSystemModuleImp(_outer)
31 | with HasPeripheryUARTModuleImp
32 | with HasControlPlaneModuleImpl
33 | with BindL2WayMaskModuleImp
34 |
35 |
36 | class LvNAFPGATop(implicit p: Parameters) extends ExampleRocketSystem
37 | with HasControlPlane
38 | with BindL2WayMask
39 | {
40 | override lazy val module = new LvNAFPGATopModule(this)
41 | }
42 |
43 | class LvNAFPGATopModule[+L <: LvNAFPGATop](_outer: L) extends ExampleRocketSystemModuleImp(_outer)
44 | with HasControlPlaneModuleImpl
45 | with BindL2WayMaskModuleImp
46 |
47 | //class LvNAFPGATopAHB(implicit p: Parameters) extends ExampleRocketSystemAHB
48 | //
49 | //class LvNAFPGATopAHBModule[+L <: LvNAFPGATopAHB](_outer: L) extends ExampleRocketSystemModuleAHBImp(_outer)
50 |
51 | class LvNABoomFPGATopModule[+L <: LvNABoomFPGATop](_outer: L) extends ExampleBoomSystemModuleImp(_outer)
52 | with HasControlPlaneBoomModuleImpl
53 |
54 | class LvNABoomFPGATop(implicit p: Parameters) extends ExampleBoomSystem
55 | with HasBoomControlPlane
56 | {
57 | override lazy val module = new LvNABoomFPGATopModule(this)
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/src/main/scala/lvna/controlplane/TokenBucketNode.scala:
--------------------------------------------------------------------------------
1 | package lvna
2 |
3 | import chisel3._
4 | import freechips.rocketchip.config._
5 | import freechips.rocketchip.diplomacy._
6 | import freechips.rocketchip.tilelink._
7 | import freechips.rocketchip.util._
8 | import boom.common._
9 |
10 | class TokenBucketNode(implicit p: Parameters) extends LazyModule {
11 | val node = TLIdentityNode()
12 | lazy val module = new TokenBucketNodeImp(this)
13 | }
14 |
15 | class TokenBucketNodeImp(outer: TokenBucketNode) extends LazyModuleImp(outer) {
16 | val (bundleIn, _) = outer.node.in.unzip
17 | val (bundleOut, _) = outer.node.out.unzip
18 |
19 | val bucketIO = IO(Flipped(new BucketIO()))
20 |
21 | // require(bundleIn.size == 1, s"[TokenBucket] Only expect one link for a hart, current link count is ${bundleIn.size}")
22 | val (in, out) = (bundleIn zip bundleOut).head
23 |
24 | val phy = in.a.bits.address < p(MemInitAddr).U
25 |
26 | bucketIO.dsid := in.a.bits.dsid
27 | bucketIO.fire := out.a.ready && out.a.valid && !phy
28 | bucketIO.size := (1.U << in.a.bits.size) >> 6
29 |
30 | out.a.valid := in.a.valid && (phy || bucketIO.enable)
31 | in.a.ready := out.a.ready && (phy || bucketIO.enable)
32 | if (DEBUG_TB_FETCH) {
33 | when(in.a.valid && !out.a.valid) {
34 | printf(p"request blocked by token bucket: 0x${Hexadecimal(in.a.bits.address)}\n")
35 | }
36 | when(out.a.valid && !in.a.ready) {
37 | printf(p"response blocked by token bucket: 0x${Hexadecimal(in.a.bits.address)}\n")
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/scala/regmapper/Annotation.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.regmapper
4 |
5 | import chisel3.experimental.{ChiselAnnotation, RawModule, RunFirrtlTransform}
6 | import firrtl.annotations._
7 | import firrtl.{CircuitForm, CircuitState, LowForm, Transform}
8 |
9 | case class RegFieldDescSer(
10 | byteOffset: String,
11 | bitOffset: Int,
12 | bitWidth: Int,
13 | name: String,
14 | resetValue: BigInt,
15 | accessType: String,
16 | wrType: String,
17 | rdAction: String,
18 | desc: String,
19 | group: String,
20 | groupDesc: String,
21 | volatile: Boolean = false,
22 | hasReset: Boolean = false,
23 | enumerations: Map[BigInt, (String, String)] = Map()
24 | )
25 |
26 | case class RegistersSer(
27 | displayName: String,
28 | deviceName: String,
29 | baseAddress: BigInt,
30 | regFields: Seq[RegFieldDescSer]
31 | )
32 |
--------------------------------------------------------------------------------
/src/main/scala/regmapper/DescribedReg.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package freechips.rocketchip.regmapper
3 |
4 | import Chisel._
5 | import chisel3.experimental._
6 | import chisel3.{Input, Output}
7 | import freechips.rocketchip.util.{AsyncResetRegVec, SimpleRegIO}
8 |
9 | object DescribedReg {
10 | import freechips.rocketchip.regmapper.RegFieldAccessType._
11 | import freechips.rocketchip.regmapper.RegFieldWrType._
12 | import freechips.rocketchip.regmapper.RegFieldRdAction._
13 |
14 | def apply[T <: Data](
15 | gen: => T,
16 | name: String,
17 | desc: String,
18 | reset: Option[T],
19 | access: RegFieldAccessType = RW,
20 | wrType: Option[RegFieldWrType] = None,
21 | rdAction: Option[RegFieldRdAction] = None,
22 | volatile: Boolean = false,
23 | enumerations: Map[BigInt, (String, String)] = Map()): (T, RegFieldDesc) = {
24 | val rdesc = RegFieldDesc(name, desc, None, None,
25 | access, wrType, rdAction, volatile, reset.map{_.litValue}, enumerations)
26 | val reg = reset.map{i => RegInit(i)}.getOrElse(Reg(gen))
27 | reg.suggestName(name + "_reg")
28 | (reg, rdesc)
29 | }
30 |
31 | def async(
32 | width: Int,
33 | name: String,
34 | desc: String,
35 | reset: Int,
36 | access: RegFieldAccessType = RW,
37 | wrType: Option[RegFieldWrType] = None,
38 | rdAction: Option[RegFieldRdAction] = None,
39 | volatile: Boolean = false,
40 | enumerations: Map[BigInt, (String, String)] = Map()): (SimpleRegIO, RegFieldDesc) = {
41 | val rdesc = RegFieldDesc(name, desc, None, None,
42 | access, wrType, rdAction, volatile, Some(reset), enumerations)
43 | val reg = Module(new AsyncResetRegVec(w = width, init = reset))
44 | reg.suggestName(name + "_reg")
45 | (reg.io, rdesc)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/scala/regmapper/RegisterRouter.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.regmapper
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.interrupts._
9 | import freechips.rocketchip.tilelink._
10 |
11 | case class RegisterRouterParams(
12 | name: String,
13 | compat: Seq[String],
14 | base: BigInt,
15 | size: BigInt = 4096,
16 | concurrency: Int = 0,
17 | beatBytes: Int = 4,
18 | undefZero: Boolean = true,
19 | executable: Boolean = false)
20 |
21 | abstract class RegisterRouter[T <: Data](devParams: RegisterRouterParams)(implicit p: Parameters)
22 | extends LazyModule
23 | with HasClockDomainCrossing {
24 |
25 | require (isPow2(devParams.size))
26 | val address = Seq(AddressSet(devParams.base, devParams.size-1))
27 | val concurrency = devParams.concurrency
28 | val beatBytes = devParams.beatBytes
29 | val undefZero = devParams.undefZero
30 | val executable = devParams.executable
31 | val device = new SimpleDevice(devParams.name, devParams.compat) {
32 | override def describe(resources: ResourceBindings): Description = {
33 | val Description(name, mapping) = super.describe(resources)
34 | Description(name, mapping ++ extraResources(resources))
35 | }
36 | }
37 | // Allow devices to extend the DTS mapping
38 | def extraResources(resources: ResourceBindings) = Map[String, Seq[ResourceValue]]()
39 |
40 | protected def regmap(mapping: RegField.Map*): Unit
41 | }
42 |
43 | abstract class IORegisterRouter[T <: Data](devParams: RegisterRouterParams, portBundle: => T)(implicit p: Parameters)
44 | extends RegisterRouter(devParams) {
45 | val ioNode = BundleBridgeSource(() => portBundle.cloneType)
46 | val port = InModuleBody { ioNode.bundle }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/scala/rocket/Events.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 | // See LICENSE.SiFive for license details.
3 |
4 | package freechips.rocketchip.rocket
5 |
6 | import Chisel._
7 | import freechips.rocketchip.util._
8 | import freechips.rocketchip.util.property._
9 |
10 | class EventSet(gate: (UInt, UInt) => Bool, events: Seq[(String, () => Bool)]) {
11 | def size = events.size
12 | def hits = events.map(_._2()).asUInt
13 | def check(mask: UInt) = gate(mask, hits)
14 | def dump() {
15 | for (((name, _), i) <- events.zipWithIndex)
16 | when (check(1.U << i)) { printf(s"Event $name\n") }
17 | }
18 | def withCovers {
19 | events.zipWithIndex.foreach {
20 | case ((name, func), i) => cover(gate((1.U << i), (func() << i)), name)
21 | }
22 | }
23 | }
24 |
25 | class EventSets(val eventSets: Seq[EventSet]) {
26 | def maskEventSelector(eventSel: UInt): UInt = {
27 | // allow full associativity between counters and event sets (for now?)
28 | val setMask = (BigInt(1) << log2Ceil(eventSets.size)) - 1
29 | val maskMask = ((BigInt(1) << eventSets.map(_.size).max) - 1) << eventSetIdBits
30 | eventSel & (setMask | maskMask).U
31 | }
32 |
33 | private def decode(counter: UInt): (UInt, UInt) = {
34 | require(eventSets.size <= (1 << eventSetIdBits))
35 | (counter(log2Ceil(eventSets.size)-1, 0), counter >> eventSetIdBits)
36 | }
37 |
38 | def evaluate(eventSel: UInt): Bool = {
39 | val (set, mask) = decode(eventSel)
40 | val sets = eventSets map (_ check mask)
41 | sets(set)
42 | }
43 |
44 | def cover() = eventSets.foreach { _ withCovers }
45 |
46 | private def eventSetIdBits = 8
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/scala/rocket/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 |
3 | package freechips.rocketchip
4 |
5 | package object rocket extends rocket.constants.ScalarOpConstants with rocket.constants.MemoryOpConstants
6 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/devices/uart/UARTCtrlRegs.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.devices.uart
3 |
4 | object UARTCtrlRegs {
5 | val rxfifo = 0x00
6 | val txfifo = 0x04
7 | val stat = 0x08
8 | val ctrl = 0x0c
9 |
10 | /*
11 | val txfifo = 0x00
12 | val rxfifo = 0x04
13 | val txctrl = 0x08
14 | val txmark = 0x0a
15 | val rxctrl = 0x0c
16 | val rxmark = 0x0e
17 |
18 | val ie = 0x10
19 | val ip = 0x14
20 | val div = 0x18
21 | */
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/devices/uart/UARTPeriphery.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.devices.uart
3 |
4 | import Chisel._
5 | import freechips.rocketchip.tilelink._
6 | import freechips.rocketchip.config.Field
7 | import freechips.rocketchip.subsystem._
8 | import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
9 |
10 | //case object PeripheryUARTKey extends Field[Seq[UARTParams]]
11 |
12 | trait HasPeripheryUART { this: BaseSubsystem =>
13 | val uartParams = Seq.tabulate(p(NTiles)) { i => //p(PeripheryUARTKey)
14 | UARTParams(address = BigInt(0x60000000L + i * 0x1000L))
15 | }
16 | val uarts = uartParams map { params =>
17 | val uart = LazyModule(new TLUART(pbus.beatBytes, params))
18 |
19 | pbus.toVariableWidthSlave(Some("uart")) { uart.node }
20 | ibus.fromSync := uart.intnode
21 | uart
22 | }
23 | }
24 |
25 | trait HasPeripheryUARTModuleImp extends LazyModuleImp {
26 | val outer: HasPeripheryUART
27 | val io = IO(new Bundle {
28 | val uarts = Vec(outer.uartParams.size, new UARTPortIO)
29 | })
30 | (io.uarts zip outer.uarts).foreach { case (io, device) =>
31 | io <> device.module.io.port
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/devices/uart/UARTPrinter.scala:
--------------------------------------------------------------------------------
1 | package sifive.blocks.devices.uart
2 |
3 | import chisel3._
4 |
5 | // if you have a clock
6 | // use UARTPrinter
7 | // if do not have a clock(eg: you can not extend Module)
8 | // you can use UARTPrinterWrapper
9 | class UARTPrinter(filename: String) extends BlackBox(
10 | Map("FILENAME" -> chisel3.core.StringParam(filename))) {
11 | val io = IO(new Bundle {
12 | val clock = Input(Clock())
13 | val valid = Input(Bool())
14 | val data = Input(UInt(8.W)) // Always expect an ASCII character
15 | })
16 | }
17 |
18 | class UARTPrinterWrapper(filename: String) extends Module {
19 | val io = IO(new Bundle {
20 | val valid = Input(Bool())
21 | val data = Input(UInt(8.W)) // Always expect an ASCII character
22 | })
23 |
24 | val printer = Module(new UARTPrinter(filename))
25 | printer.io.clock := clock;
26 | printer.io.valid := io.valid;
27 | printer.io.data := io.data;
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/util/DeglitchShiftRegister.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.util
3 |
4 | import Chisel._
5 |
6 | //Allows us to specify a different clock for a shift register
7 | // and to force input to be high for > 1 cycle.
8 | class DeglitchShiftRegister(shift: Int) extends Module {
9 | val io = new Bundle {
10 | val d = Bool(INPUT)
11 | val q = Bool(OUTPUT)
12 | }
13 | val sync = ShiftRegister(io.d, shift)
14 | val last = ShiftRegister(sync, 1)
15 | io.q := sync & last
16 | }
17 |
18 | object DeglitchShiftRegister {
19 | def apply (shift: Int, d: Bool, clock: Clock,
20 | name: Option[String] = None): Bool = {
21 | val deglitch = Module (new DeglitchShiftRegister(shift))
22 | name.foreach(deglitch.suggestName(_))
23 | deglitch.clock := clock
24 | deglitch.reset := Bool(false)
25 | deglitch.io.d := d
26 | deglitch.io.q
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/util/RegMapFIFO.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.util
3 |
4 | import Chisel._
5 | import freechips.rocketchip.regmapper._
6 |
7 | // MSB indicates full status
8 | object NonBlockingEnqueue {
9 | def apply(enq: DecoupledIO[UInt], regWidth: Int = 32): Seq[RegField] = {
10 | val enqWidth = enq.bits.getWidth
11 | require(enqWidth > 0)
12 | require(regWidth > enqWidth)
13 | Seq(
14 | RegField(enqWidth,
15 | RegReadFn(UInt(0)),
16 | RegWriteFn((valid, data) => {
17 | enq.valid := valid
18 | enq.bits := data
19 | Bool(true)
20 | })),
21 | RegField(regWidth - enqWidth - 1),
22 | RegField.r(1, !enq.ready))
23 | }
24 | }
25 |
26 | // MSB indicates empty status
27 | object NonBlockingDequeue {
28 | def apply(deq: DecoupledIO[UInt], regWidth: Int = 32): Seq[RegField] = {
29 | val deqWidth = deq.bits.getWidth
30 | require(deqWidth > 0)
31 | require(regWidth > deqWidth)
32 | Seq(
33 | RegField.r(deqWidth,
34 | RegReadFn(ready => {
35 | deq.ready := ready
36 | (Bool(true), deq.bits)
37 | })),
38 | RegField(regWidth - deqWidth - 1),
39 | RegField.r(1, !deq.valid))
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/util/ResetCatchAndSync.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.util
3 |
4 | import Chisel._
5 | import freechips.rocketchip.util.AsyncResetRegVec
6 |
7 | /** Reset: asynchronous assert,
8 | * synchronous de-assert
9 | *
10 | */
11 |
12 | class ResetCatchAndSync (sync: Int = 3) extends Module {
13 |
14 | val io = new Bundle {
15 | val sync_reset = Bool(OUTPUT)
16 | }
17 |
18 | val reset_n_catch_reg = Module (new AsyncResetRegVec(sync, 0))
19 |
20 | reset_n_catch_reg.io.en := Bool(true)
21 | reset_n_catch_reg.io.d := Cat(Bool(true), reset_n_catch_reg.io.q >> 1)
22 |
23 | io.sync_reset := ~reset_n_catch_reg.io.q(0)
24 |
25 | }
26 |
27 | object ResetCatchAndSync {
28 |
29 | def apply(clk: Clock, rst: Bool, sync: Int = 3, name: Option[String] = None): Bool = {
30 |
31 | val catcher = Module (new ResetCatchAndSync(sync))
32 | if (name.isDefined) {catcher.suggestName(name.get)}
33 | catcher.clock := clk
34 | catcher.reset := rst
35 |
36 | catcher.io.sync_reset
37 | }
38 |
39 | def apply(clk: Clock, rst: Bool, sync: Int, name: String): Bool = apply(clk, rst, sync, Some(name))
40 | def apply(clk: Clock, rst: Bool, name: String): Bool = apply(clk, rst, name = Some(name))
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/util/SRLatch.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.util
3 |
4 | import Chisel._
5 |
6 | class SRLatch extends BlackBox {
7 | val io = new Bundle {
8 | val set = Bool(INPUT)
9 | val reset = Bool(INPUT)
10 | val q = Bool(OUTPUT)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/util/ShiftReg.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | package sifive.blocks.util
3 |
4 | import Chisel._
5 |
6 | object ShiftRegisterInit {
7 | def apply[T <: Data](in: T, n: Int, init: T): T =
8 | (0 until n).foldLeft(in) {
9 | case (next, _) => Reg(next, next = next, init = init)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/scala/sifive-blocks/vsrc/SRLatch.v:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 | module SRLatch (
3 | input set,
4 | input reset,
5 | output q
6 | );
7 |
8 | reg latch;
9 |
10 | // synopsys async_set_reset "set"
11 | // synopsys one_hot "set, reset"
12 | always @(set or reset)
13 | begin
14 | if (set)
15 | latch <= 1'b1;
16 | else if (reset)
17 | latch <= 1'b0;
18 | end
19 |
20 | assign q = latch;
21 |
22 | endmodule
23 |
--------------------------------------------------------------------------------
/src/main/scala/subsystem/FrontBus.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.subsystem
4 |
5 | import freechips.rocketchip.config.{Parameters}
6 | import freechips.rocketchip.devices.tilelink._
7 | import freechips.rocketchip.diplomacy._
8 | import freechips.rocketchip.tilelink._
9 |
10 | case class FrontBusParams(
11 | beatBytes: Int,
12 | blockBytes: Int,
13 | zeroDevice: Option[AddressSet] = None,
14 | errorDevice: Option[DevNullParams] = None)
15 | extends HasTLBusParams with HasBuiltInDeviceParams
16 |
17 | class FrontBus(params: FrontBusParams)(implicit p: Parameters)
18 | extends TLBusWrapper(params, "front_bus")
19 | with CanHaveBuiltInDevices
20 | with CanAttachTLMasters
21 | with HasTLXbarPhy {
22 | attachBuiltInDevices(params)
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/scala/subsystem/RTC.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.subsystem
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config._
7 | import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase}
8 | import freechips.rocketchip.devices.tilelink.CanHavePeripheryCLINT
9 |
10 | case object RTCPeriod extends Field[Int]
11 |
12 | trait HasRTCModuleImp extends LazyModuleImp {
13 | val outer: BaseSubsystem with CanHavePeripheryCLINT
14 | private val pbusFreq = outer.p(PeripheryBusKey).frequency
15 | private val rtcFreq = outer.p(DTSTimebase)
16 | private val internalPeriod: BigInt = pbusFreq / rtcFreq
17 |
18 | // check whether pbusFreq >= rtcFreq
19 | require(internalPeriod > 0)
20 | // check wehther the integer division is within 5% of the real division
21 | require((pbusFreq - rtcFreq * internalPeriod) * 100 / pbusFreq <= 5)
22 |
23 | // Use the static period to toggle the RTC
24 | val (_, int_rtc_tick) = Counter(true.B, internalPeriod.toInt)
25 | //val (_, int_rtc_tick) = Counter(true.B, p(RTCPeriod))
26 |
27 | outer.clintOpt.foreach { clint =>
28 | clint.module.io.rtcTick := int_rtc_tick
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/scala/subsystem/ResetVector.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.subsystem
4 |
5 | import Chisel._
6 |
7 | /** A single place for all tiles to find out the reset vector */
8 | trait HasResetVectorWire {
9 | def resetVectorBits: Int
10 | val global_reset_vector = Wire(UInt(width = resetVectorBits))
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/scala/subsystem/SystemBus.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.subsystem
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.{Parameters}
7 | import freechips.rocketchip.devices.tilelink._
8 | import freechips.rocketchip.diplomacy._
9 | import freechips.rocketchip.tilelink._
10 | import freechips.rocketchip.util._
11 | import lvna.TokenBucketNode
12 |
13 | case class SystemBusParams(
14 | beatBytes: Int,
15 | blockBytes: Int,
16 | policy: TLArbiter.Policy = TLArbiter.roundRobin,
17 | zeroDevice: Option[AddressSet] = None,
18 | errorDevice: Option[DevNullParams] = None)
19 | extends HasTLBusParams with HasBuiltInDeviceParams
20 |
21 | class SystemBus(params: SystemBusParams)(implicit p: Parameters)
22 | extends TLBusWrapper(params, "system_bus")
23 | with CanHaveBuiltInDevices
24 | with CanAttachTLSlaves
25 | with CanAttachTLMasters
26 | with HasTLXbarPhy {
27 | attachBuiltInDevices(params)
28 |
29 | def fromTile
30 | (name: Option[String], buffer: BufferParams = BufferParams.none, cork: Option[Boolean] = None, token: Option[TokenBucketNode] = None)
31 | (gen: => TLOutwardNode): NoHandle = {
32 | // println(s"inward node size: ${inwardNode.inward.inputs.size}")
33 | // println(s"outward node size: ${gen.outward.outputs.size}")
34 | from("tile" named name) {
35 | if (token.isDefined) {
36 | inwardNode := token.get.node :=* TLBuffer(buffer) :=* TLFIFOFixer(TLFIFOFixer.allUncacheable) :=* gen
37 | }
38 | else {
39 | inwardNode :=* TLBuffer(buffer) :=* TLFIFOFixer(TLFIFOFixer.allUncacheable) :=* gen
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/scala/tile/CustomCSRs.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tile
4 |
5 | import chisel3._
6 |
7 | import freechips.rocketchip.config.Parameters
8 |
9 | case class CustomCSR(id: Int, mask: BigInt, init: Option[BigInt])
10 |
11 | object CustomCSR {
12 | def constant(id: Int, value: BigInt): CustomCSR = CustomCSR(id, BigInt(0), Some(value))
13 | }
14 |
15 | class CustomCSRIO(implicit p: Parameters) extends CoreBundle {
16 | val wen = Bool()
17 | val wdata = UInt(xLen.W)
18 | val value = UInt(xLen.W)
19 | }
20 |
21 | class CustomCSRs(implicit p: Parameters) extends CoreBundle {
22 | // Not all cores have these CSRs, but those that do should follow the same
23 | // numbering conventions. So we list them here but default them to None.
24 | protected def bpmCSRId = 0x7c0
25 | protected def bpmCSR: Option[CustomCSR] = None
26 |
27 | protected def chickenCSRId = 0x7c1
28 | protected def chickenCSR: Option[CustomCSR] = None
29 |
30 | // If you override this, you'll want to concatenate super.decls
31 | def decls: Seq[CustomCSR] = bpmCSR.toSeq ++ chickenCSR
32 |
33 | val csrs = Vec(decls.size, new CustomCSRIO)
34 |
35 | def flushBTB = getOrElse(bpmCSR, _.wen, false.B)
36 | def bpmStatic = getOrElse(bpmCSR, _.value(0), false.B)
37 | def disableDCacheClockGate = getOrElse(chickenCSR, _.value(0), true.B)
38 | def disableICacheClockGate = getOrElse(chickenCSR, _.value(1), true.B)
39 | def disableCoreClockGate = getOrElse(chickenCSR, _.value(2), true.B)
40 |
41 | protected def getByIdOrElse[T](id: Int, f: CustomCSRIO => T, alt: T): T = {
42 | val idx = decls.indexWhere(_.id == id)
43 | if (idx < 0) alt else f(csrs(idx))
44 | }
45 |
46 | protected def getOrElse[T](csr: Option[CustomCSR], f: CustomCSRIO => T, alt: T): T =
47 | csr.map(c => getByIdOrElse(c.id, f, alt)).getOrElse(alt)
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/scala/tile/L1Cache.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tile
4 |
5 | import Chisel._
6 |
7 | import freechips.rocketchip.config.{Parameters, Field}
8 | import freechips.rocketchip.subsystem.CacheBlockBytes
9 | import freechips.rocketchip.tilelink.ClientMetadata
10 | import freechips.rocketchip.util._
11 |
12 | trait L1CacheParams {
13 | def nSets: Int
14 | def nWays: Int
15 | def rowBits: Int
16 | def nTLBEntries: Int
17 | def blockBytes: Int // TODO this is ignored in favor of p(CacheBlockBytes) in BaseTile
18 | }
19 |
20 | trait HasL1CacheParameters extends HasTileParameters {
21 | val cacheParams: L1CacheParams
22 | private val bundleParams = p(SharedMemoryTLEdge).bundle
23 |
24 | def nSets = cacheParams.nSets
25 | def blockOffBits = lgCacheBlockBytes
26 | def idxBits = log2Up(cacheParams.nSets)
27 | def untagBits = blockOffBits + idxBits
28 | def tagBits = bundleParams.addressBits - (if (usingVM) untagBits min pgIdxBits else untagBits)
29 | def nWays = cacheParams.nWays
30 | def wayBits = log2Up(nWays)
31 | def isDM = nWays == 1
32 | def rowBits = cacheParams.rowBits
33 | def rowBytes = rowBits/8
34 | def rowOffBits = log2Up(rowBytes)
35 | def nTLBEntries = cacheParams.nTLBEntries
36 |
37 | def cacheDataBits = bundleParams.dataBits
38 | def cacheDataBeats = (cacheBlockBytes * 8) / cacheDataBits
39 | def refillCycles = cacheDataBeats
40 | }
41 |
42 | abstract class L1CacheModule(implicit val p: Parameters) extends Module
43 | with HasL1CacheParameters
44 |
45 | abstract class L1CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
46 | with HasL1CacheParameters
47 |
--------------------------------------------------------------------------------
/src/main/scala/tilelink/CrossingHelper.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tilelink
4 |
5 | import freechips.rocketchip.config.Parameters
6 | import freechips.rocketchip.diplomacy._
7 | import freechips.rocketchip.util.RationalDirection
8 |
9 | case class TLInwardCrossingHelper(name: String, scope: LazyScope, node: TLInwardNode) {
10 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): TLInwardNode = {
11 | xing match {
12 | case x: AsynchronousCrossing =>
13 | node :*=* scope { TLAsyncCrossingSink(x.asSinkParams) :*=* TLAsyncNameNode(name) } :*=* TLAsyncNameNode(name) :*=* TLAsyncCrossingSource(x.sourceSync)
14 | case RationalCrossing(direction) =>
15 | node :*=* scope { TLRationalCrossingSink(direction.flip) :*=* TLRationalNameNode(name) } :*=* TLRationalNameNode(name) :*=* TLRationalCrossingSource()
16 | case SynchronousCrossing(buffer) =>
17 | node :*=* scope { TLBuffer(buffer) :*=* TLNameNode(name) } :*=* TLNameNode(name)
18 | }
19 | }
20 | }
21 |
22 | case class TLOutwardCrossingHelper(name: String, scope: LazyScope, node: TLOutwardNode) {
23 | def apply(xing: ClockCrossingType = NoCrossing)(implicit p: Parameters): TLOutwardNode = {
24 | xing match {
25 | case x: AsynchronousCrossing =>
26 | TLAsyncCrossingSink(x.asSinkParams) :*=* TLAsyncNameNode(name) :*=* scope { TLAsyncNameNode(name) :*=* TLAsyncCrossingSource(x.sourceSync) } :*=* node
27 | case RationalCrossing(direction) =>
28 | TLRationalCrossingSink(direction) :*=* TLRationalNameNode(name) :*=* scope { TLRationalNameNode(name) :*=* TLRationalCrossingSource() } :*=* node
29 | case SynchronousCrossing(buffer) =>
30 | TLNameNode(name) :*=* scope { TLNameNode(name) :*=* TLBuffer(buffer) } :*=* node
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/scala/tilelink/Dumper.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tilelink
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 |
9 | class TLDumper()(implicit p: Parameters) extends LazyModule
10 | {
11 | val node = TLAdapterNode()
12 |
13 | lazy val module = new LazyModuleImp(this) {
14 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
15 | out <> in
16 | }
17 | }
18 | }
19 |
20 | object TLDumper
21 | {
22 | def apply()(implicit p: Parameters): TLNode =
23 | {
24 | val tldump = LazyModule(new TLDumper())
25 | tldump.node
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/main/scala/tilelink/Example.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tilelink
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.regmapper._
8 |
9 | case class ExampleParams(num: Int, address: BigInt)
10 |
11 | trait ExampleBundle
12 | {
13 | val params: ExampleParams
14 | val gpio = UInt(width = params.num)
15 | }
16 |
17 | trait ExampleModule extends HasRegMap
18 | {
19 | val params: ExampleParams
20 | val io: ExampleBundle
21 | val interrupts: Vec[Bool]
22 |
23 | val state = RegInit(UInt(0, width = params.num))
24 | val pending = RegInit(UInt(0xf, width = 4))
25 |
26 | io.gpio := state
27 | interrupts := pending.asBools
28 |
29 | regmap(
30 | 0 -> Seq(
31 | RegField(params.num, state,
32 | RegFieldDesc("state", "State: Example of a R/W Register with description.", reset = Some(0)))),
33 | 4 -> Seq(
34 | RegField.w1ToClear(4, pending, state,
35 | Some(RegFieldDesc("pending", "Pending: Example of a special (W1ToC) Register. " +
36 | "Writing a bit here causes it to be reset to 0. " +
37 | "The bits are set when the corresponding bit in 'state' is high.",
38 | reset=Some(0xF), volatile=true))))
39 | )
40 | }
41 |
42 | // Create a concrete TL2 version of the abstract Example slave
43 | class TLExample(params: ExampleParams)(implicit p: Parameters)
44 | extends TLRegisterRouter(params.address, "somedev", Seq("ucbbar,random-interface"), 4)(
45 | new TLRegBundle(params, _) with ExampleBundle)(
46 | new TLRegModule(params, _, _) with ExampleModule)
47 |
--------------------------------------------------------------------------------
/src/main/scala/tilelink/Map.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tilelink
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 | import freechips.rocketchip.diplomacy._
8 | import scala.math.{min,max}
9 |
10 | // Moves the AddressSets of slave devices around
11 | // Combine with TLFilter to remove slaves or reduce their size
12 | class TLMap(fn: AddressSet => BigInt)(implicit p: Parameters) extends LazyModule
13 | {
14 | val node = TLAdapterNode(
15 | clientFn = { cp => cp },
16 | managerFn = { mp =>
17 | mp.copy(managers = mp.managers.map(m =>
18 | m.copy(address = m.address.map(a =>
19 | AddressSet(fn(a), a.mask)))))})
20 |
21 | lazy val module = new LazyModuleImp(this) {
22 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
23 | out <> in
24 | val convert = edgeIn.manager.managers.flatMap(_.address) zip edgeOut.manager.managers.flatMap(_.address)
25 | def forward(x: UInt) =
26 | convert.map { case (i, o) => Mux(i.contains(x), UInt(o.base) | (x & UInt(o.mask)), UInt(0)) }.reduce(_ | _)
27 | def backward(x: UInt) =
28 | convert.map { case (i, o) => Mux(o.contains(x), UInt(i.base) | (x & UInt(i.mask)), UInt(0)) }.reduce(_ | _)
29 |
30 | out.a.bits.address := forward(in.a.bits.address)
31 | if (edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe) {
32 | out.c.bits.address := forward(in.c.bits.address)
33 | in.b.bits.address := backward(out.b.bits.address)
34 | }
35 | }
36 | }
37 | }
38 |
39 | object TLMap
40 | {
41 | def apply(fn: AddressSet => BigInt)(implicit p: Parameters): TLNode =
42 | {
43 | val map = LazyModule(new TLMap(fn))
44 | map.node
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/scala/tilelink/RegionReplication.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tilelink
4 |
5 | import chisel3._
6 | import freechips.rocketchip.config._
7 | import freechips.rocketchip.diplomacy._
8 |
9 | case object MultiChipMaskKey extends Field[BigInt](0)
10 |
11 | trait HasRegionReplicatorParams {
12 | val replicatorMask: BigInt
13 | }
14 |
15 | // Replicate all devices below this adapter to multiple addreses.
16 | // If a device was at 0x4000-0x4fff and mask=0x10000, it will now be at 0x04000-0x04fff and 0x14000-0x14fff.
17 | class RegionReplicator(mask: BigInt = 0)(implicit p: Parameters) extends LazyModule {
18 | def ids = AddressSet.enumerateMask(mask)
19 |
20 | val node = TLAdapterNode(
21 | clientFn = { cp => cp },
22 | managerFn = { mp => mp.copy(managers = mp.managers.map { m => m.copy(
23 | address = m.address.flatMap { a => ids.map { id =>
24 | AddressSet(a.base | id, a.mask) } })})})
25 |
26 | lazy val module = new LazyModuleImp(this) {
27 | (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
28 | out <> in
29 | out.a.bits.address := ~(~in.a.bits.address | mask.U)
30 |
31 | // We can't support probes; we don't have the required information
32 | edgeOut.manager.managers.foreach { m =>
33 | require (m.regionType < RegionType.TRACKED, s"${m.name} has regionType ${m.regionType}, which requires Probe support a RegionReplicator cannot provide")
34 | }
35 | }
36 | }
37 | }
38 |
39 | object RegionReplicator {
40 | def apply(mask: BigInt = 0)(implicit p: Parameters): TLNode = {
41 | val replicator = LazyModule(new RegionReplicator(mask))
42 | replicator.node
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/scala/tilelink/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip
4 |
5 | import Chisel._
6 | import freechips.rocketchip.diplomacy._
7 |
8 | package object tilelink
9 | {
10 | type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle]
11 | type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle]
12 | type TLNode = NodeHandle[TLClientPortParameters, TLManagerPortParameters, TLEdgeIn, TLBundle, TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLBundle]
13 |
14 | implicit class TLClockDomainCrossing(val x: HasClockDomainCrossing) extends AnyVal {
15 | def crossIn (n: TLInwardNode) (implicit valName: ValName) = TLInwardCrossingHelper (valName.name, x, n)
16 | def crossOut(n: TLOutwardNode)(implicit valName: ValName) = TLOutwardCrossingHelper(valName.name, x, n)
17 | def cross(n: TLInwardNode) (implicit valName: ValName) = crossIn(n)
18 | def cross(n: TLOutwardNode)(implicit valName: ValName) = crossOut(n)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/scala/unittest/Generator.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.unittest
4 |
5 | object Generator extends freechips.rocketchip.util.GeneratorApp {
6 | val longName = names.topModuleProject + "." + names.configs
7 | generateFirrtl
8 | generateAnno
9 | generateTestSuiteMakefrags // TODO: Needed only for legacy make targets
10 | generateArtefacts
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/scala/unittest/TestGenerator.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.unittest
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config._
7 | import freechips.rocketchip.diplomacy._
8 |
9 | abstract class LazyUnitTest(implicit p: Parameters) extends LazyModule
10 | { self =>
11 | protected def finished: Bool
12 |
13 | lazy val module = new LazyModuleImp(this) {
14 | val finished = IO(Bool(OUTPUT))
15 | finished := self.finished
16 | }
17 | }
18 |
19 | // FYI, you can call .finished on a Seq[LazyUnitTest]
20 | class TestGenerator(gen: LazyModule => Seq[LazyUnitTest])
21 | {
22 | def apply(lm: LazyModule) = gen(lm)
23 | def ++ (other: TestGenerator) = new TestGenerator(gen = lm => gen(lm) ++ other(lm))
24 | }
25 |
26 | object TestGenerator
27 | {
28 | def apply(matcher: PartialFunction[LazyModule, Seq[LazyUnitTest]]): TestGenerator =
29 | new TestGenerator(gen = matcher.lift(_).getOrElse(Nil))
30 | def recurse(other: TestGenerator): TestGenerator = {
31 | def helper(lm: LazyModule, tail: Seq[LazyUnitTest]): Seq[LazyUnitTest] =
32 | lm.getChildren.foldLeft(other(lm) ++ tail) { case (tail, child) => helper(child, tail) }
33 | new TestGenerator(gen = helper(_, Nil))
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/scala/unittest/TestHarness.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.unittest
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config.Parameters
7 |
8 | class TestHarness(implicit val p: Parameters) extends Module {
9 | val io = new Bundle { val success = Bool(OUTPUT) }
10 | io.success := Module(new UnitTestSuite).io.finished
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/scala/unittest/UnitTest.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.unittest
4 |
5 | import Chisel._
6 | import chisel3.experimental.MultiIOModule
7 | import freechips.rocketchip.config._
8 | import freechips.rocketchip.util._
9 |
10 | trait UnitTestIO {
11 | val finished = Bool(OUTPUT)
12 | val start = Bool(INPUT)
13 | }
14 |
15 | trait HasUnitTestIO {
16 | val io: UnitTestIO
17 | }
18 |
19 | trait UnitTestLegacyModule extends HasUnitTestIO {
20 | val io = new Bundle with UnitTestIO
21 | }
22 |
23 | trait UnitTestModule extends MultiIOModule with HasUnitTestIO {
24 | val io = IO(new Bundle with UnitTestIO)
25 | ElaborationArtefacts.add("plusArgs", PlusArgArtefacts.serialize_cHeader)
26 | }
27 |
28 | abstract class UnitTest(val timeout: Int = 4096) extends Module with UnitTestLegacyModule {
29 | val testName = this.getClass.getSimpleName
30 |
31 | when (io.start) { printf(s"Started UnitTest $testName\n") }
32 |
33 | val timed_out = SimpleTimer(timeout, io.start, io.finished)
34 | assert(!timed_out, s"UnitTest $testName timed out")
35 | }
36 |
37 | case object UnitTests extends Field[Parameters => Seq[UnitTest]]
38 |
39 | class UnitTestSuite(implicit p: Parameters) extends Module {
40 | val io = new Bundle {
41 | val finished = Bool(OUTPUT)
42 | }
43 |
44 | val tests = p(UnitTests)(p)
45 |
46 | val s_idle :: s_start :: s_busy :: s_done :: Nil = Enum(Bits(), 4)
47 | val state = Reg(init = s_idle)
48 | val tests_finished = Vec(tests.map(_.io.finished)).reduce(_&&_)
49 |
50 | tests.foreach { _.io.start := (state === s_start) }
51 | io.finished := (state === s_done)
52 |
53 | when (state === s_idle) { state := s_start }
54 | when (state === s_start) { state := s_busy }
55 | when (state === s_busy && tests_finished) { state := s_done }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/scala/unittest/package.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip
4 |
5 | import Chisel._
6 |
7 | package object unittest
8 | {
9 | implicit class LazyUnitTestSeq(val seq: Seq[LazyUnitTest]) {
10 | def finished = seq.map(_.module.finished).foldLeft(Bool(true))(_ && _)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/scala/util/Broadcaster.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 | // See LICENSE.Berkeley for license details.
3 |
4 | package freechips.rocketchip.util
5 |
6 | import Chisel._
7 |
8 | /** Takes in data on one decoupled interface and broadcasts it
9 | * to N decoupled output interfaces.
10 | */
11 | class Broadcaster[T <: Data](typ: T, n: Int) extends Module {
12 | val io = new Bundle {
13 | val in = Decoupled(typ).flip
14 | val out = Vec(n, Decoupled(typ))
15 | }
16 |
17 | require (n > 0)
18 |
19 | if (n == 1) {
20 | io.out.head <> io.in
21 | } else {
22 | val idx = Reg(init = UInt(0, log2Up(n)))
23 | val save = Reg(typ)
24 |
25 | io.out.head.valid := idx === UInt(0) && io.in.valid
26 | io.out.head.bits := io.in.bits
27 | for (i <- 1 until n) {
28 | io.out(i).valid := idx === UInt(i)
29 | io.out(i).bits := save
30 | }
31 | io.in.ready := io.out.head.ready && idx === UInt(0)
32 |
33 | when (io.in.fire()) { save := io.in.bits }
34 |
35 | when (io.out(idx).fire()) {
36 | when (idx === UInt(n - 1)) { idx := UInt(0) }
37 | .otherwise { idx := idx + UInt(1) }
38 | }
39 | }
40 | }
41 |
42 | object Broadcaster {
43 | def apply[T <: Data](in: DecoupledIO[T], n: Int): Vec[DecoupledIO[T]] = {
44 | val split = Module(new Broadcaster(in.bits, n))
45 | split.io.in <> in
46 | split.io.out
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/scala/util/CRC.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 |
7 | object CRC
8 | {
9 | // A divisor of 0x1d5 is interpretted to be x^8 + x^7 + x^6 + x^4 + x^2 + 1
10 | // Let n be the highest term in the divisor; n=8 in 0x1d5.
11 | // Then, this function calculates c mod d, returning an n-bit UInt.
12 | // coefficient.width must be <= width
13 | def apply(divisor: BigInt, coefficient: UInt, width: Integer): UInt = {
14 | require (divisor > 0 && divisor.testBit(0))
15 | require (width > 0)
16 | assert (coefficient >> width === UInt(0))
17 | val n = log2Floor(divisor)
18 | val m = width
19 | if (m <= n) return coefficient
20 |
21 | // Initialize the reduction matrix
22 | val array = Array.tabulate(m) { BigInt(1) << _ }
23 | // Reduce the matrix of terms larger than n
24 | for {
25 | i <- (n until m).reverse
26 | j <- 0 to n
27 | if divisor.testBit(j)
28 | } array(i-(n-j)) ^= array(i)
29 | // Construct the circuit
30 | Cat(Seq.tabulate(n) { i => (UInt(array(i)) & coefficient).xorR } .reverse)
31 | }
32 |
33 | // Find more great CRC polynomials here: https://users.ece.cmu.edu/~koopman/crc/
34 | val CRC_16F_4_2 = BigInt(0x1a2eb) // HD=4 for <32751 bits and HD=6 for <93 bits
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/scala/util/CheckOneHot.scala:
--------------------------------------------------------------------------------
1 | package freechips.rocketchip.util
2 |
3 | import Chisel._
4 |
5 | object CheckOneHot {
6 | def apply(in: Seq[Bool]): Unit = {
7 | val value = Vec(in).asUInt
8 | val length = in.length
9 | def bitMap[T <: Data](f: Int => T) = Vec((0 until length).map(f))
10 | val bitOneHot = bitMap((w: Int) => value === (1 << w).asUInt(length.W)).asUInt
11 | val oneHot = bitOneHot.orR
12 | val noneHot = value === 0.U
13 | assert(oneHot || noneHot)
14 | }
15 | }
16 |
17 | // a and b must be both hot or none hot
18 | object bothHotOrNoneHot {
19 | def apply(a: Bool, b: Bool, str: String): Unit = {
20 | val cond = (a === b)
21 | assert(cond, str)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/scala/util/ClockDivider.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import chisel3.util.HasBlackBoxResource
7 | import chisel3.experimental.withClock
8 |
9 | /** This black-boxes a Clock Divider by 2.
10 | * The output clock is phase-aligned to the input clock.
11 | * If you use this in synthesis, make sure your sdc
12 | * declares that you want it to do the same.
13 | *
14 | * Because Chisel does not support
15 | * blocking assignments, it is impossible
16 | * to create a deterministic divided clock.
17 | */
18 | class ClockDivider2 extends BlackBox with HasBlackBoxResource {
19 | val io = new Bundle {
20 | val clk_out = Clock(OUTPUT)
21 | val clk_in = Clock(INPUT)
22 | }
23 |
24 | setResource("/vsrc/ClockDivider2.v")
25 | }
26 | class ClockDivider3 extends BlackBox with HasBlackBoxResource {
27 | val io = new Bundle {
28 | val clk_out = Clock(OUTPUT)
29 | val clk_in = Clock(INPUT)
30 | }
31 |
32 | setResource("/vsrc/ClockDivider3.v")
33 | }
34 |
35 | /** Divide the clock by power of 2 times.
36 | * @param pow2 divides the clock 2 ^ pow2 times */
37 | class Pow2ClockDivider(pow2: Int) extends Module {
38 | val io = new Bundle {
39 | val clock_out = Clock(OUTPUT)
40 | }
41 |
42 | if (pow2 == 0) {
43 | io.clock_out := clock
44 | } else {
45 | val dividers = Seq.fill(pow2) { Module(new ClockDivider2) }
46 |
47 | dividers.init.zip(dividers.tail).map { case (last, next) =>
48 | next.io.clk_in := last.io.clk_out
49 | }
50 |
51 | dividers.head.io.clk_in := clock
52 | io.clock_out := dividers.last.io.clk_out
53 | }
54 | }
55 |
56 | object Pow2ClockDivider {
57 | def apply(pow2: Int): Clock = Module(new Pow2ClockDivider(pow2)).io.clock_out
58 | def apply(clock_in: Clock, pow2: Int): Clock = withClock(clock_in) { apply(pow2) }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/scala/util/ClockGate.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import chisel3._
6 | import freechips.rocketchip.config.{Field, Parameters}
7 |
8 | case object ClockGateImpl extends Field[() => ClockGate](() => new EICG_wrapper)
9 |
10 | abstract class ClockGate extends BlackBox {
11 | val io = IO(new Bundle{
12 | val in = Input(Clock())
13 | val en = Input(Bool())
14 | val out = Output(Clock())
15 | })
16 | }
17 |
18 | object ClockGate {
19 | def apply[T <: ClockGate](
20 | in: Clock,
21 | en: Bool,
22 | name: Option[String] = None)(implicit p: Parameters): Clock = {
23 | val cg = Module(p(ClockGateImpl)())
24 | name.foreach(cg.suggestName(_))
25 | cg.io.in := in
26 | cg.io.en := en
27 | cg.io.out
28 | }
29 |
30 | def apply[T <: ClockGate](
31 | in: Clock,
32 | en: Bool,
33 | name: String)(implicit p: Parameters): Clock =
34 | apply(in, en, Some(name))
35 | }
36 |
37 | // behavioral model of Integrated Clock Gating cell
38 | class EICG_wrapper extends ClockGate
39 |
--------------------------------------------------------------------------------
/src/main/scala/util/CoreMonitor.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 | // See LICENSE.SiFive for license details.
3 |
4 | package freechips.rocketchip.util
5 |
6 | import chisel3._
7 |
8 | // this bundle is used to expose some internal core signals
9 | // to verification monitors which sample instruction commits
10 | class CoreMonitorBundle(val xLen: Int) extends Bundle with Clocked {
11 | val hartid = UInt(width = xLen.W)
12 | val timer = UInt(width = 32.W)
13 | val valid = Bool()
14 | val pc = UInt(width = xLen.W)
15 | val wrdst = UInt(width = 5.W)
16 | val wrdata = UInt(width = xLen.W)
17 | val wren = Bool()
18 | val rd0src = UInt(width = 5.W)
19 | val rd0val = UInt(width = xLen.W)
20 | val rd1src = UInt(width = 5.W)
21 | val rd1val = UInt(width = xLen.W)
22 | val inst = UInt(width = 32.W)
23 | }
24 |
25 | // mark a module that has cores with CoreMonitorBundles
26 | trait HasCoreMonitorBundles {
27 | def coreMonitorBundles: List[CoreMonitorBundle]
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/scala/util/Crossing.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import chisel3.util.{DecoupledIO, Decoupled, Irrevocable, IrrevocableIO, ReadyValidIO}
7 |
8 | class CrossingIO[T <: Data](gen: T) extends Bundle {
9 | // Enqueue clock domain
10 | val enq_clock = Clock(INPUT)
11 | val enq_reset = Bool(INPUT) // synchronously deasserted wrt. enq_clock
12 | val enq = Decoupled(gen).flip
13 | // Dequeue clock domain
14 | val deq_clock = Clock(INPUT)
15 | val deq_reset = Bool(INPUT) // synchronously deasserted wrt. deq_clock
16 | val deq = Decoupled(gen)
17 | }
18 |
19 | abstract class Crossing[T <: Data] extends Module {
20 | val io: CrossingIO[T]
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/scala/util/DescribedSRAM.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 | // See LICENSE.SiFive for license details.
3 |
4 | package freechips.rocketchip.util
5 |
6 | import chisel3.internal.InstanceId
7 | import freechips.rocketchip.util.Annotated
8 | import freechips.rocketchip.diplomacy.DiplomaticSRAM
9 | import Chisel._
10 | import chisel3.SyncReadMem
11 | import freechips.rocketchip.amba.axi4.AXI4RAM
12 |
13 | import scala.math.log10
14 |
15 | object DescribedSRAM {
16 | def apply[T <: Data](
17 | name: String,
18 | desc: String,
19 | size: Int, // depth
20 | data: T
21 | ): SyncReadMem[T] = {
22 |
23 | val mem = SeqMem(size, data)
24 |
25 | mem.suggestName(name)
26 |
27 | val granWidth = data match {
28 | case v: Vec[_] => v.head.getWidth
29 | case d => d.getWidth
30 | }
31 |
32 | Annotated.srams(
33 | component = mem,
34 | name = name,
35 | address_width = log2Ceil(size),
36 | data_width = data.getWidth,
37 | depth = size,
38 | description = desc,
39 | write_mask_granularity = granWidth)
40 |
41 | mem
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/scala/util/Frequency.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 | // See LICENSE.Berkeley for license details.
3 |
4 | package freechips.rocketchip.util
5 |
6 | import Chisel._
7 |
8 | /** Given a list of (frequency, value) pairs, return a random value
9 | * according to the frequency distribution. The sum of the
10 | * frequencies in the distribution must be a power of two.
11 | */
12 | object Frequency {
13 | def apply(dist : List[(Int, Bits)]) : Bits = {
14 | // Distribution must be non-empty
15 | require(dist.length > 0)
16 |
17 | // Require that the frequencies sum to a power of two
18 | val (freqs, vals) = dist.unzip
19 | val total = freqs.sum
20 | require(isPow2(total))
21 |
22 | // First item in the distribution
23 | val (firstFreq, firstVal) = dist.head
24 |
25 | // Result wire
26 | val result = Wire(Bits(width = firstVal.getWidth))
27 | result := UInt(0)
28 |
29 | // Random value
30 | val randVal = LCG(log2Up(total))
31 |
32 | // Pick return value
33 | var count = firstFreq
34 | var select = when (randVal < UInt(firstFreq)) { result := firstVal }
35 | for (p <- dist.drop(1)) {
36 | count = count + p._1
37 | select = select.elsewhen(randVal < UInt(count)) { result := p._2 }
38 | }
39 |
40 | return result
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/src/main/scala/util/GenericParameterizedBundle.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 |
7 | abstract class GenericParameterizedBundle[+T <: Object](val params: T) extends Bundle
8 | {
9 | override def cloneType = {
10 | try {
11 | this.getClass.getConstructors.head.newInstance(params).asInstanceOf[this.type]
12 | } catch {
13 | case e: java.lang.IllegalArgumentException =>
14 | throw new Exception("Unable to use GenericParameterizedBundle.cloneType on " +
15 | this.getClass + ", probably because " + this.getClass +
16 | "() takes more than one argument. Consider overriding " +
17 | "cloneType() on " + this.getClass, e)
18 | }
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/main/scala/util/GlobalTimer.scala:
--------------------------------------------------------------------------------
1 | package freechips.rocketchip.util
2 |
3 | import Chisel._
4 |
5 | object GTimer {
6 | def apply(): UInt = {
7 | val (t, c) = Counter(Bool(true), 0x7fffffff)
8 | t
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/scala/util/HeterogeneousBag.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import chisel3.core.Record
7 | import scala.collection.immutable.ListMap
8 |
9 | final case class HeterogeneousBag[T <: Data](elts: Seq[T]) extends Record with collection.IndexedSeq[T] {
10 | def apply(x: Int) = elts(x)
11 | def length = elts.length
12 |
13 | val elements = ListMap(elts.zipWithIndex.map { case (n,i) => (i.toString, n) }:_*)
14 | override def cloneType: this.type = (new HeterogeneousBag(elts.map(_.chiselCloneType))).asInstanceOf[this.type]
15 |
16 | // IndexedSeq has its own hashCode/equals that we must not use
17 | override def hashCode: Int = super[Record].hashCode
18 | override def equals(that: Any): Boolean = super[Record].equals(that)
19 | }
20 |
21 | object HeterogeneousBag
22 | {
23 | def fromNode[D <: Data, E](elts: Seq[(D, E)]) = new HeterogeneousBag(elts.map(_._1.cloneType))
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/scala/util/IDPool.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import chisel3._
6 | import chisel3.util._
7 |
8 | class IDPool(numIds: Int) extends Module {
9 | require (numIds > 0)
10 | val idWidth = log2Up(numIds)
11 |
12 | val io = IO(new Bundle {
13 | val free = Flipped(Valid(UInt(idWidth.W)))
14 | val alloc = Irrevocable(UInt(idWidth.W))
15 | })
16 |
17 | // True indicates that the id is available
18 | val bitmap = RegInit(~0.U(numIds.W))
19 | val select = RegInit(0.U(idWidth.W))
20 | val valid = RegInit(true.B)
21 |
22 | io.alloc.valid := valid
23 | io.alloc.bits := select
24 |
25 | val taken = (io.alloc.ready << io.alloc.bits)(numIds-1, 0)
26 | val given = (io.free .valid << io.free .bits)(numIds-1, 0)
27 | val bitmap1 = (bitmap & ~taken) | given
28 | val select1 = OHToUInt(~(leftOR(bitmap1, numIds) << 1) & bitmap1, numIds)
29 | val valid1 = bitmap1.orR
30 |
31 | // Clock gate the bitmap
32 | when (io.alloc.ready || io.free.valid) {
33 | bitmap := bitmap1
34 | valid := valid1
35 | }
36 |
37 | // Make select irrevocable
38 | when (io.alloc.ready || (!io.alloc.valid && io.free.valid)) {
39 | select := select1
40 | }
41 |
42 | // No double freeing
43 | assert (!io.free.valid || !(bitmap & ~taken)(io.free.bits))
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/scala/util/IdentityModule.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.tilelink
4 |
5 | import Chisel._
6 |
7 | class IdentityModule[T <: Data](gen: T) extends Module
8 | {
9 | val io = new Bundle {
10 | val in = gen.cloneType.flip
11 | val out = gen.cloneType
12 | }
13 |
14 | io.out := io.in
15 | }
16 |
17 | object IdentityModule
18 | {
19 | def apply[T <: Data](x: T): T = {
20 | val identity = Module(new IdentityModule(x))
21 | identity.io.in := x
22 | identity.io.out
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/scala/util/LCG.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 | // See LICENSE.Berkeley for license details.
3 |
4 | package freechips.rocketchip.util
5 |
6 | import Chisel._
7 |
8 | /** A 16-bit psuedo-random generator based on a linear conguential
9 | * generator (LCG). The state is stored in an unitialised register.
10 | * When using the C++ backend, it is straigtforward to arrange a
11 | * random initial value for each uninitialised register, effectively
12 | * seeding each LCG16 instance with a different seed.
13 | */
14 | class LCG16 extends Module {
15 | val io = new Bundle {
16 | val out = UInt(OUTPUT, 16)
17 | val inc = Bool(INPUT)
18 | }
19 | val state = Reg(UInt(width = 32))
20 | when (io.inc) {
21 | state := state * UInt(1103515245, 32) + UInt(12345, 32)
22 | }
23 | io.out := state(30, 15)
24 | }
25 |
26 | /** An n-bit psuedo-random generator made from many instances of a
27 | * 16-bit LCG. Parameter 'width' must be larger than 0.
28 | */
29 | class LCG(val w: Int) extends Module {
30 | val io = new Bundle {
31 | val out = UInt(OUTPUT, w)
32 | val inc = Bool(INPUT)
33 | }
34 | require(w > 0)
35 | val numLCG16s : Int = (w+15)/16
36 | val outs = Seq.fill(numLCG16s) { LCG16(io.inc) }
37 | io.out := Cat(outs)
38 | }
39 |
40 | object LCG16 {
41 | def apply(inc: Bool = Bool(true)): UInt = {
42 | val lcg = Module(new LCG16)
43 | lcg.io.inc := inc
44 | lcg.io.out
45 | }
46 | }
47 |
48 | object LCG {
49 | def apply(w: Int, inc: Bool = Bool(true)): UInt = {
50 | val lcg = Module(new LCG(w))
51 | lcg.io.inc := inc
52 | lcg.io.out
53 | }
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/src/main/scala/util/LatencyPipe.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.Berkeley for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import chisel3.util.{Irrevocable, IrrevocableIO}
7 |
8 | class LatencyPipe[T <: Data](typ: T, latency: Int) extends Module {
9 | val io = new Bundle {
10 | val in = Decoupled(typ).flip
11 | val out = Decoupled(typ)
12 | }
13 |
14 | def doN[T](n: Int, func: T => T, in: T): T =
15 | (0 until n).foldLeft(in)((last, _) => func(last))
16 |
17 | io.out <> doN(latency, (last: DecoupledIO[T]) => Queue(last, 1, pipe=true), io.in)
18 | }
19 |
20 | object LatencyPipe {
21 | def apply[T <: Data](in: DecoupledIO[T], latency: Int): DecoupledIO[T] = {
22 | val pipe = Module(new LatencyPipe(in.bits, latency))
23 | pipe.io.in <> in
24 | pipe.io.out
25 | }
26 | }
27 |
28 | class LatencyPipeIrrevocable[T <: Data](typ: T, latency: Int) extends Module {
29 | val io = new Bundle {
30 | val in = Irrevocable(typ).flip
31 | val out = Irrevocable(typ)
32 | }
33 |
34 | def doN[T](n: Int, func: T => T, in: T): T =
35 | (0 until n).foldLeft(in)((last, _) => func(last))
36 |
37 | io.out <> doN(latency, (last: IrrevocableIO[T]) => Queue.irrevocable(last, 1, pipe=true), io.in)
38 | }
39 |
40 | object LatencyPipeIrrevocable {
41 | def apply[T <: Data](in: IrrevocableIO[T], latency: Int): IrrevocableIO[T] = {
42 | val pipe = Module(new LatencyPipeIrrevocable(in.bits, latency))
43 | pipe.io.in <> in
44 | pipe.io.out
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/scala/util/PSDTestMode.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import freechips.rocketchip.config._
7 | import freechips.rocketchip.diplomacy.BundleBridgeNexus
8 |
9 | case object IncludePSDTest extends Field[Boolean](false)
10 | //Note: one should never have `IncludePSDTest without
11 | // PSDTestModeBroadcastKey defined everywhere one wants to use it.
12 | // One could just use the PSDTestModeBroadcastKey.isDefined directly,
13 | // but it's a more error prone process to instantiate it and pass it in an
14 | // altered Parameters so the API is to have both.
15 | case object PSDTestModeBroadcastKey extends Field[Option[BundleBridgeNexus[PSDTestMode]]](None)
16 |
17 | class PSDTestMode extends Bundle {
18 | val test_mode = Bool()
19 | val test_mode_reset = Bool()
20 | // TODO: Clocks?
21 | }
22 |
23 | trait CanHavePSDTestModeIO {
24 | implicit val p: Parameters
25 | val psd = p(IncludePSDTest).option(new PSDTestMode().asInput)
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/scala/util/ROMGenerator.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import scala.collection.mutable.{HashMap}
7 |
8 | case class ROMConfig(name: String, depth: Int, width: Int)
9 |
10 | class BlackBoxedROM(c: ROMConfig) extends BlackBox {
11 | val io = new Bundle {
12 | val clock = Clock(INPUT)
13 | val address = UInt(INPUT, log2Ceil(c.depth))
14 | val oe = Bool(INPUT)
15 | val me = Bool(INPUT)
16 | val q = UInt(OUTPUT, c.width)
17 | }
18 |
19 | override def desiredName: String = c.name
20 | }
21 |
22 | object ROMGenerator {
23 | private var finalized = false
24 | private val roms = HashMap[BlackBoxedROM, ROMConfig]()
25 | def apply(c: ROMConfig): BlackBoxedROM = {
26 | require(!finalized)
27 | val m = Module(new BlackBoxedROM(c))
28 | roms(m) = c
29 | m
30 | }
31 | def lookup(m: BlackBoxedROM): ROMConfig = {
32 | finalized = true
33 | roms(m)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/scala/util/ReduceOthers.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 |
7 | object ReduceOthers {
8 | // Given a list of bools, create this output:
9 | // out[i] = AND[j=0..out.size, j!=i] in[j]
10 | def apply(x: Seq[Bool]): Seq[Bool] = {
11 | val (literals, variables) = x.partition(_.isLit)
12 |
13 | val falses = literals.count(_.litValue == 0)
14 | if (falses > 2) {
15 | Seq.fill(x.size) { Bool(false) }
16 | } else if (falses == 1) {
17 | x.map { b =>
18 | if (b.isLit && b.litValue == 0) {
19 | variables.foldLeft(Bool(true))(_ && _)
20 | } else {
21 | Bool(false)
22 | }
23 | }
24 | } else {
25 | var (out, all) = helper(variables)
26 | x.map { b =>
27 | if (b.isLit) {
28 | all
29 | } else {
30 | val sel = out.head
31 | out = out.tail
32 | sel
33 | }
34 | }
35 | }
36 | }
37 | // Take pairs of (output_wire, input_bool)
38 | def apply(x: Seq[(Bool, Bool)]) {
39 | (x.map(_._1) zip apply(x.map(_._2))) foreach { case (w, x) => w := x }
40 | }
41 | private def helper(x: Seq[Bool]): (Seq[Bool], Bool) = {
42 | if (x.size <= 1) {
43 | (Seq.fill(x.size) { Bool(true) }, x.headOption.getOrElse(Bool(true)))
44 | } else if (x.size <= 3) {
45 | (Seq.tabulate(x.size) { i =>
46 | (x.take(i) ++ x.drop(i+1)).reduce(_ && _)
47 | }, x.reduce(_ && _))
48 | } else {
49 | val (half, all) = helper(x.grouped(2).map(_.reduce(_ && _)).toList)
50 | (Seq.tabulate(x.size) { i =>
51 | if ((i ^ 1) >= x.size) half(i/2) else x(i ^ 1) && half(i / 2)
52 | }, all)
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/scala/util/Repeater.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 |
7 | // A Repeater passes it's input to it's output, unless repeat is asserted.
8 | // When repeat is asserted, the Repeater copies the input and repeats it next cycle.
9 | class Repeater[T <: Data](gen: T) extends Module
10 | {
11 | val io = new Bundle {
12 | val repeat = Bool(INPUT)
13 | val full = Bool(OUTPUT)
14 | val enq = Decoupled(gen).flip
15 | val deq = Decoupled(gen)
16 | }
17 |
18 | val full = RegInit(Bool(false))
19 | val saved = Reg(gen)
20 |
21 | // When !full, a repeater is pass-through
22 | io.deq.valid := io.enq.valid || full
23 | io.enq.ready := io.deq.ready && !full
24 | io.deq.bits := Mux(full, saved, io.enq.bits)
25 | io.full := full
26 |
27 | when (io.enq.fire() && io.repeat) { full := Bool(true); saved := io.enq.bits }
28 | when (io.deq.fire() && !io.repeat) { full := Bool(false) }
29 | }
30 |
31 | object Repeater
32 | {
33 | def apply[T <: Data](enq: DecoupledIO[T], repeat: Bool): DecoupledIO[T] = {
34 | val repeater = Module(new Repeater(enq.bits))
35 | repeater.io.repeat := repeat
36 | repeater.io.enq := enq
37 | repeater.io.deq
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/scala/util/ResetCatchAndSync.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | import Chisel._
6 | import chisel3.experimental.{withClockAndReset, withReset}
7 |
8 | /** Reset: asynchronous assert,
9 | * synchronous de-assert
10 | *
11 | */
12 |
13 | class ResetCatchAndSync (sync: Int = 3) extends Module {
14 |
15 | override def desiredName = s"ResetCatchAndSync_d${sync}"
16 |
17 | val io = new Bundle {
18 | val sync_reset = Bool(OUTPUT)
19 | val psd = new PSDTestMode().asInput
20 | }
21 |
22 | // Bypass both the resets to the flops themselves (to prevent DFT holes on
23 | // those flops) and on the output of the synchronizer circuit (to control
24 | // reset to any flops this circuit drives).
25 |
26 | val post_psd_reset = Mux(io.psd.test_mode, io.psd.test_mode_reset, reset)
27 | withReset(post_psd_reset) {
28 | io.sync_reset := Mux(io.psd.test_mode, io.psd.test_mode_reset,
29 | ~AsyncResetSynchronizerShiftReg(Bool(true), sync))
30 | }
31 | }
32 |
33 | object ResetCatchAndSync {
34 |
35 | def apply(clk: Clock, rst: Bool, sync: Int = 3, name: Option[String] = None,
36 | psd: Option[PSDTestMode] = None): Bool = {
37 |
38 | withClockAndReset(clk, rst) {
39 | val catcher = Module (new ResetCatchAndSync(sync))
40 | if (name.isDefined) {catcher.suggestName(name.get)}
41 | catcher.io.psd <> psd.getOrElse(Wire(new PSDTestMode()).fromBits(UInt(0)))
42 | catcher.io.sync_reset
43 | }
44 | }
45 |
46 | def apply(clk: Clock, rst: Bool, sync: Int, name: String): Bool = apply(clk, rst, sync, Some(name))
47 | def apply(clk: Clock, rst: Bool, name: String): Bool = apply(clk, rst, name = Some(name))
48 |
49 | def apply(clk: Clock, rst: Bool, sync: Int, name: String, psd: PSDTestMode): Bool =
50 | apply(clk, rst, sync, Some(name), Some(psd))
51 | def apply(clk: Clock, rst: Bool, name: String, psd: PSDTestMode): Bool =
52 | apply(clk, rst, name = Some(name), psd = Some(psd))
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/scala/util/SeededRandom.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE.SiFive for license details.
2 |
3 | package freechips.rocketchip.util
4 |
5 | /** Using e.g. Random.nextInt makes your hardware generation non-repoducible,
6 | * which is almost certainly undesirable. Use LCG to increment random numbers in HW,
7 | * or use this SeededRandom.fromSeed to make reproducible Scala PRNGs.
8 | */
9 | object SeededRandom {
10 | val fromSeed = new scala.util.Random(42)
11 | }
12 |
--------------------------------------------------------------------------------
/vsim/.gitignore:
--------------------------------------------------------------------------------
1 | simv*
2 | csrc
3 | *.vpd
4 | *.key
5 | DVE*
6 | .vcs*
7 | timestamp
8 | *.out
9 | *.h
10 | *.log
11 | *.cmd
12 | *.daidir
13 | *.ucli
14 | *.a
15 | *.vcd
16 | generated-src
17 | output
18 |
--------------------------------------------------------------------------------
/vsim/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # Makefile for Verilog simulation w/ VCS
3 | #-----------------------------------------------------------------------
4 | # Yunsup Lee (yunsup@cs.berkeley.edu)
5 | #
6 | # This makefile will build a rtl simulator and run various tests to
7 | # verify proper functionality.
8 | #
9 |
10 | default: all
11 |
12 | base_dir = $(abspath ..)
13 | generated_dir = $(abspath ./generated-src)
14 | mem_gen = $(VLSI_MEM_GEN)
15 | sim_dir = .
16 | output_dir = $(sim_dir)/output
17 |
18 | BACKEND ?= v
19 | TB ?= TestDriver
20 |
21 | include $(base_dir)/Makefrag
22 | include $(sim_dir)/Makefrag
23 | ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),)
24 | -include $(generated_dir)/$(long_name).d
25 | endif
26 | include $(base_dir)/vsim/Makefrag-verilog
27 |
28 | all: $(simv)
29 | debug: $(simv_debug)
30 |
31 | clean:
32 | rm -rf $(junk) simv* csrc *.key DVE* *.h *.a *.daidir $(generated_dir)
33 |
34 | .PHONY: default all debug clean
35 |
--------------------------------------------------------------------------------