iT邦幫忙

2021 iThome 鐵人賽

DAY 2
1
Software Development

猴子都寫得出來的 RISC-V CPU Emulator系列 第 24

RISC-V: R-type 小於指令

  • 分享至 

  • xImage
  •  

今天一樣是簡單的 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);
}
...

上一篇
RISC-V: R-type 位元運算指令
下一篇
RISC-V: R-type 位移指令
系列文
猴子都寫得出來的 RISC-V CPU Emulator31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言