2013年12月29日 星期日

Rocket-chip Risc-V core design and debugging in IntelliJ IDE

Refer to:
https://github.com/chipsalliance/rocket-tools/blob/master/README.md
https://github.com/chipsalliance/rocket-chip/blob/master/README.md
https://fatalfeel.blogspot.com/2013/12/chisel-design-ic-for-risc-v.html
https://hardsecurity.github.io/docs/untether-v0.2/figures/pipeline.png

1.
#preinstall
apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev libusb-1.0-0-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev device-tree-compiler pkg-config libexpat-dev libfl-dev

2.
#export must add to last line of ~/.bashrc
export RISCV="/opt/riscv"
export ROCKETCHIP="/root/riscv_cpu/rocket-chip"
export MAKEFLAGS="$MAKEFLAGS -j8"

3.
git clone --recursive https://github.com/freechipsproject/rocket-tools
git clone --recursive https://github.com/chipsalliance/rocket-chip.git

4.
cd ~/riscv_cpu/rocket-tools
git submodule update --init --recursive
./build.sh

5.
cd ~/riscv_cpu/rocket-chip
git submodule update --init

6.
gedit ~/riscv_cpu/rocket-chip/.sbtopts
-Dsbt.workspace=$PWD
#change to
-Dsbt.workspace=/root/riscv_cpu/rocket-chip

7.
cd ~/riscv_cpu/rocket-chip/emulator
make
make run (option, run emulator)

8.
# IntelliJ IDE debug
open /root/riscv_cpu/rocket-chip
right click ~/riscv_cpu/rocket-chip/src/test/scala/generatorTests/StageGeneratorSpec.scala
[Create] -> Configuration -> Environment variables:
JAVA_TOOL_OPTIONS=-Xmx16384m -Xss256m

9.
set breakpoint at any line of ~/riscv_cpu/rocket-chip/src/main/scala/rocket/ALU.scala
start debug
Done.

demo: https://www.mediafire.com/view/bbv5poiuh31u56h/rocket-chip.png

//////////////////generate TestHarness.v//////////////////
//////////////////////////////////////////////////////////////////////////
1. gedit ~/riscv_cpu/rocket-chip/src/main/scala/system/RocketChipStageGenerator.scala
after "override def run(annotations: AnnotationSeq): AnnotationSeq"
add 2 functions

def getConfig(fullConfigClassNames: Seq[String]): Config =
{
    new Config(fullConfigClassNames.foldRight(Parameters.empty)
    {
        case (currentName, config) => val currentConfig = try
        {
            Class.forName(currentName).newInstance.asInstanceOf[Config]
        }
        catch
        {
            case e: java.lang.ClassNotFoundException => throwException(s"""Unable to find part "$currentName" from "$fullConfigClassNames", did you misspell it or specify the wrong package path?""", e)
        }
        currentConfig ++ config
    })
}

def emitVerilog(annotations: AnnotationSeq): AnnotationSeq =
{
    val stageOpts = view[StageOptions](annotations)
    val rOpts = view[RocketChipOptions](annotations)

    val config = getConfig(rOpts.configNames.get).alterPartial
    {
        case TargetDirKey => stageOpts.targetDir
    }

    (new chisel3.stage.ChiselStage).emitVerilog(new TestHarness()(config))

    annotations
}

2. gedit ~/riscv_cpu/rocket-chip/src/test/scala/generatorTests/StageGeneratorSpec.scala
new RocketChipStage().run(Seq(new TargetDirAnnotation(dirName),
                                new TopModuleAnnotation(Class.forName("freechips.rocketchip.system.TestHarness")),
                                new ConfigsAnnotation(Seq("freechips.rocketchip.system.DefaultConfig")),
                                dummyAspect))

#change to

new RocketChipStage().emitVerilog(Seq(new TargetDirAnnotation(dirName),
                                      new TopModuleAnnotation(Class.forName("freechips.rocketchip.system.TestHarness")),
                                      new ConfigsAnnotation(Seq("freechips.rocketchip.system.DefaultConfig")),
                                      dummyAspect))

download: https://www.mediafire.com/file/xo3ln5g8kq6cpdq/RocketChipStageGenerator.scala

3.
start debug
auto generate ~/riscv_cpu/rocket-chip/TestHarness.v

4.
because  SimDTM.v made from SimDTM.cc we need modify it.
gedit ~/riscv_cpu/rocket-chip/src/main/resources/vsrc/SimDTM.v
#modify these  sections
(a)
/*import "DPI-C" function int debug_tick
(
  output bit     debug_req_valid,
  input  bit     debug_req_ready,
  output int     debug_req_bits_addr,
  output int     debug_req_bits_op,
  output int     debug_req_bits_data,

  input  bit        debug_resp_valid,
  output bit        debug_resp_ready,
  input  int        debug_resp_bits_resp,
  input  int        debug_resp_bits_data
);*/
(b)
//bit r_reset;
reg [ 1:0] r_reset;
(c)
/*bit __debug_req_valid;
  int __debug_req_bits_addr;
  int __debug_req_bits_op;
  int __debug_req_bits_data;
  bit __debug_resp_ready;
  int __exit;*/
  reg [ 1:0] __debug_req_valid;
  reg [31:0] __debug_req_bits_addr;
  reg [31:0] __debug_req_bits_op;
  reg [31:0] __debug_req_bits_data;
  reg [ 1:0] __debug_resp_ready;
  reg [31:0] __exit;
