提交 e3f2a5cf 编写于 作者: Fa_wang's avatar Fa_wang

Merge remote-tracking branch 'origin/master' into opt-sbuffer-timing

# XiangShan 自动化批量测试脚本
Copyright 2020 zyy
## Quick Start
进入该目录,运行以下命令:
```bash
ulimit -n 4096 # 设置操作系统允许打开的最大文件数
python3 run.py
```
输出结果默认保存在当前目录,建议使用者阅读 `run.py` 源码进行修改。
## Usage
`python3 run.py -h` 可以打印帮助列表。
参数:
+ -I 仿真最大指令数
+ -e 仿真可执行文件的路径(比如 XiangShan/build/emu)
+ -T 仿真的线程数(一般和香山 emu 编译时候指定的线程数相同)
+ -h 帮助列表
某些默认参数可以在 `run.py` 脚本里面查看和修改,建议使用者阅读 `run.py` 源码。
example:
```bash
python3 run.py -I 10000000 -T 8 # 每个 `emu` 任务占用 8 个核,仿真最大指令数为 100M
```
## Backend
+ 该脚本会将一定数量的服务器处理器核作为资源池,每个 `emu` 任务都会占用相邻的和 `emu` 线程数量相同的处理核。
+ 如果当前所有的处理核资源都被占用,剩余的 `emu` 任务将会被阻塞。
+ 当一个 `emu` 任务运行完毕(成功或者失败),它占用的处理核资源会被释放,下一个 `emu` 就会继续占用该处理核资源运行。
+ 当一个 `emu` 任务“跑挂了”,它会回溯 `10000` 周期重新运行,并加上 `--dump-wave` 参数,直到再次“跑挂”或者 “hit good trap"。
+ 所有输出结果都会以文件形式保存在输出目录(`run.py` 指定)。
## End
更详细可以阅读`语雀`文档`开发工具部分`
# Copyright 2020 zyy
import os
# /path/to/spec2006/benchspec/CPU2006
spec_cpu_2006_dir = os.environ['cpu_2006_dir']
# /path/to/spec2017/benchspec/CPU
spec_cpu_2017_dir = os.environ['cpu_2017_dir']
gathered_spec2017_data_dir = os.environ['spec2017_run_dir']
gathered_spec2006_data_dir = os.environ['spec2006_run_dir']
# Copyright 2020 zyy
import sh
import os
import os.path as osp
from pprint import pprint
from multiprocessing import Lock
class SimulatorTaskGoBack:
def __init__(
self, exe: str, top_data_dir: str,
task_name: str, workload: str, sub_phase: int):
# options passing to simulator
self.direct_options = []
# options passing to python parser
self.dict_options = dict()
self.list_options = set()
self.final_options = []
self.work_dir = None
self.log_dir = None
assert osp.isdir(top_data_dir)
self.top_data_dir = top_data_dir
self.task_name = task_name
self.workload = workload
self.sub_phase_id = sub_phase
self.exe = exe
# assert osp.isfile(exe) # numactl isn't a file
self.dry_run = False
def set_workload(self, workload: str):
self.workload = workload
def add_direct_options(self, options: list):
self.direct_options += options
def insert_direct_options(self, options: list, index: int):
assert(index < len(self.direct_options))
insert_index = index
for op in options:
self.direct_options.insert(insert_index, op)
insert_index += 1
def add_dict_options(self, options: dict, replace=True):
for k, v in options.items():
if replace or k not in self.dict_options:
self.dict_options[k] = v
def add_list_options(self, options: list):
for x in options:
self.list_options.add(x)
def format_options(self):
self.final_options = self.direct_options
self.final_options += list(self.list_options)
for k, v in self.dict_options.items():
self.final_options.append(f'{k}={v}')
def workload_level_path_format(self):
self.log_dir = f'{self.top_data_dir}/{self.task_name}/{self.workload}/'
def sub_workload_level_path_format(self):
self.log_dir = f'{self.top_data_dir}/{self.task_name}/{self.workload}/{self.sub_phase_id}/'
def set_trivial_workdir(self):
self.work_dir = self.log_dir
def check_and_makedir(self, d):
if not osp.isdir(d):
assert not osp.isfile(d)
os.makedirs(d)
def run(self, is_goback):
assert self.work_dir is not None
assert self.log_dir is not None
self.check_and_makedir(self.log_dir)
self.check_and_makedir(self.work_dir)
self.check_and_makedir(osp.join(self.log_dir, 'build'))
if self.dry_run:
pprint(self.exe)
pprint(self.final_options)
print('log_dir: ', self.log_dir)
return 0
os.chdir(self.work_dir)
cmd = sh.Command(self.exe)
# sh.rm(['-f', osp.join(self.log_dir, 'aborted')])
# sh.rm(['-f', osp.join(self.log_dir, 'completed')])
# sh.rm(['-f', osp.join(self.log_dir, 'aborted_back')])
# sh.rm(['-f', osp.join(self.log_dir, 'completed_back')])
sh.touch(osp.join(self.log_dir, 'running'))
out_path = 'simulator_out.txt' if not is_goback else 'simulator_out_back.txt'
err_path = 'simulator_err.txt' if not is_goback else 'simulator_err_back.txt'
aborted_signal = 'aborted' if not is_goback else 'aborted_back'
completed_signal = 'completed' if not is_goback else 'completed_back'
print(self.final_options)
try:
cmd(
_out = osp.join(self.log_dir, out_path),
_err = osp.join(self.log_dir, err_path),
_env = {"NOOP_HOME": self.log_dir} if is_goback else {"NOOP_HOME": "/home/ccc/XiangShan"},
*self.final_options
)
except sh.ErrorReturnCode_1 as e:
# TODO
pass
except sh.ErrorReturnCode_2 as e:
print(e)
sh.rm(osp.join(self.log_dir, 'running'))
sh.touch(osp.join(self.log_dir, aborted_signal))
cycle_cnt = check_simulator(osp.join(self.log_dir, out_path))
assert(cycle_cnt != -1)
return cycle_cnt
except sh.ErrorReturnCode_3 as e:
# TODO
pass
sh.rm(osp.join(self.log_dir, 'running'))
sh.touch(osp.join(self.log_dir, completed_signal))
return 0
def check_simulator(simulator_out_path: str):
file = open(simulator_out_path, 'r')
is_aborted = False
for line in file.readlines():
if line.find('cycleCnt') != -1:
words = line.split(' ')
cycle_cnt_index = 0
for word in words:
if word == 'cycleCnt':
assert(len(words) >= cycle_cnt_index + 3)
words = words[cycle_cnt_index + 2].split(',')
assert(len(words) == 2)
assert(words[1] == '')
file.close()
return int(words[0])
else:
cycle_cnt_index += 1
file.close()
return -1
# Copyright 2020 zyy
from common.simulator_task_goback import SimulatorTaskGoBack
# example task tree structure:
ExampleTask = {
'gcc': {
'0': '/path/to/gcc/0/cpt0.gz',
'1': '/path/to/gcc/1/cpt0.gz',
}
}
def task_tree_to_batch_task(
task,
batch_task_desc: dict,
exe: str, top_data_dir: str, batch_task_name: str, emu: str, max_instr: int):
tasks = []
for workload, cpts in batch_task_desc.items():
for cpt_id, cpt_file in cpts.items():
tasks.append(task(exe, top_data_dir, batch_task_name, workload, cpt_id, emu, max_instr))
return tasks
# Copyright 2020 zyy
from common.simulator_task_goback import SimulatorTaskGoBack
class EmuTasksConfig(SimulatorTaskGoBack):
def __init__(self, exe: str, top_data_dir: str, task_name: str, workload: str, sub_phase: int, emu: str, max_instr: int):
super().__init__(exe, top_data_dir, task_name, workload, sub_phase)
self.window_size = 192
self.add_direct_options(
[ emu ],
)
self.add_direct_options(
['-I', str(max_instr)],
)
self.list_conf = [
# '-i'
]
self.core_dict = {
# TODO
}
self.mem_dict = {
# TODO
}
self.dict_options = {
**self.dict_options,
**self.core_dict,
**self.mem_dict,
}
self.add_list_options(self.list_conf)
# Copyright 2020 zyy
import sh
import os
import re
import os.path as osp
import sys, getopt
from pprint import pprint
import multiprocessing
from multiprocessing import Pool, Lock, Manager, Process
from common.simulator_task_goback import SimulatorTaskGoBack
from common.task_tree_go_back import task_tree_to_batch_task
from config import EmuTasksConfig
# XiangShan 自动化测试脚本:可以让香山项目编译出来的 `emu` 自动批量运行某个目录下的 `checkpoints`
# 在 `XiangShan/scripts/autorun` 目录下运行: `python3 /path/to/this/file [参数]`
# 如果报错找不到相应的 `module`,则在前面指定 `PYTHONPATH`: `PYTHONPATH=/path/to/XiangShan/scripts/autorun python3 /path/to/this/file [参数]`
# 参数:
# + -I 仿真最大指令数
# + -e 仿真可执行文件的路径(比如 XiangShan/build/emu)
# + -T 仿真的线程数(一般和香山 emu 编译时候指定的线程数相同)
# + -h 帮助列表
# 运行这个脚本前请先设置操作系统允许打开的最大文件数:
# ulimit -n 最大文件数,可以设成 4096, 即 `ulimit -n 4096`
TaskSummary = {}
noop_home = os.environ["NOOP_HOME"]
exe = 'numactl'
emu = noop_home + '/build/emu' # 仿真可执行文件的路径
# 使用者可以选择性修改以下写死的参数
data_dir = '/bigdata/ccc_data/gcpt_shared/random_cpts' # `checkpoint` 目录,比如左边这个路径
top_output_dir = noop_home + '/scripts/autorun/' # 结果输出目录(默认为该文件目录,建议使用者修改)
THREADS_NUM = 8 # 每个 `emu` 任务运行时将会所占的 `cpu` 核数,一般和编译 `emu` 时设置的线程数一致
MAX_CORE = 128 # 所有 `emu` 任务占用的最大 `cpu` 核数,因此可以同时运行 `MAX_CORE / THREADS_NUM` 个 `emu` 任务
MAX_INSTR = 1000000 # 每个 `emu` 任务运行的最大指令数
cpt_dir_pattern = re.compile(r'\d+')
def find_task(d: str):
for workload in os.listdir(d):
workload_dir = osp.join(d, workload)
if not osp.isdir(workload_dir):
continue
TaskSummary[workload] = {}
for cpt in os.listdir(workload_dir):
cpt_dir = osp.join(workload_dir, cpt)
if not cpt_dir_pattern.match(cpt) or not osp.isdir(cpt_dir):
continue
cpt_file = os.listdir(cpt_dir)[0]
cpt_file = osp.join(cpt_dir, cpt_file)
assert osp.isfile(cpt_file)
TaskSummary[workload][cpt] = cpt_file
return TaskSummary
def task_wrapper(task: SimulatorTaskGoBack, thread_num: int, cores_id: int, cores):
core_options = [
'-C',
str(cores_id * thread_num) + '-' + str(cores_id * thread_num + thread_num - 1)
]
task.insert_direct_options(core_options, 0)
is_goback = False
cycle_cnt = task.run(False)
simulator_success = (cycle_cnt == 0)
if not simulator_success:
print('simulator abort, go back...')
back_cycle_cnt = cycle_cnt - 10000
task.add_direct_options(['-b', str(back_cycle_cnt), '-e', '-1', '--dump-wave'])
cycle_cnt = task.run(True)
simulator_success = (cycle_cnt == 0)
is_goback = True
cores[cores_id] = 0
print(cores_id * thread_num, cores_id * thread_num + thread_num - 1, "simulator task finish")
# return simulator_success, is_goback, cycle_cnt, task.workload, task.sub_phase_id
sys.exit()
if __name__ == "__main__":
argv = sys.argv[1:]
try:
opts, args = getopt.getopt(argv, "he:I:T:")
except getopt.GetoptError:
print("py3 this-file -e <Simulator Executable File> -I <Max Instruction> -T <Threads Num>")
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print("py3 this-file -e <Simulator Executable File> -I <Max Instruction> -T <Threads Num>")
sys.exit()
elif opt == '-e':
emu = arg
elif opt == '-I':
MAX_INSTR = int(arg)
# assert(MAX_INSTR > 10000)
elif opt == '-T':
THREADS_NUM = int(arg)
assert(THREADS_NUM > 0)
assert(THREADS_NUM % 4 == 0)
task_tree = find_task(data_dir)
# pprint(task_tree)
tasks = task_tree_to_batch_task(EmuTasksConfig, task_tree, exe, top_output_dir, "emu_ooo_run_sepc06_cpt", emu, MAX_INSTR)
for task in tasks:
# task.dry_run = True
task.sub_workload_level_path_format()
task.set_trivial_workdir()
cpt_file = task_tree[task.workload][task.sub_phase_id]
# print(cpt_file)
task.direct_options += ['-i', cpt_file]
task.add_dict_options({
# TODO
})
task.format_options()
with Manager() as manager:
cores_list = [0] * int(MAX_CORE / THREADS_NUM)
cores = manager.list(cores_list)
task_id = 0
proc_list = []
while True:
if 0 not in cores:
continue
c_id = cores.index(0)
cores[c_id] = 1
if task_id >= len(tasks):
break
p = Process(target=task_wrapper, args=(tasks[task_id], THREADS_NUM, c_id, cores))
task_id += 1
p.start()
proc_list.append(p)
for proc in proc_list:
proc.join()
package xiangshan.backend.decode
import chisel3._
import chisel3.util.BitPat
import xiangshan.{FuType, HasXSParameter}
import xiangshan.backend._
import xiangshan.backend.decode.isa._
trait HasInstrType {
// TODO: optimize these encoding
def InstrN = "b0000".U
def InstrI = "b0001".U
def InstrR = "b0010".U
def InstrS = "b0011".U
def InstrB = "b0100".U
def InstrU = "b0101".U
def InstrJ = "b0110".U
def InstrA = "b0111".U
def InstrSA = "b1000".U // Atom Inst: SC
def InstrFR = "b1001".U
def InstrFI = "b1010".U // flw/fld
def InstrGtoF = "b1011".U
def InstrFS = "b1100".U
def InstrFtoG = "b1101".U
def isrfWen(instrType : UInt): Bool = Array(
InstrI, InstrR, InstrU, InstrJ, InstrA, InstrSA, InstrFtoG
).map(_===instrType).reduce(_||_)
def isfpWen(instrType: UInt): Bool = Array(
InstrFI, InstrFR, InstrGtoF
).map(_===instrType).reduce(_||_)
}
object FuOpType {
def apply() = UInt(6.W)
}
object Instructions extends HasInstrType with HasXSParameter {
def NOP = 0x00000013.U
val DecodeDefault = List(InstrN, FuType.alu, ALUOpType.sll) // TODO: need check
def DecodeTable =
RVIInstr.table ++
XSTrap.table ++
RVZicsrInstr.table ++
RVZifenceiInstr.table ++
Privileged.table ++
RVAInstr.table ++
(if (HasMExtension) RVMInstr.table else Nil) ++
(if (HasCExtension) RVCInstr.table else Nil) ++
(if (HasFPU) RVFInstr.table ++ RVDInstr.table else Nil)
}
object CInstructions extends HasInstrType with HasXSParameter {
def NOP = 0x00000013.U
val DecodeDefault = List(RVCInstr.ImmNone, RVCInstr.DtCare, RVCInstr.DtCare, RVCInstr.DtCare)
// val DecodeDefault = List(InstrN, FuType.csr, CSROpType.jmp)
def CExtraDecodeTable = RVCInstr.cExtraTable
}
......@@ -16,7 +16,7 @@ import freechips.rocketchip.util.{uintToBitPat,UIntIsOneOf}
import xiangshan._
import utils._
import xiangshan.backend._
import xiangshan.backend.decode.AltInstructions._
import xiangshan.backend.decode.Instructions._
import xiangshan.backend.fu.fpu.FPUOpType
import freechips.rocketchip.tile.RocketTile
......
package xiangshan.backend.decode
import chisel3._
import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend._
import xiangshan.backend.decode.isa.{RVCInstr, RV32I_ALUInstr, RVFInstr, RVDInstr}
import xiangshan.{CfCtrl, CtrlFlow}
class Decoder extends XSModule with HasInstrType {
val io = IO(new Bundle() {
val in = Input(new CtrlFlow)
val out = Output(new CfCtrl)
})
io.out := DontCare // FIXME: remove me!!!
io.out.cf := io.in
val instr: UInt = io.in.instr
val decodeList = ListLookup(instr, Instructions.DecodeDefault, Instructions.DecodeTable)
val instrType :: fuType :: fuOpType :: Nil = decodeList
// todo: remove this when fetch stage can decide if an instr is br/jmp
// io.out.cf.brUpdate.isBr := (instrType === InstrB ||
// (fuOpType === JumpOpType.jal && instrType === InstrJ && fuType === FuType.jmp) ||
// (fuOpType === JumpOpType.jalr && instrType === InstrI && fuType === FuType.jmp) ||
// (fuOpType === CSROpType.jmp && instrType === InstrI && fuType === FuType.csr))
val isRVC = instr(1, 0) =/= "b11".U
val rvcImmType :: rvcSrc1Type :: rvcSrc2Type :: rvcDestType :: Nil =
ListLookup(instr, CInstructions.DecodeDefault, CInstructions.CExtraDecodeTable)
io.out.ctrl.fuOpType := fuOpType
io.out.ctrl.fuType := fuType
val SrcTypeTable = List(
InstrI -> (SrcType.reg, SrcType.imm),
InstrFI -> (SrcType.reg, SrcType.imm),
InstrR -> (SrcType.reg, SrcType.reg),
InstrFR -> (SrcType.fp, SrcType.fp ),
InstrS -> (SrcType.reg, SrcType.reg),
InstrFS -> (SrcType.reg, SrcType.fp ),
InstrSA -> (SrcType.reg, SrcType.reg),
InstrB -> (SrcType.reg, SrcType.reg),
InstrU -> (SrcType.pc , SrcType.imm),
InstrJ -> (SrcType.pc , SrcType.imm),
InstrN -> (SrcType.pc , SrcType.imm),
InstrGtoF -> (SrcType.reg, SrcType.imm),
InstrFtoG -> (SrcType.fp , SrcType.fp)
)
val src1Type = LookupTree(instrType, SrcTypeTable.map(p => (p._1, p._2._1)))
val src2Type = LookupTree(instrType, SrcTypeTable.map(p => (p._1, p._2._2)))
val (rs, rt, rd) = (instr(19, 15), instr(24, 20), instr(11, 7))
val rs1 = instr(11,7)
val rs2 = instr(6,2)
val rs1p = LookupTree(instr(9,7), RVCInstr.RVCRegNumTable.map(p => (p._1, p._2)))
val rs2p = LookupTree(instr(4,2), RVCInstr.RVCRegNumTable.map(p => (p._1, p._2)))
val rvc_shamt = Cat(instr(12),instr(6,2))
val RegLookUpTable = List(
RVCInstr.DtCare -> 0.U,
RVCInstr.REGrs -> rs,
RVCInstr.REGrt -> rt,
RVCInstr.REGrd -> rd,
RVCInstr.REGrs1 -> rs1,
RVCInstr.REGrs2 -> rs2,
RVCInstr.REGrs1p -> rs1p,
RVCInstr.REGrs2p -> rs2p,
RVCInstr.REGx1 -> 1.U,
RVCInstr.REGx2 -> 2.U
)
val rvc_src1 = LookupTree(rvcSrc1Type, RegLookUpTable.map(p => (p._1, p._2)))
val rvc_src2 = LookupTree(rvcSrc2Type, RegLookUpTable.map(p => (p._1, p._2)))
val rvc_dest = LookupTree(rvcDestType, RegLookUpTable.map(p => (p._1, p._2)))
val rfSrc1 = Mux(isRVC, rvc_src1, rs)
val rfSrc2 = Mux(isRVC, rvc_src2, rt)
val rfSrc3 = instr(31, 27)
val rfDest = Mux(isRVC, rvc_dest, rd)
// TODO: refactor decode logic
// make non-register addressing to zero, since isu.sb.isBusy(0) === false.B
val rfWen = isrfWen(instrType) && fuType=/=FuType.fence // NOTE: fence instr use instrU but do not wb
val fpWen = isfpWen(instrType)
io.out.ctrl.lsrc1 := Mux(src1Type === SrcType.pc, 0.U, rfSrc1)
io.out.ctrl.lsrc2 := Mux(src2Type === SrcType.imm, 0.U, rfSrc2)
io.out.ctrl.lsrc3 := rfSrc3
io.out.ctrl.rfWen := rfWen
io.out.ctrl.fpWen := fpWen
io.out.ctrl.ldest := Mux(fpWen || rfWen, rfDest, 0.U)
val imm = LookupTree(instrType, List(
InstrI -> SignExt(instr(31, 20), XLEN),
InstrFI -> SignExt(instr(31, 20), XLEN),
InstrS -> SignExt(Cat(instr(31, 25), instr(11, 7)), XLEN),
InstrFS -> SignExt(Cat(instr(31, 25), instr(11, 7)), XLEN),
InstrSA -> SignExt(Cat(instr(31, 25), instr(11, 7)), XLEN),
InstrB -> SignExt(Cat(instr(31), instr(7), instr(30, 25), instr(11, 8), 0.U(1.W)), XLEN),
InstrU -> SignExt(Cat(instr(31, 12), 0.U(12.W)), XLEN),//fixed
InstrJ -> SignExt(Cat(instr(31), instr(19, 12), instr(20), instr(30, 21), 0.U(1.W)), XLEN)
))
val immrvc = LookupTree(rvcImmType, List(
RVCInstr.ImmNone -> 0.U(XLEN.W),
RVCInstr.ImmLWSP -> ZeroExt(Cat(instr(3,2), instr(12), instr(6,4), 0.U(2.W)), XLEN),
RVCInstr.ImmLDSP -> ZeroExt(Cat(instr(4,2), instr(12), instr(6,5), 0.U(3.W)), XLEN),
RVCInstr.ImmSWSP -> ZeroExt(Cat(instr(8,7), instr(12,9), 0.U(2.W)), XLEN),
RVCInstr.ImmSDSP -> ZeroExt(Cat(instr(9,7), instr(12,10), 0.U(3.W)), XLEN),
RVCInstr.ImmSW -> ZeroExt(Cat(instr(5), instr(12,10), instr(6), 0.U(2.W)), XLEN),
RVCInstr.ImmSD -> ZeroExt(Cat(instr(6,5), instr(12,10), 0.U(3.W)), XLEN),
RVCInstr.ImmLW -> ZeroExt(Cat(instr(5), instr(12,10), instr(6), 0.U(2.W)), XLEN),
RVCInstr.ImmLD -> ZeroExt(Cat(instr(6,5), instr(12,10), 0.U(3.W)), XLEN),
RVCInstr.ImmJ -> SignExt(Cat(instr(12), instr(8), instr(10,9), instr(6), instr(7), instr(2), instr(11), instr(5,3), 0.U(1.W)), XLEN),
RVCInstr.ImmB -> SignExt(Cat(instr(12), instr(6,5), instr(2), instr(11,10), instr(4,3), 0.U(1.W)), XLEN),
RVCInstr.ImmLI -> SignExt(Cat(instr(12), instr(6,2)), XLEN),
RVCInstr.ImmLUI -> SignExt(Cat(instr(12), instr(6,2), 0.U(12.W)), XLEN),
RVCInstr.ImmADDI -> SignExt(Cat(instr(12), instr(6,2)), XLEN),
RVCInstr.ImmADDI16SP-> SignExt(Cat(instr(12), instr(4,3), instr(5), instr(2), instr(6), 0.U(4.W)), XLEN),
RVCInstr.ImmADD4SPN-> ZeroExt(Cat(instr(10,7), instr(12,11), instr(5), instr(6), 0.U(2.W)), XLEN)
))
io.out.ctrl.imm := Mux(isRVC, immrvc, imm)
when (fuType === FuType.jmp) {
def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
when (isLink(rfDest) && fuOpType === JumpOpType.jal) { io.out.ctrl.fuOpType := JumpOpType.call }
when (fuOpType === JumpOpType.jalr) {
when (isLink(rfSrc1)) { io.out.ctrl.fuOpType := JumpOpType.ret }
when (isLink(rfDest)) { io.out.ctrl.fuOpType := JumpOpType.call }
}
}
def bitPatLookup(key: UInt, default: UInt, mapping: Seq[(BitPat, UInt)]) = {
mapping.foldLeft(default){case (d, (k, v)) => Mux(k === key, v, d)}
}
io.out.ctrl.src1Type := bitPatLookup(instr, src1Type, Seq(
RV32I_ALUInstr.LUI -> SrcType.reg // FIX LUI
))
io.out.ctrl.src2Type := bitPatLookup(instr, src2Type, Seq(
RVFInstr.FSQRT_S -> SrcType.imm,
RVFInstr.FCLASS_S -> SrcType.imm,
RVFInstr.FMV_X_W -> SrcType.imm,
RVFInstr.FCVT_W_S -> SrcType.imm,
RVFInstr.FCVT_WU_S -> SrcType.imm,
RVFInstr.FCVT_L_S -> SrcType.imm,
RVFInstr.FCVT_LU_S -> SrcType.imm,
RVDInstr.FSQRT_D -> SrcType.imm,
RVDInstr.FCVT_S_D -> SrcType.imm,
RVDInstr.FCVT_D_S -> SrcType.imm,
RVDInstr.FCLASS_D -> SrcType.imm,
RVDInstr.FMV_X_D -> SrcType.imm,
RVDInstr.FCVT_W_D -> SrcType.imm,
RVDInstr.FCVT_WU_D -> SrcType.imm,
RVDInstr.FCVT_L_D -> SrcType.imm,
RVDInstr.FCVT_LU_D -> SrcType.imm
))
io.out.ctrl.src3Type := bitPatLookup(instr, SrcType.imm, Seq(
RVFInstr.FMADD_S -> SrcType.fp,
RVFInstr.FNMADD_S -> SrcType.fp,
RVFInstr.FMSUB_S -> SrcType.fp,
RVFInstr.FNMSUB_S -> SrcType.fp,
RVDInstr.FMADD_D -> SrcType.fp,
RVDInstr.FNMADD_D -> SrcType.fp,
RVDInstr.FMSUB_D -> SrcType.fp,
RVDInstr.FNMSUB_D -> SrcType.fp,
))
io.out.cf.exceptionVec.map(_ := false.B)
io.out.cf.exceptionVec(illegalInstr) := instrType === InstrN
io.out.cf.exceptionVec(instrPageFault) := io.in.exceptionVec(instrPageFault)
// io.out.cf.exceptionVec(instrAccessFault) := io.in.pc(VAddrBits - 1, PAddrBits).orR && !vmEnable // NOTE: PAddrBits is larger than VAddrBits, so comment it
io.out.ctrl.isXSTrap := (instr === XSTrap.TRAP)
when(io.out.ctrl.isXSTrap){
io.out.ctrl.lsrc1 := 10.U // a0
}
/*noSpecExec make it sent to alu0,for roq is empty*/
io.out.ctrl.noSpecExec := io.out.ctrl.isXSTrap ||
io.out.ctrl.fuType===FuType.csr ||
io.out.ctrl.fuType===FuType.mou ||
io.out.ctrl.fuType===FuType.fence
// fflags zero csrrs rd csr
val isFrflags = BitPat("b000000000001_00000_010_?????_1110011") === io.in.instr
io.out.ctrl.blockBackward := io.out.ctrl.isXSTrap ||
(io.out.ctrl.fuType===FuType.csr && !isFrflags) ||
io.out.ctrl.fuType===FuType.mou ||
io.out.ctrl.fuType===FuType.fence
io.out.ctrl.flushPipe := io.out.ctrl.fuType===FuType.fence
io.out.ctrl.isRVF := instr(26, 25) === 0.U
XSDebug("in: instr=%x pc=%x excepVec=%b intrVec=%b crossPageIPFFix=%d\n",
io.in.instr, io.in.pc, io.in.exceptionVec.asUInt, io.in.intrVec.asUInt, io.in.crossPageIPFFix)
XSDebug("out: src1Type=%b src2Type=%b src3Type=%b lsrc1=%d lsrc2=%d lsrc3=%d ldest=%d fuType=%b fuOpType=%b\n",
io.out.ctrl.src1Type, io.out.ctrl.src2Type, io.out.ctrl.src3Type, io.out.ctrl.lsrc1, io.out.ctrl.lsrc2, io.out.ctrl.lsrc3, io.out.ctrl.ldest, io.out.ctrl.fuType, io.out.ctrl.fuOpType)
XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d isRVF=%d imm=%x\n",
io.out.ctrl.rfWen, io.out.ctrl.fpWen, io.out.ctrl.isXSTrap, io.out.ctrl.noSpecExec, io.out.ctrl.blockBackward, io.out.ctrl.flushPipe, io.out.ctrl.isRVF, io.out.ctrl.imm)
}
......@@ -3,7 +3,7 @@ package xiangshan.backend.decode
import chisel3._
import chisel3.util._
object AltInstructions {
object Instructions {
def TRAP = BitPat("b000000000000?????000000001101011")
def BEQ = BitPat("b?????????????????000?????1100011")
def BNE = BitPat("b?????????????????001?????1100011")
......
package xiangshan.backend.decode
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.ALUOpType
object XSTrap extends HasInstrType {
def StateGoodTrap = 0.U
def StateBadTrap = 1.U
def StateInvOpcode = 2.U
def StateRunning = 3.U
/*
calculate as ADDI => addi zero, a0, 0
replace rs '?????' with '01010'(a0) in decode stage
*/
def TRAP = BitPat("b000000000000_?????_000_00000_1101011")
val table = Array(TRAP -> List(InstrI, FuType.alu, ALUOpType.add))
}
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend._
import xiangshan.backend.decode.HasInstrType
object Privileged extends HasInstrType {
def ECALL = BitPat("b000000000000_00000_000_00000_1110011")
def MRET = BitPat("b001100000010_00000_000_00000_1110011")
def SRET = BitPat("b000100000010_00000_000_00000_1110011")
def SFANCE_VMA = BitPat("b0001001_?????_?????_000_00000_1110011")
def FENCE = BitPat("b????????????_?????_000_?????_0001111")
def WFI = BitPat("b0001000_00101_00000_000_00000_1110011")
// fixme: add privilege inst
val table = Array(
ECALL -> List(InstrI, FuType.csr, CSROpType.jmp),
MRET -> List(InstrI, FuType.csr, CSROpType.jmp),
SRET -> List(InstrI, FuType.csr, CSROpType.jmp),
SFANCE_VMA -> List(InstrI, FuType.fence, FenceOpType.sfence), // NOTE: Ignore Src2, no need for asid
FENCE -> List(InstrU, FuType.fence, FenceOpType.fence),
WFI -> List(InstrU, FuType.alu, ALUOpType.sll)
// FENCE -> List(InstrS, FuType.alu, ALUOpType.add), // nop InstrS -> !wen
// WFI -> List(InstrI, FuType.alu, ALUOpType.add) // nop
// FENCE -> List(InstrB, FuType.mou, MOUOpType.fencei)
)
}
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.LSUOpType
import xiangshan.backend.decode.HasInstrType
object RVAInstr extends HasInstrType {
// Note: use instr(14,12) to distinguish D/W inst
// def LR = BitPat("b00010??00000_?????_???_?????_0101111")
// def SC = BitPat("b00011??00000_?????_???_?????_0101111")
def LR_D = BitPat("b00010_??_00000_?????_011_?????_0101111")
def SC_D = BitPat("b00011_??_?????_?????_011_?????_0101111")
def AMOSWAP_D = BitPat("b00001_??_?????_?????_011_?????_0101111")
def AMOADD_D = BitPat("b00000_??_?????_?????_011_?????_0101111")
def AMOXOR_D = BitPat("b00100_??_?????_?????_011_?????_0101111")
def AMOAND_D = BitPat("b01100_??_?????_?????_011_?????_0101111")
def AMOOR_D = BitPat("b01000_??_?????_?????_011_?????_0101111")
def AMOMIN_D = BitPat("b10000_??_?????_?????_011_?????_0101111")
def AMOMAX_D = BitPat("b10100_??_?????_?????_011_?????_0101111")
def AMOMINU_D = BitPat("b11000_??_?????_?????_011_?????_0101111")
def AMOMAXU_D = BitPat("b11100_??_?????_?????_011_?????_0101111")
def LR_W = BitPat("b00010_??_00000_?????_010_?????_0101111")
def SC_W = BitPat("b00011_??_?????_?????_010_?????_0101111")
def AMOSWAP_W = BitPat("b00001_??_?????_?????_010_?????_0101111")
def AMOADD_W = BitPat("b00000_??_?????_?????_010_?????_0101111")
def AMOXOR_W = BitPat("b00100_??_?????_?????_010_?????_0101111")
def AMOAND_W = BitPat("b01100_??_?????_?????_010_?????_0101111")
def AMOOR_W = BitPat("b01000_??_?????_?????_010_?????_0101111")
def AMOMIN_W = BitPat("b10000_??_?????_?????_010_?????_0101111")
def AMOMAX_W = BitPat("b10100_??_?????_?????_010_?????_0101111")
def AMOMINU_W = BitPat("b11000_??_?????_?????_010_?????_0101111")
def AMOMAXU_W = BitPat("b11100_??_?????_?????_010_?????_0101111")
// funct3 === 010 or 011
val table = Array(
LR_D -> List(InstrI, FuType.mou, LSUOpType.lr_d),
SC_D -> List(InstrSA, FuType.mou, LSUOpType.sc_d),
AMOSWAP_D -> List(InstrR, FuType.mou, LSUOpType.amoswap_d),
AMOADD_D -> List(InstrR, FuType.mou, LSUOpType.amoadd_d),
AMOXOR_D -> List(InstrR, FuType.mou, LSUOpType.amoxor_d),
AMOAND_D -> List(InstrR, FuType.mou, LSUOpType.amoand_d),
AMOOR_D -> List(InstrR, FuType.mou, LSUOpType.amoor_d),
AMOMIN_D -> List(InstrR, FuType.mou, LSUOpType.amomin_d),
AMOMAX_D -> List(InstrR, FuType.mou, LSUOpType.amomax_d),
AMOMINU_D -> List(InstrR, FuType.mou, LSUOpType.amominu_d),
AMOMAXU_D -> List(InstrR, FuType.mou, LSUOpType.amomaxu_d),
LR_W -> List(InstrI, FuType.mou, LSUOpType.lr_w),
SC_W -> List(InstrSA, FuType.mou, LSUOpType.sc_w),
AMOSWAP_W -> List(InstrR, FuType.mou, LSUOpType.amoswap_w),
AMOADD_W -> List(InstrR, FuType.mou, LSUOpType.amoadd_w),
AMOXOR_W -> List(InstrR, FuType.mou, LSUOpType.amoxor_w),
AMOAND_W -> List(InstrR, FuType.mou, LSUOpType.amoand_w),
AMOOR_W -> List(InstrR, FuType.mou, LSUOpType.amoor_w),
AMOMIN_W -> List(InstrR, FuType.mou, LSUOpType.amomin_w),
AMOMAX_W -> List(InstrR, FuType.mou, LSUOpType.amomax_w),
AMOMINU_W -> List(InstrR, FuType.mou, LSUOpType.amominu_w),
AMOMAXU_W -> List(InstrR, FuType.mou, LSUOpType.amomaxu_w),
)
}
// This package is used to deal with RVC decode
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.backend.decode.HasInstrType
import xiangshan.FuType
import xiangshan.backend._
trait HasRVCConst {
val RVCRegNumTable = List(
"b000".U -> 8.U,
"b001".U -> 9.U,
"b010".U -> 10.U,
"b011".U -> 11.U,
"b100".U -> 12.U,
"b101".U -> 13.U,
"b110".U -> 14.U,
"b111".U -> 15.U
)
// Imm src
def ImmNone = "b10000".U
def ImmLWSP = "b00000".U
def ImmLDSP = "b00001".U
def ImmSWSP = "b00010".U
def ImmSDSP = "b00011".U
def ImmSW = "b00100".U
def ImmSD = "b00101".U
def ImmLW = "b00110".U
def ImmLD = "b00111".U
def ImmJ = "b01000".U
def ImmB = "b01001".U
def ImmLI = "b01010".U
def ImmLUI = "b01011".U
def ImmADDI = "b01100".U
def ImmADDI16SP = "b01101".U
def ImmADD4SPN = "b01110".U
// REG src
def DtCare = "b0000".U // reg x0
def REGrs = "b0011".U
def REGrt = "b0001".U
def REGrd = "b0010".U
def REGrs1 = "b0100".U
def REGrs2 = "b0101".U
def REGrs1p = "b0110".U
def REGrs2p = "b0111".U
def REGx1 = "b1000".U
def REGx2 = "b1001".U
}
object RVCInstr extends HasInstrType with HasRVCConst {
// RVC 00
// def C_XX = BitPat("b????????????????_???_?_10_987_65_432_10")
def C_ILLEGAL = BitPat("b0000000000000000_000_0_00_000_00_000_00")
def C_ADDI4SPN = BitPat("b????????????????_000_?_??_???_??_???_00")
def C_FLD = BitPat("b????????????????_001_?_??_???_??_???_00")
// def C_LQ = BitPat("b????????????????_001_?_??_???_??_???_00")
def C_LW = BitPat("b????????????????_010_?_??_???_??_???_00")
// def C_FLW = BitPat("b????????????????_011_?_??_???_??_???_00") // RV32FC Only
def C_LD = BitPat("b????????????????_011_?_??_???_??_???_00")
// def C_LI = BitPat("b????????????????_100_?_??_???_??_???_00") //reserved
def C_FSD = BitPat("b????????????????_101_?_??_???_??_???_00")
// def C_SQ = BitPat("b????????????????_101_?_??_???_??_???_00")
def C_SW = BitPat("b????????????????_110_?_??_???_??_???_00")
// def C_FSW = BitPat("b????????????????_111_?_??_???_??_???_00") // RV32FC Only
def C_SD = BitPat("b????????????????_111_?_??_???_??_???_00")
// RVC 01
def C_NOP = BitPat("b????????????????_000_?_00_000_??_???_01")
def C_ADDI = BitPat("b????????????????_000_?_??_???_??_???_01")
// def C_JAL = BitPat("b????????????????_001_?_??_???_??_???_01")
def C_ADDIW = BitPat("b????????????????_001_?_??_???_??_???_01")
def C_LI = BitPat("b????????????????_010_?_??_???_??_???_01")
def C_ADDI16SP= BitPat("b????????????????_011_?_00_010_??_???_01")
def C_LUI = BitPat("b????????????????_011_?_??_???_??_???_01")
def C_SRLI = BitPat("b????????????????_100_?_00_???_??_???_01")
// def C_SRLI64 = BitPat("b????????????????_100_0_01_???_00_000_01")
def C_SRAI = BitPat("b????????????????_100_?_01_???_??_???_01")
// def C_SAI64 = BitPat("b????????????????_100_0_01_???_00_000_01")
def C_ANDI = BitPat("b????????????????_100_?_10_???_??_???_01")
def C_SUB = BitPat("b????????????????_100_0_11_???_00_???_01")
def C_XOR = BitPat("b????????????????_100_0_11_???_01_???_01")
def C_OR = BitPat("b????????????????_100_0_11_???_10_???_01")
def C_AND = BitPat("b????????????????_100_0_11_???_11_???_01")
def C_SUBW = BitPat("b????????????????_100_1_11_???_00_???_01")
def C_ADDW = BitPat("b????????????????_100_1_11_???_01_???_01")
// def C_RES = BitPat("b????????????????_100_1_11_???_??_???_01")
// def C_RES = BitPat("b????????????????_100_1_11_???_??_???_01")
def C_J = BitPat("b????????????????_101_?_??_???_??_???_01")
def C_BEQZ = BitPat("b????????????????_110_?_??_???_??_???_01")
def C_BNEZ = BitPat("b????????????????_111_?_??_???_??_???_01")
//RVC 11
def C_SLLI = BitPat("b????????????????_000_?_??_???_??_???_10")
// def C_SLLI64 = BitPat("b????????????????_000_0_??_???_00_000_10")
def C_FLDSP = BitPat("b????????????????_001_?_??_???_??_???_10")
// def C_LQSP = BitPat("b????????????????_001_?_??_???_??_???_10")
def C_LWSP = BitPat("b????????????????_010_?_??_???_??_???_10")
// def C_FLWSP = BitPat("b????????????????_011_?_??_???_??_???_10") // RV32FC Only
def C_LDSP = BitPat("b????????????????_011_?_??_???_??_???_10")
def C_JR = BitPat("b????????????????_100_0_??_???_00_000_10")
def C_MV = BitPat("b????????????????_100_0_??_???_??_???_10")
def C_EBREAK = BitPat("b????????????????_100_1_00_000_00_000_10")
def C_JALR = BitPat("b????????????????_100_1_??_???_00_000_10")
def C_ADD = BitPat("b????????????????_100_1_??_???_??_???_10")
def C_FSDSP = BitPat("b????????????????_101_?_??_???_??_???_10")
// def C_SQSP = BitPat("b????????????????_101_?_??_???_??_???_10")
def C_SWSP = BitPat("b????????????????_110_?_??_???_??_???_10")
// def C_FSWSP = BitPat("b????????????????_111_?_??_???_??_???_10") // RV32FC Only
def C_SDSP = BitPat("b????????????????_111_?_??_???_??_???_10")
// TODO: HINT
// TODO: RES
// def is_C_ADDI4SPN(op: UInt) = op(12,5) =/= 0.U
val table = Array(
C_ILLEGAL -> List(InstrN, FuType.csr, CSROpType.jmp),
C_ADDI4SPN -> List(InstrI, FuType.alu, ALUOpType.add),
C_FLD -> List(InstrFI, FuType.ldu, LSUOpType.ld),
C_LW -> List(InstrI, FuType.ldu, LSUOpType.lw),
C_LD -> List(InstrI, FuType.ldu, LSUOpType.ld),
C_FSD -> List(InstrFS, FuType.stu, LSUOpType.sd),
C_SW -> List(InstrS, FuType.stu, LSUOpType.sw),
C_SD -> List(InstrS, FuType.stu, LSUOpType.sd),
C_NOP -> List(InstrI, FuType.alu, ALUOpType.add),
C_ADDI -> List(InstrI, FuType.alu, ALUOpType.add),
// C_JAL -> List(InstrI, FuType.alu, ALUOpType.add),//RV32C only
C_ADDIW -> List(InstrI, FuType.alu, ALUOpType.addw),
C_LI -> List(InstrI, FuType.alu, ALUOpType.add),
C_ADDI16SP -> List(InstrI, FuType.alu, ALUOpType.add),
C_LUI -> List(InstrI, FuType.alu, ALUOpType.add),
C_SRLI -> List(InstrI, FuType.alu, ALUOpType.srl),
C_SRAI -> List(InstrI, FuType.alu, ALUOpType.sra),
C_ANDI -> List(InstrI, FuType.alu, ALUOpType.and),
C_SUB -> List(InstrR, FuType.alu, ALUOpType.sub),
C_XOR -> List(InstrR, FuType.alu, ALUOpType.xor),
C_OR -> List(InstrR, FuType.alu, ALUOpType.or),
C_AND -> List(InstrR, FuType.alu, ALUOpType.and),
C_SUBW -> List(InstrR, FuType.alu, ALUOpType.subw),
C_ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
C_J -> List(InstrJ, FuType.jmp, JumpOpType.jal),
C_BEQZ -> List(InstrB, FuType.alu, ALUOpType.beq),
C_BNEZ -> List(InstrB, FuType.alu, ALUOpType.bne),
C_SLLI -> List(InstrI, FuType.alu, ALUOpType.sll),
C_FLDSP -> List(InstrFI, FuType.ldu, LSUOpType.ld),
C_LWSP -> List(InstrI, FuType.ldu, LSUOpType.lw),
// C_FLWSP -> List(InstrI, FuType.alu, ALUOpType.add),
C_LDSP -> List(InstrI, FuType.ldu, LSUOpType.ld),
C_JR -> List(InstrI, FuType.jmp, JumpOpType.jalr),
C_MV -> List(InstrR, FuType.alu, ALUOpType.add),
C_EBREAK -> List(InstrI, FuType.alu, ALUOpType.add),
C_JALR -> List(InstrI, FuType.jmp, JumpOpType.jalr),
C_ADD -> List(InstrR, FuType.alu, ALUOpType.add),
C_FSDSP -> List(InstrFS, FuType.stu, LSUOpType.sd),
C_SWSP -> List(InstrS, FuType.stu, LSUOpType.sw),
// C_FSWSP -> List(InstrI, FuType.alu, ALUOpType.add),
C_SDSP -> List(InstrS, FuType.stu, LSUOpType.sd)
)
val cExtraTable = Array(
C_ADDI4SPN -> List(ImmADD4SPN, REGx2, DtCare, REGrs2p),
C_FLD -> List(ImmLD, REGrs1p, DtCare, REGrs2p),
C_LW -> List(ImmLW, REGrs1p, DtCare, REGrs2p),
C_LD -> List(ImmLD, REGrs1p, DtCare, REGrs2p),
C_FSD -> List(ImmSD, REGrs1p, REGrs2p, DtCare),
C_SW -> List(ImmSW, REGrs1p, REGrs2p, DtCare),
C_SD -> List(ImmSD, REGrs1p, REGrs2p, DtCare),
C_NOP -> List(ImmNone, DtCare, DtCare, DtCare),
C_ADDI -> List(ImmADDI, REGrd, DtCare, REGrd),
// C_JAL -> List(),
C_ADDIW -> List(ImmADDI, REGrd, DtCare, REGrd),
C_LI -> List(ImmLI, DtCare, DtCare, REGrd),
C_ADDI16SP -> List(ImmADDI16SP, REGx2, DtCare, REGx2),
C_LUI -> List(ImmLUI, DtCare, DtCare, REGrd),
C_SRLI -> List(ImmLI, REGrs1p, DtCare, REGrs1p),
C_SRAI -> List(ImmLI, REGrs1p, DtCare, REGrs1p),
C_ANDI -> List(ImmLI, REGrs1p, DtCare, REGrs1p),
C_SUB -> List(ImmNone, REGrs1p, REGrs2p, REGrs1p),
C_XOR -> List(ImmNone, REGrs1p, REGrs2p, REGrs1p),
C_OR -> List(ImmNone, REGrs1p, REGrs2p, REGrs1p),
C_AND -> List(ImmNone, REGrs1p, REGrs2p, REGrs1p),
C_SUBW -> List(ImmNone, REGrs1p, REGrs2p, REGrs1p),
C_ADDW -> List(ImmNone, REGrs1p, REGrs2p, REGrs1p),
C_J -> List(ImmJ, DtCare, DtCare, DtCare),
C_BEQZ -> List(ImmB, REGrs1p, DtCare, DtCare), // rd: x0
C_BNEZ -> List(ImmB, REGrs1p, DtCare, DtCare), // rd: x0
C_SLLI -> List(ImmLI, REGrd, DtCare, REGrd),
C_FLDSP -> List(ImmLDSP, REGx2, DtCare, REGrd),
// C_LQSP -> List(),
C_LWSP -> List(ImmLWSP, REGx2, DtCare, REGrd),
C_LDSP -> List(ImmLDSP, REGx2, DtCare, REGrd),
C_JR -> List(ImmNone, REGrs1, DtCare, DtCare),
C_MV -> List(ImmNone, REGrs2, DtCare, REGrd),
C_EBREAK -> List(ImmNone, DtCare, DtCare, DtCare), //not implemented
C_JALR -> List(ImmNone, REGrs1, DtCare, REGx1),
C_ADD -> List(ImmNone, REGrd, REGrs2, REGrd),
C_FSDSP -> List(ImmSDSP, REGx2, REGrs2, DtCare),
// C_SQSP -> List(),
C_SWSP -> List(ImmSWSP, REGx2, REGrs2, DtCare),
C_SDSP -> List(ImmSDSP, REGx2, REGrs2, DtCare)
)
//TODO: support pc = 2 aligned address
//TODO: branch predictor support pc = 2 align
}
package xiangshan.backend.decode.isa
import chisel3.util._
import xiangshan.HasXSParameter
import xiangshan.FuType._
import xiangshan.backend.decode._
import xiangshan.backend.LSUOpType
import xiangshan.backend.fu.fpu.FPUOpType._
object RVDInstr extends HasXSParameter with HasInstrType {
def FADD_D = BitPat("b0000001??????????????????1010011")
def FSUB_D = BitPat("b0000101??????????????????1010011")
def FMUL_D = BitPat("b0001001??????????????????1010011")
def FDIV_D = BitPat("b0001101??????????????????1010011")
def FSGNJ_D = BitPat("b0010001??????????000?????1010011")
def FSGNJN_D = BitPat("b0010001??????????001?????1010011")
def FSGNJX_D = BitPat("b0010001??????????010?????1010011")
def FMIN_D = BitPat("b0010101??????????000?????1010011")
def FMAX_D = BitPat("b0010101??????????001?????1010011")
def FCVT_S_D = BitPat("b010000000001?????????????1010011")
def FCVT_D_S = BitPat("b010000100000?????????????1010011")
def FSQRT_D = BitPat("b010110100000?????????????1010011")
def FLE_D = BitPat("b1010001??????????000?????1010011")
def FLT_D = BitPat("b1010001??????????001?????1010011")
def FEQ_D = BitPat("b1010001??????????010?????1010011")
def FCVT_W_D = BitPat("b110000100000?????????????1010011")
def FCVT_WU_D = BitPat("b110000100001?????????????1010011")
def FCVT_L_D = BitPat("b110000100010?????????????1010011")
def FCVT_LU_D = BitPat("b110000100011?????????????1010011")
def FMV_X_D = BitPat("b111000100000?????000?????1010011")
def FCLASS_D = BitPat("b111000100000?????001?????1010011")
def FCVT_D_W = BitPat("b110100100000?????????????1010011")
def FCVT_D_WU = BitPat("b110100100001?????????????1010011")
def FCVT_D_L = BitPat("b110100100010?????????????1010011")
def FCVT_D_LU = BitPat("b110100100011?????????????1010011")
def FMV_D_X = BitPat("b111100100000?????000?????1010011")
def FLD = BitPat("b?????????????????011?????0000111")
def FSD = BitPat("b?????????????????011?????0100111")
def FMADD_D = BitPat("b?????01??????????????????1000011")
def FMSUB_D = BitPat("b?????01??????????????????1000111")
def FNMSUB_D = BitPat("b?????01??????????????????1001011")
def FNMADD_D = BitPat("b?????01??????????????????1001111")
val table = Array(
FLD -> List(InstrFI, ldu, LSUOpType.ld),
FSD -> List(InstrFS, stu, LSUOpType.sd),
// FR
FADD_D -> List(InstrFR, fmac, fadd),
FSUB_D -> List(InstrFR, fmac, fsub),
FMUL_D -> List(InstrFR, fmac, fmul),
FDIV_D -> List(InstrFR, fmisc, fdiv),
FMIN_D -> List(InstrFR, fmisc, fmin),
FMAX_D -> List(InstrFR, fmisc, fmax),
FSGNJ_D -> List(InstrFR, fmisc, fsgnj),
FSGNJN_D -> List(InstrFR, fmisc, fsgnjn),
FSGNJX_D -> List(InstrFR, fmisc, fsgnjx),
FSQRT_D -> List(InstrFR, fmisc, fsqrt),
FMADD_D -> List(InstrFR, fmac, fmadd),
FNMADD_D -> List(InstrFR, fmac, fnmadd),
FMSUB_D -> List(InstrFR, fmac, fmsub),
FNMSUB_D -> List(InstrFR, fmac, fnmsub),
FCVT_S_D -> List(InstrFR, fmisc, d2s),
FCVT_D_S -> List(InstrFR, fmisc, s2d),
// FtoG
FCLASS_D -> List(InstrFtoG, fmisc, fclass),
FMV_X_D -> List(InstrFtoG, fmisc, fmv_f2i),
FCVT_W_D -> List(InstrFtoG, fmisc, f2w),
FCVT_WU_D -> List(InstrFtoG, fmisc, f2wu),
FCVT_L_D -> List(InstrFtoG, fmisc, f2l),
FCVT_LU_D -> List(InstrFtoG, fmisc, f2lu),
FLE_D -> List(InstrFtoG, fmisc, fle),
FLT_D -> List(InstrFtoG, fmisc, flt),
FEQ_D -> List(InstrFtoG, fmisc, feq),
// GtoF
FMV_D_X -> List(InstrGtoF, i2f, fmv_i2f),
FCVT_D_W -> List(InstrGtoF, i2f, w2f),
FCVT_D_WU -> List(InstrGtoF, i2f, wu2f),
FCVT_D_L -> List(InstrGtoF, i2f, l2f),
FCVT_D_LU -> List(InstrGtoF, i2f, lu2f)
)
}
package xiangshan.backend.decode.isa
import chisel3.util._
import xiangshan.backend._
import xiangshan.HasXSParameter
import xiangshan.FuType._
import xiangshan.backend.decode._
import xiangshan.backend.fu.fpu.FPUOpType._
object RVFInstr extends HasXSParameter with HasInstrType {
def FLW = BitPat("b?????????????????010?????0000111")
def FSW = BitPat("b?????????????????010?????0100111")
def FADD_S = BitPat("b0000000??????????????????1010011")
def FSUB_S = BitPat("b0000100??????????????????1010011")
def FMUL_S = BitPat("b0001000??????????????????1010011")
def FDIV_S = BitPat("b0001100??????????????????1010011")
def FSGNJ_S = BitPat("b0010000??????????000?????1010011")
def FSGNJN_S = BitPat("b0010000??????????001?????1010011")
def FSGNJX_S = BitPat("b0010000??????????010?????1010011")
def FMIN_S = BitPat("b0010100??????????000?????1010011")
def FMAX_S = BitPat("b0010100??????????001?????1010011")
def FSQRT_S = BitPat("b010110000000?????????????1010011")
def FLE_S = BitPat("b1010000??????????000?????1010011")
def FLT_S = BitPat("b1010000??????????001?????1010011")
def FEQ_S = BitPat("b1010000??????????010?????1010011")
def FCVT_W_S = BitPat("b110000000000?????????????1010011")
def FCVT_WU_S = BitPat("b110000000001?????????????1010011")
def FCVT_L_S = BitPat("b110000000010?????????????1010011")
def FCVT_LU_S = BitPat("b110000000011?????????????1010011")
def FMV_X_W = BitPat("b111000000000?????000?????1010011")
def FCLASS_S = BitPat("b111000000000?????001?????1010011")
def FCVT_S_W = BitPat("b110100000000?????????????1010011")
def FCVT_S_WU = BitPat("b110100000001?????????????1010011")
def FCVT_S_L = BitPat("b110100000010?????????????1010011")
def FCVT_S_LU = BitPat("b110100000011?????????????1010011")
def FMV_W_X = BitPat("b111100000000?????000?????1010011")
def FMADD_S = BitPat("b?????00??????????????????1000011")
def FMSUB_S = BitPat("b?????00??????????????????1000111")
def FNMSUB_S = BitPat("b?????00??????????????????1001011")
def FNMADD_S = BitPat("b?????00??????????????????1001111")
val table = Array(
FLW -> List(InstrFI, ldu, LSUOpType.flw),
FSW -> List(InstrFS, stu, LSUOpType.sw),
// FR
FADD_S -> List(InstrFR, fmac, fadd),
FSUB_S -> List(InstrFR, fmac, fsub),
FMUL_S -> List(InstrFR, fmac, fmul),
FDIV_S -> List(InstrFR, fmisc, fdiv),
FMIN_S -> List(InstrFR, fmisc, fmin),
FMAX_S -> List(InstrFR, fmisc, fmax),
FSGNJ_S -> List(InstrFR, fmisc, fsgnj),
FSGNJN_S -> List(InstrFR, fmisc, fsgnjn),
FSGNJX_S -> List(InstrFR, fmisc, fsgnjx),
FSQRT_S -> List(InstrFR, fmisc, fsqrt),
FMADD_S -> List(InstrFR, fmac, fmadd),
FNMADD_S -> List(InstrFR, fmac, fnmadd),
FMSUB_S -> List(InstrFR, fmac, fmsub),
FNMSUB_S -> List(InstrFR, fmac, fnmsub),
// F -> G
FCLASS_S -> List(InstrFtoG, fmisc, fclass),
FMV_X_W -> List(InstrFtoG, fmisc, fmv_f2i),
FCVT_W_S -> List(InstrFtoG, fmisc, f2w),
FCVT_WU_S -> List(InstrFtoG, fmisc, f2wu),
FCVT_L_S -> List(InstrFtoG, fmisc, f2l),
FCVT_LU_S -> List(InstrFtoG, fmisc, f2lu),
FLE_S -> List(InstrFtoG, fmisc, fle),
FLT_S -> List(InstrFtoG, fmisc, flt),
FEQ_S -> List(InstrFtoG, fmisc, feq),
// G -> F
FMV_W_X -> List(InstrGtoF, i2f, fmv_i2f),
FCVT_S_W -> List(InstrGtoF, i2f, w2f),
FCVT_S_WU -> List(InstrGtoF, i2f, wu2f),
FCVT_S_L -> List(InstrGtoF, i2f, l2f),
FCVT_S_LU -> List(InstrGtoF, i2f, lu2f)
)
}
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.{FuType, HasXSParameter}
import xiangshan.backend.decode._
import xiangshan.backend._
object RV32I_ALUInstr extends HasInstrType with HasXSParameter {
def ADDI = BitPat("b????????????_?????_000_?????_0010011")
def SLLI = if (XLEN == 32) BitPat("b0000000?????_?????_001_?????_0010011")
else BitPat("b000000??????_?????_001_?????_0010011")
def SLTI = BitPat("b????????????_?????_010_?????_0010011")
def SLTIU = BitPat("b????????????_?????_011_?????_0010011")
def XORI = BitPat("b????????????_?????_100_?????_0010011")
def SRLI = if (XLEN == 32) BitPat("b0000000?????_?????_101_?????_0010011")
else BitPat("b000000??????_?????_101_?????_0010011")
def ORI = BitPat("b????????????_?????_110_?????_0010011")
def ANDI = BitPat("b????????????_?????_111_?????_0010011")
def SRAI = if (XLEN == 32) BitPat("b0100000?????_?????_101_?????_0010011")
else BitPat("b010000??????_?????_101_?????_0010011")
def ADD = BitPat("b0000000_?????_?????_000_?????_0110011")
def SLL = BitPat("b0000000_?????_?????_001_?????_0110011")
def SLT = BitPat("b0000000_?????_?????_010_?????_0110011")
def SLTU = BitPat("b0000000_?????_?????_011_?????_0110011")
def XOR = BitPat("b0000000_?????_?????_100_?????_0110011")
def SRL = BitPat("b0000000_?????_?????_101_?????_0110011")
def OR = BitPat("b0000000_?????_?????_110_?????_0110011")
def AND = BitPat("b0000000_?????_?????_111_?????_0110011")
def SUB = BitPat("b0100000_?????_?????_000_?????_0110011")
def SRA = BitPat("b0100000_?????_?????_101_?????_0110011")
def AUIPC = BitPat("b????????????????????_?????_0010111")
def LUI = BitPat("b????????????????????_?????_0110111")
val table = Array(
ADDI -> List(InstrI, FuType.alu, ALUOpType.add),
SLLI -> List(InstrI, FuType.alu, ALUOpType.sll),
SLTI -> List(InstrI, FuType.alu, ALUOpType.slt),
SLTIU -> List(InstrI, FuType.alu, ALUOpType.sltu),
XORI -> List(InstrI, FuType.alu, ALUOpType.xor),
SRLI -> List(InstrI, FuType.alu, ALUOpType.srl),
ORI -> List(InstrI, FuType.alu, ALUOpType.or ),
ANDI -> List(InstrI, FuType.alu, ALUOpType.and),
SRAI -> List(InstrI, FuType.alu, ALUOpType.sra),
ADD -> List(InstrR, FuType.alu, ALUOpType.add),
SLL -> List(InstrR, FuType.alu, ALUOpType.sll),
SLT -> List(InstrR, FuType.alu, ALUOpType.slt),
SLTU -> List(InstrR, FuType.alu, ALUOpType.sltu),
XOR -> List(InstrR, FuType.alu, ALUOpType.xor),
SRL -> List(InstrR, FuType.alu, ALUOpType.srl),
OR -> List(InstrR, FuType.alu, ALUOpType.or ),
AND -> List(InstrR, FuType.alu, ALUOpType.and),
SUB -> List(InstrR, FuType.alu, ALUOpType.sub),
SRA -> List(InstrR, FuType.alu, ALUOpType.sra),
AUIPC -> List(InstrU, FuType.alu, ALUOpType.add),
LUI -> List(InstrU, FuType.alu, ALUOpType.add)
)
}
object RV32I_BRUInstr extends HasInstrType {
def JAL = BitPat("b????????????????????_?????_1101111")
def JALR = BitPat("b????????????_?????_000_?????_1100111")
def BNE = BitPat("b???????_?????_?????_001_?????_1100011")
def BEQ = BitPat("b???????_?????_?????_000_?????_1100011")
def BLT = BitPat("b???????_?????_?????_100_?????_1100011")
def BGE = BitPat("b???????_?????_?????_101_?????_1100011")
def BLTU = BitPat("b???????_?????_?????_110_?????_1100011")
def BGEU = BitPat("b???????_?????_?????_111_?????_1100011")
val table = Array(
JAL -> List(InstrJ, FuType.jmp, JumpOpType.jal),
JALR -> List(InstrI, FuType.jmp, JumpOpType.jalr),
BEQ -> List(InstrB, FuType.alu, ALUOpType.beq),
BNE -> List(InstrB, FuType.alu, ALUOpType.bne),
BLT -> List(InstrB, FuType.alu, ALUOpType.blt),
BGE -> List(InstrB, FuType.alu, ALUOpType.bge),
BLTU -> List(InstrB, FuType.alu, ALUOpType.bltu),
BGEU -> List(InstrB, FuType.alu, ALUOpType.bgeu)
)
val bruFuncTobtbTypeTable = List(
ALUOpType.beq -> BTBtype.B,
ALUOpType.bne -> BTBtype.B,
ALUOpType.blt -> BTBtype.B,
ALUOpType.bge -> BTBtype.B,
ALUOpType.bltu -> BTBtype.B,
ALUOpType.bgeu -> BTBtype.B,
JumpOpType.call -> BTBtype.J,
JumpOpType.ret -> BTBtype.R,
JumpOpType.jal -> BTBtype.J,
JumpOpType.jalr -> BTBtype.I
)
}
object RV32I_LSUInstr extends HasInstrType {
def LB = BitPat("b????????????_?????_000_?????_0000011")
def LH = BitPat("b????????????_?????_001_?????_0000011")
def LW = BitPat("b????????????_?????_010_?????_0000011")
def LBU = BitPat("b????????????_?????_100_?????_0000011")
def LHU = BitPat("b????????????_?????_101_?????_0000011")
def SB = BitPat("b???????_?????_?????_000_?????_0100011")
def SH = BitPat("b???????_?????_?????_001_?????_0100011")
def SW = BitPat("b???????_?????_?????_010_?????_0100011")
val table = Array(
LB -> List(InstrI, FuType.ldu, LSUOpType.lb ),
LH -> List(InstrI, FuType.ldu, LSUOpType.lh ),
LW -> List(InstrI, FuType.ldu, LSUOpType.lw ),
LBU -> List(InstrI, FuType.ldu, LSUOpType.lbu),
LHU -> List(InstrI, FuType.ldu, LSUOpType.lhu),
SB -> List(InstrS, FuType.stu, LSUOpType.sb ),
SH -> List(InstrS, FuType.stu, LSUOpType.sh ),
SW -> List(InstrS, FuType.stu, LSUOpType.sw )
)
}
object RV64IInstr extends HasInstrType {
def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011")
def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011")
def SRLIW = BitPat("b0000000_?????_?????_101_?????_0011011")
def SRAIW = BitPat("b0100000_?????_?????_101_?????_0011011")
def SLLW = BitPat("b0000000_?????_?????_001_?????_0111011")
def SRLW = BitPat("b0000000_?????_?????_101_?????_0111011")
def SRAW = BitPat("b0100000_?????_?????_101_?????_0111011")
def ADDW = BitPat("b0000000_?????_?????_000_?????_0111011")
def SUBW = BitPat("b0100000_?????_?????_000_?????_0111011")
def LWU = BitPat("b???????_?????_?????_110_?????_0000011")
def LD = BitPat("b???????_?????_?????_011_?????_0000011")
def SD = BitPat("b???????_?????_?????_011_?????_0100011")
val table = Array(
ADDIW -> List(InstrI, FuType.alu, ALUOpType.addw),
SLLIW -> List(InstrI, FuType.alu, ALUOpType.sllw),
SRLIW -> List(InstrI, FuType.alu, ALUOpType.srlw),
SRAIW -> List(InstrI, FuType.alu, ALUOpType.sraw),
SLLW -> List(InstrR, FuType.alu, ALUOpType.sllw),
SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw),
SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw),
ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
SUBW -> List(InstrR, FuType.alu, ALUOpType.subw),
LWU -> List(InstrI, FuType.ldu, LSUOpType.lwu),
LD -> List(InstrI, FuType.ldu, LSUOpType.ld ),
SD -> List(InstrS, FuType.stu, LSUOpType.sd)
)
}
object RVIInstr extends HasXSParameter {
val table = RV32I_ALUInstr.table ++ RV32I_BRUInstr.table ++ RV32I_LSUInstr.table ++
(if (XLEN == 64) RV64IInstr.table else Nil)
}
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.{FuType, HasXSParameter}
import xiangshan.backend.decode._
import xiangshan.backend.MDUOpType
object RV32MInstr extends HasInstrType with HasXSParameter {
def MUL = BitPat("b0000001_?????_?????_000_?????_0110011")
def MULH = BitPat("b0000001_?????_?????_001_?????_0110011")
def MULHSU = BitPat("b0000001_?????_?????_010_?????_0110011")
def MULHU = BitPat("b0000001_?????_?????_011_?????_0110011")
def DIV = BitPat("b0000001_?????_?????_100_?????_0110011")
def DIVU = BitPat("b0000001_?????_?????_101_?????_0110011")
def REM = BitPat("b0000001_?????_?????_110_?????_0110011")
def REMU = BitPat("b0000001_?????_?????_111_?????_0110011")
def MULW = BitPat("b0000001_?????_?????_000_?????_0111011")
def DIVW = BitPat("b0000001_?????_?????_100_?????_0111011")
def DIVUW = BitPat("b0000001_?????_?????_101_?????_0111011")
def REMW = BitPat("b0000001_?????_?????_110_?????_0111011")
def REMUW = BitPat("b0000001_?????_?????_111_?????_0111011")
val mulTable = Array(
MUL -> List(InstrR, FuType.mul, MDUOpType.mul),
MULH -> List(InstrR, FuType.mul, MDUOpType.mulh),
MULHSU -> List(InstrR, FuType.mul, MDUOpType.mulhsu),
MULHU -> List(InstrR, FuType.mul, MDUOpType.mulhu)
)
val divTable = Array(
DIV -> List(InstrR, FuType.div, MDUOpType.div),
DIVU -> List(InstrR, FuType.div, MDUOpType.divu),
REM -> List(InstrR, FuType.div, MDUOpType.rem),
REMU -> List(InstrR, FuType.div, MDUOpType.remu)
)
val table = mulTable ++ (if (HasDiv) divTable else Nil)
}
object RV64MInstr extends HasInstrType with HasXSParameter {
def MULW = BitPat("b0000001_?????_?????_000_?????_0111011")
def DIVW = BitPat("b0000001_?????_?????_100_?????_0111011")
def DIVUW = BitPat("b0000001_?????_?????_101_?????_0111011")
def REMW = BitPat("b0000001_?????_?????_110_?????_0111011")
def REMUW = BitPat("b0000001_?????_?????_111_?????_0111011")
val mulTable = Array(
MULW -> List(InstrR, FuType.mul, MDUOpType.mulw)
)
val divTable = Array(
DIVW -> List(InstrR, FuType.div, MDUOpType.divw),
DIVUW -> List(InstrR, FuType.div, MDUOpType.divuw),
REMW -> List(InstrR, FuType.div, MDUOpType.remw),
REMUW -> List(InstrR, FuType.div, MDUOpType.remuw)
)
val table = mulTable ++ (if (HasDiv) divTable else Nil)
}
object RVMInstr extends HasXSParameter {
val table = RV32MInstr.table ++ (if (XLEN == 64) RV64MInstr.table else Nil)
}
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend._
import xiangshan.backend.decode.HasInstrType
object RVZicsrInstr extends HasInstrType {
def CSRRW = BitPat("b????????????_?????_001_?????_1110011")
def CSRRS = BitPat("b????????????_?????_010_?????_1110011")
def CSRRC = BitPat("b????????????_?????_011_?????_1110011")
def CSRRWI = BitPat("b????????????_?????_101_?????_1110011")
def CSRRSI = BitPat("b????????????_?????_110_?????_1110011")
def CSRRCI = BitPat("b????????????_?????_111_?????_1110011")
val table = Array(
CSRRW -> List(InstrI, FuType.csr, CSROpType.wrt),
CSRRS -> List(InstrI, FuType.csr, CSROpType.set),
CSRRC -> List(InstrI, FuType.csr, CSROpType.clr),
CSRRWI -> List(InstrI, FuType.csr, CSROpType.wrti),
CSRRSI -> List(InstrI, FuType.csr, CSROpType.seti),
CSRRCI -> List(InstrI, FuType.csr, CSROpType.clri)
)
}
package xiangshan.backend.decode.isa
import chisel3._
import chisel3.util._
import xiangshan.FuType
import xiangshan.backend.FenceOpType
import xiangshan.backend.decode._
import xiangshan.backend.decode.isa.RV64IInstr.InstrU
object RVZifenceiInstr extends HasInstrType {
def FENCEI = BitPat("b000000000000_00000_001_00000_0001111")
// fixme: add rvzifencei inst
val table = Array(
FENCEI -> List(InstrU, FuType.fence, FenceOpType.fencei)
)
}
\ No newline at end of file
......@@ -24,7 +24,9 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
val s_invalid :: s_valid:: Nil = Enum(2)
// queue data array
val uopEntries = Mem(size, new MicroOp)
val dataModule = Module(new DataModuleTemplate(new MicroOp, size, deqnum, enqnum))
val roqIdxEntries = Reg(Vec(size, new RoqPtr))
val debug_uopEntries = Mem(size, new MicroOp)
val stateEntries = RegInit(VecInit(Seq.fill(size)(s_invalid)))
// head: first valid entry (dispatched entry)
......@@ -55,10 +57,16 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
*/
// enqueue: from s_invalid to s_valid
io.enq.canAccept := canEnqueue
dataModule.io.wen := VecInit((0 until enqnum).map(_ => false.B))
dataModule.io.waddr := DontCare
dataModule.io.wdata := VecInit(io.enq.req.map(_.bits))
for (i <- 0 until enqnum) {
when (io.enq.req(i).valid && canActualEnqueue) {
dataModule.io.wen(i) := true.B
val sel = if (i == 0) 0.U else PopCount(io.enq.req.take(i).map(_.valid))
uopEntries(tailPtr(sel).value) := io.enq.req(i).bits
dataModule.io.waddr(i) := tailPtr(sel).value
roqIdxEntries(tailPtr(sel).value) := io.enq.req(i).bits.roqIdx
debug_uopEntries(tailPtr(sel).value) := io.enq.req(i).bits
stateEntries(tailPtr(sel).value) := s_valid
}
}
......@@ -75,14 +83,14 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
// redirect: cancel uops currently in the queue
val needCancel = Wire(Vec(size, Bool()))
for (i <- 0 until size) {
needCancel(i) := stateEntries(i) =/= s_invalid && uopEntries(i.U).roqIdx.needFlush(io.redirect)
needCancel(i) := stateEntries(i) =/= s_invalid && roqIdxEntries(i).needFlush(io.redirect)
when (needCancel(i)) {
stateEntries(i) := s_invalid
}
XSInfo(needCancel(i), p"valid entry($i)(pc = ${Hexadecimal(uopEntries(i).cf.pc)}) " +
p"roqIndex 0x${Hexadecimal(uopEntries(i).roqIdx.asUInt)} " +
XSInfo(needCancel(i), p"valid entry($i)(pc = ${Hexadecimal(debug_uopEntries(i).cf.pc)}) " +
p"roqIndex ${roqIdxEntries(i)} " +
p"cancelled with redirect roqIndex 0x${Hexadecimal(io.redirect.bits.roqIdx.asUInt)}\n")
}
......@@ -175,8 +183,11 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
* Part 3: set output and input
*/
// TODO: remove this when replay moves to roq
dataModule.io.raddr := VecInit(headPtr.map(_.value))
for (i <- 0 until deqnum) {
io.deq(i).bits := uopEntries(headPtr(i).value)
io.deq(i).bits := dataModule.io.rdata(i)
io.deq(i).bits.roqIdx := roqIdxEntries(headPtr(i).value)
// io.deq(i).bits := debug_uopEntries(headPtr(i).value)
// do not dequeue when io.redirect valid because it may cause dispatchPtr work improperly
io.deq(i).valid := stateEntries(headPtr(i).value) === s_valid && !lastCycleMisprediction
}
......
......@@ -4,9 +4,7 @@ import chisel3._
import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend.decode.XSTrap
import xiangshan.backend.roq.RoqPtr
import xiangshan.mem._
import xiangshan.backend.fu.HasCSRConst
import chisel3.ExcitingUtils._
......
......@@ -3,9 +3,7 @@ package xiangshan.frontend
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.backend.ALUOpType
import utils._
import xiangshan.backend.decode.XSTrap
import chisel3.experimental.chiselName
trait BimParams extends HasXSParameter {
......
......@@ -6,7 +6,6 @@ import chisel3.util._
import xiangshan._
import xiangshan.backend.ALUOpType
import utils._
import xiangshan.backend.decode.XSTrap
import chisel3.experimental.chiselName
......
......@@ -4,9 +4,6 @@ import chisel3._
import chisel3.util._
import device.RAMHelper
import xiangshan._
import utils.{GTimer, XSDebug}
import xiangshan.backend.decode.isa
import xiangshan.backend.decode.Decoder
trait HasICacheConst { this: XSModule =>
// 4-byte align * FetchWidth-inst
......
#include <csignal>
#include "common.h"
#include "emu.h"
int assert_count = 0;
static pthread_mutex_t assert_mutex;
int signal_num = 0;
void assert_init() {
pthread_mutex_init(&assert_mutex, 0);
......@@ -18,3 +19,7 @@ extern "C" void xs_assert(long long line) {
assert_count++;
pthread_mutex_unlock(&assert_mutex);
}
void sig_handler(int signo) {
signal_num = signo;
}
......@@ -26,4 +26,7 @@ extern int assert_count;
void assert_init();
void assert_finish();
extern int signal_num;
void sig_handler(int signo);
#endif // __COMMON_H
......@@ -266,16 +266,6 @@ inline void Emulator::single_cycle() {
cycles ++;
}
#if VM_COVERAGE == 1
uint64_t *max_cycle_ptr = NULL;
// when interrupted, we set max_cycle to zero
// so that the emulator will stop gracefully
void sig_handler(int signo) {
if (signo == SIGINT)
*max_cycle_ptr = 0;
}
#endif
uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
extern void poll_event(void);
extern uint32_t uptime(void);
......@@ -299,10 +289,7 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
// we dump coverage into files at the end
// since we are not sure when an emu will stop
// we distinguish multiple dat files by emu start time
time_t start_time = time(NULL);
max_cycle_ptr = &max_cycle;
if (signal(SIGINT, sig_handler) == SIG_ERR)
printf("\ncan't catch SIGINT\n");
time_t coverage_start_time = time(NULL);
#endif
while (!Verilated::gotFinish() && trapCode == STATE_RUNNING) {
......@@ -310,16 +297,21 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
trapCode = STATE_LIMIT_EXCEEDED;
break;
}
single_cycle();
max_cycle --;
if (dut_ptr->io_trap_valid) trapCode = dut_ptr->io_trap_code;
if (assert_count > 0) {
difftest_display(dut_ptr->io_difftest_priviledgeMode);
eprintf("The simulation stopped. There might be some assertion failed.\n");
trapCode = STATE_ABORT;
break;
}
if (signal_num != 0) {
trapCode = STATE_SIG;
break;
}
single_cycle();
max_cycle --;
if (dut_ptr->io_trap_valid) trapCode = dut_ptr->io_trap_code;
if (trapCode != STATE_RUNNING) break;
if (lastcommit - max_cycle > stuck_limit && hascommit) {
......@@ -412,7 +404,7 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
#endif
#if VM_COVERAGE == 1
save_coverage(start_time);
save_coverage(coverage_start_time);
#endif
display_trapinfo();
......@@ -479,6 +471,9 @@ void Emulator::display_trapinfo() {
case STATE_LIMIT_EXCEEDED:
eprintf(ANSI_COLOR_YELLOW "EXCEEDING CYCLE/INSTR LIMIT at pc = 0x%" PRIx64 "\n" ANSI_COLOR_RESET, pc);
break;
case STATE_SIG:
eprintf(ANSI_COLOR_YELLOW "SOME SIGNAL STOPS THE PROGRAM at pc = 0x%" PRIx64 "\n" ANSI_COLOR_RESET, pc);
break;
default:
eprintf(ANSI_COLOR_RED "Unknown trap code: %d\n", trapCode);
}
......
#ifndef __EMU_H
#define __EMU_H
#include "common.h"
#include "snapshot.h"
#include "VXSSimSoC.h"
......@@ -42,6 +45,7 @@ class Emulator {
STATE_BADTRAP = 1,
STATE_ABORT = 2,
STATE_LIMIT_EXCEEDED = 3,
STATE_SIG = 4,
STATE_RUNNING = -1
};
......@@ -75,3 +79,5 @@ public:
bool is_good_trap() { return trapCode == STATE_GOODTRAP; };
int get_trapcode() { return trapCode; }
};
#endif
#include "emu.h"
#include <functional>
#include <locale.h>
#include <csignal>
#include "emu.h"
static char mybuf[BUFSIZ];
......@@ -16,6 +17,10 @@ int main(int argc, const char** argv) {
// enable thousands separator for printf()
setlocale(LC_NUMERIC, "");
if (signal(SIGINT, sig_handler) == SIG_ERR) {
printf("\ncan't catch SIGINT\n");
}
auto emu = new Emulator(argc, argv);
get_sc_time_stamp = [&emu]() -> double {
......
package xiangshan.backend.decode
import xiangshan.CtrlFlow
import xiangshan.CfCtrl
import xiangshan.backend.fu.HasExceptionNO
import xiangshan.XSModule
import xiangshan.frontend.HasTageParameter
import chisel3._
import chisel3.util._
import org.scalatest._
import chiseltest._
import chisel3.experimental.BundleLiterals._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.must.Matchers
import chiseltest.ChiselScalatestTester
import scala.util.Random._
import scala.collection.mutable
import scala.io.Source.fromFile
import scala.io.BufferedSource
import xiangshan.SrcType
import xiangshan.FuType
class DualDecodeUnitDut extends XSModule {
val io = IO(new Bundle {
val in = Input(new CtrlFlow)
val out_ref = Output(new CfCtrl)
val out_dut = Output(new CfCtrl)
})
val ref = Module(new Decoder)
val dut = Module(new DecodeUnit)
ref.io.in := io.in
io.out_ref := ref.io.out
dut.io.enq.ctrl_flow := io.in
io.out_dut := dut.io.deq.cf_ctrl
}
class CtrlFlowGenerator(fileName: String) extends HasExceptionNO {
private var source: BufferedSource = _
private var instructions: Iterator[String] = _
var current_line: String = _
def init: Unit = {
source = fromFile(fileName)
instructions = source.getLines()
}
def close: Unit = source.close()
private val pattern = """[0-9a-z]{8,}:\s[0-9a-z]{8,}""".r
def getPcInstrPair: Option[Tuple2[Long, Long]] = {
instructions.hasNext match {
case true => { pattern.findFirstIn({
current_line = instructions.next()
current_line
}) match {
case None => getPcInstrPair
case Some(value) => Some(str2Tuple(value))
}}
case false => None
}
}
def str2Tuple(str: String): Tuple2[Long, Long] = {
val pair = str.split("""[\s]?:\s""")
require(pair.length == 2)
new Tuple2(java.lang.Long.parseLong(pair(0), 16), java.lang.Long.parseLong(pair(1), 16))
}
def genCtrlFlow(x: => CtrlFlow): Boolean = {
// read pc and instr from file
getPcInstrPair match {
case None => false
case Some(value) => genCtrlFlow(x, value._1, value._2)
}
}
def genCtrlFlow(x: => CtrlFlow, pc: Long, inst: Long): Boolean = {
x.instr.poke(inst.U)
x.pc.poke(pc.U)
x.crossPageIPFFix.poke(nextBoolean().B)
// input: instrPageFault -> true or false others: false
// output: may modify illegalInstr , others : false , instrPageFault: hold
x.exceptionVec.map(_.poke(false.B))
x.intrVec.map(_.poke(nextBoolean().B))
true
}
}
class DecodeUnitDiffTest
extends AnyFlatSpec
with ChiselScalatestTester
with Matchers
with BeforeAndAfterAllConfigMap
{
var file = "not set"
override protected def beforeAll(configMap: ConfigMap): Unit = {
if (configMap.get("file").isDefined) {
file = configMap.get("file").fold("parameter not found")(_.toString())
}
println(s"input file: ${file}")
}
"DecodeUnit" must "yield same output as old Decoder" in {
test(new DualDecodeUnitDut) { c =>
val generator = new CtrlFlowGenerator(file) // * use -Dfile=<path> to set input file
generator.init
while (generator.genCtrlFlow(c.io.in)) {
c.clock.step(1)
println(generator.current_line)
// 1. Ctrl Flow
// do not care about brUpdate and crossPageIPFFix and instr
c.io.out_dut.cf.pc.expect(c.io.out_ref.cf.pc.peek())
c.io.out_dut.cf.exceptionVec.indices.foreach(i => {
c.io.out_dut.cf.exceptionVec(i).expect(c.io.out_ref.cf.exceptionVec(i).peek())
})
c.io.out_dut.cf.intrVec.indices.foreach(i => {
c.io.out_dut.cf.intrVec(i).expect(c.io.out_ref.cf.intrVec(i).peek())
})
// 2. Ctrl Signals
// ignore isRVF and ldest and commitType
c.io.out_dut.ctrl.src1Type.expect(c.io.out_ref.ctrl.src1Type.peek())
c.io.out_dut.ctrl.src2Type.expect(c.io.out_ref.ctrl.src2Type.peek())
c.io.out_dut.ctrl.src3Type.expect(c.io.out_ref.ctrl.src3Type.peek())
c.io.out_dut.ctrl.lsrc1.expect(c.io.out_ref.ctrl.lsrc1.peek())
if (c.io.out_ref.ctrl.src2Type.peek() == SrcType.reg) {
c.io.out_dut.ctrl.lsrc2.expect(c.io.out_ref.ctrl.lsrc2.peek())
}
c.io.out_dut.ctrl.lsrc3.expect(c.io.out_ref.ctrl.lsrc3.peek())
// c.io.out_dut.ctrl.ldest.expect(c.io.out_ref.ctrl.ldest.peek())
c.io.out_dut.ctrl.fuType.expect(c.io.out_ref.ctrl.fuType.peek())
c.io.out_dut.ctrl.fuOpType.expect(c.io.out_ref.ctrl.fuOpType.peek())
c.io.out_dut.ctrl.rfWen.expect(c.io.out_ref.ctrl.rfWen.peek())
c.io.out_dut.ctrl.fpWen.expect(c.io.out_ref.ctrl.fpWen.peek())
c.io.out_dut.ctrl.isXSTrap.expect(c.io.out_ref.ctrl.isXSTrap.peek())
c.io.out_dut.ctrl.noSpecExec.expect(c.io.out_ref.ctrl.noSpecExec.peek())
c.io.out_dut.ctrl.blockBackward.expect(c.io.out_ref.ctrl.blockBackward.peek())
c.io.out_dut.ctrl.flushPipe.expect(c.io.out_ref.ctrl.flushPipe.peek())
if (c.io.out_ref.ctrl.fuType.peek() == FuType.fmac ||
c.io.out_ref.ctrl.fuType.peek() == FuType.fmisc ||
c.io.out_ref.ctrl.fuType.peek() == FuType.fDivSqrt) {
c.io.out_dut.ctrl.isRVF.expect(c.io.out_ref.ctrl.isRVF.peek())
}
if (c.io.out_ref.ctrl.src2Type.peek() == SrcType.imm) {
c.io.out_dut.ctrl.imm.expect(c.io.out_ref.ctrl.imm.peek())
}
c.io.out_dut.ctrl.commitType.expect(c.io.out_ref.ctrl.commitType.peek())
// 3. Branch Tag: ignore
}
generator.close
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册