blob: 30114b99aa2808ffcd91f547ae3360be65d8a53a [file] [log] [blame]
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package common
import chisel3._
import chisel3.util._
import chisel3.simulator.scalatest.ChiselSim
import org.scalatest.freespec.AnyFreeSpec
class BasicModule extends Module {
val io = IO(new Bundle {
val in = Input(UInt(32.W))
val out = Output(UInt(32.W))
})
io.out := io.in + 1.U
}
class ValidModule extends Module {
val io = IO(new Bundle {
val in = Input(Valid(UInt(32.W)))
val out = Output(Valid(UInt(32.W)))
})
io.out := io.in.map(_ + 1.U)
}
object TrafficLight extends ChiselEnum {
val RED = Value
val YELLOW = Value
val GREEN = Value
}
class ChiselEnumModule extends Module {
val io = IO(new Bundle {
val in = Input(TrafficLight())
val out = Output(TrafficLight())
})
io.out := MuxLookup(io.in, TrafficLight.RED)(Seq(
TrafficLight.RED -> TrafficLight.GREEN,
TrafficLight.GREEN -> TrafficLight.YELLOW,
TrafficLight.YELLOW -> TrafficLight.RED,
))
}
class VectorModule extends Module {
val io = IO(new Bundle {
val in = Input(Vec(4, UInt(8.W)))
val out = Output(Vec(4, UInt(8.W)))
})
io.out := io.in
}
class KitchenSync extends Bundle {
val b = Bool()
val u = UInt(12.W)
val s = SInt(7.W)
val e = TrafficLight()
val v = Vec(3, new Bundle {
val nu = UInt(3.W)
val ns = SInt(2.W)
})
}
class KitchenSyncModule extends Module {
val io = IO(new Bundle {
val in = Flipped(Decoupled(new KitchenSync()))
val out = Decoupled(new KitchenSync())
})
io.out <> Queue(io.in, 2)
}
class GenerateInterfaceSpec extends AnyFreeSpec with ChiselSim {
"BasicModule" in {
val expectedInterface =
""" input logic [31:0] io_in,
| output logic [31:0] io_out""".stripMargin
simulate(new BasicModule()) { dut =>
val interface = GenerateInterface(dut.io, "io")
assert(interface === expectedInterface)
}
}
"ValidModule" in {
val expectedInterface =
""" input logic io_in_valid,
| input logic [31:0] io_in_bits,
| output logic io_out_valid,
| output logic [31:0] io_out_bits""".stripMargin
simulate(new ValidModule()) { dut =>
val interface = GenerateInterface(dut.io, "io")
assert(interface === expectedInterface)
}
}
"ChiselEnumModule" in {
val expectedInterface =
""" input logic [1:0] io_in,
| output logic [1:0] io_out""".stripMargin
simulate(new ChiselEnumModule()) { dut =>
val interface = GenerateInterface(dut.io, "io")
assert(interface === expectedInterface)
}
}
"VectorModule" in {
val expectedInterface =
""" input logic [7:0] io_in_0,
| input logic [7:0] io_in_1,
| input logic [7:0] io_in_2,
| input logic [7:0] io_in_3,
| output logic [7:0] io_out_0,
| output logic [7:0] io_out_1,
| output logic [7:0] io_out_2,
| output logic [7:0] io_out_3""".stripMargin
simulate(new VectorModule()) { dut =>
val interface = GenerateInterface(dut.io, "io")
assert(interface === expectedInterface)
}
}
"KitchenSyncModule" in {
val expectedInterface =
""" output logic io_in_ready,
| input logic io_in_valid,
| input logic io_in_bits_b,
| input logic [11:0] io_in_bits_u,
| input logic [6:0] io_in_bits_s,
| input logic [1:0] io_in_bits_e,
| input logic [2:0] io_in_bits_v_0_nu,
| input logic [1:0] io_in_bits_v_0_ns,
| input logic [2:0] io_in_bits_v_1_nu,
| input logic [1:0] io_in_bits_v_1_ns,
| input logic [2:0] io_in_bits_v_2_nu,
| input logic [1:0] io_in_bits_v_2_ns,
| input logic io_out_ready,
| output logic io_out_valid,
| output logic io_out_bits_b,
| output logic [11:0] io_out_bits_u,
| output logic [6:0] io_out_bits_s,
| output logic [1:0] io_out_bits_e,
| output logic [2:0] io_out_bits_v_0_nu,
| output logic [1:0] io_out_bits_v_0_ns,
| output logic [2:0] io_out_bits_v_1_nu,
| output logic [1:0] io_out_bits_v_1_ns,
| output logic [2:0] io_out_bits_v_2_nu,
| output logic [1:0] io_out_bits_v_2_ns""".stripMargin
simulate(new KitchenSyncModule()) { dut =>
val interface = GenerateInterface(dut.io, "io")
assert(interface === expectedInterface)
}
}
}