Skip to main content

Easy simulations for lower level tasks

Project description

TDT4160 1.1.0

tdt4160 is an emulator for IJVM-microinstructions and pseudo-assembly, as is commonly seen in the NTNU subject TDT4160, particularly on its exams.

There are two main components to this package. tdt4160.assembly and tdt4160.ijvm. Both function by letting you set registries, memory addresses and queue instructions before executing them. During execution, each individual instruction is stepped through, with lots of information printed so you can easily see what's going on. Technically requires Python >= 3.7 to be conformant, but should probably work with any version >= 3.6. There are no external dependencies besides the standard library.

View on PyPI | Fork me on gitgud

Installation

To install tdt4160, run:

$ python3 -m pip install tdt4160

or to install from source:

$ python3 setup.py install

Introduction

Due to COVID-19, most NTNU classes switched from exams in exam halls with no external help/tools allowed to home exams with all tools allowed. I thought it would be pretty funny if you could just automate the exams now that you're allowed to use tools.

I was right, it was pretty funny.

Example usage

Pseudo-assembly

# This example from the Autumn 2020 exam, task 6

from tdt4160.assembly import *

# First set the registries as specified in the task
set_asm_registries(
    R0=0xFFFF0000,
    R7=0xFFFF0001,
    R8=0xFFFF0002,
    R9=0xFFFF0003,
)

# Then set the memory addresses as specified
set_asm_addresses({
    0xFFFF0000: 0x00000001,
    0xFFFF0001: 0x00000002,
    0xFFFF0002: 0x00000003,
    0xFFFF0003: 0x00000004,
    0xFFFF0004: 0xFFFF0005
})

# Queue all the instructions to be performed
assemble(0x0000FFFE, LOAD, R8, R0)
assemble(0x0000FFFF, MOVC, R7, 1)
assemble(0x00010000, ADD, R0, R0, R7)
assemble(0x00010001, LOAD, R9, R0)
assemble(0x00010002, MUL, R9, R8, R9)
assemble(0x00010003, ADD, R9, R9, R8)
assemble(0x00010004, ADD, R0, R0, R7)
assemble(0x00010005, LOAD, R8, R0)
assemble(0x00010006, ADD, R8, R9, R8)

# Then actually run them
execute_assembly(0x0000FFFE)

# This function prints all the registries used in the task
# In this case, we're looking for R8, which is 6
print_asm_regs()

This outputs the following:

=============================== MEMORY: 0000FFFE ===============================
INSTRUCTION: LOAD R8=FFFF0002, R0=FFFF0000
Loaded value 00000001 into R8 from address FFFF0000
=============================== MEMORY: 0000FFFF ===============================
INSTRUCTION: MOVC R7=FFFF0001, Constant=00000001
Moved value 00000001 into R7
=============================== MEMORY: 00010000 ===============================
INSTRUCTION: ADD R0=FFFF0000, R0=FFFF0000, R7=00000001
Added R0=FFFF0000+R7=00000001
Result FFFF0001 stored in R0
=============================== MEMORY: 00010001 ===============================
INSTRUCTION: LOAD R9=FFFF0003, R0=FFFF0001
Loaded value 00000002 into R9 from address FFFF0001
=============================== MEMORY: 00010002 ===============================
INSTRUCTION: MUL R9=00000002, R8=00000001, R9=00000002
Multiplied R8=00000001*R9=00000002
Result 00000002 stored in R9
=============================== MEMORY: 00010003 ===============================
INSTRUCTION: ADD R9=00000002, R9=00000002, R8=00000001
Added R9=00000002+R8=00000001
Result 00000003 stored in R9
=============================== MEMORY: 00010004 ===============================
INSTRUCTION: ADD R0=FFFF0001, R0=FFFF0001, R7=00000001
Added R0=FFFF0001+R7=00000001
Result FFFF0002 stored in R0
=============================== MEMORY: 00010005 ===============================
INSTRUCTION: LOAD R8=00000001, R0=FFFF0002
Loaded value 00000003 into R8 from address FFFF0002
=============================== MEMORY: 00010006 ===============================
INSTRUCTION: ADD R8=00000003, R9=00000003, R8=00000003
Added R9=00000003+R8=00000003
Result 00000006 stored in R8
================================================================================
R0  = 0xFFFF0002
R7  = 0x00000001
R8  = 0x00000006
R9  = 0x00000003

IJVM

# This example from the Autumn 2020 exam, task 4

from tdt4160.ijvm import *

