Skip to content

Commit

Permalink
top: implement XSNoCTop and standalone devices (OpenXiangShan#3136)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tang-Haojin authored Jul 4, 2024
1 parent 0938652 commit 720dd62
Show file tree
Hide file tree
Showing 18 changed files with 951 additions and 14 deletions.
22 changes: 21 additions & 1 deletion .github/workflows/emu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,32 @@ jobs:
- name: check top wiring
run:
bash .github/workflows/check-usage.sh "BoringUtils" $GITHUB_WORKSPACE
- name: generate standalone clint
run: |
make StandAloneCLINT DEVICE_BASE_ADDR=0x38000000 DEVICE_ADDR_WIDTH=32 DEVICE_DATA_WIDTH=64 DEVICE_TL=0
make clean
make StandAloneCLINT DEVICE_BASE_ADDR=0x38000000 DEVICE_ADDR_WIDTH=32 DEVICE_DATA_WIDTH=64 DEVICE_TL=1
make clean
- name: generate standalone debug module
run: |
make StandAloneDebugModule DEVICE_BASE_ADDR=0x38020000 DEVICE_ADDR_WIDTH=32 DEVICE_DATA_WIDTH=64 DEVICE_TL=0
make clean
make StandAloneDebugModule DEVICE_BASE_ADDR=0x38020000 DEVICE_ADDR_WIDTH=32 DEVICE_DATA_WIDTH=64 DEVICE_TL=1
make clean
- name: generate XSNoCTop verilog file
run: |
python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --generate --config XSNoCTopConfig --mfc
- name: check XSNoCTop verilog
run: |
python3 $GITHUB_WORKSPACE/.github/workflows/check_verilog.py build/rtl
python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --clean
- name: generate verilog file
run:
python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --generate --num-cores 2 --mfc
- name: check verilog
run:
run: |
python3 $GITHUB_WORKSPACE/.github/workflows/check_verilog.py build/rtl
python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --clean
- name: build MinimalConfig Release emu
run: |
python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --build \
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@
[submodule "openLLC"]
path = openLLC
url = https://github.com/OpenXiangShan/OpenLLC.git
[submodule "src/main/resources/aia"]
path = src/main/resources/aia
url = https://github.com/OpenXiangShan/OpenAIA.git
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ TEST_FILE = $(shell find ./src/test/scala -name '*.scala')
MEM_GEN = ./scripts/vlsi_mem_gen
MEM_GEN_SEP = ./scripts/gen_sep_mem.sh

IMAGE ?= temp
CONFIG ?= DefaultConfig
NUM_CORES ?= 1
MFC ?= 1

ifneq ($(shell echo "$(MAKECMDGOALS)" | grep ' '),)
$(error At most one target can be specified)
endif

ifeq ($(MAKECMDGOALS),)
GOALS = verilog
Expand Down Expand Up @@ -68,6 +70,12 @@ DEBUG_ARGS += --xstop-prefix $(XSTOP_PREFIX)
PLDM_ARGS += --xstop-prefix $(XSTOP_PREFIX)
endif

ifeq ($(IMSIC_USE_TL),1)
RELEASE_ARGS += --imsic-use-tl
DEBUG_ARGS += --imsic-use-tl
PLDM_ARGS += --imsic-use-tl
endif

# co-simulation with DRAMsim3
ifeq ($(WITH_DRAMSIM3),1)
ifndef DRAMSIM3_HOME
Expand Down Expand Up @@ -140,7 +148,7 @@ $(TOP_V): $(SCALA_FILE)
--target-dir $(@D) --config $(CONFIG) $(FPGA_MEM_ARGS) \
--num-cores $(NUM_CORES) $(RELEASE_ARGS)
ifeq ($(MFC),1)
$(MEM_GEN_SEP) "$(MEM_GEN)" "$(TOP_V).conf" "$(RTL_DIR)"
$(MEM_GEN_SEP) "$(MEM_GEN)" "$@.conf" "$(@D)"
endif
@git log -n 1 >> .__head__
@git diff >> .__diff__
Expand All @@ -160,7 +168,7 @@ $(SIM_TOP_V): $(SCALA_FILE) $(TEST_FILE)
--target-dir $(@D) --config $(CONFIG) $(SIM_MEM_ARGS) \
--num-cores $(NUM_CORES) $(SIM_ARGS) --full-stacktrace
ifeq ($(MFC),1)
$(MEM_GEN_SEP) "$(MEM_GEN)" "$(SIM_TOP_V).conf" "$(RTL_DIR)"
$(MEM_GEN_SEP) "$(MEM_GEN)" "$@.conf" "$(@D)"
endif
@git log -n 1 >> .__head__
@git diff >> .__diff__
Expand Down Expand Up @@ -228,4 +236,6 @@ pldm-debug:

include Makefile.test

include src/main/scala/device/standalone/standalone_device.mk

.PHONY: verilog sim-verilog emu clean help init bump bsp $(REF_SO)
1 change: 1 addition & 0 deletions src/main/resources/aia
Submodule aia added at f65858
152 changes: 152 additions & 0 deletions src/main/scala/device/imsic_axi_top.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/***************************************************************************************
* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
* Copyright (c) 2024 Institute of Computing Technology, Chinese Academy of Sciences
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

package device

import chisel3._
import chisel3.util._
import chisel3.experimental.dataview._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.tilelink._
import utils.{AXI4LiteBundle, VerilogAXI4LiteRecord}

class imsic_axi_top(
AXI_ID_WIDTH: Int = 5,
AXI_ADDR_WIDTH: Int = 32,
NR_INTP_FILES: Int = 7,
NR_HARTS: Int = 1,
NR_SRC: Int = 256,
SETIP_KEEP_CYCLES: Int = 8
) extends BlackBox(Map(
"AXI_ID_WIDTH" -> AXI_ID_WIDTH,
"AXI_ADDR_WIDTH" -> AXI_ADDR_WIDTH,
"NR_INTP_FILES" -> NR_INTP_FILES,
"NR_HARTS" -> NR_HARTS,
"NR_SRC" -> NR_SRC,
"SETIP_KEEP_CYCLES" -> SETIP_KEEP_CYCLES
)) with HasBlackBoxResource {
private val NR_SRC_WIDTH = log2Ceil(NR_SRC)
private val NR_HARTS_WIDTH = if (NR_HARTS == 1) 1 else log2Ceil(NR_HARTS)
private val INTP_FILE_WIDTH = log2Ceil(NR_INTP_FILES)
private val MSI_INFO_WIDTH = NR_HARTS_WIDTH + INTP_FILE_WIDTH + NR_SRC_WIDTH
val io = IO(new Bundle {
// crg
val axi_clk = Input(Clock())
val axi_rstn = Input(AsyncReset())
val fifo_rstn = Input(AsyncReset())
// bus to access the m interrupt file
val m_s = Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH))
// bus to access the s interrupt file
val s_s = Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH))
// imsic_csr_top
val o_msi_info = Output(UInt(MSI_INFO_WIDTH.W))
val o_msi_info_vld = Output(Bool())
})
addResource("/aia/src/rtl/imsic/imsic_axi_top.v")
addResource("/aia/src/rtl/imsic/imsic_axi2reg.v")
addResource("/aia/src/rtl/imsic/imsic_regmap.v")
addResource("/aia/src/rtl/imsic/common/generic_fifo_dc_gray.v")
addResource("/aia/src/rtl/imsic/common/generic_dpram.v")
}

class imsic_bus_top(
useTL: Boolean = false,
AXI_ID_WIDTH: Int = 5,
AXI_ADDR_WIDTH: Int = 32,
NR_INTP_FILES: Int = 7,
NR_HARTS: Int = 1,
NR_SRC: Int = 256,
SETIP_KEEP_CYCLES: Int = 8
)(implicit p: Parameters) extends LazyModule {
private val NR_SRC_WIDTH = log2Ceil(NR_SRC)
private val NR_HARTS_WIDTH = if (NR_HARTS == 1) 1 else log2Ceil(NR_HARTS)
private val INTP_FILE_WIDTH = log2Ceil(NR_INTP_FILES)
private val MSI_INFO_WIDTH = NR_HARTS_WIDTH + INTP_FILE_WIDTH + NR_SRC_WIDTH

private val tuple_axi4_tl = Option.when(useTL) {
val tlnodes = Seq.fill(2)(TLClientNode(Seq(TLMasterPortParameters.v1(
clients = Seq(TLMasterParameters.v1(
"tl",
sourceId = IdRange(0, 1)
))
))))
val axi4nodes = Seq.fill(2)(AXI4SlaveNode(Seq(AXI4SlavePortParameters(
Seq(AXI4SlaveParameters(
Seq(AddressSet(0x0, (1L << AXI_ADDR_WIDTH) - 1)),
regionType = RegionType.UNCACHED,
supportsWrite = TransferSizes(1, 4),
supportsRead = TransferSizes(1, 4),
interleavedId = Some(0)
)),
beatBytes = 4
))))
axi4nodes zip tlnodes foreach { case (axi4node, tlnode) =>
axi4node :=
AXI4IdIndexer(AXI_ID_WIDTH) :=
AXI4Buffer() :=
AXI4Buffer() :=
AXI4UserYanker(Some(1)) :=
TLToAXI4() :=
TLWidthWidget(4) :=
TLFIFOFixer() :=
tlnode
}

(axi4nodes, tlnodes)
}

val axi4 = tuple_axi4_tl.map(_._1)
private val tl = tuple_axi4_tl.map(_._2)
val tl_m = tl.map(x => InModuleBody(x(0).makeIOs()))
val tl_s = tl.map(x => InModuleBody(x(1).makeIOs()))

class imsic_bus_top_imp(wrapper: imsic_bus_top) extends LazyModuleImp(wrapper) {
// imsic csr top io
val o_msi_info = IO(Output(UInt(MSI_INFO_WIDTH.W)))
val o_msi_info_vld = IO(Output(Bool()))

// axi4lite io
val m_s = Option.when(!useTL)(IO(Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH))))
val s_s = Option.when(!useTL)(IO(Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH))))

// imsic axi top
val u_imsic_axi_top = Module(new imsic_axi_top)

// connection: crg
u_imsic_axi_top.io.axi_clk := clock
u_imsic_axi_top.io.axi_rstn := (~reset.asBool).asAsyncReset
u_imsic_axi_top.io.fifo_rstn := (~reset.asBool).asAsyncReset // TODO: axi_rstn & sw_rstn

// connection: imsic csr top
o_msi_info := u_imsic_axi_top.io.o_msi_info
o_msi_info_vld := u_imsic_axi_top.io.o_msi_info_vld

// connection: axi4lite
m_s.foreach(_ <> u_imsic_axi_top.io.m_s)
s_s.foreach(_ <> u_imsic_axi_top.io.s_s)

// connection: axi4
wrapper.axi4.foreach { axi4 =>
axi4.map(_.in.head._1) zip Seq(u_imsic_axi_top.io.m_s, u_imsic_axi_top.io.s_s) foreach {
case (axi4, axi4lite) => axi4lite.viewAs[AXI4LiteBundle].connectFromAXI4(axi4)
}
}
}

lazy val module = new imsic_bus_top_imp(this)
}
55 changes: 55 additions & 0 deletions src/main/scala/device/standalone/StandAloneCLINT.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
* Copyright (c) 2020-2021 Peng Cheng Laboratory
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

package device.standalone

import chisel3._
import freechips.rocketchip.diplomacy._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.interrupts._

class StandAloneCLINT (
useTL: Boolean = false,
baseAddress: BigInt,
addrWidth: Int,
dataWidth: Int = 64,
hartNum: Int
)(implicit p: Parameters) extends StandAloneDevice(
useTL, baseAddress, addrWidth, dataWidth, hartNum
) {

private def clintParam = CLINTParams(baseAddress)
def addressSet: AddressSet = clintParam.address

private val clint = LazyModule(new CLINT(clintParam, dataWidth / 8))
clint.node := xbar

// interrupts
val clintIntNode = IntSinkNode(IntSinkPortSimple(hartNum, 2))
clintIntNode :*= clint.intnode
val int = InModuleBody(clintIntNode.makeIOs())

class StandAloneCLINTImp(outer: StandAloneCLINT)(implicit p: Parameters) extends StandAloneDeviceImp(outer) {
val io = IO(new Bundle {
val rtcTick = Input(Bool())
})
outer.clint.module.io.rtcTick := io.rtcTick
}

override lazy val module = new StandAloneCLINTImp(this)

}
58 changes: 58 additions & 0 deletions src/main/scala/device/standalone/StandAloneDebugModule.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
* Copyright (c) 2020-2021 Peng Cheng Laboratory
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

package device.standalone

import chisel3._
import freechips.rocketchip.diplomacy._
import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.interrupts._
import device.XSDebugModuleParams
import system.SoCParamsKey
import xiangshan.XSCoreParamsKey
import xiangshan.XSTileKey
import device.DebugModule

class StandAloneDebugModule (
useTL: Boolean = false,
baseAddress: BigInt,
addrWidth: Int,
dataWidth: Int = 64,
hartNum: Int
)(implicit p: Parameters) extends StandAloneDevice(
useTL, baseAddress, addrWidth, dataWidth, hartNum
) with HasMasterInterface {

def addressSet: AddressSet = AddressSet(XSDebugModuleParams.apply(p(XSTileKey).head.XLEN).baseAddress, 0xfff)

val debugModule = LazyModule(new DebugModule(hartNum)(p))
debugModule.debug.node := xbar
debugModule.debug.dmInner.dmInner.sb2tlOpt.foreach(masternode := _.node)

// interrupts
val debugModuleIntNode = IntSinkNode(IntSinkPortSimple(hartNum, 1))
debugModuleIntNode :*= debugModule.debug.dmOuter.dmOuter.intnode
val int = InModuleBody(debugModuleIntNode.makeIOs())

class StandAloneDebugModuleImp(val outer: StandAloneDebugModule)(implicit p: Parameters) extends StandAloneDeviceImp(outer) {
val io = IO(new outer.debugModule.DebugModuleIO)
io <> outer.debugModule.module.io
}

override lazy val module = new StandAloneDebugModuleImp(this)

}
Loading

0 comments on commit 720dd62

Please sign in to comment.