本來因為 RISC-V 指令規格書寫明 imm 全部都是 Sign Extended,
決定全部都用 imm 表示,
寫到一半發現這次的指令單純寫 imm 會不好理解,
稍微修改格式為 SignExt-imm。
指令格式如下:
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | funct3 | rd | pocode |
+-------------------------------------------+
rd = rs1 < SignExt-imm ? 1 : 0
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | 010 | rd | 0010011 |
+-------------------------------------------+
這邊是將 imm 拿出來 Sign Extension 後,
再當作 unsigned 跟 rs1 比。
rd = rs1 < (uint32_t) SignExt-imm ? 1 : 0
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | 011 | rd | 0010011 |
+-------------------------------------------+
這道指令也是跟 SLTIU 一樣,
只是將 imm 值設定為 1,
這時候小於 1 的就只能是 0 了。
rd = rs1 < (uint32_t) 1 ? 1 : 0
= (rs1 == 0) ? 1 : 0
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| 1 | rs1 | 011 | rd | 0010011 |
+-------------------------------------------+
github 頁面 Tag: ITDay12
大家有猜到昨天說的 bug 是什麼嗎?
就是 Immediate 沒有 Sign Extension 拉!
所以執行結果的第二道指令 1 + (-1)運算出來的值才會是 4096,而不是0。
可能是因為不夠熟悉,找來找去沒在 SystemC 找到相關的功能,
只好自己做。
知道的夥伴可以歡迎留言告訴我!
//instructionDecoder.cpp
int32_t INSTRUCTION_DECODER::get_imm(uint32_t end, uint32_t start)
{
return sc_dt::sc_int<32>(instruction_value) << (31-end) >> start;
}
//instructionDecoderInterface.h
...
SLTI_FN3 = 0b010,
SLTIU_FN3 = 0b011,
...
兩道指令唯一的差別只 SLTIU 多了 int 轉為 uint 的轉型而已,
這邊因為型別很單純,為了可讀性使用 c style 轉型,
而不使用 static_cast<uint32_t>。
//executor.cpp
...
case INSTRUCTION_DECODER_INTERFACE::SLTI_FN3:
SLTI_E();
break;
case INSTRUCTION_DECODER_INTERFACE::SLTIU_FN3:
SLTIU_E();
break;
...
void EXECUTOR::SLTI_E()
{
auto rs1 = instruction_decoder->get_rs1();
auto rd = instruction_decoder->get_rd();
auto value = register_file->get_value_integer(rs1) < instruction_decoder->get_imm(31, 20);
register_file->set_value_integer(rd, value);
...
}
void EXECUTOR::SLTIU_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(31, 20);
register_file->set_value_integer(rd, value);
...
}
$ 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: 0
ADDI
rs1: 0
rd: 0
value: 0
SLTI
rs1: 0
rd: 0
value: 0
SLTIU
rs1: 0
rd: 0
value: 1