# Set the registries as specified
set_ijvm_registries(
    SP=0x10101010,
    LV=0x30000000,
    CPP=0x10000001,
    TOS=0xFF000000,
    OPC=0xABCDE000,
    H=0x12345678,
    MAR=0xA5A5A5A5,
    MDR=0x5A5A5A5A,
    PC=0x55AA55AA
)

# Queue the microinstructions to run
ijvm(0b000001000, 0b000001001, 0b000, 0b00010000, 0b100000000, 0b000, 0b1111)
ijvm(0b000001001, 0b000001011, 0b000, 0b00111001, 0b100000000, 0b000, 0b1100)
ijvm(0b000001010, 0b000010000, 0b001, 0b01011000, 0b010101010, 0b000, 0b0001)
ijvm(0b000001011, 0b000001100, 0b000, 0b00111100, 0b100000000, 0b000, 0b0101)
ijvm(0b000001100, 0b000000000, 0b000, 0b00111100, 0b000010000, 0b000, 0b0101)
ijvm(0b000001101, 0b000001110, 0b000, 0b00110010, 0b001000101, 0b100, 0b1000)

# Actually run them
execute_ijvm(0b000001000)

# Print the value of all the registries after execution
# In this case, we're looking for several registries, so just check the ones you want
print_all_ijvm()

This outputs the following:

======================= Instruction address: 0x000001000 =======================
next=0b000001001 JAM=0b000 ALU=0b00010000 C=0b100000000 Mem=0b000 B=0b1111
ALU is 0b010000, function: 0
Result of operation: 0x00000000
Final result: 0x00000000
C is 0b100000000
The following registries take the value of 0x00000000
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001001
======================= Instruction address: 0x000001001 =======================
next=0b000001011 JAM=0b000 ALU=0b00111001 C=0b100000000 Mem=0b000 B=0b1100
ALU is 0b111001, function: A + 1
A is always H=0x00000000
Result of operation: 0x00000001
Final result: 0x00000001
C is 0b100000000
The following registries take the value of 0x00000001
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001011
======================= Instruction address: 0x000001011 =======================
next=0b000001100 JAM=0b000 ALU=0b00111100 C=0b100000000 Mem=0b000 B=0b0101
ALU is 0b111100, function: A + B
A is always H=0x00000001
B is 0b0101 (5), yielding LV=0x30000000
Result of operation: 0x30000001
Final result: 0x30000001
C is 0b100000000
The following registries take the value of 0x30000001
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001100
======================= Instruction address: 0x000001100 =======================
next=0b000000000 JAM=0b000 ALU=0b00111100 C=0b000010000 Mem=0b000 B=0b0101
ALU is 0b111100, function: A + B
A is always H=0x30000001
B is 0b0101 (5), yielding LV=0x30000000
Result of operation: 0x60000001
Final result: 0x60000001
C is 0b000010000
The following registries take the value of 0x60000001
LV
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000000000
================================================================================
Next instruction is 0. We're done
SP = 0x10101010
LV = 0x60000001
CPP = 0x10000001
TOS = 0xFF000000
OPC = 0xABCDE000
H = 0x30000001
MAR = 0xA5A5A5A5
MDR = 0x5A5A5A5A
PC = 0x55AA55AA
MBR = 0xUNINITIALIZED
MBRU = 0xUNINITIALIZED
MPC = 0x00000000

Note the uninitialized values were never touched, so they remain uninitialized. That's okay as long as we don't use them after.

Pテ・ Norsk

tdt4160 er en emulator for IJVM-mikronstruksjoner og pseudo-assemblykode, som den man ofte ser i NTNU faget TDT4160 sine eksamener.

Det er to hoveddeler i pakkken. tdt4160.assembly og tdt4160.ijvm. Begge lar deg sette opp registre, minneaddresser, og sette instruksjoner i kテク, fテクr de blir utfテクrt. Mens instruksjonene kjテクrer printes det masse informasjon ut om hva som faktisk utfテクres, slik at det blir lettere テ・ se hva som skjer. Pakken krever teknisk sett en Pythonversjon som er >= 3.7, men bテクr fungere fint med alt >= 3.6. Pakken har ingen andre avhengigheter enn standardbiblioteket.

Se pテ・ PyPI | Gafle meg pテ・ gitgud

Installering

For テ・ installere tdt4160, kjテクr:

$ python3 -m pip install tdt4160

eller for テ・ installere fra kildekode:

$ python3 setup.py install

Introduction

