joe 发表于 2021-9-9 23:24:01

匿名和命名Bundle类问题


两个注释掉的二次实验都是失败的,提示是因为“must be a Chisel type, not hardware"
但我将外面命名Bundle类即MyArbiterIO类的代码全部用在模块内部的IO(new Bundle{...})中则一切正常。
不知原因?

joe 发表于 2021-9-9 23:24:33

将上图中代码列出:
import chisel3._
import chisel3.util._
class MyArbiterIO ( val gen:T,val n:Int) extends Bundle {
//val enq = Flipped(Vec(n,new DecoupledIO(gen)))
val enq = Flipped(Vec(n,Decoupled(gen)))
val deq = new DecoupledIO(gen)
val chosen = Output(UInt(log2Ceil(n).W))

}
abstract class AbstractMyArbiter(gen:T,n:Int) extends Module {
val io = IO(new MyArbiterIO(gen,n))
}
//class MyArbiter (gen:T,n:Int) extends AbstractMyArbiter(gen,n) { //chisel3.package$ExpectedChiselTypeException: 'UInt<8>(IO in unelaborated MyArbiter)' must be a Chisel type, not hardware
//val arbiter = Module(new Arbiter(gen,n))
//arbiter.io.in <> io.enq
//arbiter.io.out <> io.deq
//arbiter.io.chosen <> io.chosen
//
//}
//class MyArbiter (gen:T,n:Int) extends Module{
//val io = IO(new MyArbiterIO(gen,n)) //chisel3.package$ExpectedChiselTypeException: 'UInt<8>(IO in unelaborated MyArbiter)' must be a Chisel type, not hardware
//val arbiter = Module(new Arbiter(gen,n))
//arbiter.io.in <> io.enq
//arbiter.io.out <> io.deq
//arbiter.io.chosen <> io.chosen
//
//}
class MyArbiter (gen:T,n:Int) extends Module{ //为什么只有这样写代码才OK???
    val io = IO(new Bundle {
      val enq = Flipped(Vec(n,Decoupled(gen)))
      val deq = new DecoupledIO(gen)
      val chosen = Output(UInt(log2Ceil(n).W))
    }) //定义好模块的IO口Bundle 但IO的apply方法需要的是chisel类型,而不是硬件类型
val arbiter = Module(new Arbiter(gen,n))
arbiter.io.in <> io.enq
arbiter.io.out <> io.deq
arbiter.io.chosen <> io.chosen

}

joe 发表于 2021-9-10 13:31:40

先看这个帖子中所说的分析:https://github.com/chipsalliance/chisel3/issues/765其中有一段:

[*]Breaking things seriously sucks for users, so we're going to try and preserve current behavior, even if few users seem to be using it.
[*]For 3.1, Bundle field detection will continue under current rules (is it a val), and autoclonetype will clone data parameters. These types must still be unbound, bound types will trigger an autoclonetype error (because we cannot perfectly and meaningfully clone a bound type). The two options for constructor arguments of type Data that are not meant to be fields are:
[*]Make them private vals, which allows the use of autoclonetype. This is ugly.
[*]Define a custom cloneType, which is probably what most code was already doing.


joe 发表于 2021-9-10 13:35:27

