今天又發現新鮮的 Bug 拉!
我養蟲,蟲養我,
今天的我拯救昨天的我。
幸好 Code Base 還小,
不然每天猴肉測試實在不是辦法,
小猴子都快 Debug De 成老猴子了,
好想抽時間補 Unit Test 阿...
指令格式如下:
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | funct3 | rd | opcode |
+-------------------------------------------+
rd = rs1 << shamt
|31 25|24 20|19 15|14 12|11 7|6 0|
+-------------------------------------------------+
| 0 | shamt | rs1 | 001 | rd | 0010011 |
+-------------------------------------------------+
rd = (uint32_t) rs1 >> shamt
|31 25|24 20|19 15|14 12|11 7|6 0|
+-------------------------------------------------+
| 0 | shamt | rs1 | 101 | rd | 0010011 |
+-------------------------------------------------+
比較特別的是 opcode 和 funct3 都和 SRLI
一樣,
需要用 imm 的某個 bit 來判斷是哪一種。
rd = rs1 >> shamt
|31 25|24 20|19 15|14 12|11 7|6 0|
+-------------------------------------------------+
| 32 | shamt | rs1 | 101 | rd | 0010011 |
+-------------------------------------------------+
github 頁面 Tag: ITDay13
這次的問題是因為漏算了已經先左移的部分,
在跑 Test Binary Code 的 SLLI
會變成 shamt 每次都拿到 8,
修改結果如下:
int32_t INSTRUCTION_DECODER::get_imm(uint32_t end, uint32_t start)
{
return sc_dt::sc_int<32>(instruction_value) << (31-end) >> (31 - end + start);
}
三道指令內容都很單純是位移,比較特別的是 imm 有一部份用來當 shamnt,
另外一部分用來區別 SRLI
和 SRAI
。
//executor.cpp
...
case INSTRUCTION_DECODER_INTERFACE::SLLI_FN3:
SLLI_E();
break;
case INSTRUCTION_DECODER_INTERFACE::SRLI_FN3://same as INSTRUCTION_DECODER_INTERFACE::SRAI_FN3
if(instruction_decoder->get_imm(30, 30) == 0)
{
SRLI_E();
}
else
{
SRAI_E();
}
break;
...
void EXECUTOR::SLLI_E()
{
auto rs1 = instruction_decoder->get_rs1();
auto rd = instruction_decoder->get_rd();
auto value = register_file->get_value_integer(rs1) << (uint32_t) instruction_decoder->get_imm(24, 20);
register_file->set_value_integer(rd, value);
//TODO: just for test, move these to decoder and logger in future
...
}
void EXECUTOR::SRLI_E()
{
auto rs1 = instruction_decoder->get_rs1();
auto rd = instruction_decoder->get_rd();
auto value = (uint32_t) register_file->get_value_integer(rs1) >> (uint32_t) instruction_decoder->get_imm(24, 20);
register_file->set_value_integer(rd, value);
...
}
void EXECUTOR::SRAI_E()
{
auto rs1 = instruction_decoder->get_rs1();
auto rd = instruction_decoder->get_rd();
auto value = register_file->get_value_integer(rs1) >> (uint32_t) instruction_decoder->get_imm(24, 20);
register_file->set_value_integer(rd, value);
...
}
//instructionDecoderInterface.h
...
SLLI_FN3 = 0b001,
SRLI_FN3 = 0b101,
SRAI_FN3 = 0b101,
...
前面的不重要就省略,從 SLTIU
給值,
配合 SLLI
、SRLI
、SRAI
幾道指令區別不同運算結果,
最後的數值以 Signed Integer 表示。
$ make run
./simulator
SystemC 2.3.3-Accellera --- Sep 17 2021 22:09:07
Copyright (c) 1996-2018 by all Contributors,
ALL RIGHTS RESERVED
...
SLTIU
rs1: 2
rd: 2
value: 1
SLLI
rs1: 2
rd: 3
value: -2147483648
SRLI
rs1: 3
rd: 4
value: 1073741824
SRAI
rs1: 3
rd: 5
value: -1073741824