(d)
always @(negedge clk)
  begin
    r_reset <= reset;
    if (reset || r_reset)
    begin
      __debug_req_valid = 0;
      __debug_resp_ready = 0;
      __exit = 0;
    end
    /*else
    begin
      __exit = debug_tick(
        __debug_req_valid,
        __debug_req_ready,
        __debug_req_bits_addr,
        __debug_req_bits_op,
        __debug_req_bits_data,
        __debug_resp_valid,
        __debug_resp_ready,
        __debug_resp_bits_resp,
        __debug_resp_bits_data
      );
    end*/
  end

download: https://www.mediafire.com/file/2ks5vkfw8fnb5xf/SimDTM_xilinx.v

5.
#in
"Vivado HL System Edition" 2019.2.1
Add Sources:
~/riscv_cpu/rocket-chip/TestHarness.v
~/riscv_cpu/rocket-chip/src/main/resources/vsrc/plusarg_reader.v
~/riscv_cpu/rocket-chip/src/main/resources/vsrc/EICG_wrapper.v
~/riscv_cpu/rocket-chip/src/main/resources/vsrc/SimDTM.v

demo: https://www.mediafire.com/view/a19x57o7llkbzv3/testharness.png

///////////////////XiangShan rocket-chip///////////////////
//////////////////////////////////////////////////////////////////////////
1.
#export must add to last line of ~/.bashrc
export RISCV="/opt/riscv"
export ROCKETCHIP="/root/riscv_cpu/XiangShan/rocket-chip"
export MAKEFLAGS="$MAKEFLAGS -j8"

2.
cd ~/riscv_cpu/XiangShan/rocket-chip
git submodule update --init

3.
gedit ~/riscv_cpu/XiangShan/rocket-chip/.sbtopts
-Dsbt.workspace=$PWD
#change to
-Dsbt.workspace=/root/riscv_cpu/XiangShan/rocket-chip

4.
cd 
~/riscv_cpu/XiangShan/rocket-chip/emulator
make

5.

# IntelliJ IDE debug
oepn ~/riscv_cpu/XiangShan/rocket-chip
Rebuild Project
before Rebuild Project pass, do not goto Version Control remove directory git

6. Option step
# because sbt version different, only meet chisel3 or firrtl compile error do this
gedit ~/riscv_cpu/XiangShan/rocket-chip/build.sc
# comment 2 objects and rebuild
/*object firrtlRocket extends firrtl.build.firrtlCrossModule("2.12.11") {
  override def millSourcePath = os.pwd / "firrtl"
}
object chisel3Rocket extends chisel3.build.chisel3CrossModule("2.12.12") {
  override def millSourcePath = os.pwd / "chisel3"

  def firrtlModule: Option[PublishModule] = Some(firrtlRocket)
}*/

7.
right click ~/riscv_cpu/XiangShan/rocket-chip/src/test/scala/generatorTests/StageGeneratorSpec.scala
[Create] -> Configuration -> Environment variables:
JAVA_TOOL_OPTIONS=-Xmx16384m -Xss256m

8.
start debug
demo: https://www.mediafire.com/view/25uav37ia8qfn5d/xiang_rocket.png

/////////////////////////tutorial
/////////////////////////
//ALU.scala
val in2_inv = Mux(isSub(io.fn), ~io.in2, io.in2)
io.adder_out := io.in1 + in2_inv + isSub(io.fn)
...
val out = Mux(io.fn === FN_ADD || io.fn === FN_SUB, io.adder_out, shift_logic)
io.out := out

//
mux select:
val dmem_resp_xpu = !io.dmem.resp.bits.tag(0).asBool
...
(io.dmem.resp.valid && io.dmem.resp.bits.has_data) && dmem_resp_xpu

path 1
io.adder_out -> io.dmem.req.bits.addr -> io.requestor(1).req.bits.addr -> dcachearb -> io.requestor(1).resp.bits.data -> io.dmem.resp.bits.addr -> rf_wdata -> rf_MPORT_data -> WD3(rf_reg)

path 2
io.out -> mem_reg_wdata -> mem_int_wdata -> wb_reg_wdata -> rf_wdata -> rf_MPORT_data -> WD3(rf_reg)

path 1 when dcache io.dmem.resp.valid is true and io.dmem.resp.bits.has_data is true
path 2 when dcache io.dmem.resp.valid is false  or io.dmem.resp.bits.has_data is false

It's mean when dcachet(dmem) out failed then alu write back directly not through
dcache(memory stage)

[MPORT] of rf_MPORT_data be generated by RawModule.scala in ~/.cache/coursier/v1/https/repo1.maven.org/maven2/edu/berkeley/cs/chisel3-core_2.12/3.4.3/chisel3-core_2.12-3.4.3-sources.jar

id.topBinding match {
    case OpBinding(_, _) =>
        id.forceName(Some(""), default="T", _namespace)
    case MemoryPortBinding(_, _) =>
        id.forceName(None, default="MPORT", _namespace)  //>>> generate key [MPORT] here
    case PortBinding(_) =>
        id.forceName(None, default="PORT", _namespace)
    case RegBinding(_, _) =>
        id.forceName(None, default="REG", _namespace)
    case WireBinding(_, _) =>
        id.forceName(Some(""), default="WIRE", _namespace)
    case _ => 
}

沒有留言:

張貼留言