SAPsim.utils package
Submodules
SAPsim.utils.exceptions module
Custom exceptions.
- exception SAPsim.utils.exceptions.ARegisterNegativeInt[source]
Bases:
ExceptionThere’s somehow a negative number in unsigned register A.
- exception SAPsim.utils.exceptions.ARegisterNotEnoughBits[source]
Bases:
ExceptionThe unsigned value in register A can’t be stored in NUM_BITS_IN_REGISTERS bits.
- exception SAPsim.utils.exceptions.BRegisterNegativeInt[source]
Bases:
ExceptionThere’s somehow a negative number in unsigned register B.
- exception SAPsim.utils.exceptions.BRegisterNotEnoughBits[source]
Bases:
ExceptionThe unsigned value in register B can’t be stored in NUM_BITS_IN_REGISTERS bits.
- exception SAPsim.utils.exceptions.DroppedOffBottom(message='PC is greater than max address in RAM. Your program does not always HLT.')[source]
Bases:
ExceptionRaised if
PC> max address inRAM.
- exception SAPsim.utils.exceptions.FileNotCSV(path: Path, message='Invalid filepath provided. Extension must be .csv')[source]
Bases:
Exception
- exception SAPsim.utils.exceptions.InstructionRequiresArg(instruction: str)[source]
Bases:
Exception
- exception SAPsim.utils.exceptions.InvalidInstructionString(instruction: str)[source]
Bases:
Exception
- exception SAPsim.utils.exceptions.JumpToNegativeAddress(message='Attempted to jump to a negative address.')[source]
Bases:
Exception
SAPsim.utils.execute module
Execute instructions in RAM.
- SAPsim.utils.execute.execute_full_speed() None[source]
Execute instructions in
RAMat full speed untilEXECUTINGisFalseorPC > max addr.- Returns:
None
- SAPsim.utils.execute.execute_next() None[source]
Execute a single instruction at the current
PCvalue ifEXECUTING. If attempting to execute an empty address,PC += 1(i.e., doesn’t skip to next filled address).- Returns:
None
- SAPsim.utils.execute.run(prog_path: str, **kwargs) None | dict[str, Any][source]
Run given .csv program in SAPsim format.
- Parameters:
prog_path (
str) – .csv file in SAPsim format.**kwargs – See below
- Keyword Arguments:
- debug (
bool) – Whether to run in debug mode (True) or at full speed (False)
Default is full speed
- debug (
- change (
dict[int, int]) – dict[address, byte] of values to change in RAM
The value at each address (0 to 15) will be overwritten to that byte
Useful for debugging programs (edit a value without changing the CSV)
Useful for autograding programs (overwrite a reserved instruction/data value)
- change (
- table_format (
str) – Printed table format
Options: https://github.com/astanin/python-tabulate#table-format
Default value in
global_varsis"simple_outline"
- table_format (
- The rest of the parameters are pretty much exclusively for unit testing, and you should not use these
- return_state (
bool) – If
True, then program state will be returnedSee
utils.helpers.get_state()Will probably cause type warnings since the return type is
Union[None, dict[str, Any]]To avoid type warnings, use
run_and_return_state
- return_state (
- non_blocking (
bool) – This is used to unit test debug mode of
run(), you likely don’t have a need for thisIf
True, thenrun()won’t block on inputinput()won’t be called in debug mode (i.e., don’t have to press enter to continue execution)If this is
True, then debug mode will be on even ifdebugisn’t in kwargs
- non_blocking (
- no_print (
bool) – This is used to save computation time during unit testing
If
True, thenprint_RAM()andprint_info()won’t be calledIn debug mode, “Program halted.” will still be printed
- no_print (
- bits (
int) – You should not modify this
Number of bits in registers
Default value in
global_varsis 88 is also the maximum value since everything in RAM should fit in a byte
- bits (
- Returns:
Noneor program state ifreturn_state- Return type:
Union[None, dict[str, Any]]
- SAPsim.utils.execute.run_and_return_state(prog_path: str, **kwargs: Any) dict[str, Any][source]
Run given .csv program in SAPsim format.
- Parameters:
prog_path (
str) – .csv file in SAPsim format.**kwargs – See below
- Keyword Arguments:
- debug (
bool) – Whether to run in debug mode (True) or at full speed (False)
Default is full speed
- debug (
- change (
dict[int, int]) – dict[address, byte] of values to change in RAM
The value at each address (0 to 15) will be overwritten to that byte
Useful for debugging programs (edit a value without changing the CSV)
Useful for autograding programs (overwrite a reserved instruction/data value)
- change (
- table_format (
str) – Printed table format
Options: https://github.com/astanin/python-tabulate#table-format
Default value in
global_varsis"simple_outline"
- table_format (
- The rest of the parameters are pretty much exclusively for unit testing, and you should not use these
- return_state (
bool) – If
True, then program state will be returnedSee
utils.helpers.get_state()Will probably cause type warnings since the return type is
Union[None, dict[str, Any]]To avoid type warnings, use
run_and_return_state
- return_state (
- non_blocking (
bool) – This is used to unit test debug mode of
run(), you likely don’t have a need for thisIf
True, thenrun()won’t block on inputinput()won’t be called in debug mode (i.e., don’t have to press enter to continue execution)If this is
True, then debug mode will be on even ifdebugisn’t in kwargs
- non_blocking (
- no_print (
bool) – This is used to save computation time during unit testing
If
True, thenprint_RAM()andprint_info()won’t be calledIn debug mode, “Program halted.” will still be printed
- no_print (
- bits (
int) – You should not modify this
Number of bits in registers
Default value in
global_varsis 88 is also the maximum value since everything in RAM should fit in a byte
- bits (
- Returns:
Noneor program state ifreturn_state- Returns:
dictcontaining program state (seehelpers.get_state)- Return type:
dict[str, Any]
SAPsim.utils.global_vars module
Global variables.
If changing anything in this file, also modify SAPsim/__init__.py and helpers.print_info.
- SAPsim.utils.global_vars.A: int = 0
Register A, default value 0
- SAPsim.utils.global_vars.B: int = 0
Register B, default value 0
- SAPsim.utils.global_vars.EXECUTING: bool = True
Is the program executing? Set to
Falsebyhlt()
- SAPsim.utils.global_vars.FLAG_C: bool = False
Carry-out bit, modified by
add()andsub(). Default value False (0).
- SAPsim.utils.global_vars.FLAG_Z: bool = False
Zero flag = NOR(Sum bits), modified by
add()andsub(). Default value False (0).Lab 3’s ALU has default value True (1) for FlagZ because the results register is initially 0.
However, it makes more sense in the simulation to set it to False by default.
- SAPsim.utils.global_vars.MAX_PC: int = 15
Max PC value. 2**4-1
- SAPsim.utils.global_vars.MNEMONIC_TO_OPCODE: bidict = bidict({'NOP': 0, 'LDA': 1, 'ADD': 2, 'SUB': 3, 'STA': 4, 'LDI': 5, 'JMP': 6, 'JC': 7, 'JZ': 8, 'OUT': 14, 'HLT': 15})
Bidirectional mapping
str mnemonic : int opcode.Use
MNEMONIC_TO_OPCODE.inverse[opcode]to get mnemonic from opcode.All mnemonics in this dict are in all caps.
- SAPsim.utils.global_vars.NUM_BITS_IN_REGISTERS: int = 8
This variable is the #bits in registers and affects how
add,sub,ldi, andldawork. Default value is 8. Max value is 8 since everything in RAM needs to fit in a byte.
- SAPsim.utils.global_vars.PC: int = 0
Program counter that indexes into
RAM, default value 0
- SAPsim.utils.global_vars.RAM: dict[int, int] = {}
dict[int, int]mappingPC:byte, wherebytecan be instruction or data (indistinguishable, mostly)
- SAPsim.utils.global_vars.table_format: str = 'simple_outline'
Tabulate
table_fmtkwarg to customize pretty-printing. Defaults tosimple_outline, see all options: https://github.com/astanin/python-tabulate#table-format
SAPsim.utils.helpers module
Miscellaneous helper functions.
- SAPsim.utils.helpers.check_state(**kwargs)[source]
Compare the current state to expected values. Mostly used in testing functions.
Optional parameters RAM=, PC=, A=, B=, FLAG_C=, FLAG_Z=, EXECUTING=
- SAPsim.utils.helpers.check_state_all(RAM, PC: int, A: int, B: int, FLAG_C: bool, FLAG_Z: bool, EXECUTING: bool)[source]
Compare all current state variables to expected values. Mostly used in testing functions.
- SAPsim.utils.helpers.get_state() dict[str, Any][source]
Return a dict of global variables and their values. Mostly used in testing functions.
- SAPsim.utils.helpers.instruction_to_byte(instruction: str) int[source]
Given an instruction in the form <Mnemonic> <Arg>, with a space, return the byte representation.
For NOP, OUT, and HLT, if an Arg is not given, then the right hexit will just be 0.
Haven’t yet tested exception handling.
- SAPsim.utils.helpers.is_documented_by(original, lines_to_remove: int = 0, prepend: str = '', append: str = '')[source]
Use for wrapper functions that should have the original function’s docstring.
- Parameters:
original – The original function
lines_to_remove (
int) – How many lines to remove from the end of the docstring (i.e., to remove old return)preprend – What to prepend to docstring. Pass in a docstring (i.e., triple quotation marks), and there should be a trailing newline
append (
str) – What to append to docstring. Pass in a docstring (i.e., triple quotation marks), and there should be a leading newline
- SAPsim.utils.helpers.pad_hex(hex: str, width: int)[source]
Pad given hex str with 0x prefix to width hexits. That is, 0x prefix not included in the width.
- SAPsim.utils.helpers.parse_arg(byte: int) int[source]
Given a byte, return the 4-bit arg, just the bottom 4 bits.
- Parameters:
byte (int)
- Returns:
4-bit arg
- Return type:
int
- SAPsim.utils.helpers.parse_byte(byte: int)[source]
Given a byte (2 hexits), return the opcode (1 hexit) and arg (1 hexit). Return as dict for readability.
- Parameters:
byte (int)
- Returns:
{‘opcode’: opcode, ‘arg’: arg}
- Return type:
dict[str, int]
- SAPsim.utils.helpers.parse_opcode(byte: int)[source]
Given a byte, return the 4-bit opcode, just the top 4 bits.
- Parameters:
byte (int)
- Returns:
4-bit opcode
- Return type:
int
- SAPsim.utils.helpers.print_RAM()[source]
Pretty print the contents of RAM, sorted by address.
PC | Addr | Instruction | Dec | Hex |Display byte in dec and hex format and attempt to display as instruction (except when opcode invalid) for all bytes since we can’t distinguish instructions from data.
Display arrow on current PC value.
Uses
global_vars.table_formatfor table format passed totabulate().
- SAPsim.utils.helpers.print_info()[source]
Print the values of everything in
global_vars.pyexcept RAM.
SAPsim.utils.instructions module
SAP instruction implementation.
All function docstrings (and even most implementations) are ripped straight from the SAP Instruction Set, with only slight modifications.
This DOES NOT exist in actual SAP but for the purposes of simulation and testing,
add(arg) and sub(arg) have optional kwargs direct_add= and direct_sub=
that will cause A = A + arg, A = A - arg instead of A = A + Mem(arg), A = A - Mem(arg).
This DOES NOT exist in actual SAP but for implementation purposes, instructions that don’t need an arg (i.e. NOP, OUT, HLT) get a default parameter so that they can still be called with an argument. In actual SAP, all instructions (byte) have a required Arg, not a default or optional arg.
OPCODE_TO_INSTR_PROCEDURE dict that maps opcodes to procedures is defined at the bottom.
- SAPsim.utils.instructions.OPCODE_TO_INSTR_PROCEDURE = {0: <function nop>, 1: <function lda>, 2: <function add>, 3: <function sub>, 4: <function sta>, 5: <function ldi>, 6: <function jmp>, 7: <function jc>, 8: <function jz>, 14: <function out>, 15: <function hlt>}
This
dictmaps opcodes to the procedures defined in this file.The syntax
OPCODE_TO_INSTR_PROCEDURE[opcode](arg)will execute the correct instruction withargpassed as argument! Very cool.
- SAPsim.utils.instructions.add(arg: int, **kwargs) None[source]
A = A + Mem(arg). Accounts forNUM_BITS_IN_REGISTERSto setFLAG_CandFLAG_Z. Handles overflow.Opcode 2
Parameters
- arg: int
memory address, usually
- kwarg
direct_add: boolSet to
Trueto directly addarg(i.e.A = A + arginstead ofA = A + Mem(arg)), for testing purposes and use insub.This behavior does not exist in actual SAP.
- SAPsim.utils.instructions.out(arg: int = 0) None[source]
Display = OUT = A. Prints | PC | A (dec) | A (hex) |Opcode 14
- SAPsim.utils.instructions.sta(arg: int) None[source]
Mem(Arg) = A. CAN store to unmapped addr, which will simply map the addr in RAM.Opcode 4
- SAPsim.utils.instructions.sub(arg: int, **kwargs) None[source]
A = A - Mem(arg). Accounts forNUM_BITS_IN_REGISTERSto setFLAG_CandFLAG_Z. Callsadd()twice to perform 2’s complement subtraction.Opcode 3
Parameters
- arg: int
memory address, usually
- kwarg
- direct_sub: bool
set to
Trueto directly subarg(i.e.A = A - arginstead ofA = A - Mem(arg)), for testing purposes.This behavior does not exist in actual SAP.
SAPsim.utils.parser module
Parses a SAP program in the CSV format given in template.csv into global_vars.RAM.
- SAPsim.utils.parser.parse_csv(file_path: Path | str) None[source]
Takes a
.csvfile path in SAPsimtemplate.csvformat and parses it intoRAM.Calls
setup_state()iffile_pathis valid.If an address is skipped (not in the
.csvfile), it is not mapped inRAM. If an address is mapped but First Hexit and Second Hexit are blank, aNOP 0(0x00) is inserted.The reasoning here is that if an addr is skipped completely in the CSV, it shouldn’t show up in RAM. If an addr is mapped but First Hexit and Second Hexit are blank, it should show up in RAM (as
NOP 0).- Parameters:
file_path (Union[Path, str]) – The path to the
.csvfile to parse.- Raises:
RowWithNoAddress – If a row has no address.
InvalidAddress – If a row has an invalid address.
NegativeAddress – If a row has a negative address.
DuplicateAddress – If a row has a duplicate address.
NoFirstHexit – If a row has no First Hexit.
NoSecondHexit – If a row has no Second Hexit.
FirstHexitNegative – If a row has a negative First Hexit.
FirstHexitGreaterThan15 – If a row has a First Hexit greater than 15.
SecondHexitNegative – If a row has a negative Second Hexit.
SecondHexitGreaterThan15 – If a row has a Second Hexit greater than 15.
InvalidFirstHexit – If a row has an invalid First Hexit.
InvalidSecondHexit – If a row has an invalid Second Hexit.
MoreThan16MappedAddresses – If there are more than 16 mapped addresses.
- Returns:
None
Module contents
Utilities for SAPsim.