看到标题一定都猜到了,
相信大家对这几道指令都不陌生,这次实作的就是 ANDI、ORI、XORI,
对应到程序语言中,分别是 &、|、^ 的位元运算。
为了方便阅读,接下来章节都会列出指令格式。
指令格式如下:
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | funct3 | rd | pocode |
+-------------------------------------------+
rd = rs1 & imm
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | 111 | rd | 0010011 |
+-------------------------------------------+
rd = rs1 | imm
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | 110 | rd | 0010011 |
+-------------------------------------------+
rd = rs1 ^ imm
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | 100 | rd | 0010011 |
+-------------------------------------------+
没错,和这次实作的第一道指令一样,
这个指令也是致敬 XORI,
RISC-V 的 imm 运算前都会进行 sign extension,
只要填入 -1 ,就会变成:
rd = rs1 ^ (0xFFFF)
= ~rs1
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| -1 | rs1 | 100 | rd | 0010011 |
+-------------------------------------------+
github 页面 Tag: ITDay11
这次修了一个已知的小 Bug,
一开始在 Register File 其实没有实作 x0 Hard Wire to Zero 的功能。
导致写入 x0 实际上也是会把值存进去的,读取也会读取实际的值。
还有一个 Bug 在 Decoder 里面,留着明天处理,
答案其实在 Console 印出来的运算结果里面,大家可以先猜猜看罗。
太习惯平常的工作流程了,
开发没有 Unit Test 保护,写起来实在没什麽没安全感。
//register.cpp
void REGISTER::set_value_integer(unsigned int register_index, int32_t value)
{
if(register_index == 0)
return;
...
}
int32_t REGISTER::get_value_integer(unsigned int register_index)
{
if(register_index == 0)
return 0;
...
}
这次在 Decoder 新增了 Func3
,增加可读性。
也把 OP_IMM
改成 IMM_OP
,
让 vim 的 auto complete 能够更精准地提供选项。
//instructionDecoderInterface.h
enum Opcode {
IMM_OP = 0b0010011,
};
enum Func3 {
//IMM_OP
ADDI_FN3 = 0b000,
ANDI_FN3 = 0b111,
ORI_FN3 = 0b110,
XORI_FN3 = 0b100,
};
在 Executor 里面新增 ANDI、ORI、XORI 的实作,
另外把 if 用 switch 取代,减少重复性的程序码。
void EXECUTOR::execute()
{
switch (instruction_decoder->get_opcode()) {
case INSTRUCTION_DECODER_INTERFACE::IMM_OP:
switch (instruction_decoder->get_func3()) {
case INSTRUCTION_DECODER_INTERFACE::ADDI_FN3:
ADDI_E();
break;
case INSTRUCTION_DECODER_INTERFACE::ANDI_FN3:
ANDI_E();
break;
case INSTRUCTION_DECODER_INTERFACE::XORI_FN3:
ORI_E();
break;
case INSTRUCTION_DECODER_INTERFACE::ORI_FN3:
XORI_E();
break;
default:
std::cout << "INVALID: Func3 in IMM_OP :" << instruction_decoder->get_func3() << std::endl;
break;
}
break;
default:
std::cout << "INVALID: Opcode :" << instruction_decoder->get_opcode() << std::endl;
break;
}
}
$ make run
./simulator
SystemC 2.3.3-Accellera --- Sep 17 2021 22:09:07
Copyright (c) 1996-2018 by all Contributors,
ALL RIGHTS RESERVED
ADDI
rs1: 0
rd: 1
value: 1
ADDI
rs1: 1
rd: 2
value: 4096
ADDI
rs1: 0
rd: 0
value: 0
>>: Day25. Blue Prism让你远离挑灯夜战的日子 –BP自动登打订单
Unit Test 应用於 Async Code-2 - 用程序码讲故事(测试码 Exception...
Go(又称 Golang)是 Google 开发的程序语言,详细简介在 wiki 上都可以找得到。 ...
当一个函数被建立时,闭包就会被产生,虽然常见的闭包说明方式会使用巢状函数当作例子,这是最常见的例子没...
今日来介绍 solidity 里的 contracts。 contract contract 其实是...
开始接触 Gradle 的原因 身为一位 Kotlin 开发者,每天需要接触的就是 JVM 生态系的...