risc-v中文社区

 找回密码
 立即注册
查看: 1290|回复: 0

[原创] 仲裁器Arbiter(1)

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-9-9 15:40:53 | 显示全部楼层 |阅读模式
chisel有二种仲裁器,一种是优先仲裁器Arbiter,另一种是循环仲裁器RRAribter。
仲裁器的输入叫producer,一个输出叫consumer,producer有多个,但consumer只有一个.
所谓优先仲裁是指各个输入(也叫Producer)的优先级都是固定一样的,但每次选择有效通道中优先级最高的;
循环仲裁器每次都从不同的起点开始,采用轮巡方式,哪个先查询有效,则选择这个有效的通道输出。

chisel仲裁器源码中用到了带ready-valid接口的Decoupled,其实Decoupled的apply方法
返回的是DecoupledIO,然后ArbiterIO将这些(其实是多个输入,一个输出)信号作为Bundle:
class ArbiterIO[T <: Data](private gen:T,val n:Int) extends Bundle{ //什么gen是private参考:github.com/freechipsproject/chisel3/issues/765
        val in = Flipped(Vec(n,Decoupled(gen)))
        val out = Decoupled(gen)
        val chosen = Output(UInt(log2Ceil(n).W)) //log2Ceil(n)表示数值n-1需要多少位bit
}
ArbiterIO只是将多个输入和一个输出以及一个表示选择哪个输入作为仲裁输出的索引指示混在一起作为Bundle以便
用于模块中作为接口使用。用到ArbiterIO的是仲裁器类Arbiter和RRArbiter,先介绍Arbiter优先仲裁器:
class Arbiter[T <: Data](gen:T,n:Int) extends Module {
        val io = IO(new ArbiterIO(gen,n))
        io.chosen := (n-1).asUInt //需要一个初值
        io.out.bits := io.in(n-1).bits //数据线也需要一个初值 不赋初值编译出错
        for(i <- n-2 to 0 by -1){ //从n-2,n-3...,1,0降序
                when(io.in(i).valid) { //输入进来的valid有效
                        io.chosen := i.asUInt //在这些降序输入排序中,只要有一个valid了则就选择这个通道
                        io.out.bits := io.in(i).bits //当然,数据肯定也是取这个通道的数据
                }
        }
        //上面for循环,如果有多个输入的valid都是有效状态,那么最终io.chosen只能是最小通道值才起作用 因为:=操作可以多次,但最后一次才起效
        private val grant = ArbiterCtrl(io.in.map(_.valid))
        for((in,g) <- io.in zip grant)
                in.ready := g && io.out.ready
        io.out.valid := !grant.last || io.in.last.valid
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-5-2 21:56 , Processed in 0.014735 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表