aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/firrtlTests/transforms/LegalizeClocksAndAsyncResets.scala
blob: 325634282c3d117820ebc67415e54129e9122ba0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// See LICENSE for license details.

package firrtlTests.transforms

import firrtl._
import firrtl.testutils._
import firrtl.testutils.FirrtlCheckers.containLine

class LegalizeClocksTransformSpec extends FirrtlFlatSpec {
  def compile(input: String): CircuitState =
    (new MinimumVerilogCompiler).compileAndEmit(CircuitState(parse(input), ChirrtlForm), Nil)

  behavior.of("LegalizeClocksTransform")

  it should "not emit @(posedge 1'h0) for stop" in {
    val input =
      """circuit test :
        |  module test :
        |    stop(asClock(UInt(1)), UInt(1), 1)
        |""".stripMargin
    val result = compile(input)
    result should containLine(s"always @(posedge _GEN_0) begin")
    result.getEmittedCircuit.value shouldNot include("always @(posedge 1")
  }

  it should "not emit @(posedge 1'h0) for printf" in {
    val input =
      """circuit test :
        |  module test :
        |    printf(asClock(UInt(1)), UInt(1), "hi")
        |""".stripMargin
    val result = compile(input)
    result should containLine(s"always @(posedge _GEN_0) begin")
    result.getEmittedCircuit.value shouldNot include("always @(posedge 1")
  }

  it should "not emit @(posedge 1'h0) for reg" in {
    val input =
      """circuit test :
        |  module test :
        |    output out : UInt<8>
        |    input in : UInt<8>
        |    reg r : UInt<8>, asClock(UInt(0))
        |    r <= in
        |    out <= r
        |""".stripMargin
    val result = compile(input)
    result should containLine(s"always @(posedge _GEN_0) begin")
    result.getEmittedCircuit.value shouldNot include("always @(posedge 1")
  }

  it should "not emit @(posedge clock or posedge 1'h0) for a constantly deasserted areset" in {
    val input = """circuit test :
                  |  module test :
                  |    input clock : Clock
                  |    input i: UInt<1>
                  |    output z: UInt<1>
                  |    wire reset : AsyncReset
                  |    reset <= asAsyncReset(UInt<1>("h0"))
                  |    reg r : UInt<1>, clock with : (reset => (reset, UInt(0)))
                  |    r <= i
                  |    z <= r""".stripMargin
    val result = compile(input)
    result should containLine(s"always @(posedge clock or posedge _GEN_0) begin")
    result.getEmittedCircuit.value shouldNot include("always @(posedge clock or posedge 1")
  }

  it should "not emit @(posedge clock or posedge 1'h1) for a constantly asserted areset" in {
    val input = """circuit test :
                  |  module test :
                  |    input clock : Clock
                  |    input i: UInt<1>
                  |    output z: UInt<1>
                  |    wire reset : AsyncReset
                  |    reset <= asAsyncReset(UInt<1>("h1"))
                  |    reg r : UInt<1>, clock with : (reset => (reset, UInt(0)))
                  |    r <= i
                  |    z <= r""".stripMargin
    val result = compile(input)
    result should containLine(s"always @(posedge clock or posedge _GEN_0) begin")
    result.getEmittedCircuit.value shouldNot include("always @(posedge clock or posedge 1")
  }

  it should "not emit @(posedge 1'h0 or posedge 1'h0) for a reg with tied off clocks and areset" in {
    val input = """circuit test :
                  |  module test :
                  |    input i: UInt<1>
                  |    output z: UInt<1>
                  |    wire clock : Clock
                  |    clock <= asClock(UInt(1))
                  |    wire reset : AsyncReset
                  |    reset <= asAsyncReset(UInt<1>("h0"))
                  |    reg r : UInt<1>, clock with : (reset => (reset, UInt(0)))
                  |    r <= i
                  |    z <= r""".stripMargin
    val result = compile(input)
    result should containLine(s"always @(posedge _GEN_0 or posedge _GEN_1) begin")
    result.getEmittedCircuit.value shouldNot include("always @(posedge clock or posedge 1")
    result.getEmittedCircuit.value shouldNot include("or posedge 1")
  }

  it should "deduplicate injected nodes for literal clocks" in {
    val input =
      """circuit test :
        |  module test :
        |    printf(asClock(UInt(1)), UInt(1), "hi")
        |    stop(asClock(UInt(1)), UInt(1), 1)
        |""".stripMargin
    val result = compile(input)
    result should containLine(s"wire  _GEN_0 = 1'h1;")
    // Check that there's only 1 _GEN_0 instantiation
    val verilog = result.getEmittedCircuit.value
    val matches = "wire\\s+_GEN_0\\s+=\\s+1'h1".r.findAllIn(verilog)
    matches.size should be(1)

  }
}