RISC-V: Memory Store 指令

昨天已经把 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,
...

<<:  Chapter4 - Canvas背景动画(IV)把纷飞的落叶,通通抓回来当作收藏吧!

>>:  15 - Logs - 挖掘系统内部发生的状况 (3/4) - 透过 Filebeat 收集 Elastic Stack 中各种服务的细节资讯

创建App-上传图片

创建App-上传图片 本App中会使用多种不同的图片来显示不同的主题,所以上传不同图片来使用! 例如...

#27-微互动折线图动态!就是要比较才看得出结果啊 (D3.js)

前两天都是展现Data而已,今天来试做看看互动&换资料的动态! 折线图也是满常见的样式, 这次以非洲...

Day 16 留言是种互动!

好奇是知识的萌芽,萌芽之後,就要给予养分,让知识茁壮,没有养分的知识,只是一个没有办法萌芽的种子而已...

Day20 - 用 Ruby on Rails 抓台湾证券交易所资料-每日收盘行情

前言 这篇开始会有几篇是与「台湾证券交易所」有关,示范如何用 Ruby on Rails 来爬虫将资...

Android Studio初学笔记-Day25-ExpandableListVIew(1)

ExpandableListView 这是一个我个人认为稍微进阶的列表,因为它多了包覆一层的效果,不...