Search code examples
hdlchisel

Why this chisel code compiling without error with wrong size UInt assignement?


I declared a Module port like this (it was a mistake) in my top RawModule:

class TopMyModule extends RawModule {
...
  val enet1_tx_data0 = IO(Output(Bool()))
  val enet1_tx_data1 = IO(Output(Bool()))
...
  val tx1data = IO(Output(Bool()))
...

And connected it like this :

  tx1data := enet1_tx_data1 ## enet1_tx_data0

The '##' operator should concatenate the two bits in a vector of size to no ? But it's compiling without any error. If I'm looking under the verilog generated code, I see that concatenation is done but only least significant bit is used for output:

...
  wire [1:0] _T_1; // @[spiDualkszRmiiChecker.scala 73:29]
...
  assign _T_1 = {enet1_tx_data1,enet1_tx_data0}; // @[spiDualkszRmiiChecker.scala 73:29]
...
  assign tx1data = _T_1[0]; // @[spiDualkszRmiiChecker.scala 73:11]

In my mind tx1data should have been declared as 2 bits UInt :

  val tx1data = IO(Output(UInt(2.W)))

But I was surprised that first version doesn't generate any error.


Solution

  • I believe this is an original design decision that some like and some do not. There is a good discussion on this issue Remove implicit width truncation / Don't repeat Verilog's assignment issue in Chisel #1163. Please feel free to chime in.