CS-A1120 Programming 2
Department of Computer Science
Aalto University
(Based on material by Petteri Kaski and Tommi Junttila)
Using the building blocks of combinational logic:
Is this enough to build a computer that can be programmed?
How do we build a programmable machine?
https://presemo.aalto.fi/prog2/
What about a length \(m\) list of \(n\)-bit numbers?
Consider: combinational logic Adder/Subtracter
\(a \pm b\)
\(a + b\), if \(p = 0\)
\(a - b\), if \(p = 1\)
Could be built using one adder circuit, one subtracter circuit, and one multiplexer from last week.
Three input words and two 'program' bits selecting the operation
\(\left(a\pm b\right) \pm c\)
\(\left(a + b\right) + c\), if \(p = 00\)
\(\left(a + b\right) - c\), if \(p = 01\)
\(\left(a - b\right) + c\), if \(p = 10\)
\(\left(a - b\right) - c\), if \(p = 11\)
Can still be built, but must implement each and every possible program path!
Feedback from outputs to inputs every time a 'button' is pressed
What are the new values (left to right) in this four gate bus after triggering feedback once?
(Violet arrows indicate feedback.)
What are the new values (left to right) in this four gate bus after triggering feedback once?
(Violet arrows indicate feedback.)
What are the new values (left to right) in this four gate bus after triggering feedback once?
(Violet arrows indicate feedback.)
We will need to engineer a few things to make it practical, but in principle Sequential logic is enough!
acc to \(x_1\), in to \(x_2\), and p to the operator, say \(0\) for \(+\), \(1\) for \(-\)acc is now the result of the addition / subtraction of the first two numbersin to \(x_3\) and p to the operatoracc is updated to new resultCan be done for any sequence of additions subtractions (up to the number of bits we use to represent the numbers of course).
Steps 1,3,5,… is a 'program'
minilog - Sequential logic in Scala
tinylog package needs an upgrade
Gate and Bus objects now must be part of a Circuit object
Gate or Bus hostminilog
minilog has an XOR operator (can use either ^^ or + between gates in code)val c = new Circuit() creates a circuitval g = c.input() creates an input element on circuit cval bb = c.input(8) create an 8 input element bus on circuit cg.host will get the circuit g belongs toa.buildFeedbackFrom(b) will build feedback from b to the input element(s) ac.clock() trigger the clock in circuit c
More about the design of minilog in the reading material (*)
minilog example: feedback between gatesCreate a four bit bus with feedback from gate \(n\) to gate \(n+1\):
// Using minilog now import minilog._ // Always need a circuit val c = Circuit() // Create the bus of input elements val aa = c.inputs(4) // Feedback TO gate at index 1 // FROM gate at index 0 aa(1).buildFeedbackFrom(aa(0)) // From index 1 -> index 2 aa(2).buildFeedbackFrom(aa(1)) // You should use a loop for this aa(3).buildFeedbackFrom(aa(2)) // Build a trigger to visualise val t = Trigger(c) t.watch("aa", aa.reverse) t.go()
1 and clock the circuit?1 and clock it?
minilog example: building the incrementer
import minilog.* // Note: minilog not tinylog def buildHalfAdder(ai: Gate, c: Gate) = (ai && c, (!ai && c)||(ai && !c)) def buildIncrementer(aa: Bus) = var c = aa.host.True // initial carry is true val r = new Array[Gate](aa.length) for i <- 0 until aa.length do val (c_out,s) = buildHalfAdder(aa(i), c) r(i) = s c = c_out end for new Bus(r.toSeq) end buildIncrementer
In combinational logic circuit without feedback this would increase the input once.
Now for the feedback:
val n = 4 val c = Circuit() val ins = c.inputs(n) val outs = buildIncrementer(ins) ins.buildFeedbackFrom(outs)
We can play with it using minilog Trigger:
val t = Trigger(c) t.watch("ins", ins.reverse) t.watch("outs", outs.reverse) t.go()
minilog example: building an accumulator-adder
def buildAdder(aa: Bus, bb: Bus) : Bus = val pairs = aa.zip(bb) var c : Gate = aa.host.False // Create sequence of gates using loop val sum = for (a,b) <- pairs yield // Construct s gate for this bit val s = a ^^ b ^^ c // ^^ means XOR // Update carry c = ( (a && b) || (a && c) || (b && c) ) s // Return s gate new Bus(sum) end buildAdder
val n = 8 val c = Circuit() val accum_in = c.inputs(n) val user_in = c.inputs(n) val accum_out = buildAdder(accum_in, user_in) accum_in.buildFeedbackFrom(accum_out)
val t = Trigger(c) t.watch("accum_in", accum_in.reverse) t.watch("user_in", user_in.reverse) t.watch("accum_out", accum_out.reverse) t.go()
Buffer or Array in Scalaaddress is an 'index' into the memoryenable write is true the word indicated by address is overwritten by data inenable read is true the word indicated by address is copied to data out
The width of the address bus limits the size of the address space, that is how many different memory places that can be accessed. When implemented in hardware this is a physical limitation of the machine.
How many bits are needed to address a memory bank of 8 words?
(Hint: it is 1 bit for a 2 word memory.)
Let's start conceptually building a programmable processor architecture
minilog package!
Describes how data is transformed in one clock of the Processor
$0, $1, $2, $3, $4, $5, $6, and $7
$0 to $7operation selects which one is used the current 'tick'L is the number (0-7) of the register where the result is storedA is the number (0-7) of the register of the first operandB is the number (0-7) of the register of the second operand
Example: to have the ALU put the sum of $0 and $3 into $4
operation to the number corresponding to addition instructionL to 100 (4)A to 000 (0)B to 011 (3)With a slight upgrade, the ALU can handle 'constant' in operations
immed_in is a 16-bit word that can be used in place of a registeradd:
A and B,A to the constant stored in immed_in
The armlet package (part of the exercises) comes with a UI that lets you test out the ALU by setting different inputs and clocking the circuit.
launchALUTrigger.scala in the exercise package, orscala> new ALUTrigger()
Do we have a programmable computer?
Almost, we somehow need to load our program - the instructions for the data path - and have them executed automatically.
More on that next time.
minilog allows both ^^ and + for XOR, they do the same!Circuit of a Gate or Bus by using the .host methodbuildFeedbackFrom on input elementsloadEnable and readyBus is a sequence!play-programs to check the behaviour of your implementations
t.go() line