Add exercises
This commit is contained in:
commit
ac3cf23632
19 changed files with 21160 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
simWorkspace/
|
||||
target/
|
||||
tmp/
|
||||
project/
|
||||
*.v
|
||||
6
Exercises/.gitignore
vendored
Normal file
6
Exercises/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
*.v
|
||||
.idea/
|
||||
project/
|
||||
simWorkspace/
|
||||
target/
|
||||
tmp/
|
||||
13
Exercises/build.sbt
Normal file
13
Exercises/build.sbt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name := "SpinalExercises"
|
||||
version := "0.1"
|
||||
|
||||
scalaVersion := "2.11.12"
|
||||
val spinalVersion = "1.7.3"
|
||||
|
||||
fork := true
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.spinalhdl" % "spinalhdl-core_2.11" % spinalVersion,
|
||||
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % spinalVersion,
|
||||
compilerPlugin("com.github.spinalhdl" % "spinalhdl-idsl-plugin_2.11" % spinalVersion)
|
||||
)
|
||||
16
Exercises/src/main/scala/examples/Counter16.scala
Normal file
16
Exercises/src/main/scala/examples/Counter16.scala
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package examples
|
||||
|
||||
import spinal.core._
|
||||
|
||||
class Counter16 extends Component {
|
||||
val enable = in(Bool)
|
||||
val counter = out(UInt(16 bits))
|
||||
|
||||
val lsb = new Counter8
|
||||
lsb.enable := enable
|
||||
|
||||
val msb = new Counter8
|
||||
msb.enable := enable && (lsb.counter === 0xff);
|
||||
|
||||
counter := msb.counter @@ lsb.counter
|
||||
}
|
||||
16
Exercises/src/main/scala/examples/Counter8.scala
Normal file
16
Exercises/src/main/scala/examples/Counter8.scala
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package examples
|
||||
|
||||
import spinal.core._
|
||||
|
||||
class Counter8 extends Component {
|
||||
val enable = in(Bool)
|
||||
val counter = out(Reg(UInt(8 bits)).init(0))
|
||||
|
||||
def count(): Unit = {
|
||||
enable := True
|
||||
}
|
||||
|
||||
when (enable) {
|
||||
counter := counter + 1
|
||||
}
|
||||
}
|
||||
30
Exercises/src/main/scala/examples/Spi.scala
Normal file
30
Exercises/src/main/scala/examples/Spi.scala
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package examples
|
||||
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
class SpiBus(numSlaves: Int = 1) extends Bundle with IMasterSlave {
|
||||
val sclk = Bool
|
||||
val mosi = Bool
|
||||
val miso = Bool
|
||||
val ss = Bits(numSlaves bits)
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
out(sclk, mosi, ss)
|
||||
in(ss)
|
||||
}
|
||||
}
|
||||
|
||||
class SpiMaster extends Component {
|
||||
val bus = master(new SpiBus)
|
||||
}
|
||||
|
||||
class SpiSlave extends Component {
|
||||
val bus = slave(new SpiBus)
|
||||
}
|
||||
|
||||
class Soc extends Component {
|
||||
val spiMaster = new SpiMaster
|
||||
val spiSlave = new SpiSlave
|
||||
spiMaster.bus <> spiSlave.bus
|
||||
}
|
||||
27
Exercises/src/main/scala/examples/Top.scala
Normal file
27
Exercises/src/main/scala/examples/Top.scala
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package examples
|
||||
|
||||
import spinal.core._
|
||||
import spinal.core.sim._
|
||||
|
||||
object CounterGen {
|
||||
def main(args: Array[String]): Unit = {
|
||||
SpinalVerilog(new Counter16)
|
||||
}
|
||||
}
|
||||
|
||||
object CounterSim {
|
||||
def main(args: Array[String]) {
|
||||
SimConfig.withWave.compile(new Counter16).doSim {dut =>
|
||||
dut.enable #= true
|
||||
|
||||
dut.clockDomain.forkStimulus(10)
|
||||
|
||||
var tick = 0
|
||||
|
||||
while (tick < 256 * 256) {
|
||||
dut.clockDomain.waitSampling()
|
||||
tick += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Exercises/src/main/scala/exercises/Popcnt.scala
Normal file
15
Exercises/src/main/scala/exercises/Popcnt.scala
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package exercises
|
||||
|
||||
import spinal.core._
|
||||
|
||||
class Popcnt(width: BitCount = 4 bits, multiCycle: Boolean = false) extends Component {
|
||||
// Replace these by the correct I/O ports
|
||||
val start, ready = Bool
|
||||
val value, count = UInt(42 bits)
|
||||
|
||||
if (!multiCycle) {
|
||||
// Implement asynchronous logic here.
|
||||
} else {
|
||||
// Implement multi-cycle logic here.
|
||||
}
|
||||
}
|
||||
14
Exercises/src/main/scala/exercises/ShiftReg.scala
Normal file
14
Exercises/src/main/scala/exercises/ShiftReg.scala
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package exercises
|
||||
|
||||
import spinal.core._
|
||||
|
||||
|
||||
class ShiftReg extends Component {
|
||||
def addReg(name: String, width: BitCount, delay: Int): (Bits, Bits) = {
|
||||
(null, null)
|
||||
}
|
||||
|
||||
def getReg(name: String): (Bits, Bits) = {
|
||||
(null, null)
|
||||
}
|
||||
}
|
||||
55
Exercises/src/main/scala/exercises/Top.scala
Normal file
55
Exercises/src/main/scala/exercises/Top.scala
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package exercises
|
||||
|
||||
import spinal.core._
|
||||
import spinal.core.sim._
|
||||
|
||||
object PopcntSim {
|
||||
def runSim(width: BitCount, multiCycle: Boolean, input: Int): Unit = {
|
||||
SimConfig.withWave.compile(new Popcnt(width, multiCycle)).doSim {dut =>
|
||||
dut.clockDomain.forkStimulus(10)
|
||||
|
||||
dut.value #= input
|
||||
dut.start #= true
|
||||
dut.clockDomain.waitSampling()
|
||||
dut.start #= false
|
||||
|
||||
while (!dut.ready.toBoolean) {
|
||||
dut.clockDomain.waitSampling()
|
||||
}
|
||||
|
||||
dut.clockDomain.waitSampling()
|
||||
println(s"popcnt($input) = ${dut.count.toBigInt}")
|
||||
}
|
||||
}
|
||||
|
||||
def main(args: Array[String]) {
|
||||
runSim(4 bits, false, 15)
|
||||
}
|
||||
}
|
||||
|
||||
object ShiftRegSim {
|
||||
def createShiftReg: ShiftReg = {
|
||||
val sr = new ShiftReg
|
||||
sr.addReg("foo", 8 bits, 3)
|
||||
sr.addReg("bar", 16 bits, 5)
|
||||
sr
|
||||
}
|
||||
|
||||
def main(args: Array[String]) {
|
||||
SimConfig.withWave.compile(createShiftReg).doSim {dut =>
|
||||
dut.clockDomain.forkStimulus(10)
|
||||
|
||||
val (fooIn, fooOut) = dut.getReg("foo")
|
||||
val (barIn, barOut) = dut.getReg("bar")
|
||||
|
||||
var tick = 0
|
||||
|
||||
while (tick < 10) {
|
||||
fooIn #= tick
|
||||
barIn #= 10 - tick
|
||||
dut.clockDomain.waitSampling()
|
||||
tick += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
Images/.gitignore
vendored
Normal file
5
Images/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
*.aux
|
||||
*.fdb_latexmk
|
||||
*.fls
|
||||
*.log
|
||||
*.pdf
|
||||
7
Images/Makefile
Normal file
7
Images/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
all: shift_reg.svg
|
||||
|
||||
%.svg: %.pdf
|
||||
pdf2svg $< $@
|
||||
|
||||
%.pdf: %.tex
|
||||
latexmk -pdf $<
|
||||
20155
Images/circuitikz.sty
Normal file
20155
Images/circuitikz.sty
Normal file
File diff suppressed because it is too large
Load diff
209
Images/shift_reg.svg
Normal file
209
Images/shift_reg.svg
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="373.521" height="107.453" viewBox="0 0 373.521 107.453">
|
||||
<defs>
|
||||
<g>
|
||||
<g id="glyph-0-0">
|
||||
</g>
|
||||
<g id="glyph-0-1">
|
||||
<path d="M 2.0625 -5.421875 C 2.0625 -5.734375 2.078125 -5.84375 2.796875 -5.84375 L 3.015625 -5.84375 L 3.015625 -6.125 C 2.65625 -6.09375 2.046875 -6.09375 1.65625 -6.09375 C 1.28125 -6.09375 0.65625 -6.09375 0.296875 -6.125 L 0.296875 -5.84375 L 0.515625 -5.84375 C 1.234375 -5.84375 1.25 -5.734375 1.25 -5.421875 L 1.25 -0.703125 C 1.25 -0.390625 1.234375 -0.28125 0.515625 -0.28125 L 0.296875 -0.28125 L 0.296875 0 C 0.65625 -0.03125 1.28125 -0.03125 1.65625 -0.03125 C 2.046875 -0.03125 2.65625 -0.03125 3.015625 0 L 3.015625 -0.28125 L 2.796875 -0.28125 C 2.078125 -0.28125 2.0625 -0.390625 2.0625 -0.703125 Z M 2.0625 -5.421875 "/>
|
||||
</g>
|
||||
<g id="glyph-0-2">
|
||||
<path d="M 6.640625 -3.046875 C 6.640625 -4.875 5.25 -6.328125 3.578125 -6.328125 C 1.90625 -6.328125 0.515625 -4.859375 0.515625 -3.046875 C 0.515625 -1.21875 1.90625 0.203125 3.578125 0.203125 C 5.25 0.203125 6.640625 -1.21875 6.640625 -3.046875 Z M 3.578125 -0.078125 C 2.671875 -0.078125 1.421875 -0.859375 1.421875 -3.171875 C 1.421875 -5.359375 2.703125 -6.078125 3.578125 -6.078125 C 4.453125 -6.078125 5.734375 -5.359375 5.734375 -3.171875 C 5.734375 -0.859375 4.484375 -0.078125 3.578125 -0.078125 Z M 3.578125 -0.078125 "/>
|
||||
</g>
|
||||
<g id="glyph-1-0">
|
||||
</g>
|
||||
<g id="glyph-1-1">
|
||||
<path d="M 1.75 -4.296875 L 1.75 -5.453125 C 1.75 -6.328125 2.21875 -6.8125 2.65625 -6.8125 C 2.6875 -6.8125 2.84375 -6.8125 2.984375 -6.734375 C 2.875 -6.703125 2.6875 -6.5625 2.6875 -6.3125 C 2.6875 -6.09375 2.84375 -5.890625 3.125 -5.890625 C 3.40625 -5.890625 3.5625 -6.09375 3.5625 -6.328125 C 3.5625 -6.703125 3.1875 -7.03125 2.65625 -7.03125 C 1.96875 -7.03125 1.109375 -6.5 1.109375 -5.4375 L 1.109375 -4.296875 L 0.328125 -4.296875 L 0.328125 -3.984375 L 1.109375 -3.984375 L 1.109375 -0.75 C 1.109375 -0.3125 1 -0.3125 0.34375 -0.3125 L 0.34375 0 C 0.734375 -0.015625 1.203125 -0.03125 1.46875 -0.03125 C 1.875 -0.03125 2.34375 -0.03125 2.734375 0 L 2.734375 -0.3125 L 2.53125 -0.3125 C 1.796875 -0.3125 1.78125 -0.421875 1.78125 -0.78125 L 1.78125 -3.984375 L 2.90625 -3.984375 L 2.90625 -4.296875 Z M 1.75 -4.296875 "/>
|
||||
</g>
|
||||
<g id="glyph-1-2">
|
||||
<path d="M 4.6875 -2.140625 C 4.6875 -3.40625 3.703125 -4.46875 2.5 -4.46875 C 1.25 -4.46875 0.28125 -3.375 0.28125 -2.140625 C 0.28125 -0.84375 1.3125 0.109375 2.484375 0.109375 C 3.6875 0.109375 4.6875 -0.875 4.6875 -2.140625 Z M 2.5 -0.140625 C 2.0625 -0.140625 1.625 -0.34375 1.359375 -0.8125 C 1.109375 -1.25 1.109375 -1.859375 1.109375 -2.21875 C 1.109375 -2.609375 1.109375 -3.140625 1.34375 -3.578125 C 1.609375 -4.03125 2.078125 -4.25 2.484375 -4.25 C 2.921875 -4.25 3.34375 -4.03125 3.609375 -3.59375 C 3.875 -3.171875 3.875 -2.59375 3.875 -2.21875 C 3.875 -1.859375 3.875 -1.3125 3.65625 -0.875 C 3.421875 -0.421875 2.984375 -0.140625 2.5 -0.140625 Z M 2.5 -0.140625 "/>
|
||||
</g>
|
||||
<g id="glyph-1-3">
|
||||
<path d="M 4.578125 -3.1875 C 4.578125 -3.984375 4.53125 -4.78125 4.1875 -5.515625 C 3.734375 -6.484375 2.90625 -6.640625 2.5 -6.640625 C 1.890625 -6.640625 1.171875 -6.375 0.75 -5.453125 C 0.4375 -4.765625 0.390625 -3.984375 0.390625 -3.1875 C 0.390625 -2.4375 0.421875 -1.546875 0.84375 -0.78125 C 1.265625 0.015625 2 0.21875 2.484375 0.21875 C 3.015625 0.21875 3.78125 0.015625 4.21875 -0.9375 C 4.53125 -1.625 4.578125 -2.40625 4.578125 -3.1875 Z M 2.484375 0 C 2.09375 0 1.5 -0.25 1.328125 -1.203125 C 1.21875 -1.796875 1.21875 -2.71875 1.21875 -3.3125 C 1.21875 -3.953125 1.21875 -4.609375 1.296875 -5.140625 C 1.484375 -6.328125 2.234375 -6.421875 2.484375 -6.421875 C 2.8125 -6.421875 3.46875 -6.234375 3.65625 -5.25 C 3.765625 -4.6875 3.765625 -3.9375 3.765625 -3.3125 C 3.765625 -2.5625 3.765625 -1.890625 3.65625 -1.25 C 3.5 -0.296875 2.9375 0 2.484375 0 Z M 2.484375 0 "/>
|
||||
</g>
|
||||
<g id="glyph-1-4">
|
||||
<path d="M 2.546875 2.5 L 2.546875 2.09375 L 1.578125 2.09375 L 1.578125 -7.078125 L 2.546875 -7.078125 L 2.546875 -7.484375 L 1.171875 -7.484375 L 1.171875 2.5 Z M 2.546875 2.5 "/>
|
||||
</g>
|
||||
<g id="glyph-1-5">
|
||||
<path d="M 4.75 -6.078125 C 4.828125 -6.1875 4.828125 -6.203125 4.828125 -6.421875 L 2.40625 -6.421875 C 1.203125 -6.421875 1.171875 -6.546875 1.140625 -6.734375 L 0.890625 -6.734375 L 0.5625 -4.6875 L 0.8125 -4.6875 C 0.84375 -4.84375 0.921875 -5.46875 1.0625 -5.59375 C 1.125 -5.65625 1.90625 -5.65625 2.03125 -5.65625 L 4.09375 -5.65625 C 3.984375 -5.5 3.203125 -4.40625 2.984375 -4.078125 C 2.078125 -2.734375 1.75 -1.34375 1.75 -0.328125 C 1.75 -0.234375 1.75 0.21875 2.21875 0.21875 C 2.671875 0.21875 2.671875 -0.234375 2.671875 -0.328125 L 2.671875 -0.84375 C 2.671875 -1.390625 2.703125 -1.9375 2.78125 -2.46875 C 2.828125 -2.703125 2.953125 -3.5625 3.40625 -4.171875 Z M 4.75 -6.078125 "/>
|
||||
</g>
|
||||
<g id="glyph-1-6">
|
||||
<path d="M 1.90625 -3.765625 C 1.90625 -4.0625 1.671875 -4.296875 1.390625 -4.296875 C 1.09375 -4.296875 0.859375 -4.0625 0.859375 -3.765625 C 0.859375 -3.484375 1.09375 -3.234375 1.390625 -3.234375 C 1.671875 -3.234375 1.90625 -3.484375 1.90625 -3.765625 Z M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 "/>
|
||||
</g>
|
||||
<g id="glyph-1-7">
|
||||
<path d="M 1.578125 -7.484375 L 0.21875 -7.484375 L 0.21875 -7.078125 L 1.1875 -7.078125 L 1.1875 2.09375 L 0.21875 2.09375 L 0.21875 2.5 L 1.578125 2.5 Z M 1.578125 -7.484375 "/>
|
||||
</g>
|
||||
<g id="glyph-1-8">
|
||||
<path d="M 2.9375 -6.375 C 2.9375 -6.625 2.9375 -6.640625 2.703125 -6.640625 C 2.078125 -6 1.203125 -6 0.890625 -6 L 0.890625 -5.6875 C 1.09375 -5.6875 1.671875 -5.6875 2.1875 -5.953125 L 2.1875 -0.78125 C 2.1875 -0.421875 2.15625 -0.3125 1.265625 -0.3125 L 0.953125 -0.3125 L 0.953125 0 C 1.296875 -0.03125 2.15625 -0.03125 2.5625 -0.03125 C 2.953125 -0.03125 3.828125 -0.03125 4.171875 0 L 4.171875 -0.3125 L 3.859375 -0.3125 C 2.953125 -0.3125 2.9375 -0.421875 2.9375 -0.78125 Z M 2.9375 -6.375 "/>
|
||||
</g>
|
||||
<g id="glyph-1-9">
|
||||
<path d="M 1.265625 -0.765625 L 2.328125 -1.796875 C 3.875 -3.171875 4.46875 -3.703125 4.46875 -4.703125 C 4.46875 -5.84375 3.578125 -6.640625 2.359375 -6.640625 C 1.234375 -6.640625 0.5 -5.71875 0.5 -4.828125 C 0.5 -4.28125 1 -4.28125 1.03125 -4.28125 C 1.203125 -4.28125 1.546875 -4.390625 1.546875 -4.8125 C 1.546875 -5.0625 1.359375 -5.328125 1.015625 -5.328125 C 0.9375 -5.328125 0.921875 -5.328125 0.890625 -5.3125 C 1.109375 -5.96875 1.65625 -6.328125 2.234375 -6.328125 C 3.140625 -6.328125 3.5625 -5.515625 3.5625 -4.703125 C 3.5625 -3.90625 3.078125 -3.125 2.515625 -2.5 L 0.609375 -0.375 C 0.5 -0.265625 0.5 -0.234375 0.5 0 L 4.203125 0 L 4.46875 -1.734375 L 4.234375 -1.734375 C 4.171875 -1.4375 4.109375 -1 4 -0.84375 C 3.9375 -0.765625 3.28125 -0.765625 3.0625 -0.765625 Z M 1.265625 -0.765625 "/>
|
||||
</g>
|
||||
<g id="glyph-1-10">
|
||||
<path d="M 3.484375 -3.875 L 2.203125 -4.171875 C 1.578125 -4.328125 1.203125 -4.859375 1.203125 -5.4375 C 1.203125 -6.140625 1.734375 -6.75 2.515625 -6.75 C 4.171875 -6.75 4.390625 -5.109375 4.453125 -4.671875 C 4.46875 -4.609375 4.46875 -4.546875 4.578125 -4.546875 C 4.703125 -4.546875 4.703125 -4.59375 4.703125 -4.78125 L 4.703125 -6.78125 C 4.703125 -6.953125 4.703125 -7.03125 4.59375 -7.03125 C 4.53125 -7.03125 4.515625 -7.015625 4.453125 -6.890625 L 4.09375 -6.328125 C 3.796875 -6.625 3.390625 -7.03125 2.5 -7.03125 C 1.390625 -7.03125 0.5625 -6.15625 0.5625 -5.09375 C 0.5625 -4.265625 1.09375 -3.53125 1.859375 -3.265625 C 1.96875 -3.234375 2.484375 -3.109375 3.1875 -2.9375 C 3.453125 -2.875 3.75 -2.796875 4.03125 -2.4375 C 4.234375 -2.171875 4.34375 -1.84375 4.34375 -1.515625 C 4.34375 -0.8125 3.84375 -0.09375 3 -0.09375 C 2.71875 -0.09375 1.953125 -0.140625 1.421875 -0.625 C 0.84375 -1.171875 0.8125 -1.796875 0.8125 -2.15625 C 0.796875 -2.265625 0.71875 -2.265625 0.6875 -2.265625 C 0.5625 -2.265625 0.5625 -2.1875 0.5625 -2.015625 L 0.5625 -0.015625 C 0.5625 0.15625 0.5625 0.21875 0.671875 0.21875 C 0.734375 0.21875 0.75 0.203125 0.8125 0.09375 C 0.8125 0.078125 0.84375 0.046875 1.171875 -0.484375 C 1.484375 -0.140625 2.125 0.21875 3.015625 0.21875 C 4.171875 0.21875 4.96875 -0.75 4.96875 -1.859375 C 4.96875 -2.84375 4.3125 -3.671875 3.484375 -3.875 Z M 3.484375 -3.875 "/>
|
||||
</g>
|
||||
<g id="glyph-1-11">
|
||||
<path d="M 1.09375 -0.75 C 1.09375 -0.3125 0.984375 -0.3125 0.3125 -0.3125 L 0.3125 0 C 0.671875 -0.015625 1.171875 -0.03125 1.453125 -0.03125 C 1.703125 -0.03125 2.21875 -0.015625 2.5625 0 L 2.5625 -0.3125 C 1.890625 -0.3125 1.78125 -0.3125 1.78125 -0.75 L 1.78125 -2.59375 C 1.78125 -3.625 2.5 -4.1875 3.125 -4.1875 C 3.765625 -4.1875 3.875 -3.65625 3.875 -3.078125 L 3.875 -0.75 C 3.875 -0.3125 3.765625 -0.3125 3.09375 -0.3125 L 3.09375 0 C 3.4375 -0.015625 3.953125 -0.03125 4.21875 -0.03125 C 4.46875 -0.03125 5 -0.015625 5.328125 0 L 5.328125 -0.3125 C 4.8125 -0.3125 4.5625 -0.3125 4.5625 -0.609375 L 4.5625 -2.515625 C 4.5625 -3.375 4.5625 -3.671875 4.25 -4.03125 C 4.109375 -4.203125 3.78125 -4.40625 3.203125 -4.40625 C 2.359375 -4.40625 1.921875 -3.8125 1.75 -3.421875 L 1.75 -6.921875 L 0.3125 -6.8125 L 0.3125 -6.5 C 1.015625 -6.5 1.09375 -6.4375 1.09375 -5.9375 Z M 1.09375 -0.75 "/>
|
||||
</g>
|
||||
<g id="glyph-1-12">
|
||||
<path d="M 1.765625 -4.40625 L 0.375 -4.296875 L 0.375 -3.984375 C 1.015625 -3.984375 1.109375 -3.921875 1.109375 -3.4375 L 1.109375 -0.75 C 1.109375 -0.3125 1 -0.3125 0.328125 -0.3125 L 0.328125 0 C 0.640625 -0.015625 1.1875 -0.03125 1.421875 -0.03125 C 1.78125 -0.03125 2.125 -0.015625 2.46875 0 L 2.46875 -0.3125 C 1.796875 -0.3125 1.765625 -0.359375 1.765625 -0.75 Z M 1.796875 -6.140625 C 1.796875 -6.453125 1.5625 -6.671875 1.28125 -6.671875 C 0.96875 -6.671875 0.75 -6.40625 0.75 -6.140625 C 0.75 -5.875 0.96875 -5.609375 1.28125 -5.609375 C 1.5625 -5.609375 1.796875 -5.828125 1.796875 -6.140625 Z M 1.796875 -6.140625 "/>
|
||||
</g>
|
||||
<g id="glyph-1-13">
|
||||
<path d="M 1.71875 -3.984375 L 3.15625 -3.984375 L 3.15625 -4.296875 L 1.71875 -4.296875 L 1.71875 -6.125 L 1.46875 -6.125 C 1.46875 -5.3125 1.171875 -4.25 0.1875 -4.203125 L 0.1875 -3.984375 L 1.03125 -3.984375 L 1.03125 -1.234375 C 1.03125 -0.015625 1.96875 0.109375 2.328125 0.109375 C 3.03125 0.109375 3.3125 -0.59375 3.3125 -1.234375 L 3.3125 -1.796875 L 3.0625 -1.796875 L 3.0625 -1.25 C 3.0625 -0.515625 2.765625 -0.140625 2.390625 -0.140625 C 1.71875 -0.140625 1.71875 -1.046875 1.71875 -1.21875 Z M 1.71875 -3.984375 "/>
|
||||
</g>
|
||||
<g id="glyph-1-14">
|
||||
<path d="M 2.234375 -3.515625 L 2.234375 -6.09375 C 2.234375 -6.328125 2.234375 -6.453125 2.453125 -6.484375 C 2.546875 -6.5 2.84375 -6.5 3.046875 -6.5 C 3.9375 -6.5 5.046875 -6.453125 5.046875 -5.015625 C 5.046875 -4.328125 4.8125 -3.515625 3.34375 -3.515625 Z M 4.34375 -3.390625 C 5.296875 -3.625 6.078125 -4.234375 6.078125 -5.015625 C 6.078125 -5.96875 4.9375 -6.8125 3.484375 -6.8125 L 0.34375 -6.8125 L 0.34375 -6.5 L 0.59375 -6.5 C 1.359375 -6.5 1.375 -6.390625 1.375 -6.03125 L 1.375 -0.78125 C 1.375 -0.421875 1.359375 -0.3125 0.59375 -0.3125 L 0.34375 -0.3125 L 0.34375 0 C 0.703125 -0.03125 1.421875 -0.03125 1.796875 -0.03125 C 2.1875 -0.03125 2.90625 -0.03125 3.265625 0 L 3.265625 -0.3125 L 3.015625 -0.3125 C 2.25 -0.3125 2.234375 -0.421875 2.234375 -0.78125 L 2.234375 -3.296875 L 3.375 -3.296875 C 3.53125 -3.296875 3.953125 -3.296875 4.3125 -2.953125 C 4.6875 -2.609375 4.6875 -2.296875 4.6875 -1.625 C 4.6875 -0.984375 4.6875 -0.578125 5.09375 -0.203125 C 5.5 0.15625 6.046875 0.21875 6.34375 0.21875 C 7.125 0.21875 7.296875 -0.59375 7.296875 -0.875 C 7.296875 -0.9375 7.296875 -1.046875 7.171875 -1.046875 C 7.0625 -1.046875 7.0625 -0.953125 7.046875 -0.890625 C 6.984375 -0.171875 6.640625 0 6.390625 0 C 5.90625 0 5.828125 -0.515625 5.6875 -1.4375 L 5.546875 -2.234375 C 5.375 -2.875 4.890625 -3.203125 4.34375 -3.390625 Z M 4.34375 -3.390625 "/>
|
||||
</g>
|
||||
<g id="glyph-1-15">
|
||||
<path d="M 1.109375 -2.515625 C 1.171875 -4 2.015625 -4.25 2.359375 -4.25 C 3.375 -4.25 3.484375 -2.90625 3.484375 -2.515625 Z M 1.109375 -2.296875 L 3.890625 -2.296875 C 4.109375 -2.296875 4.140625 -2.296875 4.140625 -2.515625 C 4.140625 -3.5 3.59375 -4.46875 2.359375 -4.46875 C 1.203125 -4.46875 0.28125 -3.4375 0.28125 -2.1875 C 0.28125 -0.859375 1.328125 0.109375 2.46875 0.109375 C 3.6875 0.109375 4.140625 -1 4.140625 -1.1875 C 4.140625 -1.28125 4.0625 -1.3125 4 -1.3125 C 3.921875 -1.3125 3.890625 -1.25 3.875 -1.171875 C 3.53125 -0.140625 2.625 -0.140625 2.53125 -0.140625 C 2.03125 -0.140625 1.640625 -0.4375 1.40625 -0.8125 C 1.109375 -1.28125 1.109375 -1.9375 1.109375 -2.296875 Z M 1.109375 -2.296875 "/>
|
||||
</g>
|
||||
<g id="glyph-1-16">
|
||||
<path d="M 2.21875 -1.71875 C 1.34375 -1.71875 1.34375 -2.71875 1.34375 -2.9375 C 1.34375 -3.203125 1.359375 -3.53125 1.5 -3.78125 C 1.578125 -3.890625 1.8125 -4.171875 2.21875 -4.171875 C 3.078125 -4.171875 3.078125 -3.1875 3.078125 -2.953125 C 3.078125 -2.6875 3.078125 -2.359375 2.921875 -2.109375 C 2.84375 -2 2.609375 -1.71875 2.21875 -1.71875 Z M 1.0625 -1.328125 C 1.0625 -1.359375 1.0625 -1.59375 1.21875 -1.796875 C 1.609375 -1.515625 2.03125 -1.484375 2.21875 -1.484375 C 3.140625 -1.484375 3.828125 -2.171875 3.828125 -2.9375 C 3.828125 -3.3125 3.671875 -3.671875 3.421875 -3.90625 C 3.78125 -4.25 4.140625 -4.296875 4.3125 -4.296875 C 4.34375 -4.296875 4.390625 -4.296875 4.421875 -4.28125 C 4.3125 -4.25 4.25 -4.140625 4.25 -4.015625 C 4.25 -3.84375 4.390625 -3.734375 4.546875 -3.734375 C 4.640625 -3.734375 4.828125 -3.796875 4.828125 -4.03125 C 4.828125 -4.203125 4.71875 -4.515625 4.328125 -4.515625 C 4.125 -4.515625 3.6875 -4.453125 3.265625 -4.046875 C 2.84375 -4.375 2.4375 -4.40625 2.21875 -4.40625 C 1.28125 -4.40625 0.59375 -3.71875 0.59375 -2.953125 C 0.59375 -2.515625 0.8125 -2.140625 1.0625 -1.921875 C 0.9375 -1.78125 0.75 -1.453125 0.75 -1.09375 C 0.75 -0.78125 0.890625 -0.40625 1.203125 -0.203125 C 0.59375 -0.046875 0.28125 0.390625 0.28125 0.78125 C 0.28125 1.5 1.265625 2.046875 2.484375 2.046875 C 3.65625 2.046875 4.6875 1.546875 4.6875 0.765625 C 4.6875 0.421875 4.5625 -0.09375 4.046875 -0.375 C 3.515625 -0.640625 2.9375 -0.640625 2.328125 -0.640625 C 2.078125 -0.640625 1.65625 -0.640625 1.578125 -0.65625 C 1.265625 -0.703125 1.0625 -1 1.0625 -1.328125 Z M 2.5 1.828125 C 1.484375 1.828125 0.796875 1.3125 0.796875 0.78125 C 0.796875 0.328125 1.171875 -0.046875 1.609375 -0.0625 L 2.203125 -0.0625 C 3.0625 -0.0625 4.171875 -0.0625 4.171875 0.78125 C 4.171875 1.328125 3.46875 1.828125 2.5 1.828125 Z M 2.5 1.828125 "/>
|
||||
</g>
|
||||
<g id="glyph-1-17">
|
||||
<path d="M 1.09375 -3.421875 L 1.09375 -0.75 C 1.09375 -0.3125 0.984375 -0.3125 0.3125 -0.3125 L 0.3125 0 C 0.671875 -0.015625 1.171875 -0.03125 1.453125 -0.03125 C 1.703125 -0.03125 2.21875 -0.015625 2.5625 0 L 2.5625 -0.3125 C 1.890625 -0.3125 1.78125 -0.3125 1.78125 -0.75 L 1.78125 -2.59375 C 1.78125 -3.625 2.5 -4.1875 3.125 -4.1875 C 3.765625 -4.1875 3.875 -3.65625 3.875 -3.078125 L 3.875 -0.75 C 3.875 -0.3125 3.765625 -0.3125 3.09375 -0.3125 L 3.09375 0 C 3.4375 -0.015625 3.953125 -0.03125 4.21875 -0.03125 C 4.46875 -0.03125 5 -0.015625 5.328125 0 L 5.328125 -0.3125 C 4.8125 -0.3125 4.5625 -0.3125 4.5625 -0.609375 L 4.5625 -2.515625 C 4.5625 -3.375 4.5625 -3.671875 4.25 -4.03125 C 4.109375 -4.203125 3.78125 -4.40625 3.203125 -4.40625 C 2.46875 -4.40625 2 -3.984375 1.71875 -3.359375 L 1.71875 -4.40625 L 0.3125 -4.296875 L 0.3125 -3.984375 C 1.015625 -3.984375 1.09375 -3.921875 1.09375 -3.421875 Z M 1.09375 -3.421875 "/>
|
||||
</g>
|
||||
<g id="glyph-1-18">
|
||||
<path d="M 3.890625 -0.78125 L 3.890625 0.109375 L 5.328125 0 L 5.328125 -0.3125 C 4.640625 -0.3125 4.5625 -0.375 4.5625 -0.875 L 4.5625 -4.40625 L 3.09375 -4.296875 L 3.09375 -3.984375 C 3.78125 -3.984375 3.875 -3.921875 3.875 -3.421875 L 3.875 -1.65625 C 3.875 -0.78125 3.390625 -0.109375 2.65625 -0.109375 C 1.828125 -0.109375 1.78125 -0.578125 1.78125 -1.09375 L 1.78125 -4.40625 L 0.3125 -4.296875 L 0.3125 -3.984375 C 1.09375 -3.984375 1.09375 -3.953125 1.09375 -3.078125 L 1.09375 -1.578125 C 1.09375 -0.796875 1.09375 0.109375 2.609375 0.109375 C 3.171875 0.109375 3.609375 -0.171875 3.890625 -0.78125 Z M 3.890625 -0.78125 "/>
|
||||
</g>
|
||||
</g>
|
||||
<clipPath id="clip-0">
|
||||
<path clip-rule="nonzero" d="M 59 15 L 308 15 L 308 107.453125 L 59 107.453125 Z M 59 15 "/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<path fill="none" stroke-width="0.797" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -23.809375 -35.718969 L 23.811719 -35.718969 L 23.811719 35.718531 L -23.809375 35.718531 Z M -23.809375 -35.718969 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -23.809375 -19.051 L -19.047656 -23.812719 L -23.809375 -28.574437 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-0-1" x="72.836" y="40.528"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-0-2" x="107.147" y="40.528"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -23.809375 -23.812719 L -31.746875 -23.812719 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -23.809375 23.812281 L -31.746875 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 23.811719 23.812281 L 31.749219 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-1" x="73.517" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-2" x="76.561571" y="64.065"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-2" x="81.821823" y="64.065"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.398" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.0004375 -0.0011875 L 2.988719 -0.0011875 " transform="matrix(1, 0, 0, -1, 87.398, 63.866)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-3" x="90.387" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-4" x="95.3683" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-5" x="98.13591" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-6" x="103.11721" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-3" x="105.884821" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-7" x="110.866121" y="64.065"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.797" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 66.33125 -35.718969 L 113.952344 -35.718969 L 113.952344 35.718531 L 66.33125 35.718531 Z M 66.33125 -35.718969 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 66.33125 -19.051 L 71.092969 -23.812719 L 66.33125 -28.574437 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-0-1" x="162.977" y="40.528"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-0-2" x="197.288" y="40.528"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 66.33125 -23.812719 L 58.39375 -23.812719 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 66.33125 23.812281 L 58.39375 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 113.952344 23.812281 L 121.889844 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-1" x="163.658" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-2" x="166.702571" y="64.065"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-2" x="171.962823" y="64.065"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.398" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -0.0009375 -0.0011875 L 2.987344 -0.0011875 " transform="matrix(1, 0, 0, -1, 177.54, 63.866)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-8" x="180.528" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-4" x="185.5093" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-5" x="188.27691" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-6" x="193.25821" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-3" x="196.025821" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-7" x="201.007121" y="64.065"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.797" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 156.475781 -35.718969 L 204.096875 -35.718969 L 204.096875 35.718531 L 156.475781 35.718531 Z M 156.475781 -35.718969 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 156.475781 -19.051 L 161.2375 -23.812719 L 156.475781 -28.574437 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-0-1" x="253.119" y="40.528"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-0-2" x="287.429" y="40.528"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 156.475781 -23.812719 L 148.538281 -23.812719 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 156.475781 23.812281 L 148.538281 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 204.096875 23.812281 L 212.034375 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-1" x="253.8" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-2" x="256.844571" y="64.065"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-2" x="262.104823" y="64.065"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.398" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -0.0013125 -0.0011875 L 2.990875 -0.0011875 " transform="matrix(1, 0, 0, -1, 267.681, 63.866)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-9" x="270.67" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-4" x="275.6513" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-5" x="278.41891" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-6" x="283.40021" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-3" x="286.167821" y="64.065"/>
|
||||
<use xlink:href="#glyph-1-7" x="291.149121" y="64.065"/>
|
||||
</g>
|
||||
<g clip-path="url(#clip-0)">
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -33.774219 -45.679906 L 214.057813 -45.679906 L 214.057813 45.679469 L -33.774219 45.679469 Z M -33.774219 -45.679906 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-10" x="164.967" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-11" x="170.502221" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-12" x="176.037441" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-1" x="178.805051" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-13" x="181.849622" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-14" x="185.724077" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-15" x="193.057547" y="10.239"/>
|
||||
<use xlink:href="#glyph-1-16" x="197.484926" y="10.239"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -31.746875 23.812281 L -41.711719 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -40.121875 23.812281 C -40.121875 24.687281 -40.832812 25.398219 -41.711719 25.398219 C -42.586719 25.398219 -43.297656 24.687281 -43.297656 23.812281 C -43.297656 22.933375 -42.586719 22.222438 -41.711719 22.222438 C -40.832812 22.222438 -40.121875 22.933375 -40.121875 23.812281 Z M -40.121875 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-1" x="3.321" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-2" x="6.365571" y="40.254"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-2" x="11.625823" y="40.254"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.398" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 0.001125 0.0003125 L 2.989406 0.0003125 " transform="matrix(1, 0, 0, -1, 17.202, 40.055)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-12" x="20.191" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-17" x="22.95861" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-4" x="28.493831" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-5" x="31.261441" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-6" x="36.242741" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-3" x="39.010351" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-7" x="43.991651" y="40.254"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 31.749219 23.812281 L 58.39375 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 121.889844 23.812281 L 148.538281 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill="none" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 212.034375 23.812281 L 221.995313 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" stroke-width="0.3985" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 223.58125 23.812281 C 223.58125 24.687281 222.874219 25.398219 221.995313 25.398219 C 221.120313 25.398219 220.409375 24.687281 220.409375 23.812281 C 220.409375 22.933375 221.120313 22.222438 221.995313 22.222438 C 222.874219 22.222438 223.58125 22.933375 223.58125 23.812281 Z M 223.58125 23.812281 " transform="matrix(1, 0, 0, -1, 93.575, 61.574)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-1" x="320.675" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-2" x="323.719571" y="40.254"/>
|
||||
</g>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-2" x="328.979823" y="40.254"/>
|
||||
</g>
|
||||
<path fill="none" stroke-width="0.398" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -0.0013125 0.0003125 L 2.990875 0.0003125 " transform="matrix(1, 0, 0, -1, 334.556, 40.055)"/>
|
||||
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
|
||||
<use xlink:href="#glyph-1-2" x="337.545" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-18" x="342.5263" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-13" x="348.061521" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-4" x="351.935976" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-5" x="354.703586" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-6" x="359.684886" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-3" x="362.452496" y="40.254"/>
|
||||
<use xlink:href="#glyph-1-7" x="367.433796" y="40.254"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
24
Images/shift_reg.tex
Normal file
24
Images/shift_reg.tex
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
\documentclass{standalone}
|
||||
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{positioning, fit}
|
||||
|
||||
\usepackage{circuitikz}
|
||||
\tikzset{
|
||||
register/.style={flipflop, flipflop def={t1=I, t6=O, c3=1}},
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{circuitikz}
|
||||
\node[register] (reg 0) {foo\_0[7:0]};
|
||||
\node[register, right=1.5 of reg 0] (reg 1) {foo\_1[7:0]};
|
||||
\node[register, right=1.5 of reg 1] (reg 2) {foo\_2[7:0]};
|
||||
\node[draw, inner sep=10pt, fit=(reg 0) (reg 1) (reg 2), label=north:ShiftReg] {};
|
||||
\draw (reg 0.pin 1) -- ++(-10pt, 0) node[ocirc, label=left:{foo\_in[7:0]}] {};
|
||||
\draw (reg 0.pin 6) -- (reg 1.pin 1);
|
||||
\draw (reg 1.pin 6) -- (reg 2.pin 1);
|
||||
\draw (reg 2.pin 6) -- ++(10pt, 0) node[ocirc, label=right:{foo\_out[7:0]}] {};
|
||||
\end{circuitikz}
|
||||
|
||||
\end{document}
|
||||
477
README.md
Normal file
477
README.md
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
[[_TOC_]]
|
||||
|
||||
# Introduction
|
||||
|
||||
This exercise session introduces SpinalHDL, a Scala-based Hardware Description
|
||||
Language (HDL). SpinalHDL is implemented as a Scala library that generates RTL
|
||||
in the form of either Verilog or VHDL code. It is also capable of running, and
|
||||
interacting with, a Verilog simulation from Scala.
|
||||
|
||||
SpinalHDL is a RTL code generator rather than a higher-level HDL. Of course, the
|
||||
full power of Scala can be used to build abstractions on top of the basic RTL
|
||||
components but only by combining those basic components. Having a good
|
||||
understanding of RTL is therefore imperative before using SpinalHDL.
|
||||
|
||||
This text explains the basic concepts of SpinalHDL before introducing the
|
||||
exercises. However, it is not meant to be a comprehensive description of all its
|
||||
features. For that, we refer to the official
|
||||
[documentation](https://spinalhdl.github.io/SpinalDoc-RTD/).
|
||||
|
||||
# Setup
|
||||
|
||||
Read [this](SpinalTest) to learn how to install all prerequisites and test your
|
||||
setup.
|
||||
|
||||
# Basic logic
|
||||
|
||||
We will introduce the basic concepts of RTL modelling in SpinalHDL by building
|
||||
the same 16-bit timer module we built in Verilog during the lectures. As in
|
||||
Verilog, we will create an 8-bit timer module first and use that as the building
|
||||
blocks for a 16-bit timer.
|
||||
|
||||
While designing the combinational path in Verilog, we ended-up with the
|
||||
following code (ignoring the declaration of all signals that are read):
|
||||
|
||||
```verilog
|
||||
reg [7:0] t2;
|
||||
|
||||
always @* begin
|
||||
if (rst) t2 = 0;
|
||||
else if (enable) t2 = counter + 1;
|
||||
else t2 = counter ;
|
||||
end
|
||||
```
|
||||
|
||||
In SpinalHDL, the same logic could be modelled as follows:
|
||||
|
||||
```scala
|
||||
val t2 = UInt(8 bits)
|
||||
|
||||
when (rst) {
|
||||
t2 := 0
|
||||
} elsewhen (enable) {
|
||||
t2 := counter + 1
|
||||
} otherwise {
|
||||
t2 := counter
|
||||
}
|
||||
```
|
||||
|
||||
Structurally, this looks very similar to the Verilog code. The most important
|
||||
difference is the lack of an equivalent of Verilog's `always` block. When a
|
||||
value is assigned to a variable, SpinalHDL uses its type annotations to figure
|
||||
out if it should create combinational or synchronous logic. In this case, since
|
||||
`t2` is not declared as a register, combinational logic will automatically be
|
||||
created that is equivalent to the Verilog code above.
|
||||
|
||||
While in Verilog we only specify the bit width of signals, SpinalHDL has
|
||||
stricter
|
||||
[types](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Data%20types). The
|
||||
most important simple types are `Bool` (single-bit signal), `Bits` (bit-vector),
|
||||
`UInt`/`SInt` (multi-bit signal supporting unsigned/signed arithmetic
|
||||
operations). The multi-bit types take their bit width as a constructor argument,
|
||||
which is specified as a positive integer followed by the keyword `bits`.
|
||||
|
||||
Signals can freely be "cast" between types using the methods `asBits`, `asUInt`,
|
||||
`asSInt`, and `asBools`. The latter method converts a multi-bit signal to a
|
||||
`Vec[Bool]` ([see here](#aggregate-data-types)).
|
||||
|
||||
SpinalHDL uses the `:=` operator to connect signals. For most arithmetic
|
||||
operations, the same operators as in Verilog or Scala are used (e.g., `+`,
|
||||
`&&`,...). The two exceptions are tests for equality (`===`) and inequality
|
||||
(`=/=`) because using the standard operators (`==` and `!=`) would clash with
|
||||
the use of those operators in Scala's class hierarchy.
|
||||
|
||||
Because Scala already has keywords named `if` and `else`, SpinalHDL introduces
|
||||
the keywords `when` (`if` in Verilog), `elsewhen` (`else if`), and `otherwise`
|
||||
(`else`). Besides their names, they are syntactically similar as normal
|
||||
conditional execution in Scala.
|
||||
|
||||
For storing the value in a register, we initially had the following Verilog code:
|
||||
|
||||
```verilog
|
||||
reg [7:0] counter;
|
||||
|
||||
always @(posedge clk) begin
|
||||
counter <= t2;
|
||||
end
|
||||
```
|
||||
|
||||
which can be coded like this in SpinalHDL:
|
||||
|
||||
```scala
|
||||
val counter = Reg(UInt(8 bits))
|
||||
counter := t2
|
||||
```
|
||||
|
||||
Next to its type (`UInt`), the `counter` signal is explicitly annotated to be a
|
||||
register
|
||||
([`Reg`](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Sequential%20logic/registers.html)).
|
||||
Since SpinalHDL knows that `counter` is a register, we do not have specify any
|
||||
clock edge sensitivity like we have to in Verilog. Note that there is no mention
|
||||
of any clock signal at all. By default, SpinalHDL uses a global "clock domain"
|
||||
(which contains, among others, a clock signal) to drive all registers in the
|
||||
design. This means that in most designs it is not necessary to ever explicitly
|
||||
refer to a clock.
|
||||
|
||||
The 8-bit counter design with all logic combined looked like this in Verilog:
|
||||
|
||||
```verilog
|
||||
reg [7:0] counter;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) counter <= 0;
|
||||
else if (enable) counter <= counter + 1;
|
||||
end
|
||||
```
|
||||
|
||||
which is concisely specified as follows in SpinalHDL:
|
||||
|
||||
```scala
|
||||
val counter = Reg(UInt(8 bits)).init(0)
|
||||
|
||||
when (enable) {
|
||||
counter := counter + 1
|
||||
}
|
||||
```
|
||||
|
||||
The most important difference with Verilog is that we don't have to explicitly
|
||||
deal with the reset signal. Like the clock signal, an implicit reset signal is
|
||||
contained within the global clock domain. A reset value can be specified for a
|
||||
register by calling its `init` method.
|
||||
|
||||
# Advanced muxing
|
||||
|
||||
We ran into trouble in Verilog when trying to model a 3-input mux like this:
|
||||
|
||||
```verilog
|
||||
reg o;
|
||||
|
||||
always @* begin
|
||||
if (s == 0) o = i0;
|
||||
else if (s == 1) o = i1;
|
||||
else if (s == 2) o = i2;
|
||||
end
|
||||
```
|
||||
|
||||
Here, Verilog would silently create a latch for `o`.
|
||||
|
||||
If we model the same logic in SpinalHDL:
|
||||
|
||||
```scala
|
||||
val o = Bool
|
||||
|
||||
when (s === 0) {
|
||||
o := i0
|
||||
} elsewhen (s === 1) {
|
||||
o := i1
|
||||
} elsewhen (s === 2) {
|
||||
o := i2
|
||||
}
|
||||
```
|
||||
|
||||
we get a very useful error (SpinalHDL checks for many [common design
|
||||
errors](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Design%20errors):
|
||||
|
||||
```
|
||||
LATCH DETECTED from the combinatorial signal (toplevel/o : Bool), defined at ...
|
||||
```
|
||||
|
||||
The solution is the same as in Verilog: make sure a value is assigned to `o` under all conditions.
|
||||
Like in Verilog, later assignments override earlier ones so we could do something like this:
|
||||
|
||||
```scala
|
||||
val o = Bool
|
||||
o := False // or o.assignDontCare()
|
||||
...
|
||||
```
|
||||
|
||||
SpinalHDL also supports a [switch
|
||||
construct](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Semantic/when_switch.html):
|
||||
|
||||
```scala
|
||||
switch (s) {
|
||||
is (0) { o := i0 }
|
||||
is (1) { o := i1 }
|
||||
is (2) { o := i0 }
|
||||
default { o := False }
|
||||
}
|
||||
```
|
||||
|
||||
and a more explicit `mux` method:
|
||||
|
||||
```scala
|
||||
o := s.mux(
|
||||
0 -> i1,
|
||||
1 -> i1,
|
||||
2 -> i2,
|
||||
default -> False
|
||||
)
|
||||
```
|
||||
|
||||
# Modules
|
||||
|
||||
The full 8-bit counter module looked as follows in Verilog:
|
||||
|
||||
```verilog
|
||||
module counter8(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire enable,
|
||||
output reg[7:0] counter
|
||||
);
|
||||
always @(posedge clk) begin
|
||||
if (rst) counter <= 0;
|
||||
else if (enable) counter <= counter + 1;
|
||||
end
|
||||
endmodule
|
||||
```
|
||||
|
||||
In SpinalHDL, modules are created by wrapping logic in the constructor of a
|
||||
class that inherits from `Component`:
|
||||
|
||||
```scala
|
||||
class Counter8 extends Component {
|
||||
val enable = in(Bool)
|
||||
val counter = out(Reg(UInt(8 bits)).init(0))
|
||||
|
||||
when (enable) {
|
||||
counter := counter + 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
I/O ports are created by wrapping signal types with the `in` or `out`
|
||||
annotations. Signals that are not annotated as I/O are local signals which
|
||||
cannot be accessed from outside the surrounding module. Note again that the
|
||||
`clk` and `rst` signals are not visible since they are part of the implicit
|
||||
global clock domain.
|
||||
|
||||
Modules can be instantiated by creating objects of their classes.
|
||||
I/O ports are then connected by simply assigning to or reading from them:
|
||||
|
||||
```scala
|
||||
class Counter16 extends Component {
|
||||
val enable = in(Bool)
|
||||
val counter = out(UInt(16 bits))
|
||||
|
||||
val lsb = new Counter8
|
||||
lsb.enable := enable
|
||||
|
||||
val msb = new Counter8
|
||||
msb.enable := enable && (lsb.counter === 0xff);
|
||||
|
||||
counter := msb.counter @@ lsb.counter
|
||||
}
|
||||
```
|
||||
|
||||
# Workflow
|
||||
|
||||
SpinalHDL is implemented as a Scala library and all "keywords" discussed so for
|
||||
are, in fact, not keywords but simply methods defined by this library. When
|
||||
running a Scala program using SpinalHDL, an internal RTL representation is
|
||||
created that corresponds to the logic defined by the library calls. This RTL can
|
||||
then be converted to Verilog or VHDL:
|
||||
|
||||
```scala
|
||||
object Generate {
|
||||
def main(args: Array[String]): Unit = {
|
||||
SpinalVerilog(new Counter16)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here, the instantiation of the `Counter16` module builds an internal
|
||||
representation of all `RTL` for this module which is then converted to Verilog
|
||||
by passing the instance to the `SpinalVerilog` method. When running this main
|
||||
method, a file called `Counter16.v` will be created that contains the generated
|
||||
Verilog code.
|
||||
|
||||
SpinalHDL also supports running [Verilog
|
||||
simulations](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Simulation/)
|
||||
directly from Scala. This is implemented by first generating Verilog and then
|
||||
simulating this code using [Verilator](https://www.veripool.org/wiki/verilator).
|
||||
While the simulation is running, it is possible to access Verilog signals from
|
||||
Scala which allows, for example, writing test cases in Scala. For this exercise
|
||||
session, all necessary simulation code is provided.
|
||||
|
||||
The temporary files and results of the simulation are stored in the
|
||||
`simWorkspace` directory. When a top-level component called `Foo` is simulated,
|
||||
the following files are created (among others):
|
||||
|
||||
- `Foo/test.vcd`: VCD file resulting from the simulation;
|
||||
- `Foo/rtl/Foo.v`: Verilog code used for the simulation.
|
||||
|
||||
# Naming
|
||||
|
||||
Since SpinalHDL generates Verilog or runs simulations using a Verilog simulator,
|
||||
it is important that modules and signals defined in Scala are properly named in
|
||||
Verilog. For the most common cases, SpinalHDL is able to automatically figure
|
||||
out good names to use in Verilog using the following rules:
|
||||
|
||||
- Modules get the same name as the `Component` subclass used to generate them;
|
||||
- Top-level signals defined in the constructor of a `Component` subclass get the
|
||||
same name as the Scala instance variable used to store them.
|
||||
|
||||
In both cases, SpinalHDL will resolve naming conflicts with Verilog keywords by
|
||||
appending a number to the name. It is recommended to avoid using Verilog
|
||||
keywords for modules or signal names.
|
||||
|
||||
In more advanced use cases where signals are not necessarily stored in top-level
|
||||
Scala instance variables, SpinalHDL will not be able to automatically select a
|
||||
good name. Instead, it will generate a name of the form `_zz_n_` where `n` is
|
||||
a natural number. Such signals are not dumped to theVCD file during simulation.
|
||||
In these cases, the `setName` method can be used to manually select a name.
|
||||
|
||||
# Aggregate data types
|
||||
|
||||
SpinalHDL offers an array-like data structure called
|
||||
[`Vec`](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Data%20types/Vec.html)
|
||||
that holds a fixed number of signals of the same type. It implements Scala's
|
||||
`IndexedSeq` trait. The main advantage of using `Vec` over one of Scala's
|
||||
built-in collections is that SpinalHDL's naming algorithm recognizes it. It
|
||||
creates a signal for each element that is named by appending its index to the
|
||||
name of the `Vec`.
|
||||
|
||||
Multiple signals of different types can be bundled in a struct-like data
|
||||
structure using the
|
||||
[`Bundle`](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Data%20types/bundle.html)
|
||||
base class. This is mainly useful to define complex buses in which multiple
|
||||
signals are always used together. For example, an [SPI
|
||||
bus](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface) could be defined
|
||||
as follows:
|
||||
|
||||
```scala
|
||||
class SpiBus(numSlaves: Int) extends Bundle {
|
||||
val sclk = Bool
|
||||
val mosi = Bool
|
||||
val miso = Bool
|
||||
val ss = Bits(numSlaves bits)
|
||||
}
|
||||
```
|
||||
|
||||
Buses often have an I/O direction and what is an output on one side of the bus,
|
||||
is an input on the other side. The two sides of a bus are called master and
|
||||
slave. To handle this, SpinalHDL defines the `IMasterSlave` trait. When
|
||||
implementing this trait, the `asMaster` method must be implemented which should
|
||||
set the I/O direction of all signals when the bus is used as a master (when used
|
||||
as a slave, SpinalHDL automatically flips the direction of all signals):
|
||||
|
||||
```scala
|
||||
class SpiBus(numSlaves: Int) extends Bundle with IMasterSlave {
|
||||
...
|
||||
override def asMaster(): Unit = {
|
||||
out(sclk, mosi, ss)
|
||||
in(ss)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
SpinalHDL also supports an "auto-connect" operator (`<>`) that automatically
|
||||
connects all signals of a bus to the corresponding signals of another bus
|
||||
(taking their directions into account):
|
||||
|
||||
```scala
|
||||
class SpiMaster extends Component {
|
||||
val bus = master(new SpiBus)
|
||||
...
|
||||
}
|
||||
|
||||
class SpiSlave extends Component {
|
||||
val bus = slave(new SpiBus)
|
||||
...
|
||||
}
|
||||
|
||||
class Soc extends Component {
|
||||
val spiMaster = new SpiMaster
|
||||
val spiSlave = new SpiSlave
|
||||
spiMaster.bus <> spiSlave.bus
|
||||
}
|
||||
```
|
||||
|
||||
# Exercise: popcnt
|
||||
|
||||
For the first exercise, the `popcnt` module discussed during the Verilog lecture
|
||||
should be implemented in SpinalHDL. The end goal is to implement a class that is
|
||||
configurable in the number of bits of the input and in whether the operation
|
||||
should be implemented in multiple cycles. The logic should be implemented in
|
||||
`Popcnt.scala` and the simulation can be run using the `PopcntSim` object in
|
||||
`Top.scala`.
|
||||
|
||||
The `Popcnt` component has the following constructor parameters:
|
||||
|
||||
- `width`: the bit width of the input;
|
||||
- `multiCycle`: boolean indicating whether the logic should be implemented in
|
||||
multiple cycles or asynchronous.
|
||||
|
||||
The following I/O ports should be defined by the `Popcnt` component:
|
||||
|
||||
- `start` (input): asserted when the operation should start. Not needed for the
|
||||
asynchronous logic but should still be defined;
|
||||
- `value` (input): input to the operation;
|
||||
- `count` (output): result of the operation;
|
||||
- `ready` (output): asserted when the operation is ready. Not needed for the
|
||||
asynchronous logic but should still be defined;
|
||||
|
||||
It is recommended to implement the logic incrementally:
|
||||
|
||||
1. Implement the logic for a 4-bit asynchronous circuit. Beware that even though
|
||||
the operation should be implemented using purely combinational logic, the
|
||||
result should still be stored in a register. Also, the simulation will fail
|
||||
with an obscure error message if you try to run it before defining a register
|
||||
in your implementation;
|
||||
1. Generalize this logic to support arbitrary bit widths. Hint: one way to do
|
||||
this is to use a fold operation on the bits of the input;
|
||||
1. Add the logic for the multi-cycle implementation.
|
||||
|
||||
# Exercise: a configurable shift register
|
||||
|
||||
In this exercise, you will be implementing a component that manages [shift
|
||||
registers](https://en.wikipedia.org/wiki/Shift_register). This component
|
||||
provides the following method to dynamically add a shift register:
|
||||
|
||||
```scala
|
||||
def addReg(name: String, width: BitCount, delay: Int): (Bits, Bits)
|
||||
```
|
||||
|
||||
This methods adds a new shift register to the component containing `delay`
|
||||
`width`-bit registers in cascade. The `name` argument can be used to generate
|
||||
readable names for all created I/O ports and registers. The return value of this
|
||||
method is a 2-tuple where the first element is an input connected to the first
|
||||
register in the cascade and the second element an output connected to the last.
|
||||
The method `getReg` should return the same tuple.
|
||||
|
||||
As an example, the image below shows the configuration of the component after
|
||||
calling
|
||||
|
||||
```scala
|
||||
addReg("foo", 8 bits, 3)|
|
||||
```
|
||||
|
||||
In this case, the tuple returned would be `(foo_in, foo_out)`.
|
||||
|
||||

|
||||
|
||||
SpinalHDL globally keeps track of the "current component". Whenever a new
|
||||
instance is created of a `Component` subclass, the current component is set to
|
||||
this instance. When logic is created, it is added to the current component. This
|
||||
means that if logic is created inside the `addReg` method, it will be added to
|
||||
the component that called this method, which is not what we want. To solve this,
|
||||
SpinalHDL offers the `rework` method which can be called on a `Component` to add
|
||||
logic to it after its creation:
|
||||
|
||||
```scala
|
||||
class ExtendableComponent extends Component {
|
||||
def addLogic(): Unit = {
|
||||
rework {
|
||||
// Add logic here
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The logic for this exercise should be implemented in `ShiftReg.scala` and the
|
||||
simulation can be run using the `ShiftRegSim` object in `Top.scala`. The
|
||||
simulation adds two registers (see method `createShiftReg`) and runs for 10
|
||||
cycles, setting the input of the first register to increasing values starting at
|
||||
0, and the input of the second register to decreasing values starting at 10.
|
||||
|
||||
42
SpinalTest/README.md
Normal file
42
SpinalTest/README.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Prerequisites
|
||||
|
||||
- [sbt](https://www.scala-sbt.org/download.html)
|
||||
- [Verilator](https://verilator.org/guide/latest/install.html)
|
||||
- A Java JDK
|
||||
|
||||
More info can be found in the SpinalHDL
|
||||
[documentation](https://spinalhdl.github.io/SpinalDoc-RTD/master/SpinalHDL/Getting%20Started/getting_started.html).
|
||||
|
||||
On Arch Linux, everything can be installed from the package repositories:
|
||||
|
||||
```
|
||||
sudo pacman -S sbt verilator jdk-openjdk
|
||||
```
|
||||
|
||||
The PCs in the CS department have everything installed.
|
||||
|
||||
# Test installation
|
||||
|
||||
To test code generation (this should create a file called `Counter.v`):
|
||||
|
||||
```
|
||||
sbt 'runMain spinaltest.Gen'
|
||||
```
|
||||
|
||||
To test simulation:
|
||||
|
||||
```
|
||||
sbt 'runMain spinaltest.Sim'
|
||||
```
|
||||
|
||||
This should print something like the following at the end:
|
||||
|
||||
```
|
||||
[info] [Progress] Simulation workspace in /.../SpinalTest/./simWorkspace/Counter
|
||||
[info] [Progress] Verilator compilation started
|
||||
[info] [Progress] Verilator compilation done in 2986.102 ms
|
||||
[info] [Progress] Start Counter test simulation with seed 267472656
|
||||
[info] counter: 9
|
||||
[info] [Done] Simulation done in 23.684 ms
|
||||
[success] Total time: 4 s, completed Oct 13, 2022, 11:00:52 AM
|
||||
```
|
||||
13
SpinalTest/build.sbt
Normal file
13
SpinalTest/build.sbt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name := "SpinalTest"
|
||||
version := "0.1"
|
||||
|
||||
scalaVersion := "2.11.12"
|
||||
val spinalVersion = "1.7.3"
|
||||
|
||||
fork := true
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.spinalhdl" % "spinalhdl-core_2.11" % spinalVersion,
|
||||
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % spinalVersion,
|
||||
compilerPlugin("com.github.spinalhdl" % "spinalhdl-idsl-plugin_2.11" % spinalVersion)
|
||||
)
|
||||
31
SpinalTest/src/main/scala/spinaltest/Test.scala
Normal file
31
SpinalTest/src/main/scala/spinaltest/Test.scala
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package spinaltest
|
||||
|
||||
import spinal.core._
|
||||
import spinal.core.sim._
|
||||
|
||||
class Counter extends Component {
|
||||
val count = out(Reg(UInt(8 bits)).init(0))
|
||||
count := count + 1
|
||||
}
|
||||
|
||||
object Gen {
|
||||
def main(args: Array[String]) {
|
||||
SpinalVerilog(new Counter)
|
||||
}
|
||||
}
|
||||
|
||||
object Sim {
|
||||
def main(args: Array[String]) {
|
||||
SimConfig.withWave.compile(new Counter).doSim {dut =>
|
||||
dut.clockDomain.forkStimulus(10)
|
||||
var tick = 0
|
||||
|
||||
while (tick < 10) {
|
||||
dut.clockDomain.waitSampling()
|
||||
tick += 1
|
||||
}
|
||||
|
||||
println(s"counter: ${dut.count.toBigInt}")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue