joe 发表于 2021-9-1 19:07:35

chisel中使用参数配置的方式(2)

有时候,需要使用非常复杂的类型作为参数,简单的参数方式不能满足要求,比如:
def myMux(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 (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)
}

joe 发表于 2021-9-1 19:28:44

def myMux (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


joe 发表于 2021-9-1 19:50:54

def myMux (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 (sel:Bool,a:T,b:T): T = {
    val ret = WireDefault(a)//用硬件类型参数创建Wire类型对象
    when(sel) {
      ret := a
    } otherwise {
      ret := b
    }
    ret
}

页: [1]
查看完整版本: chisel中使用参数配置的方式(2)