RISC-V: R-type 小於指令

今天一样是简单的 SLT、SLTU 指令实作,
并为了 Code Stream Logger 做准备,
唯一有趣的是遇到 g++ 未实做的 feature 导致编译错误,
只好改用别种方式实做。

R-type

指令格式如下:

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|  func7  |  rs2  |  rs1  | funct3 |  rd  | opcode  |
+---------------------------------------------------+

SLT

rd = rs1 < rs2 ? 1 : 0

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0000000   |  rs2  |  rs1  |  010   |  rd  | 0110011 |
+-------------------------------------------------------+

SLTU

rd = (uint32_t)rs1 < (uint32_t)rs2 ? 1 : 0

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0000000   |  rs2  |  rs1  |  011   |  rd  | 0110011 |
+-------------------------------------------------------+

实际程序

github 页面 Tag: ITDay24

RISC-V-TLM 的 Logger 设计不太适合接下来的模拟用途,
作者客制化每道指令的 Log 内容,为了可读性牺牲了一致性,
这样的设计也在维护上容易有一些小疏失
接下来实做的时候会尝试重新设计 Logger 的部分,
这次先把 Code Stream Logger 需要用到的指令和指令名称列出来。

Instruction Name 需要从数字一对一对应到字串,本来想用 std::array 做,
exactstep 类似,结果遇到了 g++ 很有礼貌的说:
sorry, unimplemented: non-trivial designated initializers not supported
先改用 std::map 实做。

//instructionDecoderInterface.h
...
	enum Instruction {
		ADDI_INSTRUCTION_ENUM,
		ANDI_INSTRUCTION_ENUM,
		ORI_INSTRUCTION_ENUM,
		XORI_INSTRUCTION_ENUM,
...
	std::map<Instruction, std::string> instruction_name_map = {
		{ADDI_INSTRUCTION_ENUM,"ADDI"},
		{ANDI_INSTRUCTION_ENUM,"ANDI"},
		{ORI_INSTRUCTION_ENUM,"ORI"},
		{XORI_INSTRUCTION_ENUM,"XORI"},
...

指令实作:

//instructionDecoderInterface.h
...
		SLT_FN3 = 0b010,
		SLTU_FN3 = 0b011,
...
		SLT_FN7 = 0b0000000,
		SLTU_FN7 = 0b0000000,
...
//executor.cpp
...
		case INSTRUCTION_DECODER_INTERFACE::SLT_FN3:
			SLT_E();
			//do not check FN7 for readibility, refactor in future
			break;
		case INSTRUCTION_DECODER_INTERFACE::SLTU_FN3:
			SLTU_E();
			//do not check FN7 for readibility, refactor in future
			break;
...
void EXECUTOR::SLT_E()
{
	auto rd = instruction_decoder->get_rd();
	auto rs1 = instruction_decoder->get_rs1();
	auto rs2 = instruction_decoder->get_rs2();

	auto value = register_file->get_value_integer(rs1) < register_file->get_value_integer(rs2) ? 1 : 0;
	register_file->set_value_integer(rd, value);
}

void EXECUTOR::SLTU_E()
{
	auto rd = instruction_decoder->get_rd();
	auto rs1 = instruction_decoder->get_rs1();
	auto rs2 = instruction_decoder->get_rs2();

	auto value = (uint32_t)register_file->get_value_integer(rs1) < (uint32_t)register_file->get_value_integer(rs2) ? 1 : 0;
	register_file->set_value_integer(rd, value);
}
...

<<:  [Day23] 第二十三章 - 学会laravel的query方法来filter资料(Query Builder)

>>:  DAY 25:Flyweight Pattern,节省空间的好帮手

Day 28:Diffie–Hellman演算法

一路到了铁人赛最後阶段,最後写两个完全不同但都蛮有趣的演算法。 我们之前写到SHA家族演算法可以用来...

【Day 27】Cmd 指令很乱,主办单位要不要管一下 (上) - Cmd 指令混淆

环境 Windows 10 21H1 System Monitor v13.01 前情提要 在【Da...

[iT铁人赛Day25]练习题(4)

今天来讲第四题练习题罗 其实自己练习到现在,自己的java也有一些些的进步 虽然还是有一些看不懂,甚...

[Day5] 策略买卖讯号回测

延续前一天的程序码,首先先把图片里的程序码搬到箭头的地方,固定前面放函数後面放程序,这样看起来比较清...

连续 30 天 玩玩看 ProtoPie - Day 10

今天要来进行使用者点击之後跳到下一页的行为,一样延续昨天使用的介面。 所以我们选择下方的按钮(Ge...