Pga. COVID-19 har de fleste fag pテ・ NTNU byttet fra eksamen i eksamenshaller uten hjelpemidler til hjemmeeksamener med alle hjelpemidler tillat. Jeg syntes det hadde vテヲrt litt morsomt hvis man bare hadde noe verktテクy som gjorde hele eksamenen for deg, nテ・ som du kan bruke det du vil.

Hadde rett, det var ganske morsomt.

Eksempel

Pseudo-assembly

# Dette eksempelet er fra Hテクsteksamen 2020, oppgave 6

from tdt4160.assembly import *

# Fテクrst, sett opp alle registre som det stテ・r i oppgaven
set_asm_registries(
    R0=0xFFFF0000,
    R7=0xFFFF0001,
    R8=0xFFFF0002,
    R9=0xFFFF0003,
)

# Sテ・ sett opp alle minneaddresser
set_asm_addresses({
    0xFFFF0000: 0x00000001,
    0xFFFF0001: 0x00000002,
    0xFFFF0002: 0x00000003,
    0xFFFF0003: 0x00000004,
    0xFFFF0004: 0xFFFF0005
})

# Legg alle instruksjonene i kテク for utfテクrsel
assemble(0x0000FFFE, LOAD, R8, R0)
assemble(0x0000FFFF, MOVC, R7, 1)
assemble(0x00010000, ADD, R0, R0, R7)
assemble(0x00010001, LOAD, R9, R0)
assemble(0x00010002, MUL, R9, R8, R9)
assemble(0x00010003, ADD, R9, R9, R8)
assemble(0x00010004, ADD, R0, R0, R7)
assemble(0x00010005, LOAD, R8, R0)
assemble(0x00010006, ADD, R8, R9, R8)

# Kjテクr instruksjonene
execute_assembly(0x0000FFFE)


# Denne funksjonen printer alle registre som ble brukt i utfテクrselen
# I dette tilfellet ser vi etter R8, som bテクr vテヲre 6
print_asm_regs()

Koden spytter ut fテクlgende:

=============================== MEMORY: 0000FFFE ===============================
INSTRUCTION: LOAD R8=FFFF0002, R0=FFFF0000
Loaded value 00000001 into R8 from address FFFF0000
=============================== MEMORY: 0000FFFF ===============================
INSTRUCTION: MOVC R7=FFFF0001, Constant=00000001
Moved value 00000001 into R7
=============================== MEMORY: 00010000 ===============================
INSTRUCTION: ADD R0=FFFF0000, R0=FFFF0000, R7=00000001
Added R0=FFFF0000+R7=00000001
Result FFFF0001 stored in R0
=============================== MEMORY: 00010001 ===============================
INSTRUCTION: LOAD R9=FFFF0003, R0=FFFF0001
Loaded value 00000002 into R9 from address FFFF0001
=============================== MEMORY: 00010002 ===============================
INSTRUCTION: MUL R9=00000002, R8=00000001, R9=00000002
Multiplied R8=00000001*R9=00000002
Result 00000002 stored in R9
=============================== MEMORY: 00010003 ===============================
INSTRUCTION: ADD R9=00000002, R9=00000002, R8=00000001
Added R9=00000002+R8=00000001
Result 00000003 stored in R9
=============================== MEMORY: 00010004 ===============================
INSTRUCTION: ADD R0=FFFF0001, R0=FFFF0001, R7=00000001
Added R0=FFFF0001+R7=00000001
Result FFFF0002 stored in R0
=============================== MEMORY: 00010005 ===============================
INSTRUCTION: LOAD R8=00000001, R0=FFFF0002
Loaded value 00000003 into R8 from address FFFF0002
=============================== MEMORY: 00010006 ===============================
INSTRUCTION: ADD R8=00000003, R9=00000003, R8=00000003
Added R9=00000003+R8=00000003
Result 00000006 stored in R8
================================================================================
R0  = 0xFFFF0002
R7  = 0x00000001
R8  = 0x00000006
R9  = 0x00000003

IJVM

# Dette eksempelet er fra Hテクsteksamen 2020, oppgave 4

from tdt4160.ijvm import *

# Sett opp registre som det stテ・r i oppgaven
set_ijvm_registries(
    SP=0x10101010,
    LV=0x30000000,
    CPP=0x10000001,
    TOS=0xFF000000,
    OPC=0xABCDE000,
    H=0x12345678,
    MAR=0xA5A5A5A5,
    MDR=0x5A5A5A5A,
    PC=0x55AA55AA
)

