Post on 02-Dec-2014
description
CSC 343 Lab 8 - Page 1/12 - docmarionum1@gmail.com
PwnCorp P9001 Microprocessor Programmer's Manual
CSC 343 Lab 8 - Page 2/12 - docmarionum1@gmail.com
Table of ContentsTable of Contents ............................................................................................................................ 2
Introduction .................................................................................................................................... 3
Registers .......................................................................................................................................... 3
Memory ........................................................................................................................................... 3
Instructions ..................................................................................................................................... 3
MV ................................................................................................................................................... 4
MVI .................................................................................................................................................. 4
MVNZ .............................................................................................................................................. 4
ADD ................................................................................................................................................. 4
SUB .................................................................................................................................................. 5
LD .................................................................................................................................................... 5
ST ..................................................................................................................................................... 5
HLT ................................................................................................................................................... 6
Labels .............................................................................................................................................. 6
Assembler Directive: .raw ............................................................................................................... 6
Example Programs: ......................................................................................................................... 7
Usage ............................................................................................................................................... 9
Appendix 1: pasm.py ..................................................................................................................... 10
CSC 343 Lab 8 - Page 3/12 - docmarionum1@gmail.com
Introduction This manual has been written to help the reader program the PwnCorp P9001 microprocessor in assembly language. The topics covered are: registers, memory and the 8 instructions.
Registers The P9001 features 8 general-purpose, 16-bit registers. They are referred to as $0-7. $7 additionally acts as the program counter, and should not be used for operations other than branching.
Memory The P9001 addresses memory in words of size 16 bits. The CPU uses a 16-bit address line, so it can theoretically support up to 1 Mb of memory, but at this time, current motherboards only support up to 4Kb of memory (addresses 0x0-0xFF) and the higher addresses are for I/O operations. Therefore, the P9001 Assembly (PASM) will only support programs up to 4Kb in length.
Instructions The P9001 supports 8 instructions – mv, mvi, add, sub, ld, st, mvnz and hlt. Each instruction is between 1 and 2 words in length (2-4 bytes). The instruction format for two register instructions is: XXXXXXXX YYYY ZZZZ
opcode sr dt
Opcodes are always 1 byte. sr and dt are values from 0000-0111 that represent registers $0-7. The format of instructions that use immediate values is: XXXXXXXX YYYY 0000 ZZZZZZZZZZZZZZZZ
opcode sr dt imm
dt is not used in immediate operations.
CSC 343 Lab 8 - Page 4/12 - docmarionum1@gmail.com
MV The mv (move) instruction copies the contents of one register (source register) into another (destination register). The contents of the source register are left unchanged. Instruction Size: 2 bytes Opcode: 00000000 Cycles: 4 Syntax: mv $x,$y (move the contents of $y to $x)
MVI The mvi (move immediate) instruction copies an immediate value into a register. Instruction Size: 4 bytes Opcode: 00000001 Cycles: 7 Syntax: mvi $x,imm (move the value imm into $x)
MVNZ The mvnz (move not zero) instruction perform a move operation only if the result of the previous add or subtract operation was not zero. Instruction Size: 2 bytes Opcode: 00000010 Cycles: 4 Syntax: mvnz $x,$y (move the contents of $y into $x if not zero)
ADD The add (addition) instruction adds the contents of one register to the contents of another and stores the result in the first register. Instruction Size: 2 bytes Opcode: 00000011 Cycles: 8 Syntax: add $x,$y (add $x and $y and store the result in $x)
CSC 343 Lab 8 - Page 5/12 - docmarionum1@gmail.com
SUB The sub (subtraction) instruction subtracts the contents of one register from the contents of another and stores the result in the first register. Instruction Size: 2 bytes Opcode: 00000100 Cycles: 8 Syntax: sub $x,$y (subtract $y from $x and store the result in $x)
LD The ld (load) instruction loads the contents of the memory address pointed to by one register into the contents of another register Instruction Size: 2 bytes Opcode: 00000101 Cycles: 7 Syntax: ld $x,($y) (load the value at memory address $y into $x)
ST The st (st) instruction stores the contents of a register at the memory address pointed to by another register Instruction Size: 2 bytes Opcode: 00000110 Cycles: 8 Syntax: st $x,($y) (store the value in $x at the memory address $y)
CSC 343 Lab 8 - Page 6/12 - docmarionum1@gmail.com
HLT The hlt (halt) instruction halts the CPU execution. It must be restarted to resume operation. Instruction Size: 2 bytes Opcode: 11111111 Cycles: 4 Syntax: hlt
Labels PASM supports labels within your assembly code. Labels are one word, followed by a colon, and take the value of the next line's memory address. Labels must be on their own line. For example: …
mvi $6,loop1
loop1:
sub $0,$1
mvnz $7,$6
…
The above code implements a loop. The address pointed to by loop1 (the address of the sub instruction) is stored in $6. Then $1 is subtracted from $0. If the result is not 0, the value in $6, which is the address of the sub instruction, is moved to $7, which is the program counter. Once the result is 0, the mvnz instruction won't perform the move, and the execution will continue on to the rest of the program.
Assembler Directive: .raw The assembler directive .raw will take a value and write it exactly as written into the program code. The value must be in binary and it must be exactly 16 bits. This can be used to initialize memory with variable values. For example: …
mvi $6,variable1
ld $1,($6)
CSC 343 Lab 8 - Page 7/12 - docmarionum1@gmail.com
…
hlt
variable1:
.raw 0000000000000001
This stores a 1 at the memory address pointed to by variable1. This value can then be read and written by moving variable1 into a register and loading or storing using that register as the pointer register.
Example Programs: Fibonacci Sequence: mvi $0,10
mvi $1,1
mv $2,$1
mvi $3,2
sub $0,$3
mv $3,$1
mvi $5,loop
loop:
mv $4,$1
add $1,$2
mv $2,$4
sub $0,$3
mvnz $7,$5
mvi $6,#111111111
st $1,($6)
hlt
This program computes the Fibonacci sequence up to 10 and then writes the result to the display, which in this case has address #1111111.
CSC 343 Lab 8 - Page 8/12 - docmarionum1@gmail.com
Vector Addition: mvi $0,4
mvi $1,vector1
mvi $2,vector2
mvi $3,vector3
mvi $6,loop
loop:
ld $4,($1)
ld $5,($2)
add $4,$5
st $4,($3)
mvi $4,1
add $1,$4
add $2,$4
add $3,$4
sub $0,$4
mvnz $7,$6
mvi $3,vector3
mvi $6,#111111111
st $3,($6)
hlt
vector1:
.raw 0000000000000001
.raw 0000000000000010
.raw 0000000000000100
.raw 0000000000001000
vector2:
.raw 0000000000010000
.raw 0000000000100000
.raw 0000000001000000
.raw 0000000010000000
vector3:
.raw 0000000000000000
.raw 0000000000000000
.raw 0000000000000000
.raw 0000000000000000
This program sums vector1 and vector2 component-wise and stores the result in vector3. It then writes the first component of vector3 to IO.
CSC 343 Lab 8 - Page 9/12 - docmarionum1@gmail.com
Usage PASM is written in python. With the assembler program, named pasm.py in this case, run: python pasm.py input.asm output.mif
Where input.asm is the name of you input assembly file and output.mif is the outputted mif (memory initialization file) file.
CSC 343 Lab 8 - Page 10/12 - docmarionum1@gmail.com
Appendix 1: pasm.py import sys
OPCODES = {
'mv' : "00000000",
'mvi' : "00000001",
'mvnz' : "00000010",
'add' : "00000011",
'sub' : "00000100",
'ld' : "00000101",
'st' : "00000110",
'hlt' : "11111111",
}
REGISTERS = {
'$0' : "0000",
'$1' : "0001",
'$2' : "0010",
'$3' : "0011",
'$4' : "0100",
'$5' : "0101",
'$6' : "0110",
'$7' : "0111"
}
def RType(op):
def op_handler(args):
return ''.join([OPCODES[op], REGISTERS[args.split(',')[0]],
REGISTERS[args.split(',')[1].strip("()")]])
return op_handler
def IType(op):
def op_handler(args):
return ''.join([OPCODES[op],
REGISTERS[args.split(',')[0]],
"0000\n",
(args.split(',')[1][1:].zfill(16) if
args.split(',')[1][0] is "#" else
"!!tag!!" + args.split(',')[1] if
args.split(',')[1][0].isalpha() else
bin(int(args.split(',')[1].strip("#")))[2:].zfill(16)),
""])
return op_handler
def QType(op):
def op_handler():
return ''.join([OPCODES[op], "00000000"])
return op_handler
CSC 343 Lab 8 - Page 11/12 - docmarionum1@gmail.com
def DRaw(args):
return args
PARSERS = {
'mv' : RType('mv'),
'mvi' : IType('mvi'),
'mvnz' : RType('mvnz'),
'add' : RType('add'),
'sub' : RType('sub'),
'ld' : RType('ld'),
'st' : RType('st'),
'hlt' : QType('hlt'),
'.raw' : DRaw
}
def parseline(line):
try:
return PARSERS[line.split()[0]](line.split()[1])
except:
return PARSERS[line.split()[0]]()
def parseFile(filename):
labels = dict()
addr = 0
mif_file =
"WIDTH=16;\nDEPTH=256;\n\nADDRESS_RADIX=UNS;\nDATA_RADIX=BIN;\n\nCONTENT
BEGIN\n"
f = open(filename)
lines = f.read().splitlines()
f.close()
for line in lines:
if ":" in line:
labels[line.strip()[:-1]] = addr
else:
binr = parseline(line)
for word in binr.splitlines():
mif_file += "\n" + str(addr) + " : " + word + ";"
addr += 1
mif_file += " -- " + line
for label in labels:
mif_file = mif_file.replace("!!tag!!"+label,
bin(labels[label])[2:].zfill(16))
if addr < 256:
mif_file += "\n\n[" + str(addr) + "..255] : 0000000000000000;"
mif_file+= "\nEND;"
return mif_file
if __name__ == '__main__':
mif = parseFile(sys.argv[1])
f = open(sys.argv[2], 'w')
CSC 343 Lab 8 - Page 12/12 - docmarionum1@gmail.com
f.write(mif)
f.close()