关于RISC小端模式的访存指令

3 篇文章 0 订阅
2 篇文章 0 订阅

大家好我是木林,我之前有说要连载的RIACV系列好像就先停滞一下吧,确实挺忙的,那么前一段时间一直在考虑一个问题,就是体系结构的一个方面,就是为什么访存指令的后*位用来确定是某一字节,一直很疑惑,直到最近研究超标量处理器的时候去设计cache的时候才真真正正的理解了为什么,也可以说真真正正的理解了SRAM把。好了废话不多说。
下面展示一些 访存代码块

 wire [2:0] byte_sel        = ls_addr_i[2:0];
    wire [1:0] half_byte_sel   = ls_addr_i[2:1];
    wire       word_sel        = ls_addr_i[2];

    reg  [7:0]  data_byte;
    reg  [15:0] data_half_byte;
    wire [31:0] data_word;

    always @(*) begin
        case (byte_sel)
            3'b000:  data_byte = data_i[ 7: 0];
            3'b001:  data_byte = data_i[15: 8];
            3'b010:  data_byte = data_i[23:16];
            3'b011:  data_byte = data_i[31:24];
            3'b100:  data_byte = data_i[39:32];
            3'b101:  data_byte = data_i[47:40];
            3'b110:  data_byte = data_i[55:48];
            default: data_byte = data_i[63:56];
        endcase
    end

    always @(*) begin
        case (half_byte_sel)
            2'b00:   data_half_byte = data_i[15: 0];
            2'b01:   data_half_byte = data_i[31:16];
            2'b10:   data_half_byte = data_i[47:32];
            default: data_half_byte = data_i[63:48];
        endcase
    end

    assign data_word = word_sel ? data_i[63:32] : data_i[31:0];

    always @(*) begin
        if(inst_type_i == 8'b0000_0010) begin
            case (ls_sel_i)
                `LB_SEL :begin load_data = {{56{data_byte[7]}}, data_byte};            end
                `LH_SEL :begin load_data = {{48{data_half_byte[15]}}, data_half_byte}; end                                 
                `LW_SEL :begin load_data = {{32{data_word[31]}}, data_word};           end
                `LBU_SEL:begin load_data = {{56{1'b0}}, data_byte};                    end
                `LHU_SEL:begin load_data = {{48{1'b0}}, data_half_byte};               end
                `LWU_SEL:begin load_data = {{32{1'b0}}, data_word};                    end
                `LD_SEL :begin load_data = data_i;                                     end
                default :begin load_data = `ZeroWord;                                  end
            endcase
        end
        else begin load_data = `ZeroWord;  end
    end

RISC ISA ARCH

大家可以知道现在我们研究的很多架构都是RISC架构第一点就是容易理解,实现起来简单。如果真的像x86这样的,真的不是可以简简单单说做就做的,毕竟工程量太大了。
然后我这里说的例子也是那RISC举的例子。

riscv or MIPS load and store

MIPS的load和store部分指令
LB rt, offset(base)

8位加载,

LBU

LBU rt, offset(base)

8位加载,结果0扩展

LH

LH rt, offset(base)

加载半字

LHU

LHU rt, offset(base)

加载半字,结果0扩展

LW

LW rt, offset(base)

加载字

LWU

LWU rt, offset(base)

加载字,结果0扩展

SB

SB rt, offset(base)

存字节

SH

SH rt, offset(base)

存半字

SW

SW rt, offset(base)

存字
RISCVload和store
关于riscv的load和store我就不列出来了,本身来说就是做一个对比,然后大家可以自行去查找。

load and store 详解

所以从以上来看大家可以看到访存指令其实就是通过对内存的访问把源寄存器的数据写到内存中或者把内存中的数据以字节的形式写到源寄存器中,当然这里列出的代码是load指令的代码,那么store指令的代码只不过是翻了过来,同时后三位也会决定把源寄存器的数据写到内存的那些位即会决定写掩码,也不知道这样描述的准不住却,语言表达能力还是得练呀。hhh

可能会有的疑惑

那么这里就是最重点的地方了,也就是我感觉大家可能会有疑惑的地方,就是为什么访存的地址的后三位或者后两位(取决于大家的内核设计的位数决定的 ),那么为什么是这样呢,其实这里的愿意其实就是SARM的机制决定的,这里我们可以暂时可以拿cache作为例子来理解。也就是说我们访问可以先理解为访问cache,那么cache本身的结构就分为块,然后块分为bank,然后又分为line。那么我们再方寸地址去访存的时候其实就是通过前某某位来确定那个块,然后后面的几位来确定是哪个bank,然后在最后面的三位或者两位来确定是lian的某一个字节。所以这里暂时可以这么理解。你的访存地址就是再一个大房子里找小房子,就是和俄罗斯套娃一样。对吧。

总结

好的我是木林学长技术水平有限,如有错误欢迎批评指正:779163410@qq.com(本人会在闲暇时在嵌入式,集成电路,计算机,物联网互联网方面发布自己经验与心得,喜欢可以关注。谢谢。)
我这里有一个群聊大家可以加进去有问题可以交流:366475079

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木林学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值