根据上帖中所说,我重新修改代码,增加private,实验成功:
class MyArbiterIO5 ( private val gen:T, n:Int) extends ArbiterIO(gen,n) {
val mysignal = Output(Bool())
}
abstract class AbstractMyArbiter5(gen:T,n:Int) extends Module {
val io = IO(new MyArbiterIO5(gen,n)) ////chisel3.package$ExpectedChiselTypeException: 'UInt<8>(IO in unelaborated MyArbiter4)' must be a Chisel type, not hardware
}
class MyArbiter5 (gen:T,n:Int) extends AbstractMyArbiter5(gen,n) {
val arbiter = Module(new Arbiter(gen,n))
arbiter.io.in <> io.in
arbiter.io.out <> io.out
arbiter.io.chosen <> io.chosen
io.mysignal := arbiter.io.out.valid
}
结果实验OK,Driver.execute(Array("--target-dir","generated"),()=>new MyArbiter5(UInt(8.W),3)),产生的verilog代码如下:
module Arbiter(
output       io_in_0_ready,
input      io_in_0_valid,
input io_in_0_bits,
output       io_in_1_ready,
input      io_in_1_valid,
input io_in_1_bits,
output       io_in_2_ready,
input      io_in_2_valid,
input io_in_2_bits,
input      io_out_ready,
output       io_out_valid,
output io_out_bits,
output io_chosen
);
wire _GEN_0 = io_in_1_valid ? 2'h1 : 2'h2; // @
wire _GEN_1 = io_in_1_valid ? io_in_1_bits : io_in_2_bits; // @
wire_T = io_in_0_valid | io_in_1_valid; // @
wire_T_1 = ~io_in_0_valid; // @
wire_T_2 = ~_T; // @
wire_T_6 = ~_T_2; // @
assign io_in_0_ready = io_out_ready; // @
assign io_in_1_ready = _T_1 & io_out_ready; // @
assign io_in_2_ready = _T_2 & io_out_ready; // @
assign io_out_valid = _T_6 | io_in_2_valid; // @
assign io_out_bits = io_in_0_valid ? io_in_0_bits : _GEN_1; // @
assign io_chosen = io_in_0_valid ? 2'h0 : _GEN_0; // @
endmodule
module MyArbiter5(
input      clock,
input      reset,
output       io_in_0_ready,
input      io_in_0_valid,
input io_in_0_bits,
output       io_in_1_ready,
input      io_in_1_valid,
input io_in_1_bits,
output       io_in_2_ready,
input      io_in_2_valid,
input io_in_2_bits,
input      io_out_ready,
output       io_out_valid,
output io_out_bits,
output io_chosen,
output       io_mysignal
);
wirearbiter_io_in_0_ready; // @
wirearbiter_io_in_0_valid; // @
wire arbiter_io_in_0_bits; // @
wirearbiter_io_in_1_ready; // @
wirearbiter_io_in_1_valid; // @
wire arbiter_io_in_1_bits; // @
wirearbiter_io_in_2_ready; // @
wirearbiter_io_in_2_valid; // @
wire arbiter_io_in_2_bits; // @
wirearbiter_io_out_ready; // @
wirearbiter_io_out_valid; // @
wire arbiter_io_out_bits; // @
wire arbiter_io_chosen; // @
Arbiter arbiter ( // @
    .io_in_0_ready(arbiter_io_in_0_ready),
    .io_in_0_valid(arbiter_io_in_0_valid),
    .io_in_0_bits(arbiter_io_in_0_bits),
    .io_in_1_ready(arbiter_io_in_1_ready),
    .io_in_1_valid(arbiter_io_in_1_valid),
    .io_in_1_bits(arbiter_io_in_1_bits),
    .io_in_2_ready(arbiter_io_in_2_ready),
    .io_in_2_valid(arbiter_io_in_2_valid),
    .io_in_2_bits(arbiter_io_in_2_bits),
    .io_out_ready(arbiter_io_out_ready),
    .io_out_valid(arbiter_io_out_valid),
    .io_out_bits(arbiter_io_out_bits),
    .io_chosen(arbiter_io_chosen)
);
assign io_in_0_ready = arbiter_io_in_0_ready; // @
assign io_in_1_ready = arbiter_io_in_1_ready; // @
assign io_in_2_ready = arbiter_io_in_2_ready; // @
assign io_out_valid = arbiter_io_out_valid; // @
assign io_out_bits = arbiter_io_out_bits; // @
assign io_chosen = arbiter_io_chosen; // @
assign io_mysignal = arbiter_io_out_valid; // @
assign arbiter_io_in_0_valid = io_in_0_valid; // @
assign arbiter_io_in_0_bits = io_in_0_bits; // @
assign arbiter_io_in_1_valid = io_in_1_valid; // @
assign arbiter_io_in_1_bits = io_in_1_bits; // @
assign arbiter_io_in_2_valid = io_in_2_valid; // @
assign arbiter_io_in_2_bits = io_in_2_bits; // @
assign arbiter_io_out_ready = io_out_ready; // @
endmodule

joe 发表于 2021-9-10 14:00:46

//参考https://github.com/chipsalliance/chisel3/issues/765,改为private val gen:T, n:Int则run能成功,但有下面很多warn
// class com.joe.stu.MyArbiterIO31 (1 calls): Unable to automatically infer cloneType on class com.joe.stu.MyArbiterIO31: constructor has parameters (n) that are not both immutable and accessible. Either make all parameters immutable and accessible (vals) so cloneType can be inferred, or define a custom cloneType method.
// There were 1 deprecated function(s) used. These may stop compiling in a future release - you are encouraged to fix these issues.
// Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:
//   In the sbt interactive console, enter:
//   set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")
//   or, in your build.sbt, add the line:
//   scalacOptions := Seq("-unchecked", "-deprecation")
class MyArbiterIO31 (private val gen:T, n:Int) extends Bundle {
val enq = Flipped(Vec(n,new DecoupledIO(gen)))
val deq = new DecoupledIO(gen)
val chosen = Output(UInt(log2Ceil(n).W))
}
abstract class AbstractMyArbiter31(gen:T,n:Int) extends Module {
val io = IO(new MyArbiterIO31(gen,n))
}
class MyArbiter31 (gen:T,n:Int) extends AbstractMyArbiter31(gen,n) {
val arbiter = Module(new Arbiter(gen,n))
arbiter.io.in <> io.enq
arbiter.io.out <> io.deq
arbiter.io.chosen <> io.chosen
}
//在MyArbiterIO31代码基础上,重载cloneType方法 则没有那些warn
class MyArbiterIO32 (private val gen:T, n:Int) extends Bundle {
val enq = Flipped(Vec(n,new DecoupledIO(gen)))
val deq = new DecoupledIO(gen)
val chosen = Output(UInt(log2Ceil(n).W))
override def cloneType: this.type = new MyArbiterIO32(gen,n).asInstanceOf
}
abstract class AbstractMyArbiter32(gen:T,n:Int) extends Module {
val io = IO(new MyArbiterIO32(gen,n))
}
class MyArbiter32 (gen:T,n:Int) extends AbstractMyArbiter32(gen,n) {
val arbiter = Module(new Arbiter(gen,n))
arbiter.io.in <> io.enq
arbiter.io.out <> io.deq
arbiter.io.chosen <> io.chosen
}
最后将MyArbiterIO31和MyArbiterIO32生成的verilog文件内容比对,发现内容相同。

joe 发表于 2021-9-10 14:12:47

//在MyArbiterIO31基础上将n也改为val,则也没有warn
class MyArbiterIO33[T <: Data] (private val gen:T,val n:Int) extends Bundle {
val enq = Flipped(Vec(n,new DecoupledIO(gen)))
val deq = new DecoupledIO(gen)
val chosen = Output(UInt(log2Ceil(n).W))
}
abstract class AbstractMyArbiter33[T <: Data](gen:T,n:Int) extends Module {
val io = IO(new MyArbiterIO33[T](gen,n))
}
class MyArbiter33 [T <: Data](gen:T,n:Int) extends AbstractMyArbiter33(gen,n) {
val arbiter = Module(new Arbiter(gen,n))
arbiter.io.in <> io.enq
arbiter.io.out <> io.deq
arbiter.io.chosen <> io.chosen
}
页: [1]
查看完整版本: 匿名和命名Bundle类问题