Chisel (Constructing Hardware In a Scala Embedded Language) is een hardwareconstructietaal die hardwareontwerp en verificatie vergemakkelijkt. Het is gebouwd bovenop de Scala-programmeertaal, waarbij gebruik wordt gemaakt van de expressiviteit en functionele programmeermogelijkheden om ontwerpers in staat te stellen geavanceerde hardwareontwerpen en testbenches eenvoudig te creëren. Chisel wordt voornamelijk gebruikt bij de ontwikkeling van digitale circuits, met name op het gebied van FPGA- en ASIC-ontwerp.
Chisel werd ontwikkeld als een onderzoeksproject aan de Universiteit van Californië, Berkeley, onder auspiciën van de Berkeley Architecture Research-groep. De motivatie achter de creatie was om een productievere en efficiëntere manier van hardwareontwerp te bieden in vergelijking met traditionele Hardware Description Languages (HDL's) zoals Verilog of VHDL. Door hardwareontwerp binnen een programmeertaal op hoog niveau te integreren, had Chisel als doel een betere abstractie, hogere constructies en codehergebruik te bieden.
Sinds de oprichting heeft Chisel populariteit gewonnen binnen academische en industriële omgevingen. De taal is geëvolueerd met bijdragen van talrijke ontwikkelaars, wat heeft geleid tot verbeteringen in de functies, bibliotheken en bruikbaarheid. De integratie met Scala heeft ontwerpers in staat gesteld krachtige functies zoals functioneel programmeren, typeveiligheid en geavanceerde verzamelingenbibliotheken te benutten. Chisel wordt nu veel gebruikt in moderne hardwareontwikkelingsprojecten, variërend van academisch onderzoek tot commerciële producten.
Chisel put inspiratie uit HDL's zoals Verilog en VHDL, waarbij de kernconcepten worden overgenomen en verbeterd met programmeerparadigma's uit Scala. Het heeft ook een nauwe relatie met andere hardwareconstructiekaders zoals SpinalHDL, die zich ook richten op productiviteit en expressiviteit. Chisel-ontwerpen kunnen worden omgezet in Verilog, waardoor het gebruik van bestaande synthesetools en workflows mogelijk is.
Chisel biedt een embedded Domain-Specific Language (DSL) binnen Scala, waardoor hardwareontwerpers de syntaxis van Scala kunnen gebruiken voor hardwarebeschrijving. Bijvoorbeeld, het definiëren van een eenvoudige 2-ingang multiplexer kan als volgt worden uitgedrukt:
class SimpleMux extends Module {
val io = IO(new Bundle {
val a = Input(Bool())
val b = Input(Bool())
val sel = Input(Bool())
val out = Output(Bool())
})
io.out := Mux(io.sel, io.b, io.a)
}
Chisel ondersteunt een verscheidenheid aan types en stelt ontwerpers in staat om bitbreedtes expliciet op te geven, wat betere controle biedt over het gebruik van hardwarebronnen. Bijvoorbeeld:
val myWire = Wire(UInt(8.W)) // 8-bits unsigned integer
De taal biedt abstracties voor veelvoorkomende hardwarecomponenten. Bijvoorbeeld, om een eenvoudige register te maken:
val reg = RegInit(0.U(8.W)) // 8-bits register geïnitialiseerd op 0
Chisel maakt de creatie van geparameteriseerde modules mogelijk, waardoor herbruikbare ontwerpen met verschillende configuraties mogelijk zijn:
class ParamModule(val size: Int) extends Module {
val io = IO(new Bundle {
val input = Input(UInt(size.W))
val output = Output(UInt(size.W))
})
io.output := io.input + 1.U
}
Chisel ondersteunt voorwaardelijke expressies om complexe hardwarelogica te vergemakkelijken:
val result = Mux(condition, trueValue, falseValue) // Multiplexer
Construeer modulaire hardwarecomponenten met behulp van hogere-orde functies om hardwareconfiguraties te genereren:
def makeAdder(n: Int) = new Module {
val io = IO(new Bundle {
val a = Input(UInt(n.W))
val b = Input(UInt(n.W))
val sum = Output(UInt(n.W))
})
io.sum := io.a + io.b
}
Chisel maakt het gebruik van Scala-verzamelingsutilities mogelijk om hardware-elementen effectief te manipuleren:
val wires = VecInit(Seq.fill(4)(Wire(UInt(8.W)))) // Maak een vector van 4 draden
Sequentiële logica wordt eenvoudig uitgedrukt met behulp van Chisel's speciale constructies, zoals registers:
when(condition) {
reg := newValue
} .otherwise {
reg := oldValue
}
Chisel integreert met ScalaTest, waardoor ontwikkelaars op een natuurlijke manier tests voor hun hardwareontwerpen kunnen schrijven:
class MyModuleTester extends PeekPokeTester(new MyModule) {
poke(dut.a, 1)
poke(dut.b, 0)
expect(dut.out, 1)
}
Chisel ondersteunt method chaining, waardoor beknopte en leesbare definities van complexe hardwarecircuits mogelijk zijn:
val result = (a + b).asUInt + c
Chisel kan worden ontwikkeld met elke IDE die Scala ondersteunt, zoals IntelliJ IDEA met de Scala-plugin. Daarnaast wordt sbt (Scala Build Tool) vaak gebruikt om projecten en afhankelijkheden te beheren, evenals om Chisel-projecten naar Verilog-code te compileren.
Om een Chisel-project te maken, kun je een standaard sbt-projectstructuur opzetten. Een eenvoudig build.sbt
-bestand kan er als volgt uitzien:
name := "MyChiselProject"
version := "0.1"
scalaVersion := "2.12.10"
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.4.4"
Om te bouwen, voer je sbt run
uit vanuit de opdrachtregel en de uitvoer Verilog-bestanden worden gegenereerd in de doelmap.
Chisel wordt voornamelijk gebruikt in digitaal hardwareontwerp en verificatie. Het vindt toepassingen in gebieden zoals:
Chisel onderscheidt zich van traditionele HDL's zoals Verilog en VHDL door functies te bieden die te vinden zijn in programmeertalen op hoog niveau, zoals functioneel programmeren, typeveiligheid en abstracties op hoger niveau.
Vergeleken met andere talen:
Voor het vertalen van Chisel naar andere hardwarebeschrijvingstalen kunnen tools zoals de Chisel-compiler Verilog rechtstreeks genereren vanuit Chisel-broncode. Er zijn geen algemeen bekende bron-naar-bron vertaaltools die Chisel rechtstreeks naar een andere HDL converteren, maar de gegenereerde Verilog kan indien nodig handmatig worden aangepast.
Momenteel is de meest erkende tool de Chisel-toolchain zelf, die gebruikers in staat stelt om Chisel-ontwerpen te compileren naar synthesizable Verilog-code. Er zijn ook inspanningen om Chisel te integreren met andere hardwarekaders via verschillende bibliotheken en tools, wat samenwerking en interoperabiliteit tussen verschillende hardwareontwerpmethodologieën bevordert.