components and sequential circuitsi we talked about git last week i to version your source i maybe...
TRANSCRIPT
Components and Sequential Circuits
Martin Schoeberl
Technical University of DenmarkEmbedded Systems Engineering
February 27, 2020
1 / 67
Overview
I Vending machine projectI Repeat combinational building blocksI Power user III Components and top-levelI Sequential circuits
2 / 67
Admin
I How is the lab work going so far?I Start to organize yourself in groups of 2–3
I You can ask for finding a group via slackI Register at Google spreadsheet
3 / 67
A Vending Machine from 1952
Source: Minnesota Historical Society, CC BY-SA 2.0
4 / 67
The Vending Machine
I Final project is a vending machineI Specification document is in DTU Inside (show it)I Inputs: coins, buyI Display: price and current amountI Output: release can or errorI Small challenge to multiplex the displayI State machine with data path is the brain of the VMI Guided step by step over several weeks
5 / 67
Vending Machine Specification I
I Sell 1 item and not returning any moneyI Set price with 5 switches (1–31 kr.)I Display price on two 7-segment displays (hex.)I Accept 2 and 5 kr. (two push buttons)I Display sum on two 7-segment displays (hex.)
I Amount entered so farI Does not return money, left for the next purchase
6 / 67
Vending Machine Specification II
I Push button BuyI If not enough money, activate alarm as long as buy is
pressedI If enough money, activate release item for as long as buy is
pressed and reduce sum by the price of the itemI Optional extras (for a 12)
I Display decimal numbersI Supplement alarm by some visuals (e.g., blinking display)I Count coins and display an alarm when compartment is full
(> 20 coins)I Have some text scrolling on the displayI ...I Your ideas :-)
7 / 67
Design and Implementation
I Implementation shall be a state machine plus datapathI Design your datapath on a sheet of paperI Datapath
I Does add and subtractI Contains a register to hold the sumI Needs some mulitplexer to operate
I Display needs multiplexingI Implemented with some counters and a multiplexer
I Show each part of your design to a TAI 7-segment decoder, 7-segment with a counter, display
multiplexer, complete vending machine
8 / 67
Vending Machine Design and Implementation Steps
I We start next weekI 2 + 2 + 3 + 3 + 4 + 4 = 18 supervised lab hoursI 1a. Hexadecimal to 7-segment decoderI 1b. 7-segment display with a counterI 2. Multiplexed Seven-Segment DisplayI 3. Complete Vending MachineI Show your working design to a TA
9 / 67
Final ReportI One report per groupI A single PDF
I Your group number is part of the file name (e.g., group7.pdf)I Code as listing in an appendix (no .zip files)I Hand in in DTU Inside
I ContentI AbstractI Preface (Who did what)
1. Introduction and Problem Formulation2. Analysis and Design3. Implementation4. Testing5. Results6. Discussion7. Conclusion
I List of ReferencesI Appendix: Chisel code
10 / 67
Questions on Final Project?
11 / 67
Combinational Circuit with Conditional Update
I Value first needs to be wrapped into a WireI Updates with the Chisel update operation :=I With when we can express a conditional updateI The condition is an expression with a Boolean resultI The resulting circuit is a multiplexerI The rule is that the last enabled assignment counts
I Here the order of statements has a meaning
val enoughMoney = Wire(Bool())
enoughMoney := false.B
when (coinSum >= price) {
enoughMoney := true.B
}
12 / 67
Comparison
I The usual operations (as in Java or C)I Unusual equal and unequal operator symbolsI To keep the original Sala operators usable for references
I Operands are UInt and SIntI Operands can be Bool for equal and unequalI Result is Bool
>, >=, <, <=
===, =/=
13 / 67
Boolean Logical Operations
I Operands and result are BoolI Logical NOT, AND, and OR
val notX = !x
val bothTrue = a && b
val orVal = x || y
14 / 67
The “Else” Branch
I We can express a form of “else”I Note the . in .otherwise
val w = Wire(UInt())
when (cond) {
w := 1.U
} .otherwise {
w := 2.U
}
15 / 67
A Chain of Conditions
I To test for different conditionsI Select with a priority orderI The first expression that is true countsI The hardware is a chain of multiplexers
val w = Wire(UInt())
when (cond) {
w := 1.U
} .elsewhen (cond2) {
w := 2.U
} .otherwise {
w := 3.U
}
2
cond2
3
w
cond
1
16 / 67
Default Assignment
I Practical for complex expressionsI Forgetting to assign a value on all conditions
I Would describe a latchI Runtime error in Chisel
I Assign a default value is good practise
val w = WireDefault(0.U)
when (cond) {
w := 3.U
}
// ... and some more complex conditional
assignments
17 / 67
Logic Can Be Expressed as a Table
I Sometimes more convenientI Still combinational logic (gates)I Is converted to Boolean expressionsI Let the synthesize tool do the conversion!I We use the switch statement
switch (sel) {
is ("b00".U) { result := "b0001".U}
is ("b01".U) { result := "b0010".U}
is ("b10".U) { result := "b0100".U}
is ("b11".U) { result := "b1000".U}
}
18 / 67
A Decoder
a1Decoder
a0
b0
b1
b2
b3
I Converts a binary number of n bits to an m-bit signal,where m ≤ 2n
I The output is one-hot encoded (exactly one bit is one)I Building block for a m-way MuxI Used for address decoding in a computer systemI Maybe of use for the display multiplexer
19 / 67
Truth Table of a Decoder
a b
00 000101 001010 010011 1000
20 / 67
An Encoder
a1Encoder
a0
a2
a3
b0
b1
I Converts one-hot encoded signalI To binary representation
21 / 67
Truth Table of an Encoder
a b
0001 000010 010100 101000 11???? ??
I Only defined for one-hot input
22 / 67
Encoder in Chisel
I We cannot describe a function with undefined outputsI We use a default assignment of "b00"
b := "b00".U
switch (a) {
is ("b0001".U) { b := "b00".U}
is ("b0010".U) { b := "b01".U}
is ("b0100".U) { b := "b10".U}
is ("b1000".U) { b := "b11".U}
}
23 / 67
Power User II
I Every craftsmen starts with good-quality toolsI “Tools amplify your talent”1
I The better your tools, the more productive you areI The better you know them, the more productive you are
I IDEs (Eclipse, InelliJ) are nice, I love them tooI But we shall go beyond itI Use tools (and write your own)I Help with: google, man pages, or even plain –help (or -h)I https://www.oreilly.com/learning/ten-steps-to-linux-survivalI This is about command line tools, not just Linux
1The Pragmatic Programmer: From Journeyman to Master, by AndrewHunt and David Thomas
24 / 67
Power User II
I Use the command line, shell, terminalI In Windows: PowerShell
I You may want to install the Linux subsystemI Universal Unix commands (Windows, Mac, Linux)I Navigating the file system:
I Change directory: cdI Print working directory: pwdI Make a directory: mkdir abcI Create a file: echo test > abc.txtI Show file content: cat abc.txtI Remove a file: rm abc.txt
I Run your Chisel code with sbt runI You used the terminal already from within IntelliJ ;-)
25 / 67
Power User II
I We talked about git last weekI To version your sourceI Maybe hosting on GitHubI Most teaching material is on GitHubI Use git pull to update the lab materialI Show how to use it, now!
I Clone a repo: git clone pathI Get the newest version: git pullI Further commands: git commit, push, log, statusI Overview of changes: gitk
26 / 67
Structure With Bundles
I A Bundle to group signalsI Can be different typesI Defined by a class that extends BundleI Named fields as vals within the blockI Like a C struct or VHDL record
class Channel() extends Bundle {
val data = UInt(32.W)
val valid = Bool()
}
27 / 67
Using a Bundle
I Create it with newI Wrap it into a WireI Field access with dot notation
val ch = Wire(new Channel())
ch.data := 123.U
ch.valid := true.B
val b = ch.valid
28 / 67
Components
I Components are building blocksI Components have input and output ports (= pins)
I Organized as a BundleI assigned to field io
I We build circuits as a hierarchy of componentsI In Chisel a component is called ModuleI Components/Modules are used to organize the circuit
I Similar as using methods in Java
29 / 67
Hierarchy of Components Example
CompA
CompB CompD
CompC
30 / 67
Input/Output Ports
I Ports are bundles with directionsI Ports used to connect modules
class AluIO extends Bundle {
val function = Input(UInt(2.W))
val inputA = Input(UInt(4.W))
val inputB = Input(UInt(4.W))
val result = Output(UInt(4.W))
}
31 / 67
An Adder Module
I A class that extends ModuleI Interface (port) is a Bundle, wrapped into an IO(), and
stored in the field ioI Circuit description in the constructor
class Adder extends Module {
val io = IO(new Bundle {
val a = Input(UInt(4.W))
val b = Input(UInt(4.W))
val result = Output(UInt(4.W))
})
val addVal = io.a + io.b
io.result := addVal
}
32 / 67
Connections
I Simple connections just with assignments, e.g.,
adder.io.a := ina
adder.io.b := inb
I Note the dot access to the field io and then the IO field
33 / 67
Module Usage
I Create with new and wrap into a Module()I Interface port via the io fieldI Note the assignment operator := on io fields
val adder = Module(new Adder())
adder.io.a := ina
adder.io.b := inb
val result = adder.io.result
34 / 67
Example: Arithmetic Logic Unit
ALU Y
fn
B
A
I Also called ALUI A central component of a microprocessorI Two inputs, one function select, and an outputI Part of the datapath
35 / 67
Example: Arithmetic Logic Unitclass Alu extends Module {
val io = IO(new Bundle {
val a = Input(UInt(16.W))
val b = Input(UInt(16.W))
val fn = Input(UInt(2.W))
val y = Output(UInt(16.W))
})
// some default value is needed
io.y := 0.U
// The ALU selection
switch(io.fn) {
is(0.U) { io.y := io.a + io.b }
is(1.U) { io.y := io.a - io.b }
is(2.U) { io.y := io.a | io.b }
is(3.U) { io.y := io.a & io.b }
}
}
36 / 67
Hierarchy of Components Example
CompA
CompB CompD
CompC
37 / 67
Components CompA and CompBclass CompA extends Module {
val io = IO(new Bundle {
val a = Input(UInt(8.W))
val b = Input(UInt(8.W))
val x = Output(UInt(8.W))
val y = Output(UInt(8.W))
})
// function of A
}
class CompB extends Module {
val io = IO(new Bundle {
val in1 = Input(UInt(8.W))
val in2 = Input(UInt(8.W))
val out = Output(UInt(8.W))
})
// function of B
} 38 / 67
Component CompCclass CompC extends Module {
val io = IO(new Bundle {
val in_a = Input(UInt(8.W))
val in_b = Input(UInt(8.W))
val in_c = Input(UInt(8.W))
val out_x = Output(UInt(8.W))
val out_y = Output(UInt(8.W))
})
// create components A and B
val compA = Module(new CompA())
val compB = Module(new CompB())
// connect A
compA.io.a := io.in_a
compA.io.b := io.in_b
io.out_x := compA.io.x
// connect B
compB.io.in1 := compA.io.y
compB.io.in2 := io.in_c
io.out_y := compB.io.out
}
39 / 67
Chisel Main
I Create one top-level ModuleI Invoke the Chisel driver from the AppI Pass the top module (e.g., new Hello())I Optional: pass some parameters (in the Array)I Following code generates Verilog code for Hello World
object Hello extends App {
chisel3.Driver.execute(Array[String](), () =>
new Hello())
}
40 / 67
Hello World in Chisel
class Hello extends Module {
val io = IO(new Bundle {
val led = Output(UInt(1.W))
})
val CNT_MAX = (50000000 / 2 - 1).U;
val cntReg = RegInit(0.U(32.W))
val blkReg = RegInit(0.U(1.W))
cntReg := cntReg + 1.U
when(cntReg === CNT_MAX) {
cntReg := 0.U
blkReg := ˜blkReg
}
io.led := blkReg
}
41 / 67
Generated Verilog for Hello
I Hello is the top-level of our blinking LEDI No real need to read this codeI But pin assignment for the synthsisI Additional pins: clock and resetI User pin names with a leading io
module Hello(
input clock,
input reset,
output io_led
);
42 / 67
Generated Verilog for Hello
I We can find our two register definitionsI @... gives Chisel source and line number (e.g., 17)
reg [31:0] cntReg; // @[Hello.scala 17:23]
reg [31:0] _RAND_0;
reg blkReg; // @[Hello.scala 18:23]
43 / 67
Generated Verilog for Hello
I The increment and comparison against maximum value
assign _T_1 = cntReg + 32’h1; // @[Hello.scala 20:20]
assign _T_2 = cntReg == 32’h2faf07f; // @[Hello.scala 21:15]
assign _T_3 = ˜ blkReg; // @[Hello.scala 23:15]
assign io_led = blkReg; // @[Hello.scala 25:10]
44 / 67
Generated Verilog for Hello
I Verilog register code
always @(posedge clock) begin
if (reset) begin
cntReg <= 32’h0;
end else if (_T_2) begin
cntReg <= 32’h0;
end else begin
cntReg <= _T_1;
end
end
45 / 67
Verilog Generation Summary
I Verilog is generated for synthesisI We do not need to read itI Just pins are interestingI Additional clock and resetI Pin names with additional io
46 / 67
File Organization in Scala/Chisel
I A Scala file can contain several classes (and objects)I For large classes use one file per class with the class nameI Scala has packages, like JavaI Use folders with the package names for file organizationI sbt looks into current folder and src/main/scala/I Tests shall be in src/test/scala/
47 / 67
File Organization in Scala/Chisel
project
src
main
scala
package
sub-package
test
scala
package
target
generated
48 / 67
What is a Minimal Chisel Project?
I Scala class (e.g., Hello.scala)I Build info in build.sbt for sbt:
scalaVersion := "2.11.12"
libraryDependencies += "edu.berkeley.cs" %%
"chisel3" % "3.2.2"
49 / 67
Sequential Building Blocks
I Contain a registerI Plus combinational circuits
D Q
clock
val q = RegNext(d)
50 / 67
Register With Reset
D Qinit
reset
data
val valReg = RegInit(0.U(4.W))
valReg := inVal
51 / 67
Timing Diagram of the Register with Reset
clock
reset
inVal 3 5 2 7 4
regVal 0 5 2 7
A B C D E F
I Also called waveform diagramI Logic function over timeI Can be used to describe a circuit functionI Useful for debugging
52 / 67
Register with Enable
D Q
enable
data
I Only when enable true is a value is stored
val enableReg = Reg(UInt(4.W))
when (enable) {
enableReg := inVal
}
53 / 67
A Register with Reset and Enable
I We can combine initialization and enable
val resetEnableReg = RegInit(0.U(4.W))
when (enable) {
resetEnableReg := inVal
}
I A register can also be part of an expressionI What does the following circuit do?
val risingEdge = din & !RegNext(din)
54 / 67
A Register with an Adder is a Counter
D Q +
1
I Is a free running counterI 0, 1, ... 14, 15, 0, 1, ...
val cntReg = RegInit(0.U(4.W))
cntReg := cntReg + 1.U
55 / 67
A Counter with a Mux
val cntReg = RegInit(0.U(8.W))
cntReg := Mux(cntReg === 9.U, 0.U, cntReg + 1.U)
I This counter counts from 0 to 9I And starts from 0 again after reaching 9
I Starting from 0 is common in computer engineeringI A counter is the hardware version of a for loopI Often needed
56 / 67
Counting Events
D Q +
1
event
val cntEventsReg = RegInit(0.U(4.W))
when(event) {
cntEventsReg := cntEventsReg + 1.U
}
57 / 67
Counting Up and Down
I Up:
val cntReg = RegInit(0.U(8.W))
cntReg := cntReg + 1.U
when(cntReg === N) {
cntReg := 0.U
}
I Down:
val cntReg = RegInit(N)
cntReg := cntReg - 1.U
when(cntReg === 0.U) {
cntReg := N
}
58 / 67
Preview: Testing with Chisel
I Tester extends class PeekPokeTesterI Has the device under test (DUT) as parameterI Testing code can use all features of Scala
class CounterTester(dut: Counter) extends
PeekPokeTester(dut) {
// Here comes the Chisel/Scala code
// for the testing
}
59 / 67
Testing
I Set input values with pokeI Advance the simulation with stepI Read the output values with peekI Compare the values with expect
60 / 67
Testing Example
// Set input values
poke(dut.io.a, 3)
poke(dut.io.b, 4)
// Execute one iteration
step(1)
// Print the result
val res = peek(dut.io.result)
println(res)
// Or compare against expected value
expect(dut.io.result, 7)
61 / 67
Chisel Main for Testing
I Tests can be written in Scala/ChiselI Invoke execute with some parameters, the DUT, and a
tester
object CounterTester extends App {
iotesters.Driver.execute(Array[String](), () =>
new Counter(2)) {
c => new CounterTester(c)
}
}
I More on testing and waveform generation next week
62 / 67
Common Acronyms
ADC analog-to-digital converterALU arithmetic and logic unit
ASIC application-specific integrated circuitChisel constructing hardware in a Scala embedded
languageCISC complex instruction set computerCRC cyclic redundancy checkDAC digital-to-analog converterDFF D flip-flop, data flip-flopDMA direct memory access
DRAM dynamic random access memoryFF flip-flop
63 / 67
Common Acronyms II
FIFO first-in, first-outFPGA field-programmable gate array
HDL hardware description languageHLS high-level synthesis
IC instruction countIDE integrated development environment
IO input/outputISA instruction set architectureJDK Java development kitJIT just-Iin-time
JVM Java virtual machineLC logic cell
64 / 67
Common Acronyms III
LRU least-recently usedMMIO memory-mapped IOMUX multiplexer
OO object orientedRISC reduced instruction set computer
SDRAM synchronous DRAMSRAM static random access memory
TOS top-of stackUART universal asynchronous receiver/transmitterVHDL VHSIC hardware description language
VHSIC very high speed integrated circuit
65 / 67
Lab Today
I Components and Small Sequential CircuitsI Lab 4 PageI You need to download again, as I have updated the lab
I Or learn to use git and do a git pull ;-)I Each exercise contains a test, which initially failsI sbt test runs them all
I To just run a single test, run e.g.,sbt "testOnly SingleTest"
When all test succeed your are done ;-)I Except: additional some drawing exercise
66 / 67
Summary
I Vending machine is your final projectI The vending machine and the report are part of your gradeI A digital circuit is organized in componentsI Components have ports with directionsI Sequential circuits are combinations of registers with
combinational circuits
67 / 67