Components and Sequential CircuitsI We talked about git last week I To version your source I Maybe...

Post on 02-Aug-2020

0 views 0 download

Transcript of Components and Sequential CircuitsI We talked about git last week I To version your source I Maybe...

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