question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

In low Firrtl second clock referenced before declared.

See original GitHub issue

This 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:closed
  • Created 6 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
jackkoenigcommented, Mar 2, 2018

I think the issue is that you could technically have a loop through a register back to it’s own clock, eg.

wire clockWire : Clock
reg r : UInt<1>, clockWire
clockWire <= asClock(r)

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.

0reactions
jackkoenigcommented, Jun 22, 2018

Fixed by #823

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found