iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0
Software Development

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

RISC-V: Memory Store 指令

  • 分享至 

  • xImage
  •  

昨天已經把 Memory Write 的功能做完了,
今天稍微輕鬆一點,就來完成 Memory Store 指令吧。

剛剛又發現 LH, LHU Test Binary Code 其實有 Misalignment Access 的 Bug,
如果有實做 Trap 就會發現了,
另外 Ececutable Enviroment Intergace (EEI),規範了 L/S 系列指令可以存取的範圍。
也可以規定 Misaligned Memory Access 是硬體有支援,
或者發生 Trap 讓軟體處理。

10/8 補充:Trap 的部分因為考量到存取的 Address Space 可以是 Memory Mapped Device,
可能有 Side Effect,規格書分成兩種 Exception 來處理,
一種是 address misalignment trap,另外一種是 fatal trap,

S-type

指令格式如下:

|31       25|24   20|19   15|14    12|11       7|6       0|
+---------------------------------------------------------+
| imm[11:5] |  rs2  |  rs1  | funct3 | imm[4:0] | opcode  |
+---------------------------------------------------------+

SB

Write(base + imm[11:0], src, 1)

|31       25|24   20|19   15|14    12|11       7|6       0|
+---------------------------------------------------------+
| imm[11:5] |  src  | base  |  000  | imm[4:0] | 0100011 |
+---------------------------------------------------------+

SH

Write(base + imm[11:0], src, 2)

|31       25|24   20|19   15|14    12|11       7|6       0|
+---------------------------------------------------------+
| imm[11:5] |  src  | base  |  001  | imm[4:0] | 0100011 |
+---------------------------------------------------------+

SW

Write(base + imm[11:0], src, 4)

|31       25|24   20|19   15|14    12|11       7|6       0|
+---------------------------------------------------------+
| imm[11:5] |  src  | base  |  010  | imm[4:0] | 0100011 |
+---------------------------------------------------------+

實際程式

github 頁面 Tag: ITDay16

為了準備今天的測試,順便修改了昨天的 LH, LHU,
意外發現昨天竟然整個 Binary Code 都寫錯了,竟然少了 func3 欄位!
可怕的是還意外的跑出正確的結果,在大家還沒發現之前趕快自己改掉!

這件事偶爾會發生,
雖然在寫 Unit Test 的過程中為了減少出錯機率,會盡量保持邏輯簡單,
但是因為是人寫的,還是會有錯誤的發生,
唯一的解決方案就是看到的當下趕快修好。

Unit Test 或者各種自動化測試並不是萬靈丹,
它只是幫助我們減少 80% 犯錯的機會而已,
那剩下的 20% 該怎麼辦?

就交給路過的猴子吧!

//memory.cpp
		0b000000000100'00000'001'00111'0000011, //LH x7 = sign_ext(read(4, 2))
		0b000000000100'00000'101'01000'0000011, //LHU x8 = read(4, 2)

指令實做的部分:

//executor.cpp
...
		case INSTRUCTION_DECODER_INTERFACE::STORE_OP:
			switch (instruction_decoder->get_func3()) {
				case INSTRUCTION_DECODER_INTERFACE::SB_FN3:
					SB_E();
					break;
				case INSTRUCTION_DECODER_INTERFACE::SH_FN3:
					SH_E();
					break;
				case INSTRUCTION_DECODER_INTERFACE::SW_FN3:
					SW_E();
					break;
				default:
					std::cout << "INVALID: Func3 in STORE_OP :" << instruction_decoder->get_func3() << std::endl;
					break;
			}
...
void EXECUTOR::SH_E()
{
	auto rs1 = instruction_decoder->get_rs1();
	auto rs2 = instruction_decoder->get_rs2();

	auto offset =  (instruction_decoder->get_imm(31, 25) << 5) |
	               (instruction_decoder->get_imm(11, 7) & 0x1F);
	auto addr = register_file->get_value_integer(rs1) + offset;
	address_space->write(addr, register_file->get_value_integer(rs2), 2);
...
}
...
//instructionDecoderInterface.h
...
		STORE_OP = 0b0100011,
...
		SB_FN3 = 0b000,
		SH_FN3 = 0b001,
		SW_FN3 = 0b010,
...

上一篇
RISC-V: Memory Load指令
下一篇
Computer Architecture: Memory Hierarchy
系列文
猴子都寫得出來的 RISC-V CPU Emulator31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言