Readings
- Counters (Program Counter - PC):
- N2T: Chapter 3 Intro, 3.1 (Counters), 3.2.4, 3.3 (Counter), 3.4, 3.5 (slides 47-50, 59, 60-end)
- Assembly Language:
Description
This assignment will focus on the following tasks:
- building the program counter and jump/branch module
- writing programs that use functions and recursion in Assembly (at the end)
Build the
PC circuit described in Project 3:
N2T: Project 3
Chapters 3 provides the contract for each chip, i.e. description of its behavior, names and number inputs, names and state of outputs. The API is available here:
The Hack Chipset
Assembly Language Programming
vvv
vvv Scroll to the bottom. Consider starting with the Assembly section.
vvv
Design in Logisim
Note the following requirements:
- arrange the circuits vertically in the given order (each below the previous one, *not* in a grid)
- label the input pins as specified in the contract
Here are additional specific requirements:
- save the Logisim files in folder
computer/cpu1/circ
PC:
- save in file named PC.circ
- hint: this is a register that increments by 1
- the bus widths of in/out will be 16 bit
- use existing components from Logisim (all implemented previously)
- for testing will need to attach a clock
- minimal use of basic gates
- do not use the
Counter component, since it is essentially the PC
Jumper [not in the book, combinational gate]:
Chip name: Jumper
Inputs: zr, ng, // same meaning as ALU
opcode[3] // 001=BGT, 010=BEQ, 011=BGE,
// 100=BLT, 101=BNE, 110=BLE
// 000=no jump, 111=BAL
Outputs: jump
Function: jump = 1, if zr and ng correspond to the given opcode; else jump=0
(for zr,ng combination that our ALU cannot produce jump could be anything)
Recall that the ALU from Chapter produces two single-bit outputs:
zr - to indicate whether the result was zero
ng - to indicate whether the result was negative
Create a circuit with the following inputs and outputs:
- save in Jumper.circ
zr, ng : same meaning as in ALU
opcode : indicates what branch we are attempting to achieve; corresponds to the ARM instructions BXX
- the output
jump indicates whether the program execution should jump to a new line; in other words, the output indicates whether the opcode corresponds to the given values of zr, ng
- moderate use of basic gates
Design in HDL
Here are additional specific requirements:
- Implement one circuit at a time. For circuit X copy X.hdl, X.cmp, X.tst to folder computer/cpu1/hdl/X.
PC:
- hint: this is a register that increments by 1
- use existing HDL components (all implemented previously)
- minimal use of basic gates
Jumper:
- see description in Logisim section
- save in Jumper.hdl
- create Mux8Way.hdl and Mux4Way.hdl based on the 16-bit versions from Project 5
Mux8Way should be built primarily of Mux, Mux4Way (as few as possible); basic gates should be avoided if possible
- create Mux8Way.(tst|cmp) and Mux4Way.(tst|cmp) based on the 16-bit versions from Project 5
- download test files: Jumper.tst, Jumper.cmp (need to fill in output; see quiz)
- moderate use of basic gates
Assembly Language Programming
Part 0
Save in folder
computer/cpu1/arm
Part I: Arrays as Parameters
Modify the example from class
sum_array.arm (linked at the top), so that it can be used as a function of two parameters that returns the sum of the first
n numbers:
def sum_array( numbers, n ):
...
...
return the-sum-of-first-n-numbers
- the code should be put in a function section
- the function should take two parameters:
- the base to the beginning of the array
- the number of elements in the array
- the function should return the sum of the first
n numbers in the array
At the top declare two different arrays of different lengths and run the function as follows:
- once for each array and its true size
- once for each array for half its size
- once for each array for size 1
- indicate in a comment at the top whether the function worked or not for each of the cases
Part II: Fibonacci Numbers
In file
fibonacci.arm write a recursive function that computes the
n-th Fibonacci number:
def fib( n ):
if n == 1:
return 0
elif n == 2:
return 1
else:
return fib(n-1) + fib(n-2)
At the top run the function 4 times times one after the other:
- once for the required cases
- once for
n=6,10
- indicate in a comment at the top whether the function worked or not for each of the cases
Part III: Recursive Binary Search
In file
binarySearch.arm write a recursive function that searches for a value in an array using binary search.
Recall that binary search requires a sorted array and works as follows:
- check the middle index in the current range
- if value at middle is bigger than value to find, search in left half of range; otherwise, search in right half
- do not include the middle index as part of the next range to search
def binarySearch( i, j, numbers, value ):
if i > j:
return 0, -1
m = (i+j) / 2
if numbers[m] == value:
return 1, m
elif numbers[m] > value:
return binarySearch( i, m-1, numbers, value )
else:
return binarySearch( m+1, j, numbers, value )
The function takes 4 parameters in this order:
i,j (inclusive) of current section to search
- the base of the array
- the value to search for
The function returns two numbers:
- either 1 or 0 to indicate the result of the search
- the index where the value was found (or -1 if value not found)
Note that ARM does not have instruction to divide, but division by 2 can be accomplished via right shift. To emphasize the distinction between the various types of shifts we are using Arithmetic Right Shift, which handles the sign properly, although, technically, it is not needed, since the indices are not negative:
ASR DestReg, RegToShift, NumShifts
At the top declare one array of 8-10 elements and run the function several times:
- look for first, last, inside, missings
- indicate in a comment at the top which values you tried to search for and whether the function worked or not for each of the cases
- note that the test array must be sorted