# Skriv inn alle mikronstruksjonene
ijvm(0b000001000, 0b000001001, 0b000, 0b00010000, 0b100000000, 0b000, 0b1111)
ijvm(0b000001001, 0b000001011, 0b000, 0b00111001, 0b100000000, 0b000, 0b1100)
ijvm(0b000001010, 0b000010000, 0b001, 0b01011000, 0b010101010, 0b000, 0b0001)
ijvm(0b000001011, 0b000001100, 0b000, 0b00111100, 0b100000000, 0b000, 0b0101)
ijvm(0b000001100, 0b000000000, 0b000, 0b00111100, 0b000010000, 0b000, 0b0101)
ijvm(0b000001101, 0b000001110, 0b000, 0b00110010, 0b001000101, 0b100, 0b1000)

# Kjテクr instruksjonene
execute_ijvm(0b000001000)

# Skriv ut verdien til alle registrene etter at programmet har kjテクrt
# I dette tilfellet ser vi etter flere registre, plukk ut de du vil
print_all_ijvm()

Denne koden gir:

======================= Instruction address: 0x000001000 =======================
next=0b000001001 JAM=0b000 ALU=0b00010000 C=0b100000000 Mem=0b000 B=0b1111
ALU is 0b010000, function: 0
Result of operation: 0x00000000
Final result: 0x00000000
C is 0b100000000
The following registries take the value of 0x00000000
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001001
======================= Instruction address: 0x000001001 =======================
next=0b000001011 JAM=0b000 ALU=0b00111001 C=0b100000000 Mem=0b000 B=0b1100
ALU is 0b111001, function: A + 1
A is always H=0x00000000
Result of operation: 0x00000001
Final result: 0x00000001
C is 0b100000000
The following registries take the value of 0x00000001
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001011
======================= Instruction address: 0x000001011 =======================
next=0b000001100 JAM=0b000 ALU=0b00111100 C=0b100000000 Mem=0b000 B=0b0101
ALU is 0b111100, function: A + B
A is always H=0x00000001
B is 0b0101 (5), yielding LV=0x30000000
Result of operation: 0x30000001
Final result: 0x30000001
C is 0b100000000
The following registries take the value of 0x30000001
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001100
======================= Instruction address: 0x000001100 =======================
next=0b000000000 JAM=0b000 ALU=0b00111100 C=0b000010000 Mem=0b000 B=0b0101
ALU is 0b111100, function: A + B
A is always H=0x30000001
B is 0b0101 (5), yielding LV=0x30000000
Result of operation: 0x60000001
Final result: 0x60000001
C is 0b000010000
The following registries take the value of 0x60000001
LV
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000000000
================================================================================
Next instruction is 0. We're done
SP = 0x10101010
LV = 0x60000001
CPP = 0x10000001
TOS = 0xFF000000
OPC = 0xABCDE000
H = 0x30000001
MAR = 0xA5A5A5A5
MDR = 0x5A5A5A5A
PC = 0x55AA55AA
MBR = 0xUNINITIALIZED
MBRU = 0xUNINITIALIZED
MPC = 0x00000000

Merk at to av registrene aldri ble satt, verken i oppsettet eller i koden, sテ・ de er bare UNINITIALIZED. Det er greit sテ・ lenge de aldri brukes til noe.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tdt4160-1.1.0.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

tdt4160-1.1.0-py3-none-any.whl (26.8 kB view details)

Uploaded Python 3

File details

Details for the file tdt4160-1.1.0.tar.gz.

File metadata

  • Download URL: tdt4160-1.1.0.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.9.0

File hashes

Hashes for tdt4160-1.1.0.tar.gz
Algorithm Hash digest
SHA256 47156f219ac94295973911892953854b97134d553cee48f827dfc0cdf91018f0
MD5 10126d7b66e602ddd3cd95ab5bb409cd
BLAKE2b-256 5bb4675b8ebb57f1269af2c74b0a7e119f7592218fdd0c2b22203bbba514190e

See more details on using hashes here.

File details

Details for the file tdt4160-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: tdt4160-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.9.0

File hashes

Hashes for tdt4160-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5cc93289a979683e00bd416ac9d300823f260e81e0f79247c032307c7749b759
MD5 c1c105b0b2a0be582a0769c99360dc6f
BLAKE2b-256 0c47612e596b48eb028a5a5c48ab5cb31ebcb660c258d5f1ca016761b2a8c23e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page