riscv-sodor-rv32_3stage(2)

现在分析的是arbiter.scala。因为instruction 和data共用一个memory,所以需要用到arbiter来进行仲裁:

package Sodor
{

import chisel3._
import chisel3.util._

import Common._

// arbitrates memory access
class SodorMemArbiter(implicit val conf: SodorConfiguration) extends Module
{
   val io = IO(new Bundle
      {
         // TODO I need to come up with better names... this is too confusing 
         // from the point of view of the other modules
         //instruction memory的端口,是MemPortIo的反向
         val imem = Flipped(new MemPortIo(conf.xprlen)) // instruction fetch
	    //data memory的端口,是MemPortIo的反向
         val dmem = Flipped(new MemPortIo(conf.xprlen)) // load/store 
         //memory的端口,单端,是MemPortIo的正向
         val mem  = new MemPortIo(conf.xprlen)      // the single-ported memory
      }) 

   //***************************
   //定义一个i1reg的寄存器
   val i1reg = Reg(UInt(conf.xprlen.W))
   //定义一个d1reg的寄存器
   val d1reg = Reg(UInt(conf.xprlen.W))
   //定义一个nextdreq的寄存器,初始值为true
   val nextdreq = Reg(init = true.B)
   //data memory一直ready
   io.dmem.req.ready := true.B
   //d_fire : when true data request will be put on bus
   //当data进行数据请求时,d_fire会为1
   val d_fire = Wire(Bool()) 
   //instruction memory的ready看d_fire信号
   //我个人觉得这里有错,应该是io.imem.req.ready := !d_fire
   //d_fire正确memory此时是data在用,instruction的ready应该为0才对
   io.imem.req.ready := d_fire
   //***************************
   // hook up requests
   // 3 cycle FSM on LW , SW , FENCE in exe stage
   // HAZ since contention for MEM PORT so next cycle STALL
   // CYC 1 : Store inst in reg requested in prev CYC 
   //         make data addr available on MEM PORT
   // CYC 2 : Store data in reg to be used in next CYC
   // CYC 3 : Default State with data addr on MEM PORT
   // nextdreq ensures that data req gets access to bus only
   // for one cycle 
   // alternate between data and instr to avoid starvation
   //指令和数据交替提前或写入,防止单方面阻塞太久
   //当此时数据请求,且nextdreq为1时,将d_fire置1,并将nextdreq置0,下周期将data的控制信号输
   //入到memory中,同时instruction memory的resp_valid由memory的resp_valid决定
   when (io.dmem.req.valid && nextdreq)
   {
        d_fire := true.B
        nextdreq := false.B // allow only instr in next cycle
        io.imem.resp.valid := io.mem.resp.valid
   }
   //当此时数据请求,且且nextdreq不为1时,将d_fire置0,并将将nextdreq置1,下周期将inst的控制
   //信号输入到memory中,同时instruction memory的resp_valid为0
   .elsewhen(io.dmem.req.valid && !nextdreq)
   {
        d_fire := false.B
        nextdreq := true.B  // allow any future data request
        io.imem.resp.valid := false.B
   }
   //其他情况是d_fire为0,io.imem.resp.valid 由io.mem.resp.valid决定,是指令取指的情况
   .otherwise
   {
        d_fire := false.B
        io.imem.resp.valid := io.mem.resp.valid
   }
   //输出给memory的控制信号,当d_fire为1时,给data的,当d_fire为0时,给inst的
   // SwITCH BET DATA AND INST REQ FOR SINGLE PORT
   when (d_fire)
   {
      io.mem.req.valid     := io.dmem.req.valid
      io.mem.req.bits.addr := io.dmem.req.bits.addr
      io.mem.req.bits.fcn  := io.dmem.req.bits.fcn
      io.mem.req.bits.typ  := io.dmem.req.bits.typ
   }
   .otherwise
   {
      io.mem.req.valid     := io.imem.req.valid
      io.mem.req.bits.addr := io.imem.req.bits.addr
      io.mem.req.bits.fcn  := io.imem.req.bits.fcn
      io.mem.req.bits.typ  := io.imem.req.bits.typ
   }
   
   //data写给mem的数据
   io.mem.req.bits.data := io.dmem.req.bits.data
   //data的resp valid由io.mem.resp.valid和io.imem.resp.valid决定,当不是指令回复,同时memory回复
   //有效时就是data数据的回复
   io.dmem.resp.valid := io.mem.resp.valid && !io.imem.resp.valid
   
   //当nextdreq为0,将data memory请求的数据存入到d1reg中,数据比控制信号慢一个周期
   when (!nextdreq){
      d1reg := io.mem.resp.bits.data
   }

   //当指令回复有效,同时数据请求有效,且下一次是数据请求时,将指令回复数据存入i1reg中
   when (io.imem.resp.valid && io.dmem.req.valid && nextdreq){
      i1reg := io.mem.resp.bits.data
   }

   //instruction memory的数据需要选择,当instruction回复无效,且数据请求有效,下一个cycle不为数据
   //请求时,将i1reg回复,不然将读到的memory data回复,也就是没有指令请求时,保持这个就的值
   io.imem.resp.bits.data := Mux( !io.imem.resp.valid && io.dmem.req.valid && !nextdreq , i1reg , io.mem.resp.bits.data )
   //data memory的数据请求直接从d1reg中取
   io.dmem.resp.bits.data := d1reg
}
 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值