Add exercises

This commit is contained in:
Job Noorman 2022-10-13 11:52:00 +02:00
commit ac3cf23632
19 changed files with 21160 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
simWorkspace/
target/
tmp/
project/
*.v

6
Exercises/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
*.v
.idea/
project/
simWorkspace/
target/
tmp/

13
Exercises/build.sbt Normal file
View 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)
)

View 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
}

View 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
}
}

View 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
}

View 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
}
}
}
}

View 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.
}
}

View 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)
}
}

View 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
View file

@ -0,0 +1,5 @@
*.aux
*.fdb_latexmk
*.fls
*.log
*.pdf

7
Images/Makefile Normal file
View file

@ -0,0 +1,7 @@
all: shift_reg.svg
%.svg: %.pdf
pdf2svg $< $@
%.pdf: %.tex
latexmk -pdf $<

20155
Images/circuitikz.sty Normal file

File diff suppressed because it is too large Load diff

209
Images/shift_reg.svg Normal file
View 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
View 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
View 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)`.
![Example shift register configuration](Images/shift_reg.svg)
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
View 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
View 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)
)

View 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}")
}
}
}