risc-v中文社区

 找回密码
 立即注册
查看: 3618|回复: 5

[原创] 匿名和命名Bundle类问题

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-9-9 23:24:01 | 显示全部楼层 |阅读模式

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-9 23:24:33 | 显示全部楼层
将上图中代码列出:
import chisel3._
import chisel3.util._
class MyArbiterIO[T <: Data] ( 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[T <: Data](gen:T,n:Int) extends Module {
  val io = IO(new MyArbiterIO[T](gen,n))
}
//class MyArbiter [T <: Data](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 [T <: Data](gen:T,n:Int) extends Module{
//  val io = IO(new MyArbiterIO[T](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 [T <: Data](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

}
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 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.


回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-10 13:35:27 | 显示全部楼层
根据上帖中所说,我重新修改代码,增加private,实验成功:
class MyArbiterIO5[T <: Data] ( private val gen:T, n:Int) extends ArbiterIO(gen,n) {
  val mysignal = Output(Bool())
}
abstract class AbstractMyArbiter5[T <: Data](gen:T,n:Int) extends Module {
  val io = IO(new MyArbiterIO5[T](gen,n)) ////chisel3.package$ExpectedChiselTypeException: 'UInt<8>(IO in unelaborated MyArbiter4)' must be a Chisel type, not hardware
}
class MyArbiter5 [T <: Data](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  [7:0] io_in_0_bits,
  output       io_in_1_ready,
  input        io_in_1_valid,
  input  [7:0] io_in_1_bits,
  output       io_in_2_ready,
  input        io_in_2_valid,
  input  [7:0] io_in_2_bits,
  input        io_out_ready,
  output       io_out_valid,
  output [7:0] io_out_bits,
  output [1:0] io_chosen
);
  wire [1:0] _GEN_0 = io_in_1_valid ? 2'h1 : 2'h2; // @[Arbiter.scala 126:27]
  wire [7:0] _GEN_1 = io_in_1_valid ? io_in_1_bits : io_in_2_bits; // @[Arbiter.scala 126:27]
  wire  _T = io_in_0_valid | io_in_1_valid; // @[Arbiter.scala 31:68]
  wire  _T_1 = ~io_in_0_valid; // @[Arbiter.scala 31:78]
  wire  _T_2 = ~_T; // @[Arbiter.scala 31:78]
  wire  _T_6 = ~_T_2; // @[Arbiter.scala 135:19]
  assign io_in_0_ready = io_out_ready; // @[Arbiter.scala 134:14]
  assign io_in_1_ready = _T_1 & io_out_ready; // @[Arbiter.scala 134:14]
  assign io_in_2_ready = _T_2 & io_out_ready; // @[Arbiter.scala 134:14]
  assign io_out_valid = _T_6 | io_in_2_valid; // @[Arbiter.scala 135:16]
  assign io_out_bits = io_in_0_valid ? io_in_0_bits : _GEN_1; // @[Arbiter.scala 124:15 Arbiter.scala 128:19 Arbiter.scala 128:19]
  assign io_chosen = io_in_0_valid ? 2'h0 : _GEN_0; // @[Arbiter.scala 123:13 Arbiter.scala 127:17 Arbiter.scala 127:17]
endmodule
module MyArbiter5(
  input        clock,
  input        reset,
  output       io_in_0_ready,
  input        io_in_0_valid,
  input  [7:0] io_in_0_bits,
  output       io_in_1_ready,
  input        io_in_1_valid,
  input  [7:0] io_in_1_bits,
  output       io_in_2_ready,
  input        io_in_2_valid,
  input  [7:0] io_in_2_bits,
  input        io_out_ready,
  output       io_out_valid,
  output [7:0] io_out_bits,
  output [1:0] io_chosen,
  output       io_mysignal
);
  wire  arbiter_io_in_0_ready; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_in_0_valid; // @[MyArbiter.scala 65:23]
  wire [7:0] arbiter_io_in_0_bits; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_in_1_ready; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_in_1_valid; // @[MyArbiter.scala 65:23]
  wire [7:0] arbiter_io_in_1_bits; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_in_2_ready; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_in_2_valid; // @[MyArbiter.scala 65:23]
  wire [7:0] arbiter_io_in_2_bits; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_out_ready; // @[MyArbiter.scala 65:23]
  wire  arbiter_io_out_valid; // @[MyArbiter.scala 65:23]
  wire [7:0] arbiter_io_out_bits; // @[MyArbiter.scala 65:23]
  wire [1:0] arbiter_io_chosen; // @[MyArbiter.scala 65:23]
  Arbiter arbiter ( // @[MyArbiter.scala 65:23]
    .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; // @[MyArbiter.scala 66:17]
  assign io_in_1_ready = arbiter_io_in_1_ready; // @[MyArbiter.scala 66:17]
  assign io_in_2_ready = arbiter_io_in_2_ready; // @[MyArbiter.scala 66:17]
  assign io_out_valid = arbiter_io_out_valid; // @[MyArbiter.scala 67:18]
  assign io_out_bits = arbiter_io_out_bits; // @[MyArbiter.scala 67:18]
  assign io_chosen = arbiter_io_chosen; // @[MyArbiter.scala 68:21]
  assign io_mysignal = arbiter_io_out_valid; // @[MyArbiter.scala 69:15]
  assign arbiter_io_in_0_valid = io_in_0_valid; // @[MyArbiter.scala 66:17]
  assign arbiter_io_in_0_bits = io_in_0_bits; // @[MyArbiter.scala 66:17]
  assign arbiter_io_in_1_valid = io_in_1_valid; // @[MyArbiter.scala 66:17]
  assign arbiter_io_in_1_bits = io_in_1_bits; // @[MyArbiter.scala 66:17]
  assign arbiter_io_in_2_valid = io_in_2_valid; // @[MyArbiter.scala 66:17]
  assign arbiter_io_in_2_bits = io_in_2_bits; // @[MyArbiter.scala 66:17]
  assign arbiter_io_out_ready = io_out_ready; // @[MyArbiter.scala 67:18]
endmodule
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-9-10 14:00:46 | 显示全部楼层
//参考https://github.com/chipsalliance/chisel3/issues/765,改为private val gen:T, n:Int则run能成功,但有下面很多warn
//[deprecated] 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.
//[warn] There were 1 deprecated function(s) used. These may stop compiling in a future release - you are encouraged to fix these issues.
//[warn] Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:
//[warn]   In the sbt interactive console, enter:
//[warn]     set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")
//[warn]   or, in your build.sbt, add the line:
//[warn]     scalacOptions := Seq("-unchecked", "-deprecation")
class MyArbiterIO31[T <: Data] (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[T <: Data](gen:T,n:Int) extends Module {
  val io = IO(new MyArbiterIO31[T](gen,n))
}
class MyArbiter31 [T <: Data](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[T <: Data] (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[this.type]
}
abstract class AbstractMyArbiter32[T <: Data](gen:T,n:Int) extends Module {
  val io = IO(new MyArbiterIO32[T](gen,n))
}
class MyArbiter32 [T <: Data](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文件内容比对,发现内容相同。

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 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
}
回复

使用道具 举报

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

本版积分规则



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

GMT+8, 2024-4-29 19:08 , Processed in 0.027064 second(s), 18 queries .

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

Copyright © 2018-2021, risc-v open source

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