In low Firrtl second clock referenced before declared.
See original GitHub issueThis repository’s issues are reserved for feature requests and bug reports.
-
Bug Report The chisel3 MultiClockSpec ClockDividerTest is converted to low Firrtl, the firrtl is re-arranged so that clock2 is referenced before it is declared.
-
How to reproduce the problem:
Here is the Chirrtl.
;buildInfoPackage: chisel3, version: 3.1-SNAPSHOT, scalaVersion: 2.11.12, sbtVersion: 1.0.4
circuit ClockDividerTest :
module ClockDividerTest :
input clock : Clock
input reset : UInt<1>
output io : {}
reg cDiv : UInt<1>, clock with : (reset => (reset, UInt<1>("h01"))) @[MultiClockSpec.scala 12:21]
node _T_8 = eq(cDiv, UInt<1>("h00")) @[MultiClockSpec.scala 13:11]
cDiv <= _T_8 @[MultiClockSpec.scala 13:8]
node clock2 = asClock(cDiv) @[MultiClockSpec.scala 14:21]
reg reg1 : UInt<8>, clock with : (reset => (reset, UInt<8>("h00"))) @[MultiClockSpec.scala 16:21]
node _T_12 = add(reg1, UInt<1>("h01")) @[MultiClockSpec.scala 17:16]
node _T_13 = tail(_T_12, 1) @[MultiClockSpec.scala 17:16]
reg1 <= _T_13 @[MultiClockSpec.scala 17:8]
reg reg2 : UInt<8>, clock2 with : (reset => (reset, UInt<8>("h00"))) @[MultiClockSpec.scala 18:41]
node _T_17 = add(reg2, UInt<1>("h01")) @[MultiClockSpec.scala 19:16]
node _T_18 = tail(_T_17, 1) @[MultiClockSpec.scala 19:16]
reg2 <= _T_18 @[MultiClockSpec.scala 19:8]
node _T_20 = lt(reg1, UInt<4>("h0a")) @[MultiClockSpec.scala 21:14]
when _T_20 : @[MultiClockSpec.scala 21:22]
node _T_22 = div(reg1, UInt<2>("h02")) @[MultiClockSpec.scala 22:26]
node _T_23 = eq(reg2, _T_22) @[MultiClockSpec.scala 22:17]
node _T_24 = bits(reset, 0, 0) @[MultiClockSpec.scala 22:11]
node _T_25 = or(_T_23, _T_24) @[MultiClockSpec.scala 22:11]
node _T_27 = eq(_T_25, UInt<1>("h00")) @[MultiClockSpec.scala 22:11]
when _T_27 : @[MultiClockSpec.scala 22:11]
printf(clock, UInt<1>(1), "Assertion failed\n at MultiClockSpec.scala:22 assert(reg2 === reg1 / 2.U) // 1:2 clock relationship\n") @[MultiClockSpec.scala 22:11]
stop(clock, UInt<1>(1), 1) @[MultiClockSpec.scala 22:11]
skip @[MultiClockSpec.scala 22:11]
skip @[MultiClockSpec.scala 21:22]
node _T_29 = eq(reg1, UInt<4>("h0a")) @[MultiClockSpec.scala 25:14]
when _T_29 : @[MultiClockSpec.scala 25:24]
node _T_30 = bits(reset, 0, 0) @[MultiClockSpec.scala 26:9]
node _T_32 = eq(_T_30, UInt<1>("h00")) @[MultiClockSpec.scala 26:9]
when _T_32 : @[MultiClockSpec.scala 26:9]
stop(clock, UInt<1>(1), 0) @[MultiClockSpec.scala 26:9]
skip @[MultiClockSpec.scala 26:9]
skip @[MultiClockSpec.scala 25:24]
After transforming to low Firrtl
circuit ClockDividerTest :
module ClockDividerTest :
input clock : Clock
input reset : UInt<1>
reg cDiv : UInt<1>, clock with :
reset => (UInt<1>("h0"), cDiv) @[MultiClockSpec.scala 12:21]
reg reg1 : UInt<8>, clock with :
reset => (UInt<1>("h0"), reg1) @[MultiClockSpec.scala 16:21]
reg reg2 : UInt<8>, clock2 with :
reset => (UInt<1>("h0"), reg2) @[MultiClockSpec.scala 18:41]
node _T_8 = eq(cDiv, UInt<1>("h0")) @[MultiClockSpec.scala 13:11]
node clock2 = asClock(cDiv) @[MultiClockSpec.scala 14:21]
node _T_12 = add(reg1, UInt<1>("h1")) @[MultiClockSpec.scala 17:16]
node _T_13 = tail(_T_12, 1) @[MultiClockSpec.scala 17:16]
node _T_17 = add(reg2, UInt<1>("h1")) @[MultiClockSpec.scala 19:16]
node _T_18 = tail(_T_17, 1) @[MultiClockSpec.scala 19:16]
node _T_20 = lt(reg1, UInt<4>("ha")) @[MultiClockSpec.scala 21:14]
node _T_22 = div(reg1, UInt<2>("h2")) @[MultiClockSpec.scala 22:26]
node _T_23 = eq(reg2, _T_22) @[MultiClockSpec.scala 22:17]
node _T_24 = bits(reset, 0, 0) @[MultiClockSpec.scala 22:11]
node _T_25 = or(_T_23, _T_24) @[MultiClockSpec.scala 22:11]
node _T_27 = eq(_T_25, UInt<1>("h0")) @[MultiClockSpec.scala 22:11]
node _T_29 = eq(reg1, UInt<4>("ha")) @[MultiClockSpec.scala 25:14]
node _T_30 = bits(reset, 0, 0) @[MultiClockSpec.scala 26:9]
node _T_32 = eq(_T_30, UInt<1>("h0")) @[MultiClockSpec.scala 26:9]
cDiv <= mux(reset, UInt<1>("h1"), _T_8)
reg1 <= mux(reset, UInt<8>("h0"), _T_13)
reg2 <= mux(reset, UInt<8>("h0"), _T_18)
printf(clock, and(and(and(UInt<1>("h1"), _T_20), _T_27), UInt<1>("h1")), "Assertion failed\n at MultiClockSpec.scala:22 assert(reg2 === reg1 / 2.U) // 1:2 clock relationship\n") @[MultiClockSpec.scala 22:11]
stop(clock, and(and(and(UInt<1>("h1"), _T_20), _T_27), UInt<1>("h1")), 1) @[MultiClockSpec.scala 22:11]
stop(clock, and(and(and(UInt<1>("h1"), _T_29), _T_32), UInt<1>("h1")), 0) @[MultiClockSpec.scala 26:9]
Clock2 is referenced in the reg2 declaration, this is before it is declared two statements later.
- What is the use case for changing the behavior?
This causes problems for the treadle firrtl compiler. If it is acceptable, a work-around in the compiler might be found but it seems to be the only case in which this ordering problems occurs.
- Impact There should be no functional changes other than a test that doesn’t run will run. This will have no impact on the Treadle API
Issue Analytics
- State:
- Created 6 years ago
- Comments:10 (10 by maintainers)
Top Results From Across the Web
In low Firrtl second clock referenced before declared. · Issue #749 ...
Bug Report The chisel3 MultiClockSpec ClockDividerTest is converted to low Firrtl, the firrtl is re-arranged so that clock2 is referenced before it is...
Read more >Specification for the FIRRTL Language | ASPIRE
The following example declares a module with one input port, one output ... The clock type is used to describe wires and ports...
Read more >freechipsproject/chisel3 - Gitter
I am very new to Chisel. In my Kirin_Alu.scala block, i am using the emitVerilog() function as foolow to emit the Verilog for...
Read more >firrtl 1.5.3 - firrtl.ir
Represents a statement that can be referenced in a firrtl expression. ... name: String, tpe: Type, clock: Expression, reset: Expression, init: Expression) ...
Read more >firrtl 1.4.2 - firrtl.transforms - javadoc.io
The stage package provides an implementation of the FIRRTL compiler using the firrtl.options package. ... Output form: Low FIRRTL (identity transform).
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I think the issue is that you could technically have a loop through a register back to it’s own clock, eg.
I don’t think this is common (or something anyone should be doing), but it’s technically legal FIRRTL.
It’s long overdue that we insert additional checks, at least HighFormCheck, between all transforms during testing, and probably more checks during normal compilation.
Fixed by #823