risc-v中文社区

 找回密码
 立即注册
查看: 1093|回复: 2

[原创] chisel中使用参数配置的方式(2)

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-9-1 19:07:35 | 显示全部楼层 |阅读模式
有时候,需要使用非常复杂的类型作为参数,简单的参数方式不能满足要求,比如:
def myMux[T <: Data](sel:Bool,aPath:T,bPath:T):T = {
        val ret = WireDefalult(aPath) //定义一个线网类型,并且直接连到aPath
        when(sel) {
                ret := bPath
        }
        ret        //根据scala语法,这个值是myMux返回的返回值
}
这个例子中允许使用类型参数化函数,Data是chisel类型系统的根,所以参数类型是Data的子集。
Mux是一个多路复用器,三个参数,一个是选择器sel,另二个是数据通道。实验代码如下:
import chisel3._
class ParamAdder(n:Int) extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(n.W))
    val b = Input(UInt(n.W))
    val c = Output(UInt(n.W))
  })
  io.c := io.a + io.b
}
class TestParamAdderModule extends Module {
  val io = IO(new Bundle {
    val a8 = Input(UInt(8.W))
    val b8 = Input(UInt(8.W))
    val out8 = Output(UInt(8.W))
    val a16 = Input(UInt(16.W))
    val b16 = Input(UInt(16.W))
    val out16 = Output(UInt(16.W))
    val o = Output(UInt(8.W))
  })
  val add8 = Module(new ParamAdder(8)) //不能直接new模块,只能用object的apply产生模块(因为有些chisel内部状态需要处理)
  val add16 = Module(new ParamAdder(16))
  add8.io.a := io.a8
  add8.io.b := io.b8
  io.out8 := add8.io.c
  add16.io.a := io.a16
  add16.io.b := io.b16
  io.out16 := add16.io.c

  def myMux[T <: Data] (sel:Bool,a:T,b:T): T = {
    val ret = WireDefault(a)
    when(sel) {  
      ret := a
    } otherwise {
      ret := b
    }
    ret
  }

  io.o := myMux(add8.io.a === 10.U,add8.io.a,add8.io.b)
}

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-1 19:28:44 | 显示全部楼层
def myMux[T <: Data] (sel:Bool,a:T,b:T): T的类型T其实还可以是复杂的数据类型Bundle,比如:class ComplexIO extends Bundle {
  val a = UInt(8.W)
  val b = Bool()
}
使用时:
  val t = Wire(new ComplexIO)
  t.a := io.a8
  t.b := true.B
  val r = Reg(new ComplexIO)
  r.a := io.a8
  r.b := t.b


回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-1 19:50:54 | 显示全部楼层
  def myMux[T <: Data] (sel:Bool,a:T,b:T): T = {
    //Data类中有def cloneType:this.type 但源码中说这是内部API,应该用chiselTypeOf这个API
    //chiselTypeOf返回硬件object的对应的chisel type 对象
    //Wire的apply其实是Wire工厂(WireFactory)的apply,参数是chisel类型,这个apply中需要将chisel类型绑定到对应的硬件类型对象
    val ret = Wire(chiselTypeOf(a)) //Wire(a.cloneType)
    when(sel) {
      ret := a
    } otherwise {
      ret := b
    }
    ret
  }
  def myMuxx[T <: Data] (sel:Bool,a:T,b:T): T = {
    val ret = WireDefault(a)  //用硬件类型参数创建Wire类型对象
    when(sel) {
      ret := a
    } otherwise {
      ret := b
    }
    ret
  }

回复

使用道具 举报

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

本版积分规则



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

GMT+8, 2024-4-29 04:00 , Processed in 0.016390 second(s), 17 queries .

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

Copyright © 2018-2021, risc-v open source

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