Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Interaction between Chisel._, DedupModules, and ExpandConnects can result in dropped connections #1703

Closed
5 tasks done
mwachs5 opened this issue Jun 22, 2020 · 0 comments · Fixed by #1713
Closed
5 tasks done

Comments

@mwachs5
Copy link
Contributor

mwachs5 commented Jun 22, 2020

Checklist

  • Did you specify the current behavior?
  • Did you specify the expected behavior?
  • Did you provide a code example showing the problem?
  • Did you describe your environment?
  • Did you specify relevant external information?

What is the current behavior?

When connecting things with Chisel._, it's possible that DedupModules and ExpandConnects interact badly with eachother to result in dropped wires (wires tied off to 0 instead of being connected as specified by the user).

What is the expected behavior?

The Chisel user's intended connectivity should not be changed by DedupModules and wires should end up connected properly in the final verilog.

OR an error should be thrown by Chisel/FIRRTL alerting user that this is not going to work in this case.

Steps to Reproduce

This was originally discovered in implementing. chipsalliance/rocket-chip#2528

Thanks to @jackkoenig for getting this cut-down example coded up:

https://scastie.scala-lang.org/yJUyW088TVOPhQpLlSX1Ng

Code duplicated below:

/* FIRRTL Dedup bug

This illustrates a problem with Dedup where Modules using <- (partial connect) from
compatibility mode can have their semantics changed by Dedup. Because partial connect
uses by-name connections, name-agnostic deduplication can change the names of the ports
thus changing the semantics of connections to those ports.

You can see this bug by changing the import between Chisel._ and chisel3._
Under chisel3._ things work correctly (bulk connections are flattened before FIRRTL)
But if you use Chisel._, the connection semantics change and the connections to bar
get dropped (defaulted to 0 because Chisel._)

*/
import Chisel._
//import chisel3._
import chisel3.stage.ChiselStage

class Foo extends Bundle {
  val foo = Input(Bool())
  val fuzz = Output(Bool())
}

class Bar extends Bundle {
  val bar = Input(Bool())
  val buzz = Output(Bool())
}

class FooModule extends Module {
  val io = IO(new Foo)
  io.fuzz := io.foo
}

class BarModule extends Module {
  val io = IO(new Bar)
  io.buzz := io.bar
}

class FooAndBarModule extends Module {
  
  val io = IO(new Bundle {
    val foo = new Foo
    val bar = new Bar
  })
  val foo = Module(new FooModule)
  val bar = Module(new BarModule)
  io.foo <> foo.io
  io.bar <> bar.io

}

println((new ChiselStage).emitVerilog(new FooAndBarModule()))

Here is the bad result:

module FooModule(
  input   io_foo,
  output  io_fuzz
);
  assign io_fuzz = io_foo; // @[main.scala 32:11]
endmodule
module FooAndBarModule(
  input   clock,
  input   reset,
  input   io_foo_foo,
  output  io_foo_fuzz,
  input   io_bar_bar,
  output  io_bar_buzz
);
  wire  foo_io_foo; // @[main.scala 46:19]
  wire  foo_io_fuzz; // @[main.scala 46:19]
  wire  bar_io_foo; // @[main.scala 47:19]
  wire  bar_io_fuzz; // @[main.scala 47:19]
  FooModule foo ( // @[main.scala 46:19]
    .io_foo(foo_io_foo),
    .io_fuzz(foo_io_fuzz)
  );
  FooModule bar ( // @[main.scala 47:19]
    .io_foo(bar_io_foo),
    .io_fuzz(bar_io_fuzz)
  );
  assign io_foo_fuzz = foo_io_fuzz; // @[main.scala 48:10]
  assign io_bar_buzz = 1'h0;
  assign foo_io_foo = io_foo_foo; // @[main.scala 48:10]
  assign bar_io_foo = 1'h0;
endmodule

Your environment

  • Chisel Versions: * 21ea734 - (9 weeks ago) Merge branch 'master' into 3.3.x - Jim Lawson
  • firrtl Version: | * e599dba - (10 days ago) delete usages of toSet for determinism (#1686) (#1688) - mergify[bot]

External Information

chipsalliance/rocket-chip#2528, chipsalliance/rocket-chip#2487

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant