RISC-V: I-type 小於指令

本来因为 RISC-V 指令规格书写明 imm 全部都是 Sign Extended,
决定全部都用 imm 表示,
写到一半发现这次的指令单纯写 imm 会不好理解,
稍微修改格式为 SignExt-imm。

I-type

指令格式如下:

|31     20|19   15|14    12|11   7|6       0|
+-------------------------------------------+
|   imm   |  rs1  | funct3 |  rd  | pocode  |
+-------------------------------------------+

SLTI

rd = rs1 < SignExt-imm ? 1 : 0

|31     20|19   15|14    12|11   7|6       0|
+-------------------------------------------+
|   imm   |  rs1  |  010   |  rd  | 0010011 |
+-------------------------------------------+

SLTIU

这边是将 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 |
+-------------------------------------------+

SEQZ

这道指令也是跟 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


<<:  Day 26 - Stripe Follow Along Dropdown Navigation [更新]

>>:  【把玩Azure DevOps】Day14 Extensions for Azure DevOps:Azure DevOps也能装外挂?

Day 15 : 笔记篇 02 — 使用「渐进式总结」来写笔记,逐步萃取出高含金量的知识内容

前言 这是 Obsidian 使用教学 — 笔记篇的第 2 篇文章。 在 上一篇文章 中,我说明了:...

Day 01 : 导言 - 知识是如何形成的?

【Obsidian 双向链结型笔记工具研究与应用,打造属於个人的专业知识图谱】 Day 01 : 导...

[Day_12]资料储存容器 - 练习题

今天来为大家介绍资料储存容器的练习题, 过程跟解法可能跟大家不太一样还请大家见谅, 那就让我们开始吧...

{DAY10} SQL查询语法2

前言 我上的课程一样是郭耀仁老师在台大资讯系统训练班所开设的『SQL资料分析』 这篇文章会使用老师上...

[Day 10 ]资料和资料之间的多对多关联

除了一对多的关联方式以外,资料和资料间也有可能是多对多的关联方式。 比方说常见的用户标签(tag) ...