Chisel (Constructing Hardware In a Scala Embedded Language) er eit språk for konstruksjon av maskinvare som legg til rette for design og verifisering av maskinvare. Det er bygd på toppen av programmeringsspråket Scala, og utnyttar uttrykksfullheita og funksjonell programmering for å gjere det enklare for designarar å lage sofistikerte maskinvaredesign og testbenkar. Chisel blir primært brukt i utvikling av digitale kretser, spesielt innan FPGA- og ASIC-design.
Chisel blei utvikla som eit forskingsprosjekt ved Universitetet i California, Berkeley, under leiing av Berkeley Architecture Research-gruppa. Motivasjonen bak opprettinga var å tilby ein meir produktiv og effektiv måte å designe maskinvare på samanlikna med tradisjonelle maskinvarebeskrivingsspråk (HDL) som Verilog eller VHDL. Ved å integrere maskinvaredesign i eit høgnivå programmeringsspråk, hadde Chisel som mål å tilby betre abstraksjon, høgnivå konstruksjonar og gjenbruk av kode.
Sidan starten har Chisel fått popularitet innan akademiske og industrielle miljø. Språket har utvikla seg med bidrag frå mange utviklarar, noko som har ført til forbetringar i funksjonar, bibliotek og brukervennlegheit. Integrasjonen med Scala har gjort det mogleg for designarar å utnytte kraftige funksjonar som funksjonell programmering, typesikkerheit og avanserte samlingsbibliotek. Chisel blir no mykje brukt i moderne maskinvareutviklingsprosjekt, frå akademisk forsking til kommersielle produkt.
Chisel hentar inspirasjon frå HDL-ar som Verilog og VHDL, og låner deira kjerneomgrep samtidig som det forsterkar dei med programmeringsparadigmar frå Scala. Det har også nært forhold til andre rammeverk for maskinvarekonstruksjon som SpinalHDL, som på liknande måte fokuserer på produktivitet og uttrykksfullheit. Chisel-design kan bli konvertert til Verilog, noko som gjer det mogleg å bruke eksisterande synteseverktøy og arbeidsflytar.
Chisel tilbyr ein innebygd domene-spesifikk språk (DSL) innan Scala, som gjer det mogleg for maskinvaredesignarar å bruke Scala sin syntaks for maskinvarebeskriving. For eksempel kan definisjonen av ein enkel 2-inngangs multiplexer uttrykkast som:
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 støttar eit mangfald av typar og gjer det mogleg for designarar å spesifisere bitbreiddar eksplisitt, noko som gir betre kontroll over utnytting av maskinvareressursar. For eksempel:
val myWire = Wire(UInt(8.W)) // 8-bit usignert heiltal
Språket tilbyr abstraksjonar for vanlege maskinvarekomponentar. For eksempel, for å lage eit enkelt register:
val reg = RegInit(0.U(8.W)) // 8-bit register initialisert til 0
Chisel gjer det mogleg å lage parametriserte modul, som gjer det mogleg å gjenbruke design med ulike konfigurasjonar:
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 støttar betinga utrykk for å lette kompleks maskinvarelogikk:
val result = Mux(condition, trueValue, falseValue) // Multiplexer
Konstruer modulære maskinvarekomponentar ved å bruke høgare ordens funksjonar for å generere maskinvarekonfigurasjonar:
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 gjer det mogleg å bruke Scala-samlingsverktøy for å manipulere maskinvareelement effektivt:
val wires = VecInit(Seq.fill(4)(Wire(UInt(8.W)))) // Lag ein vektor med 4 ledningar
Sekvensiell logikk blir uttrykt enkelt ved å bruke Chisel sine dedikerte konstruksjonar, som register:
when(condition) {
reg := newValue
} .otherwise {
reg := oldValue
}
Chisel integrerer med ScalaTest, noko som gjer det mogleg for utviklarar å skrive testar for maskinvaredesigna sine på ein naturleg måte:
class MyModuleTester extends PeekPokeTester(new MyModule) {
poke(dut.a, 1)
poke(dut.b, 0)
expect(dut.out, 1)
}
Chisel støttar kjeding av metodar, noko som gjer det mogleg å definere komplekse maskinvarekretser på ein kortfatta og lesbar måte:
val result = (a + b).asUInt + c
Chisel kan utviklast ved hjelp av ein kvar IDE som støttar Scala, som IntelliJ IDEA med Scala-plugin. I tillegg blir sbt (Scala Build Tool) ofte brukt for å administrere prosjekt og avhengigheiter, samt for å kompilere Chisel-prosjekt til Verilog-kode.
For å opprette eit Chisel-prosjekt kan du sette opp ein standard sbt-prosjektstruktur. Ein enkel build.sbt
-fil kan sjå slik ut:
name := "MyChiselProject"
version := "0.1"
scalaVersion := "2.12.10"
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % "3.4.4"
For å bygge, kan du køyre sbt run
frå kommandolinja, og dei genererte Verilog-filene vil bli laga i mål-mappa.
Chisel blir hovudsakleg brukt i design og verifisering av digital maskinvare. Det finn applikasjonar innan områda som:
Chisel skiller seg frå tradisjonelle HDL-ar som Verilog og VHDL ved å tilby funksjonar som finst i høgnivå programmeringsspråk, som funksjonell programmering, typesikkerheit og høgnivå abstraksjonar.
Samanlikna med andre språk:
For å oversette Chisel til andre maskinvarebeskrivingsspråk, kan verktøy som Chisel-kompilatoren generere Verilog direkte frå Chisel-kildekode. Det finst ingen allment kjente kilde-til-kilde oversettingsverktøy som konverterer Chisel direkte til ein annan HDL, men den genererte Verilog-koden kan tilpassast manuelt om nødvendig.
For tida er det mest kjente verktøyet Chisel-verktøykjeda sjølv, som gjer det mogleg for brukarar å kompilere Chisel-design til syntetiserbar Verilog-kode. Det er også arbeid for å integrere Chisel med andre maskinvare-rammeverk gjennom ulike bibliotek og verktøy, noko som fremjar samarbeid og interoperabilitet mellom ulike metodar for maskinvaredesign.