mor1k icache源码分析详解;组相联cache结构详细分析与具体代码实现

注意:原创文章,如需转载请务必标明转载,并附上原文出处链接!!!侵权必究!
作者 : thundersnark
邮箱 : thundersnark@gmail.com
个人邮箱,不是经常查看,如有问题联系请发邮件的同时在本文末尾回复一下!

/******************************************************************************
 This Source Code Form is subject to the terms of the
 Open Hardware Description License, v. 1.0. If a copy
 of the OHDL was not distributed with this file, You
 can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt

 Description: Instruction cache implementation

 Copyright (C) 2012-2013
    Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
    Stefan Wallentowitz <stefan.wallentowitz@tum.de>

 ******************************************************************************/
// 关于这个mor1kx_icache module的整体性说明
// 1、这个icache实现是组相联cache结构,关于什么是组相联cache的结构,请自行查阅书籍或search internet
//
// 2、该cache结构中默认参数所实现的是 cache有2条way(路),way之间是全相连;每条way中分成了2^9个Block(块);所有way中处于
//    同一位置处的Block组成一个set(组);
//    举个例子:假设有2条way,每条way有3个Block;主存中那么cache的形式为:
//    cache way0: way0_Block0, way0_Block1, way0_Block2;
//    cache way1: way1_Block0, way1_Block1, way1_Block2;
//    3个set    :    set0   ,     set1   ,      set2  ;即set0由way0_Block0和way1_Block0组成,其余set类推
//    也就是说 cache中的set总数和一条way中的Block的数量是相同的;
//    一个set内的Block数和cache中的way数量是相同的
//    
// 3、Block是主存和cache相映射的最小单元,即每当没有命中的时候cache需要更新(refill)一个Block;
//    每个Block的深度是2^5即32Byte,即8个word也就是8条指令为一个Block;主存与每条way中的Block是直接相连映射
//
// 4、具体映射方式可以这样理解:主存以一条way的大小来分割成一个个区域;每个区域中又按照Block的大小分割成Block
//    直接相连映射指的就是主存的每个区域中的Block只能放到cache的way中的相应位置的Block处(即只能放到特定的组);
//    全相连映射指的就是从主存中一个区域中取出的Block能够放入cache中任意一条way中相应Block的位置(可以任意放到组内的任意一个Block);
//    即way之间(也就是set内部)是全相连;way内部(也就是set之间)是直接映射;
//    举个例子:假设主存的结构被划分成下面这样:
//    mem0_Block0, mem0_Block1, mem0_Block2; mem1_Block0,mem1_Block1,mem1_Block2; mem2_Block0,mem2_Block1,mem2_Block2;
//    其中mem0,mem1,mem2是将主存以每个way的空间大小划分成的区,区内又划分成Block,结合上面举的cache的例子,
//    那么mem1的Block2只能放到set2中,也就是只能放到way0的block2处或way1的block2处;至于是way1和way2则是任意的;
//    在这个例子中;way之间(set内部)是全相连的具体体现就是上述Block可以任意放到way1或way2;
//    way内部(也就是set之间)是直接映射的具体体现就是上述Block只能放到way的Block2处;    
//    (注:怕讲不明白,所以写的有点啰嗦;此外网上有些博客上写的cache的组相联结构分了line,block,set,way等等,
//    写的很繁杂,绕来绕去;我没仔细去查阅相应的计算机架构的书籍,也不清楚他们是不是真正写对了,我这里写的这个按way
//    和block和set来进行组相联的cache结构仅仅是我根据mor1k的icache代码实现总结出来的,也不保证完全正确(至少我自己
//    现在认为没问题!)如果有什么问题可以在下面留言我看到的话会回答^_^,但平时比较忙不一定会及时哈~)
// 4、这个代码的主要状态分为三个即 1、cpu读指令 2、cpu读指令miss的情况下进行cache refill 3、写spr寄存器清空cache中的Block
//    
// 5、关于cache和immu相关联的地方主要有两处 1、cpu读指令的时候地址有两个,cpu_adr_i和cpu_adr_match_i分别是虚拟地址和物理地址
//    当然,前提是immu使能了,如果immu不是能的话两个都是虚拟地址,也可以理解成两个都是物理地址;2、refill cache的wadr_i
//    从这里可以看处写cache的时候只用了一个地址,而读cache的时候用了两个地址;从fetch模块的代码中可以看出wadr_i在immu使能
//    的时候写入cache的是物理地址,而immu不是能的时候写入的是虚拟地址;这就存在一个问题,也就是说当immu使能的时候,写入icache
//    的地址时物理地址,tag mem中存放的也是物理地址的tag;而采用cpu_adr_i这个虚拟地址对tag mem和way mem进行索引,再讲索引的结果
//    与cpu_adr_match_i这个物理地址的tag进行比较;这时不合理的;为了解释这个问题,观察代码中用到cpu_adr_i的地方,可以看出,
//    对tag mem和way mem进行索引的时候只用到了cpu_adr_i[WAY_WIDTH-1:OPTION_ICACHE_BLOCK_WIDTH]这一部分,
//    所以我猜测,不管immu怎么样,虚拟地址和物理地址的[WAY_WIDTH-1:0]这一区域都是相同的,不同的仅仅是两个地址的tag部分;
//    需要等到我看完immu指令部分的代码,再回头确认这个问题!!!
//
`include "mor1kx-defines.v"

module mor1kx_icache
  #(
    parameter OPTION_OPERAND_WIDTH = 32, //指令宽度
    parameter OPTION_ICACHE_BLOCK_WIDTH = 5, //block(块)的宽度,5bit,即每个块由2^5即32个Byte组成
                                             //块是cache中存放的主存数据的最小单位
    parameter OPTION_ICACHE_SET_WIDTH = 9,   //
    parameter OPTION_ICACHE_WAYS = 2,
    parameter OPTION_ICACHE_LIMIT_WIDTH = 32
    )
   (
    input 			      clk,
    input 			      rst,

    //这里应该是指令的prefetch模块跟icache的接口
    input 			      ic_imem_err_i, //instruction memory err
    input 			      ic_access_i, //指示cpu是否请求读icache 
    output 			      refill_o, //指示当前icache模块处于refill(重填)某一个way中的某一Block的状态
    output 			      refill_req_o, //需要refill icache;此信号的assert会从read不命中开始直到refill Block结束
    output 			      refill_done_o, //refill结束
    output 			      invalidate_o, //处于通过写spt寄存器使cache的set invalidate的状态
    output 			      cache_hit_o, //cache命中

    // CPU Interface
    // CPU对于cache的操作分为两种,一种从cache中取指令的操作,令一种是将指令写
    // 入cache的操作,也就是refill cache
    // 取指令操作对应的信号如下:
    output 			                  cpu_ack_o,
    output reg [`OR1K_INSN_WIDTH-1:0] cpu_dat_o, //输出给CPU的指令
    input [OPTION_OPERAND_WIDTH-1:0]  cpu_adr_i, // CPU读指令时给出的虚拟地址,这个地址用来索引icache的tag mem和way mem
    in
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值