summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala
blob: 64aabb4b14544af2d8fc3b15ac0596da35539b32 (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
// SPDX-License-Identifier: Apache-2.0

package chiselTests
package experimental

import chisel3._
import chisel3.stage.ChiselStage

// NOTE This is currently an experimental API and subject to change
// Example using a private port
class PrivatePort extends NamedModuleTester {
  private val port = expectName(IO(Input(UInt(8.W))), "foo")
  port.suggestName("foo")
}

// Example of using composition to add ports to a Module
class CompositionalPort(module: NamedModuleTester, name: String) {
  import chisel3.experimental.IO
  val foo = module.expectName(IO(Output(Bool())), name)
  foo.suggestName(name)
  foo := true.B
}

class CompositionalPortTester extends NamedModuleTester {
  val a = new CompositionalPort(this, "cheese")
  val b = new CompositionalPort(this, "tart")
}

class PortsWinTester extends NamedModuleTester {
  val wire = expectName(Wire(UInt()), "wire_1")
  val foo = expectName(Wire(UInt()).suggestName("wire"), "wire_2")
  val output = expectName(IO(Output(UInt())).suggestName("wire"), "wire")
}

class ProgrammaticPortsSpec extends ChiselFlatSpec with Utils {

  private def doTest(testMod: => NamedModuleTester): Unit = {
    var module: NamedModuleTester = null
    ChiselStage.elaborate { module = testMod; module }
    assert(module.getNameFailures() == Nil)
  }

  "Programmatic port creation" should "be supported" in {
    doTest(new PrivatePort)
  }

  "Calling IO outside of a Module definition" should "be supported" in {
    doTest(new CompositionalPortTester)
  }

  "Ports" should "always win over internal components in naming" in {
    doTest(new PortsWinTester)
  }

  "Module" should "ignore suggestName on clock and reset" in {
    doTest(new Module with NamedModuleTester {
      val io = IO(new Bundle {
        val foo = Output(UInt(8.W))
      })
      expectName(clock.suggestName("tart"), "clock")
      expectName(reset.suggestName("teser"), "reset")
    })
  }

  "SuggestName collisions on ports" should "be illegal" in {
    a[ChiselException] should be thrownBy extractCause[ChiselException] {
      ChiselStage.elaborate(new Module {
        val foo = IO(UInt(8.W)).suggestName("apple")
        val bar = IO(UInt(8.W)).suggestName("apple")
      })
    }
  }
}