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)
}
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
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]